/* SourceTether — cinematic mission stage, in an editorial page.
   Visual language ported from BehaviorDiff: a luminous void, dark liquid
   glass (never white), a bevel instead of a border, exactly one lit accent
   per state, serif for claims and mono for every identifier, and two layers
   of film grain over the whole frame — the one texture borrowed from
   BehaviorDiff, and the only thing borrowed from it here.

   Two themes live here. The page follows the reader (system preference, or
   an explicit choice stored by the toggle). The mission console never does:
   it re-declares the dark tokens on itself, because a lunar descent rendered
   on white would be a lie about what the scene is. */

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
[hidden] { display: none !important; }

/* ------------------------------------------------------------- tokens

   Every value the page paints with is declared once here, in the dark
   theme, then re-declared in the light theme below. Nothing outside these
   two blocks hard-codes a page colour. */

:root {
  color-scheme: dark;

  /* Void, lifted off pure black: the old #040410 page swallowed the type
     around the console. The console keeps the deeper value for itself. */
  --bg-0: #0a0a14;
  --bg-1: #10101c;
  --bg-void: #050510;
  --page-bg: #0a0a14;
  --void: #040410;

  --text-0: #f7f7fa;
  --text-1: #dcdce7;
  --text-2: #a6a6bd;
  --text-3: #78788f;

  --border: rgba(255,255,255,0.09);
  --border-strong: rgba(255,255,255,0.16);

  --cyan: #67e8f9;
  --teal: #5aebd4;
  --green: #34d399;
  --amber: #fbbf24;
  --orange: #fb923c;
  --red: #f87171;
  --blue: #60a5fa;

  /* The one lit accent. Every console state swaps these two and nothing else. */
  --accent: var(--teal);
  --accent-rgb: 90,235,212;

  /* Semantic pair used by the narrative copy in both themes. */
  --hot: var(--orange);
  --ok: var(--green);

  --mono: 'JetBrains Mono', ui-monospace, 'SF Mono', SFMono-Regular, Menlo, monospace;
  --sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
  --display: 'Instrument Serif', 'Iowan Old Style', Georgia, 'Times New Roman', serif;

  /* ---- Liquid glass ----
     Dark tint, not a white veil: a white wash at any useful opacity paints
     over the scene behind it and leaves nothing for the rim to bend. */
  --glass-radius: 14px;
  --glass-radius-sm: 10px;
  --glass-sheen: linear-gradient(180deg, rgba(16,16,28,0.40), rgba(12,12,22,0.62));
  --glass-base: rgba(14,14,26,0.36);
  --glass-fill: var(--glass-sheen), var(--glass-base);
  --glass-blur: blur(18px);
  /* A bevel rather than a border: specular catch on the top edge, soft
     internal glow off the bottom, a faint inset ring standing in for the
     border, and a long shadow lifting the pane off the void. */
  --glass-shadow:
    0 24px 60px rgba(0,0,0,0.55),
    inset 0 1px 1px rgba(255,255,255,0.42),
    inset 0 -8px 20px rgba(255,255,255,0.05),
    inset 0 0 0 1px rgba(255,255,255,0.11);
  --glass-refract: url(#liquid-glass-refraction) blur(6px) saturate(170%);

  /* Ambient light the page is lit by, and how hard the grain bites. */
  --wash-1: rgba(34,211,238,0.10);
  --wash-2: rgba(90,235,212,0.07);
  --wash-3: rgba(96,165,250,0.06);
  --star: rgba(255,255,255,0.5);
  --chrome: rgba(8,8,18,0.72);
  --grain-fine: 0.20;
  --grain-coarse: 0.09;
  --stars: 0.42;

  --ease: cubic-bezier(0.16, 1, 0.3, 1);

  /* One deterministic 900px tile of stars, repeated. The page uses it at
     native scale; the mission gates use it at two scales for parallax. */
  --star-tile: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='900' height='900' fill='white'><circle cx='291.4' cy='135.8' r='1.1' opacity='0.22'/><circle cx='739.1' cy='84.7' r='0.9' opacity='0.22'/><circle cx='456.7' cy='33.7' r='0.8' opacity='0.5'/><circle cx='216.6' cy='495.9' r='0.5' opacity='0.45'/><circle cx='111.4' cy='200.9' r='1.1' opacity='0.63'/><circle cx='55.7' cy='527.0' r='0.5' opacity='0.51'/><circle cx='41.9' cy='772.6' r='0.7' opacity='0.28'/><circle cx='486.6' cy='513.8' r='0.9' opacity='0.81'/><circle cx='162.7' cy='523.4' r='1.1' opacity='0.32'/><circle cx='87.7' cy='640.9' r='0.9' opacity='0.23'/><circle cx='185.4' cy='612.4' r='0.8' opacity='0.78'/><circle cx='419.0' cy='831.1' r='0.7' opacity='0.23'/><circle cx='714.9' cy='629.1' r='0.6' opacity='0.13'/><circle cx='270.2' cy='445.6' r='0.7' opacity='0.41'/><circle cx='259.1' cy='882.2' r='0.5' opacity='0.32'/><circle cx='148.5' cy='307.9' r='0.8' opacity='0.5'/><circle cx='865.8' cy='69.9' r='0.9' opacity='0.62'/><circle cx='787.9' cy='282.4' r='1.1' opacity='0.45'/><circle cx='447.0' cy='717.2' r='0.5' opacity='0.45'/><circle cx='850.2' cy='426.7' r='1.1' opacity='0.23'/><circle cx='658.0' cy='278.6' r='0.9' opacity='0.94'/><circle cx='739.7' cy='256.1' r='0.8' opacity='0.86'/><circle cx='312.3' cy='846.6' r='0.7' opacity='0.17'/><circle cx='105.4' cy='53.1' r='1.4' opacity='0.4'/><circle cx='664.5' cy='358.1' r='1.4' opacity='0.56'/><circle cx='149.7' cy='361.5' r='0.7' opacity='0.47'/><circle cx='737.4' cy='777.6' r='0.7' opacity='0.4'/><circle cx='887.8' cy='614.5' r='0.8' opacity='0.92'/><circle cx='135.8' cy='158.6' r='0.6' opacity='0.38'/><circle cx='10.9' cy='748.0' r='0.6' opacity='0.21'/><circle cx='3.7' cy='377.1' r='0.7' opacity='0.36'/><circle cx='286.8' cy='112.9' r='1.4' opacity='0.58'/><circle cx='555.8' cy='608.6' r='0.5' opacity='0.29'/><circle cx='783.9' cy='856.7' r='1.1' opacity='0.79'/><circle cx='353.1' cy='359.1' r='0.5' opacity='0.3'/><circle cx='360.4' cy='171.5' r='0.6' opacity='0.29'/><circle cx='98.9' cy='540.7' r='0.5' opacity='0.1'/><circle cx='136.1' cy='91.3' r='0.7' opacity='0.36'/><circle cx='63.3' cy='187.2' r='0.8' opacity='0.29'/><circle cx='227.0' cy='312.7' r='0.7' opacity='0.3'/><circle cx='103.8' cy='439.3' r='0.8' opacity='0.55'/><circle cx='280.7' cy='129.7' r='1.1' opacity='0.44'/><circle cx='238.3' cy='746.0' r='0.6' opacity='0.32'/><circle cx='184.7' cy='856.8' r='0.7' opacity='0.16'/><circle cx='488.9' cy='24.3' r='0.9' opacity='0.41'/><circle cx='578.6' cy='81.9' r='1.4' opacity='0.38'/></svg>");
}

/* ---- Light theme ----
   Not the dark palette inverted: warm paper, ink, and a deeper teal that
   actually holds contrast on white. The console is exempt (see below), so
   the page reads as an editorial sheet with a lit screen set into it. */

@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) { color-scheme: light; }
}
:root[data-theme="light"] { color-scheme: light; }

@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
    --bg-0: #f6f5f1;
    --bg-1: #fffefb;
    --bg-void: #eceae4;
  --page-bg: #f6f5f1;
    --page-bg: #f6f5f1;

    --text-0: #12121b;
    --text-1: #33333f;
    --text-2: #5d5d6e;
    --text-3: #74748a;

    --border: rgba(18,18,32,0.10);
    --border-strong: rgba(18,18,32,0.18);

    --teal: #0e8c7d;
    --green: #047857;
    --amber: #b45309;
    --orange: #c2410c;
    --red: #b91c1c;
    --blue: #1d4ed8;

    --accent: var(--teal);
    --accent-rgb: 14,140,125;
    --hot: var(--orange);
    --ok: var(--green);

    --glass-sheen: linear-gradient(180deg, rgba(255,255,255,0.92), rgba(255,255,255,0.68));
    --glass-base: rgba(255,255,255,0.55);
    --glass-shadow:
      0 22px 48px rgba(24,24,48,0.09),
      0 2px 6px rgba(24,24,48,0.05),
      inset 0 1px 0 rgba(255,255,255,0.95),
      inset 0 0 0 1px rgba(18,18,32,0.07);

    --wash-1: rgba(14,140,125,0.10);
    --wash-2: rgba(96,165,250,0.08);
    --wash-3: rgba(251,191,36,0.10);
    --star: rgba(18,18,32,0.16);
    --chrome: rgba(246,245,241,0.78);
    --grain-fine: 0.13;
    --grain-coarse: 0.055;
    --stars: 0;
  }
}

