/* ============================================================
   Oli Home — Post-it stack
   Loaded after main.css; overrides where needed.
   No gradients. Flat brand colours only.
   ============================================================ */

:root {
  /* Hard-coded fallbacks so the post-its render even if theme-colors.css
     gets served stale from cache. */
  --oli-bright:      #4a8b2c;
  --oli-forest:      #1a4921;
  --oli-cream:       #f5efe2;
  --oli-paper:       #fbf8f1;
  --oli-bright-dark: #3a6e22;
  --oli-bright-soft: #6aab4c;
  --oli-forest-soft: #2a6431;
  --oli-mist:        #e6efde;

  --postit-radius: 28px;
  --postit-shadow:
    0 2px 4px rgba(26, 73, 33, 0.06),
    0 12px 24px rgba(26, 73, 33, 0.14),
    0 32px 60px rgba(26, 73, 33, 0.12);
  --postit-shadow-soft:
    0 1px 2px rgba(26, 73, 33, 0.05),
    0 6px 14px rgba(26, 73, 33, 0.08);
  --postit-overlap: 96px;
  --postit-ease: cubic-bezier(0.34, 1.4, 0.5, 1);
}

/* ============================================================
   Body — paper / desk background
   ============================================================ */
body.home {
  background: var(--oli-cream);
  color: var(--oli-forest);
  /* clip, not hidden — hidden makes body a scroll container and
     breaks the deck's position:sticky */
  overflow-x: hidden;
  overflow-x: clip;
}

/* Subtle paper texture using SVG noise */
body.home::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: 0.6;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='180' height='180'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' seed='4'/><feColorMatrix values='0 0 0 0 0.1 0 0 0 0 0.28 0 0 0 0 0.13 0 0 0 0.06 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
  background-size: 180px 180px;
}

/* ============================================================
   Nav — white bar, distinct from cream hero
   ============================================================ */
/* Nav styling moved to main.css so the component renders identically
   on every page. Page-specific nav overrides intentionally removed. */

/* Hero sits below the now-taller nav */
body.home .hero-split {
  padding-top: clamp(72px, 10vh, 120px);
}

/* ============================================================
   Section primitives
   ============================================================ */
.section {
  position: relative;
  z-index: 1;
  padding: clamp(64px, 9vh, 120px) clamp(20px, 4vw, 64px);
}

.section--neutral {
  background: var(--oli-cream);
}

/* ============================================================
   HERO — single centred column + rotating platform screens
   ============================================================ */
.hero-home {
  position: relative;
  z-index: 1;
  background: var(--oli-cream);
  padding: clamp(72px, 9vh, 110px) clamp(20px, 4vw, 64px) clamp(48px, 6vh, 80px);
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  overflow: hidden;
}

/* Rising panel behind the content. As the user scrolls home.js grows
   --hero-rise-h; the cream "background" appears to recede upward,
   ending with the panel's top edge crossing the video at its vertical
   midpoint. Uses --oli-paper to match the next (#the-problem) section,
   so it reads as that section's background rising into the hero. */
/* Rising panel retired: hero and the problem statement now share one
   continuous cream background. */
.hero-home::after { content: none; }

.hero-home-inner {
  position: relative;
  z-index: 1;
  max-width: 1100px;
  margin: 0 auto;
  width: 100%;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
}

/* "Oli by Oaklin" lockup + sparkle + tagline share a single inline row.
   Using align-items: baseline so the logo's bottom edge anchors to the
   tagline's text baseline. The logo's height is in em, which scales
   with the tagline's font-size, so the lockup and text track each other
   identically at every viewport — "by Oaklin" stays on the same line
   as "Your AI innovation partner" on desktop AND mobile. */
.hero-home-tag {
  display: inline-flex;
  align-items: baseline;
  gap: 0.55rem;
  font-family: var(--fb);
  font-size: clamp(0.82rem, 0.98vw, 0.975rem);
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--oli-forest);
  margin: 0 0 0.6rem;
}
.hero-home-logo {
  display: block;
  height: 3em;
  width: auto;
  flex-shrink: 0;
  position: relative;
  /* The "by Oaklin" letters sit at 80.9% of the image height, so
     there's ~19.1% of image height (= 0.574em at 3em) of whitespace
     between the text and the image's bottom edge. Pushing the logo
     down by exactly that amount drops the "by Oaklin" baseline onto
     the tagline's text baseline — locked at every viewport size
     because both numbers are in em. */
  top: 0.72em;
}
.hero-home-tag-spark {
  color: var(--oli-forest);
  font-size: 0.9em;
  line-height: 1;
}

.hero-home-headline {
  font-family: var(--fd);
  font-weight: 400;
  font-size: clamp(2rem, 4.4vw, 3.6rem);
  line-height: 1.05;
  letter-spacing: -0.02em;
  color: var(--oli-forest);
  margin: 0 0 1rem;
  max-width: 18ch;
}
.hero-home-headline strong {
  font-weight: 700;
  color: var(--oli-bright);
}

.hero-home-sub {
  font-family: var(--fb);
  font-size: clamp(1.05rem, 1.4vw, 1.3rem);
  line-height: 1.5;
  color: var(--ink-muted);
  margin: 0 0 1.85rem;
  max-width: 560px;
}

.hero-home-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.85rem;
  justify-content: center;
  margin: 0 0 clamp(2.4rem, 5vh, 3.6rem);
}

/* Single hero CTA — sized to match the nav's "Book a consultation" button. */
.hero-home-actions .btn-solid {
  font-size: 0.83rem;
  padding: 10px 22px;
  background: var(--oli-bright);
  border-color: var(--oli-bright);
}
.hero-home-actions .btn-solid:hover {
  background: var(--oli-forest);
  border-color: var(--oli-forest);
}

/* ------------------------------------------------------------
   Hero demo video
   ------------------------------------------------------------ */
.hero-video {
  position: relative;
  width: 100%;
  max-width: 1080px;       /* size at full scale (= 1) — bigger */
  margin: 0 auto;
  border-radius: 14px;
  overflow: hidden;
  /* No background — the video element fills the container completely
     at its native aspect, so any background here would only appear if
     there were a gap (and we don't want one). */
  background: transparent;
  border: 1px solid rgba(26, 73, 33, 0.18);
  box-shadow:
    0 24px 60px -28px rgba(var(--rgb-forest), 0.35),
    0 8px 22px -10px rgba(var(--rgb-forest), 0.18);

  /* Scroll-driven scale: starts at 0.70, grows to 1.0 within the
     first 30% of the hero's scroll range. ~43% size jump.
     --hero-video-y is an extra negative translateY applied as the
     user scrolls into the mission section, so the video pulls up
     faster than the scroll itself, opening more space for the
     section below. home.js drives both vars. */
  --hero-video-scale: 0.70;
  --hero-video-y:     0px;
  transform: translate3d(0, var(--hero-video-y), 0) scale(var(--hero-video-scale));
  transform-origin: center top;
  will-change: transform;
  transition: transform 0.08s linear;
}

.hero-video-el {
  display: block;
  width: 100%;
  height: auto;          /* always render at the source video's
                            native aspect ratio — no letterbox, no
                            squash, no white space. */
  object-fit: fill;      /* belt-and-braces: even if the element
                            ever ends up at a non-native size, fill
                            stretches without padding. */
}

/* ============================================================
   HERO — full-bleed two-column (legacy, no longer rendered)
   ============================================================ */
.hero-split {
  position: relative;
  z-index: 1;
  background: var(--oli-cream);
  padding: clamp(56px, 8vh, 96px) clamp(20px, 4vw, 64px) clamp(72px, 10vh, 120px);
  overflow: hidden;
}

/* Desktop: hero always fills the viewport vertically. The inner grid
   sits centred within whatever height the viewport happens to be — so
   resizing the window updates the hero height dynamically. Uses dvh
   so it tracks the actual visible viewport, not the ideal one. */
@media (min-width: 901px) {
  .hero-split {
    min-height: 100vh;
    min-height: 100dvh;
    display: flex;
    align-items: center;
  }
  .hero-split-inner {
    width: 100%;
  }
}

.hero-split-inner {
  max-width: 1320px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
}

.hero-split-copy {
  min-width: 0;
}

.hero-logo {
  display: block;
  width: clamp(220px, 28vw, 360px);
  height: auto;
  margin: 0 0 clamp(1.5rem, 3vw, 2.25rem);
}

.hero-eyebrow {
  font-family: var(--fm);
  font-size: 0.74rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--oli-bright);
  margin: 0 0 1.1rem;
}

.hero-headline {
  font-family: var(--fd);
  font-weight: 400;
  font-size: clamp(2.4rem, 5.4vw, 4.2rem);
  line-height: 1.04;
  letter-spacing: -0.02em;
  color: var(--oli-forest);
  margin: 0 0 1.25rem;
}

.hero-headline strong {
  font-weight: 600;
  color: var(--oli-bright);
}

.hero-sub {
  font-family: var(--fb);
  font-size: clamp(1.05rem, 1.4vw, 1.25rem);
  line-height: 1.55;
  color: var(--ink-muted);
  margin: 0 0 2rem;
  max-width: 520px;
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.85rem;
}

.btn-solid,
.btn-line {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--fb);
  font-weight: 700;
  font-size: 0.94rem;
  padding: 14px 28px;
  border-radius: 9999px;
  text-decoration: none;
  cursor: pointer;
  transition: background 0.18s ease, border-color 0.18s ease, transform 0.12s ease, color 0.18s ease;
  white-space: nowrap;
}

.btn-solid {
  background: var(--oli-forest);
  color: var(--white);
  border: 1.5px solid var(--oli-forest);
}
.btn-solid:hover {
  background: var(--oli-bright);
  border-color: var(--oli-bright);
}

.btn-line {
  background: transparent;
  color: var(--oli-forest);
  border: 1.5px solid var(--oli-bright);
}
.btn-line:hover {
  background: var(--oli-mist);
}

.btn-solid:active,
.btn-line:active { transform: scale(0.97); }

/* Right column — photo with branded frame */
.hero-split-visual {
  position: relative;
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

.hero-photo-frame {
  position: relative;
  width: 100%;
  max-width: 540px;
  isolation: isolate;
  transform: rotate(-1.5deg);
}

.hero-photo-back {
  position: absolute;
  left: -28px;
  bottom: -28px;
  width: 75%;
  height: 75%;
  background: var(--oli-forest);
  border-radius: 28px;
  z-index: 0;
}

.hero-photo {
  position: relative;
  z-index: 2;
  display: block;
  width: 100%;
  height: auto;
  border-radius: 24px;
  box-shadow:
    0 4px 10px rgba(26, 73, 33, 0.08),
    0 24px 50px rgba(26, 73, 33, 0.16);
}

/* Icon overlay — actual Oli icon image at top-right of Dan */
.hero-icon-overlay {
  position: absolute;
  top: -34px;
  right: -42px;
  width: clamp(110px, 16vw, 180px);
  height: auto;
  z-index: 3;
  transform: rotate(8deg);
  filter: drop-shadow(0 12px 24px rgba(26, 73, 33, 0.22));
  will-change: transform;
  animation: icon-wobble 7s ease-in-out infinite alternate;
}

@keyframes icon-wobble {
  0%   { transform: rotate(8deg)  translateY(0); }
  100% { transform: rotate(11deg) translateY(-8px); }
}

@media (max-width: 900px) {
  .hero-split-inner {
    grid-template-columns: 1fr;
    gap: 3rem;
  }
  .hero-photo-frame { transform: rotate(-1deg); max-width: 420px; margin: 0 auto; }
  .hero-icon-overlay { width: 110px; top: -22px; right: -22px; }
}

/* ============================================================
   Post-it stack — single-card variant
   ============================================================ */
.postit-stack {
  position: relative;
  z-index: 1;
  padding: clamp(48px, 8vh, 96px) clamp(20px, 4vw, 64px) clamp(96px, 14vh, 180px);
  max-width: 1200px;
  margin: 0 auto;
}

.postit-stack--single {
  padding: 0;
  max-width: 1040px;
  margin: 0 auto;
}

/* ============================================================
   Base post-it
   ============================================================ */
.postit {
  position: relative;
  display: block;
  margin: 0 auto;
  max-width: 980px;
  padding: clamp(40px, 6vw, 72px) clamp(28px, 5vw, 64px);
  border-radius: var(--postit-radius);
  background: var(--postit-bg, var(--oli-bright));
  color: var(--postit-fg, var(--white));
  box-shadow: var(--postit-shadow);
  transform-origin: 50% 0%;
  will-change: transform, opacity;
  /* Stack overlap — each post-it pulled up over the previous */
  margin-top: calc(-1 * var(--postit-overlap));
}

.postit:first-of-type {
  margin-top: 0;
}

/* Tilt variants — applied to the resting transform via custom property */
.postit { --tilt: 0deg; --shift-x: 0px; }
.postit.tilt-l-1 { --tilt: -1.4deg; --shift-x: -8px; }
.postit.tilt-l-2 { --tilt: -2.6deg; --shift-x: -14px; }
.postit.tilt-r-1 { --tilt:  1.2deg; --shift-x:  10px; }
.postit.tilt-r-2 { --tilt:  2.4deg; --shift-x:  16px; }

/* Z-index ladder — newer post-its stack on top */
.postit:nth-of-type(1) { z-index: 1; }
.postit:nth-of-type(2) { z-index: 2; }
.postit:nth-of-type(3) { z-index: 3; }
.postit:nth-of-type(4) { z-index: 4; }
.postit:nth-of-type(5) { z-index: 5; }
.postit:nth-of-type(6) { z-index: 6; }
.postit:nth-of-type(7) { z-index: 7; }

/* Colour variants */
.postit--bright {
  --postit-bg: var(--oli-bright);
  --postit-fg: var(--white);
}
.postit--forest {
  --postit-bg: var(--oli-forest);
  --postit-fg: var(--white);
}
.postit--paper {
  --postit-bg: var(--oli-paper);
  --postit-fg: var(--oli-forest);
  box-shadow:
    0 2px 4px rgba(26, 73, 33, 0.06),
    0 14px 32px rgba(26, 73, 33, 0.10),
    0 32px 70px rgba(26, 73, 33, 0.08),
    inset 0 0 0 1px rgba(26, 73, 33, 0.04);
}

/* Tape strip across the top of each post-it for character */
.postit::before {
  content: '';
  position: absolute;
  top: -10px;
  left: 50%;
  transform: translateX(-50%) rotate(calc(var(--tilt) * -0.5));
  width: clamp(80px, 14vw, 130px);
  height: 22px;
  background: rgba(245, 239, 226, 0.55);
  border-radius: 2px;
  box-shadow: 0 2px 6px rgba(26, 73, 33, 0.10);
  pointer-events: none;
  z-index: 1;
}

.postit--paper::before {
  background: rgba(74, 139, 44, 0.18);
}

/* Optional corner peel — small triangle hint at bottom-right */
.postit-peel {
  position: absolute;
  right: 0;
  bottom: 0;
  width: 44px;
  height: 44px;
  pointer-events: none;
  overflow: hidden;
  border-bottom-right-radius: var(--postit-radius);
}
.postit-peel::before {
  content: '';
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.12);
  clip-path: polygon(100% 0, 0 100%, 100% 100%);
}

