/* ==========================================================================
   Dictorio — "The Better Echo" scroll journey — VISUAL SYSTEM v2 (rev. 4)
   Source of truth: site/design-spec.md rev 3 + revision round 1
   (site/proposals/2026-07-07-ux-spec-round1.md §1–§6, creative-round1 §3–§7,
   decision-package RULINGS). Board: site/design/v2/_full-board.png.
   Doctrine: one continuous navy world, value shifts only; glows are earned,
   not default (whitelist: S8 rings · S9 terminal lamp · S11
   sunrise); mono-grey = raw voice, Inter white = Dictorio's output;
   the parrot is frame-swap-only and never deformed.
   De-blob law (ux-spec §6): full-shadow .glass is reserved for real
   screenshots in device chrome and for accordions; text content sits on
   flat navy with glyph + typography.
   ========================================================================== */

/* ---------- fonts (single variable subsets, swap) ---------- */
@font-face {
  font-family: "InterVariable";
  src: url("../assets/fonts/InterVariable-subset.woff2") format("woff2-variations");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "JetBrainsMonoVariable";
  src: url("../assets/fonts/JetBrainsMono-subset.woff2") format("woff2-variations");
  font-weight: 100 800;
  font-style: normal;
  font-display: swap;
}

/* ---------- tokens (§1.3) ---------- */
:root {
  --navy-base: #1d2440;             /* THE canvas — canonical rgb(29,36,64) */
  --navy-deep: #151a30;             /* night scenes 8-9, vignette edges */
  --navy-lift: #252d4e;             /* "daylight" scenes 3-6 */
  --ink: #f4f6fb;
  --ink-76: rgba(244, 246, 251, 0.76);
  --ink-55: rgba(244, 246, 251, 0.55);
  --ink-52: rgba(244, 246, 251, 0.52);
  --ink-40: rgba(244, 246, 251, 0.4);
  --mint: #8ce8c8;
  --emerald: #3ecf8e;
  --teal: #2fb8a6;                  /* gradient partner of mint only */
  --coral: #ff7a66;                 /* CTA-only */
  --amber: #ffc24d;                 /* typographic amber = the 4x anchor ONLY (no exemptions —
                                       the D2 gradient-wordmark exemption is superseded by R2-1) */
  --card: rgba(255, 255, 255, 0.045);
  --card-edge: rgba(255, 255, 255, 0.09);
  --font-sans: "InterVariable", -apple-system, BlinkMacSystemFont, "SF Pro Display", "Helvetica Neue", "Segoe UI", Roboto, sans-serif;
  --font-mono: "JetBrainsMonoVariable", ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;
  /* per-scene parrot presence (spec §1.8 hero-grade vs supporting) */
  --pw-hero: clamp(84px, 8vw, 104px);   /* perched ON the Perch bar (109px capture) — bird ≤ bar */
  --pw-s2: clamp(120px, 15vw, 200px);
  --pw-s3: clamp(110px, 12vw, 160px);
  --pw-s5: clamp(100px, 12vw, 160px);
  --pw-s6: clamp(100px, 11vw, 150px);
  --pw-s65: clamp(180px, 22vw, 300px);
  --pw-s7: clamp(130px, 17vw, 220px);
  --pw-s8: clamp(96px, 10vw, 130px);    /* reduced: perches on the STOP sign, not over it */
  --pw-s9: clamp(96px, 11vw, 140px);
  --pw-s10: clamp(110px, 13vw, 170px);
  --pw-s11: clamp(220px, 30vw, 420px);
}

* { margin: 0; padding: 0; box-sizing: border-box; }
html { scroll-behavior: smooth; scroll-padding-top: 62px; /* gate-fix 4b-2: anchor targets clear the fixed 54px chapter bar */ }
body {
  font-family: var(--font-sans);
  background: var(--navy-base);
  color: var(--ink);
  font-size: 19px;
  font-weight: 400;
  line-height: 1.6;
  overflow-x: hidden;
  overflow-anchor: none; /* pinned scenes swap content on scroll — browser scroll anchoring
                            would fight the reader (observed: phantom scroll jumps); we manage
                            positions ourselves and never move the viewport */
  -webkit-font-smoothing: antialiased;
}
img { max-width: 100%; height: auto; }
a { color: var(--mint); }

/* visually hidden (a11y live regions) */
.vh {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ---------- type scale (§1.1) ---------- */
.wrap { max-width: 1120px; margin: 0 auto; padding: 0 24px; width: 100%; }
.text-col { max-width: 720px; }
h1 {
  font-size: clamp(44px, 7vw, 84px);
  font-weight: 650; line-height: 1.02; letter-spacing: -0.025em;
  color: var(--ink); max-width: 14ch;
}
h2 {
  font-size: clamp(34px, 4.6vw, 56px);
  font-weight: 630; line-height: 1.05; letter-spacing: -0.02em;
  color: var(--ink); margin-bottom: 24px;
}
h3 { font-size: clamp(20px, 2vw, 24px); font-weight: 600; line-height: 1.2; letter-spacing: -0.01em; }
.sub { font-size: clamp(17px, 1.6vw, 19px); color: var(--ink-76); max-width: 62ch; }
.kill-line {
  font-size: clamp(24px, 2.9vw, 34px); font-weight: 560; line-height: 1.25;
  letter-spacing: -0.01em; margin-bottom: 24px; max-width: 26ch;
}
.kill-line em { color: var(--mint); font-style: italic; }
.eyebrow {
  font-size: 14px; font-weight: 550; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--mint); margin-bottom: 24px;
}
.microcopy { font-size: 14px; font-weight: 450; color: var(--ink-52); margin-top: 1.4em; line-height: 1.5; }
.hero-copy .microcopy { margin-top: 1em; }
.footnote { font-size: 14px; font-weight: 450; color: var(--ink-52); margin-top: 1.6em; max-width: 52em; line-height: 1.5; }
.fn-ref { text-decoration: none; color: var(--ink-52); }
.caption { font-size: 14px; font-weight: 450; color: var(--ink-52); margin-top: 1.6em; }
.mono { font-family: var(--font-mono); font-weight: 460; }

/* amber is typographically reserved for the 4x anchor — flat, no glow (§1.5) */
.anchor { color: var(--amber); font-weight: 650; text-shadow: none; }

/* ---------- THE WORDMARK — SINGLE COLOR (R2-1, supersedes D2 after the owner's live review) ----------
   Owner: "Dictorio" is one color everywhere, logo stations included.
   ARCHIVED for the record — the D2 crest-gradient lockup (do not delete this comment):
     .wordmark {
       background: linear-gradient(90deg, var(--coral) 0%, var(--amber) 42%, var(--teal) 80%, var(--mint) 94%);
       -webkit-background-clip: text; background-clip: text;
       -webkit-text-fill-color: transparent; color: transparent;
     }
*/
.wordmark {
  display: inline-block;
  font-weight: 650; letter-spacing: -0.02em; text-decoration: none; line-height: 1.2;
  color: var(--ink);
}
.wordmark--nav { font-size: 22px; }
.wordmark--finale { font-size: 24px; margin-bottom: 20px; letter-spacing: 0; }

/* ---------- SKIP-LINK (round 4b, topnav spec — a11y blocker fix) ----------
   Off-screen until keyboard focus, then top-left above everything. */
.skip-link {
  position: fixed; top: 10px; left: 10px; z-index: 90;
  transform: translateY(-200%);
  background: var(--navy-deep); color: var(--ink);
  font-size: 15px; font-weight: 550; text-decoration: none;
  padding: 10px 16px; border-radius: 10px; border: 1px solid var(--card-edge);
}
.skip-link:focus-visible { transform: none; outline: 2px solid var(--mint); outline-offset: 2px; }

/* ---------- CHAPTER BAR (round 4b, topnav spec §2/§3/§5) ----------
   One slim fixed bar, three states:
   · base (above the hero): transparent, wordmark ONLY — the Perch performs;
   · .is-on (between hero and finale): navy + blur separation; anchors + CTA
     materialize with the Round-4 entrance language (240ms, translateY -6→0);
   · .is-away (finale): the whole bar yields to the finale wordmark station.
   No scroll-direction awareness — visibility depends only on WHERE you are. */
.nav {
  position: fixed; top: 0; left: 0; right: 0; z-index: 70;
  display: flex; align-items: center; justify-content: space-between; gap: 18px;
  min-height: 54px;
  padding: 0 clamp(20px, 4vw, 48px);
  border-bottom: 1px solid transparent;
  transition: background 0.24s ease, border-color 0.24s ease,
    opacity 0.24s ease, transform 0.24s ease, visibility 0.24s;
}
html.js .nav.is-on {
  background: rgba(29, 36, 64, 0.82);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  border-bottom-color: var(--card-edge);
}
/* gate-fix 4b-1 (WCAG focus order): visibility rides the fade — it flips at
   the END of the fade-out and INSTANTLY on show, so hidden controls are out
   of the tab order (keyboard users never Tab into invisible links). */
html.js .nav.is-away { opacity: 0; transform: translateY(-6px); pointer-events: none; visibility: hidden; }
.nav-sections { display: flex; gap: 24px; }
.nav-sections a {
  color: var(--ink-76); text-decoration: none; font-size: 15px; font-weight: 550;
  line-height: 1; padding: 6px 2px;
}
.nav-sections a:hover, .nav-sections a:focus-visible { color: var(--mint); }
.nav-sections a:focus-visible { outline: 2px solid var(--mint); outline-offset: 2px; }
.nav-sections a[aria-current="page"] {
  color: var(--mint);
  text-decoration: underline; text-decoration-thickness: 2px;
  text-decoration-color: var(--mint); text-underline-offset: 7px;
}
/* CTA — the merged sticky pill: coral through the story, DE-ESCALATING to
   ghost/mint over #pricing/#finale (one coral per viewport, and the download
   point never disappears — spec §2). */
.nav-cta {
  display: inline-block; text-decoration: none; white-space: nowrap;
  font-weight: 600; font-size: 14px; letter-spacing: -0.01em; line-height: 1;
  background: var(--coral); color: #151a30;
  padding: 10px 18px; border-radius: 999px;
  border: 1px solid transparent;
  transition: background 0.24s ease, color 0.24s ease, border-color 0.24s ease, filter 0.15s ease;
}
.nav-cta:hover { filter: brightness(1.06); }
.nav-cta:focus-visible { outline: 2px solid var(--mint); outline-offset: 2px; }
/* brand-gate fix: explicit mint OUTLINE at rest (spec §5 "ghost/mint-outline")
   so the de-escalated state still reads as a button, not a text link */
.nav-cta.is-calm {
  background: transparent; color: var(--mint);
  border: 1px solid rgba(140, 232, 200, 0.55); filter: none;
}
.nav-cta.is-calm:hover { border-color: var(--mint); }
/* above the hero (JS mode): only the wordmark — anchors + CTA wait off-stage,
   then materialize with the bar. visibility:hidden keeps them OUT of the tab
   order until the bar is on (gate-fix 4b-1). */