/* The explicit choice repeats the block so the toggle wins in both
   directions, including for a reader whose system is set to dark. */
:root[data-theme="light"] {
  --bg-0: #f6f5f1;
  --bg-1: #fffefb;
  --bg-void: #eceae4;
  --page-bg: #f6f5f1;

  --text-0: #12121b;
  --text-1: #33333f;
  --text-2: #5d5d6e;
  --text-3: #74748a;

  --border: rgba(18,18,32,0.10);
  --border-strong: rgba(18,18,32,0.18);

  --teal: #0e8c7d;
  --green: #047857;
  --amber: #b45309;
  --orange: #c2410c;
  --red: #b91c1c;
  --blue: #1d4ed8;

  --accent: var(--teal);
  --accent-rgb: 14,140,125;
  --hot: var(--orange);
  --ok: var(--green);

  --glass-sheen: linear-gradient(180deg, rgba(255,255,255,0.92), rgba(255,255,255,0.68));
  --glass-base: rgba(255,255,255,0.55);
  --glass-shadow:
    0 22px 48px rgba(24,24,48,0.09),
    0 2px 6px rgba(24,24,48,0.05),
    inset 0 1px 0 rgba(255,255,255,0.95),
    inset 0 0 0 1px rgba(18,18,32,0.07);

  --wash-1: rgba(14,140,125,0.10);
  --wash-2: rgba(96,165,250,0.08);
  --wash-3: rgba(251,191,36,0.10);
  --star: rgba(18,18,32,0.16);
  --chrome: rgba(246,245,241,0.78);
  --grain-fine: 0.13;
  --grain-coarse: 0.055;
  --stars: 0;
}

/* ---- The live-proof section is theme-proof ----
   It re-declares the original void palette on itself, so a light page never
   reaches into the scene. --accent is deliberately absent: it is set per
   mission phase below and has to keep inheriting. --page-bg is absent too:
   the section's fade strips need the colour of the page it is dissolving
   into, which is the one value here that must not be overridden. */

.mission-chapter {
  color-scheme: dark;
  color: var(--text-1);

  --bg-0: #040410;
  --bg-1: #0b0b14;

  --text-0: #f4f4f6;
  --text-1: #cdcdda;
  --text-2: #9494ac;
  --text-3: #6a6a82;

  --border: rgba(255,255,255,0.06);
  --border-strong: rgba(255,255,255,0.10);

  --teal: #5aebd4;
  --green: #34d399;
  --amber: #fbbf24;
  --orange: #fb923c;
  --red: #f87171;

  --glass-sheen: linear-gradient(180deg, rgba(10,10,18,0.42), rgba(10,10,18,0.62));
  --glass-base: rgba(8,8,16,0.34);
  --glass-fill: var(--glass-sheen), var(--glass-base);
  --glass-shadow:
    0 24px 60px rgba(0,0,0,0.55),
    inset 0 1px 1px rgba(255,255,255,0.42),
    inset 0 -8px 20px rgba(255,255,255,0.05),
    inset 0 0 0 1px rgba(255,255,255,0.11);
}

html {
  scroll-behavior: smooth;
  /* Proximity, not mandatory: the editorial sections scroll normally and
     only the mission screen claims a stop. */
  scroll-snap-type: y proximity;
}
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }
body {
  background: var(--bg-0);
  color: var(--text-1);
  font-family: var(--sans);
  font-size: 14px;
  line-height: 1.5;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* Ambient light on the page itself, so the long scroll between sections is
   a lit surface rather than a flat fill. Fixed, so it does not travel. */
body::before {
  content: ""; position: fixed; inset: 0; z-index: -2; pointer-events: none;
  background:
    radial-gradient(ellipse 70% 50% at 18% 8%, var(--wash-1), transparent 62%),
    radial-gradient(ellipse 60% 46% at 84% 44%, var(--wash-2), transparent 64%),
    radial-gradient(ellipse 80% 50% at 50% 100%, var(--wash-3), transparent 68%);
}

/* The page sits in the same sky the mission does. One 900px tile of stars,
   drawn once and repeated, at an opacity the light theme takes to zero. */
body::after {
  content: ""; position: fixed; inset: 0; z-index: -1; pointer-events: none;
  opacity: var(--stars);
  background-image: var(--star-tile);
  background-size: 900px 900px;
  background-repeat: repeat;
  transition: opacity 0.9s var(--ease);
}

/* ---- Film grain ----
   Fine grain carries the texture, coarse grain the mottling. Soft-light
   keeps both from flattening contrast: they darken the darks and lift the
   lights instead of greying the whole frame. */
.grain {
  position: fixed; inset: 0; z-index: 90;
  width: 100%; height: 100%;
  pointer-events: none;
  mix-blend-mode: soft-light;
}
.grain-fine { opacity: var(--grain-fine); }
.grain-coarse { opacity: var(--grain-coarse); }

.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

/* The mission phase relights the console, and only the console: the page
   around it keeps whichever accent its theme declared. */
body[data-phase="lunar"] .console,
body[data-phase="replay"] .console,
body[data-phase="settled"] .console {
  --accent: var(--amber);
  --accent-rgb: 251,191,36;
}

.glass-filters { position: absolute; width: 0; height: 0; overflow: hidden; pointer-events: none; }

.liquid-glass {
  background: var(--glass-fill);
  border: 1px solid transparent;
  border-radius: var(--glass-radius);
  box-shadow: var(--glass-shadow);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
}

/* ------------------------------------------------- mission console shell

   The stage is no longer the whole document: it is a framed console embedded
   in the page, so the same grid now sizes to the console instead of the
   viewport. Everything inside it is unchanged. */

.shell {
  height: 100%;
  min-height: 480px;
  display: grid;
  grid-template-rows: 48px 1fr 76px;
  position: relative;
}

/* ---------------------------------------------------------------- topbar */

.topbar {
  display: flex; align-items: center; gap: 14px;
  padding: 0 24px;
  border-bottom: 1px solid var(--border);
  background: rgba(4,4,16,0.62);
  backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px);
  position: relative; z-index: 40;
}
.brand, .console-brand {
  font-size: 15px; font-weight: 600; color: var(--text-0);
  letter-spacing: -0.02em; text-decoration: none;
}
.console-brand { font-size: 13px; color: var(--text-1); }
.sep { width: 1px; height: 16px; background: var(--border-strong); }
.ctx {
  font-family: var(--mono); font-size: 10.5px;
  letter-spacing: 0.10em; text-transform: uppercase;
  color: rgba(var(--accent-rgb), 0.82);
  transition: color 0.5s var(--ease);
}
.ctx::before {
  content: ""; display: inline-block;
  width: 5px; height: 5px; border-radius: 50%;
  margin-right: 8px; vertical-align: middle;
  background: rgb(var(--accent-rgb));
  box-shadow: 0 0 10px rgba(var(--accent-rgb), 0.85);
}
.topbar-right { margin-left: auto; display: flex; align-items: center; gap: 14px; }
.hosted-note {
  font-family: var(--mono); font-size: 9px; letter-spacing: 0.07em;
  color: var(--text-3); text-transform: uppercase; white-space: nowrap;
}

/* Technical proof stays behind a disclosure so it never competes with the
   story; it opens as a panel, not as a card in the layout. */
.proof { position: relative; }
.proof > summary {
  list-style: none; cursor: pointer;
  font-family: var(--mono); font-size: 10px;
  letter-spacing: 0.09em; text-transform: uppercase;
  color: var(--text-3);
  padding: 5px 10px; border-radius: 7px;
  border: 1px solid transparent;
  transition: color 0.15s, border-color 0.15s;
}
.proof > summary::-webkit-details-marker { display: none; }
.proof > summary:hover { color: var(--text-1); border-color: var(--border-strong); }
.proof[open] > summary { color: var(--text-1); border-color: var(--border-strong); }
.proof-body {
  position: absolute; top: calc(100% + 10px); right: 0;
  width: 400px; padding: 16px 18px;
  z-index: 60;
  background: var(--glass-fill);
  border: 1px solid transparent;
  border-radius: var(--glass-radius);
  box-shadow: var(--glass-shadow);
  backdrop-filter: var(--glass-blur); -webkit-backdrop-filter: var(--glass-blur);
  animation: proofIn 0.35s var(--ease);
}
@keyframes proofIn { from { opacity: 0; transform: translateY(-6px); } }
.proof-body dl { display: grid; grid-template-columns: 132px 1fr; gap: 7px 14px; }
.proof-body dt {
  font-family: var(--mono); font-size: 9.5px;
  letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--text-3); padding-top: 1px;
}
.proof-body dd code {
  font-family: var(--mono); font-size: 11px;
  color: var(--text-1); overflow-wrap: anywhere;
}
.proof-body dd code.hot { color: var(--amber); }
.proof-body dd code.ok { color: var(--teal); }