/* ============================================================
   Inner post-it content
   ============================================================ */
.postit-inner {
  position: relative;
  z-index: 2;
  max-width: 780px;
  margin: 0 auto;
  text-align: center;
}

.postit-inner--left {
  text-align: left;
  margin: 0;
}

.postit-eyebrow {
  font-family: var(--fm);
  font-size: 0.7rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  font-weight: 600;
  margin: 0 0 1.4rem;
  opacity: 0.85;
}

.postit-headline {
  font-family: var(--fd);
  font-weight: 400;
  font-size: clamp(2.4rem, 6vw, 4.4rem);
  line-height: 1.04;
  letter-spacing: -0.02em;
  margin: 0 0 1.5rem;
}

.postit-headline strong {
  font-weight: 600;
}

.postit-headline em {
  font-style: normal;
  font-weight: 400;
}

.postit-sub {
  font-family: var(--fb);
  font-size: clamp(1.05rem, 1.5vw, 1.3rem);
  line-height: 1.5;
  margin: 0 0 2rem;
  opacity: 0.92;
  max-width: 640px;
  margin-left: auto;
  margin-right: auto;
}

.postit-body {
  font-family: var(--fb);
  font-size: clamp(1rem, 1.25vw, 1.15rem);
  line-height: 1.6;
  margin: 0 0 1.1rem;
  opacity: 0.92;
  max-width: 640px;
  margin-left: auto;
  margin-right: auto;
}

.postit-body:last-child { margin-bottom: 0; }

.postit-buttons {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 0.85rem;
  margin-top: 1.5rem;
}

/* Buttons inside post-its — light on dark, dark on light */
.postit--bright .postit-btn-primary,
.postit--forest .postit-btn-primary {
  background: var(--white);
  color: var(--oli-forest);
  border: 1.5px solid var(--white);
}
.postit--bright .postit-btn-primary:hover,
.postit--forest .postit-btn-primary:hover {
  background: var(--oli-cream);
  border-color: var(--oli-cream);
}
.postit--bright .postit-btn-ghost,
.postit--forest .postit-btn-ghost {
  background: transparent;
  color: var(--white);
  border: 1.5px solid rgba(255,255,255,0.65);
}
.postit--bright .postit-btn-ghost:hover,
.postit--forest .postit-btn-ghost:hover {
  background: rgba(255,255,255,0.12);
  border-color: var(--white);
}
.postit--paper .postit-btn-primary {
  background: var(--oli-forest);
  color: var(--white);
  border: 1.5px solid var(--oli-forest);
}
.postit--paper .postit-btn-primary:hover {
  background: var(--oli-bright);
  border-color: var(--oli-bright);
}
.postit--paper .postit-btn-ghost {
  background: transparent;
  color: var(--oli-forest);
  border: 1.5px solid var(--oli-bright);
}
.postit--paper .postit-btn-ghost:hover {
  background: var(--oli-mist);
}

.postit-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--fb);
  font-weight: 700;
  font-size: 0.95rem;
  padding: 14px 28px;
  border-radius: 9999px;
  text-decoration: none;
  cursor: pointer;
  transition: background 0.18s ease, border-color 0.18s ease, transform 0.12s ease;
  white-space: nowrap;
}
.postit-btn:active { transform: scale(0.97); }

/* ============================================================
   Section-specific layouts
   ============================================================ */

/* Stats post-it — 3-column figures */
.postit-stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(1.5rem, 4vw, 3rem);
  margin-top: 2.5rem;
}

.postit-stat {
  text-align: center;
}

.postit-stat-num {
  font-family: var(--fd);
  font-size: clamp(2.5rem, 6vw, 4.5rem);
  font-weight: 400;
  line-height: 1;
  color: var(--oli-bright-soft);
  margin: 0 0 0.85rem;
  letter-spacing: -0.02em;
}

.postit-stat-text {
  font-family: var(--fb);
  font-size: clamp(0.92rem, 1.1vw, 1rem);
  line-height: 1.45;
  color: rgba(255, 255, 255, 0.82);
  margin: 0;
  max-width: 240px;
  margin-left: auto;
  margin-right: auto;
}

@media (max-width: 720px) {
  .postit-stats { grid-template-columns: 1fr; gap: 2rem; }
}

/* What changes — mini post-its grid */
.mini-stickies {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(1rem, 2vw, 1.5rem);
  margin-top: 2.5rem;
}

.mini-sticky {
  position: relative;
  background: var(--mini-bg, var(--oli-paper));
  color: var(--mini-fg, var(--oli-forest));
  padding: 1.5rem 1.4rem;
  border-radius: 18px;
  box-shadow: var(--postit-shadow-soft);
  text-align: left;
  transform: rotate(var(--mini-tilt, 0deg));
  transition: transform 0.3s var(--postit-ease), box-shadow 0.3s ease;
}

.mini-sticky:hover {
  transform: rotate(0deg) translateY(-3px);
  box-shadow:
    0 4px 8px rgba(26, 73, 33, 0.08),
    0 14px 28px rgba(26, 73, 33, 0.14);
}

.mini-sticky:nth-child(1) { --mini-tilt: -2deg;  --mini-bg: var(--oli-paper);  --mini-fg: var(--oli-forest); }
.mini-sticky:nth-child(2) { --mini-tilt:  1.5deg; --mini-bg: var(--oli-mist);   --mini-fg: var(--oli-forest); }
.mini-sticky:nth-child(3) { --mini-tilt: -1deg;  --mini-bg: var(--oli-forest); --mini-fg: var(--white); }
.mini-sticky:nth-child(4) { --mini-tilt:  2deg;  --mini-bg: var(--oli-forest); --mini-fg: var(--white); }
.mini-sticky:nth-child(5) { --mini-tilt: -1.5deg; --mini-bg: var(--oli-paper);  --mini-fg: var(--oli-forest); }
.mini-sticky:nth-child(6) { --mini-tilt:  1deg;  --mini-bg: var(--oli-mist);   --mini-fg: var(--oli-forest); }

.mini-sticky-title {
  font-family: var(--fd);
  font-size: 1.18rem;
  font-weight: 600;
  line-height: 1.18;
  margin: 0 0 0.55rem;
  letter-spacing: -0.01em;
}

.mini-sticky-body {
  font-family: var(--fb);
  font-size: 0.95rem;
  line-height: 1.45;
  opacity: 0.85;
  margin: 0;
}

@media (max-width: 920px) {
  .mini-stickies { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 560px) {
  .mini-stickies { grid-template-columns: 1fr; }
  .mini-sticky { transform: rotate(0deg); }
}

/* ============================================================
   Drop-and-land entrance animation
   ============================================================ */
.postit {
  /* Resting transform: tilt + horizontal nudge */
  transform: translate(var(--shift-x), 0) rotate(var(--tilt));
  opacity: 1;
  transition:
    transform 0.95s var(--postit-ease),
    opacity 0.6s ease;
}

.postit.dropping {
  /* Pre-drop state */
  transform: translate(var(--shift-x), -120vh) rotate(calc(var(--tilt) - 18deg));
  opacity: 0;
  transition: none;
}

.postit.landed {
  /* Rest position */
  transform: translate(var(--shift-x), 0) rotate(var(--tilt));
  opacity: 1;
}

/* Subtle hover wobble on resting post-its */
.postit:hover {
  transform: translate(var(--shift-x), -4px) rotate(calc(var(--tilt) * 0.85));
}

/* Mini stickies — slight reveal on parent landing */
.mini-sticky {
  opacity: 0;
  transition: opacity 0.5s ease, transform 0.5s var(--postit-ease);
}
.postit.landed .mini-sticky { opacity: 1; }
.postit.landed .mini-sticky:nth-child(1) { transition-delay: 0.12s; }
.postit.landed .mini-sticky:nth-child(2) { transition-delay: 0.20s; }
.postit.landed .mini-sticky:nth-child(3) { transition-delay: 0.28s; }
.postit.landed .mini-sticky:nth-child(4) { transition-delay: 0.36s; }
.postit.landed .mini-sticky:nth-child(5) { transition-delay: 0.44s; }
.postit.landed .mini-sticky:nth-child(6) { transition-delay: 0.52s; }

/* Stats — sequential reveal */
.postit-stat {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 0.5s ease, transform 0.6s var(--postit-ease);
}
.postit.landed .postit-stat { opacity: 1; transform: translateY(0); }
.postit.landed .postit-stat:nth-child(1) { transition-delay: 0.20s; }
.postit.landed .postit-stat:nth-child(2) { transition-delay: 0.30s; }
.postit.landed .postit-stat:nth-child(3) { transition-delay: 0.40s; }

@media (prefers-reduced-motion: reduce) {
  .postit,
  .postit.dropping,
  .postit.landed,
  .mini-sticky,
  .postit-stat {
    transition: none !important;
    transform: none !important;
    opacity: 1 !important;
  }
}

/* ============================================================
   Trust footer — light strip below the stack
   ============================================================ */
body.home #trust {
  position: relative;
  background: var(--oli-cream);
  border-top: 1px solid rgba(26, 73, 33, 0.10);
  z-index: 2;
}

body.home .trust-headline,
body.home .trust-copy {
  color: var(--oli-forest);
}

/* ============================================================
   Tighten mobile spacing
   ============================================================ */
@media (max-width: 720px) {
  :root { --postit-overlap: 60px; }
  .postit { border-radius: 22px; }
  .postit-buttons { flex-direction: column; align-items: stretch; }
  .postit-btn { width: 100%; }
}

/* ============================================================
   WHY OLI — two-column with icon
   ============================================================ */
.why-section {
  background: var(--oli-cream);
}

.why-inner {
  max-width: 1240px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1.05fr 0.95fr;
  gap: clamp(2rem, 5vw, 5rem);
  align-items: center;
}

.why-copy { min-width: 0; }

.why-eyebrow {
  font-family: var(--fm);
  font-size: 0.74rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--oli-bright);
  margin: 0 0 1.1rem;
}

.why-headline {
  font-family: var(--fd);
  font-weight: 400;
  font-size: clamp(2rem, 4.2vw, 3.2rem);
  line-height: 1.06;
  letter-spacing: -0.02em;
  color: var(--oli-forest);
  margin: 0 0 1.5rem;
}

.why-headline strong {
  font-weight: 600;
  color: var(--oli-bright);
}

.why-body {
  font-family: var(--fb);
  font-size: clamp(1rem, 1.2vw, 1.1rem);
  line-height: 1.6;
  color: var(--ink-muted);
  margin: 0 0 1.1rem;
}

.why-body--emphasis {
  color: var(--oli-forest);
  font-weight: 500;
  border-left: 3px solid var(--oli-bright);
  padding-left: 1rem;
  margin-top: 1.5rem;
}

.why-visual {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1.5rem;
}

.why-icon {
  display: block;
  width: clamp(220px, 30vw, 380px);
  height: auto;
  animation: why-icon-float 9s ease-in-out infinite alternate;
}

@keyframes why-icon-float {
  0%   { transform: translateY(0) rotate(-2deg); }
  100% { transform: translateY(-12px) rotate(1deg); }
}

.why-quote {
  text-align: center;
  max-width: 320px;
}

.why-quote-text {
  font-family: var(--fd);
  font-size: 1.6rem;
  font-weight: 600;
  color: var(--oli-forest);
  margin: 0 0 0.35rem;
  font-style: normal;
}

.why-quote-attrib {
  font-family: var(--fm);
  font-size: 0.7rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--oli-bright);
  margin: 0;
  font-weight: 600;
}

@media (max-width: 900px) {
  .why-inner { grid-template-columns: 1fr; gap: 3rem; }
}

/* ============================================================
   PIPELINE OUTCOMES — "Build a stronger innovation pipeline"
   Light mist section, four outcome cards.
   ============================================================ */
.pipeline-sec {
  background: var(--oli-fern);
  overflow: hidden;
  overflow: clip;
}

.pipeline-sec__inner {
  position: relative;
  z-index: 1;
  max-width: 1240px;
  margin: 0 auto;
}

.pipeline-sec__head {
  max-width: 880px;
  margin: 0 auto clamp(2.5rem, 5vw, 4rem);
  text-align: center;
}

.pipeline-sec__eyebrow,
.service-sec__eyebrow {
  font-family: var(--fm);
  font-size: 0.74rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--oli-bright);
  margin: 0 0 1.25rem;
}

.pipeline-sec__title,
.service-sec__title {
  font-family: var(--fd);
  font-weight: 400;
  font-size: clamp(2.2rem, 4.8vw, 3.8rem);
  line-height: 1.08;
  letter-spacing: -0.02em;
  color: var(--oli-forest);
  margin: 0 0 1.4rem;
}

.pipeline-sec__title strong,
.service-sec__title strong {
  font-weight: 600;
  color: var(--oli-bright);
}

.pipeline-sec__lead,
.service-sec__lead {
  font-family: var(--fb);
  font-size: clamp(1rem, 1.3vw, 1.18rem);
  line-height: 1.6;
  color: var(--ink-muted);
  margin: 0 auto;
  max-width: 760px;
}

.pipeline-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: clamp(1rem, 1.8vw, 1.6rem);
}

.pipeline-card {
  background: var(--white);
  border: 1px solid rgba(26, 73, 33, 0.08);
  border-radius: 20px;
  padding: clamp(1.4rem, 2.2vw, 2rem);
  box-shadow: 0 4px 14px rgba(26, 73, 33, 0.05);
  transition:
    transform 0.45s var(--postit-ease),
    box-shadow 0.3s ease,
    border-color 0.3s ease;
}

.pipeline-card:hover {
  transform: translateY(-5px) rotate(-0.6deg);
  border-color: rgba(74, 139, 44, 0.45);
  box-shadow: 0 18px 44px rgba(26, 73, 33, 0.13);
}

