/* ============================================================================
   Oravo — oravo.app
   Design tokens transcribed from Oravo_Brand_Guidelines.pdf v1.0 (Edition 01, 2026).
   §3.0 colour · §3.1 neutrals · §3.2 semantic · §4.0/4.1 type · §5.0 grid & spacing
   · §8.0 UI principles · §8.2 motion · §11.0 accessibility.

   Every brand value lives in this :root block. If the brand direction changes
   (see site/README.md — "Known conflict: ADR-0008"), edit here and nowhere else.
   ========================================================================== */

@font-face {
  font-family: 'Manrope';
  src: url('assets/fonts/manrope-latin-var.woff2') format('woff2-variations');
  font-weight: 200 800;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+2000-206F, U+2122, U+2190-21BB, U+2212, U+2318, U+2325, U+21E7;
}
@font-face {
  font-family: 'JetBrains Mono';
  src: url('assets/fonts/jetbrains-mono-latin-var.woff2') format('woff2-variations');
  font-weight: 400 500;
  font-display: swap;
  unicode-range: U+0000-00FF, U+2000-206F, U+2122, U+2212, U+2318, U+2325, U+21E7;
}

:root {
  /* §3.0 primary — the signature gradient is thought (purple) flowing into clarity (blue) */
  --iris: #7C5CE6;
  --iris-mid: #6C7AE8;
  --azure: #4EA1E6;
  --gradient: linear-gradient(125deg, var(--iris) 0%, var(--iris-mid) 52%, var(--azure) 100%);
  /* Button ramp stops short of Azure on purpose: white text measures 4.64:1 on Iris but
     only 2.78:1 on Azure, so the full signature gradient cannot legally carry white
     label text (§11.0 wants 4.5:1). This purple-dominant ramp holds 4.6–4.7:1 end to end
     and still reads unmistakably as the brand gradient. */
  --gradient-cta: linear-gradient(125deg, #7C5CE6 0%, #6A63DE 100%);

  /* §3.1 neutral system — cool-leaning so the gradient stays the only bright note */
  --ink: #0B0E14;
  --obsidian: #14181F;
  --graphite: #1E2430;
  --slate: #5A6373;
  --steel: #8A93A3;
  --off-white: #F6F8FB;
  --light-gray: #EEF1F5;
  --border: #E2E6ED;
  --white: #FFFFFF;

  /* §3.2 semantic — state only, never decoration, always paired with a non-colour cue */
  --success: #10B77F;
  --warning: #F5A310;
  --error: #EF4E64;
  --info: #4C8DF6;

  /* dark-surface companions (§9.0 — the product ships dark and light) */
  --dark-line: rgba(255, 255, 255, .09);
  --dark-line-strong: rgba(255, 255, 255, .16);
  --dark-fill: rgba(255, 255, 255, .045);

  /* §5.0 spacing — 4px base; 8 and 16 do most of the work, 24–64 set section rhythm */
  --s-1: 4px;  --s-2: 8px;  --s-3: 12px; --s-4: 16px;
  --s-6: 24px; --s-8: 32px; --s-12: 48px; --s-16: 64px;

  /* §5.0 corner radius — nothing is fully sharp */
  --r-chip: 8px;
  --r-input: 12px;
  --r-card: 18px;
  --r-panel: 28px;
  --r-pill: 999px;

  /* §5.0 grid — 12 columns, 88px margins, 24px gutters */
  --container: 1200px;
  --margin: 88px;
  --gutter: 24px;

  /* §8.0 elevation — soft depth, never heavy */
  --e-raised: 0 8px 24px rgba(11, 14, 20, .07);
  --e-float: 0 20px 60px rgba(11, 14, 20, .13);
  --e-dark: 0 24px 70px rgba(0, 0, 0, .5);

  /* §8.2 motion — soft spring easing, 160–280ms, always interruptible */
  --t-fast: 160ms;
  --t-base: 220ms;
  --t-slow: 280ms;
  --ease: cubic-bezier(.22, .72, .2, 1);
  --ease-out: cubic-bezier(.16, 1, .3, 1);
}

/* ---------- reset ---------- */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
/* overflow-x uses `clip`, not `hidden`: `hidden` makes the element a scroll
   container (overflow-y computes to auto), which silently breaks every
   `position: sticky` descendant — it was why the workspace scroll sequence
   unpinned and left a long dark gap. `clip` hides the horizontal overhang
   (the hero laptop) without creating a scroll container, so sticky works. */
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; overflow-x: clip; }
body {
  font-family: 'Manrope', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  font-size: 17px;               /* §4.1 body — 17 / 1.6 */
  line-height: 1.6;
  font-weight: 400;
  color: var(--ink);
  background: var(--white);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: clip;   /* clip, not hidden — see the note on html above (keeps position:sticky working) */
}
img { max-width: 100%; display: block; }
button, input, textarea, select { font: inherit; color: inherit; }
button { background: none; border: none; cursor: pointer; }
a { color: inherit; text-decoration: none; }

/* §11.0 — every control shows a clear Iris focus ring, in natural reading order */
:focus-visible {
  outline: 2px solid var(--iris);
  outline-offset: 3px;
  border-radius: var(--r-chip);
}

.vh {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}
/* The skip link is a .vh — which meant a keyboard user tabbing onto it had focus
   on something they could not see, failing the very control meant to help them.
   Bring it back on screen while focused. */
a.vh:focus, a.vh:focus-visible {
  position: fixed; top: 12px; left: 12px; width: auto; height: auto;
  overflow: visible; clip: auto; clip-path: none;
  padding: 10px 16px; border-radius: 10px; z-index: 999;
  background: var(--iris); color: #fff; font-size: 14px; font-weight: 600;
}

/* ---------- type scale (§4.1) ---------- */
.mono {
  font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11px;
  font-weight: 400;
  letter-spacing: .14em;
  text-transform: uppercase;
}
h1, h2, h3, h4 { letter-spacing: -.02em; line-height: 1.1; text-wrap: balance; }
h1 { font-size: clamp(40px, 6.4vw, 64px); font-weight: 200; letter-spacing: -.035em; }
h2 { font-size: clamp(28px, 3.6vw, 44px); font-weight: 300; letter-spacing: -.03em; }
h3 { font-size: clamp(22px, 2.4vw, 32px); font-weight: 600; }
h4 { font-size: 17px; font-weight: 700; letter-spacing: -.01em; }
.lead { font-size: 19px; line-height: 1.55; color: var(--slate); text-wrap: pretty; }
.small { font-size: 14px; line-height: 1.6; }
.muted { color: var(--slate); }

/* ---------- layout ---------- */
.wrap { max-width: var(--container); margin: 0 auto; padding: 0 var(--s-6); }
@media (min-width: 1100px) { .wrap { padding: 0 var(--margin); } }

section { padding: clamp(64px, 9vw, 112px) 0; position: relative; }
.sec-head { max-width: 720px; }
.sec-head.center { margin: 0 auto; text-align: center; }
.sec-head .mono { color: var(--iris); display: block; margin-bottom: var(--s-4); }
.sec-head h2 + p { margin-top: var(--s-4); }

/* overflow clipped so the gradient orbs stay inside their own band */
.band-dark { background: var(--ink); color: var(--white); overflow: hidden; }
.band-dark .lead, .band-dark .muted { color: var(--steel); }
.band-dark .sec-head .mono { color: var(--azure); }
.band-soft { background: var(--off-white); }

/* the gradient orb (§6.1) — a soft, blurred presence, never heavy */
.orb {
  position: absolute; border-radius: 50%; filter: blur(90px);
  pointer-events: none; z-index: 0;
}
.band-dark > .wrap, .hero > .wrap { position: relative; z-index: 1; }

/* ---------- buttons (§8.1) — gradient only for the primary action ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s-2);
  font-size: 14px; font-weight: 600; letter-spacing: -.01em;
  padding: 13px 22px; border-radius: var(--r-pill);
  transition: transform var(--t-fast) var(--ease), box-shadow var(--t-base) var(--ease),
              background-color var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease);
  will-change: transform;
}
.btn-primary {
  background: var(--gradient-cta); color: var(--white);
  box-shadow: 0 6px 20px rgba(124, 92, 230, .34);
}
/* The persistent nav CTA is solid white on Ink — 18:1, and the only white fill in the
   nav, so it reads as the primary action at a glance instead of sinking into the bar. */
.nav .btn-primary {
  background: var(--white); color: var(--iris);
  box-shadow: 0 2px 10px rgba(0, 0, 0, .35);
}
.nav .btn-primary:hover {
  background: var(--white); color: #6845D6;   /* 6.0:1 — iris-mid would drop to 3.8:1 */
  box-shadow: 0 6px 18px rgba(124, 92, 230, .45), 0 0 0 3px rgba(124, 92, 230, .28);
}
.btn-primary:hover { transform: translateY(-1px); box-shadow: 0 10px 28px rgba(124, 92, 230, .42); }
.btn-primary:active { transform: translateY(0); }
.btn-ghost { border: 1px solid var(--border); background: var(--white); color: var(--ink); }
.btn-ghost:hover { border-color: var(--slate); transform: translateY(-1px); }
.btn-ghost-dark { border: 1px solid var(--dark-line-strong); color: var(--white); background: var(--dark-fill); }
.btn-ghost-dark:hover { border-color: rgba(255,255,255,.34); background: rgba(255,255,255,.08); transform: translateY(-1px); }
.btn-sm { padding: 9px 16px; font-size: 13px; }

/* Pre-launch: download buttons stay visible but inert ("Coming soon"). Every
   download CTA sits on a dark band (nav, hero, pricing, #download), so the muted
   style is tuned for dark: a translucent ghost fill with greyed text that clearly
   reads "disabled," not the active white primary. Neutralizes every .btn variant's
   fill/border/hover. */
.btn.is-disabled {
  background: rgba(255,255,255,.06); color: var(--steel);
  border: 1px solid rgba(255,255,255,.14); box-shadow: none;
  opacity: .8; cursor: not-allowed; transform: none; pointer-events: none;
}

/* ---------- nav ---------- */
.nav {
  position: sticky; top: 0; z-index: 80;
  background: var(--ink);                /* matches the hero exactly, so it reads as one field */
  border-bottom: 1px solid transparent;
  transition: border-color var(--t-base) var(--ease), background-color var(--t-base) var(--ease);
}
.nav.scrolled {
  border-bottom-color: var(--dark-line);
  background: rgba(11, 14, 20, .82);
  -webkit-backdrop-filter: saturate(180%) blur(18px);
  backdrop-filter: saturate(180%) blur(18px);
}
.nav-in { display: flex; align-items: center; justify-content: space-between; height: 68px; gap: var(--s-6); }
.brand { display: flex; align-items: center; gap: 10px; }
/* The ring's lower-left arc is deep violet and all but disappeared on Ink. Lifting
   luminance restores the full stroke while leaving the artwork itself untouched —
   the mark is not redrawn, recoloured or re-spaced, only lit for a dark field. */