/* ---------------------------------------------------------------- stage */

.stage { position: relative; overflow: hidden; background: var(--bg-0); }

#hero { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }

/* Vignette + film grain, laid over the scene but under every overlay so
   type stays clean. */
.stage-veil {
  position: absolute; inset: 0; pointer-events: none; z-index: 2;
  background:
    radial-gradient(ellipse 92% 84% at 50% 46%, transparent 52%, rgba(4,4,16,0.26) 80%, rgba(4,4,16,0.58) 100%),
    linear-gradient(180deg, rgba(4,4,16,0.50) 0%, transparent 15%);
}
.stage-grain {
  position: absolute; inset: 0; pointer-events: none; z-index: 3;
  opacity: 0.07; mix-blend-mode: soft-light;
  background-repeat: repeat;
  background-size: 180px 180px;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='180' height='180'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/><feColorMatrix type='saturate' values='0'/></filter><rect width='180' height='180' filter='url(%23n)'/></svg>");
  animation: grainShift 1.1s steps(4) infinite;
}
@keyframes grainShift {
  0%   { transform: translate(0, 0); }
  25%  { transform: translate(-3px, 2px); }
  50%  { transform: translate(2px, -3px); }
  75%  { transform: translate(-2px, -1px); }
  100% { transform: translate(0, 0); }
}

/* Instrument markings at the frame edges, not chrome. */
.edge {
  position: absolute; top: 20px; z-index: 5;
  font-family: var(--mono); font-size: 9.5px;
  letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--text-3);
  transition: opacity 0.5s var(--ease), color 0.5s var(--ease);
}
.edge-l { left: 26px; }
.edge-r { right: 26px; text-align: right; }

/* ---- the one focal statement ---- */

.narrative {
  position: absolute; left: 52px; bottom: 46px; z-index: 10;
  width: 384px; padding: 22px 24px 20px;
  background: var(--glass-fill);
  border: 1px solid transparent;
  border-radius: var(--glass-radius);
  box-shadow: var(--glass-shadow);
  backdrop-filter: var(--glass-blur); -webkit-backdrop-filter: var(--glass-blur);
  transition: opacity 0.55s var(--ease), transform 0.55s var(--ease);
}
.narrative::after {
  /* a single lit hairline along the top edge, in the state's accent */
  content: ""; position: absolute; left: 24px; right: 24px; top: 0; height: 1px;
  background: linear-gradient(90deg, transparent, rgba(var(--accent-rgb), 0.55), transparent);
  transition: background 0.5s var(--ease);
}
.n-kicker {
  font-family: var(--mono); font-size: 9.5px;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--text-3); margin-bottom: 10px;
}
.verdict {
  font-family: var(--display);
  font-size: 33px; line-height: 1.02; font-weight: 400;
  letter-spacing: -0.018em;
  color: var(--text-0);
  text-shadow: 0 2px 26px rgba(var(--accent-rgb), 0.20);
}
.lesson {
  margin-top: 11px; font-size: 13.5px; line-height: 1.55;
  color: var(--text-2); text-wrap: balance;
}
.claim {
  margin-top: 13px; padding-top: 13px;
  border-top: 1px solid var(--border);
  font-family: var(--display); font-size: 15.5px; line-height: 1.42;
  color: rgba(var(--accent-rgb), 0.92);
}
.reread {
  margin-top: 13px; padding-top: 13px;
  border-top: 1px solid var(--border);
  display: flex; flex-direction: column; gap: 6px;
}
.rr-label {
  font-family: var(--mono); font-size: 9.5px;
  letter-spacing: 0.12em; text-transform: uppercase; color: var(--text-3);
}
.rr-symbol { font-family: var(--mono); font-size: 13px; color: var(--amber); }
.rr-reason {
  font-family: var(--mono); font-size: 10.5px; color: var(--orange);
  align-self: flex-start;
  padding: 2px 8px; border-radius: 5px;
  background: rgba(251,146,60,0.08); border: 1px solid rgba(251,146,60,0.20);
}

/* ---- live source declaration, pinned beside the source marker ---- */

.sourcecard {
  position: absolute; z-index: 10;
  width: 296px; padding: 14px 16px;
  background: var(--glass-fill);
  border: 1px solid transparent;
  border-radius: var(--glass-radius);
  box-shadow: var(--glass-shadow);
  backdrop-filter: var(--glass-blur); -webkit-backdrop-filter: var(--glass-blur);
  transition: opacity 0.5s var(--ease), transform 0.6s var(--ease);
}
.sc-head { display: flex; align-items: baseline; gap: 8px; margin-bottom: 9px; }
.sc-label {
  font-family: var(--mono); font-size: 9.5px;
  letter-spacing: 0.12em; text-transform: uppercase; color: var(--text-3);
}
.sc-kind { font-family: var(--mono); font-size: 9.5px; color: var(--text-3); margin-left: auto; }
.sc-decl {
  display: block; font-family: var(--mono); font-size: 14px; line-height: 1.5;
  color: rgba(var(--accent-rgb), 0.95);
  overflow-wrap: anywhere;
  transition: color 0.5s var(--ease);
}
.sc-path { display: block; margin-top: 8px; font-family: var(--mono); font-size: 10px; color: var(--text-3); }

/* ---- memory chip, pinned beside the memory marker ---- */

.memcard {
  position: absolute; z-index: 10;
  padding: 10px 14px;
  background: var(--glass-fill);
  border: 1px solid transparent;
  border-radius: var(--glass-radius-sm);
  box-shadow: var(--glass-shadow);
  backdrop-filter: var(--glass-blur); -webkit-backdrop-filter: var(--glass-blur);
  transition: opacity 0.5s var(--ease);
}
.mc-label {
  display: block;
  font-family: var(--mono); font-size: 9.5px;
  letter-spacing: 0.12em; text-transform: uppercase; color: var(--text-3);
  margin-bottom: 5px;
}
.mc-id { display: block; font-family: var(--mono); font-size: 12px; color: var(--text-1); }
.mc-state {
  display: inline-block; margin-top: 7px;
  font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.08em;
  padding: 2px 8px; border-radius: 5px;
  color: rgb(var(--accent-rgb));
  background: rgba(var(--accent-rgb), 0.08);
  border: 1px solid rgba(var(--accent-rgb), 0.20);
  transition: color 0.5s var(--ease), background 0.5s var(--ease), border-color 0.5s var(--ease);
}

/* ---- replay outcome strip ---- */

/* Sits to the right of the narrative panel, which keeps the focal statement
   and the outcomes on one line without either card stack fighting the other. */
.results {
  position: absolute; left: 468px; right: 44px; bottom: 46px; z-index: 12;
  display: grid; grid-template-columns: 1fr 1fr; gap: 12px;
  pointer-events: none;
}
.result {
  padding: 14px 18px;
  background: var(--glass-fill);
  border: 1px solid transparent;
  border-radius: var(--glass-radius);
  box-shadow: var(--glass-shadow);
  backdrop-filter: var(--glass-blur); -webkit-backdrop-filter: var(--glass-blur);
  animation: resultIn 0.6s var(--ease) backwards;
}
.result.good { animation-delay: 0.18s; }
@keyframes resultIn { from { opacity: 0; transform: translateY(14px); } }
.r-title {
  display: block;
  font-family: var(--mono); font-size: 9.5px;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--text-3); margin-bottom: 8px;
}
.r-outcome { display: block; font-family: var(--display); font-size: 23px; line-height: 1.1; }
.result.stale .r-outcome { color: var(--orange); }
.result.good  .r-outcome { color: var(--green); }
.r-stat { display: block; margin-top: 7px; font-family: var(--mono); font-size: 11px; color: var(--text-2); }

/* ---------------------------------------------------------------- dock */

.dock {
  display: flex; align-items: center; gap: 18px;
  padding: 0 24px;
  border-top: 1px solid var(--border);
  background: rgba(4,4,16,0.72);
  backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px);
  position: relative; z-index: 40;
}
.obs {
  display: flex; align-items: center; gap: 9px;
  font-family: var(--mono); font-size: 9.5px;
  letter-spacing: 0.12em; text-transform: uppercase; color: var(--text-3);
}
.obs input {
  width: 58px; padding: 5px 8px;
  background: rgba(255,255,255,0.03);
  border: 1px solid var(--border-strong);
  border-radius: 7px;
  color: var(--text-0);
  font-family: var(--mono); font-size: 12px; letter-spacing: 0;
}
.obs input:focus { outline: none; border-color: rgba(var(--accent-rgb), 0.45); }
.obs:has(input:disabled) { opacity: 0.35; }

.actions { margin-left: auto; display: flex; align-items: center; gap: 9px; }

/* Neutral frost is the resting state for every action. */
.btn {
  padding: 9px 18px;
  border-radius: var(--glass-radius-sm);
  border: 1px solid transparent;
  background: var(--glass-sheen);
  color: var(--text-2);
  font-family: var(--sans); font-size: 13px; font-weight: 500;
  cursor: pointer;
  backdrop-filter: var(--glass-blur); -webkit-backdrop-filter: var(--glass-blur);
  box-shadow: var(--glass-shadow);
  transition: color 0.18s, border-color 0.18s, background 0.18s, box-shadow 0.18s, opacity 0.25s;
}
.btn:hover:not(:disabled) { color: var(--text-1); border-color: var(--border-strong); }
.btn:disabled { opacity: 0.26; cursor: default; }