html.js .nav .nav-sections, html.js .nav .nav-cta {
  opacity: 0; transform: translateY(-6px); pointer-events: none; visibility: hidden;
  transition: opacity 0.24s ease, transform 0.24s ease, visibility 0.24s;
}
html.js .nav.is-on .nav-sections, html.js .nav.is-on .nav-cta {
  opacity: 1; transform: none; pointer-events: auto; visibility: visible;
}
/* no-JS: static sticky bar, always complete (hash anchors work; CTA → #finale) */
html:not(.js) .nav {
  position: sticky;
  background: rgba(29, 36, 64, 0.94); border-bottom-color: var(--card-edge);
}
/* gate-fix 4b-3: 5 chapter slots must fit 900–1100px without wrapping —
   tighten gaps/type before the mobile cut */
@media (max-width: 1100px) {
  .nav { gap: 14px; }
  .nav-sections { gap: 15px; }
  .nav-sections a { font-size: 14px; }
}
/* tablet band (721–900px): all 5 chapter anchors still show — tighten gaps/type
   further so wordmark + anchors + CTA fit ONE line without cramping/clipping down
   to 721px (round 5a mobile pass, L5). Below 721px they're hidden entirely. */
@media (max-width: 900px) and (min-width: 721px) {
  .nav { gap: 12px; }
  .nav-sections { gap: 12px; }
  .nav-sections a { font-size: 13.5px; }
}
/* mobile (≤720px, spec §3): wordmark + CTA only — no chapter anchors, no
   hamburger (scroll + thumb beat jump-nav on a phone; nothing left to hide) */
@media (max-width: 720px) {
  .nav-sections { display: none; }
}

/* ---------- buttons (§1.4; twin-coral download pair = the only exception) ---------- */
.cta-row { display: flex; gap: 16px; flex-wrap: wrap; margin-top: 24px; justify-content: center; }
.cta-col { display: flex; flex-direction: column; align-items: center; gap: 8px; }
.cta-sys { font-size: 14px; font-weight: 450; color: var(--ink-52); }
.btn {
  display: inline-block; text-decoration: none; font-weight: 600; font-size: 17px;
  padding: 16px 24px; border-radius: 12px; letter-spacing: -0.01em; line-height: 1;
  transition: transform 0.15s ease, box-shadow 0.15s ease, filter 0.15s ease;
}
.btn--primary { background: var(--coral); color: #151a30; }
.btn--primary:hover { filter: brightness(1.06); box-shadow: 0 8px 28px rgba(255, 122, 102, 0.35); transform: translateY(-1px); }
.btn--ghost { background: transparent; color: var(--ink); border: 1px solid rgba(255, 255, 255, 0.18); }
.btn--ghost:hover { border-color: var(--mint); color: var(--mint); }
.btn:focus-visible, .tab:focus-visible, .app-tile:focus-visible,
.faq summary:focus-visible, .offer-row summary:focus-visible {
  outline: 2px solid var(--mint); outline-offset: 2px;
}
.btn--ghost { cursor: pointer; font-family: inherit; } /* .win-cta is a <button> */

/* ---------- WINDOWS WAITLIST (round 3) — the honest Windows CTA: an inline
   email field revealed under the "coming soon" button. Minimal, no glass. ---------- */
.win-wait {
  display: flex; flex-wrap: wrap; gap: 8px; justify-content: center;
  width: min(320px, 88vw); margin-top: 2px;
}
.win-wait[hidden] { display: none; }
.win-wait input[type="email"] {
  flex: 1 1 170px; min-width: 0;
  font: inherit; font-size: 15px; color: var(--ink);
  padding: 10px 14px; border-radius: 10px;
  background: rgba(255, 255, 255, 0.05); border: 1px solid var(--card-edge);
}
.win-wait input[type="email"]::placeholder { color: var(--ink-40); }
.win-wait input[type="email"]:focus-visible { outline: 2px solid var(--mint); outline-offset: 2px; border-color: var(--mint); }
.win-wait .win-wait-send { font-size: 15px; padding: 11px 16px; }
.win-note { flex-basis: 100%; font-size: 13px; font-weight: 450; color: var(--ink-52); margin: 0; line-height: 1.45; }
.win-note a { color: var(--mint); }
.win-wait.is-done input, .win-wait.is-done .win-wait-send { display: none; } /* after a successful signup only the confirmation line stays */
/* the long waitlist label must fit one column on true phone widths (≤420px) */
@media (max-width: 420px) {
  .win-cta { font-size: 15px; padding: 14px 16px; white-space: normal; line-height: 1.3; max-width: 100%; }
}
/* no-JS: the toggle can't work — show the form permanently (the field + promise line
   are the honest static state; wire a real POST action for no-JS when the endpoint lands) */
html:not(.js) .win-wait[hidden] { display: flex; }

/* ---------- glass card (§1.4) ---------- */
.glass {
  background: var(--card);
  border: 1px solid var(--card-edge);
  border-radius: 20px;
  backdrop-filter: blur(20px);
  box-shadow: 0 24px 64px rgba(0, 0, 0, 0.45), inset 0 1px 0 rgba(255, 255, 255, 0.1);
}
/* screenshot frame — device-accurate chrome (§1.4) */
.shot {
  border-radius: 12px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  box-shadow: 0 32px 80px rgba(0, 0, 0, 0.55);
  display: block;
}
.shot--float { box-shadow: 0 19px 48px rgba(0, 0, 0, 0.33); } /* free-floating pills at 60% */
/* clean alpha window captures (panel_*.png): the capture IS the panel — no border,
   no radius, no background; a subtle drop-shadow that follows the alpha silhouette */
.panel-img { display: block; width: auto; height: auto; filter: drop-shadow(0 14px 28px rgba(0, 0, 0, 0.45)); }

/* round 4b: .sticky-cta (bottom pill) RETIRED — merged into the chapter bar's
   .nav-cta (topnav spec §2). */

/* ==========================================================================
   THE PARROT — fixed flight sprite (desktop scrub). Frame swaps + translate
   only; size steps discretely to the active perch's slot width (never
   animated scaling, never deformation).
   ========================================================================== */
#parrot {
  position: fixed; left: 0; top: 0;
  width: var(--pw-s5); height: auto;
  z-index: 50; pointer-events: none;
  display: none; /* enabled by JS in scrub mode */
  will-change: transform;
}
.perch { display: block; position: relative; width: var(--pw-s5); aspect-ratio: 463 / 512; }
/* SHARED SCALE (frame-integration law, per design/demo/poses-demo.html): 1 source px = same
   on-screen px in EVERY frame. Each perch box is sized for its REST frame (data-basew = that
   frame's natural width, default 463); when JS swaps to another frame it sets the img width to
   naturalW/basew — the bird's body never changes size, only the drawn canvas does. The img is
   bottom-center anchored so the feet stay planted through every swap. */
.parrot-inline {
  display: block; position: absolute; bottom: 0; left: 50%;
  transform: translateX(-50%); /* stage anchoring of the drawing, not a deformation */
  width: 100%; height: auto;
}
html.scrub .parrot-inline { visibility: hidden; }
/* ghost perches: flight waypoints only, never inline sprites */
html:not(.scrub) .perch--ghost { display: none; }
/* per-perch boxes sized for non-canonical rest frames (shared scale × natural canvas) */
.perch--window1, .perch--desk, .perch--quiet { aspect-ratio: 615 / 598; }
.perch--glam { aspect-ratio: 734 / 454; }
.perch--seam { aspect-ratio: 540 / 486; }

/* ==========================================================================
   SCENES — one continuous navy canvas; value/temperature shifts ONLY (§1.5).
   ========================================================================== */
.scene { position: relative; padding: clamp(96px, 12vh, 160px) 0; overflow: hidden; }
.scene .wrap { position: relative; z-index: 2; }

.scene--1 { min-height: 100svh; padding: 84px 0 58px; display: flex; flex-direction: column; justify-content: center; background: var(--navy-base); }
.scene--2 { background: var(--navy-base); }
.scene--3 { background: linear-gradient(180deg, var(--navy-base) 0%, var(--navy-lift) 30%, var(--navy-lift) 100%); }
.scene--4 { background: var(--navy-lift); }
.scene--5 { background: var(--navy-lift); }
.scene--5b { background: var(--navy-lift); }
.scene--6 { background: linear-gradient(180deg, var(--navy-lift) 0%, var(--navy-base) 100%); }
.scene--65 { background: var(--navy-base); }
.scene--7 { background: linear-gradient(180deg, var(--navy-base) 0%, var(--navy-deep) 100%); }
.scene--8 {
  background:
    radial-gradient(140% 100% at 50% 50%, rgba(21, 26, 48, 0) 55%, rgba(13, 17, 32, 0.35) 100%),
    var(--navy-deep);
}
.scene--9 { background: var(--navy-deep); }
.scene--10 { background: linear-gradient(180deg, var(--navy-deep) 0%, var(--navy-base) 100%); }
.scene--11 {
  /* earned glow: the sunrise bloom (whitelist §1.5) — peaks ~12%, dies before mid-frame */
  background:
    radial-gradient(120% 45% at 50% 104%, rgba(255, 194, 77, 0.12) 0%, rgba(140, 232, 200, 0.05) 45%, rgba(29, 36, 64, 0) 68%),
    var(--navy-base);
}

/* ==========================================================================
   PIN & STEP (ux-spec §1) — desktop scrub mode only (html.pinning).
   The wrapper provides the scroll track; the scene stays sticky until every
   step has been seen. No scroll-hijack: JS only READS scrollY.
   ========================================================================== */
html.pinning .pin { position: relative; height: calc(100vh + var(--steps) * var(--stepvh, 78vh)); }
html.pinning .pin > .scene {
  position: sticky; top: 0; min-height: 100svh;
  display: flex; flex-direction: column; justify-content: center;
  justify-content: safe center; /* content taller than the viewport clips at the BOTTOM, never the tab bar */
  padding: 32px 0;
}
/* compact mode for short viewports: a pinned scene must fit 100vh — shrink the
   parrot slot and vertical fat instead of clipping the switcher */
@media (max-height: 960px) {
  html.pinning .pin > .scene h2 { font-size: clamp(28px, 3.4vw, 42px); margin-bottom: 14px; }
  html.pinning .pin--apps > .scene { --pw-s5: clamp(80px, 9vh, 118px); }
  html.pinning .pin--apps .switcher { margin-top: 26px; }
  html.pinning .pin--apps .step-dots, html.pinning .pin .step-dots { margin-top: 16px; }
  html.pinning .pin--apps .demo-app { margin-top: calc(var(--pw-s5) * 1.3 + 8px); }
  html.pinning .pin--apps .tone-caption { margin-top: 14px; }
  html.pinning .pin .echo-stage { margin-top: 28px; }
}

/* step indicator — visible progress affordance (§1.1); decorative twin of the tablist */
.step-dots { display: none; }
html.pinning .step-dots { display: flex; gap: 8px; margin: 26px 0 0; }
.scene--5 .step-dots { justify-content: center; }
.step-dots i {
  width: 8px; height: 8px; border-radius: 50%;
  background: rgba(255, 255, 255, 0.18);
  transition: background 0.2s ease, transform 0.2s ease;
}
.step-dots i.on { background: var(--mint); transform: scale(1.25); }