.brand img.mark {
  width: 30px; height: 30px;
  filter: brightness(1.42) saturate(1.12);
}
.brand img.word { height: 13px; width: auto; }
.nav-links { display: flex; align-items: center; gap: var(--s-8); }
.nav-links a { font-size: 14px; font-weight: 500; color: var(--steel); transition: color var(--t-fast) var(--ease); }
.nav-links a:hover { color: var(--white); }
@media (max-width: 860px) { .nav-links a.nlink { display: none; } }

/* ---------- hero (§10.0 — dark, cinematic, few words, the HUD doing the talking) ---------- */
.hero {
  background: var(--ink); color: var(--white);
  padding: clamp(56px, 8vw, 96px) 0 clamp(72px, 10vw, 128px);
  overflow: hidden; position: relative;
}
.hero-head { max-width: 760px; position: relative; z-index: 2; }

/* ---------- hero: text left, a real Mac on the right ---------- */
.hero-top { display: grid; gap: clamp(28px, 3.4vw, 48px); align-items: center; }
@media (min-width: 1000px) {
  /* text ~41% / visual ~59%, vertically centred, tighter gap */
  .hero-top { grid-template-columns: minmax(0, 0.7fr) minmax(0, 1fr); }
  .hero-head { max-width: none; }
  .hero .lead { max-width: 480px; }
}
/* Desktop: the artwork is absolutely positioned over the right of the hero, large
   enough that its top edge softens into the field and its left edge feathers into
   the copy — so it reads as one immersive scene, not a boxed screenshot (matching
   the reference). .hero-top is the positioning context; .hero's overflow:hidden
   clips any bleed. The entrance is kept opacity-only here so its transform doesn't
   fight the vertical-centering transform. */
@media (min-width: 1000px) {
  .hero-top { position: relative; }
  /* absolutely place the artwork over the hero's right side, vertically centred.
     The centring transform is repeated on the .is-loaded state (higher specificity
     than the shared entrance rules below) so entrance becomes an opacity-only fade
     and never cancels the centring. */
  .hero .hero-mac {
    position: absolute; top: 50%; transform: translateY(-50%);
    /* break the right edge out to the viewport edge, sized in vw so the artwork is
       large and dominant like the reference (not capped to the container); clamped
       so it grows smoothly and never gets absurd on very wide screens */
    right: calc(50% - 50vw); width: clamp(680px, 56vw, 900px); margin: 0; z-index: 1; display: block;
  }
  .is-loaded .hero .hero-mac { transform: translateY(-50%); opacity: 1;
    transition: opacity 900ms var(--ease-out) 420ms; }
  .hero-head { position: relative; z-index: 2; }           /* copy stays above the artwork */
}

/* ---- the hero laptop: the approved render, floated ---------------------------------
   The render's dark backdrop is keyed out to real alpha (luminance-derived, so the
   blue halo survives as a soft glow), which is why no plate or edge mask is needed:
   there is no rectangle to hide. Screen content and proportions are untouched. */