/* Exactly one lit key at a time. */
.btn.primary:not(:disabled) {
  background: linear-gradient(135deg, rgba(var(--accent-rgb), 0.16), rgba(var(--accent-rgb), 0.07));
  border-color: rgba(var(--accent-rgb), 0.30);
  color: var(--text-0);
  box-shadow:
    0 24px 60px rgba(0,0,0,0.5),
    inset 0 1px 1px rgba(255,255,255,0.5),
    inset 0 -8px 20px rgba(255,255,255,0.06),
    inset 0 0 0 1px rgba(255,255,255,0.14),
    0 0 24px rgba(var(--accent-rgb), 0.14);
}
.btn.primary:not(:disabled):hover {
  background: linear-gradient(135deg, rgba(var(--accent-rgb), 0.26), rgba(var(--accent-rgb), 0.12));
  border-color: rgba(var(--accent-rgb), 0.48);
  box-shadow:
    0 24px 60px rgba(0,0,0,0.5),
    inset 0 1px 1px rgba(255,255,255,0.6),
    inset 0 -8px 20px rgba(255,255,255,0.10),
    inset 0 0 0 1px rgba(255,255,255,0.20),
    0 0 36px rgba(var(--accent-rgb), 0.26);
}
.btn-ghost { background: none; box-shadow: none; color: var(--text-3); }
.btn-ghost:hover:not(:disabled) { background: none; box-shadow: none; }

.err {
  position: absolute; left: 24px; bottom: 84px;
  font-family: var(--mono); font-size: 11px;
  color: var(--red);
  padding: 8px 12px; border-radius: 8px;
  background: rgba(248,113,113,0.08);
  border: 1px solid rgba(248,113,113,0.20);
}

/* ---------------------------------------------------------------- states */

/* During replay the narrative recedes: the landers are the subject. */
body[data-phase="replay"] .narrative { opacity: 0; transform: translateY(10px); pointer-events: none; }
body[data-phase="replay"] .sourcecard,
body[data-phase="replay"] .memcard { opacity: 0; pointer-events: none; }
body[data-phase="replay"] .edge { opacity: 0; }

body[data-phase="settled"] .narrative { transform: translateY(0); }

/* ---------------------------------------------------------------- motion */

@media (prefers-reduced-motion: reduce) {
  .stage-grain { animation: none; }
  .result, .proof-body { animation: none; }
  .narrative, .sourcecard, .memcard, .ctx, .edge, .sc-decl, .mc-state { transition: none; }
}

/* Chromium is the only engine that runs an SVG filter as a backdrop filter;
   everywhere else keeps the dressed, blurred surface and loses only the warp. */
@supports (backdrop-filter: url(#liquid-glass-refraction))
      and (not (-moz-appearance: none))
      and (not (background: -webkit-named-image(apple-pay-logo-black))) {
  .narrative, .sourcecard, .memcard, .result, .proof-body, .btn {
    backdrop-filter: var(--glass-refract);
    -webkit-backdrop-filter: var(--glass-refract);
  }
}

/* ==================================================================
   LANDING PAGE
   The page around the console: same void, same glass, same one-accent
   rule. Nothing here introduces a second visual system — the sections
   are voids with type in them, and the only cards are the two that
   carry a value (the mismatch) and the three that carry a step.
   ================================================================== */

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 200;
  padding: 10px 16px; border-radius: 0 0 10px 0;
  background: var(--bg-1); color: var(--text-0);
  font-family: var(--mono); font-size: 11px;
}
.skip:focus { left: 0; }

/* ---------------------------------------------------------- site nav */

.sitebar {
  position: sticky; top: 0; z-index: 80;
  display: flex; align-items: center; gap: 14px;
  height: 52px; padding: 0 clamp(18px, 4vw, 44px);
  background: var(--chrome);
  backdrop-filter: blur(18px); -webkit-backdrop-filter: blur(18px);
  border-bottom: 1px solid var(--border);
}
.sitebar-tag {
  font-family: var(--mono); font-size: 9.5px;
  letter-spacing: 0.12em; text-transform: uppercase; color: var(--text-3);
  padding-left: 14px; border-left: 1px solid var(--border-strong);
}
.sitebar-links { margin-left: auto; display: flex; align-items: center; gap: 22px; }
.sitebar-links a {
  font-family: var(--mono); font-size: 10.5px;
  letter-spacing: 0.09em; text-transform: uppercase;
  color: var(--text-3); text-decoration: none;
  transition: color 0.18s;
}
.sitebar-links a:hover { color: rgba(var(--accent-rgb), 0.95); }

.theme-toggle {
  display: grid; place-items: center;
  width: 30px; height: 30px; padding: 0;
  border-radius: 8px; cursor: pointer;
  border: 1px solid var(--border);
  background: var(--glass-sheen);
  color: var(--text-3);
  transition: color 0.18s, border-color 0.18s, background 0.18s;
}
.theme-toggle:hover { color: rgba(var(--accent-rgb), 0.95); border-color: var(--border-strong); }
.theme-toggle:focus-visible { outline: 2px solid rgba(var(--accent-rgb), 0.6); outline-offset: 2px; }
.ti { width: 15px; height: 15px; grid-area: 1 / 1; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; }
.ti-moon { fill: currentColor; stroke: none; }
/* The icon shows the theme you would switch *to*. */
.ti-sun { display: none; }
:root[data-theme="dark"] .ti-sun { display: block; }
:root[data-theme="dark"] .ti-moon { display: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .ti-sun { display: block; }
  :root:not([data-theme="light"]) .ti-moon { display: none; }
}

/* -------------------------------------------------------- typography */

.display { font-family: var(--display); font-weight: 400; letter-spacing: -0.02em; }
.h1 { font-size: clamp(40px, 5.9vw, 70px); line-height: 1.02; color: var(--text-0); letter-spacing: -0.025em; }
.h2 { font-size: clamp(28px, 3.7vw, 46px); line-height: 1.06; color: var(--text-0); }
.kicker {
  font-family: var(--mono); font-size: 10px;
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--text-3);
}
.lede {
  margin-top: 22px; max-width: 46ch;
  font-size: clamp(15px, 1.35vw, 17.5px); line-height: 1.62;
  color: var(--text-2); text-wrap: pretty;
}

/* --------------------------------------------------------------- hero */

.hero {
  position: relative; overflow: hidden;
  min-height: calc(100svh - 52px);
  display: flex; flex-direction: column; justify-content: center;
  padding: clamp(56px, 9vh, 110px) clamp(20px, 5vw, 64px) 96px;
}
/* A star-void built from gradients in the dark, an atmospheric wash in the
   light: the same lit-from-behind composition either way. */
.hero-sky {
  position: absolute; inset: -20% -10% 0; z-index: 0;
  background:
    radial-gradient(ellipse 60% 46% at 26% 34%, var(--wash-1), transparent 62%),
    radial-gradient(ellipse 50% 40% at 78% 62%, var(--wash-2), transparent 66%),
    radial-gradient(ellipse 90% 70% at 50% 0%, var(--wash-3), transparent 70%),
    radial-gradient(circle at 12% 18%, var(--star) 0.6px, transparent 1.2px),
    radial-gradient(circle at 82% 12%, var(--star) 0.6px, transparent 1.2px),
    radial-gradient(circle at 46% 76%, var(--star) 0.6px, transparent 1.2px),
    radial-gradient(circle at 66% 30%, var(--star) 0.5px, transparent 1.1px),
    radial-gradient(circle at 30% 58%, var(--star) 0.5px, transparent 1.1px);
  background-repeat: no-repeat;
}
.hero-sky::after {
  /* vignette down into the first band so the fold is not a hard edge */
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, transparent 55%, var(--bg-0) 100%);
}

.hero-inner {
  position: relative; z-index: 2;
  width: 100%; max-width: 1180px; margin: 0 auto;
  display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  gap: clamp(24px, 5vw, 72px); align-items: center;
}
.hero-copy .kicker { margin-bottom: 22px; }

.hero-actions { margin-top: 38px; display: flex; flex-wrap: wrap; gap: 12px; }