/* ---------- scroll-enter reveals ---------- */
html.js .reveal, html.js .app-tile, html.js .wall li,
html.js .offer-row {
  opacity: 0; transform: translateY(22px);
  transition: opacity 0.6s ease, transform 0.6s ease;
}
html.js .scene.on .reveal, html.js .scene.on .app-tile,
html.js .scene.on .wall li,
html.js .scene.on .offer-row { opacity: 1; transform: none; }
/* R2-9 — the scene BUILDS around the parrot: the bird lands first (inline frame / sprite is
   immediate), copy and objects compose AFTER it (base +0.35s), never a finished empty slot.
   (Round 4: S3 beats + S6 desk rows left this generic system — they build as counted
   narrative beats in their own sections below.) */
html.js .scene.on .app-tile:nth-child(1) { transition-delay: 0.35s; }
html.js .scene.on .app-tile:nth-child(2) { transition-delay: 0.45s; }
html.js .scene.on .app-tile:nth-child(3) { transition-delay: 0.55s; }
html.js .scene.on .app-tile:nth-child(4) { transition-delay: 0.65s; }
html.js .scene.on .app-tile:nth-child(5) { transition-delay: 0.75s; }
html.js .scene.on .app-tile:nth-child(6) { transition-delay: 0.85s; }
html.js .scene--7 .lang-col { opacity: 0; transform: translateY(14px); transition: opacity 0.55s ease 0.35s, transform 0.55s ease 0.35s; }
html.js .scene--7.on .lang-col { opacity: 1; transform: none; }

/* ==========================================================================
   ROUND 4 — THE TEXT BUILD (owner 2026-07-08, page-wide diagnosis): every
   scene's heading block COMPOSES on entry — from blur, staggered. JS tags the
   elements (.bb + --bb-d inline delay) at boot, ONLY when motion is allowed;
   no-JS and reduced-motion therefore see everything by construction.
   Triggered (never scrolled-scrubbed — scrubbed text is unreadable).
   Variants: .bb--far = arrives from depth (scale+blur) · .bb--lift =
   rise+fade only (containers that hold the parrot — the bird may translate,
   never scale/blur, canon) · .bb--flat = opacity only (large read surfaces).
   ========================================================================== */
html.js .bb {
  opacity: 0; transform: translateY(16px); filter: blur(7px);
  transition:
    opacity 0.56s cubic-bezier(0.22, 1, 0.36, 1) var(--bb-d, 0s),
    transform 0.56s cubic-bezier(0.22, 1, 0.36, 1) var(--bb-d, 0s),
    filter 0.56s cubic-bezier(0.22, 1, 0.36, 1) var(--bb-d, 0s);
}
html.js .bb--far { transform: scale(0.94) translateY(10px); }
html.js .bb--lift { filter: none; }
html.js .bb--flat { transform: none; filter: none; }
html.js .scene.on .bb { opacity: 1; transform: none; filter: none; }
/* the logo wall reveals row by row (~60ms stagger per row of 6) */
html.js .scene.on .wall li:nth-child(n+7)  { transition-delay: 0.06s; }
html.js .scene.on .wall li:nth-child(n+13) { transition-delay: 0.12s; }
html.js .scene.on .wall li:nth-child(n+19) { transition-delay: 0.18s; }
html.js .scene.on .wall li:nth-child(n+25) { transition-delay: 0.24s; }

/* ==========================================================================
   SCENE 1 — HERO (flat navy, NO glow; ux-spec §2 rev: Perch bar + bird ON it)
   ========================================================================== */
.scene--1 { text-align: center; }
.hero-copy { display: flex; flex-direction: column; align-items: center; }
.hero-copy h1 { margin-left: auto; margin-right: auto; }
.hero-copy .sub { margin: 24px auto 0; }
.hero-copy .footnote { margin-left: auto; margin-right: auto; }

/* headroom = the parrot standing on the bar (parrot ≈ 1.1× its width tall, feet overlap 4px) */
.hero-demo { position: relative; margin: calc(var(--pw-hero) * 1.08) auto 0; max-width: 560px; width: 100%; }
.hero-panel { position: relative; width: max-content; margin: 0 auto; }
/* single-bird rule (ux-spec §2.1/§2.2): feet ON the bar's top edge — parrot.bottom == perch.top
   (4px foot overlap); the silhouette never enters the bar, waveform 100% visible. */
.perch--panel {
  position: absolute;
  left: 50%; margin-left: calc(var(--pw-hero) * -0.5);
  bottom: calc(100% - 4px);
  width: var(--pw-hero);
  z-index: 3;
}
/* THE LIVE PERCH BAR (R2-2): faithful DOM re-creation of the app's Perch soundbar —
   the static capture can't animate; the bars move in the app's own rhythm (js: heroTalk).
   Visual reference: assets/app/panel_grzeda.png. */