.hero-mac { position: relative; z-index: 1; display: flex; justify-content: center; }
.hero-laptop-tilt {
  position: relative; z-index: 1; width: 100%;
  transform-origin: center center;
  transition: transform 600ms var(--ease-out);
  will-change: transform;
}
.hero-laptop {
  /* the asset carries 17% transparent padding on each side so its glow can decay
     invisibly, so it is drawn 34% wider than the column and the padding hangs
     outside — harmless, since those pixels are fully transparent */
  /* All the overhang goes right. Centred, its left padding used to sit over the
     copy — invisible while the asset was transparent, but it is opaque now and was
     clipping the lead paragraph. */
  width: 134%; max-width: none; height: auto;
  margin-inline: 0 -34%; object-fit: contain;
  pointer-events: none; user-select: none; -webkit-user-select: none;
  transform-origin: center center;
  filter: drop-shadow(0 30px 60px rgba(0, 60, 130, .22));
  animation: laptopFloat 6.5s ease-in-out infinite;
  /* The current asset is an opaque JPG, so its rectangular edge shows a faint seam
     against the near-black page (the CSS above was written for a transparent PNG).
     Feather all four edges to dissolve that rectangle into the background — the
     transparent look without the alpha channel. Swapping back to a real transparent
     PNG later is still preferable; this makes the JPG ship clean in the meantime. */
  -webkit-mask-image:
    linear-gradient(to right,  transparent 0, #000 8%, #000 92%, transparent 100%),
    linear-gradient(to bottom, transparent 0, #000 8%, #000 92%, transparent 100%);
          mask-image:
    linear-gradient(to right,  transparent 0, #000 8%, #000 92%, transparent 100%),
    linear-gradient(to bottom, transparent 0, #000 8%, #000 92%, transparent 100%);
  -webkit-mask-composite: source-in;   /* intersect the two gradients (legacy WebKit keyword) */
          mask-composite: intersect;
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
}
@keyframes laptopFloat {
  0%, 100% { transform: translate3d(0, 0, 0) rotate(0deg); }
  50%      { transform: translate3d(0, -8px, 0) rotate(.35deg); }
}

/* entrance lives on the outer wrapper so it never fights the float or the tilt */
.hero-mac { opacity: 0; transform: translateY(24px); }
.is-loaded .hero-mac {
  opacity: 1; transform: none;
  transition: opacity 900ms var(--ease-out) 420ms, transform 900ms var(--ease-out) 420ms;
}

/* Past this width the page has margin to spare outside the container, so the laptop
   may lean into it — the spec's "intentional overflow" — without ever being clipped. */
@media (min-width: 1280px) { .hero-mac { margin-right: -7%; } }

@media (max-width: 999px) {
  /* stacked under the copy; a touch wider than the column so it doesn't look timid */
  .hero-laptop { width: 132%; margin-inline: 0 -32%; }
}
@media (max-width: 620px) {
  .hero-laptop { width: 136%; margin-inline: 0 -36%; }
}
.hero .mono.eyebrow { color: var(--steel); display: block; margin-bottom: var(--s-6); }
.hero h1 { color: var(--white); }
.hero h1 .b { display: block; }
.hero .lead { color: var(--steel); margin-top: var(--s-6); max-width: 540px; }
.hero-cta { display: flex; flex-wrap: wrap; gap: var(--s-3); margin-top: var(--s-8); }
.hero-note { margin-top: var(--s-4); color: var(--steel); font-size: 13px; }
.hero-note b { color: var(--white); font-weight: 600; }

/* ============================================================================
   HERO REDESIGN — "Say anything. Turn it into anything." + the voice→output
   workflow artwork on the right. The artwork already ships on a near-black
   ground, so it blends by colour-match + a soft radial mask (no plate/border);
   a purple↔blue bloom breathes behind it. Parallax (.hero-laptop-tilt) and the
   entrance (.hero-mac) are inherited from the wrappers above.
   ========================================================================== */
.hero-h1 {
  font-size: clamp(44px, 5.6vw, 76px);
  line-height: 1.0; font-weight: 200; letter-spacing: -.04em;
}
.hero-h1 .b { white-space: nowrap; }   /* controlled 3-line break; never mid-phrase */
/* purple→electric-blue accent on the final word (author-approved gradient text) */
.hero-h1 .grad {
  background: linear-gradient(104deg, var(--iris) 0%, #6C7AE8 46%, var(--azure) 100%);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
}
.hero-cta .play {
  display: inline-block; width: 0; height: 0; margin-right: 9px; vertical-align: middle;
  border-left: 8px solid currentColor; border-top: 5px solid transparent; border-bottom: 5px solid transparent;
}

/* trust statements under the CTAs — side by side on desktop/tablet, stacked on
   phones. The items share the row and shrink (min-width:0) so they stay side by
   side inside the ~42% text column at 1280/1440/1728 without overflowing. */
.hero-trust {
  list-style: none; padding: 0; margin: var(--s-8) 0 0;
  display: flex; gap: 40px;
}
.hero-trust li { display: flex; align-items: flex-start; gap: var(--s-3); flex: 1 1 0; min-width: 0; }
@media (max-width: 768px) {
  .hero-trust { flex-direction: column; gap: 18px; }
  .hero-trust li { flex: 0 1 auto; }
}
.ht-ic { width: 22px; height: 22px; flex: none; color: var(--iris); margin-top: 1px; }
.ht-txt { font-size: 13px; line-height: 1.4; color: var(--steel); }
.ht-txt b { display: block; color: var(--white); font-size: 14px; font-weight: 600; }

/* the workflow artwork: large, aspect-preserved, dominant on the right */
.hero-workflow {
  width: 100%; max-width: none; height: auto; display: block;
  object-fit: contain; border: 0; border-radius: 0;
  pointer-events: none; user-select: none; -webkit-user-select: none;
  /* Lift the artwork's faint baked-in labels ("You speak", the card captions) so
     they read; contrast keeps the near-black ground dark so the blend holds. */
  filter: brightness(1.2) contrast(1.06);
}
/* Dissolve the crop's rectangle by making its edges TRANSPARENT, not by painting
   the background colour over them.

   The original approach overlaid four --ink gradients on the assumption that "the
   artwork's own ground is --ink". Measured, it is not: the top-right corner is
   rgb(0,0,8) against a page of rgb(11,14,20), and the brightness filter above
   drives it to rgb(0,0,3). Worse, .hero-bloom sits BEHIND the artwork, so its glow
   is occluded inside the image rectangle and visible outside it — painting --ink on
   the seam makes the inside flat while the outside glows, which IS the outline.

   A mask makes the seam alpha, so neither the artwork's ground nor the page
   background has to match anything, and the bloom runs continuously across it. */
.hero-laptop-tilt { position: relative; }
.hero-workflow {
  /* Two gradients composited to an intersection — one per axis — so all four
     edges feather at once. `mask-composite: intersect` was avoided here for a
     long time on the belief that it zeroes the image in Chromium; re-tested on
     Chrome 148 it works correctly, so this is the simpler single-element form.
     -webkit-mask-composite takes the older WebKit keyword for the same operation.

     Stops are set from the artwork's measured content, not by eye, so the fade
     cannot clip the Email / Message / Summary / Translation cards: bright content
     spans 0.2%–88.9% horizontally and 9.2%–99.5% vertically, so the ramps stop
     exactly where the cards begin. */
  -webkit-mask-image:
    linear-gradient(to right,  transparent 0%, #000 8%, #000 89%, transparent 100%),
    linear-gradient(to bottom, transparent 0%, #000 9%, #000 90%, transparent 100%);
  -webkit-mask-composite: source-in;
  mask-image:
    linear-gradient(to right,  transparent 0%, #000 8%, #000 89%, transparent 100%),
    linear-gradient(to bottom, transparent 0%, #000 9%, #000 90%, transparent 100%);
  mask-composite: intersect;
}
/* purple↔blue bloom breathing behind the artwork */
.hero-bloom {
  position: absolute; inset: -6% -4%; z-index: 0; pointer-events: none;
  background: radial-gradient(44% 40% at 54% 46%,
    rgba(124, 92, 230, .34) 0%, rgba(78, 161, 230, .16) 44%, transparent 72%);
  filter: blur(14px);
  animation: bloomPulse 6.5s ease-in-out infinite;
}
@keyframes bloomPulse {
  0%, 100% { opacity: .72; transform: scale(1); }
  50%      { opacity: 1;   transform: scale(1.05); }
}

/* bottom supporting line — restrained, centred, never competing with the h1 */
.hero-tagline { margin-top: clamp(36px, 5vw, 64px); text-align: center; }
.hero-tagline .tag-lead {
  display: block; color: var(--azure); font-size: 15px; font-weight: 500; letter-spacing: .01em;
}
.hero-tagline .tag-meta {
  display: inline-flex; flex-wrap: wrap; justify-content: center; align-items: center;
  gap: var(--s-2) var(--s-4); margin-top: var(--s-4);
  padding: 8px 18px; border-radius: 999px;
  background: rgba(255, 255, 255, .03); border: 1px solid var(--dark-line);
  font-size: 10px; color: var(--steel);
}
.hero-tagline .tag-meta span { position: relative; }
.hero-tagline .tag-meta span + span::before {
  content: ""; position: absolute; left: calc(var(--s-4) / -2 - 1px); top: 50%;
  width: 3px; height: 3px; margin-top: -1px; border-radius: 50%; background: rgba(255, 255, 255, .28);
}

@media (max-width: 999px) {
  .hero-workflow { width: 100%; margin-inline: 0; }
}
@media (max-width: 620px) {
  .hero-h1 { font-size: clamp(40px, 11vw, 52px); line-height: 1.05; }
}
@media (prefers-reduced-motion: reduce) {
  .hero-workflow, .hero-bloom { animation: none !important; }
}

/* ---------- the HUD — brand guide §9.0, and the live demo ---------- */
.hud-shell { margin-top: clamp(40px, 6vw, 64px); position: relative; z-index: 1; }
.hud {
  max-width: 940px; margin: 0 auto;
  background: linear-gradient(180deg, #171C25 0%, var(--obsidian) 100%);
  border: 1px solid var(--dark-line);
  border-radius: var(--r-panel);
  box-shadow: var(--e-dark);
  overflow: hidden;
}
.hud-bar {
  display: flex; align-items: center; gap: var(--s-3);
  padding: 14px var(--s-6); border-bottom: 1px solid var(--dark-line);
}
.hud-dots { display: flex; gap: 7px; }
.hud-dots i { width: 11px; height: 11px; border-radius: 50%; background: #2B313C; }
.hud-bar .word { height: 10px; width: auto; opacity: .5; margin-left: var(--s-2); }
.hud-bar .kbd { margin-left: auto; color: var(--steel); }

.hud-body { padding: var(--s-6); }
@media (min-width: 700px) { .hud-body { padding: var(--s-8); } }

.hud-status { display: flex; align-items: center; justify-content: space-between; gap: var(--s-4); }
.rec { display: inline-flex; align-items: center; gap: var(--s-2); color: var(--white); font-size: 14px; font-weight: 500; }
.rec-dot {
  width: 9px; height: 9px; border-radius: 50%; background: var(--error);
  box-shadow: 0 0 0 0 rgba(239, 78, 100, .45);
}
.is-live .rec-dot { animation: pulse 2.4s var(--ease) infinite; }
@keyframes pulse {
  50% { box-shadow: 0 0 0 7px rgba(239, 78, 100, 0); }
}
.hud-status .mic { color: var(--steel); }
.hud-status .time { color: var(--steel); margin-left: var(--s-1); letter-spacing: .08em; }

/* waveform (§6.1 — voice made visible, the primary motif) */
.wave { display: flex; align-items: center; gap: 3px; height: 40px; margin: var(--s-4) 0 var(--s-3); }
/* Bars are full-height and scaled on the Y axis rather than animated on `height`:
   36 of them loop continuously behind a scroll-linked hero, and animating a layout
   property would run layout on every frame. scaleY is composited, and with the
   container centring them the result is pixel-identical. */
.wave i {
  flex: 1; max-width: 5px; min-width: 3px; height: 100%;
  border-radius: var(--r-pill); background: var(--gradient); opacity: .5;
  transform: scaleY(.26); transform-origin: center;
  transition: transform var(--t-slow) var(--ease), opacity var(--t-base) var(--ease);
}
/* at rest the waveform keeps the shape of what was said, rather than flattening to dots */
.wave i:nth-child(3n)   { transform: scaleY(.52); }
.wave i:nth-child(4n)   { transform: scaleY(.34); }
.wave i:nth-child(5n)   { transform: scaleY(.68); }
.wave i:nth-child(7n)   { transform: scaleY(.22); }
.wave i:nth-child(11n)  { transform: scaleY(.80); }
.is-live .wave i { animation: bar 1.1s var(--ease) infinite; opacity: .9; }
@keyframes bar { 0%, 100% { transform: scaleY(.14); } 50% { transform: scaleY(.88); } }

.hud-input {
  width: 100%; resize: vertical; min-height: 92px;
  background: rgba(255,255,255,.03); color: var(--white);
  border: 1px solid var(--dark-line); border-radius: var(--r-input);
  padding: var(--s-4); font-size: 17px; line-height: 1.6;
  transition: border-color var(--t-fast) var(--ease), background-color var(--t-fast) var(--ease);
}
.hud-input::placeholder { color: var(--steel); }
.hud-input:focus { outline: none; border-color: var(--iris); background: rgba(255,255,255,.05); }
.hud-input:focus-visible { outline: 2px solid var(--iris); outline-offset: 2px; }

.hud-samples { display: flex; align-items: center; flex-wrap: wrap; gap: var(--s-2); margin-top: var(--s-3); }
.hud-samples .lbl { color: var(--steel); margin-right: var(--s-1); }
.chip {
  font-size: 13px; font-weight: 500; padding: 6px 12px;
  border-radius: var(--r-chip); border: 1px solid var(--dark-line);
  color: var(--steel); background: transparent;
  transition: color var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease), background-color var(--t-fast) var(--ease);
}
.chip:hover { color: var(--white); border-color: var(--dark-line-strong); background: var(--dark-fill); }

.hud-actions {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2);
  margin-top: var(--s-6); padding-top: var(--s-6); border-top: 1px solid var(--dark-line);
}
.act {
  font-size: 14px; font-weight: 600; padding: 10px 18px;
  border-radius: var(--r-pill); border: 1px solid var(--dark-line-strong);
  color: var(--white); background: var(--dark-fill);
  transition: background-color var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease), transform var(--t-fast) var(--ease);
}
.act:hover { background: rgba(255,255,255,.1); transform: translateY(-1px); }
.act[aria-pressed="true"] { background: var(--gradient); border-color: transparent; box-shadow: 0 6px 18px rgba(124,92,230,.3); }
.act:disabled { opacity: .45; cursor: default; transform: none; }
.lang {
  font-size: 13px; font-weight: 500; padding: 10px 30px 10px 13px;
  border-radius: var(--r-chip);
  background-color: var(--dark-fill); border: 1px solid var(--dark-line-strong);
  color: var(--steel); cursor: pointer;
  -webkit-appearance: none; appearance: none;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%238A93A3' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 12px center;
  transition: color var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease);
}
.lang:hover { color: var(--white); border-color: rgba(255,255,255,.28); }
.lang option { background: var(--obsidian); color: var(--white); }
.hud-actions .kbd { margin-left: auto; color: var(--steel); }
@media (max-width: 620px) { .hud-actions .kbd { display: none; } }

/* result — §8.2 "finished output rises and settles into place" */
.hud-result {
  margin-top: var(--s-6); padding: var(--s-4);
  border: 1px solid var(--dark-line); border-radius: var(--r-card);
  background: rgba(124, 92, 230, .07);
  opacity: 0; transform: translateY(8px);
  transition: opacity var(--t-slow) var(--ease-out), transform var(--t-slow) var(--ease-out);
}
.hud-result.shown { opacity: 1; transform: none; }
.res-head { display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); }
.res-head .res-label { color: var(--azure); }
.res-head .res-meta { color: var(--steel); text-transform: none; letter-spacing: .04em; }
.res-text { margin-top: var(--s-3); font-size: 17px; line-height: 1.65; color: var(--white); white-space: pre-wrap; min-height: 1.65em; }
.res-text .caret {
  display: inline-block; width: 2px; height: 1.05em; vertical-align: -2px;
  background: var(--azure); margin-left: 1px;
}
.is-typing .res-text .caret { animation: blink 1s steps(2) infinite; }
@keyframes blink { 50% { opacity: 0; } }
.res-actions { display: flex; gap: var(--s-2); margin-top: var(--s-4); }
.res-actions button {
  font-size: 13px; font-weight: 600; padding: 8px 14px; border-radius: var(--r-chip);
  border: 1px solid var(--dark-line-strong); color: var(--white); background: var(--dark-fill);
  transition: background-color var(--t-fast) var(--ease);
}
.res-actions button:hover { background: rgba(255,255,255,.1); }

/* an honest, non-colour-only notice (§3.2, §11.0) */
.notice {
  display: flex; gap: var(--s-3); align-items: flex-start;
  font-size: 14px; line-height: 1.55; color: var(--steel);
}
.notice .ic {
  flex: none; width: 18px; height: 18px; border-radius: 50%; margin-top: 2px;
  background: rgba(76, 141, 246, .16); color: var(--info);
  display: grid; place-items: center; font-size: 11px; font-weight: 700;
}
.demo-note { margin-top: var(--s-4); font-size: 13px; line-height: 1.6; color: var(--steel); }
.demo-note b { color: var(--white); font-weight: 600; }

/* ---------- how it works ---------- */
.steps { display: grid; gap: var(--s-6); margin-top: var(--s-12); }
@media (min-width: 800px) { .steps { grid-template-columns: repeat(3, 1fr); gap: var(--gutter); } }
.step { padding-top: var(--s-6); border-top: 1px solid var(--border); }
.band-dark .step { border-top-color: var(--dark-line); }
.step .n { color: var(--iris); display: block; margin-bottom: var(--s-4); }
.step h4 { margin-bottom: var(--s-2); }
.step p { color: var(--slate); font-size: 15px; }
.kbd-inline {
  display: inline-block; padding: 3px 8px; border-radius: 6px;
  background: var(--light-gray); border: 1px solid var(--border);
  font-family: 'JetBrains Mono', monospace; font-size: 12px; letter-spacing: .04em;
  color: var(--ink); vertical-align: 1px;
}
.band-dark .kbd-inline { background: var(--dark-fill); border-color: var(--dark-line-strong); color: var(--white); }

/* ---------- feature rows ---------- */
.feature { display: grid; gap: var(--s-8); align-items: center; }
@media (min-width: 900px) {
  .feature { grid-template-columns: 1fr 1fr; gap: clamp(48px, 6vw, 88px); }
  .feature.flip .fig { order: -1; }
}
.feature + .feature { margin-top: clamp(64px, 8vw, 112px); }
.feature .mono { color: var(--iris); display: block; margin-bottom: var(--s-3); }
.feature h3 { margin-bottom: var(--s-4); }
.feature p { color: var(--slate); }
.feature .pills { display: flex; flex-wrap: wrap; gap: var(--s-2); margin-top: var(--s-6); }
.pill {
  font-size: 13px; font-weight: 500; padding: 6px 13px; border-radius: var(--r-pill);
  background: var(--light-gray); color: var(--slate);
}

/* The 13 translate languages — flag + name chips, same family as .pill. Each chip
   keeps its name so it stays legible even where OS emoji don't render flag glyphs. */
.feature .lang-flags {
  list-style: none; display: flex; flex-wrap: wrap; gap: var(--s-2);
  margin-top: var(--s-4); padding: 0;
}
.feature .lang-flags li {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 6px 12px 6px 9px; border-radius: var(--r-pill);
  background: var(--light-gray); color: var(--slate);
  font-size: 13px; font-weight: 500;
  transition: transform var(--t-fast) var(--ease), background-color var(--t-fast) var(--ease);
}
.feature .lang-flags li:hover { transform: translateY(-2px); background: var(--border); }
.feature .lang-flags .flag { font-size: 16px; line-height: 1; }

/* ---------- human photo slots ----------
   A drop-in image frame with a graceful placeholder: save a real photo at the
   referenced assets/ path and it fills the frame; until then the labelled hint
   keeps the layout intact (the <img> removes itself via onerror when missing). */
.photo-slot {
  position: relative; overflow: hidden; border-radius: var(--r-card);
  background: linear-gradient(135deg, var(--light-gray), #e6e8ee);
  box-shadow: var(--e-raised);
  aspect-ratio: 4 / 5;                 /* portrait by default */
}
.photo-slot--wide { aspect-ratio: 16 / 9; }
.photo-slot--dark {
  background: linear-gradient(135deg, #1b1b21, #0e0e12);
  box-shadow: none; border: 1px solid var(--dark-line);
}
.photo-slot::after {                    /* placeholder hint — covered once a real img loads */
  content: attr(data-hint); position: absolute; inset: 0; z-index: 0;
  display: grid; place-items: center; padding: 24px; text-align: center;
  font-size: 13px; line-height: 1.6; color: var(--slate);
}
.photo-slot--dark::after { color: var(--steel); }
.photo-slot > img {
  position: absolute; inset: 0; z-index: 1;
  width: 100%; height: 100%; object-fit: cover; display: block;
}

/* Early-access CTA: text/buttons beside a portrait photo (replaces the old form) */
.cta-grid { position: relative; z-index: 1; display: grid; gap: clamp(32px, 5vw, 64px); align-items: center; }
@media (min-width: 900px) { .cta-grid { grid-template-columns: 1.25fr .85fr; } }

/* the little product figures that carry each feature */
.fig {
  background: var(--white); border: 1px solid var(--border); border-radius: var(--r-card);
  padding: var(--s-6); box-shadow: var(--e-raised);
}
.fig-row { display: flex; align-items: center; gap: var(--s-3); padding: var(--s-3) 0; }
.fig-row + .fig-row { border-top: 1px solid var(--border); }
.fig-tag {
  font-family: 'JetBrains Mono', monospace; font-size: 10px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--steel); flex: none; width: 78px;
  white-space: nowrap;
}
code, .nowrap { white-space: nowrap; }
.fig-text { font-size: 15px; line-height: 1.55; }
.fig-text.was { color: var(--steel); }
.fig-text.now { color: var(--ink); font-weight: 500; }
.mark-hl {
  background: rgba(124, 92, 230, .13); border-radius: 5px; padding: 1px 6px;
  font-weight: 600; box-shadow: inset 0 0 0 1px rgba(124, 92, 230, .2);
}
.fig-bullets { list-style: none; display: grid; gap: var(--s-3); }
.fig-bullets li { display: flex; gap: var(--s-3); font-size: 15px; line-height: 1.5; }
.fig-bullets .dot { flex: none; width: 6px; height: 6px; border-radius: 50%; background: var(--gradient); margin-top: 8px; }
.fig-mail { font-size: 15px; line-height: 1.6; }
.fig-mail .hdr { color: var(--steel); font-size: 13px; padding-bottom: var(--s-2); border-bottom: 1px solid var(--border); margin-bottom: var(--s-3); }

/* ---------- works everywhere ---------- */
.apps { display: grid; grid-template-columns: repeat(auto-fill, minmax(132px, 1fr)); gap: var(--s-2); margin-top: var(--s-12); }
.app {
  padding: 18px var(--s-4); border-radius: var(--r-chip); text-align: center;
  font-size: 14px; font-weight: 500; color: var(--slate);
  background: var(--white); border: 1px solid var(--border);
  transition: color var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease), transform var(--t-fast) var(--ease);
}
.app:hover { color: var(--ink); border-color: var(--slate); transform: translateY(-2px); }

/* ---------- testimonials ---------- */
.quotes { display: grid; gap: var(--s-6); margin-top: var(--s-12); }
@media (min-width: 860px) { .quotes { grid-template-columns: repeat(3, 1fr); gap: var(--gutter); } }
.quote {
  background: var(--white); border: 1px solid var(--border); border-radius: var(--r-card);
  padding: var(--s-8); display: flex; flex-direction: column; gap: var(--s-6);
}
.quote blockquote { font-size: 17px; line-height: 1.6; }
.quote figcaption { display: flex; align-items: center; gap: var(--s-3); margin-top: auto; }
.avatar {
  width: 38px; height: 38px; border-radius: 50%; flex: none;
  position: relative; overflow: hidden;
  background: var(--gradient);            /* brand tint behind the initials fallback */
  display: grid; place-items: center;
}
.avatar::before {                          /* initials — shown until a headshot loads over them */
  content: attr(data-initials);
  font-size: 12px; font-weight: 600; color: #fff; letter-spacing: .02em;
}
.avatar img {                              /* the headshot; removes itself via onerror if missing */
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
}
.quote .who { font-size: 14px; font-weight: 600; }
.quote .role { font-size: 13px; color: var(--slate); }

/* "How people use Oravo" scenario cards (reuse the .quote card shell). */
.quote .use-tag { color: var(--iris); display: block; margin-bottom: var(--s-3); }
.quote .use-title { font-size: 18px; letter-spacing: -.01em; margin-bottom: var(--s-2); }
.quote .use-desc { color: var(--slate); font-size: 15px; line-height: 1.55; }

/* ============================================================================
   PRICING — dark, calm, gradient-accented. Cards sit on Ink; the Pro card is
   highlighted with a GRADIENT RING (not a gradient fill) plus a glow and tag, so
   the full signature gradient never has to carry body text (§11.0 contrast).
   Prices are real text. Toggle is a keyboard-accessible segmented control.
   ========================================================================== */
.bill-toggle {
  display: flex; width: max-content; margin: clamp(28px, 4vw, 40px) auto 0;
  gap: 4px; padding: 4px; border-radius: var(--r-pill);
  background: var(--dark-fill); border: 1px solid var(--dark-line);
}
.bill-opt {
  appearance: none; -webkit-appearance: none; border: 0; background: transparent;
  cursor: pointer; color: var(--steel); font: inherit; font-size: 14px; font-weight: 600;
  padding: 9px 20px; border-radius: var(--r-pill);
  transition: color var(--t-fast) var(--ease), background-color var(--t-fast) var(--ease);
}
.bill-opt:hover { color: var(--white); }
.bill-opt.is-on { color: var(--white); background: var(--dark-line-strong); }
.bill-opt:focus-visible { outline: 2px solid var(--iris); outline-offset: 2px; }

.price-grid { display: grid; gap: var(--s-6); margin-top: clamp(32px, 4vw, 48px); align-items: stretch; }
@media (min-width: 960px) { .price-grid { grid-template-columns: repeat(3, 1fr); } }

.price-card {
  display: flex; flex-direction: column; position: relative;
  background: var(--obsidian); border: 1px solid var(--dark-line);
  border-radius: var(--r-card); padding: clamp(24px, 2.6vw, 32px);
}
.price-card .pc-name {
  font-size: 13px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase;
  color: var(--steel); margin-bottom: var(--s-3);
}
.pc-price { display: flex; align-items: baseline; flex-wrap: wrap; gap: 8px; margin: 0; }
.pc-amt { font-size: clamp(38px, 5vw, 46px); font-weight: 300; letter-spacing: -.02em; color: var(--white); line-height: 1; }
.pc-per { font-size: 15px; color: var(--steel); }
.pc-was { font-size: 15px; color: var(--steel); text-decoration: line-through; }
.pc-save { font-size: 12px; font-weight: 600; color: var(--success); background: rgba(16,183,127,.14); border-radius: var(--r-pill); padding: 3px 9px; }
.pc-founder { font-size: 13px; font-weight: 600; color: var(--azure); margin: 8px 0 0; }
.pc-tag { color: var(--steel); font-size: 14px; margin-top: var(--s-3); line-height: 1.5; }

.pc-feats { list-style: none; display: flex; flex-direction: column; gap: 11px; margin: var(--s-6) 0; padding: 0; }
.pc-feats li { position: relative; padding-left: 27px; font-size: 13.5px; line-height: 1.5; color: rgba(255,255,255,.82); }
.pc-feats li::before { content: "✓"; position: absolute; left: 0; top: -1px; color: var(--azure); font-weight: 700; }

.pc-callout {
  font-size: 13px; line-height: 1.5; color: rgba(255,255,255,.9); margin: 0 0 var(--s-6);
  background: rgba(124,92,230,.10); border: 1px solid rgba(124,92,230,.28);
  border-radius: var(--r-input); padding: 12px 14px;
}
.pc-callout span { color: var(--iris-mid); margin-right: 5px; }

.pc-cta { width: 100%; margin-top: auto; }   /* pin CTAs to the card bottom so they align across cards */
.pc-fine { font-size: 12px; color: var(--steel); text-align: center; margin-top: 10px; }

/* Pro highlight */
.price-card.pro {
  border-color: transparent;
  background: linear-gradient(180deg, rgba(124,92,230,.10), rgba(255,255,255,.02));
  box-shadow: 0 24px 60px rgba(124,92,230,.18);
}
.price-card.pro::before {
  content: ""; position: absolute; inset: 0; border-radius: inherit; padding: 1.5px;
  background: var(--gradient); pointer-events: none;
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
          mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude;
}
.pc-pop {
  position: absolute; top: -13px; left: 50%; transform: translateX(-50%);
  background: var(--gradient-cta); color: var(--white);
  font-size: 12px; font-weight: 600; letter-spacing: .01em; white-space: nowrap;
  padding: 5px 14px; border-radius: var(--r-pill); box-shadow: 0 6px 18px rgba(124,92,230,.4);
}

/* Comparison table */
/* ---------- BYOK explainer (answers the double-charge objection) ---------- */
.byok { margin-top: clamp(56px, 8vw, 96px); text-align: center; }
.byok-title { font-size: clamp(21px, 2.8vw, 27px); color: var(--white); letter-spacing: -.02em; }
.byok-title em { font-style: normal; color: var(--azure); }
.byok-lede { color: var(--steel); font-size: 15px; margin-top: var(--s-3); }
.byok-grid {
  display: grid; gap: var(--s-4); margin-top: var(--s-8); text-align: left;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
}
.byok-item {
  padding: 20px 22px; border-radius: 14px;
  background: rgba(255, 255, 255, .03); border: 1px solid var(--dark-line);
}
.byok-item h4 { color: var(--white); font-size: 15px; font-weight: 600; margin-bottom: 7px; }
.byok-item p { color: var(--steel); font-size: 14px; line-height: 1.6; }
.byok-foot { margin-top: var(--s-6); color: var(--steel); font-size: 13.5px; }

.cmp { margin-top: clamp(56px, 8vw, 96px); }
.cmp-title { text-align: center; font-size: clamp(22px, 3vw, 28px); color: var(--white); margin-bottom: var(--s-8); }
.cmp-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.cmp-table { width: 100%; min-width: 680px; border-collapse: collapse; }
.cmp-table th, .cmp-table td { padding: 14px 18px; text-align: left; font-size: 14px; border-bottom: 1px solid var(--dark-line); }
.cmp-table thead th { color: var(--steel); font-weight: 600; font-size: 13px; border-bottom-color: var(--dark-line-strong); }
.cmp-table tbody th[scope="row"] { color: var(--steel); font-weight: 500; }
.cmp-table td { color: rgba(255,255,255,.72); }
.cmp-table thead th.col-oravo { background: var(--gradient-cta); color: var(--white); border-radius: 10px 10px 0 0; }
.cmp-table td.col-oravo { background: rgba(124,92,230,.09); color: var(--white); font-weight: 600; }
.cmp-table tbody tr:last-child td.col-oravo { border-radius: 0 0 10px 10px; }
.cmp-note-inline { color: var(--azure); font-weight: 500; font-size: 12.5px; }
.cmp-kicker { text-align: center; margin-top: var(--s-8); font-size: 15px; color: rgba(255,255,255,.9); }
/* --steel, not --slate: this line sits on the dark band, where --slate measures
   3.2:1 and fails AA. (--slate is fine everywhere else — it's only used on white.) */
.cmp-asof { text-align: center; margin-top: var(--s-3); font-size: 12px; color: var(--steel); }

/* ---------- download / waitlist ---------- */
.cta-panel {
  background: var(--ink); color: var(--white); border-radius: var(--r-panel);
  padding: clamp(40px, 6vw, 72px); position: relative; overflow: hidden;
}
.cta-inner { position: relative; z-index: 1; max-width: 640px; }
.cta-panel h2 { color: var(--white); }
.cta-panel .lead { color: var(--steel); margin-top: var(--s-4); }
.wait { display: flex; flex-wrap: wrap; gap: var(--s-2); margin-top: var(--s-8); }
.wait input[type="email"] {
  flex: 1 1 240px; min-width: 0;
  background: rgba(255,255,255,.05); border: 1px solid var(--dark-line-strong);
  border-radius: var(--r-pill); padding: 13px 20px; color: var(--white); font-size: 15px;
  transition: border-color var(--t-fast) var(--ease);
}
.wait input::placeholder { color: var(--steel); }
.wait input:focus { outline: none; border-color: var(--iris); }
.wait input:focus-visible { outline: 2px solid var(--iris); outline-offset: 2px; }
.form-msg { margin-top: var(--s-3); font-size: 14px; min-height: 1.5em; }
.form-msg[data-state="ok"] { color: var(--success); }
.form-msg[data-state="err"] { color: var(--error); }

/* ---------- footer ---------- */
footer { background: var(--ink); color: var(--steel); padding: var(--s-16) 0 var(--s-12); border-top: 1px solid var(--dark-line); }
.foot-top { display: flex; flex-wrap: wrap; gap: var(--s-8); justify-content: space-between; align-items: flex-start; }
.foot-links { display: flex; flex-wrap: wrap; gap: var(--s-6); }
.foot-links a { font-size: 14px; transition: color var(--t-fast) var(--ease); }
.foot-links a:hover { color: var(--white); }
.foot-bot {
  margin-top: var(--s-12); padding-top: var(--s-6); border-top: 1px solid var(--dark-line);
  display: flex; flex-wrap: wrap; gap: var(--s-4); justify-content: space-between;
  font-size: 13px; color: var(--steel);
}

/* Legal row in the footer. Its own line rather than more entries in .foot-links,
   which is already ten items — the legal links are a different kind of thing and
   crowding them in makes both harder to scan. Wraps to a stack on phones. */
.foot-legal { display: flex; flex-wrap: wrap; gap: var(--s-2) var(--s-6); }
.foot-legal a { font-size: 13px; color: var(--steel); transition: color var(--t-fast) var(--ease); }
.foot-legal a:hover { color: var(--white); }
@media (max-width: 620px) {
  .foot-bot { flex-direction: column; gap: var(--s-3); }
  .foot-legal { gap: var(--s-2) var(--s-4); }
}
/* Doc pages carry only the legal footer, so give it room to breathe without the
   .foot-top block above it. */
.doc-body + footer .foot-bot { margin-top: 0; border-top: 0; padding-top: 0; }

/* ---------- scroll reveal (§8.2 — shows where something went, then gets out of the way) ---------- */
.reveal { opacity: 0; transform: translateY(14px); }
.reveal.in {
  opacity: 1; transform: none;
  transition: opacity var(--t-slow) var(--ease-out), transform var(--t-slow) var(--ease-out);
}

/* ============================================================================
   THE WORKSPACE — "One voice. Every app."

   A dark 3D desk of application windows that stay unlit until your voice reaches
   them. Built from CSS 3D transforms rather than a WebGL library: no dependency,
   no CDN, ~4 KB, and it composites on the GPU like the rest of the page.
   ========================================================================== */
.workspace { background: var(--ink); color: var(--white); padding: 0; }
.ws-rail { height: 460vh; position: relative; }          /* scroll length for the sequence */
.ws-sticky {
  position: sticky; top: 0; height: 100vh; overflow: hidden;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
}
.ws-head { text-align: center; position: relative; z-index: 3; padding: 0 var(--s-6); }
.ws-head .mono { color: var(--azure); display: block; margin-bottom: var(--s-3); }
.ws-head h2 { color: var(--white); }
.ws-head p { color: var(--steel); margin-top: var(--s-3); font-size: 17px; }


/* The stage is a real grid, not absolute percentages. Percent offsets were sized
   against a viewport-scaled stage while the windows and cards stay a fixed pixel
   height — so on a shorter screen they compressed into each other (the Browser panel
   clipped the "Reply without typing" card). A grid cannot overlap: each window and
   its card own a row, and the 3D depth is applied as transforms, which don't affect
   layout at all. */
.ws-stage {
  position: relative; width: min(1080px, 92vw);
  margin-top: clamp(28px, 4.5vh, 60px);
  perspective: 1500px; perspective-origin: 50% 40%;
}
.ws-floor {
  position: relative;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  column-gap: clamp(14px, 2.2vw, 30px);
  row-gap: clamp(12px, 1.4vh, 18px);
  transform-style: preserve-3d;
  transform: rotateX(13deg) rotateZ(-.6deg);
  transition: transform 900ms var(--ease-out);
}

/* the voice, entering the scene from the speaker */
.ws-source {
  position: absolute; left: 50%; bottom: -14%; transform: translateX(-50%);
  width: 120px; height: 120px; border-radius: 50%;
  background: radial-gradient(circle, rgba(124,92,230,.55), transparent 68%);
  filter: blur(14px); opacity: .8; pointer-events: none;
}

.ws-win {
  padding: clamp(10px, 1.5vh, 15px);
  border-radius: 13px;
  background: #10141B;
  border: 1px solid rgba(255, 255, 255, .07);
  box-shadow: 0 16px 34px rgba(0, 0, 0, .5);
  transform-style: preserve-3d;
  transition: background-color 600ms var(--ease), border-color 600ms var(--ease),
              box-shadow 700ms var(--ease), transform 700ms var(--ease-out);
}
.ws-win .ttl {
  font-family: 'JetBrains Mono', monospace; font-size: 10px; letter-spacing: .14em;
  text-transform: uppercase; color: #454C5A;
  transition: color 600ms var(--ease);
}
.ws-win .lines { margin-top: 9px; display: grid; gap: 5px; }
.ws-win .lines i {
  height: 5px; border-radius: 3px; background: rgba(255, 255, 255, .07);
  transition: background-color 600ms var(--ease);
}
.ws-win .lines i:nth-child(2) { width: 82%; }
.ws-win .lines i:nth-child(3) { width: 58%; }

/* lit — the voice has reached this app */
.ws-win.lit {
  background: #1A1F2C;
  border-color: rgba(124, 92, 230, .5);
  box-shadow: 0 0 0 1px rgba(124, 92, 230, .18), 0 16px 40px rgba(0, 0, 0, .5),
              0 0 54px rgba(124, 92, 230, .28);
}
.ws-win.lit .ttl { color: var(--white); }
.ws-win.lit .lines i { background: rgba(255, 255, 255, .3); }
.ws-win.lit .lines i:first-child { background: var(--gradient); }

/* the card that opens beneath its own window */
.ws-card {
  align-self: start;
  padding: clamp(10px, 1.5vh, 14px) 15px;
  border-radius: var(--r-chip);
  background: var(--white); color: var(--ink);
  box-shadow: 0 14px 34px rgba(0, 0, 0, .45);
  transform-style: preserve-3d;
  opacity: 0;
  transition: opacity 460ms var(--ease-out), transform 520ms var(--ease-out);
  pointer-events: none;
}
.ws-card b { display: block; font-size: 14px; font-weight: 700; letter-spacing: -.01em; }
.ws-card span { display: block; margin-top: 3px; font-size: 12.5px; line-height: 1.45; color: var(--slate); }

/* column and row placement — window on top, its card directly beneath it */
.ws-win.w0, .ws-card.c0 { grid-column: 1; }
.ws-win.w1, .ws-card.c1 { grid-column: 2; }
.ws-win.w2, .ws-card.c2 { grid-column: 3; }
.ws-win.w3, .ws-card.c3 { grid-column: 1; }
.ws-win.w4, .ws-card.c4 { grid-column: 2; }
.ws-win.w5, .ws-card.c5 { grid-column: 3; }
.ws-win.w0, .ws-win.w1, .ws-win.w2 { grid-row: 1; }
.ws-card.c0, .ws-card.c1, .ws-card.c2 { grid-row: 2; }
.ws-win.w3, .ws-win.w4, .ws-win.w5 { grid-row: 3; margin-top: clamp(14px, 2.2vh, 30px); }
.ws-card.c3, .ws-card.c4, .ws-card.c5 { grid-row: 4; }

/* depth: kept modest so perspective scaling never grows a panel into its neighbour */
.ws-win.w0 { transform: translateZ(18px) rotateY(9deg); }
.ws-win.w1 { transform: translateZ(40px) rotateY(0deg); }
.ws-win.w2 { transform: translateZ(14px) rotateY(-9deg); }
.ws-win.w3 { transform: translateZ(30px) rotateY(8deg); }
.ws-win.w4 { transform: translateZ(52px) rotateY(0deg); }
.ws-win.w5 { transform: translateZ(24px) rotateY(-8deg); }
.ws-win.lit.w0 { transform: translateZ(40px) rotateY(9deg); }
.ws-win.lit.w1 { transform: translateZ(62px) rotateY(0deg); }
.ws-win.lit.w2 { transform: translateZ(36px) rotateY(-9deg); }
.ws-win.lit.w3 { transform: translateZ(52px) rotateY(8deg); }
.ws-win.lit.w4 { transform: translateZ(72px) rotateY(0deg); }
.ws-win.lit.w5 { transform: translateZ(46px) rotateY(-8deg); }

.ws-card.c0 { transform: translateZ(18px) rotateY(9deg)  translateY(8px); }
.ws-card.c1 { transform: translateZ(40px) rotateY(0deg)  translateY(8px); }
.ws-card.c2 { transform: translateZ(14px) rotateY(-9deg) translateY(8px); }
.ws-card.c3 { transform: translateZ(30px) rotateY(8deg)  translateY(8px); }
.ws-card.c4 { transform: translateZ(52px) rotateY(0deg)  translateY(8px); }
.ws-card.c5 { transform: translateZ(24px) rotateY(-8deg) translateY(8px); }
.ws-card.c0.on { transform: translateZ(18px) rotateY(9deg); }
.ws-card.c1.on { transform: translateZ(40px) rotateY(0deg); }
.ws-card.c2.on { transform: translateZ(14px) rotateY(-9deg); }
.ws-card.c3.on { transform: translateZ(30px) rotateY(8deg); }
.ws-card.c4.on { transform: translateZ(52px) rotateY(0deg); }
.ws-card.c5.on { transform: translateZ(46px) rotateY(-8deg); }
.ws-card.on { opacity: 1; }


/* Skip — the sequence is a long scroll, so there is always a one-click way past it.
   Sits clear of the stage on the right and never covers a card. */
.ws-skip {
  /* Sits in the centered sticky column, directly below the progress pips (it is
     the last child of that flex column) — moved out of its old right-middle
     absolute anchor so it reads as "progress, then the way out." */
  position: relative; margin-top: clamp(14px, 2.2vh, 26px);
  z-index: 6; display: inline-flex; align-items: center; gap: var(--s-2);
  padding: 11px 16px; border-radius: var(--r-pill);
  font-size: 13px; font-weight: 600; color: var(--white);
  background: rgba(255, 255, 255, .07);
  border: 1px solid var(--dark-line-strong);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  transition: background-color var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease),
              transform var(--t-fast) var(--ease);
}
.ws-skip:hover {
  color: var(--white); background: rgba(255, 255, 255, .13);
  border-color: rgba(255, 255, 255, .3); transform: translateY(-2px);
}
.ws-skip-ic {
  display: grid; place-items: center; opacity: .75;
  transition: transform var(--t-base) var(--ease);
}
/* the arrow points the way the button will actually take you */
.ws-skip.up .ws-skip-ic { transform: rotate(180deg); }
/* Skip now flows in the centered column below the pips, so it needs no
   width-specific repositioning — it only hides when the sequence collapses. */
@media (max-width: 860px) { .ws-skip { display: none; } }

.ws-progress {
  position: relative; z-index: 3; margin-top: clamp(16px, 3vh, 32px);
  display: flex; gap: 7px;
}
.ws-progress i {
  width: 26px; height: 3px; border-radius: 2px; background: rgba(255, 255, 255, .14);
  transition: background-color 400ms var(--ease);
}
.ws-progress i.on { background: var(--gradient); }

/* below the breakpoint the 3D room becomes an honest single-column list */
/* Collapse the pinned 3-D room into a plain stacked list only on NARROW screens.
   The old rule also collapsed on `max-height: 620px`, which fired on ordinary
   desktops at 100% zoom (content area ≤620px tall) and stretched the windows into
   full-width bars. The desktop grid fits comfortably down to ~520px tall, so width
   alone decides the layout now. */
@media (max-width: 860px) {
  .ws-rail { height: auto; }
  .ws-sticky { position: static; height: auto; padding: clamp(64px, 9vw, 112px) 0; }
  .ws-stage { perspective: none; width: 100%; padding: 0 var(--s-6); }
  .ws-floor { transform: none; grid-template-columns: 1fr; row-gap: var(--s-2); }
  .ws-win, .ws-win.lit, .ws-card, .ws-card.on {
    grid-column: 1 !important; grid-row: auto !important;
    transform: none !important; margin-top: 0;
  }
  .ws-card { opacity: 1; margin-bottom: var(--s-4); }
  .ws-source, .ws-progress { display: none; }
}

/* ============================================================================
   WORKS WHERE YOU WORK — Oravo at the centre, apps in orbit around it.
   Positions are computed in JS from a single angle driven by scroll progress;
   CSS only owns appearance. No pin: the section immediately follows the pinned
   workspace, and two consecutive pinned sections would feel like a trap.
   ========================================================================== */
.orbit-sec {
  background: var(--ink); color: var(--white);
  position: relative; overflow: hidden;
  padding: clamp(72px, 9vw, 120px) 0 clamp(56px, 7vw, 96px);
}
.orbit-sec .sec-head .mono { color: var(--iris); }
.orbit-sec h2 { color: var(--white); }
.orbit-sec h2 em {
  font-style: italic; font-weight: 300;
  background: var(--gradient-cta); -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: var(--iris);
}
.orbit-sec .lead { color: var(--steel); margin-left: auto; margin-right: auto; }
.orb-glow {
  position: absolute; left: 50%; top: 54%; transform: translate(-50%, -50%);
  width: min(1000px, 96vw); height: 620px; pointer-events: none; z-index: 0;
  background: radial-gradient(ellipse at center, rgba(124,92,230,.26), transparent 62%);
  filter: blur(50px);
}
.orbit-sec > .wrap { position: relative; z-index: 1; }

.orbit-layout { display: grid; gap: clamp(24px, 3vw, 44px); margin-top: clamp(24px, 4vw, 48px); }
@media (min-width: 1040px) {
  .orbit-layout { grid-template-columns: minmax(0, 1fr) 268px; align-items: center; }
}

/* ---- the stage ---- */
.orbit-stage {
  position: relative; width: 100%; aspect-ratio: 16 / 10.6;
  min-height: 300px;
}
.orb-rings { position: absolute; inset: 0; pointer-events: none; }
.orb-rings i {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  border: 1px solid rgba(160, 140, 240, .16);
  border-radius: 50%;
}
.orb-rings i:nth-child(1) { width: 54%; height: 46%; }
.orb-rings i:nth-child(2) { width: 78%; height: 66%; }
.orb-rings i:nth-child(3) { width: 100%; height: 86%; border-color: rgba(160,140,240,.1); }

/* ---- Oravo, at the centre ---- */
.orb-core {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  z-index: 50;
  width: clamp(98px, 12%, 138px); aspect-ratio: 1;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px;
  border-radius: 26px;
  background: linear-gradient(160deg, #1B1F2B 0%, #0E1119 100%);
  border: 1px solid rgba(160, 140, 240, .3);
  box-shadow: 0 0 0 1px rgba(124,92,230,.12), 0 24px 60px rgba(0,0,0,.6),
              0 0 70px rgba(124, 92, 230, .38);
}
.orb-core-mark { width: 46%; height: auto; filter: brightness(1.42) saturate(1.12); }
.orb-core-word { width: 58%; height: auto; opacity: .92; }

/* ---- an app in orbit ---- */
.orb-apps { position: absolute; inset: 0; perspective: 900px; perspective-origin: 50% 45%; }
.orb-app {
  position: absolute; left: 0; top: 0;
  transform-style: preserve-3d;
  width: clamp(44px, 5.4vw, 62px); aspect-ratio: 1;
  will-change: transform;
  transition: filter var(--t-base) var(--ease);
}
/* A squircle with real body: stacked hard shadows form the extruded side wall,
   a diagonal sheen supplies the specular highlight, and the rim lights catch the
   top edge — the same way a rendered macOS icon reads. No image assets involved. */
.orb-tile {
  position: relative;
  display: grid; place-items: center; width: 100%; height: 100%;
  border-radius: 25%;
  background: linear-gradient(157deg, #FFFFFF 0%, #F4F6FA 38%, #DFE4EC 100%);
  box-shadow:
    0 1px 0 #D3D9E3, 0 2px 0 #C8CFDA, 0 3px 0 #BDC5D2,
    0 4px 0 #B3BBCA, 0 5px 0 #A9B2C2,                 /* the side wall */
    0 10px 14px rgba(0, 0, 0, .45),
    0 20px 30px rgba(0, 0, 0, .40),                    /* cast shadow */
    inset 0 1.5px 0 rgba(255, 255, 255, 1),            /* top rim light */
    inset 0 -1px 0 rgba(11, 14, 20, .1);
  transition: box-shadow var(--t-base) var(--ease), transform var(--t-base) var(--ease);
}
.orb-tile::after {                                     /* specular sheen */
  content: ''; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  background: linear-gradient(148deg,
    rgba(255,255,255,.9) 0%, rgba(255,255,255,.35) 24%,
    rgba(255,255,255,0) 46%, rgba(11,14,20,.05) 100%);
}
.orb-tile svg {
  width: 52%; height: 52%; position: relative; z-index: 1;
  filter: drop-shadow(0 1px 1px rgba(11, 14, 20, .28));
}
.orb-app:hover .orb-tile, .orb-app:focus-visible .orb-tile,
.orb-app.active .orb-tile {
  transform: translateY(-3px);
  box-shadow:
    0 1px 0 #D3D9E3, 0 2px 0 #C8CFDA, 0 3px 0 #BDC5D2,
    0 4px 0 #B3BBCA, 0 5px 0 #A9B2C2,
    0 16px 22px rgba(0, 0, 0, .5), 0 26px 40px rgba(0, 0, 0, .42),
    inset 0 1.5px 0 rgba(255, 255, 255, 1),
    0 0 0 2px rgba(124, 92, 230, .6), 0 0 30px rgba(124, 92, 230, .55);
}
.orb-app:focus-visible { outline: 2px solid var(--iris); outline-offset: 4px; border-radius: 30%; }

/* ---- the featured card ---- */
.orb-card {
  align-self: center; justify-self: center; width: min(268px, 100%);
  padding: var(--s-6);
  border-radius: 22px;
  background: linear-gradient(165deg, rgba(30,24,58,.92), rgba(14,17,25,.92));
  border: 1px solid rgba(160, 140, 240, .32);
  box-shadow: 0 24px 60px rgba(0,0,0,.5), 0 0 46px rgba(124, 92, 230, .18);
}
.orb-card-tile {
  display: grid; place-items: center; width: 54px; height: 54px; border-radius: 15px;
  background: linear-gradient(157deg, #FFFFFF 0%, #F4F6FA 38%, #DFE4EC 100%);
  box-shadow: 0 1px 0 #D3D9E3, 0 2px 0 #C8CFDA, 0 3px 0 #BDC5D2, 0 4px 0 #B3BBCA,
              0 10px 18px rgba(0,0,0,.45), inset 0 1.5px 0 rgba(255,255,255,1);
}
.orb-card-tile svg { width: 56%; height: 56%; }
.orb-card-name { font-size: 26px; font-weight: 700; margin-top: var(--s-4); color: var(--white); }
.orb-card-rule {
  display: block; width: 46px; height: 2px; border-radius: 2px; margin: var(--s-3) 0;
  background: var(--gradient);
}
.orb-card-use { font-size: 15px; line-height: 1.55; color: var(--steel); min-height: 3.1em; }
.orb-dots { display: flex; gap: 7px; margin-top: var(--s-4); }
.orb-dot {
  width: 6px; height: 6px; border-radius: 50%; background: rgba(255,255,255,.2);
  transition: background-color var(--t-base) var(--ease);
}
.orb-dot.on { background: var(--iris); }
/* the card swaps content, so cross-fade it rather than sliding anything */
.orb-card.swapping .orb-card-tile,
.orb-card.swapping .orb-card-name,
.orb-card.swapping .orb-card-use { opacity: 0; }
.orb-card-tile, .orb-card-name, .orb-card-use { transition: opacity 200ms var(--ease); }

/* ---- the dock ---- */
.dock { margin-top: clamp(28px, 4vw, 52px); display: flex; justify-content: center; }
.dock-row::-webkit-scrollbar { display: none; }
.dock-row {
  display: flex; justify-content: center; gap: 8px; list-style: none;
  padding: 12px 14px; border-radius: 20px;
  max-width: 100%; overflow-x: auto; scrollbar-width: none;
  background: rgba(255, 255, 255, .04);
  border: 1px solid var(--dark-line);
}
.dock-tile {
  display: grid; place-items: center; width: 32px; height: 32px; border-radius: 9px;
  flex: none;
  background: linear-gradient(157deg, #FFFFFF 0%, #F4F6FA 38%, #DFE4EC 100%);
  box-shadow: 0 1px 0 #CFD6E1, 0 2px 0 #C2CAD7, 0 3px 0 #B6BFCD,
              0 6px 10px rgba(0,0,0,.45), inset 0 1px 0 rgba(255,255,255,1);
  transition: transform var(--t-fast) var(--ease);
}
.dock-tile:hover { transform: translateY(-2px); }
.dock-tile svg { width: 56%; height: 56%; }

.orbit-sec .works-legal {
  text-align: center; max-width: 640px; margin: var(--s-6) auto 0; color: var(--steel);
}

@media (max-width: 1039px) {
  .orbit-stage { aspect-ratio: 16 / 11.5; }
  .orb-card { margin-top: var(--s-2); }
}
@media (max-width: 620px) {
  .orbit-stage { aspect-ratio: 1 / 1; min-height: 340px; }
  .dock-tile { width: 30px; height: 30px; }
}

/* ---------- directional reveals — elements arrive from the side they belong to ------- */
.reveal-l, .reveal-r, .reveal-scale { opacity: 0; }
.reveal-l { transform: translateX(-30px); }
.reveal-r { transform: translateX(30px); }
.reveal-scale { transform: scale(.965); }
.reveal-l.in, .reveal-r.in, .reveal-scale.in {
  opacity: 1; transform: none;
  transition: opacity 520ms var(--ease-out), transform 620ms var(--ease-out);
}
/* the long-travel reveals get a touch more time than the 280ms UI budget — they are
   scenery, not controls, and §8.2's ceiling governs interface response. */
.reveal.in { transition-duration: 460ms, 560ms; }

/* ---------- stagger — children arrive in sequence, like lights coming on ------------- */
.stagger > * { opacity: 0; transform: translateY(18px); }
.stagger.in > * {
  opacity: 1; transform: none;
  transition: opacity 480ms var(--ease-out), transform 560ms var(--ease-out);
  transition-delay: calc(var(--i, 0) * 55ms);
}
/* scattered arrival, so a grid doesn't read as a mechanical sweep */
.stagger.scatter.in > * { transition-delay: calc(var(--d, 0) * 1ms); }

/* ---------- drift — a slow vertical float that keeps a static grid alive ------------- */
/* deliberately small: on an aligned grid, anything larger reads as broken layout
   rather than as life. ±3px over 9–14s is felt more than seen. */
@keyframes drift { 0%, 100% { transform: translateY(-3px); } 50% { transform: translateY(3px); } }
/* the drift animation owns `transform` here, so these tiles enter on opacity alone —
   otherwise the entrance transform and the animation fight and the entrance is lost */
.stagger.drift > * { transform: none; }
.stagger.drift.in > * { transition: opacity 480ms var(--ease-out); }
.drift.in > * { animation: drift var(--dur, 7s) var(--ease) infinite; animation-delay: var(--phase, 0s); }

/* ---------- hero: entrance on load, then scroll-linked departure --------------------- */
.hero-head > * { opacity: 0; transform: translateY(20px); }
.is-loaded .hero-head > * {
  opacity: 1; transform: none;
  transition: opacity 620ms var(--ease-out), transform 720ms var(--ease-out);
  transition-delay: calc(var(--i, 0) * 90ms);
}
.hud-shell {
  opacity: 0; transform: translateY(28px);
  will-change: transform;
}
.is-loaded .hud-shell {
  opacity: 1; transform: none;
  transition: opacity 700ms var(--ease-out) 320ms, transform 800ms var(--ease-out) 320ms;
}
/* once scrolling starts, JS drives .hud-shell's transform directly — the transition
   above is cleared so it tracks the scroll position 1:1 rather than lagging behind it */
.hud-shell.tracking { transition: none; }

/* ---------- scroll cue — the invitation to keep going -------------------------------- */
.scroll-cue {
  display: flex; justify-content: center; margin-top: var(--s-12);
  transition: opacity var(--t-slow) var(--ease);
}
.scroll-cue .track {
  width: 24px; height: 38px; border-radius: var(--r-pill);
  border: 1px solid var(--dark-line-strong);
  display: flex; justify-content: center; padding-top: 8px;
}
.scroll-cue .bead {
  width: 3px; height: 7px; border-radius: var(--r-pill); background: var(--steel);
  animation: bead 2s var(--ease) infinite;
}
@keyframes bead { 0% { opacity: 0; transform: translateY(-3px); } 40% { opacity: 1; } 100% { opacity: 0; transform: translateY(13px); } }

/* ---------- nav retreats on the way down, returns on the way up ---------------------- */
.nav { transform: translateY(0); transition: transform var(--t-slow) var(--ease), border-color var(--t-base) var(--ease), background-color var(--t-base) var(--ease); }
.nav.hidden { transform: translateY(-100%); }

/* ---------- §11.0 Reduce Motion — movement becomes a quick cross-fade, nothing is lost ---------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
  .reveal, .reveal-l, .reveal-r, .reveal-scale,
  .stagger > *, .hero-head > *, .hud-shell { opacity: 0; transform: none !important; }
  .reveal.in, .reveal-l.in, .reveal-r.in, .reveal-scale.in,
  .stagger.in > *, .is-loaded .hero-head > *, .is-loaded .hud-shell {
    opacity: 1; transition: opacity 200ms linear !important; transition-delay: 0ms !important;
  }
  .hud-result { transform: none; transition: opacity 200ms linear; }
  .wave i, .is-live .wave i { animation: none; transform: scaleY(.45) !important; }
  .is-live .rec-dot { animation: none; }
  .drift.in > * { animation: none; }
  .hero-laptop { animation: none; }
  .hero-laptop-tilt { transform: none !important; transition: none; }
  .hero-mac { opacity: 0; transform: none; }
  .is-loaded .hero-mac { opacity: 1; transition: opacity 200ms linear; }
  /* the marquee becomes a plain centred grid — one copy of each icon, no movement */
  .marq { -webkit-mask-image: none; mask-image: none; overflow: visible; }
  .marq-track { animation: none !important; width: 100%; flex-wrap: wrap; justify-content: center; }
  .marq .dup { display: none; }
  .scroll-cue { display: none; }          /* an animated invitation with no animation is just clutter */
  .nav.hidden { transform: none; }        /* never move the nav out from under someone */
}

/* ---------- §8.0 Reduce Transparency — swap frosted panels for solid fills ---------- */
@media (prefers-reduced-transparency: reduce) {
  .nav { background: var(--ink); -webkit-backdrop-filter: none; backdrop-filter: none; }
}

/* ---------- long-form document pages (help, privacy, terms) ---------- */
  /* The shared stylesheet paints the page light; these docs are a dark surface end
     to end, so the ink has to reach the body or a white band shows between sections.
     Scoped to .doc-page — unscoped, it painted the marketing pages ink too, which
     left every heading that inherits --ink invisible on its own background. */
  .doc-page { background: var(--ink); }
  .doc-hero h1, .doc-body h2, .doc-body h3 { text-wrap: balance; }
  .doc { max-width: 760px; margin: 0 auto; padding: 0 var(--s-6); }
  .doc-hero { background: var(--ink); color: var(--white); padding: clamp(72px,9vw,120px) 0 clamp(40px,5vw,64px); }
  .doc-body { background: var(--ink); color: var(--off-white); padding-bottom: clamp(64px,8vw,110px); }
  .doc h1 { font-size: clamp(34px,5vw,52px); font-weight: 200; letter-spacing: -.035em; color: var(--white); }
  .doc h2 { font-size: clamp(20px,2.4vw,26px); font-weight: 500; color: var(--white);
            margin: 44px 0 6px; letter-spacing: -.02em; }
  .doc h3 { font-size: 16px; font-weight: 600; color: var(--white); margin: 26px 0 4px; }
  .doc p, .doc li { color: var(--steel); font-size: 15.5px; line-height: 1.7; }
  .doc a { color: var(--azure); }
  .doc ul, .doc ol { margin: 8px 0 0 20px; }
  .doc li { margin-bottom: 6px; }
  .doc code, .doc kbd {
    font-family: 'JetBrains Mono', ui-monospace, Menlo, monospace; font-size: 13px;
    background: rgba(255,255,255,.06); border: 1px solid var(--dark-line);
    border-radius: 6px; padding: 1px 6px; color: var(--off-white);
  }
  .doc hr { border: 0; border-top: 1px solid var(--dark-line); margin: 48px 0 0; }
  .doc-lede { font-size: 18px; color: var(--steel); margin-top: 14px; }
  .doc-back { display: inline-block; margin-bottom: 22px; font-size: 14px; color: var(--steel); text-decoration: none; }
  .doc-back:hover { color: var(--white); }
  .doc-contact { margin-top: 40px; padding: 20px 22px; border: 1px solid var(--dark-line);
                 border-radius: 14px; background: rgba(255,255,255,.03); }
  .doc-contact p { margin: 0; }

/* ============================================================================
   GATE PAGES — /get and /welcome
   The signup and post-checkout surfaces. Deliberately the menu bar panel's
   language rather than a checkout page's: near-black ground, one soft purple
   bloom, a single rounded panel, purple only on the primary action. Reuses the
   existing tokens and .btn styles, so it stays in step if those change.
   ========================================================================== */
.gate-page { background: var(--ink); color: var(--off-white); }
.gate-wrap {
  min-height: 100vh; display: flex; align-items: center; justify-content: center;
  padding: clamp(32px, 6vw, 72px) var(--s-6); position: relative; overflow: hidden;
}
/* The bloom behind the panel — the same breathing purple as the hero artwork,
   at low strength so it reads as depth, not decoration. */
.gate-wrap::before {
  content: ""; position: absolute; inset: -20% -10% auto; height: 70%;
  background: radial-gradient(46% 52% at 50% 0%,
    rgba(124, 92, 230, .26) 0%, rgba(78, 161, 230, .10) 46%, transparent 74%);
  filter: blur(20px); pointer-events: none;
}
.gate-card {
  position: relative; z-index: 1; width: 100%; max-width: 520px;
  background: linear-gradient(180deg, #171C25 0%, var(--obsidian) 100%);
  border: 1px solid var(--dark-line); border-radius: var(--r-panel, 22px);
  padding: clamp(28px, 4vw, 40px);
  box-shadow: 0 30px 80px rgba(0, 0, 0, .45);
}
.gate-brand { display: flex; align-items: center; gap: 10px; margin-bottom: var(--s-8); }
.gate-eyebrow { color: var(--steel); font-size: 11px; margin-bottom: 10px; }
.gate-title {
  font-size: clamp(28px, 3.6vw, 38px); font-weight: 200; letter-spacing: -.035em;
  color: var(--white); margin: 0 0 12px; text-wrap: balance;
}
.gate-sub { color: var(--steel); font-size: 15px; line-height: 1.65; margin: 0 0 var(--s-6); }

/* Trial disclosure. Full-size text on its own panel — this is an auto-renewing
   trial, so the terms sit next to the action, not in fine print below it. */
.gate-note {
  background: rgba(124, 92, 230, .10); border: 1px solid rgba(124, 92, 230, .30);
  border-radius: 14px; padding: 16px 18px; margin-bottom: var(--s-6);
}
.gate-note p { color: var(--off-white); font-size: 13.5px; line-height: 1.6; margin: 0 0 8px; }
.gate-note p:last-child { margin-bottom: 0; }
.gate-note strong { color: var(--white); }

.gate-form { display: flex; flex-direction: column; gap: 6px; }
.gate-label { font-size: 12px; color: var(--steel); margin-top: 12px; }
.gate-optional { color: var(--graphite-text, #6B7280); }
.gate-input {
  background: rgba(255, 255, 255, .04); border: 1px solid var(--dark-line);
  border-radius: 10px; padding: 12px 14px; color: var(--white);
  font: inherit; font-size: 15px; width: 100%;
}
.gate-input::placeholder { color: #5B6472; }
.gate-input:focus-visible { outline: 2px solid var(--iris); outline-offset: 1px; border-color: transparent; }

.gate-dl { width: 100%; margin-top: var(--s-6); text-align: center; }
.gate-fineprint { font-size: 12px; color: var(--steel); line-height: 1.55; margin-top: 12px; }
.gate-meta { font-size: 11px; color: var(--steel); text-align: center; margin-top: 12px; }

.gate-steps { margin: var(--s-8) 0 0; padding-left: 20px; }
.gate-steps li { color: var(--steel); font-size: 14px; line-height: 1.6; margin-bottom: 10px; }
.gate-steps strong { color: var(--white); font-weight: 600; }

.gate-foot {
  display: flex; flex-wrap: wrap; gap: var(--s-2) var(--s-6);
  margin-top: var(--s-8); padding-top: var(--s-6); border-top: 1px solid var(--dark-line);
}
.gate-foot a, .gate-alt a { font-size: 13px; }
.gate-alt { font-size: 13px; color: var(--steel); margin-top: var(--s-6); text-align: center; }

/* The gate pages carry only the legal footer, with no hero band above it. */
.gate-page footer { border-top: 1px solid var(--dark-line); padding: var(--s-8) 0; }
.gate-page .foot-bot { margin-top: 0; border-top: 0; padding-top: 0; }

@media (max-width: 620px) {
  .gate-card { padding: 24px 20px; border-radius: 18px; }
  .gate-foot { flex-direction: column; gap: var(--s-2); }
}

/* Disclosure line under a pricing CTA — an auto-renewing trial has to say so
   where the button is, at a size people actually read. */
.pc-disclose {
  font-size: 12px; line-height: 1.55; color: var(--steel);
  margin-top: 10px; text-align: center;
}
.pc-disclose strong { color: var(--off-white); font-weight: 600; }
.hero-disclose { font-size: 12.5px; color: var(--steel); margin-top: 12px; line-height: 1.55; }

/* Section headings and body inside a gate card (used by /account). */
.gate-h2 {
  font-size: 15px; font-weight: 600; color: var(--white);
  margin: var(--s-8) 0 8px;
}
.gate-body { color: var(--steel); font-size: 14px; line-height: 1.65; margin: 0 0 10px; }
.gate-body strong, .gate-list strong { color: var(--off-white); font-weight: 600; }
.gate-list { margin: 0 0 var(--s-4) 20px; }
.gate-list li { color: var(--steel); font-size: 14px; line-height: 1.6; margin-bottom: 6px; }
/* Numbered variant of .gate-list — used for the cancellation steps, where order
   is the information rather than decoration. */
.gate-ol { list-style: decimal; }

/* ---------- hardware compatibility notice ----------------------------------
   Injected by main.js only when the visitor is confidently on an Intel Mac.
   Sits above download and purchase buttons on both the light marketing bands
   and the dark gate pages, so it carries its own colours rather than
   inheriting a ground it cannot predict. */
.compat-warn {
  display: flex; gap: 10px; align-items: flex-start; text-align: left;
  margin: 0 0 var(--s-5); padding: 12px 14px;
  border: 1px solid rgba(245, 163, 16, .42);
  background: rgba(245, 163, 16, .11);
  border-radius: 12px;
  font-size: 14px; line-height: 1.55;
  color: #7A4E08;
}
.compat-warn b { display: block; margin-bottom: 2px; color: #5E3C06; }
.compat-ico { flex: none; color: var(--warning); font-size: 15px; line-height: 1.45; }

/* On every dark surface the same amber has to lighten to stay legible. */
.band-dark .compat-warn, .gate-page .compat-warn,
.workspace .compat-warn, .orbit-sec .compat-warn {
  color: #F0CE96; border-color: rgba(245, 163, 16, .38); background: rgba(245, 163, 16, .13);
}
.band-dark .compat-warn b, .gate-page .compat-warn b,
.workspace .compat-warn b, .orbit-sec .compat-warn b { color: #FAE3BE; }