.pipeline-card__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  border-radius: 13px;
  background: var(--oli-mist);
  color: var(--oli-bright);
  margin-bottom: 1.1rem;
}
.pipeline-card__icon svg {
  width: 22px;
  height: 22px;
}

.pipeline-card__title {
  font-family: var(--fd);
  font-weight: 600;
  font-size: clamp(1.2rem, 1.7vw, 1.45rem);
  line-height: 1.15;
  letter-spacing: -0.01em;
  color: var(--oli-forest);
  margin: 0 0 0.6rem;
}

.pipeline-card__body {
  font-family: var(--fb);
  font-size: 0.97rem;
  line-height: 1.55;
  color: var(--ink-muted);
  margin: 0;
}

@media (max-width: 760px) {
  .pipeline-grid { grid-template-columns: 1fr; }
}

/* ============================================================
   OAKLIN INNOVATION SERVICE — the wrapper around Oli.
   Paper section; three pillars as brand post-it cards.
   ============================================================ */
.service-sec {
  background: var(--oli-paper);
  overflow: hidden;
  overflow: clip;
}

.service-sec__inner {
  position: relative;
  z-index: 1;
  max-width: 1240px;
  margin: 0 auto;
}

.service-sec__head {
  max-width: 880px;
  margin: 0 auto clamp(2.8rem, 5.5vw, 4.5rem);
  text-align: center;
}

.service-pillars {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(1.2rem, 2.4vw, 2.4rem);
  max-width: 1140px;
  margin: 0 auto;
  align-items: stretch;
}

/* A pillar is a brand post-it: card-shape SVG behind the content.
   Square via the padding-bottom trick rather than aspect-ratio —
   Safari (especially older iOS) can collapse a grid item's height
   to zero when `aspect-ratio` is applied inside `display: grid`,
   which spills the absolutely-positioned content out of the card
   and produces a broken layout where 3 narrow text columns stack
   over the title. padding-bottom: 100% is universally supported. */
.service-note {
  position: relative;
  transform: rotate(var(--note-tilt, 0deg));
  transition: transform 0.5s var(--postit-ease);
}
.service-note::before {
  content: '';
  display: block;
  padding-bottom: 100%;
}
.service-note:nth-child(1) { --note-tilt: -2.4deg; }
.service-note:nth-child(2) { --note-tilt:  1.8deg; }
.service-note:nth-child(3) { --note-tilt: -1.4deg; }
.service-note:hover { transform: rotate(0deg) translateY(-6px); }

.service-note__shape {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  color: var(--pillar-bg, var(--oli-paper));
}

.service-note--bright { --pillar-bg: var(--oli-bright); --pillar-fg: var(--white);      --pillar-sub: rgba(255,255,255,0.88); --pillar-kicker: rgba(255,255,255,0.7); }
.service-note--forest { --pillar-bg: var(--oli-forest); --pillar-fg: var(--white);      --pillar-sub: rgba(255,255,255,0.84); --pillar-kicker: var(--oli-bright-soft); }
.service-note--mist   { --pillar-bg: var(--oli-mist);   --pillar-fg: var(--oli-forest); --pillar-sub: var(--ink-muted);       --pillar-kicker: var(--oli-bright); }

.service-note__content {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;   /* numbers pinned at the top so all 3 cards align */
  padding: 9% 12% 16% 13%;       /* tighter top so the kicker sits closer to the edge */
  color: var(--pillar-fg);
}

.service-note__kicker {
  font-family: var(--fm);
  font-size: clamp(0.72rem, 1vw, 0.88rem);
  letter-spacing: 0.18em;
  font-weight: 700;
  color: var(--pillar-kicker);
  margin: 0 0 0.7rem;
}

.service-note__title {
  font-family: var(--fd);
  font-weight: 600;
  font-size: clamp(1.25rem, 1.9vw, 1.6rem);
  line-height: 1.12;
  letter-spacing: -0.01em;
  margin: 0 0 0.7rem;
}

.service-note__body {
  font-family: var(--fb);
  font-size: clamp(0.82rem, 1.05vw, 0.95rem);
  line-height: 1.5;
  color: var(--pillar-sub);
  margin: 0;
}

.service-sec__cta {
  text-align: center;
  margin-top: clamp(2.5rem, 5vw, 4rem);
}

.service-cta-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  font-family: var(--fb);
  font-size: clamp(0.95rem, 1.15vw, 1.05rem);
  font-weight: 700;
  color: var(--white);
  background: var(--oli-bright);
  padding: 0.95rem 1.9rem;
  border-radius: 9999px;
  text-decoration: none;
  box-shadow: 0 10px 28px rgba(74, 139, 44, 0.35);
  transition:
    transform 0.35s var(--postit-ease),
    background 0.2s ease,
    box-shadow 0.3s ease;
}
.service-cta-btn:hover {
  background: var(--oli-bright-dark);
  transform: translateY(-3px);
  box-shadow: 0 16px 38px rgba(74, 139, 44, 0.42);
}
.service-cta-btn span { transition: transform 0.2s ease; }
.service-cta-btn:hover span { transform: translateX(4px); }

@media (max-width: 900px) {
  .service-pillars {
    grid-template-columns: 1fr;
    max-width: 340px;
    gap: 1.4rem;
  }
  /* Content-driven cards on mobile: text defines the height,
     padding-bottom square trick switched off, absolute content
     becomes static again. */
  .service-note::before { display: none; }
  .service-note__content {
    position: relative;
    inset: auto;
    padding: 13% 12% 20% 13%;
  }
}

/* ============================================================
   STATS BAND — full-bleed forest
   ============================================================ */
.stats-band {
  position: relative;
  z-index: 1;
  background: var(--oli-forest);
  color: var(--white);
  padding: clamp(72px, 11vh, 140px) clamp(20px, 4vw, 64px);
  overflow: hidden;
}

/* Subtle texture so it doesn't feel flat */
.stats-band::before {
  content: '';
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(rgba(255,255,255,0.03) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,0.03) 1px, transparent 1px);
  background-size: 64px 64px;
  pointer-events: none;
  opacity: 0.6;
}

.stats-band-inner {
  position: relative;
  max-width: 1180px;
  margin: 0 auto;
}

.stats-band-headline {
  font-family: var(--fd);
  font-weight: 400;
  font-size: clamp(2rem, 4.2vw, 3.2rem);
  line-height: 1.06;
  letter-spacing: -0.02em;
  text-align: center;
  margin: 0 0 clamp(2.5rem, 5vw, 4rem);
}

.stats-band-headline strong {
  font-weight: 600;
  color: var(--oli-bright-soft);
}

.stats-band-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(2rem, 5vw, 4rem);
}

.stats-band-item { text-align: center; }

.stats-band-num {
  font-family: var(--fd);
  font-size: clamp(2.6rem, 6vw, 4.6rem);
  font-weight: 400;
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--oli-bright-soft);
  margin: 0 0 1rem;
}

.stats-band-text {
  font-family: var(--fb);
  font-size: clamp(0.95rem, 1.1vw, 1.05rem);
  line-height: 1.5;
  color: rgba(255, 255, 255, 0.78);
  margin: 0;
  max-width: 260px;
  margin-left: auto;
  margin-right: auto;
}

@media (max-width: 720px) {
  .stats-band-grid { grid-template-columns: 1fr; gap: 2.5rem; }
}

/* ============================================================
   CTA — bright post-it with forest back-block
   ============================================================ */
.cta-section {
  padding-bottom: clamp(96px, 14vh, 180px);
}

.cta-postit { position: relative; }

.cta-back-block {
  position: absolute;
  left: -36px;
  bottom: -36px;
  width: 60%;
  height: 70%;
  background: var(--oli-forest);
  border-radius: 28px;
  z-index: -1;
  transform: rotate(-2deg);
  box-shadow: 0 18px 40px rgba(26, 73, 33, 0.18);
}

/* ============================================================
   Reveal-up — fade-up entrance for non-postit content
   ============================================================ */
.reveal-up {
  opacity: 0;
  transform: translateY(28px);
  transition:
    opacity 0.8s ease,
    transform 0.9s var(--postit-ease);
}
.reveal-up.in-view {
  opacity: 1;
  transform: translateY(0);
}
.reveal-d-1 { transition-delay: 0.10s; }
.reveal-d-2 { transition-delay: 0.20s; }
.reveal-d-3 { transition-delay: 0.30s; }


/* ============================================================
   Slide-in directions — left / right entrance
   ============================================================ */
.slide-in-l, .slide-in-r {
  opacity: 0;
  transition:
    opacity 0.9s ease,
    transform 1.05s var(--postit-ease);
}
.slide-in-l { transform: translate(-60px, 0); }
.slide-in-r { transform: translate( 60px, 0); }
.slide-in-l.in-view,
.slide-in-r.in-view {
  opacity: 1;
  transform: translate(0, 0);
}

/* ============================================================
   Word-stagger headlines (.split-words)
   JS wraps each word in <span class="word"><span>...</span></span>.
   Uses translateY + opacity only — no overflow:hidden — so the
   word containers don't clip ascenders or descenders.
   ============================================================ */
.split-words .word {
  display: inline-block;
  vertical-align: baseline;
  line-height: inherit;
}

.split-words .word > span {
  display: inline-block;
  transform: translateY(22px);
  opacity: 0;
  transition:
    transform 0.7s var(--postit-ease),
    opacity 0.55s ease;
  transition-delay: calc(var(--word-index, 0) * 55ms);
  will-change: transform, opacity;
}

.split-words.in-view .word > span {
  transform: translateY(0);
  opacity: 1;
}

/* ============================================================
   Parallax — JS adjusts --py for each [data-parallax] element
   ============================================================ */
[data-parallax] {
  --py: 0px;
  will-change: transform;
}

/* Special: hero icon overlay parallax composes with its wobble animation,
   so disable parallax transform there and let JS instead nudge top offset. */
.hero-photo-frame { transform: translateY(var(--py, 0px)) rotate(-1.5deg); }

/* ============================================================
   Marquee strip — between sections, rolling text
   ============================================================ */
.marquee {
  position: relative;
  z-index: 1;
  background: var(--oli-forest);
  color: var(--white);
  padding: 22px 0;
  overflow: hidden;
  border-top: 1px solid rgba(255,255,255,0.06);
  border-bottom: 1px solid rgba(255,255,255,0.06);
}

.marquee-track {
  display: flex;
  gap: 3rem;
  width: max-content;
  animation: marquee-roll 30s linear infinite;
  white-space: nowrap;
}

.marquee-item {
  font-family: var(--fd);
  font-size: clamp(1.4rem, 2.6vw, 2.1rem);
  font-weight: 400;
  letter-spacing: -0.01em;
  display: inline-flex;
  align-items: center;
  gap: 3rem;
}

.marquee-item::after {
  content: '';
  display: inline-block;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--oli-bright);
}

.marquee-item em {
  font-style: normal;
  color: var(--oli-bright-soft);
}

@keyframes marquee-roll {
  0%   { transform: translate3d(0, 0, 0); }
  100% { transform: translate3d(-50%, 0, 0); }
}

@media (prefers-reduced-motion: reduce) {
  .marquee-track { animation: none; }
}

/* ============================================================
   Count-up stats — start invisible until JS triggers
   ============================================================ */
.count-up { display: inline-block; }

/* ============================================================
   Reduced-motion fallbacks for new animations
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  .slide-in-l,
  .slide-in-r,
  .split-words .word > span {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
}

/* ============================================================
   LAUNCH OVERLAY — labs.google launch sequence, faithfully
   Phase 1 (0 – 18%) Settle: oversized + wide letter-spacing,
                     muted colour → final size, tight spacing,
                     darkened colour.
   Phase 2 (18 – 60%) Hold: shapes float around centred text.
   Phase 3 (60 – 78%) Stretch: letter-spacing widens, opacity
                     fades. Text exits horizontally.
   Phase 4 (78 – 100%) Hex reveal: cream overlay's clip-path
                       morphs from full rect → large hex → point,
                       while rotating. Page is revealed through
                       the shrinking, rotating hexagonal mask.
   ============================================================ */
:root {
  --launch-total: 4.20s;  /* settle 0-1.0s · hold 1.0-2.5s · exit 2.5-3.2s · reveal 3.0-4.05s */
}

/* Hide the SVG defs container itself (the <clipPath> is referenced by url()) */
.launch-svg {
  position: absolute;
  width: 0; height: 0;
  pointer-events: none;
}

.launch-overlay {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;

  /* Background + mask moved to .launch-overlay-cover so we can rotate
     the cutout independently of the postits & tagline. */
  animation: launch-overlay-hide var(--launch-total) ease forwards;
}

/* Counter-rotated wrapper inside the cover. The cover rotates with
   --reveal-rotation; this host rotates -reveal-rotation so the post-its
   inside stay upright relative to the viewport. The host is sized
   exactly to the viewport (inset 33.333% of the 300% cover). */
.launch-postits-host {
  position: absolute;
  inset: 33.333%;
  transform: rotate(calc(-1 * var(--reveal-rotation, 0deg)));
  transform-origin: 50% 50%;
  pointer-events: none;
}

/* The dark forest cover layer. Carries the mask AND the post-its,
   so both get hard-cut by the growing card-shape hole. Extends well
   past the viewport so rotation never exposes the corners. */