.hero-bar {
  display: flex; align-items: center; justify-content: center; gap: 2.5px;
  width: 168px; height: 30px; padding: 0 12px;
  border-radius: 999px;
  background: linear-gradient(to bottom, rgba(20, 22, 30, 0.95), rgba(14, 15, 22, 0.95));
  border: 0.5px solid rgba(255, 255, 255, 0.16);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.08);
}
.hero-bar i {
  width: 3px; height: 3px; border-radius: 99px;
  background: linear-gradient(to top, #34d399, #a7f3d0);
}
/* static waveform for no-JS / reduced-motion (JS animates heights live otherwise) */
html:not(.js) .hero-bar i:nth-child(3n) { height: 10px; }
html:not(.js) .hero-bar i:nth-child(4n+1) { height: 14px; }
html:not(.js) .hero-bar i:nth-child(5n+2) { height: 7px; }
.demo-field {
  /* round 5b (L1): flat navy, no card — a single hairline under the dictated line
     (same grammar as S3's landing line), the mint caret is the only signature. */
  margin: 16px auto 0; max-width: 560px; text-align: left;
  padding: 6px 2px 16px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}
.hero-panel-note { font-size: 12px; font-weight: 450; color: var(--ink-40); margin: 8px 0 2px; } /* sits directly under the Perch bar (its label), above the text field */
.echo-line { font-size: 17px; min-height: 3.6em; }
.echo-raw {
  display: block;
  font-family: var(--font-mono); font-weight: 460; font-size: 17px;
  color: var(--ink-55); line-height: 1.55; min-height: 1.55em;
}
html.js .echo-raw.dissolve { text-decoration: line-through; opacity: 0.45; transition: opacity 0.45s ease; }
.echo-clean { display: block; margin-top: 6px; color: var(--ink); font-weight: 600; font-size: 19px; }
html.js .echo-clean { opacity: 0; transition: opacity 0.4s ease; }
html.js .echo-clean.in { opacity: 1; }
html:not(.js) .echo-raw::before { content: "umm so like see I just— I just dictated this"; text-decoration: line-through; }
.caret { display: inline-block; width: 2px; height: 1.1em; background: var(--mint); vertical-align: text-bottom; margin-left: 2px; opacity: 0; }
html.js .caret.blink { opacity: 1; animation: blink 0.9s steps(1) infinite; }
@keyframes blink { 50% { opacity: 0; } }

.scroll-hint { position: absolute; left: 50%; bottom: 14px; transform: translateX(-50%); z-index: 3; }
.scroll-hint span { display: block; width: 22px; height: 36px; border: 2px solid rgba(255, 255, 255, 0.22); border-radius: 12px; position: relative; }
.scroll-hint span::after { content: ""; position: absolute; left: 50%; top: 7px; width: 4px; height: 8px; margin-left: -2px; border-radius: 2px; background: var(--mint); animation: hint 1.6s ease-in-out infinite; }
@keyframes hint { 0%, 100% { transform: translateY(0); opacity: 1; } 55% { transform: translateY(9px); opacity: 0.2; } }

/* ==========================================================================
   SCENE 2 — THE BETTER ECHO (pinned, 3 steps; §2 S2 rev. 3 + ux-spec §1)
   ========================================================================== */
.echo-stage { position: relative; display: grid; grid-template-columns: 1fr 1.1fr; gap: 40px; margin-top: 48px; align-items: start; }
.perch--echo { position: absolute; left: 50%; top: 26%; margin-left: calc(var(--pw-s2) * -0.96); width: var(--pw-s2); z-index: 3; } /* on the seam between the spoken words and the container — never over the written text */
.chips { display: flex; flex-wrap: wrap; gap: 14px 12px; align-content: flex-start; min-height: 200px; padding-top: 8px; }
.chip {
  font-family: var(--font-mono); font-weight: 460; font-size: 15px;
  color: var(--ink-40);
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 10px; padding: 0.35em 0.8em; white-space: nowrap;
  transform: rotate(var(--rot, 0deg));  /* chips may tilt, the parrot never does */
  transition: opacity 0.5s ease, transform 0.5s ease;
}
/* R2-3: once the output has written itself, the spoken words are CONSUMED — they dim, they don't fly */
html.js .chips.spoken .chip { opacity: 0.3; }
.echo-right { position: relative; }
/* R2-3 context containers — the output's real destination: mail window / chat bubble / notes page.
   Device chrome (justified glass per de-blob law), ONE visible per step. */
.ctx-stage { position: relative; min-height: 240px; }
.ctx {
  position: absolute; inset: 0 auto auto 0; width: 100%;
  /* round 5b (L3): light real-app windows — a light body separates itself from
     navy, so NO border (border+shadow+inset was the old placek recipe); ONE soft
     shadow only. Per-app body colors set below. overflow clips the bar to radius. */
  background: #ffffff;
  border-radius: 12px; overflow: hidden;
  box-shadow: 0 24px 64px rgba(0, 0, 0, 0.45);
  opacity: 0; visibility: hidden;
  /* A1 (round 4) — DEPTH STACK: a deselected window RECEDES INTO DEPTH
     (scale down + blur + fade, ease-in, 300ms)… */
  transform: scale(0.88); filter: blur(6px);
  transition: opacity 0.3s cubic-bezier(0.5, 0, 0.8, 0.4),
    transform 0.3s cubic-bezier(0.5, 0, 0.8, 0.4),
    filter 0.3s cubic-bezier(0.5, 0, 0.8, 0.4), visibility 0.3s;
}
/* …and the incoming one ARRIVES: JS preps its start pose (near = in front of
   the glass, far = out of the stack, mirroring scroll direction) without a
   transition, then releases it to settle over 480ms expo-out. */
html.js .ctx.ctx-near { transform: scale(1.1); transition: none; }
html.js .ctx.ctx-far { transform: scale(0.84); transition: none; }
.ctx.is-on {
  opacity: 1; visibility: visible; transform: none; filter: none;
  transition: opacity 0.48s cubic-bezier(0.22, 1, 0.36, 1) 0.1s,
    transform 0.48s cubic-bezier(0.22, 1, 0.36, 1) 0.1s,
    filter 0.48s cubic-bezier(0.22, 1, 0.36, 1) 0.1s;
}
html:not(.js) .ctx { position: relative; opacity: 1; visibility: visible; transform: none; filter: none; margin-bottom: 14px; }
/* light window chrome (round 5b, §2.2): flat light-neutral title bar + REAL macOS
   traffic-light colors — the one change that makes a window read "Mac app" not "panel". */
.ctx-bar {
  display: flex; align-items: center; gap: 7px;
  padding: 10px 14px; font-size: 12.5px; color: #55565c;
  background: #ececf0; border-bottom: 1px solid rgba(0, 0, 0, 0.08);
}
.ctx-bar i { width: 10px; height: 10px; border-radius: 50%; }
.ctx-bar i:nth-child(1) { background: #ff5f57; }
.ctx-bar i:nth-child(2) { background: #febc2e; }
.ctx-bar i:nth-child(3) { background: #28c840; }
.ctx-bar span { margin-left: 6px; }
/* Mail: one blue accent at the bar's right edge (Mail's recognizable color cue) */
.ctx--mail .ctx-bar::after { content: "Send"; margin-left: auto; color: #0a82ff; font-weight: 600; }
.ctx-head { padding: 12px 16px 0; display: grid; gap: 4px; }
.ctx-field { font-size: 13px; color: #1f2127; border-bottom: 1px solid #e4e5e9; padding-bottom: 6px; }
.ctx-field b { color: #8b8e96; font-weight: 550; }
.ctx-body { padding: 16px; font-size: 16px; font-weight: 500; line-height: 1.5; min-height: 120px; color: #1f2127; }
/* Message: warm-paper canvas + WhatsApp-green outgoing bubble (no doodle wallpaper — that would be copying) */
.ctx--chat .ctx-body { background: #efeae2; }
.ctx-body--chat { display: flex; flex-direction: column; align-items: flex-end; justify-content: flex-end; }
.bubble { max-width: 85%; padding: 10px 14px 7px; border-radius: 16px; font-size: 15.5px; }
.bubble--out { background: #d9fdd3; color: #111b21; border-bottom-right-radius: 4px; }
.bubble-meta { display: block; margin-top: 3px; font-size: 11px; color: #7d8a84; text-align: right; } /* grey ticks, not read-receipt blue (too app-specific) */
/* Notes: cream ruled page; the app's own small yellow accent stays strictly inside the window
   (canon amber rule governs DICTORIO's typography, not a depicted app's own color) */
.ctx--note .ctx-bar { background: #f5efdd; }
.ctx--note .ctx-bar span { color: #b8901f; font-weight: 600; }
.ctx--note .ctx-body { color: #3a3427; font-weight: 600; } /* Notes' first-line title behavior */
.ctx-body--note {
  background: repeating-linear-gradient(to bottom, transparent 0, transparent 27px, rgba(120, 100, 40, 0.10) 27px, rgba(120, 100, 40, 0.10) 28px) #fdf9ee;
  line-height: 28px; font-size: 15.5px;
}
/* the output WRITES itself: whole words materialize (shared with S5's Landing Beat) */
.ctx-words .w { opacity: 0; transition: opacity 0.16s ease; }
.ctx-words .w.in { opacity: 1; }
/* Dictorio's ONE signature inside any window — emerald on light bodies (mint is too pale on white) */
.ctx-caret { display: inline-block; width: 2px; height: 1.1em; background: var(--emerald); vertical-align: text-bottom; margin-left: 2px; opacity: 0; }
html.js .ctx.is-on .ctx-caret { opacity: 1; animation: blink 0.9s steps(1) infinite; }
.tabs { display: flex; gap: 8px; margin-top: 20px; }
.tab {
  font: inherit; font-size: 14px; font-weight: 550;
  color: var(--ink-52); background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.14); border-radius: 999px;
  padding: 0.5em 1.1em; min-height: 34px; cursor: pointer;
  transition: color 0.2s ease, border-color 0.2s ease, background 0.2s ease;
}
.tab.is-active { color: #151a30; background: var(--mint); border-color: var(--mint); }
.tabs-hint { font-size: 13px; font-weight: 450; color: var(--ink-40); margin-top: 10px; }

/* static fallback: all three states, nothing hidden (ux-spec §1.3) */
.echo-static { display: none; grid-template-columns: repeat(3, 1fr); gap: 24px; margin-top: 48px; }
.es-item { border-top: 1px solid rgba(255, 255, 255, 0.08); padding-top: 18px; }
.es-tag {
  display: inline-block; font-size: 13px; font-weight: 600; color: #151a30;
  background: var(--mint); border-radius: 999px; padding: 0.2em 0.9em; margin-bottom: 12px;
}
.es-raw { font-family: var(--font-mono); font-weight: 460; font-size: 14px; color: var(--ink-40); margin-bottom: 10px; }
.es-clean { font-size: 16px; font-weight: 500; color: var(--ink); }

/* ==========================================================================
   SCENE 3 — ONE KEY (flat numbered rows on navy — de-blob follow-up).
   The keycap and the parrot are the scene's ONLY objects; no glass cards.
   ========================================================================== */
.scene--3 { text-align: center; }
.beats { list-style: none; max-width: 880px; margin: 64px auto 0; text-align: left; display: grid; gap: 44px; }
.beat { display: grid; grid-template-columns: 56px 170px 1fr; gap: 28px; align-items: center; }
.beat-num {
  font-size: 44px; font-weight: 680; letter-spacing: -0.02em; line-height: 1;
  color: var(--ink-40);
}
.beat-copy h3 { margin-bottom: 6px; }
.beat-copy p { color: var(--ink-76); font-size: 17px; max-width: 52ch; }
.beat-visual { min-height: 110px; display: flex; align-items: center; justify-content: center; }
/* beat 3 object (R2-4): the landing line — dim landed text + blinking caret; the cursor IS the destination */
.land-line {
  display: inline-block; max-width: 100%;
  font-size: 15px; color: var(--ink-55);
  border-bottom: 1px solid rgba(255, 255, 255, 0.1); padding-bottom: 6px;
}
.land-caret { display: inline-block; width: 2px; height: 1.1em; background: var(--mint); vertical-align: text-bottom; margin-left: 2px; animation: blink 0.9s steps(1) infinite; }
/* generic keycap outline, rendered "pressed" (§1.6/§1.9 — JS may platform-label it) */
.keycap {
  width: 88px; height: 88px; border-radius: 18px;
  border: 2px solid rgba(244, 246, 251, 0.7);
  border-bottom-width: 3px;
  transform: translateY(4px);
  box-shadow: 0 3px 0 rgba(244, 246, 251, 0.18), 0 10px 24px rgba(0, 0, 0, 0.35);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-mono); font-weight: 460; font-size: 22px; color: var(--ink-76);
}
.perch--beat2 { width: clamp(100px, 10vw, 130px); }
.scene--3 .microcopy { text-align: center; }

/* A2 (round 4) — the beats enter as COUNTED narrative beats ("raz, dwa,
   trzy"): 600ms apart, each a micro-build — the big number lands first
   (slide from the left, from blur), its visual +140ms, its copy +260ms.
   The beat-2 visual holds the parrot → rise+fade only (canon: the bird may
   translate, never blur/scale). */
html.js .beat-num { opacity: 0; transform: translateX(-14px); filter: blur(6px); }
html.js .beat-copy { opacity: 0; transform: translateY(14px); filter: blur(6px); }
html.js .beat-visual { opacity: 0; transform: translateY(14px); }
html.js .beat-num, html.js .beat-copy, html.js .beat-visual {
  transition: opacity 0.45s cubic-bezier(0.22, 1, 0.36, 1),
    transform 0.45s cubic-bezier(0.22, 1, 0.36, 1),
    filter 0.45s cubic-bezier(0.22, 1, 0.36, 1);
}
html.js .scene--3.on .beat-num, html.js .scene--3.on .beat-copy,
html.js .scene--3.on .beat-visual { opacity: 1; transform: none; filter: none; }
/* brand-gate fix (2026-07-08): chain compressed — the LAST element starts
   ≤1.4s (score law; the scene is unpinned, a steady scroller must not outrun
   the build). Rhythm kept: beats 0.25/0.7/1.15, micro-offsets +0.1/+0.2. */
html.js .scene--3.on .beat:nth-child(1) .beat-num { transition-delay: 0.25s; }
html.js .scene--3.on .beat:nth-child(1) .beat-visual { transition-delay: 0.35s; }
html.js .scene--3.on .beat:nth-child(1) .beat-copy { transition-delay: 0.45s; }
html.js .scene--3.on .beat:nth-child(2) .beat-num { transition-delay: 0.7s; }
html.js .scene--3.on .beat:nth-child(2) .beat-visual { transition-delay: 0.8s; }
html.js .scene--3.on .beat:nth-child(2) .beat-copy { transition-delay: 0.9s; }
html.js .scene--3.on .beat:nth-child(3) .beat-num { transition-delay: 1.15s; }
html.js .scene--3.on .beat:nth-child(3) .beat-visual { transition-delay: 1.25s; }
html.js .scene--3.on .beat:nth-child(3) .beat-copy { transition-delay: 1.35s; }

/* ==========================================================================
   SCENE 4 — THE LEDGER (creative §4, ruling D16). Full sentences, one baseline
   each; a stat is ONE typographic unit and never wraps internally. Streaks =
   the earned glow (§1.5); the glide fly-through waits for frame F7.
   ========================================================================== */
.scene--4 { text-align: left; }
.ledger-col { max-width: 920px; }
.scene--4 h2 { max-width: 16em; }
.ledger { margin-top: 48px; display: grid; gap: 30px; }
.ledger-line {
  display: flex; align-items: baseline; gap: 0.4em; flex-wrap: wrap;
  font-size: clamp(19px, 2.2vw, 26px); color: var(--ink-76); line-height: 1.2;
}
.ledger-num {
  font-size: clamp(58px, 8vw, 116px);
  font-weight: 680; letter-spacing: -0.03em; line-height: 1;
  color: var(--mint); white-space: nowrap; /* unbreakable — build law (creative §4) */
}
.ledger-num.anchor { color: var(--amber); font-weight: 680; }
.ledger-rest { max-width: 34ch; }
html.js .ledger-line { opacity: 0; transform: translateY(16px); transition: opacity 0.55s ease, transform 0.55s ease; }
html.js .ledger-line.in { opacity: 1; transform: none; }
/* A3 (round 4) — THE NUMBERS ROLL: JS wraps each numeral in an odometer
   digit-strip (two 0-9 cycles, translateY only) that rolls to the true digit
   as its line reveals. The at-rest DOM text (no-JS / reduced-motion) is the
   EXACT original claim wording; the strip is aria-hidden, the real text
   stays for screen readers (.vh twin). Transform-only, zero layout shift
   (tabular figures). */
.od { display: inline-block; height: 1em; overflow: hidden; vertical-align: top; font-variant-numeric: tabular-nums; }
.od-strip {
  display: block;
  transform: translateY(calc(var(--od, 0) * -1em));
  transition: transform 0.9s cubic-bezier(0.22, 1, 0.36, 1);
}
.od-strip b { display: block; height: 1em; line-height: 1; font-weight: inherit; }
.scene--4 .footnote { margin-top: 48px; }
/* R2-5: the streak band is RETIRED — calm, flat navy; the numbers do the talking.
   (This also removes S4 from the glow whitelist — one earned glow fewer.) */

/* ==========================================================================
   SCENE 5 — CITY OF APPS (pinned, 6 steps, 600 ms dwell — ruling D11).
   Switcher = TAB BAR with real icons (ux-spec §3.3): no glass, no cards;
   mint underline marks the active app.
   ========================================================================== */
.scene--5 { text-align: center; }
.scene--5 .sub { margin-left: auto; margin-right: auto; }

.switcher {
  display: flex; justify-content: center; gap: 6px;
  margin: 44px auto 0; max-width: 920px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}
.app-tile {
  font: inherit; cursor: pointer; text-align: center;
  background: transparent; border: 0; border-bottom: 2px solid transparent;
  padding: 12px 16px 14px; min-width: 44px; min-height: 44px;
  color: var(--ink);
  transition: background 0.2s ease, border-color 0.2s ease;
}
.app-tile:hover { background: rgba(255, 255, 255, 0.03); }
.app-tile.is-active { border-bottom-color: var(--mint); }
/* Uniform mark law (owner item 26): every icon renders in ONE bounding box per
   context, centered, object-fit contain, from 128px derivatives (retina-sharp).
   iOS full-bleed squares (.sq) get the squircle radius AND a slight scale-down
   so their optical weight matches macOS icons' built-in margins. */
.aicon {
  display: inline-block; width: 42px; height: 42px; object-fit: contain;
  filter: grayscale(1); opacity: 0.65;
  /* A4 (round 4) — DOCK MAGNIFICATION: --mag (0..1) drives a macOS-dock
     scale + lift. JS feeds it two ways: cursor proximity (cosine falloff,
     desktop hover garnish) and the ACTIVE-app rest state (the selected app
     COMES FORWARD even with no cursor — scroll/keyboard/touch path).
     --sq keeps the full-bleed-square optical correction multiplied in. */
  --sq: 1;
  transform: translateY(calc(var(--mag, 0) * -8px)) scale(calc(var(--sq) * (1 + var(--mag, 0) * 0.5)));
  transform-origin: bottom center;
  transition: filter 0.2s ease, opacity 0.2s ease, transform 0.18s ease-out;
}
.aicon.sq, .wicon.sq { border-radius: 22.5%; } /* iOS App Store artwork is full-bleed square (MANIFEST.md) */
.aicon.sq { --sq: 0.88; }
.wicon { transform: scale(var(--sqw, 1)); }
.wicon.sq { --sqw: 0.88; }
.app-tile:hover .aicon, .app-tile.is-active .aicon { filter: none; opacity: 1; }
.app-tile .app-name { display: block; font-size: 16px; font-weight: 600; margin-top: 6px; }
.app-tile .app-ctx { display: block; font-size: 12.5px; font-weight: 450; color: var(--ink-52); margin-top: 1px; }

.demo-app { position: relative; max-width: 720px; margin: calc(var(--pw-s5) * 1.3 + 18px) auto 0; text-align: left; } /* headroom: the lookdown perch box above the window bar — never overlaps the tab bar */
.app-window {
  /* round 5b (§2.4): per-app light/dark theming — CSS vars swapped by JS with the
     active tab (data-app). Each screen shows its TRUE color; the light↔dark flip as
     you tab Mail→Cursor IS the honesty statement. Light body separates from navy → no border. */
  --w-bar: #ececf0; --w-barink: #55565c; --w-bg: #ffffff; --w-ink: #1f2127;
  --w-caret: var(--emerald); --w-edge: rgba(0, 0, 0, 0.08);
  background: var(--w-bg);
  border-radius: 12px; overflow: hidden;
  box-shadow: 0 24px 64px rgba(0, 0, 0, 0.45);
}
.app-window[data-app="slack"]    { --w-ink: #1d1c1d; }
.app-window[data-app="notion"]   { --w-ink: #37352f; }
.app-window[data-app="whatsapp"] { --w-bg: #efeae2; --w-ink: #111b21; }
/* dark ONLY where the real app is dark (L3) */
.app-window[data-app="cursor"]   { --w-bar: #161b22; --w-barink: #8b93a5; --w-bg: #1b1e28; --w-ink: #d6d9e0; --w-caret: var(--mint); --w-edge: rgba(255, 255, 255, 0.06); }
.app-window[data-app="terminal"] { --w-bar: #161b22; --w-barink: #8b93a5; --w-bg: #0d1117; --w-ink: #d6d9e0; --w-caret: var(--mint); --w-edge: rgba(255, 255, 255, 0.06); }
.aw-bar {
  display: flex; align-items: center; gap: 7px;
  padding: 12px 16px; font-size: 13px; color: var(--w-barink);
  background: var(--w-bar); border-bottom: 1px solid var(--w-edge);
}
/* real macOS traffic-light colors — reads "Mac app", not "generic panel" */
.aw-bar i { width: 11px; height: 11px; border-radius: 50%; }
.aw-bar i:nth-child(1) { background: #ff5f57; }
.aw-bar i:nth-child(2) { background: #febc2e; }
.aw-bar i:nth-child(3) { background: #28c840; }
.aw-bar span { margin-left: 8px; }
/* Mail's one blue accent, mirroring S2 */
.app-window[data-app="mail"] .aw-bar::after { content: "Send"; margin-left: auto; color: #0a82ff; font-weight: 600; }
/* round 5c: To/Subject header — hidden by default, shown only on the Mail step so the bare box reads as Mail */
.aw-mailhead { display: none; }
.app-window[data-app="mail"] .aw-mailhead { display: grid; gap: 4px; padding-bottom: 12px; margin-bottom: 14px; border-bottom: 1px solid #e4e5e9; }
.aw-mailhead .awh { font-size: 13px; color: #1f2127; }
.aw-mailhead .awh b { color: #8b8e96; font-weight: 550; }
.aw-body { padding: 22px 20px 26px; min-height: 128px; color: var(--w-ink); }
.app-window[data-app="whatsapp"] .aw-body { display: flex; flex-direction: column; align-items: stretch; }
/* raw utterance DE-BOXED (§2.2): plain mono strikethrough, grey — a type rule, not a box */
.aw-raw {
  display: inline-block;
  font-family: var(--font-mono); font-weight: 460; font-size: 14px;
  color: #9a9da3; text-decoration: line-through;
  margin-bottom: 14px; max-width: 100%;
  transition: opacity 0.4s ease;
}
.app-window[data-app="cursor"] .aw-raw, .app-window[data-app="terminal"] .aw-raw { color: var(--ink-40); }
.aw-raw.spent { opacity: 0.3; } /* the raw text is spent once its words have landed (creative §5) */
/* the composer box exists ONLY where the real app draws one — kills "okienko w okienku" (§2.2) */
.aw-input {
  position: relative;
  background: transparent; border: 1px solid transparent;
  border-radius: 10px; padding: 0;
  font-size: 16px; color: var(--w-ink); min-height: 3.2em;
}
.app-window[data-app="slack"] .aw-input { background: #ffffff; border-color: #d1d2d4; padding: 14px 16px; } /* the ONE authentic inner box */
.app-window[data-app="cursor"] .aw-input { background: #1b1e28; border-color: #2a2e3d; padding: 14px 16px; }
.app-window[data-app="whatsapp"] .aw-input { width: fit-content; max-width: 85%; margin-left: auto; padding: 10px 14px; background: #d9fdd3; color: #111b21; border-radius: 16px; border-bottom-right-radius: 4px; } /* words land INSIDE the green bubble */
.aw-input.mono-style { font-family: var(--font-mono); font-weight: 460; font-size: 14.5px; }
/* THE LANDING BEAT (creative §5): words materialize whole from the caret — NOT a typewriter */
.aw-words .w { opacity: 0; transition: opacity 0.16s ease; }
.aw-words .w.in { opacity: 1; }
.aw-caret { display: inline-block; width: 2px; height: 1.15em; background: var(--w-caret); vertical-align: text-bottom; margin-left: 2px; opacity: 0; } /* emerald on light bodies, mint on dark — Dictorio's one signature inside any window */
html.js .aw-caret.on { opacity: 1; animation: blink 0.9s steps(1) infinite; }
html.js .aw-caret.pulse { opacity: 1; animation: caretpulse 0.5s ease 1; }
@keyframes caretpulse {
  0% { box-shadow: 0 0 0 0 rgba(140, 232, 200, 0.55); }
  100% { box-shadow: 0 0 0 12px rgba(140, 232, 200, 0); }
}
.aw-underline {
  position: absolute; left: 16px; right: 16px; bottom: 8px; height: 1px;
  background: var(--w-caret); transform: scaleX(0); transform-origin: left; opacity: 0;
}
html.js .aw-underline.sweep { animation: sweep 0.65s ease forwards; }
@keyframes sweep {
  0% { transform: scaleX(0); opacity: 0.9; }
  65% { transform: scaleX(1); opacity: 0.9; }
  100% { transform: scaleX(1); opacity: 0; }
}
/* lookdown rest (615-wide canvas): box = pw × 615/463 wide, feet overlap the window bar by ~6px */
.perch--window1 {
  position: absolute; left: 14px;
  top: calc(var(--pw-s5) * -1.285 + 6px);
  width: calc(var(--pw-s5) * 1.328);
  z-index: 3;
}
/* R2-6: the drop-chip mechanic is DEAD ("the parrot must not poop words") — text appears
   directly in the target field; no floating word-chips anywhere. */
.tone-caption { font-size: 14px; font-weight: 450; color: var(--ink-52); margin-top: 24px; }

/* ghost perch anchor (waypoint only) inside scene 5 */
.perch--window2 { position: absolute; right: 40px; top: -8px; width: calc(var(--pw-s5) * 0.8); }

/* static fallback: the same thought in all six apps, always visible (ux-spec §1.3) */
.apps-static { display: none; max-width: 720px; margin: 40px auto 0; text-align: left; }
.as-raw {
  display: inline-block; font-family: var(--font-mono); font-weight: 460; font-size: 14px;
  color: var(--ink-40); text-decoration: line-through;
  background: rgba(255, 255, 255, 0.03); border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 8px; padding: 0.35em 0.8em; margin-bottom: 22px;
}
.apps-static ul { list-style: none; display: grid; gap: 18px; }
.apps-static .as-app { display: flex; align-items: center; gap: 10px; font-size: 16px; font-weight: 600; }
.apps-static .as-app .aicon { width: 24px; height: 24px; filter: none; opacity: 1; }
.apps-static .as-clean { color: var(--ink-76); font-size: 16px; margin-top: 4px; }

/* ==========================================================================
   SCENE 5b — THE LOGO WALL (§3.2): real icons, bare glyphs, NO boxes/borders.
   Mono (grayscale) at rest, official color on hover; the label always carries
   the name — hover color is progressive enhancement.
   ========================================================================== */
.scene--5b { text-align: center; padding-top: clamp(64px, 8vh, 96px); }
.wall-bridge { font-size: clamp(20px, 2.4vw, 28px); font-weight: 600; margin-bottom: 0; }
.wall {
  list-style: none;
  display: grid; grid-template-columns: repeat(6, 1fr); gap: 36px 28px;
  max-width: 960px; margin: 52px auto 0;
}
.wall li { text-align: center; }
.wicon {
  display: inline-block; width: 54px; height: 54px; object-fit: contain;
  filter: grayscale(1); opacity: 0.62; transition: filter 0.2s ease, opacity 0.2s ease;
}
.wall li:hover .wicon { filter: none; opacity: 1; }
/* R2-7 → A5 (round 4, "must be clearly VISIBLE"): the color WAVE now POPS —
   full official color + scale(1.22) lift at the crest, label brightening with
   its icon; replayed on every wall re-entry (JS re-arms the classes).
   --sqw keeps the full-bleed-square optical correction multiplied in;
   --wd (set by JS on the <li>) staggers icon + label together. */
@keyframes wallwave {
  0% { filter: grayscale(1); opacity: 0.62; transform: scale(var(--sqw, 1)); }
  32% { filter: grayscale(0); opacity: 1; transform: scale(calc(var(--sqw, 1) * 1.22)); }
  60% { filter: grayscale(0); opacity: 1; transform: scale(calc(var(--sqw, 1) * 1.06)); }
  100% { filter: grayscale(1); opacity: 0.62; transform: scale(var(--sqw, 1)); }
}
@keyframes wallname {
  0% { color: var(--ink-52); }
  32% { color: var(--ink); }
  60% { color: var(--ink); }
  100% { color: var(--ink-52); }
}
/* fill: backwards (NOT both) — 0% frame equals the resting style, and releasing the fill after
   the sweep lets the :hover color-up work again (a `both` fill overrides hover forever). */
.wall li.wave .wicon { animation: wallwave 1.05s cubic-bezier(0.4, 0, 0.4, 1) var(--wd, 0ms) backwards; }
.wall li.wave .mark-name { animation: wallname 1.05s cubic-bezier(0.4, 0, 0.4, 1) var(--wd, 0ms) backwards; }
.wall .mark-name { display: block; font-size: 13.5px; font-weight: 450; color: var(--ink-52); margin-top: 9px; }
.wall-chip {
  display: inline-block; margin-top: 40px;
  font-size: 14px; font-weight: 550; color: #151a30;
  background: var(--mint); border-radius: 999px; padding: 0.4em 1.1em;
}
.wall-legal { font-size: 12px; font-weight: 450; color: var(--ink-40); margin-top: 16px; }
.wall-marquee { display: none; }

/* ==========================================================================
   SCENE 6 — WRITING DESK (ux-spec §4, ruling D13): capability LIST (no blobs)
   + the panel-style RANGE with ALL FIVE styles, Hidden as the empty slot.
   ========================================================================== */
.scene--6 .wrap { position: relative; }
.scene--6 h2 { max-width: 720px; }
.perch--desk { position: absolute; right: 24px; top: -20px; width: calc(var(--pw-s6) * 1.328); z-index: 3; } /* lookdown box */

.desk-list { list-style: none; margin-top: 56px; max-width: 720px; display: grid; gap: 32px; }
.desk-list li { padding-left: 2em; position: relative; }
.desk-list li::before { content: "✓"; position: absolute; left: 0; top: 0.2em; color: var(--emerald); font-weight: 700; }
.desk-list h3 { margin-bottom: 8px; }
.desk-list p { color: var(--ink-76); font-size: 17px; max-width: 58ch; }
.desk-primary h3 { font-size: clamp(24px, 2.6vw, 30px); }

/* A6 (round 4) — the desk BUILDS row by row, counted like S3: ✓ pops first
   (spring overshoot), the title lands from blur +120ms, the body +240ms;
   rows 550ms apart. */
html.js .desk-list li::before { opacity: 0; transform: scale(0.4); transition: opacity 0.26s cubic-bezier(0.34, 1.56, 0.64, 1), transform 0.26s cubic-bezier(0.34, 1.56, 0.64, 1); }
html.js .desk-list li h3, html.js .desk-list li p {
  opacity: 0; transform: translateY(12px); filter: blur(6px);
  transition: opacity 0.45s cubic-bezier(0.22, 1, 0.36, 1),
    transform 0.45s cubic-bezier(0.22, 1, 0.36, 1),
    filter 0.45s cubic-bezier(0.22, 1, 0.36, 1);
}
html.js .scene--6.on .desk-list li::before { opacity: 1; transform: none; }
html.js .scene--6.on .desk-list li h3, html.js .scene--6.on .desk-list li p { opacity: 1; transform: none; filter: none; }
/* brand-gate fix (2026-07-08): chain compressed to the ≤1.4s score law
   (unpinned scene). Rows 0.25/0.7/1.15, micro-offsets +0.12/+0.24. */
html.js .scene--6.on .desk-list li:nth-child(1)::before { transition-delay: 0.25s; }
html.js .scene--6.on .desk-list li:nth-child(1) h3 { transition-delay: 0.37s; }
html.js .scene--6.on .desk-list li:nth-child(1) p { transition-delay: 0.49s; }
html.js .scene--6.on .desk-list li:nth-child(2)::before { transition-delay: 0.7s; }
html.js .scene--6.on .desk-list li:nth-child(2) h3 { transition-delay: 0.82s; }
html.js .scene--6.on .desk-list li:nth-child(2) p { transition-delay: 0.94s; }
html.js .scene--6.on .desk-list li:nth-child(3)::before { transition-delay: 1.15s; }
html.js .scene--6.on .desk-list li:nth-child(3) h3 { transition-delay: 1.27s; }
html.js .scene--6.on .desk-list li:nth-child(3) p { transition-delay: 1.39s; }

/* R2-8: the "Choose how much parrot" panel RANGE is CUT — the Hidden message lives in S6.5 now. */

/* ==========================================================================
   SCENE 6.5 — THE SHALLOW REASON (creative §7, ruling D16). Plain navy, no
   glow — the parrot's own glass is the scene's light. Type-led interlude.
   ========================================================================== */
.scene--65 { text-align: center; padding: clamp(72px, 9vh, 120px) 0; }
.scene--65 .sub { margin: 0 auto; max-width: 54ch; }
.perch--glam { width: calc(var(--pw-s65) * 1.585); margin: 0 auto 32px; } /* glamour box (734-wide canvas) */
.shallow-hidden { font-size: 17px; font-weight: 500; font-style: italic; color: var(--mint); margin-top: 20px; } /* the Hidden line (R2-8) */
.wardrobe { display: flex; align-items: flex-end; justify-content: center; gap: 30px; margin-top: 44px; }
.wardrobe .panel-img { max-height: 34px; width: auto; } /* the wardrobe under the model, 40% scale */

/* ==========================================================================
   SCENE 7 — LANGUAGES (dusk, flat; parrot's own glass glow is the light)
   ========================================================================== */
.scene--7 { text-align: center; }
.scene--7 .sub { margin-left: auto; margin-right: auto; }
.lang-stage {
  display: grid; grid-template-columns: 1fr auto 1fr; gap: 40px;
  align-items: center; margin-top: 64px; max-width: 980px; margin-left: auto; margin-right: auto;
}
.lang-col { display: flex; flex-direction: column; gap: 16px; }
.lang-col--raw { align-items: flex-end; }
.lang-col--polished { align-items: flex-start; }
.lchip {
  font-family: var(--font-mono); font-weight: 460; font-size: 16px;
  color: var(--ink-40);
  background: rgba(255, 255, 255, 0.03); border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 10px; padding: 0.4em 0.9em;
  transform: rotate(var(--rot, 0deg));
}
.pchip {
  font-family: var(--font-sans); font-weight: 600; font-size: 16px;
  color: var(--ink);
  background: var(--card); border: 1px solid var(--card-edge);
  border-radius: 12px; padding: 0.4em 0.9em;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.35), inset 0 1px 0 rgba(255, 255, 255, 0.1);
}
html.js .pchip { opacity: 0; transform: translateY(10px); transition: opacity 0.45s ease, transform 0.45s ease; }
html.js .pchip.in { opacity: 1; transform: none; }
.perch--lang { width: var(--pw-s7); }

/* ==========================================================================
   SCENE 8 — THE QUIET ROOM + THE CHECKPOINT (creative §3 A, ruling D15).
   Glass octagon in palette — NO red, the shape reads "stop" worldwide.
   The parrot is the guard on its top edge; nothing moves.
   ========================================================================== */
.scene--8 { text-align: center; }
.scene--8 .sub { margin: 0 auto; max-width: 620px; }
.scene--8 .sub strong { font-weight: 560; color: var(--ink); }
.quiet-stage { position: relative; margin: 88px auto 0; width: min(420px, 80vw); display: flex; align-items: center; justify-content: center; }
.rings { position: absolute; inset: -70px; pointer-events: none; }
.rings i {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  border: 1px solid rgba(140, 232, 200, 0.1); border-radius: 50%;
}
.rings i:nth-child(1) { width: 105%; height: 105%; }
.rings i:nth-child(2) { width: 132%; height: 132%; border-color: rgba(140, 232, 200, 0.06); }
.rings i:nth-child(3) { width: 162%; height: 162%; border-color: rgba(140, 232, 200, 0.03); }
.checkpoint { position: relative; display: flex; flex-direction: column; align-items: center; }
.perch--quiet { width: calc(var(--pw-s8) * 1.328); margin-bottom: -6px; position: relative; z-index: 2; } /* lookdown box; feet on the sign's top edge */
.stop-sign { display: block; filter: drop-shadow(0 18px 40px rgba(0, 0, 0, 0.45)); }
.stop-post { display: block; width: 2px; height: 64px; background: rgba(255, 255, 255, 0.14); }
.privacy-kicker {
  font-size: clamp(22px, 2.6vw, 30px); font-weight: 600; letter-spacing: -0.01em;
  margin: 44px auto 56px; max-width: 24em; color: var(--ink);
}
.checks { list-style: none; max-width: 640px; margin: 0 auto; text-align: left; }
.checks li { padding-left: 2em; position: relative; margin-bottom: 24px; color: var(--ink-76); font-size: 17px; }
.checks li strong { color: var(--ink); font-weight: 600; }
.checks li::before { content: "✓"; position: absolute; left: 0; top: 0.1em; color: var(--emerald); font-weight: 700; }
.bundle-line { font-size: 19px; font-weight: 600; margin-top: 96px; }
.pull-quote {
  font-size: clamp(24px, 3vw, 34px); font-weight: 560; letter-spacing: -0.01em;
  line-height: 1.25; max-width: 20em; margin: 96px auto 0; color: var(--mint);
}

/* ==========================================================================
   SCENE 9 — NIGHT SHIFT / AGENTS (EARNED light: the terminal lamp; §1.5)
   + the prompt LENGTH contrast (ux-spec §6.1)
   ========================================================================== */
.agents-grid { display: grid; grid-template-columns: minmax(0, 640px) minmax(0, 1fr); gap: 56px; align-items: start; }
.agents-copy .sub { max-width: 100%; }
.prompt-contrast { display: flex; align-items: center; gap: 16px; margin-top: 30px; }
.pc-weak {
  font-family: var(--font-mono); font-weight: 460; font-size: 15px;
  color: var(--ink-40); text-decoration: line-through; white-space: nowrap;
  background: rgba(255, 255, 255, 0.03); border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 8px; padding: 0.35em 0.8em;
}
.pc-vs { font-size: 12px; font-weight: 550; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-40); }
.pc-strong { font-size: 15px; font-weight: 500; color: var(--ink-76); line-height: 1.5; }
.terminal-wrap { position: relative; margin-top: calc(var(--pw-s9) + 24px); }
.terminal {
  /* round 5b (§2.5): STAYS DARK — a terminal is naturally dark (owner L3). To stop it
     reading as a generic nested panel: body DARKER than the scene (#0d1117 vs --navy-deep),
     colored traffic lights (below), and the emerald BORDER drops out of the way of the lamp. */
  background: #0d1117;
  border: 1px solid rgba(62, 207, 142, 0.12); border-radius: 12px;
  /* the screenshot as lamp — emerald bleed (whitelist earned glow) STAYS */
  box-shadow: 0 0 90px rgba(62, 207, 142, 0.13), 0 32px 80px rgba(0, 0, 0, 0.55);
  overflow: visible;
}
.term-bar {
  position: relative;
  display: flex; align-items: center; gap: 7px;
  padding: 12px 16px; font-size: 13px; color: var(--ink-52);
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}
.term-bar i { width: 11px; height: 11px; border-radius: 50%; }
.term-bar i:nth-child(1) { background: #ff5f57; }
.term-bar i:nth-child(2) { background: #febc2e; }
.term-bar i:nth-child(3) { background: #28c840; }
.term-bar span { margin-left: 8px; font-family: var(--font-mono); font-weight: 460; }
.perch--terminal { position: absolute; right: 26px; top: calc(var(--pw-s9) * -0.92 + 6px); width: var(--pw-s9); }
.term-body { padding: 22px 20px 26px; font-family: var(--font-mono); font-weight: 460; font-size: 15px; line-height: 1.55; min-height: 130px; }
.term-prompt { color: var(--emerald); }
.term-line { color: var(--ink); word-break: break-word; }
.term-resp { margin-top: 1em; color: var(--ink-55); }
html.js .term-resp { opacity: 0; transition: opacity 0.5s ease; }
html.js .term-resp.in { opacity: 1; }
html:not(.js) .term-resp { opacity: 1; }
.bullets { list-style: none; margin-top: 40px; }
.bullets li { padding-left: 1.8em; position: relative; margin-bottom: 14px; color: var(--ink-76); font-size: 17px; }
.bullets li strong { color: var(--ink); font-weight: 600; }
.bullets li::before { content: "✓"; position: absolute; left: 0; color: var(--emerald); font-weight: 700; }

/* ==========================================================================
   SCENE 10 — THE LANDING (rulings D4/D6/D9 + ux-spec §5): the typographic
   anti-subscription manifest + two LIGHT accordion rows. Zero glass cards.
   ========================================================================== */
.scene--10 { text-align: center; padding-top: clamp(72px, 9vh, 120px); } /* tighter top: the trial CTA must be in-viewport on scene entry (marketing gate) */
/* R2-10 hierarchy: the manifest is the STAR — the parrot wing-points at it from the right. */
.manifest-stage { position: relative; display: inline-block; }
.manifest-stage h2 { margin-bottom: 24px; }
.perch--seam {
  position: absolute; left: calc(100% + 20px); bottom: -10px;
  width: calc(var(--pw-s10) * 1.166); /* wingpoint box (540-wide canvas) */
  z-index: 3;
}
.manifest { font-size: clamp(20px, 2.4vw, 27px); font-weight: 560; line-height: 1.35; max-width: 26em; margin: 0 auto; }
.manifest-contrast { margin-top: 14px; font-size: 16px; font-weight: 450; color: var(--ink-40); }
.manifest-contrast s { text-decoration-thickness: 1.5px; }
.trial-line { margin-top: 28px; font-size: 15px; font-weight: 550; color: var(--mint); }

.offer { position: relative; max-width: 720px; margin: 40px auto 0; text-align: left; }
.offer-row { border: 1px solid var(--card-edge); border-radius: 14px; margin-bottom: 12px; background: var(--card); }
.offer-row summary {
  cursor: pointer; list-style: none;
  display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap;
  padding: 20px 60px 20px 24px; min-height: 44px; position: relative;
}
.offer-row summary::-webkit-details-marker { display: none; }
.offer-row summary:hover { background: rgba(255, 255, 255, 0.02); border-radius: 14px; }
.offer-name { font-size: 20px; font-weight: 650; }
.offer-lead { font-size: 16px; font-weight: 450; color: var(--ink-76); }
.offer-lead strong { color: var(--ink); font-weight: 650; }
.offer-plus { position: absolute; right: 22px; top: 50%; width: 14px; height: 14px; margin-top: -7px; }
.offer-plus::before, .offer-plus::after { content: ""; position: absolute; background: var(--mint); transition: transform 0.2s ease; }
.offer-plus::before { left: 0; top: 6px; width: 14px; height: 2px; }
.offer-plus::after { left: 6px; top: 0; width: 2px; height: 14px; }
.offer-row[open] .offer-plus::after { transform: scaleY(0); }
.offer-body { padding: 4px 24px 28px; }
.offer-body ul { list-style: none; margin-bottom: 24px; }
.offer-body ul li { padding-left: 1.6em; position: relative; margin-bottom: 10px; color: var(--ink-76); font-size: 16px; }
.offer-body ul li::before { content: "✓"; position: absolute; left: 0; color: var(--emerald); font-weight: 700; }
.offer-how { color: var(--ink-76); font-size: 16px; max-width: 56ch; margin-bottom: 8px; }
.offer-how strong { color: var(--ink); font-weight: 600; }
/* R2-10: pack chips + add-tokens CTA removed — pay-as-you-go is EXPLAINED, not sold, on the landing */
.offer-body .microcopy { margin-top: 1em; }

/* ---------- COMPARISON TABLE (round 3) — navy + typography only, no glass
   blobs; the table scrolls INSIDE .compare-scroll on narrow viewports. ---------- */
.compare { max-width: 860px; margin: 88px auto 0; text-align: left; }
.compare-title { font-size: 24px; font-weight: 630; text-align: center; margin-bottom: 26px; }
.compare-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.compare-scroll:focus-visible { outline: 2px solid var(--mint); outline-offset: 2px; }
.compare table { width: 100%; min-width: 560px; border-collapse: collapse; font-size: 15px; line-height: 1.45; }
.compare th, .compare td {
  padding: 14px 18px 14px 0; text-align: left; vertical-align: top;
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}
.compare thead th {
  font-size: 13px; font-weight: 650; letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--ink-76); border-bottom-color: rgba(255, 255, 255, 0.18); padding-bottom: 10px;
}
.compare thead th.c-us { color: var(--mint); }
.compare tbody th { font-weight: 550; color: var(--ink-55); width: 21%; padding-right: 22px; }
.compare td { color: var(--ink-76); width: 26.3%; }
.compare td.c-us { color: var(--ink); font-weight: 550; }
.compare-note { font-size: 12.5px; font-weight: 450; color: var(--ink-40); margin-top: 16px; }

/* ---------- WIN-MATRIX (round 5b, owner L2 + creative spec §1.6) — ✓/✗/~ grid,
   flat navy, NO card/shadow; the mark never stands alone (label under every mark).
   Dictorio column gets a single 1px mint hairline (its only emphasis — no fill). ---------- */
.winmatrix th, .winmatrix td { padding-top: 16px; padding-bottom: 16px; }
.winmatrix td.c-us, .winmatrix thead th.c-us {
  border-left: 1px solid rgba(140, 232, 200, 0.28);
  padding-left: 16px;
}
.wm-mark { display: inline-block; line-height: 1; font-weight: 700; }
.wm-yes { color: var(--mint); font-size: 18px; }
.winmatrix td.c-us .wm-yes { color: var(--emerald); } /* ours = emerald, matching the page's ✓ bullets */
.wm-no { color: var(--ink-40); font-size: 15px; font-weight: 600; }
.wm-part { color: var(--ink-55); font-size: 16px; font-weight: 600; } /* ~ = partly — NEVER amber */
.wm-label {
  display: block; margin-top: 6px;
  font-size: 12.5px; font-weight: 450; line-height: 1.35; color: var(--ink-55);
}
.winmatrix td.c-us .wm-label { color: var(--ink-76); }

.trust-bar { margin-top: 48px; font-size: 14px; font-weight: 450; color: var(--ink-52); }
/* CTA safety net: always-visible trial link even with both accordion rows collapsed */
.trust-cta { margin-top: 14px; font-size: 15px; }
.trust-cta a { color: var(--mint); font-weight: 600; text-decoration: none; border-bottom: 1px solid rgba(140, 232, 200, 0.4); padding-bottom: 1px; }
.trust-cta a:hover, .trust-cta a:focus-visible { border-bottom-color: var(--mint); }

.faq { max-width: 720px; margin: 96px auto 0; text-align: left; }
.faq-title { font-size: 24px; margin-bottom: 24px; text-align: center; }
.faq details { border: 1px solid var(--card-edge); border-radius: 14px; margin-bottom: 12px; background: var(--card); }
.faq summary {
  cursor: pointer; font-weight: 600; font-size: 17px; padding: 18px 22px; list-style: none;
  position: relative; padding-right: 48px;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: ""; position: absolute; right: 22px; top: 50%;
  width: 9px; height: 9px; margin-top: -7px;
  border-right: 2px solid var(--mint); border-bottom: 2px solid var(--mint);
  transform: rotate(45deg); transition: transform 0.2s ease;
}
.faq details[open] summary::after { transform: rotate(225deg); margin-top: -2px; }
.faq details p { padding: 0 22px 20px; color: var(--ink-76); font-size: 16px; }

/* ==========================================================================
   SCENE 11 — SUNRISE FINALE (EARNED glow: the amber bloom; §1.5 whitelist)
   ========================================================================== */
.scene--11 { text-align: center; padding-bottom: 0; }
.finale-wrap { position: relative; padding-top: 24px; }
.finale-rings { position: absolute; left: 50%; top: calc(var(--pw-s11) * 0.36); transform: translateX(-50%); width: 0; height: 0; pointer-events: none; }
.finale-rings i { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); border: 1px solid rgba(140, 232, 200, 0.12); border-radius: 50%; }
.finale-rings i:nth-child(1) { width: calc(var(--pw-s11) * 1.05); height: calc(var(--pw-s11) * 1.05); }
.finale-rings i:nth-child(2) { width: calc(var(--pw-s11) * 1.35); height: calc(var(--pw-s11) * 1.35); border-color: rgba(140, 232, 200, 0.07); }
.perch--finale { margin: 0 auto 32px; width: var(--pw-s11); }
.scene--11 h2 { font-size: clamp(36px, 5.4vw, 72px); max-width: 16em; margin-left: auto; margin-right: auto; }
.scene--11 .sub { margin: 0 auto; }
/* round 3: the compact 3-step recap — one quiet row between the sub and the CTAs */
.finale-steps {
  margin: 26px auto 0; font-size: 17px; font-weight: 550; color: var(--ink-76);
}
.finale-steps kbd {
  font-family: var(--font-mono); font-weight: 460; font-size: 14px; color: var(--ink);
  border: 1.5px solid rgba(244, 246, 251, 0.5); border-bottom-width: 2.5px;
  border-radius: 7px; padding: 0.1em 0.55em; margin: 0 1px;
}
.finale-steps .fs-arrow { color: var(--ink-40); margin: 0 6px; }

.footer {
  margin-top: clamp(72px, 10vh, 128px);
  padding: 36px 24px 44px;
  border-top: 1px solid rgba(255, 255, 255, 0.07);
  font-size: 14px; font-weight: 450; color: var(--ink-52);
}
.footer-links { display: flex; gap: 8px 22px; justify-content: center; flex-wrap: wrap; margin-bottom: 16px; }
.footer-links a { color: var(--ink-76); text-decoration: none; }
.footer-links a:hover { color: var(--mint); }
.footer-social { list-style: none; display: flex; gap: 14px; justify-content: center; margin: 0 0 18px; padding: 0; }
.footer-social a {
  display: inline-flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; border-radius: 50%;
  color: var(--ink-52); transition: color 0.2s ease;
}
.footer-social a:hover, .footer-social a:focus-visible { color: var(--mint); }
/* round 4b (topnav spec §4): Blog + Changelog's home — a quiet group between
   the link row and the beta line. Blog link + teaser ship hidden until real. */
.footer-follow { display: flex; gap: 8px 18px; justify-content: center; align-items: baseline; flex-wrap: wrap; margin-bottom: 16px; }
.footer-follow-title { font-size: 12px; font-weight: 550; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-40); }
.footer-follow a { color: var(--ink-76); text-decoration: none; }
.footer-follow a:hover, .footer-follow a:focus-visible { color: var(--mint); }
.footer-follow [hidden] { display: none; }
.footer-beta { margin-bottom: 12px; }
.footer-beta a { color: var(--mint); }
.footer-secure { margin-bottom: 12px; } /* round 3: official-source note (outside-App-Store trust cue) */
.footer-legal { color: var(--ink-40); }

/* ==========================================================================
   FALLBACK VISIBILITY (ux-spec §1.3) — the pinned/interactive stages exist
   only in scrub mode; every other mode gets ALL states statically.
   ========================================================================== */
html:not(.js) .echo-stage, html:not(.js) .scene--2 .tabs, html:not(.js) .tabs-hint,
html:not(.js) .switcher, html:not(.js) .demo-app, html:not(.js) .step-dots,
html:not(.js) .echo-static { display: grid; }
html:not(.js) .apps-static { display: block; }

/* ==========================================================================
   MOBILE (<900px) — static compositions, scene-enter animation only.
   Pinning is never enabled on mobile (address-bar resize makes it unreliable);
   S2/S5 show the static all-states layout instead — zero hidden content.
   ========================================================================== */
@media (max-width: 899px) {
  #parrot { display: none !important; }
  .parrot-inline { visibility: visible !important; }
  /* round 6 — MOBILE PARROT SIZE CAP (owner: "renders huge" on a phone). The free
     flight sprite is off; the inline per-scene birds must each stay a small, in-flow
     accent that never dominates the viewport. The showcase poses (glamour, finale)
     carried desktop-scale mins; cap them so none exceeds ~half the screen. The other
     inline perches already read small (hero 84px · beats 100px · lang 130px ·
     terminal 96px · quiet 127px · desk/seam ~130px after the position fix). */
  .perch--glam { width: min(190px, 50vw); }        /* was 285px (73% VW) at 390 */
  /* finale: shrink via the token so the halo rings (sized off --pw-s11) scale WITH
     the bird instead of ballooning around a smaller sprite. */
  :root { --pw-s11: clamp(150px, 44vw, 190px); }   /* was 220px (56% VW) at 390 */
  .scene { padding: 96px 0; }
  .scene--1 { padding-top: 84px; }

  .nav { padding: 0 20px; min-height: 50px; }

  .echo-stage, .scene--2 .tabs, .tabs-hint { display: none; }
  .echo-static { display: grid; grid-template-columns: 1fr; gap: 28px; }

  .beats { gap: 36px; }
  .beat { grid-template-columns: 40px 1fr; }
  .beat-num { font-size: 30px; }
  .beat .beat-visual { grid-column: 2; justify-content: flex-start; min-height: 0; }
  .beat .beat-copy { grid-column: 2; }

  .ledger-num { font-size: 56px; }

  .switcher, .demo-app { display: none; }
  .apps-static { display: block; }

  /* the wall becomes two counter-scrolling marquees (JS builds them) */
  .wall { display: none; }
  .wall-marquee { display: block; overflow: hidden; margin-top: 40px; }
  .marquee-row { display: flex; gap: 28px; width: max-content; margin-bottom: 20px; animation: marquee 36s linear infinite; }
  .marquee-row--reverse { animation-direction: reverse; }
  .marquee-row:active, .wall-marquee:hover .marquee-row { animation-play-state: paused; }
  .marquee-cell { text-align: center; flex: 0 0 auto; }
  .marquee-cell .wicon { width: 44px; height: 44px; filter: none; opacity: 1; }
  .marquee-cell .mark-name { display: block; font-size: 12px; color: var(--ink-52); margin-top: 5px; }
  @keyframes marquee { to { transform: translateX(-50%); } }

  /* MOBILE PARROT ROOT-CAUSE FIX (round 6): a perch reset to `position: static`
     RELEASES its position:absolute `.parrot-inline` child to the nearest positioned
     ancestor (`.scene .wrap`) — the bird then sizes to width:100% of the WRAP and
     floats over the text (observed: full-width parrot over the desk list / the
     "No subscription. Ever." manifest on a real iPhone). Reset to `relative`, NOT
     static, so the box stays the img's containing block and the bird stays its own
     small size. Centered in its own row. */
  .perch--desk { position: relative; inset: auto; margin: 0 auto 8px; } /* inset:auto clears the desktop top/right offsets so the relative box centers */

  .lang-stage { grid-template-columns: 1fr; gap: 28px; }
  .lang-col--raw, .lang-col--polished { flex-direction: row; flex-wrap: wrap; justify-content: center; align-items: center; }
  .perch--lang { margin: 0 auto; }

  .wardrobe { flex-wrap: wrap; gap: 20px; }

  .agents-grid { grid-template-columns: 1fr; }
  .prompt-contrast { flex-direction: column; align-items: flex-start; gap: 10px; }
  .terminal-wrap { margin-top: calc(var(--pw-s9) + 16px); }
  .perch--terminal { right: 12px; }

  .offer { margin-top: 24px; }
  .manifest-stage { display: block; }
  .perch--seam { position: relative; inset: auto; margin: 0 auto 16px; } /* round 6: relative + inset:auto — else the base left:calc(100%+20px) shoves it off-screen */
  .offer-row summary { padding: 18px 52px 18px 18px; }

  .footer-links { gap: 6px 16px; }

  /* round 4 (A7): mobile = LIGHTER choreography, same build order — blur
     dropped everywhere (costliest composite), shorter rises, compressed beat
     spacing. (JS also scales the .bb stagger to 60% under 900px.) */
  html.js .bb, html.js .bb--far { filter: none; transform: translateY(12px); }
  html.js .beat-num { filter: none; transform: translateX(-10px); }
  html.js .beat-copy, html.js .desk-list li h3, html.js .desk-list li p { filter: none; transform: translateY(10px); }
  /* brand-gate fix: mobile chains compressed further (last start ≤1.1s) */
  html.js .scene--3.on .beat:nth-child(1) .beat-num { transition-delay: 0.2s; }
  html.js .scene--3.on .beat:nth-child(1) .beat-visual { transition-delay: 0.3s; }
  html.js .scene--3.on .beat:nth-child(1) .beat-copy { transition-delay: 0.4s; }
  html.js .scene--3.on .beat:nth-child(2) .beat-num { transition-delay: 0.55s; }
  html.js .scene--3.on .beat:nth-child(2) .beat-visual { transition-delay: 0.65s; }
  html.js .scene--3.on .beat:nth-child(2) .beat-copy { transition-delay: 0.75s; }
  html.js .scene--3.on .beat:nth-child(3) .beat-num { transition-delay: 0.9s; }
  html.js .scene--3.on .beat:nth-child(3) .beat-visual { transition-delay: 1s; }
  html.js .scene--3.on .beat:nth-child(3) .beat-copy { transition-delay: 1.1s; }
  html.js .scene--6.on .desk-list li:nth-child(1)::before { transition-delay: 0.2s; }
  html.js .scene--6.on .desk-list li:nth-child(1) h3 { transition-delay: 0.32s; }
  html.js .scene--6.on .desk-list li:nth-child(1) p { transition-delay: 0.44s; }
  html.js .scene--6.on .desk-list li:nth-child(2)::before { transition-delay: 0.55s; }
  html.js .scene--6.on .desk-list li:nth-child(2) h3 { transition-delay: 0.67s; }
  html.js .scene--6.on .desk-list li:nth-child(2) p { transition-delay: 0.79s; }
  html.js .scene--6.on .desk-list li:nth-child(3)::before { transition-delay: 0.9s; }
  html.js .scene--6.on .desk-list li:nth-child(3) h3 { transition-delay: 1.02s; }
  html.js .scene--6.on .desk-list li:nth-child(3) p { transition-delay: 1.14s; }
}
/* round 6: the <375px `.perch--desk { display:none }` hack is retired — it was a
   band-aid for the full-width-escape bug (now fixed at the source: relative, not
   static). The desk bird now reads small and in-flow at every phone width. */

/* ==========================================================================
   REDUCED MOTION — full static fallback: quiet frames, all states visible,
   fades only. No pin, no scrubbing, no chip drop, no sweeps.
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  #parrot { display: none !important; }
  .parrot-inline { visibility: visible !important; }
  html.js .reveal, html.js .app-tile, html.js .wall li,
  html.js .offer-row, html.js .scene--7 .lang-col,
  html.js .echo-clean, html.js .term-resp, html.js .pchip,
  html.js .ledger-line,
  /* round 4 additions — every build element static + visible */
  html.js .bb, html.js .beat-num, html.js .beat-visual, html.js .beat-copy,
  html.js .desk-list li h3, html.js .desk-list li p,
  .od-strip { opacity: 1 !important; transform: none !important; filter: none !important; transition: none !important; }
  html.js .desk-list li::before { opacity: 1 !important; transform: none !important; transition: none !important; }
  .scroll-hint span::after, .caret, .aw-caret, .aw-underline, .ctx-caret, .land-caret,
  .wall li.wave .wicon, .wall li.wave .mark-name { animation: none !important; }
  .chip { display: none; }
  /* static hero bar (the talk loop is off) */
  .hero-bar i:nth-child(3n) { height: 10px; }
  .hero-bar i:nth-child(4n+1) { height: 14px; }
  .hero-bar i:nth-child(5n+2) { height: 7px; }
  .echo-raw { text-decoration: line-through; opacity: 0.45; }
  .btn { transition: none; }
  /* round 4b: the chapter bar switches BINARY — no fade, no slide (spec §3) */
  .nav, .nav-cta,
  html.js .nav .nav-sections, html.js .nav .nav-cta { transition: none !important; }
  html.js .nav .nav-sections, html.js .nav .nav-cta { transform: none; }
  html.js .nav.is-away { transform: none; }

  /* no pin, no cycling: statics carry every state (ux-spec §1.3) */
  html.pinning .pin { height: auto; }
  html.pinning .pin > .scene { position: static; }
  .echo-stage, .scene--2 .tabs, .tabs-hint, .step-dots, .switcher, .demo-app { display: none !important; }
  .echo-static { display: grid; }
  .apps-static { display: block; }

  /* mobile wall: static grid of the 16 most recognizable marks */
  .marquee-row { animation: none !important; flex-wrap: wrap; width: auto; justify-content: center; }
  @media (max-width: 899px) {
    .wall-marquee { display: none; }
    .wall { display: grid; grid-template-columns: repeat(4, 1fr); }
    .wall li:not([data-top16]) { display: none; }
  }
}