/* Page-level buttons reuse the console's frost, lit in the resting accent. */
.btn-cta, .btn-quiet {
  display: inline-block; text-decoration: none;
  padding: 12px 22px; border-radius: var(--glass-radius-sm);
  font-family: var(--sans); font-size: 13.5px; font-weight: 500;
  border: 1px solid transparent;
  transition: color 0.18s, border-color 0.18s, background 0.18s, box-shadow 0.18s;
}
.btn-cta {
  color: var(--text-0);
  background: linear-gradient(135deg, rgba(var(--accent-rgb), 0.16), rgba(var(--accent-rgb), 0.07));
  border-color: rgba(var(--accent-rgb), 0.30);
  box-shadow:
    0 24px 60px rgba(0,0,0,0.5),
    inset 0 1px 1px rgba(255,255,255,0.5),
    inset 0 0 0 1px rgba(255,255,255,0.14),
    0 0 24px rgba(var(--accent-rgb), 0.14);
}
.btn-cta:hover {
  background: linear-gradient(135deg, rgba(var(--accent-rgb), 0.26), rgba(var(--accent-rgb), 0.12));
  border-color: rgba(var(--accent-rgb), 0.48);
  box-shadow:
    0 24px 60px rgba(0,0,0,0.5),
    inset 0 1px 1px rgba(255,255,255,0.6),
    inset 0 0 0 1px rgba(255,255,255,0.20),
    0 0 36px rgba(var(--accent-rgb), 0.26);
}
.btn-quiet { color: var(--text-2); background: var(--glass-sheen); }
.btn-quiet:hover { color: var(--text-0); border-color: var(--border-strong); }

/* ---- hero tether figure ---- */

.tether-figure { position: relative; }
.tether-figure svg { width: 100%; height: auto; overflow: visible; }
/* Gradient stops are styled rather than hard-coded so the figure follows
   the theme along with everything else. */