.launch-overlay-cover {
  position: absolute;
  /* Bigger than viewport so the rotated cover always covers viewport */
  top: -100%; left: -100%; right: -100%; bottom: -100%;
  background: var(--oli-forest);

  /* Two-layer mask: white gradient as base, SVG card as the punch-out.
     mask-composite: subtract removes the SVG's card silhouette from
     the white base — wherever the card is drawn, the cover becomes
     transparent → home page shows through. */
  -webkit-mask-image:
    linear-gradient(#fff, #fff),
    url('../images/cardshape.svg');
          mask-image:
    linear-gradient(#fff, #fff),
    url('../images/cardshape.svg');
  -webkit-mask-size: 100% 100%, var(--reveal-size, 0px);
          mask-size: 100% 100%, var(--reveal-size, 0px);
  -webkit-mask-position: center, center;
          mask-position: center, center;
  -webkit-mask-repeat: no-repeat, no-repeat;
          mask-repeat: no-repeat, no-repeat;
  -webkit-mask-composite: source-out;
          mask-composite: subtract;

  /* The mask cutout rotates with the cover. Default 0deg; CSS transition animates. */
  transform: rotate(var(--reveal-rotation, 0deg));
  transform-origin: 50% 50%;
  will-change: transform, mask-size;

  /* GPU-smooth open: when .is-revealing is toggled by JS, the browser
     interpolates these registered custom properties natively, with a
     single ease-in curve. Replaces the rAF + setProperty loop, which
     was forcing per-frame mask rasterisation and the staggered feel. */
  transition:
    --reveal-size 1.05s cubic-bezier(0.5, 0, 0.85, 0.5),
    --reveal-rotation 1.05s cubic-bezier(0.5, 0, 0.85, 0.5);
}

/* Registered custom properties — required for browsers to interpolate
   the values smoothly via CSS transition. Without these the property
   would just snap at the end. */
@property --reveal-size {
  syntax: '<length>';
  inherits: true;
  initial-value: 0px;
}
@property --reveal-rotation {
  syntax: '<angle>';
  inherits: true;
  initial-value: 0deg;
}

.launch-overlay-cover.is-revealing {
  --reveal-size: 5200px;
  --reveal-rotation: 45deg;
}

@keyframes launch-overlay-hide {
  0%, 99% { visibility: visible; }
  100%    { visibility: hidden; }
}

/* ============================================================
   HEX REVEAL — animation handled inline via SMIL <animate>
   in index.html. Cross-browser CSS `d` animation has gaps;
   SMIL is reliable in Chrome / Firefox / Safari.
   ============================================================ */

/* Lock page scroll while the overlay is up */
body.body-launching {
  overflow: hidden;
}

/* Subsequent-visit skip: prevent any flash of the launch overlay. */
body.skip-launch .launch-overlay { display: none !important; }

/* ============================================================
   Centred content — logo + tagline
   Settle, hold, then stretch horizontally as it fades out.
   ============================================================ */
.launch-content {
  position: relative;
  z-index: 3;
  text-align: center;
  color: #ffffff;
  letter-spacing: -0.005em;
  opacity: 0;
  /* Butter exit, faster — opacity holds near 1 then falls smoothly
     to 0 toward the end, in 0.70s instead of 1.10s. Same curve shape. */
  animation:
    launch-content-settle 1.00s cubic-bezier(0.16, 1, 0.3, 1) 0s    forwards,
    launch-content-exit   0.70s cubic-bezier(0.55, 0, 0.9, 0.4) 2.50s forwards;
  will-change: opacity, transform, letter-spacing, color;
  transform-origin: 50% 50%;
  backface-visibility: hidden;
}

/* Settle — appear and tighten. */
@keyframes launch-content-settle {
  from { opacity: 0; letter-spacing: 0.42em;  transform: scale(1.12); color: rgba(255, 255, 255, 0.35); }
  to   { opacity: 1; letter-spacing: -0.005em; transform: scale(1);    color: #ffffff; }
}

/* Exit — exact reverse of settle. */
@keyframes launch-content-exit {
  from { opacity: 1; letter-spacing: -0.005em; transform: scale(1);    color: #ffffff; }
  to   { opacity: 0; letter-spacing: 0.42em;  transform: scale(1.12); color: rgba(255, 255, 255, 0.35); }
}

/* Logo (image) — BIGGER, filter-inverted to render white on dark forest.
   Uses the SAME two-animation split as .launch-content so the settle
   and exit delays are byte-for-byte identical — they start and end on
   the exact same frame. */
.launch-logo {
  display: block;
  margin: 0 auto clamp(1.5rem, 3vw, 2.5rem);
  width: clamp(380px, 50vw, 720px);  /* much bigger */
  height: auto;
  filter: brightness(0) invert(1) opacity(0);
  transform: scale(1.12);
  overflow: visible;
  animation:
    launch-logo-settle 1.00s cubic-bezier(0.16, 1, 0.3, 1) 0s    forwards,
    launch-logo-exit   0.70s cubic-bezier(0.55, 0, 0.9, 0.4) 2.50s forwards;
  will-change: opacity, transform, filter;
}

@keyframes launch-logo-settle {
  from { filter: brightness(0) invert(1) opacity(0.40); transform: scale(1.12); }
  to   { filter: brightness(0) invert(1) opacity(1);    transform: scale(1);    }
}

@keyframes launch-logo-exit {
  from { filter: brightness(0) invert(1) opacity(1);    transform: scale(1);    }
  to   { filter: brightness(0) invert(1) opacity(0);    transform: scale(1.12); }
}

.launch-tagline {
  font-family: var(--fd);
  font-weight: 400;
  font-style: normal;
  font-size: clamp(1.4rem, 2.6vw, 2.4rem);  /* bigger */
  margin: 0;
  letter-spacing: inherit;
  color: inherit;
}

/* ============================================================
   Orbiting post-it cards — five large cards travelling clockwise
   round the viewport perimeter. Each has its own orbit speed,
   self-spin, and grow/shrink pulse so none of them sync up.

   Composition trick: position is animated via `top` + `left`
   percentages (resolved against the .launch-postits parent which
   is sized to the viewport). Centering on the path point is done
   with `translate: -50% -50%` (standalone CSS property, NOT via
   `transform`). Self-rotation uses `rotate` and the size pulse
   uses `scale` — three separate properties that compose without
   fighting over a single `transform` value.
   ============================================================ */
.launch-postits {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 1;
}

.launch-postit {
  position: absolute;
  display: block;
  width:  var(--w, 380px);
  height: var(--h, 440px);

  /* The card silhouette is drawn by the inline SVG inside (which <use>s
     #card-shape from defs). currentColor flows down to the SVG fill, so
     setting `color` here colours the card. No background, no border-
     radius, no stacked box-shadow — the diagonal cut is part of the
     SVG path itself. */
  color: var(--card-bg, var(--oli-paper));
  background: transparent;

  /* Default position before the orbit keyframes take over */
  top:  -5%;
  left: -5%;

  /* Centre the card on the (top, left) anchor point */
  translate: -50% -50%;

  rotate: 0deg;
  scale: 1;
  opacity: 0;

  animation:
    launch-postit-life  var(--launch-total) ease forwards,
    orbit-cw            var(--orbit-dur, 50s) linear infinite,
    self-spin           var(--spin-dur, 12s)  linear infinite,
    pulse-size          var(--pulse-dur, 6s)  ease-in-out infinite;

  will-change: top, left, rotate, scale, opacity;
}

.launch-postit > svg {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
}

/* Post-it lifecycle: fade in and stay. The cover's growing mask
   hard-cuts each card as the card-shape opens past it — no opacity
   fade-out needed, because the mask physically erases the pixels. */
@keyframes launch-postit-life {
  0%   { opacity: 0; }
  10%  { opacity: 0; }
  45%  { opacity: 1; }
  100% { opacity: 1; }
}

/* Clockwise rectangular orbit AROUND THE PERIMETER. Card centres sit at
   -5% and 105% — outside the viewport — so only ~30% of each card peeks
   into view along whichever edge it's currently traversing. */
@keyframes orbit-cw {
  0%   { top:  -5%; left:  -5%; }   /* off-screen top-left */
  25%  { top:  -5%; left: 105%; }   /* off-screen top-right */
  50%  { top: 105%; left: 105%; }   /* off-screen bottom-right */
  75%  { top: 105%; left:  -5%; }   /* off-screen bottom-left */
  100% { top:  -5%; left:  -5%; }   /* loop back */
}

@keyframes self-spin {
  from { rotate: var(--spin-base, 0deg); }
  to   { rotate: calc(var(--spin-base, 0deg) + 360deg); }
}

@keyframes pulse-size {
  0%, 100% { scale: var(--scale-min, 0.85); }
  50%      { scale: var(--scale-max, 1.15); }
}

/* ============================================================
   Five cards — bigger sizes, varied speeds.
   animation-delay shorthand maps to:
   enter, orbit, spin, pulse
   Negative orbit delays place each card at a different point on
   the path (% along path × orbit-dur), so they start spread out
   round the perimeter and all run clockwise from there.
   ============================================================ */
.launch-postit--1 {
  --card-bg:   var(--oli-bright);
  --card-back: #3a6e22;                       /* darker bright behind */
  --w: clamp(360px, 34vw, 540px);
  --h: clamp(420px, 38vw, 620px);
  --orbit-dur: 40s;
  --spin-dur:  11s;
  --pulse-dur: 5.5s;
  --scale-min: 0.92; --scale-max: 1.18;
  --spin-base: -6deg;
  animation-delay: 0.10s, 0s, 0s, 0s;
}

.launch-postit--2 {
  --card-bg:   var(--oli-paper);
  --card-back: var(--oli-bright);             /* paper on bright — like the logo */
  --w: clamp(300px, 28vw, 460px);
  --h: clamp(340px, 32vw, 510px);
  --orbit-dur: 58s;
  --spin-dur:  17s;
  --pulse-dur: 8s;
  --scale-min: 0.78; --scale-max: 1.08;
  --spin-base: 12deg;
  /* 20% along a 58s orbit = -11.6s */
  animation-delay: 0.22s, -11.6s, -3s, -2s;
}

.launch-postit--3 {
  --card-bg:   var(--oli-bright-soft);
  --card-back: var(--oli-bright);             /* darker than soft = bright */
  --w: clamp(420px, 40vw, 640px);             /* biggest card */
  --h: clamp(480px, 44vw, 700px);
  --orbit-dur: 36s;
  --spin-dur:  9s;
  --pulse-dur: 6s;
  --scale-min: 0.90; --scale-max: 1.25;
  --spin-base: -18deg;
  /* 40% along 36s = -14.4s */
  animation-delay: 0.34s, -14.4s, -1s, -3s;
}

.launch-postit--4 {
  --card-bg:   var(--oli-paper);
  --card-back: var(--oli-bright);
  --w: clamp(260px, 24vw, 380px);             /* smallest card */
  --h: clamp(300px, 28vw, 440px);
  --orbit-dur: 50s;
  --spin-dur:  19s;
  --pulse-dur: 9s;
  --scale-min: 0.70; --scale-max: 1.05;
  --spin-base: 8deg;
  /* 60% along 50s = -30s */
  animation-delay: 0.46s, -30s, -8s, -1s;
}

.launch-postit--5 {
  --card-bg:   var(--oli-bright);
  --card-back: #3a6e22;
  --w: clamp(340px, 31vw, 500px);
  --h: clamp(400px, 36vw, 580px);
  --orbit-dur: 64s;
  --spin-dur:  13s;
  --pulse-dur: 7s;
  --scale-min: 0.85; --scale-max: 1.18;
  --spin-base: -10deg;
  /* 80% along 64s = -51.2s */
  animation-delay: 0.58s, -51.2s, -5s, -4s;
}

@media (prefers-reduced-motion: reduce) {
  /* Static splash: overlay shows briefly (home.js hides it), cards
     and reveal animations stay off */
  .launch-overlay { animation: none; clip-path: none; }
  #hex-reveal-path { animation: none; }
  .launch-content,
  .launch-logo { animation: none; opacity: 1; }
  .launch-postit { animation: none; opacity: 0; }
  body.body-launching { overflow: auto; }
}

@media (max-width: 720px) {
  /* --- Hero video: full-bleed from the start, no scroll growth --- */
  .hero-home {
    min-height: 0;
    padding-bottom: 16px;
  }
  .hero-video {
    --hero-video-scale: 1 !important;
    --hero-video-y: 0px !important;
    max-width: none;
    /* near-bleed: 12px breathing room each side, soft corners */
    width: calc(100% + 2 * clamp(20px, 4vw, 64px) - 24px);
    margin-left: calc(-1 * clamp(20px, 4vw, 64px) + 12px);
    border-radius: 12px;
  }

  /* --- Mission: wraps over two lines, compact, no roaming card --- */
  .mission-section { padding-bottom: clamp(48px, 9vh, 80px); }
  .section-card { display: none !important; }   /* roaming cards: desktop only */
  /* Mission line 2 gets a touch more breathing room on mobile.
     The headline itself sits at the shared 2.2rem mobile size set
     by the unified section-headline scale rule. */
  .mission-section .mission-line--2 { margin-top: 1rem; }

  /* On mobile cards take up too much of the screen, so dim them
     down and drop the largest two. */
  .launch-postit--3,
  .launch-postit--4 { display: none; }
  .launch-postit { opacity: 0.85 !important; }
  .launch-logo { width: clamp(260px, 78vw, 400px); }
  .launch-tagline { font-size: clamp(1.05rem, 4.5vw, 1.5rem); }
}

/* ============================================================
   INTRO SHAPES — legacy in-hero version (now unused after launch
   overlay change). Kept for reference / fallback only.
   ============================================================ */
.intro-shapes {
  position: absolute;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
  z-index: 0;
}

.intro-shape {
  position: absolute;
  display: block;
  /* Initial state — JS not needed; CSS animation handles it */
  opacity: 0;
  scale: 0.35;
  filter: blur(14px);
  /* Two animations stacked: one-shot entrance, then perpetual float.
     They target different properties (scale/filter/opacity vs translate/rotate)
     so they compose cleanly. */
  animation:
    bg-shape-enter 1.5s cubic-bezier(0.34, 1.4, 0.5, 1) 0.05s forwards,
    gl-float-y 9s 1.7s ease-in-out infinite alternate,
    gl-float-r 13s 1.7s ease-in-out infinite alternate;
}

/* Stagger the four corners so they don't all pop at once */
.intro-shape--tl { animation-delay: 0.05s, 1.7s, 1.7s; }
.intro-shape--tr { animation-delay: 0.18s, 1.8s, 1.8s; }
.intro-shape--bl { animation-delay: 0.32s, 1.95s, 1.95s; }
.intro-shape--br { animation-delay: 0.46s, 2.1s, 2.1s; }

@keyframes bg-shape-enter {
  0%   { opacity: 0; scale: 0.35; filter: blur(14px); }
  30%  { opacity: 1; filter: blur(7px); }
  55%  { scale: 1.04; filter: blur(0); }
  100% { opacity: 1; scale: 1; filter: blur(0); }
}

@keyframes gl-float-y {
  0%   { translate: 0 -10px; }
  100% { translate: 0 10px; }
}

@keyframes gl-float-r {
  0%   { rotate: -3deg; }
  100% { rotate: 3deg; }
}

/* Corner positions + sizes */
.intro-shape--tl {
  top: -8%;
  left: -6%;
  width: clamp(220px, 26vw, 360px);
  height: clamp(220px, 26vw, 360px);
}
.intro-shape--tr {
  top: -5%;
  right: -7%;
  width: clamp(180px, 22vw, 300px);
  height: clamp(180px, 22vw, 300px);
}
.intro-shape--bl {
  bottom: -8%;
  left: -4%;
  width: clamp(160px, 20vw, 260px);
  height: clamp(160px, 20vw, 260px);
}
.intro-shape--br {
  bottom: -10%;
  right: -5%;
  width: clamp(180px, 22vw, 300px);
  height: clamp(180px, 22vw, 300px);
}

/* Shape primitives — three forms like labs.google's square/circle/hex,
   but on-brand for Oli (post-it rounded square is the headline shape). */
.shape-square {
  border-radius: 22%;
}
.shape-circle {
  border-radius: 50%;
}
.shape-postit {
  border-radius: 22% 22% 22% 6%;  /* slight tail at bottom-left, post-it style */
}

/* Colour fills */
.shape-bright { background: var(--oli-bright); }
.shape-forest { background: var(--oli-forest); }
.shape-soft   { background: var(--oli-bright-soft); }
.shape-paper  { background: var(--oli-paper); box-shadow: inset 0 0 0 2px rgba(26,73,33,0.06); }

/* Each shape gets its own float amplitude / phase to feel organic.
   The keyframe values are constant; we modulate by setting animation-direction
   and using subtly different cubic translates via custom rotation amps. */
.intro-shape--tl { --gl-amp-y: 18px; }
.intro-shape--tr { --gl-amp-y: 14px; }
.intro-shape--bl { --gl-amp-y: 22px; }
.intro-shape--br { --gl-amp-y: 12px; }

/* Hero content sits above shapes */
.hero-split-inner { position: relative; z-index: 2; }

/* ============================================================
   DELAY hero copy reveal so it lands AFTER the launch overlay clears.
   Launch total ≈ 3.2s. Hero copy starts arriving at ~3.0s so it
   appears as the overlay fades, finishing in sync with the reveal.
   ============================================================ */
/* Hero is fully painted behind the launch overlay before the reveal
   opens — no entrance transition. When the card-shape cuts open, the
   hero is already there waiting. */
.hero-split .reveal-up,
.hero-split .reveal-up.reveal-d-1,
.hero-split .reveal-up.reveal-d-2,
.hero-split .reveal-up.reveal-d-3 {
  opacity: 1;
  transform: none;
  transition: none;
  transition-delay: 0s;
}

/* Hero split-words: also pre-rendered behind the overlay, no stagger. */
.hero-split .split-words .word > span {
  transition: none;
  transition-delay: 0s;
}

@media (prefers-reduced-motion: reduce) {
  .intro-shape {
    animation: none !important;
    opacity: 1 !important;
    scale: 1 !important;
    filter: none !important;
    rotate: 0 !important;
  }
  .hero-split .reveal-up,
  .hero-split .reveal-up.reveal-d-1,
  .hero-split .reveal-up.reveal-d-2,
  .hero-split .reveal-up.reveal-d-3 { transition-delay: 0s !important; }
  .hero-split .split-words .word > span { transition-delay: 0s !important; }
}

@media (max-width: 720px) {
  /* Smaller and pulled into corners more on mobile */
  .intro-shape--tl { width: 180px; height: 180px; }
  .intro-shape--tr { width: 140px; height: 140px; }
  .intro-shape--bl { width: 130px; height: 130px; }
  .intro-shape--br { width: 150px; height: 150px; }
}

/* ============================================================
   SECTION CARDS — decorative brand card silhouettes
   Each <use>s #card-shape (the same vector as the loading-screen
   post-its) and drifts/rotates slowly, anchored partly off-screen
   so only a corner of the card peeks into the section.
   ============================================================ */
.section-card {
  position: absolute;
  display: block;
  pointer-events: none;
  z-index: 0;
  aspect-ratio: 1;
  will-change: transform;
  animation: section-card-drift var(--drift-dur, 28s) ease-in-out infinite alternate;
}

.section-card svg {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
}

/* Slow wander: gentle rotation around a per-card base angle plus a
   small positional drift, mirrored by `alternate` so it never jumps. */
@keyframes section-card-drift {
  0%   { transform: rotate(var(--card-rot, 0deg)) translate3d(0, 0, 0); }
  50%  { transform: rotate(calc(var(--card-rot, 0deg) + 8deg)) translate3d(-2.5%, 3%, 0) scale(1.04); }
  100% { transform: rotate(calc(var(--card-rot, 0deg) - 6deg)) translate3d(2%, -2.5%, 0); }
}

.section-card--bright  { color: var(--oli-bright); opacity: 0.85; }
.section-card--forest  { color: var(--oli-forest); opacity: 0.95; }
.section-card--soft    { color: var(--oli-bright-soft); opacity: 0.85; }
.section-card--paper   { color: var(--oli-paper); opacity: 1; }
.section-card--mist    { color: var(--oli-mist); opacity: 1; }

.section-card--top-r {
  top: -14%;
  right: -11%;
  width: clamp(360px, 42vw, 720px);
  --card-rot: 16deg;
  --drift-dur: 30s;
}
.section-card--bot-l {
  bottom: -18%;
  left: -10%;
  width: clamp(300px, 32vw, 560px);
  --card-rot: -12deg;
  --drift-dur: 38s;
}
.section-card--mission-r {
  top: 8%;
  right: -16%;
  width: clamp(320px, 40vw, 640px);
  --card-rot: 22deg;
  --drift-dur: 42s;
}
.section-card--grad-l {
  top: -10%;
  left: -13%;
  width: clamp(320px, 38vw, 620px);
  --card-rot: -18deg;
  --drift-dur: 34s;
}

@media (prefers-reduced-motion: reduce) {
  .section-card { animation: none; }
}

/* labs.google-style inversion: a white duplicate of key headings,
   clipped to the orbiting card shapes (clip transforms set per frame
   in home.js). Sits exactly over the original text. */
.invert-copy {
  position: absolute;
  inset: 0;
  color: var(--white);
  pointer-events: none;
  user-select: none;
  z-index: 1;
}
.invert-copy,
.invert-copy * {
  color: var(--white) !important;
}

/* The invert-copy clones host.innerHTML verbatim, which means the clone
   also inherits the original's animation-hidden state — mission-sub
   starts at opacity 0 (until JS adds .is-shown on the ORIGINAL), and
   mission-sweep__inner sits off-screen waiting for the scroll sweep.
   Neither flag is ever set on the clone. Force the clone to its
   "settled" presentation so the white text reads under the orbiting
   card on every line, including line 2. */
.invert-copy .mission-sub {
  opacity: 1 !important;
  transform: none !important;
  transition: none !important;
}
/* (No mission-sweep__inner override needed — sweep mechanism removed.) */

/* ============================================================
   "SO WE BUILT OLI" SECTION — intro statement + the Oli deck
   ============================================================ */
.category-section {
  position: relative;
  z-index: 2;
  background: var(--white);
  padding: clamp(96px, 14vh, 180px) 0 clamp(96px, 14vh, 180px);
  /* clip, not hidden — hidden would break the deck's position:sticky */
  overflow: hidden;
  overflow: clip;
}

/* Pre-footer — paper bg */
.pre-footer { background: var(--oli-paper); }

/* ============================================================
   THE OLI DECK — post-it deck scroll story.
   The section pins while you scroll. Note falls and demo slides
   are SCRUBBED: home.js maps scroll progress to each element's
   motion (with exponential damping for a buttery glide) and
   writes transform/opacity inline every frame — so the speed of
   everything follows the speed of your scroll. The active demo's
   internal choreography (--p) replays on a slow timed loop.
   ============================================================ */
.oli-deck {
  position: relative;
  z-index: 2;
  height: 600vh;
}

.deck-sticky {
  position: sticky;
  top: var(--nav-height, 0px);
  height: calc(100vh - var(--nav-height, 0px));
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(2.5rem, 6vw, 6rem);
  max-width: 1320px;
  margin: 0 auto;
  padding: 0 clamp(20px, 4vw, 64px);
  overflow: hidden;   /* notes fall in from above without bleeding */
}

/* ============================================================
   Scroll nudge — small circle with a bobbing down-arrow inside,
   anchored at the bottom of the deck-sticky frame. Fades out
   only when the user is about to leave the deck for the next
   section (driven by the deck's scroll progress in home.js).
   ============================================================ */
.deck-progress {
  position: absolute;
  bottom: clamp(18px, 2.6vh, 36px);
  left: 50%;
  transform: translateX(-50%);
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: rgba(26, 73, 33, 0.06);
  border: 1.5px solid rgba(26, 73, 33, 0.38);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--oli-forest);
  opacity: 0.85;
  z-index: 6;
  pointer-events: none;
  user-select: none;
  transition: opacity 0.4s ease;
}
.deck-progress.is-complete { opacity: 0; }
.deck-progress__arrow {
  display: block;
  width: 18px;
  height: 18px;
  animation: deck-arrow-bob 1.6s ease-in-out infinite;
}
@keyframes deck-arrow-bob {
  0%, 100% { transform: translateY(-3px); }
  50%      { transform: translateY( 3px); }
}
@media (prefers-reduced-motion: reduce) {
  .deck-progress__arrow { animation: none; }
}
@media (max-width: 720px) {
  .deck-progress {
    width: 32px;
    height: 32px;
    bottom: 12px;
    border-width: 1px;
  }
  .deck-progress__arrow {
    width: 14px;
    height: 14px;
  }
}

/* --- The pile of description post-its --- */
.deck-pile {
  position: relative;
  width: min(440px, 38vw);
  aspect-ratio: 1;
  flex: 0 0 auto;
}

.deck-note {
  position: absolute;
  inset: 0;
  /* Start hidden in the sky; home.js scrubs the fall from scroll */
  transform: translateY(-130vh);
  will-change: transform;
}
.deck-note:nth-child(1) { z-index: 1; }
.deck-note:nth-child(2) { z-index: 2; }
.deck-note:nth-child(3) { z-index: 3; }
.deck-note:nth-child(4) { z-index: 4; }
.deck-note:nth-child(5) { z-index: 5; }

.deck-note__shape {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  color: var(--note-bg, var(--oli-paper));
  filter: drop-shadow(0 5px 12px rgba(26, 73, 33, 0.12));
}

.deck-note--paper  { --note-bg: var(--oli-paper);  --note-fg: var(--oli-forest); --note-sub: var(--ink-muted);            --note-kicker: var(--oli-bright); --note-icon-bg: var(--oli-mist);            --note-icon-fg: var(--oli-bright); }
.deck-note--mist   { --note-bg: var(--oli-mist);   --note-fg: var(--oli-forest); --note-sub: var(--ink-muted);            --note-kicker: var(--oli-bright); --note-icon-bg: rgba(255,255,255,0.75);     --note-icon-fg: var(--oli-bright); }
.deck-note--bright { --note-bg: var(--oli-bright); --note-fg: var(--white);      --note-sub: rgba(255,255,255,0.85);      --note-kicker: rgba(255,255,255,0.75); --note-icon-bg: rgba(255,255,255,0.18); --note-icon-fg: var(--white); }
.deck-note--forest { --note-bg: var(--oli-forest); --note-fg: var(--white);      --note-sub: rgba(255,255,255,0.82);      --note-kicker: var(--oli-bright-soft); --note-icon-bg: rgba(255,255,255,0.12); --note-icon-fg: var(--oli-bright-soft); }

/* Icon chip — top-right corner of the note */
.deck-note__icon {
  position: absolute;
  top: 8%;
  right: 8%;
  width: clamp(48px, 4.6vw, 64px);
  aspect-ratio: 1;
  border-radius: 15px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--note-icon-bg, var(--oli-mist));
  color: var(--note-icon-fg, var(--oli-bright));
  z-index: 2;
}
.deck-note__icon svg {
  width: 54%;
  height: 54%;
}

.deck-note__content {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 12% 13% 17% 13%;   /* extra bottom-left room for the cut corner */
  color: var(--note-fg);
}
.deck-note__kicker {
  font-family: var(--fm);
  font-size: clamp(0.74rem, 1.05vw, 0.92rem);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--note-kicker);
  margin: 0 0 0.8rem;
}
.deck-note__title {
  font-family: var(--fd);
  font-weight: 600;
  font-size: clamp(1.4rem, 2.4vw, 2.1rem);
  line-height: 1.08;
  letter-spacing: -0.015em;
  margin: 0 0 0.8rem;
}
.deck-note__sub {
  font-family: var(--fb);
  font-size: clamp(0.85rem, 1.15vw, 1.02rem);
  line-height: 1.5;
  color: var(--note-sub);
  margin: 0 0 1.1rem;
}
.deck-note__cta {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  align-self: flex-start;
  font-family: var(--fb);
  font-size: 0.85rem;
  font-weight: 700;
  text-decoration: none;
  color: var(--note-kicker);
}
.deck-note__cta span { transition: transform 0.2s ease; }
.deck-note__cta:hover span { transform: translateX(4px); }

/* --- The demo stage: app windows swap in from the side --- */
.deck-stage {
  position: relative;
  width: min(600px, 46vw);
  aspect-ratio: 10 / 8.4;
  flex: 0 0 auto;
}

.deck-demo {
  position: absolute;
  inset: 0;
  /* Start parked off-stage; home.js scrubs the slide from scroll */
  opacity: 0;
  transform: translateX(116%);
  will-change: transform, opacity;
  pointer-events: none;
}

.deck-demo .oli-app {
  height: 100%;
  display: flex;
  flex-direction: column;
}
.deck-demo .oli-app__body { flex: 1 1 auto; min-height: 0; }

/* --- Responsive: stack pile above stage --- */
@media (max-width: 940px) {
  .oli-deck { height: 580vh; }
  .deck-sticky {
    flex-direction: column;
    gap: clamp(1.2rem, 4vh, 2.5rem);
    padding-top: 2vh;
  }
  .deck-pile  { width: min(330px, 76vw); height: min(330px, 76vw); }
  .deck-stage { width: min(520px, 92vw); aspect-ratio: 10 / 8.8; }
}

/* ============================================================
   OLI APP WINDOW — mimics the real product chrome: mint canvas,
   white nav bar with the brand card logo, workspace pill.
   ============================================================ */
.oli-app {
  --demo-orange: #e8843c;
  --demo-red:    #d05445;
  --demo-yellow: #e5b53a;
  background: var(--oli-mist);
  border: 1px solid rgba(26, 73, 33, 0.08);
  border-radius: 18px;
  overflow: hidden;
  font-family: var(--fb);
}
.oli-app__bar {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  background: var(--white);
  padding: 8px 12px;
  border-bottom: 1px solid rgba(26, 73, 33, 0.08);
}
.oli-app__logo {
  width: 18px;
  height: 18px;
  display: inline-block;
  flex: 0 0 auto;
}
.oli-app__logo svg { display: block; width: 100%; height: 100%; color: var(--oli-bright); }
.oli-app__name {
  font-size: 0.72rem;
  font-weight: 700;
  color: var(--oli-forest);
}
.oli-app__pill {
  margin-left: auto;
  font-family: var(--fm);
  font-size: 0.54rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  background: var(--oli-mist);
  color: var(--oli-forest);
  border: 1px solid rgba(26, 73, 33, 0.10);
  padding: 3px 9px;
  border-radius: 9999px;
}
.oli-app__body {
  padding: 14px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-height: 296px;
}

/* ============================================================
   SCRUB ENGINE — scroll-linked choreography.
   Every .scrub-* element plays a PAUSED animation with both-fill;
   its delay runs backwards from --p (0→1, set by home.js on the
   card). --at = when the moment happens in the card's scroll
   window, --w = how long it lasts. Stop scrolling → demo freezes.
   ============================================================ */
.scrub-pop, .scrub-grow, .scrub-flash, .scrub-on,
.scrub-out, .scrub-inout, .scrub-float {
  animation-fill-mode: both;
  animation-play-state: paused;
  animation-duration: var(--w, 0.16s);
  animation-timing-function: cubic-bezier(0.34, 1.45, 0.5, 1);
  animation-delay: calc(var(--at, 0s) - var(--p, 0) * 1s);
}
.scrub-pop   { animation-name: scrub-pop; }
.scrub-grow  { animation-name: scrub-grow; animation-duration: var(--w, 0.9s); animation-timing-function: linear; }
.scrub-flash { animation-name: scrub-flash; animation-timing-function: ease; }
.scrub-on    { animation-name: scrub-on; animation-timing-function: ease; }
.scrub-out   { animation-name: scrub-out; animation-timing-function: ease; }
.scrub-inout { animation-name: scrub-inout; animation-timing-function: ease; }
.scrub-float { animation-name: scrub-float; animation-duration: var(--w, 0.14s); animation-timing-function: ease-out; }

@keyframes scrub-pop {
  from { opacity: 0; transform: translateY(16px) scale(0.86); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
@keyframes scrub-grow {
  from { width: 6%; }
  to   { width: 88%; }
}
/* On/off colours are per-element via --off-bg/--on-bg etc. */
@keyframes scrub-flash {
  0%   { background: var(--off-bg, var(--white)); color: var(--off-fg, var(--oli-forest)); transform: scale(1); }
  18%  { background: var(--on-bg, var(--oli-forest)); color: var(--on-fg, var(--white)); transform: scale(1.1); }
  72%  { background: var(--on-bg, var(--oli-forest)); color: var(--on-fg, var(--white)); transform: scale(1.1); }
  100% { background: var(--off-bg, var(--white)); color: var(--off-fg, var(--oli-forest)); transform: scale(1); }
}
@keyframes scrub-on {
  from { opacity: var(--on-from-o, 1); background: var(--off-bg, var(--white)); color: var(--off-fg, var(--oli-forest)); transform: scale(1); }
  to   { opacity: 1; background: var(--on-bg, var(--oli-forest)); color: var(--on-fg, var(--white)); transform: scale(1.05); }
}
@keyframes scrub-out {
  from { opacity: 1; }
  to   { opacity: 0; transform: scale(0.9); visibility: hidden; }
}
@keyframes scrub-inout {
  0%   { opacity: 0; transform: translateY(14px) scale(0.86); }
  18%  { opacity: 1; transform: translateY(0) scale(1); }
  78%  { opacity: 1; transform: translateY(0) scale(1); }
  100% { opacity: 0; transform: translateY(-12px) scale(0.9); }
}
@keyframes scrub-float {
  0%   { opacity: 0; transform: translateY(5px); }
  35%  { opacity: 1; }
  100% { opacity: 0; transform: translateY(-14px); }
}

/* ============================================================
   Demo 01 — guided problem-definition chat
   Green Oli bubbles vs orange user bubbles, like the real app.
   ============================================================ */
.demo-msg {
  display: flex;
  align-items: flex-end;
  gap: 8px;
}
.demo-msg--user { justify-content: flex-end; }
.demo-ava {
  flex: 0 0 26px;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 0.62rem;
  font-weight: 800;
}
.demo-ava--oli { background: var(--oli-forest); padding: 6px; }
.demo-ava--oli svg { display: block; width: 100%; height: 100%; color: var(--oli-bright); }
.demo-ava--user { background: var(--demo-orange); color: var(--white); }
.demo-msg__bubble {
  max-width: 76%;
  font-size: 0.73rem;
  line-height: 1.35;
  padding: 8px 12px;
  border-radius: 14px;
}
.demo-msg--oli .demo-msg__bubble {
  background: rgba(74, 139, 44, 0.16);
  color: var(--oli-forest);
  border-bottom-left-radius: 4px;
}
.demo-msg--user .demo-msg__bubble {
  background: var(--demo-orange);
  color: var(--white);
  border-bottom-right-radius: 4px;
}
.demo-progress {
  margin-top: auto;
  display: flex;
  flex-direction: column;
  gap: 5px;
  padding-top: 8px;
}
.demo-progress__label {
  font-family: var(--fm);
  font-size: 0.5rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--oli-bright);
  text-align: center;
}
.demo-progress__bar {
  height: 5px;
  border-radius: 9999px;
  background: rgba(26, 73, 33, 0.10);
  overflow: hidden;
}
.demo-progress__fill {
  display: block;
  height: 100%;
  border-radius: inherit;
  background: var(--oli-bright);
}

/* Two-phase demos — layers stacked in the same app body; one scrubs
   out as the next scrubs in (chat → produced problem statement) */
.oli-app__body--phases {
  position: relative;
  padding: 0;
}
.demo-phase {
  position: absolute;
  inset: 0;
  padding: 14px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* The produced problem statement (phase 2) — mirrors the real
   screen: forest title bar, action pills, sectioned cards with
   progress dots, follow-up pills and white inset text boxes */
.demo-doc-bar {
  background: var(--oli-forest);
  border-radius: 12px;
  padding: 9px 12px;
  text-align: center;
}
.demo-doc-bar__title {
  font-family: var(--fd);
  font-weight: 700;
  font-size: 0.78rem;
  color: var(--white);
}
.demo-doc-bar__title i {
  font-size: 0.6rem;
  opacity: 0.7;
  margin-left: 3px;
}
.demo-doc-actions {
  display: flex;
  justify-content: center;
  gap: 6px;
}
.demo-doc-act {
  font-family: var(--fm);
  font-size: 0.52rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  padding: 4px 13px;
  border-radius: 9999px;
  background: rgba(26, 73, 33, 0.10);
  color: var(--oli-forest);
}
.demo-doc-act--go {
  background: var(--oli-bright);
  color: var(--white);
}
.demo-doc-cols {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}
.demo-doc-sec {
  background: rgba(255, 255, 255, 0.72);
  border: 1px solid rgba(26, 73, 33, 0.08);
  border-radius: 12px;
  padding: 8px 10px;
  display: flex;
  flex-direction: column;
  gap: 5px;
  box-shadow: 0 2px 8px rgba(26, 73, 33, 0.04);
}
.demo-doc-sec__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.demo-doc-sec__title {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 0.62rem;
  font-weight: 700;
  color: var(--oli-forest);
}
.demo-doc-ico {
  width: 10px;
  height: 10px;
  border-radius: 3px;
  background: rgba(74, 139, 44, 0.22);
  border: 1px solid rgba(74, 139, 44, 0.55);
  flex: 0 0 auto;
}
.demo-doc-dots {
  display: inline-flex;
  gap: 3px;
}
.demo-doc-dots i {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--oli-bright);
}
.demo-doc-dots .demo-doc-dots__off { background: rgba(26, 73, 33, 0.15); }
.demo-doc-box {
  background: var(--white);
  border: 1px solid rgba(26, 73, 33, 0.12);
  border-radius: 8px;
  padding: 6px 8px;
  font-size: 0.54rem;
  line-height: 1.4;
  color: var(--ink-muted);
}
.demo-doc-box b { color: var(--oli-forest); }
.demo-doc-sec__pill {
  flex: 0 0 auto;
  font-family: var(--fm);
  font-size: 0.44rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  padding: 3px 8px;
  border-radius: 9999px;
  background: var(--white);
  border: 1px solid rgba(26, 73, 33, 0.14);
  color: var(--oli-forest);
}

/* ============================================================
   Demo 02 — Prototype Lab: stage stepper + feature build list
   ============================================================ */
.demo-steps {
  display: flex;
  gap: 4px;
  flex-wrap: wrap;
  background: var(--white);
  border: 1px solid rgba(26, 73, 33, 0.08);
  border-radius: 9999px;
  padding: 4px;
  align-self: flex-start;
}
.demo-step {
  font-family: var(--fm);
  font-size: 0.55rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  padding: 4px 10px;
  border-radius: 9999px;
  background: var(--white);
  color: var(--oli-forest);
}
.demo-label {
  font-family: var(--fm);
  font-size: 0.52rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--ink-faint);
  margin: 6px 0 0;
}
.demo-feature {
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--white);
  border: 1px solid rgba(26, 73, 33, 0.08);
  border-radius: 10px;
  padding: 8px 10px;
  box-shadow: 0 2px 6px rgba(26, 73, 33, 0.05);
}
.demo-feature__num {
  flex: 0 0 18px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--oli-bright);
  color: var(--white);
  font-family: var(--fm);
  font-size: 0.56rem;
  font-weight: 800;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.demo-feature__name {
  font-size: 0.7rem;
  font-weight: 600;
  color: var(--oli-forest);
}
.demo-slot { display: grid; }
.demo-slot > * { grid-area: 1 / 1; }
.demo-drop {
  border: 1.5px dashed rgba(74, 139, 44, 0.55);
  color: var(--oli-bright);
  border-radius: 10px;
  padding: 8px;
  text-align: center;
  font-family: var(--fm);
  font-size: 0.54rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.demo-btn {
  align-self: flex-end;
  margin-top: auto;
  font-size: 0.66rem;
  font-weight: 700;
  padding: 7px 14px;
  border-radius: 9999px;
  --off-bg: rgba(26, 73, 33, 0.10);
  --off-fg: var(--oli-forest);
}

/* ============================================================
   Demo 03 — generated prototype: alert dashboard with severity
   ============================================================ */
.oli-demo-proto .demo-dash-head {
  background: var(--oli-forest);
  padding: 12px 16px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.demo-dash-head__title {
  font-family: var(--fd);
  font-weight: 700;
  font-size: 0.95rem;
  color: var(--white);
}
.demo-dash-head__sub {
  font-size: 0.6rem;
  color: rgba(255, 255, 255, 0.75);
}
.demo-filters {
  display: flex;
  gap: 5px;
  flex-wrap: wrap;
}
.demo-filter {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 0.58rem;
  font-weight: 700;
  background: var(--white);
  color: var(--oli-forest);
  border: 1px solid rgba(26, 73, 33, 0.10);
  padding: 4px 10px;
  border-radius: 9999px;
}
.demo-filter--active {
  background: var(--oli-forest);
  color: var(--white);
  border-color: var(--oli-forest);
}
.demo-sev-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  display: inline-block;
}
.demo-sev-dot--crit { background: var(--demo-red); }
.demo-sev-dot--high { background: var(--demo-orange); }
.demo-sev-dot--med  { background: var(--demo-yellow); }
.demo-alert {
  background: var(--white);
  border: 1px solid rgba(26, 73, 33, 0.08);
  border-radius: 12px;
  padding: 10px 12px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  box-shadow: 0 2px 8px rgba(26, 73, 33, 0.05);
}
.demo-alert__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.demo-alert__title {
  font-size: 0.73rem;
  font-weight: 700;
  color: var(--oli-forest);
}
.demo-sev {
  font-family: var(--fm);
  font-size: 0.48rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 3px 8px;
  border-radius: 9999px;
  color: var(--white);
  flex: 0 0 auto;
}
.demo-sev--crit { background: var(--demo-red); }
.demo-sev--high { background: var(--demo-orange); }
.demo-alert__meta {
  font-size: 0.58rem;
  color: var(--ink-faint);
}
.demo-alert__action {
  font-size: 0.62rem;
  font-weight: 700;
  color: var(--oli-bright);
  background: rgba(74, 139, 44, 0.12);
  border-radius: 7px;
  padding: 5px 8px;
}
.demo-toast {
  display: flex;
  align-items: center;
  gap: 7px;
  margin-top: auto;
  align-self: flex-start;
  background: var(--oli-forest);
  color: var(--white);
  font-size: 0.65rem;
  font-weight: 700;
  padding: 8px 12px;
  border-radius: 10px;
  box-shadow: 0 8px 20px rgba(26, 73, 33, 0.25);
}
.demo-toast__tick {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--oli-bright);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 0.58rem;
}

/* ============================================================
   Demo 04 — Ideas Board: approved ideas collecting votes
   ============================================================ */
.demo-ideas-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  flex: 1;
}
.demo-idea {
  position: relative;
  background: var(--white);
  border: 1px solid rgba(26, 73, 33, 0.08);
  border-radius: 12px;
  padding: 8px;
  display: flex;
  flex-direction: column;
  gap: 5px;
  box-shadow: 0 2px 6px rgba(26, 73, 33, 0.05);
}

.demo-approved {
  align-self: flex-start;
  font-family: var(--fm);
  font-size: 0.46rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  background: rgba(74, 139, 44, 0.15);
  color: var(--oli-bright);
  padding: 2px 7px;
  border-radius: 9999px;
}
.demo-idea__title {
  font-size: 0.66rem;
  font-weight: 700;
  color: var(--oli-forest);
  line-height: 1.25;
}
.demo-idea__votes {
  position: relative;
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 0.62rem;
  font-weight: 600;
  color: var(--ink-muted);
  margin-top: auto;
}
.demo-idea__votes i {
  font-style: normal;
  color: var(--demo-orange);
}
.demo-plus {
  position: absolute;
  left: 34px;
  top: 0;
  color: var(--oli-bright);
  font-weight: 800;
  font-size: 0.62rem;
}