.tf-glow-in  { stop-color: rgba(var(--accent-rgb), 0.42); }
.tf-glow-out { stop-color: rgba(var(--accent-rgb), 0); }
.tf-line-end { stop-color: rgba(var(--accent-rgb), 0.16); }
.tf-line-mid { stop-color: rgba(var(--accent-rgb), 0.70); }
.tf-tether {
  fill: none; stroke: url(#tether-line); stroke-width: 2;
}
.tf-flow {
  fill: none; stroke: var(--tf-pulse, rgba(255,255,255,0.9)); stroke-width: 1.8;
  stroke-dasharray: 3 190; stroke-linecap: round;
  filter: drop-shadow(0 0 6px rgba(var(--accent-rgb), 0.9));
  animation: tetherFlow 3.6s linear infinite;
}
@keyframes tetherFlow { from { stroke-dashoffset: 193; } to { stroke-dashoffset: 0; } }
.tf-ring {
  fill: none; stroke: rgba(var(--accent-rgb), 0.55); stroke-width: 1.4;
  stroke-dasharray: 4 7;
  transform-box: fill-box; transform-origin: center;
  animation: ringSpin 34s linear infinite;
}
@keyframes ringSpin { to { transform: rotate(360deg); } }
.tf-core { fill: var(--tf-core, #d9fff7); filter: drop-shadow(0 0 10px rgba(var(--accent-rgb), 0.9)); }
.tf-bracket path { fill: none; stroke: rgba(var(--accent-rgb), 0.6); stroke-width: 2; }
.tf-label {
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.18em;
  fill: var(--text-1);
}
.tf-sub, .tf-mid {
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.06em;
  fill: var(--text-3);
}
.tf-mid { letter-spacing: 0.14em; text-transform: uppercase; font-size: 9px; }

.scroll-cue {
  position: absolute; left: 50%; bottom: 30px; transform: translateX(-50%);
  z-index: 3; text-decoration: none;
  font-family: var(--mono); font-size: 9.5px;
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--text-3);
  display: flex; flex-direction: column; align-items: center; gap: 9px;
}
.scroll-cue::after {
  content: ""; width: 1px; height: 34px;
  background: linear-gradient(180deg, rgba(var(--accent-rgb), 0.6), transparent);
  animation: cueDrift 2.6s ease-in-out infinite;
}
@keyframes cueDrift { 0%,100% { opacity: 0.35; } 50% { opacity: 1; } }
.scroll-cue:hover { color: var(--text-1); }

/* -------------------------------------------------------------- bands */

.band {
  position: relative;
  max-width: 1180px; margin: 0 auto;
  padding: clamp(84px, 12vh, 148px) clamp(20px, 5vw, 64px);
}
.band + .band { border-top: 1px solid var(--border); }
.band-head { max-width: 62ch; }
.band-head .kicker { margin-bottom: 20px; }
.band-head .h2 { text-wrap: balance; }
.band-lede {
  margin-top: 20px; max-width: 56ch;
  font-size: 15.5px; line-height: 1.62; color: var(--text-2);
}

/* ---- 01 the mismatch ---- */

.mismatch {
  margin-top: 54px;
  display: grid; grid-template-columns: 1fr 132px 1fr;
  align-items: center; gap: 0;
}
.mm-card {
  padding: 26px 28px;
  background: var(--glass-fill);
  border: 1px solid transparent;
  border-radius: var(--glass-radius);
  box-shadow: var(--glass-shadow);
  backdrop-filter: var(--glass-blur); -webkit-backdrop-filter: var(--glass-blur);
  position: relative;
}
.mm-card::after {
  content: ""; position: absolute; left: 28px; right: 28px; top: 0; height: 1px;
}
.mm-stale::after { background: linear-gradient(90deg, transparent, rgba(251,191,36,0.55), transparent); }
.mm-live::after  { background: linear-gradient(90deg, transparent, rgba(90,235,212,0.55), transparent); }
.mm-label {
  display: block;
  font-family: var(--mono); font-size: 9.5px;
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--text-3);
}
.mm-code {
  display: block; margin-top: 16px;
  font-family: var(--mono); font-size: clamp(17px, 2.1vw, 24px);
  color: var(--text-1);
}
.mm-stale .mm-code b { color: var(--amber); font-weight: 500; }
.mm-live  .mm-code b { color: var(--teal);  font-weight: 500; }
.mm-note {
  display: block; margin-top: 14px;
  font-size: 12.5px; line-height: 1.5; color: var(--text-3);
}
.mm-break {
  position: relative; height: 100%;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px;
}
.mm-break svg { width: 100%; height: 60px; overflow: visible; }
.mm-break path { fill: none; stroke-width: 1.4; }
.mb-l { stroke: rgba(251,191,36,0.6); }
.mb-r { stroke: rgba(90,235,212,0.6); }
.mb-dot { fill: rgba(255,255,255,0.5); }
.mm-break-tag {
  font-family: var(--mono); font-size: 8.5px;
  letter-spacing: 0.11em; text-transform: uppercase; color: var(--orange);
  padding: 3px 8px; border-radius: 5px; white-space: nowrap;
  background: rgba(251,146,60,0.08); border: 1px solid rgba(251,146,60,0.20);
}
.consequence {
  margin-top: 44px; max-width: 66ch;
  font-family: var(--display); font-size: clamp(18px, 2vw, 23px); line-height: 1.5;
  color: var(--text-1);
}
.consequence code { font-family: var(--mono); font-size: 0.78em; color: var(--text-2); }
.consequence .hot { color: var(--hot); font-weight: 400; }
.consequence .ok  { color: var(--ok);  font-weight: 400; }

/* ---- 02 the three steps ---- */

.steps {
  margin-top: 56px; list-style: none;
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px;
}
.step {
  padding: 26px 26px 28px;
  background: var(--glass-fill);
  border: 1px solid transparent;
  border-radius: var(--glass-radius);
  box-shadow: var(--glass-shadow);
  backdrop-filter: var(--glass-blur); -webkit-backdrop-filter: var(--glass-blur);
  display: flex; flex-direction: column;
}
.step-n {
  font-family: var(--mono); font-size: 10px;
  letter-spacing: 0.16em; color: rgba(var(--accent-rgb), 0.75);
}
.step-h {
  margin-top: 16px; font-family: var(--display); font-weight: 400;
  font-size: 25px; line-height: 1.12; color: var(--text-0);
  letter-spacing: -0.015em;
}
.step p { margin-top: 12px; font-size: 13.5px; line-height: 1.6; color: var(--text-2); }
.step-code {
  display: block; margin-top: auto; padding-top: 18px;
  font-family: var(--mono); font-size: 11.5px; line-height: 1.62;
  color: rgba(var(--accent-rgb), 0.88); overflow-wrap: anywhere;
}
.step-code-dim { display: block; margin-top: 8px; color: var(--text-3); }
.gate-list { margin-top: 18px; list-style: none; display: grid; gap: 9px; }
.gate-list li {
  display: flex; align-items: flex-start; gap: 11px;
  font-size: 12.5px; line-height: 1.5; color: var(--text-2);
}
.g-tag {
  font-family: var(--mono); font-size: 9px;
  letter-spacing: 0.10em; text-transform: uppercase;
  padding: 3px 8px; border-radius: 5px; min-width: 94px; text-align: center;
  flex: 0 0 auto; margin-top: 2px;
}
.g-ok  { color: var(--green);  background: rgba(52,211,153,0.08);  border: 1px solid rgba(52,211,153,0.22); }
.g-hot { color: var(--orange); background: rgba(251,146,60,0.08);  border: 1px solid rgba(251,146,60,0.22); }
.g-off { color: var(--text-3); background: rgba(255,255,255,0.03); border: 1px solid var(--border-strong); }

.nuance {
  margin-top: 34px; padding: 30px 34px;
  max-width: 78ch;
  border-radius: var(--glass-radius);
  border-left: 1px solid rgba(var(--accent-rgb), 0.45);
  background: linear-gradient(90deg, rgba(var(--accent-rgb), 0.055), transparent 62%);
}
.nuance p.nuance-h {
  font-size: clamp(21px, 2.4vw, 28px); line-height: 1.14;
  color: var(--text-0); margin-bottom: 12px;
}
.nuance p { font-size: 14.5px; line-height: 1.66; color: var(--text-2); }
.nuance-alt { margin-top: 16px; }

/* ---- 03 the mission chapter ----
   This is deliberately not another editorial band. It has its own long
   scroll range: a full viewport for the briefing, two for the interactive
   console, and a full viewport for the handoff back to the editorial page. */
.mission-chapter {
  position: relative;
  min-height: 600svh;
  max-width: none;
  background: var(--void);
  color: var(--text-1);
  isolation: isolate;
  overflow: clip;
  --mission-entry: 0;
  --mission-console-in: 0;
  --mission-console-out: 0;
  --mission-exit: 0;
}
.band + .mission-chapter { border-top: none; }
.mission-chapter + .band { border-top: none; }

/* Both seams are drawn by the pin (see .mission-pin::before / ::after), not
   by strips anchored to the chapter: the pin is what the reader actually
   sees, and a strip anchored to the chapter's bottom edge ends up painting
   over the pin once the pin has already dissolved into the page. */

/* The pinned frame is the other world. It stays at viewport scale while its
   parent provides enough scroll distance to enter, interact, and leave. */
.mission-pin {
  position: sticky; top: 0;
  height: 100svh;
  overflow: hidden;
  background: var(--void);
}

/* The seam on the way in. While the pin is still rising into the viewport its
   top edge meets the page as a hard line; this dissolves that edge into the
   page colour, then burns off over the first few pixels of the chapter so it
   never tints the world once the world owns the screen. --page-bg is the one
   token the chapter deliberately does not override, for exactly this. */
.mission-pin::before {
  content: ""; position: absolute; z-index: 9; inset: 0 0 auto 0;
  height: 30svh; pointer-events: none;
  background: linear-gradient(180deg, var(--page-bg), transparent 92%);
  opacity: max(0, calc(1 - var(--mission-entry) * 14));
}

/* And the seam on the way out. The pin keeps its void until the chapter ends,
   which in the light theme leaves a dark band under the returning nav. This
   floods the pin with the page colour over the last stretch of the exit, so
   the world resolves into the page instead of being cut away from it. */
.mission-pin::after {
  content: ""; position: absolute; z-index: 8; inset: 0;
  pointer-events: none;
  background: var(--page-bg);
  opacity: max(0, calc((var(--mission-exit) - 0.62) / 0.33));
}
.console {
  position: absolute; inset: 0; z-index: 2;
  height: 100%;
  transform-origin: 50% 52%;
  pointer-events: none;
  transform: translateY(calc((1 - var(--mission-console-in)) * 10svh))
    scale(calc(0.94 + var(--mission-console-in) * 0.06 - var(--mission-console-out) * 0.035));
  opacity: calc(var(--mission-console-in) * (1 - var(--mission-console-out)));
  filter: blur(calc((1 - var(--mission-console-in)) * 7px + var(--mission-console-out) * 7px));
  transition: opacity 0.08s linear, transform 0.08s linear, filter 0.08s linear;
}
.console.is-interactive { pointer-events: auto; }

/* ---- Inside the mission ----
   While the scene owns the viewport, the ordinary site chrome gets out of
   the way and the surrounding void takes on the console's star field. The
   chrome leaves at the top of the chapter rather than at the console, so the
   world has already changed by the time the first gate is legible. */
body.in-demo { --grain-fine: 0.26; --grain-coarse: 0.12; --stars: 0.72; }
body.in-demo .sitebar { transform: translateY(-100%); opacity: 0; }
.sitebar { transition: transform 0.55s var(--ease), opacity 0.4s var(--ease); }
.grain { transition: opacity 0.7s var(--ease); }

/* ---- The mission gates ----

   Entry and exit are the same object twice: a full-frame world with its own
   opaque sky, its own star field, and one centred stack — craft, kicker,
   title, line, cue — read as a single cinematic screen rather than a card
   floating over the console.

   Opaque is the point. A gate paints its own sky edge to edge, so while it
   is up the console beneath it is not merely dimmed, it is covered: the dock
   cannot show through and cannot compete with the gate's type. The console's
   own opacity is already zero either side of it (ranges in app.js leave a
   deliberate gap), and this is the second lock on the same door.

   --gate-go is how far through the gate we are: 0 on arrival, 1 at the
   handoff. Both gates drive every part of the composition from it, which is
   why the entry descends and the exit climbs off one shared set of rules. */

.mission-gate {
  position: absolute; inset: 0; z-index: 6;
  display: grid; place-items: center;
  padding: 0 24px;
  text-align: center;
  pointer-events: none;
  isolation: isolate;
  overflow: hidden;
  --gate-warp: max(0, calc((var(--gate-go) - 0.42) / 0.58));
}

.mission-entry {
  --gate-go: var(--mission-entry);
  --gate-accent: 90,235,212;
  /* Held at full strength through the approach, then gone well before the
     console starts to arrive. */
  opacity: max(0, calc((1 - var(--mission-entry)) * 3.6));
}
.mission-exit {
  --gate-go: var(--mission-exit);
  --gate-accent: 251,191,36;
  /* In as the console leaves, held through the ascent, then out again so the
     chapter hands back to the roadmap on a dissolve rather than a cut. */
  opacity: min(
    1,
    calc(var(--mission-exit) * 5),
    max(0, calc((1 - var(--mission-exit)) * 4.2))
  );
}

/* ---- sky ---- */

.gate-sky { position: absolute; inset: 0; z-index: 0; overflow: hidden; }
.gate-sky::before {
  content: ""; position: absolute; inset: 0;
  background:
    radial-gradient(ellipse 90% 55% at 50% 40%, rgba(var(--gate-accent),0.09), transparent 64%),
    radial-gradient(ellipse 130% 60% at 50% 112%, rgba(var(--gate-accent),0.16), transparent 62%),
    linear-gradient(180deg, #02020a 0%, #05050f 44%, #08081a 100%);
}

/* Two parallax layers of the same tile. The drift animates `translate`, not
   `background-position`: a composited move of one already-rastered layer
   instead of a full repaint of a viewport-and-a-half every frame. The scroll
   scale rides on `transform`, which composes with it. */
.gate-stars {
  position: absolute; left: -30%; right: -30%; top: -100%; bottom: -100%;
  background-image: var(--star-tile);
  background-repeat: repeat;
  will-change: transform, translate;
}
.gate-stars-far {
  background-size: 900px 900px; opacity: 0.55;
  transform: scale(calc(1 + var(--gate-warp) * 0.45));
  animation: gate-drift-far 190s linear infinite;
}
.gate-stars-near {
  background-size: 420px 420px; opacity: 0.8;
  transform: scale(calc(1 + var(--gate-warp) * 1.5));
  animation: gate-drift-near 96s linear infinite;
}

/* The jump. Radial hairlines out of the centre of frame, masked to a ring so
   nothing crosses the type, scaled and lit by --gate-warp alone. */
.gate-warp {
  position: absolute; left: 50%; top: 50%;
  width: min(112vmax, 1080px); aspect-ratio: 1;
  translate: -50% -50%;
  opacity: calc(var(--gate-warp) * 0.62);
  transform: scale(calc(1 + var(--gate-warp) * 2.4));
  background: repeating-conic-gradient(from 0deg at 50% 50%,
    transparent 0deg 1.05deg,
    rgba(255,255,255,0.55) 1.1deg 1.22deg,
    transparent 1.28deg 2.9deg);
  -webkit-mask-image: radial-gradient(circle at 50% 50%, transparent 17%, #000 46%, transparent 78%);
  mask-image: radial-gradient(circle at 50% 50%, transparent 17%, #000 46%, transparent 78%);
  will-change: transform, opacity;
}

/* The body being approached, or left. A shallow dome with a lit rim, low
   enough in frame that it never reaches the cue line. */
.gate-limb {
  position: absolute; left: 50%;
  bottom: calc(-24svh + var(--gate-go) * 5svh);
  width: min(180vw, 1800px); height: 42svh;
  transform: translateX(-50%) scale(calc(1 + var(--gate-go) * 0.1));
  border-radius: 50% 50% 0 0 / 100% 100% 0 0;
  background:
    radial-gradient(ellipse 46% 70% at 50% 104%, rgba(150,164,190,0.16), transparent 68%),
    linear-gradient(180deg, rgba(160,176,200,0.13), rgba(4,4,14,0.92) 46%);
  box-shadow:
    0 -1px 0 rgba(var(--gate-accent),0.5),
    0 -22px 90px rgba(var(--gate-accent),0.14);
}
.mission-exit .gate-limb { bottom: calc(-24svh - var(--gate-go) * 20svh); }

.gate-vignette {
  position: absolute; inset: 0;
  background: radial-gradient(ellipse 78% 62% at 50% 48%, transparent 42%, rgba(2,2,8,0.88) 100%);
}

/* ---- the centred stack ---- */

/* The whole stack travels as one, so the craft can never drift into the
   type: what changes between them is depth, not position. */
.gate-stack {
  position: relative; z-index: 2;
  display: grid; justify-items: center; align-content: center;
  width: min(680px, 100%);
}
.mission-entry .gate-stack {
  transform: translateY(calc(var(--gate-go) * 74px)) scale(calc(1 - var(--gate-go) * 0.1));
}
.mission-exit .gate-stack {
  transform: translateY(calc(var(--gate-go) * -52px)) scale(calc(1 - var(--gate-go) * 0.06));
}

.gate-craft {
  width: clamp(146px, 15.5vw, 208px);
  margin-bottom: 34px;
  filter: drop-shadow(0 0 26px rgba(var(--gate-accent),0.28));
}
/* Scroll drives the group; the idle float uses `translate`, which composes
   with `transform` instead of replacing it. */
/* Descending is a move away from the camera, not down the page: a short
   fall plus a hard scale-down, so the lander shrinks toward the limb. */
.mission-entry .gate-craft {
  transform: translateY(calc(var(--gate-go) * 42px)) scale(calc(1 - var(--gate-go) * 0.36));
}
.mission-exit .gate-craft {
  transform: translateY(calc(var(--gate-go) * -150px)) scale(calc(1 - var(--gate-go) * 0.55));
  opacity: calc(1 - var(--gate-go) * 0.5);
}
.lm { display: block; width: 100%; height: auto; overflow: visible; animation: gate-hover 4.6s ease-in-out infinite; }
.mission-exit .lm { animation: none; }

.gate-kicker {
  display: flex; align-items: center; gap: clamp(12px, 2vw, 20px);
  font-family: var(--mono); font-size: 9.5px; font-weight: 500;
  letter-spacing: 0.32em; text-transform: uppercase;
  color: rgba(var(--gate-accent),0.88);
}
.gate-kicker::before, .gate-kicker::after {
  content: ""; width: clamp(28px, 7vw, 78px); height: 1px;
}
.gate-kicker::before { background: linear-gradient(90deg, transparent, rgba(var(--gate-accent),0.6)); }
.gate-kicker::after  { background: linear-gradient(270deg, transparent, rgba(var(--gate-accent),0.6)); }

.gate-title {
  margin-top: 20px;
  font-size: clamp(44px, 7.2vw, 92px); line-height: 0.94; letter-spacing: -0.012em;
  color: var(--text-0);
  text-shadow: 0 0 70px rgba(var(--gate-accent),0.22);
}
.gate-copy {
  margin-top: 20px; max-width: 42ch;
  font-size: 15px; line-height: 1.62; color: var(--text-2);
}

/* ---- keep scrolling ---- */

.gate-cue { margin-top: 42px; display: grid; justify-items: center; gap: 11px; }
.gate-beacon {
  position: relative; width: 1px; height: 52px;
  background: linear-gradient(180deg, transparent, rgba(var(--gate-accent),0.45) 34%, transparent);
}
.gate-beacon::after {
  content: ""; position: absolute; left: -2.5px; top: 0;
  width: 6px; height: 6px; border-radius: 50%;
  background: #eafff9; box-shadow: 0 0 14px 3px rgba(var(--gate-accent),0.8);
  animation: gate-drop 1.7s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
.gate-chevrons { display: grid; justify-items: center; gap: 3px; }
.gate-chevrons b {
  width: 13px; height: 13px;
  border-right: 1px solid rgba(var(--gate-accent),0.92);
  border-bottom: 1px solid rgba(var(--gate-accent),0.92);
  rotate: 45deg;
  filter: drop-shadow(0 0 4px rgba(var(--gate-accent),0.75));
  animation: gate-chev 1.7s ease-in-out infinite;
}
.gate-chevrons b:nth-child(2) { animation-delay: 0.14s; opacity: 0.66; }
.gate-chevrons b:nth-child(3) { animation-delay: 0.28s; opacity: 0.38; }
.gate-cue-text {
  margin-top: 4px;
  font-family: var(--mono); font-size: 9px; letter-spacing: 0.28em; text-transform: uppercase;
  color: var(--text-3);
}

/* ---- the craft ----
   Line art, not a render: thin struts, one lit window, one lit plume, so it
   sits in the same drawing language as the tether figure on the hero. */

.lm-hull      { fill: rgba(206,220,232,0.12); stroke: rgba(228,240,242,0.78); stroke-width: 1.3; stroke-linejoin: round; }
.lm-hull-dark { fill: rgba(6,8,18,0.7);  stroke: rgba(228,240,242,0.42); stroke-width: 1; }
.lm-foil      { fill: rgba(196,174,124,0.16); stroke: rgba(230,216,178,0.6); stroke-width: 1.2; stroke-linejoin: round; }
.lm-line      { fill: none; stroke: rgba(228,240,242,0.3); stroke-width: 0.9; }
.lm-strut     { fill: none; stroke: rgba(228,240,242,0.72); stroke-width: 1.35; stroke-linecap: round; }
.lm-strut-back{ stroke: rgba(228,240,242,0.36); stroke-width: 1; }
.lm-pad       { fill: rgba(228,240,242,0.16); stroke: rgba(228,240,242,0.64); stroke-width: 1; }
.lm-pad-back  { fill: rgba(228,240,242,0.08); stroke: rgba(228,240,242,0.32); }
.lm-dish      { fill: rgba(6,8,18,0.6); stroke: rgba(228,240,242,0.5); stroke-width: 1; }
.lm-lamp      { fill: rgba(var(--gate-accent),0.95); }
.lm-bell      { fill: rgba(8,10,20,0.72); stroke: rgba(228,240,242,0.62); stroke-width: 1.2; }
.lm-glass {
  fill: rgba(var(--gate-accent),0.32);
  stroke: rgba(var(--gate-accent),0.95); stroke-width: 1.3;
  filter: drop-shadow(0 0 7px rgba(var(--gate-accent),0.85));
}

/* The burn: three stacked cones standing in for a gradient, the group scaled
   by scroll and the cones flickering inside it. */
.lm-plume, .lm-plume path { transform-box: view-box; }
.lm-plume path { animation: lm-burn 0.62s ease-in-out infinite alternate; }

/* Scaled from the nozzle, which is a different point on each craft. */
.mission-entry .lm-plume,
.mission-entry .lm-plume path { transform-origin: 100px 166px; }
.mission-exit .lm-plume,
.mission-exit .lm-plume path  { transform-origin: 100px 135px; }

.mission-entry .lm-plume { scale: 1 calc(0.88 + var(--gate-go) * 0.7); }
.mission-exit .lm-plume  { scale: 1 calc(0.9 + var(--gate-go) * 1.1); }

.lm-plume-outer { fill: rgba(var(--gate-accent),0.14); }
.lm-plume-mid   { fill: rgba(var(--gate-accent),0.4); animation-delay: 0.08s; }
.lm-plume-core  {
  fill: rgba(240,255,252,0.9); animation-delay: 0.16s;
  filter: drop-shadow(0 0 9px rgba(var(--gate-accent),0.95));
}

@keyframes gate-hover { 50% { translate: 0 -10px; } }
@keyframes gate-drop  { to { translate: 0 46px; opacity: 0; } }
@keyframes gate-chev  { 50% { opacity: 1; translate: 0 7px; } }
@keyframes gate-drift-far  { to { translate: 0 900px; } }
@keyframes gate-drift-near { to { translate: 0 420px; } }
@keyframes lm-burn    { to { scale: 0.88 1.14; opacity: 0.72; } }

/* A gate is one screen, so it is bounded by height as much as by width: on a
   short viewport the stack compacts rather than running off the frame. */
@media (max-height: 800px) {
  .gate-craft { width: clamp(104px, 11vw, 148px); margin-bottom: 22px; }
  .gate-title { font-size: clamp(34px, 5.2vw, 58px); margin-top: 15px; }
  .gate-copy { margin-top: 14px; font-size: 14px; }
  .gate-cue { margin-top: 24px; gap: 8px; }
  .gate-beacon { height: 34px; }
  /* The lit rim has to stay clear of the cue line it would otherwise cross. */
  .gate-limb { height: 32svh; bottom: -21svh; }
}
@media (max-height: 620px) {
  .gate-craft { width: clamp(88px, 9vw, 116px); margin-bottom: 16px; }
  .gate-title { font-size: clamp(29px, 4.4vw, 44px); }
  .gate-copy { display: none; }
  .gate-cue { margin-top: 18px; }
  .gate-beacon { display: none; }
}

@media (max-width: 520px) {
  .gate-kicker { font-size: 8.5px; letter-spacing: 0.2em; gap: 10px; }
  .gate-kicker::before, .gate-kicker::after { width: clamp(12px, 5vw, 28px); }
  .gate-cue-text { font-size: 8.5px; letter-spacing: 0.22em; }
}

@media (max-width: 860px) {
  .gate-craft { width: clamp(120px, 34vw, 168px); margin-bottom: 26px; }
  .gate-title { font-size: clamp(34px, 10vw, 56px); }
  .gate-copy { font-size: 14px; }
  .gate-cue { margin-top: 30px; }
  .gate-beacon { height: 38px; }
  .gate-limb { height: 34svh; }
}

/* Reduced motion keeps both gates — they carry the narrative, and a scroll-
   linked crossfade is not motion. What goes is everything that travels: the
   idle float, the burn flicker, the drifting stars, and the jump. */
@media (prefers-reduced-motion: reduce) {
  .console { transform: none; filter: none; pointer-events: auto; transition: none; }
  .gate-stack, .gate-craft, .gate-stars, .gate-limb { transform: none; }
  .lm, .lm-plume path, .gate-stars,
  .gate-beacon::after, .gate-chevrons b { animation: none; }
  .gate-chevrons b:nth-child(2) { opacity: 0.66; }
  .gate-chevrons b:nth-child(3) { opacity: 0.38; }
  .gate-warp { display: none; }
}

/* ---- 04 scope ---- */

.scope-grid {
  margin-top: 54px;
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(24px, 5vw, 72px);
}
.scope-h {
  font-family: var(--mono); font-size: 9.5px;
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--text-3);
  padding-bottom: 14px; border-bottom: 1px solid var(--border);
}
.scope-col ul { list-style: none; margin-top: 18px; display: grid; gap: 14px; }
.scope-col li {
  font-size: 14px; line-height: 1.6; color: var(--text-2);
  padding-left: 20px; position: relative;
}
.scope-col li::before {
  content: ""; position: absolute; left: 0; top: 9px;
  width: 5px; height: 5px; border-radius: 50%;
  background: rgba(var(--accent-rgb), 0.55);
}
.band-close .band-head { max-width: 78ch; }
/* The roadmap column is stated as intent, and marked as such: a hollow
   bullet against the filled one on the left. */
.scope-next li::before { background: none; box-shadow: inset 0 0 0 1px rgba(var(--accent-rgb), 0.7); }
.np {
  font-family: var(--mono); font-size: 0.86em;
  color: rgba(var(--accent-rgb), 0.95);
}
.close-actions { margin-top: 48px; display: flex; flex-wrap: wrap; gap: 12px; }

/* ------------------------------------------------------------- footer */

.sitefoot {
  border-top: 1px solid var(--border);
  padding: 26px clamp(20px, 5vw, 64px) 40px;
  max-width: 1180px; margin: 0 auto;
  display: flex; flex-wrap: wrap; gap: 12px 24px; align-items: baseline;
  font-family: var(--mono); font-size: 10px;
  letter-spacing: 0.09em; text-transform: uppercase; color: var(--text-3);
}
.sitefoot span:first-child { color: var(--text-1); }

/* -------------------------------------------------------- responsive */

@media (max-width: 1040px) {
  .hero-inner { grid-template-columns: 1fr; gap: 46px; }
  .tether-figure { max-width: 560px; }
  .steps { grid-template-columns: 1fr; }
  .step-code { margin-top: 18px; }
}

@media (max-width: 860px) {
  .sitebar-tag { display: none; }
  .mismatch { grid-template-columns: 1fr; gap: 0; }
  .mm-break { flex-direction: row; height: auto; padding: 20px 0; }
  .mm-break svg { display: none; }
  .scope-grid { grid-template-columns: 1fr; gap: 40px; }
  .scroll-cue { display: none; }

  /* Console at phone width: the overlays leave the canvas edges and stack
     as a single column so nothing lands off-frame. The screen still fills
     the viewport; the stage takes whatever the dock does not. */
  .shell { height: 100%; grid-template-rows: 44px minmax(0, 1fr) auto; }
  .topbar { padding: 0 14px; gap: 10px; }
  .console-brand { font-size: 12px; }
  .ctx { font-size: 9px; }
  .hosted-note { display: none; }
  .proof-body { width: min(84vw, 360px); }
  .proof-body dl { grid-template-columns: 104px 1fr; }

  .narrative {
    left: 12px; right: 12px; bottom: 12px; width: auto; padding: 16px 18px 15px;
  }
  .verdict { font-size: 26px; }
  .lesson { font-size: 12.5px; }
  .claim { font-size: 14px; }
  .memcard, .sourcecard { display: none; }
  .edge { font-size: 8.5px; }
  .edge-l { left: 14px; } .edge-r { right: 14px; }

  /* Outcomes move to the top of the frame so they never collide with the
     narrative panel now spanning the bottom. */
  .results {
    left: 12px; right: 12px; top: 42px; bottom: auto;
    grid-template-columns: 1fr 1fr; gap: 8px;
  }
  .result { padding: 10px 12px; }
  .r-outcome { font-size: 18px; }
  .r-stat { font-size: 9.5px; }

  .dock { flex-wrap: wrap; padding: 14px; gap: 10px; }
  .actions { margin-left: 0; width: 100%; flex-wrap: wrap; gap: 8px; }
  .actions .btn { flex: 1 1 auto; padding: 10px 12px; font-size: 12.5px; }
  .err { position: static; }
}

@media (max-width: 520px) {
  .results { grid-template-columns: 1fr; }
  .hero-actions .btn-cta, .hero-actions .btn-quiet,
  .close-actions .btn-cta, .close-actions .btn-quiet { width: 100%; text-align: center; }
}

@media (prefers-reduced-motion: reduce) {
  .tf-flow, .tf-ring, .scroll-cue::after { animation: none; }
  .tf-flow { display: none; }
}


/* ==================================================================
   LIGHT THEME CORRECTIONS
   The tokens carry most of it. These are the places where a value was
   tuned for a luminous pane over a void and has to be restated for ink
   on paper: tinted badges, hairlines, the accent lines on the mismatch
   cards, and the frame around the console — which stays dark, and so
   needs a real bezel and a cast shadow to sit on the page.
   ================================================================== */

@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) { --tf-core: #0b6f63; --tf-pulse: rgba(11,111,99,0.85); }
}
:root[data-theme="light"] { --tf-core: #0b6f63; --tf-pulse: rgba(11,111,99,0.85); }

/* One selector list per rule: :is() keeps the explicit choice and the
   system default on the same declarations without doubling the file. */
:root[data-theme="light"] .mm-stale::after { background: linear-gradient(90deg, transparent, rgba(180,83,9,0.65), transparent); }
:root[data-theme="light"] .mm-live::after  { background: linear-gradient(90deg, transparent, rgba(14,140,125,0.65), transparent); }
:root[data-theme="light"] .mm-stale .mm-code b { color: var(--amber); font-weight: 500; }
:root[data-theme="light"] .mm-live  .mm-code b { color: var(--teal);  font-weight: 500; }
:root[data-theme="light"] .mm-break-tag { background: rgba(194,65,12,0.07); border-color: rgba(194,65,12,0.24); }
:root[data-theme="light"] .mb-l { stroke: rgba(180,83,9,0.7); }
:root[data-theme="light"] .mb-r { stroke: rgba(14,140,125,0.7); }
:root[data-theme="light"] .mb-dot { fill: rgba(18,18,32,0.35); }
:root[data-theme="light"] .g-ok  { background: rgba(4,120,87,0.07);  border-color: rgba(4,120,87,0.24); }
:root[data-theme="light"] .g-hot { background: rgba(194,65,12,0.07); border-color: rgba(194,65,12,0.24); }
:root[data-theme="light"] .g-off { background: rgba(18,18,32,0.04);  border-color: var(--border-strong); }
:root[data-theme="light"] .band-steps span { background: rgba(255,255,255,0.6); }
:root[data-theme="light"] .skip { background: var(--bg-1); color: var(--text-0); }

@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) .mm-stale::after { background: linear-gradient(90deg, transparent, rgba(180,83,9,0.65), transparent); }
  :root:not([data-theme="dark"]) .mm-live::after  { background: linear-gradient(90deg, transparent, rgba(14,140,125,0.65), transparent); }
  :root:not([data-theme="dark"]) .mm-stale .mm-code b { color: var(--amber); font-weight: 500; }
  :root:not([data-theme="dark"]) .mm-live  .mm-code b { color: var(--teal);  font-weight: 500; }
  :root:not([data-theme="dark"]) .mm-break-tag { background: rgba(194,65,12,0.07); border-color: rgba(194,65,12,0.24); }
  :root:not([data-theme="dark"]) .mb-l { stroke: rgba(180,83,9,0.7); }
  :root:not([data-theme="dark"]) .mb-r { stroke: rgba(14,140,125,0.7); }
  :root:not([data-theme="dark"]) .mb-dot { fill: rgba(18,18,32,0.35); }
  :root:not([data-theme="dark"]) .g-ok  { background: rgba(4,120,87,0.07);  border-color: rgba(4,120,87,0.24); }
  :root:not([data-theme="dark"]) .g-hot { background: rgba(194,65,12,0.07); border-color: rgba(194,65,12,0.24); }
  :root:not([data-theme="dark"]) .g-off { background: rgba(18,18,32,0.04);  border-color: var(--border-strong); }
  :root:not([data-theme="dark"]) .band-steps span { background: rgba(255,255,255,0.6); }
  :root:not([data-theme="dark"]) .skip { background: var(--bg-1); color: var(--text-0); }
}