/* ============================================================
   Demo 05 — Pipeline board: one idea travels the kanban
   ============================================================ */
.demo-board {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
  flex: 1;
}
.demo-col {
  background: rgba(255, 255, 255, 0.55);
  border: 1px solid rgba(26, 73, 33, 0.06);
  border-radius: 12px;
  padding: 8px;
  display: flex;
  flex-direction: column;
  gap: 7px;
}
.demo-col__head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 4px;
  font-family: var(--fm);
  font-size: 0.46rem;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--oli-forest);
}
.demo-col__head b {
  background: var(--oli-mist);
  border-radius: 9999px;
  padding: 1px 6px;
  font-size: 0.46rem;
}
.demo-ghost {
  height: 30px;
  border-radius: 8px;
  background: rgba(26, 73, 33, 0.05);
  flex: 0 0 auto;
}
.demo-ghost--short { height: 20px; }
.demo-pipecard {
  background: var(--white);
  border: 1px solid rgba(74, 139, 44, 0.40);
  border-radius: 10px;
  padding: 8px;
  display: flex;
  flex-direction: column;
  gap: 5px;
  box-shadow: 0 3px 10px rgba(26, 73, 33, 0.10);
}
.demo-pipecard__title {
  font-size: 0.6rem;
  font-weight: 700;
  color: var(--oli-forest);
  line-height: 1.2;
}
.demo-tag {
  align-self: flex-start;
  font-family: var(--fm);
  font-size: 0.44rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  background: var(--oli-mist);
  color: var(--oli-forest);
  padding: 2px 6px;
  border-radius: 9999px;
}
.demo-tag--backed {
  --off-bg: var(--oli-mist);
  --off-fg: var(--oli-forest);
  --on-bg: var(--oli-bright);
  --on-fg: var(--white);
  --on-from-o: 0;
}

/* Static (pre-populated) pipeline cards sit quieter than the live one */
.demo-pipecard {
  border-color: rgba(26, 73, 33, 0.10);
  box-shadow: 0 2px 6px rgba(26, 73, 33, 0.06);
}
.demo-pipecard--live {
  border-color: rgba(74, 139, 44, 0.55);
  box-shadow: 0 3px 12px rgba(26, 73, 33, 0.14);
}

/* ============================================================
   Prototype Lab phases - Ideate / Design / Style / Summary
   ============================================================ */
.demo-step--done {
  background: var(--oli-mist);
  color: var(--oli-bright);
}
.demo-steps--lab {
  position: relative;
  z-index: 2;
  margin: 14px 14px 0;
}
.demo-phase--lab {
  top: 44px;   /* below the stepper */
}

/* Ideate: idea cards to pick from */
.demo-ideacard {
  background: var(--white);
  border: 1px solid rgba(26, 73, 33, 0.10);
  border-radius: 12px;
  padding: 10px 12px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  box-shadow: 0 2px 8px rgba(26, 73, 33, 0.05);
}
.demo-ideacard__top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
}
.demo-ideacard__title {
  font-size: 0.7rem;
  font-weight: 700;
  color: var(--oli-forest);
  line-height: 1.25;
}
.demo-ideacard__meta {
  flex: 0 0 auto;
  font-family: var(--fm);
  font-size: 0.5rem;
  font-weight: 700;
  color: var(--ink-faint);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.demo-ideacard__meta b { color: var(--oli-bright); }
.demo-ideacard__meta .demo-meta-low { color: var(--demo-orange); }
.demo-ideacard__meta .demo-meta-med { color: var(--demo-yellow); }
.demo-ideacard__tags {
  display: flex;
  gap: 4px;
  flex-wrap: wrap;
}
.demo-ideacard__tags i {
  font-family: var(--fm);
  font-size: 0.46rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  background: rgba(74, 139, 44, 0.14);
  color: var(--oli-bright);
  padding: 2px 7px;
  border-radius: 9999px;
}
.demo-ideacard__btn {
  align-self: flex-end;
  font-size: 0.58rem;
  font-weight: 700;
  padding: 5px 11px;
  border-radius: 9999px;
  --off-bg: rgba(26, 73, 33, 0.08);
  --off-fg: var(--oli-forest);
}

/* Design: available features left, chosen right */
.demo-design {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  flex: 1;
}
.demo-design__col {
  background: var(--white);
  border: 1px solid rgba(26, 73, 33, 0.08);
  border-radius: 12px;
  padding: 8px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.demo-design__col--proto {
  background: rgba(255, 255, 255, 0.55);
  border-style: dashed;
  border-color: rgba(74, 139, 44, 0.40);
}
.demo-design__head {
  font-family: var(--fm);
  font-size: 0.48rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--oli-forest);
  margin-bottom: 2px;
}
.demo-pickrow {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.58rem;
  font-weight: 600;
  color: var(--oli-forest);
  background: var(--oli-mist);
  border-radius: 8px;
  padding: 6px 8px;
  line-height: 1.2;
}
.demo-pickrow--chosen {
  background: var(--white);
  border: 1px solid rgba(74, 139, 44, 0.35);
  box-shadow: 0 2px 6px rgba(26, 73, 33, 0.07);
}
.demo-pickrow b {
  flex: 0 0 15px;
  width: 15px;
  height: 15px;
  border-radius: 50%;
  background: var(--oli-bright);
  color: var(--white);
  font-family: var(--fm);
  font-size: 0.48rem;
  font-weight: 800;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* Style: look & feel options */
.demo-stylebox {
  background: var(--white);
  border: 1px solid rgba(26, 73, 33, 0.08);
  border-radius: 12px;
  padding: 9px 12px;
  display: flex;
  flex-direction: column;
  gap: 7px;
  box-shadow: 0 2px 8px rgba(26, 73, 33, 0.05);
}
.demo-stylebox__head {
  font-family: var(--fm);
  font-size: 0.48rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.demo-swatches {
  display: flex;
  gap: 7px;
}
.demo-swatch {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  display: inline-block;
}
.demo-swatch--sel {
  box-shadow: 0 0 0 2px var(--white), 0 0 0 4px var(--oli-bright);
}
.demo-stylepills {
  display: flex;
  gap: 5px;
  flex-wrap: wrap;
}
.demo-stylepill {
  font-size: 0.56rem;
  font-weight: 700;
  color: var(--oli-forest);
  background: rgba(26, 73, 33, 0.07);
  padding: 4px 10px;
  border-radius: 9999px;
}
.demo-stylepill--sel {
  background: var(--oli-forest);
  color: var(--white);
}

/* Summary: ready to generate */
.demo-sumrow {
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--white);
  border: 1px solid rgba(26, 73, 33, 0.08);
  border-radius: 10px;
  padding: 8px 10px;
  font-size: 0.64rem;
  font-weight: 600;
  color: var(--oli-forest);
}
.demo-sumrow i {
  flex: 0 0 16px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--oli-bright);
  color: var(--white);
  font-size: 0.52rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* ============================================================
   Prototype generation overlay - covers the dashboard, fades away
   ============================================================ */
.oli-app__body--layered { position: relative; }
.demo-gen {
  position: absolute;
  inset: 0;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(230, 239, 222, 0.88);
  backdrop-filter: blur(3px);
}
.demo-gen__card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  background: var(--white);
  border: 1px solid rgba(26, 73, 33, 0.10);
  border-radius: 16px;
  padding: 18px 26px;
  box-shadow: 0 16px 40px rgba(26, 73, 33, 0.18);
}
.demo-gen__logo {
  width: 30px;
  height: 30px;
  animation: demo-gen-spin 2.4s ease-in-out infinite;
}
.demo-gen__logo svg {
  display: block;
  width: 100%;
  height: 100%;
  color: var(--oli-bright);
}
@keyframes demo-gen-spin {
  0%   { transform: rotate(0deg) scale(1); }
  50%  { transform: rotate(180deg) scale(0.85); }
  100% { transform: rotate(360deg) scale(1); }
}
.demo-gen__card b {
  font-size: 0.74rem;
  font-weight: 700;
  color: var(--oli-forest);
}
.demo-gen__bar {
  width: 150px;
  height: 5px;
  border-radius: 9999px;
  background: rgba(26, 73, 33, 0.10);
  overflow: hidden;
}
.demo-gen__bar i {
  display: block;
  height: 100%;
  border-radius: inherit;
  background: var(--oli-bright);
}
.demo-gen__hint {
  font-size: 0.56rem;
  color: var(--ink-faint);
}

/* ============================================================
   Generated app — sidebar + KPI cards + status + activity table
   (detail level mirrors the product-page dash mockup)
   ============================================================ */
.oli-app__body--split {
  flex-direction: row;
  gap: 10px;
}
.demo-side {
  flex: 0 0 96px;
  background: var(--white);
  border: 1px solid rgba(26, 73, 33, 0.08);
  border-radius: 10px;
  padding: 8px 7px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.demo-side__label {
  font-family: var(--fm);
  font-size: 0.42rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin: 3px 0 1px 4px;
}
.demo-side__item {
  font-size: 0.54rem;
  font-weight: 600;
  color: var(--ink-muted);
  padding: 4px 6px;
  border-radius: 6px;
  line-height: 1.2;
}
.demo-side__item--active {
  background: var(--oli-mist);
  color: var(--oli-forest);
  font-weight: 700;
}
.demo-side__btn {
  margin-top: auto;
  text-align: center;
  font-size: 0.52rem;
  font-weight: 700;
  color: var(--white);
  background: var(--oli-bright);
  border-radius: 9999px;
  padding: 4px 6px;
}
.demo-main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
  position: relative;
}
.demo-kpis {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 6px;
}
.demo-kpi {
  background: var(--white);
  border: 1px solid rgba(26, 73, 33, 0.08);
  border-radius: 10px;
  padding: 7px 8px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  box-shadow: 0 2px 6px rgba(26, 73, 33, 0.05);
}
.demo-kpi b {
  font-family: var(--fd);
  font-weight: 700;
  font-size: 0.95rem;
  letter-spacing: -0.02em;
  color: var(--oli-forest);
  line-height: 1;
}
.demo-kpi b small {
  font-size: 0.5rem;
  font-weight: 600;
  margin-left: 1px;
}
.demo-kpi span {
  font-size: 0.48rem;
  font-weight: 700;
  color: var(--oli-forest);
}
.demo-kpi em {
  font-size: 0.44rem;
  color: var(--ink-faint);
}
.demo-kpi u {
  display: block;
  height: 3px;
  border-radius: 9999px;
  background: rgba(26, 73, 33, 0.10);
  overflow: hidden;
  text-decoration: none;
  margin-top: 2px;
}
.demo-kpi u i {
  display: block;
  height: 100%;
  background: var(--oli-bright);
  border-radius: inherit;
}
.demo-statuspanel {
  background: var(--white);
  border: 1px solid rgba(26, 73, 33, 0.08);
  border-radius: 10px;
  padding: 7px 9px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.demo-statuspanel__title,
.demo-table__title {
  font-family: var(--fm);
  font-size: 0.46rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.demo-statusrow {
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 0.56rem;
  font-weight: 600;
  color: var(--oli-forest);
}
.demo-statusrow b {
  margin-left: auto;
  font-size: 0.58rem;
  font-weight: 800;
}
.demo-table {
  background: var(--white);
  border: 1px solid rgba(26, 73, 33, 0.08);
  border-radius: 10px;
  padding: 7px 9px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.demo-trow {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.52rem;
  padding: 3px 0;
  border-top: 1px solid rgba(26, 73, 33, 0.06);
}
.demo-trow b { font-weight: 700; color: var(--oli-forest); flex: 1; }
.demo-trow i { color: var(--ink-faint); }
.demo-tpill {
  text-decoration: none;
  font-family: var(--fm);
  font-size: 0.42rem;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 2px 6px;
  border-radius: 9999px;
  background: rgba(74, 139, 44, 0.15);
  color: var(--oli-bright);
}
.demo-tpill--warn {
  background: rgba(229, 181, 58, 0.18);
  color: #9a7a1c;
}
.demo-toast--float {
  position: absolute;
  bottom: 4px;
  right: 4px;
  z-index: 2;
}

/* Rich summary rows: label + populated description */
.demo-sumrow--rich { align-items: flex-start; }
.demo-sumrow--rich i { margin-top: 1px; }
.demo-sumrow__txt {
  display: flex;
  flex-direction: column;
  gap: 1px;
  font-size: 0.58rem;
  font-weight: 500;
  color: var(--ink-muted);
  line-height: 1.35;
}
.demo-sumrow__txt b {
  font-size: 0.62rem;
  font-weight: 700;
  color: var(--oli-forest);
}

/* Idea-card description line (Ideate phase) */
.demo-ideacard__line {
  font-size: 0.56rem;
  line-height: 1.35;
  color: var(--ink-muted);
}

/* Author / time metas */
.demo-pipecard__meta,
.demo-idea__meta {
  font-size: 0.5rem;
  color: var(--ink-faint);
}

/* ============================================================
   Ideas board prototype thumbnails - mini app windows, below title
   ============================================================ */
.demo-thumb {
  position: relative;
  display: block;
  height: 56px;
  border-radius: 8px;
  background: var(--oli-mist);
  border: 1px solid rgba(26, 73, 33, 0.10);
  overflow: hidden;
}
.demo-thumb::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 10px;
  background: var(--oli-forest);
}
.demo-thumb__body {
  position: absolute;
  inset: 14px 6px 5px;
  display: flex;
  gap: 4px;
}
/* dashboard: stat chips + bar chart */
.demo-thumb--dash .demo-thumb__body { flex-direction: column; }
.demo-thumb__stat {
  height: 7px;
  width: 42%;
  border-radius: 3px;
  background: var(--oli-bright);
}
.demo-thumb__stat--alt { width: 30%; background: var(--demo-orange); }
.demo-thumb__bars {
  flex: 1;
  display: flex;
  align-items: flex-end;
  gap: 4px;
}
.demo-thumb__bars i {
  flex: 1;
  border-radius: 2px 2px 0 0;
  background: var(--oli-bright-soft);
}
.demo-thumb__bars i:nth-child(even) { background: var(--oli-bright); }
/* table: rows with status dots */
.demo-thumb--table .demo-thumb__body { flex-direction: column; }
.demo-thumb__row {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 4px;
  background: var(--white);
  border-radius: 3px;
  padding: 0 5px;
}
.demo-thumb__row i {
  display: block;
  height: 4px;
  width: 60%;
  border-radius: 2px;
  background: rgba(26, 73, 33, 0.18);
}
.demo-thumb__dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
}
.demo-thumb__dot--ok   { background: var(--oli-bright); }
.demo-thumb__dot--warn { background: var(--demo-orange); }
/* board: mini kanban columns */
.demo-thumb__minicol {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 3px;
  background: var(--white);
  border-radius: 3px;
  padding: 3px;
}
.demo-thumb__minicol i {
  display: block;
  height: 9px;
  border-radius: 2px;
  background: rgba(26, 73, 33, 0.14);
}
.demo-thumb__minicol--accent i { background: var(--oli-bright-soft); }
/* form: fields + submit button */
.demo-thumb--form .demo-thumb__body { flex-direction: column; }
.demo-thumb__field {
  display: block;
  height: 9px;
  border-radius: 3px;
  background: var(--white);
  border: 1px solid rgba(26, 73, 33, 0.14);
}
.demo-thumb__field--short { width: 65%; }
.demo-thumb__btn {
  display: block;
  height: 9px;
  width: 40%;
  border-radius: 3px;
  background: var(--oli-bright);
  margin-top: auto;
}


/* ============================================================
   MISSION block — big bold copy with highlight words (Problem section)
   Background: paper (#fbf8f1) — slightly lighter than hero cream
   ============================================================ */
.mission-section {
  position: relative;
  z-index: 2;
  background: var(--oli-cream);   /* continuous with the hero */
  /* No top padding — line 1 sits right under the video. */
  padding: clamp(48px, 7vh, 96px) clamp(24px, 6vw, 96px) clamp(96px, 14vh, 180px);
  overflow-x: clip;
  overflow-y: visible;
  text-align: center;
}
.mission-section .mission-line--1 .mission-sweep__inner {
  color: var(--oli-forest);     /* darker brand green base */
}
.mission-section .mission-emph {
  color: var(--oli-bright);     /* "9 in 10" lighter brand green, only emph is bold */
  font-weight: 700;
}

.mission-eyebrow {
  position: relative;
  z-index: 2;
  font-family: var(--fm);
  font-size: 0.74rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--oli-forest);
  margin: 0 0 1.5rem;
}

.mission-headline {
  position: relative;
  z-index: 2;
  font-family: var(--fd);
  font-weight: 400;
  font-size: clamp(2rem, 4.2vw, 3.6rem);
  line-height: 1.12;
  letter-spacing: -0.015em;
  color: var(--oli-forest);
  margin: 0 auto 1.5rem;
  max-width: 1100px;
}

.mission-headline em {
  font-style: normal;
  color: var(--oli-bright);
  font-weight: 400;
}

/* Two-line problem framing: each line lays out as its own block so the
   reveal transforms (slide from left, slide up) read cleanly. */
.mission-line {
  display: block;
}
.mission-line--2 {
  margin-top: 1.4em;     /* larger gap below line 1 */
  /* Reveals are handled per-sub-line below so the two halves come
     in at different scroll points. */
}

/* Line 2 is now plain text — no entrance animation. */
.mission-sub {
  display: block;
}

/* Mission line 1 is now plain centred text — the scroll-driven
   horizontal sweep was removed because it made the original and
   the invert-copy clone fall out of alignment mid-transition. */

.mission-body {
  position: relative;
  z-index: 2;
  font-family: var(--fb);
  font-size: clamp(1.05rem, 1.4vw, 1.25rem);
  line-height: 1.6;
  color: var(--ink-muted);
  margin: 1.5rem auto 0;
  max-width: 780px;
}

/* ============================================================
   "So we built Oli" — intro block above the carousel
   ============================================================ */
.oli-intro {
  position: relative;
  z-index: 2;
  max-width: 1240px;
  margin: 0 auto clamp(3rem, 6vw, 5rem);
  padding: 0 clamp(20px, 4vw, 64px);
  text-align: left;
}

/* Two columns: title + statement copy left, workshop photo right */
.oli-intro__grid {
  display: grid;
  grid-template-columns: 1.12fr 0.88fr;
  gap: clamp(2rem, 5vw, 5rem);
  align-items: center;
}

.oli-intro__photo {
  margin: 0;
}
.oli-intro__photo img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1;              /* square -- keeps the silhouette true */
  object-fit: cover;
  clip-path: url(#card-clip);   /* the brand card silhouette */
  filter: drop-shadow(0 18px 40px rgba(26, 73, 33, 0.22));
}

/* Entrance: slides in from the right and settles with the post-it
   bounce (overrides the generic .reveal-up states) */
.oli-intro__photo.reveal-up {
  opacity: 0;
  transform: translate(110px, 24px) rotate(10deg) scale(0.94);
  transition:
    opacity 0.55s ease,
    transform 1s var(--postit-ease);
}
.oli-intro__photo.reveal-up.in-view {
  opacity: 1;
  transform: translate(0, 0) rotate(2.5deg) scale(1);
}

@media (max-width: 880px) {
  .oli-intro__grid { grid-template-columns: 1fr; }
  .oli-intro__photo {
    max-width: 420px;
    margin: 0.5rem auto 0;
  }
}

.oli-intro__eyebrow {
  font-family: var(--fm);
  font-size: 0.74rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--oli-bright);
  margin: 0 0 1.25rem;
}

.oli-intro__title {
  font-family: var(--fd);
  font-weight: 400;
  font-size: clamp(2.4rem, 5.4vw, 4.4rem);
  line-height: 1.05;
  letter-spacing: -0.025em;
  color: var(--oli-forest);
  margin: 0 0 2rem;
}

.oli-intro__title em {
  font-style: normal;   /* brand green, no italics */
  color: var(--oli-bright);
  font-weight: 400;
}
.oli-intro__title em strong {
  font-weight: 700;     /* bold "Oli" */
}

/* ============================================================
   SECTION HEADLINE SCALE — single shared size + line-height +
   letter-spacing across every major section header, so the page
   reads as one consistent typographic system on desktop and on
   mobile. Each heading still keeps its own colour / margin /
   strong emphasis from its specific rule above.
   ============================================================ */
.hero-home-headline,
.mission-headline,
.oli-intro__title,
.pipeline-sec__title,
.service-sec__title,
.stats-band-headline {
  font-size: clamp(2.2rem, 4.8vw, 3.8rem);
  line-height: 1.08;
  letter-spacing: -0.02em;
}
@media (max-width: 720px) {
  .hero-home-headline,
  .mission-headline,
  .oli-intro__title,
  .pipeline-sec__title,
  .service-sec__title,
  .stats-band-headline {
    font-size: 2.2rem;        /* identical on every mobile section */
  }
}

/* Statement copy — Apple-style scroll fill. home.js splits each
   paragraph into .fill-w word spans and drives --copy-p (0→1) from
   scroll position; each word lights up as the scrub passes its
   --ws threshold. Stop scrolling and the fill stops with you. */
.oli-intro__copy {
  max-width: 680px;
  margin: 0;
  text-align: left;
}

.oli-intro__body {
  font-family: var(--fd);
  font-size: clamp(1.2rem, 1.9vw, 1.7rem);
  line-height: 1.45;
  font-weight: 500;
  letter-spacing: -0.01em;
  color: var(--oli-forest);
  margin: 0 0 1.4rem;
}

.oli-intro__body em {
  font-style: normal;
  color: var(--oli-bright);
}

.fill-w {
  opacity: calc(0.12 + 0.88 * clamp(0, (var(--copy-p, 0) - var(--ws, 0)) * 9, 1));
}

@media (prefers-reduced-motion: reduce) {
  .fill-w { opacity: 1 !important; }
}

/* ============================================================
   GRADUATION — "From idea to outcome" pinned heading
   labs.google .graduation pattern
   ============================================================ */
.graduation {
  position: relative;
  z-index: 2;
  background: var(--oli-cream);
  padding: clamp(96px, 14vh, 180px) 0 clamp(96px, 14vh, 180px);
  overflow: hidden;
}

.graduation__heading {
  max-width: 980px;
  margin: 0 auto clamp(3rem, 6vw, 5rem);
  padding: 0 clamp(20px, 4vw, 64px);
  text-align: center;
  position: relative;
  z-index: 2;
}

.graduation__title {
  font-family: var(--fd);
  font-weight: 400;
  font-size: clamp(2.4rem, 6vw, 4.6rem);
  line-height: 1.04;
  letter-spacing: -0.025em;
  color: var(--oli-forest);
  margin: 0 0 1.5rem;
}

.graduation__title em {
  font-style: normal;
  color: var(--oli-bright);
}

.graduation__sub {
  font-family: var(--fb);
  font-size: clamp(1rem, 1.25vw, 1.15rem);
  line-height: 1.55;
  color: var(--ink-muted);
  margin: 0 auto;
  max-width: 680px;
}

.graduation__cards {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(1rem, 1.8vw, 1.8rem);
  max-width: 1500px;
  margin: 0 auto;
  padding: 0 clamp(20px, 4vw, 64px);
  position: relative;
  z-index: 2;
}

.grad-card {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: 1.5rem 1.4rem 1.6rem;
  border-radius: 22px;
  background: var(--gc-bg, var(--oli-paper));
  color: var(--gc-fg, var(--oli-forest));
  box-shadow:
    0 3px 8px rgba(26, 73, 33, 0.06),
    0 14px 28px rgba(26, 73, 33, 0.10),
    0 28px 60px rgba(26, 73, 33, 0.08);
  min-height: 360px;
}

.grad-card--paper  { --gc-bg: var(--oli-paper);  --gc-fg: var(--oli-forest); }
.grad-card--bright { --gc-bg: var(--oli-bright); --gc-fg: var(--white); }
.grad-card--forest { --gc-bg: var(--oli-forest); --gc-fg: var(--white); }

.grad-card__chips {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 1rem;
  flex-wrap: wrap;
}
.grad-card__chip {
  font-family: var(--fm);
  font-size: 0.6rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 5px 11px;
  border-radius: 9999px;
  background: rgba(0,0,0,0.06);
  font-weight: 700;
}
.grad-card--bright .grad-card__chip,
.grad-card--forest .grad-card__chip { background: rgba(255,255,255,0.18); }
.grad-card__chip--solid {
  background: var(--oli-forest);
  color: var(--white);
}
.grad-card--forest .grad-card__chip--solid {
  background: var(--oli-bright);
  color: var(--white);
}
.grad-card--bright .grad-card__chip--solid {
  background: var(--white);
  color: var(--oli-forest);
}
.grad-card__arrow {
  font-family: var(--fb);
  font-weight: 700;
  font-size: 0.9rem;
  opacity: 0.7;
}

.grad-card__visual {
  background: rgba(0,0,0,0.04);
  border-radius: 14px;
  padding: 1rem;
  margin-bottom: 1.2rem;
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 140px;
}
.grad-card--bright .grad-card__visual,
.grad-card--forest .grad-card__visual { background: rgba(255,255,255,0.10); }

.grad-card__mock--workshop {
  position: relative;
  width: 100%;
  height: 120px;
}
.grad-card__sticker {
  position: absolute;
  font-family: var(--fb);
  font-size: 0.7rem;
  font-weight: 700;
  padding: 8px 12px;
  background: var(--white);
  color: var(--oli-forest);
  border-radius: 6px;
  box-shadow: 0 4px 10px rgba(26,73,33,0.18);
}
.grad-card__sticker--1 { top: 4px; left: 8px;  transform: rotate(-6deg); background: var(--oli-mist); }
.grad-card__sticker--2 { top: 28px; left: 80px; transform: rotate(4deg); background: var(--oli-bright-soft); color: var(--white); }
.grad-card__sticker--3 { top: 56px; left: 32px; transform: rotate(-3deg); background: var(--oli-paper); }

.grad-card__mock--proto {
  display: flex;
  flex-direction: column;
  gap: 8px;
  width: 100%;
  align-items: stretch;
}
.grad-card__hero-line {
  height: 10px;
  background: rgba(255,255,255,0.25);
  border-radius: 6px;
}
.grad-card__hero-line--short { width: 60%; }
.grad-card__hero-cta {
  align-self: flex-start;
  margin-top: 0.5rem;
  padding: 6px 14px;
  border-radius: 9999px;
  background: var(--oli-bright);
  color: var(--white);
  font-family: var(--fb);
  font-weight: 700;
  font-size: 0.7rem;
}

.grad-card__mock--pilot {
  display: flex;
  flex-direction: column;
  gap: 6px;
  width: 100%;
}
.grad-card__stage-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--fb);
  font-size: 0.78rem;
  color: var(--oli-forest);
  padding: 6px 8px;
  border-radius: 8px;
  background: rgba(0,0,0,0.04);
}
.grad-card__stage-row--active {
  background: var(--oli-bright);
  color: var(--white);
}
.grad-card__dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: rgba(26,73,33,0.25);
}
.grad-card__dot--green { background: var(--white); }
.grad-card__dot--soft  { background: var(--oli-bright-soft); }

.grad-card__mock--outcome {
  text-align: center;
}
.grad-card__big {
  font-family: var(--fd);
  font-weight: 700;
  font-size: 3rem;
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--white);
}
.grad-card__small {
  font-family: var(--fb);
  font-size: 0.78rem;
  margin-top: 0.4rem;
  opacity: 0.86;
}

.grad-card__title {
  font-family: var(--fd);
  font-weight: 600;
  font-size: 1.18rem;
  line-height: 1.2;
  letter-spacing: -0.01em;
  margin: 0 0 0.85rem;
}

.grad-card__cta {
  align-self: flex-start;
  font-family: var(--fb);
  font-size: 0.85rem;
  font-weight: 700;
  text-decoration: none;
  color: inherit;
  border-bottom: 1.5px solid currentColor;
  padding-bottom: 2px;
}

@media (max-width: 980px) {
  .graduation__cards { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 560px) {
  .graduation__cards { grid-template-columns: 1fr; }
}



/* ============================================================
   Slide-in left/right direction variants — used to alternate
   section entrance directions for visual rhythm
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  .slide-in-l, .slide-in-r { transform: none !important; }
}

@media (prefers-reduced-motion: reduce) {
  .reveal-up,
  .why-icon {
    opacity: 1 !important;
    transform: none !important;
    filter: none !important;
    animation: none !important;
  }
}

/* ============================================================
   SITE FOOTER — single legal line, same colour as the nav
   ============================================================ */
.site-footer {
  background: var(--oli-mist);
  border-top: 1px solid rgba(26, 73, 33, 0.10);
  padding: 1.4rem clamp(20px, 4vw, 64px);
}
.site-footer__legal {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1.4rem;
  flex-wrap: wrap;
  font-family: var(--fb);
  font-size: 0.78rem;
  color: var(--ink-muted);
}
.site-footer__legal a {
  color: inherit;
  text-decoration: none;
  transition: color 0.2s ease;
}
.site-footer__legal a:hover { color: var(--oli-forest); }
