/*
 * APEX V3 — PUBLIC LANDING.
 *
 * Design language, so every value below has a reason:
 *
 *   The page is an INSTRUMENT READOUT, not a brochure. It opens on a dark
 *   measured field and then walks down a numbered spine — one chapter per
 *   stage of how APEX actually reasons. Each chapter carries a hairline rail
 *   that draws itself as the chapter arrives, so scrolling feels like
 *   following a single continuous path rather than passing a stack of
 *   unrelated marketing bands.
 *
 * Three rules inherited from theme.css and held to strictly here:
 *
 *   1. SURFACES CATCH LIGHT, THEY DO NOT EMIT IT. Panels have a lit top
 *      edge and a shadowed underside. Nothing on this page glows except the
 *      single decision core in the hero field, which is the one thing the
 *      composition is about.
 *
 *   2. ONE ACCENT, SPENT SPARINGLY. Ice blue marks what is interactive or
 *      what APEX is asserting. Green means authorised, amber means wait, red
 *      means invalidation. A colour that means something is never used for
 *      decoration.
 *
 *   3. TYPE SPLITS BY AUTHORSHIP. Editorial display type for statements APEX
 *      makes; tabular mono for anything the market determines. No webfont is
 *      downloaded — the system stack resolves to SF Pro / SF Mono, and the
 *      page stays render-blocking-free and fully offline.
 *
 * All tokens come from theme.css. This file adds no new palette.
 */

/* ═══════════════════════════════════════════════════════════════════
 * 1. SHELL + BASE
 * ═══════════════════════════════════════════════════════════════════ */

.shell {
  width: min(1240px, 100% - clamp(24px, 6vw, 96px));
  margin-inline: auto;
}

.landing {
  position: relative;
  z-index: 1;
}

/* The landing floor sinks below the app floor: the hero field is the only
   light source, and it needs a genuinely black ground to read against. */
.landing-body {
  background-color: var(--bg-global);
  overflow-x: hidden;
}

/* ═══════════════════════════════════════════════════════════════════
 * 2. TYPOGRAPHY
 * ═══════════════════════════════════════════════════════════════════ */

.display {
  margin: 0 0 clamp(20px, 2.4vw, 30px);
  font-family: var(--font-display);
  /* Sized so the longest line ('before conviction.') holds on ONE line at
     every desktop width inside .hero__copy. Bigger type that wraps into a
     ragged third line reads as an accident, not confidence. */
  font-size: clamp(40px, 6vw, 82px);
  line-height: 1.0;
  font-weight: 600;
  letter-spacing: -0.035em;
  color: var(--text-strong);
}

/* The second clause of a display statement, held one step back. Not a
   colour accent — a WEIGHT and OPACITY step, which reads as considered
   rather than highlighted. */
.display em {
  font-style: normal;
  font-weight: 300;
  color: var(--titanium);
}

.display--sm {
  font-size: clamp(32px, 4.6vw, 62px);
  line-height: 1.06;
}

.headline {
  margin: 0 0 clamp(16px, 1.8vw, 22px);
  font-family: var(--font-display);
  font-size: clamp(26px, 3.1vw, 44px);
  line-height: 1.08;
  font-weight: 600;
  letter-spacing: -0.028em;
  color: var(--text-strong);
  text-wrap: balance;
}

.lede {
  margin: 0 0 clamp(28px, 3vw, 40px);
  max-width: 46ch;
  font-size: clamp(15px, 1.15vw, 17px);
  line-height: 1.62;
  color: var(--muted);
}

.statement {
  margin: 0 0 16px;
  max-width: 44ch;
  font-size: clamp(14px, 1vw, 15.5px);
  line-height: 1.68;
  color: var(--muted);
}

.statement--wide { max-width: 58ch; }

.eyebrow {
  margin: 0 0 clamp(14px, 1.4vw, 20px);
  font-size: var(--fs-label);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--track-caps);
  color: var(--accent);
}

.eyebrow--rule {
  display: flex;
  align-items: center;
  gap: 14px;
}
.eyebrow--rule::before {
  content: "";
  width: 34px;
  height: 1px;
  background: linear-gradient(90deg, var(--accent), transparent);
  flex: none;
}

/* ═══════════════════════════════════════════════════════════════════
 * 3. BUTTONS
 * ═══════════════════════════════════════════════════════════════════ */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 13px 26px;
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  font-family: var(--font-sans);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.02em;
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
  transition: transform 0.22s cubic-bezier(0.22, 1, 0.36, 1),
              background-color 0.22s ease, border-color 0.22s ease,
              color 0.22s ease, box-shadow 0.22s ease;
}
.btn:hover { text-decoration: none; }
/* One tap acts once. Without this, mobile Safari can hold the tap for a
   double-tap-zoom gesture, which users read as an unresponsive button. */
.btn { touch-action: manipulation; }

.btn--lg { padding: 16px 34px; font-size: 13.5px; }

.btn--primary {
  background: var(--accent-bright);
  color: #05070c;
  border-color: var(--accent-bright);
}
.btn--primary:hover {
  transform: translateY(-1px);
  box-shadow: 0 14px 34px -14px rgba(134, 184, 222, 0.7);
}

.btn--ghost {
  border-color: var(--border-strong);
  color: var(--text);
  background: transparent;
}
.btn--ghost:hover {
  border-color: var(--accent);
  color: var(--accent-bright);
  transform: translateY(-1px);
}

/* ═══════════════════════════════════════════════════════════════════
 * 4. HERO + EVIDENCE FIELD
 * ═══════════════════════════════════════════════════════════════════ */

.hero {
  position: relative;
  min-height: min(94vh, 900px);
  display: flex;
  align-items: center;
  padding-block: clamp(56px, 9vh, 120px) clamp(72px, 12vh, 150px);
  overflow: hidden;
}

/* The field sits behind the type and is pushed right, so the editorial
   column has genuinely clean ground under it. This is the single decision
   that lets the type carry the first screen. */
.field {
  position: absolute;
  inset: 0 0 0 auto;
  width: min(1180px, 96%);
  pointer-events: none;
  z-index: 0;
}
.field__canvas {
  display: block;
  width: 100%;
  height: 100%;
}

/* Masks the field's left edge into the void so it never collides with the
   headline, and softens the outer frame so it reads as depth, not a box. */
.field__vignette {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(90deg, var(--bg-global) 2%, rgba(1, 2, 4, 0.66) 18%, transparent 44%),
    radial-gradient(ellipse 74% 74% at 62% 46%, transparent 42%, var(--bg-global) 100%);
}

/* The planet layer. Sits over the field and under the type; masked so its
   rim dissolves into the void instead of ending in a square. Transform and
   opacity only (parallax + recession are compositor work). */
.hero__globe {
  position: absolute;
  z-index: 0;
  top: 50%;
  right: clamp(-160px, -7vw, -40px);
  width: min(66vw, 1060px);
  aspect-ratio: 1 / 1;
  transform: translateY(-50%);
  opacity: 0;
  pointer-events: none;
  transition: opacity 1.8s var(--ease-out);
  -webkit-mask-image: radial-gradient(circle at 50% 50%, #000 50%, rgba(0, 0, 0, 0.55) 64%, transparent 76%);
  mask-image: radial-gradient(circle at 50% 50%, #000 50%, rgba(0, 0, 0, 0.55) 64%, transparent 76%);
  will-change: transform, opacity;
}
.hero__globe.is-ready { opacity: 1; }
.hero.has-globe .field { opacity: 0.38; transition: opacity 1.8s var(--ease-out); }

/* HUD chips: three facts already stated on the page, floating in the
   planet's space. Decorative (aria-hidden) and parallaxed by the globe module. */
.hero__hud {
  position: absolute;
  inset: 0;
  z-index: 1;
  list-style: none;
  margin: 0;
  padding: 0;
  pointer-events: none;
  opacity: 0;
  transition: opacity 1.2s var(--ease-out) 1s;
}
.hero.has-globe .hero__hud { opacity: 1; }
.hud {
  position: absolute;
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 10px 14px;
  border-radius: 12px;
  background: rgba(9, 12, 19, 0.62);
  backdrop-filter: blur(14px) saturate(1.2);
  -webkit-backdrop-filter: blur(14px) saturate(1.2);
  border: 1px solid rgba(255, 255, 255, 0.08);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05), 0 14px 34px rgba(0, 0, 0, 0.4);
  will-change: transform;
}
.hud__k { font-size: 9px; font-weight: 700; letter-spacing: 0.16em; text-transform: uppercase; color: var(--dim); }
.hud__v { font-size: 12px; font-weight: 600; color: var(--text); white-space: nowrap; }
.hud--sessions { right: 11%; top: 17%; }
.hud--lanes { right: 36%; top: 58%; }
.hud--gate { right: 7%; bottom: 24%; }
@media (max-width: 979px) { .hero__globe, .hero__hud { display: none; } }

.hero__inner {
  position: relative;
  z-index: 1;
  width: min(1240px, 100% - clamp(24px, 6vw, 96px));
}

.hero__copy { max-width: 740px; }

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-bottom: clamp(34px, 4vw, 52px);
}

/* Three structural facts, set as a hairline-ruled list. Deliberately not
   "stats": no number on this page is a performance claim. */
.hero__facts {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 10px;
  max-width: 520px;
}
.hero__facts li {
  display: flex;
  align-items: baseline;
  gap: 12px;
  padding-top: 10px;
  border-top: 1px solid var(--border);
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--muted);
}
.hero__facts-k {
  flex: none;
  width: 76px;
  font-size: var(--fs-micro);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--track-caps);
  color: var(--dim);
}

/* Lane legend — names what the field is drawing, bottom-right of the hero. */
.hero__lanes {
  position: absolute;
  right: 0;
  bottom: clamp(18px, 3vh, 34px);
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 6px 18px;
  max-width: 46%;
  justify-content: flex-end;
}
.hero__lanes li {
  font-size: var(--fs-micro);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--track-caps);
  color: var(--dim);
}
.hero__lanes li::before {
  content: "";
  display: inline-block;
  width: 12px;
  height: 1px;
  margin-right: 8px;
  vertical-align: middle;
  background: var(--border-strong);
}

.scroll-cue {
  position: absolute;
  left: clamp(24px, 6vw, 96px);
  bottom: clamp(24px, 4vh, 48px);
  display: flex;
  align-items: center;
  gap: 12px;
  z-index: 2;
  transition: opacity 0.5s ease;
}
.scroll-cue[data-hidden="true"] { opacity: 0; pointer-events: none; }
.scroll-cue__rail {
  width: 44px;
  height: 1px;
  background: linear-gradient(90deg, var(--titanium), transparent);
}
.scroll-cue__label {
  font-size: var(--fs-micro);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--track-caps);
  color: var(--dim);
}

/* ═══════════════════════════════════════════════════════════════════
 * 5. CHAPTERS — the numbered spine
 * ═══════════════════════════════════════════════════════════════════ */

.chapter {
  position: relative;
  padding-block: clamp(72px, 10vh, 132px);
}

/* A raised chapter is one step above the void, with hairlines top and
   bottom. It gives the scroll a rhythm of surfacing and sinking rather than
   one uninterrupted black run. */
.chapter--raised {
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.016), transparent 62%);
  border-block: 1px solid var(--border);
}

.chapter__grid {
  display: grid;
  grid-template-columns: 54px minmax(0, 1fr) minmax(0, 1.04fr);
  gap: clamp(20px, 3.4vw, 60px);
  align-items: start;
}
.chapter__rail { grid-column: 1; grid-row: 1; }
.chapter__lead { grid-column: 2; grid-row: 1; }
.chapter__demo { grid-column: 3; grid-row: 1; min-width: 0; }

.chapter__grid--reverse { grid-template-columns: 54px minmax(0, 1.04fr) minmax(0, 1fr); }
.chapter__grid--reverse .chapter__lead { grid-column: 3; }
.chapter__grid--reverse .chapter__demo { grid-column: 2; }

/* The rail: a number and a hairline that draws downward as the chapter
   enters. This is the page's connective tissue. */
.chapter__rail {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  padding-top: 4px;
}
.chapter__n {
  font-family: var(--font-mono);
  font-size: var(--fs-caption);
  font-variant-numeric: tabular-nums;
  color: var(--accent);
  letter-spacing: 0.06em;
}
.chapter__line {
  flex: 1;
  width: 1px;
  min-height: 120px;
  background: linear-gradient(180deg, var(--border-accent), var(--border) 55%, transparent);
  transform-origin: top;
  transform: scaleY(0);
  transition: transform 1.5s cubic-bezier(0.16, 1, 0.3, 1) 0.15s;
}
.chapter.is-in .chapter__line { transform: scaleY(1); }

.chapter__rail--inline {
  flex-direction: row;
  margin-bottom: 14px;
  justify-content: flex-start;
}

.chapter__head {
  max-width: 64ch;
  margin-bottom: clamp(32px, 4vw, 56px);
}

.chapter__note {
  margin: clamp(24px, 3vw, 36px) 0 0;
  max-width: 62ch;
  font-size: var(--fs-caption);
  line-height: 1.6;
  color: var(--dim);
}

/* ═══════════════════════════════════════════════════════════════════
 * 6. REVEAL — one-shot, never perpetual motion
 * ═══════════════════════════════════════════════════════════════════ */

.reveal {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 0.85s cubic-bezier(0.16, 1, 0.3, 1),
              transform 0.85s cubic-bezier(0.16, 1, 0.3, 1);
  will-change: opacity, transform;
}
.reveal.is-in {
  opacity: 1;
  transform: none;
  will-change: auto;
}
.reveal--d1 { transition-delay: 0.1s; }
.reveal--d2 { transition-delay: 0.2s; }

/* ═══════════════════════════════════════════════════════════════════
 * 7. PANEL + TAGS
 * ═══════════════════════════════════════════════════════════════════ */

/* The APEX surface: lit top edge, shadowed underside, hairline border. */
.panel {
  position: relative;
  padding: clamp(20px, 2vw, 28px);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.028), transparent 46%),
    var(--panel);
  box-shadow: var(--shadow-panel);
}
.panel::before {
  content: "";
  position: absolute;
  inset: 0 0 auto;
  height: 1px;
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.15), transparent);
}

.panel__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 20px;
}
.panel__title {
  font-size: var(--fs-label);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--track-label);
  color: var(--text);
}
.panel__foot {
  margin: 20px 0 0;
  padding-top: 16px;
  border-top: 1px solid var(--border);
  font-size: var(--fs-caption);
  line-height: 1.6;
  color: var(--dim);
}
.panel__foot--loose {
  border-top: 0;
  padding-top: 0;
  margin-top: 22px;
}
.panel__foot strong { color: var(--text); font-weight: 600; }

.tag {
  display: inline-flex;
  align-items: center;
  padding: 4px 9px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--panel-2);
  font-size: var(--fs-micro);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--track-caps);
  color: var(--muted);
  white-space: nowrap;
}
/* The honesty tag. Deliberately legible, never a whisper. */
.tag--illus {
  border-color: color-mix(in srgb, var(--amber) 34%, var(--border));
  background: var(--amber-dim);
  color: var(--amber);
}
.tag--quiet { color: var(--dim); }

/* ═══════════════════════════════════════════════════════════════════
 * 8. CHAPTER 01 — EVIDENCE STREAMS
 * ═══════════════════════════════════════════════════════════════════ */

.streams {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 2px;
}
.stream {
  display: grid;
  grid-template-columns: 88px minmax(0, 1fr) 68px;
  align-items: center;
  gap: 14px;
  padding: 11px 12px;
  border-radius: var(--radius-sm);
  transition: background-color 0.3s ease;
}
.stream:hover { background: rgba(255, 255, 255, 0.02); }

.stream__name {
  font-size: var(--fs-label);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--track-label);
  color: var(--text);
}

.stream__trace {
  width: 100%;
  height: 20px;
  overflow: visible;
}
.stream__trace path {
  fill: none;
  stroke: var(--accent);
  stroke-width: 1;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0.55;
  /* Drawn on reveal. 260 comfortably exceeds every path length here, so a
     single value serves all seven without measuring each in JS. */
  stroke-dasharray: 260;
  stroke-dashoffset: 260;
  transition: stroke-dashoffset 1.1s cubic-bezier(0.16, 1, 0.3, 1);
  transition-delay: calc(var(--i, 0) * 90ms);
}
.stream__trace rect {
  fill: var(--accent);
  opacity: 0;
  transition: opacity 0.6s ease;
  transition-delay: calc(var(--i, 0) * 90ms + 500ms);
}
.reveal.is-in .stream__trace path { stroke-dashoffset: 0; }
.reveal.is-in .stream__trace rect { opacity: 0.16; }

.stream__state {
  justify-self: end;
  font-size: var(--fs-micro);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--track-caps);
  color: var(--dim);
}

/* ═══════════════════════════════════════════════════════════════════
 * 9. CHAPTER 02 — CONVERGENCE
 * ═══════════════════════════════════════════════════════════════════ */

.converge {
  display: block;
  width: 100%;
  height: auto;
  margin-bottom: 22px;
}
.converge__links path {
  fill: none;
  stroke: var(--accent);
  stroke-width: 1;
  opacity: 0.3;
  stroke-dasharray: 240;
  stroke-dashoffset: 240;
  transition: stroke-dashoffset 1.4s cubic-bezier(0.16, 1, 0.3, 1);
}
.converge__links path:nth-child(2) { transition-delay: 0.07s; }
.converge__links path:nth-child(3) { transition-delay: 0.14s; }
.converge__links path:nth-child(4) { transition-delay: 0.21s; }
.converge__links path:nth-child(5) { transition-delay: 0.28s; }
.converge__links path:nth-child(6) { transition-delay: 0.35s; }
.converge__links path:nth-child(7) { transition-delay: 0.42s; }
.reveal.is-in .converge__links path { stroke-dashoffset: 0; }

.converge__in circle { fill: var(--titanium); opacity: 0.6; }
.converge__out circle {
  fill: var(--accent-bright);
  opacity: 0;
  transition: opacity 0.7s ease 0.9s;
}
.reveal.is-in .converge__out circle { opacity: 0.9; }

.context-keys {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 9px;
}
.context-keys li {
  display: flex;
  align-items: baseline;
  gap: 12px;
  padding-top: 9px;
  border-top: 1px solid var(--border);
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--muted);
}
.context-keys__k {
  flex: none;
  width: 82px;
  font-size: var(--fs-micro);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--track-caps);
  color: var(--accent);
}

/* ═══════════════════════════════════════════════════════════════════
 * 10. CHAPTER 03 — THE DECISION OBJECT
 * ═══════════════════════════════════════════════════════════════════ */

.verdict {
  position: relative;
  padding: clamp(22px, 2.2vw, 32px);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-lg);
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.036), transparent 40%),
    var(--panel);
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.5), 0 26px 60px -26px rgba(0, 0, 0, 0.9);
}
.verdict::before {
  content: "";
  position: absolute;
  inset: 0 0 auto;
  height: 1px;
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  background: linear-gradient(90deg, transparent, rgba(211, 231, 247, 0.32), transparent);
}

.verdict__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding-bottom: 18px;
  border-bottom: 1px solid var(--border);
}
.verdict__instrument { display: flex; align-items: baseline; gap: 10px; }
.verdict__sym {
  font-family: var(--font-display);
  font-size: 17px;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--text-strong);
}
.verdict__tf {
  font-family: var(--font-mono);
  font-size: var(--fs-caption);
  color: var(--dim);
}

.verdict__bias {
  display: flex;
  align-items: baseline;
  gap: 16px;
  padding: 22px 0;
  border-bottom: 1px solid var(--border);
}
.verdict__bias-k {
  font-size: var(--fs-micro);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--track-caps);
  color: var(--dim);
}
.verdict__bias-v {
  font-family: var(--font-display);
  font-size: clamp(30px, 3.2vw, 42px);
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.03em;
  text-transform: uppercase;
}
.verdict__bias-v[data-dir="long"] { color: var(--green); }
.verdict__bias-v[data-dir="short"] { color: var(--red); }
.verdict__bias-v[data-dir="wait"] { color: var(--amber); }

.verdict__levels {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 1px;
  margin: 0 -4px;
  padding: 20px 0;
  border-bottom: 1px solid var(--border);
}
.level { padding: 0 4px; }
.level__k {
  display: block;
  margin-bottom: 7px;
  font-size: var(--fs-micro);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--track-caps);
  color: var(--dim);
}
.level__v {
  display: block;
  font-size: clamp(17px, 1.5vw, 21px);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--text-strong);
}
.level--red .level__v { color: var(--red); }
.level--green .level__v { color: var(--green); }

.verdict__why {
  margin: 20px 0 0;
  font-size: 13px;
  line-height: 1.68;
  color: var(--muted);
}
.verdict__note {
  margin: 16px 0 0;
  padding-top: 14px;
  border-top: 1px solid var(--border);
  font-size: var(--fs-micro);
  line-height: 1.6;
  color: var(--dim);
}

/* ═══════════════════════════════════════════════════════════════════
 * 11. CHAPTER 04 — THE RISK GATE
 * ═══════════════════════════════════════════════════════════════════ */

.gate {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
}
.gate__col {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0;
  padding: clamp(20px, 2vw, 28px) 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.02), transparent 50%), var(--panel);
  text-align: center;
}

.gate__node {
  padding: 9px 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  background: var(--panel-2);
  font-size: var(--fs-micro);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--track-caps);
  color: var(--muted);
  white-space: nowrap;
}
.gate__node--check {
  border-color: var(--border-accent);
  color: var(--accent);
}

.gate__arrow {
  width: 1px;
  height: 28px;
  margin: 4px 0;
  background: linear-gradient(180deg, var(--border-strong), var(--titanium));
  position: relative;
  transform-origin: top;
  transform: scaleY(0);
  transition: transform 0.6s cubic-bezier(0.16, 1, 0.3, 1);
}
.gate__col .gate__arrow:nth-of-type(2) { transition-delay: 0.35s; }
.reveal.is-in .gate__arrow { transform: scaleY(1); }
.gate__arrow::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: -1px;
  width: 5px;
  height: 5px;
  margin-left: -2.5px;
  border-right: 1px solid var(--titanium);
  border-bottom: 1px solid var(--titanium);
  transform: rotate(45deg);
}

/* The two outcomes are given identical visual weight. That equality is the
   argument: WAIT is a result, not a failure to produce one. */
.gate__out {
  margin-top: 4px;
  padding: 13px 26px;
  border: 1px solid;
  border-radius: var(--radius);
  font-family: var(--font-display);
  font-size: clamp(15px, 1.5vw, 19px);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 0.6s ease 0.75s, transform 0.6s cubic-bezier(0.16, 1, 0.3, 1) 0.75s;
}
.reveal.is-in .gate__out { opacity: 1; transform: none; }
.gate__out--ok {
  border-color: color-mix(in srgb, var(--green) 46%, var(--border));
  background: var(--green-dim);
  color: var(--green);
}
.gate__out--wait {
  border-color: color-mix(in srgb, var(--amber) 46%, var(--border));
  background: var(--amber-dim);
  color: var(--amber);
}

.gate__caption {
  margin: 16px 0 0;
  max-width: 26ch;
  font-size: var(--fs-caption);
  line-height: 1.55;
  color: var(--dim);
}

/* ═══════════════════════════════════════════════════════════════════
 * 12. CHAPTER 05 — LIFECYCLE
 * ═══════════════════════════════════════════════════════════════════ */

.lifecycle {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 1px;
  background: var(--border);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
}
.lifecycle__step {
  position: relative;
  padding: clamp(20px, 2vw, 28px) clamp(16px, 1.4vw, 22px);
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.018), transparent 60%), var(--panel);
  transition: background-color 0.35s ease;
}
.lifecycle__step:hover { background-color: var(--panel-2); }
/* A hairline that fills left-to-right across each step in sequence: the
   lifecycle reads as a path, not five boxes. */
.lifecycle__step::before {
  content: "";
  position: absolute;
  inset: 0 0 auto;
  height: 1px;
  background: var(--accent);
  opacity: 0.45;
  transform-origin: left;
  transform: scaleX(0);
  transition: transform 0.7s cubic-bezier(0.16, 1, 0.3, 1);
  transition-delay: calc(var(--i, 0) * 130ms);
}
.reveal.is-in .lifecycle__step::before { transform: scaleX(1); }

.lifecycle__n {
  display: block;
  margin-bottom: 14px;
  font-family: var(--font-mono);
  font-size: var(--fs-caption);
  font-variant-numeric: tabular-nums;
  color: var(--accent);
}
.lifecycle__t {
  margin: 0 0 8px;
  font-size: 14.5px;
  font-weight: 600;
  color: var(--text-strong);
}
.lifecycle__b {
  margin: 0;
  font-size: 12.5px;
  line-height: 1.58;
  color: var(--muted);
}

/* ═══════════════════════════════════════════════════════════════════
 * 13. CHAPTER 06 — MARKETS
 * ═══════════════════════════════════════════════════════════════════ */

.markets {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 12px;
}
.market {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: clamp(20px, 2vw, 26px);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.022), transparent 52%), var(--panel);
  transition: border-color 0.3s ease, transform 0.3s cubic-bezier(0.22, 1, 0.36, 1);
}
.market:hover { border-color: var(--border-strong); transform: translateY(-2px); }

.market__sym {
  font-family: var(--font-mono);
  font-size: clamp(19px, 1.9vw, 25px);
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--text-strong);
}
.market__class {
  font-size: var(--fs-micro);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--track-caps);
  color: var(--dim);
}
/* Session state. Clock-derived and therefore genuinely true — the only
   live thing on this page, and the reason no price appears beside it. */
.market__state {
  margin-top: 6px;
  padding-top: 10px;
  border-top: 1px solid var(--border);
  font-size: var(--fs-micro);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--track-caps);
  color: var(--dim);
}
.market__state[data-state="open"] { color: var(--green); }
.market__state[data-state="closed"] { color: var(--dim); }
.market__state[data-state="always"] { color: var(--accent); }

.tf-ladder {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 18px;
}
.tf-ladder__k {
  margin-right: 6px;
  font-size: var(--fs-micro);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--track-caps);
  color: var(--dim);
}
.tf {
  padding: 5px 11px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--panel);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  color: var(--muted);
}

/* ═══════════════════════════════════════════════════════════════════
 * 14. CHAPTER 07 — STRATEGY LADDER
 * ═══════════════════════════════════════════════════════════════════ */

.ladder {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 8px;
}
.ladder__step {
  display: grid;
  grid-template-columns: 108px minmax(0, 1fr);
  align-items: baseline;
  gap: 16px;
  padding: 16px 18px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--panel);
  transition: border-color 0.3s ease, transform 0.3s cubic-bezier(0.22, 1, 0.36, 1);
  /* Each rung sits fractionally further right than the last — the idea is
     climbing, not queuing. */
  margin-left: calc(var(--i, 0) * 10px);
}
.ladder__step:hover { border-color: var(--border-strong); transform: translateX(3px); }
.ladder__step--end {
  border-color: color-mix(in srgb, var(--green) 34%, var(--border));
  background: linear-gradient(90deg, var(--green-dim), transparent 60%), var(--panel);
}
.ladder__k {
  font-size: var(--fs-label);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--track-label);
  color: var(--accent);
}
.ladder__step--end .ladder__k { color: var(--green); }
.ladder__b {
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--muted);
}

/* ═══════════════════════════════════════════════════════════════════
 * 15. CHAPTER 08 — THE STACK
 * ═══════════════════════════════════════════════════════════════════ */

.stack {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: clamp(26px, 3vw, 40px) clamp(18px, 2vw, 28px);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.022), transparent 50%), var(--panel);
}
.stack__node {
  padding: 12px 24px;
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  background: var(--panel-2);
  font-size: var(--fs-label);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--track-caps);
  color: var(--muted);
  text-align: center;
}
.stack__node--core {
  border-color: var(--border-accent);
  background: var(--accent-dim);
  color: var(--accent-bright);
}
.stack__node--out {
  border-color: color-mix(in srgb, var(--green) 40%, var(--border));
  background: var(--green-dim);
  color: var(--green);
}
.stack__link {
  width: 1px;
  height: 26px;
  background: linear-gradient(180deg, var(--border-strong), var(--titanium));
  transform-origin: top;
  transform: scaleY(0);
  transition: transform 0.55s cubic-bezier(0.16, 1, 0.3, 1);
}
.stack__link:nth-of-type(2) { transition-delay: 0.18s; }
.stack__link:nth-of-type(3) { transition-delay: 0.36s; }
.reveal.is-in .stack__link { transform: scaleY(1); }

.stack__always {
  margin-top: 26px;
  padding-top: 20px;
  width: 100%;
  border-top: 1px solid var(--border);
  text-align: center;
  font-family: var(--font-mono);
  font-size: clamp(20px, 2.2vw, 28px);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.14em;
  color: var(--text-strong);
}

/* ═══════════════════════════════════════════════════════════════════
 * 16. CHAPTER 09 — ENTER
 * ═══════════════════════════════════════════════════════════════════ */

.enter {
  position: relative;
  padding-block: clamp(96px, 16vh, 190px);
  text-align: center;
  border-top: 1px solid var(--border);
  background:
    radial-gradient(ellipse 62% 100% at 50% 100%, rgba(134, 184, 222, 0.07), transparent 70%),
    var(--bg-global);
}
.enter__inner { max-width: 900px; margin-inline: auto; }
.enter .display { margin-bottom: clamp(30px, 3.6vw, 44px); }
.enter__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  justify-content: center;
}

/* ═══════════════════════════════════════════════════════════════════
 * 17. FOOTER
 * ═══════════════════════════════════════════════════════════════════ */

.landing-footer {
  padding-block: clamp(48px, 7vh, 84px);
  border-top: 1px solid var(--border);
  background: var(--bg);
}
.landing-footer__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: clamp(22px, 3vw, 44px);
  padding-bottom: clamp(30px, 4vw, 46px);
  border-bottom: 1px solid var(--border);
}
.landing-footer .label { margin: 0 0 9px; }
.landing-footer__b {
  margin: 0;
  font-size: var(--fs-caption);
  line-height: 1.6;
  color: var(--dim);
}
.landing-footer__note {
  margin: clamp(24px, 3vw, 32px) 0 0;
  max-width: 82ch;
  font-size: var(--fs-micro);
  line-height: 1.65;
  color: var(--dim);
}
.landing-footer__note + .landing-footer__note { margin-top: 12px; }

/* ═══════════════════════════════════════════════════════════════════
 * 18. RESPONSIVE
 *
 * Mobile is not the desktop page scaled down. The hero shortens, the field
 * loses its right-offset and sits behind everything at low contrast, the
 * chapter rails go inline, and every multi-column demo becomes a single
 * readable column with full-width touch targets.
 * ═══════════════════════════════════════════════════════════════════ */

@media (max-width: 1080px) {
  .lifecycle { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .lifecycle__step:last-child { grid-column: span 2; }
}

@media (max-width: 900px) {
  .hero {
    /* Still opens with presence on a tablet — just not a full desktop
       viewport. On a phone the copy is taller than this anyway, so the
       min-height quietly stops applying rather than forcing dead space. */
    min-height: 72vh;
    padding-block: clamp(48px, 8vh, 72px) clamp(72px, 10vh, 96px);
  }
  .hero__copy { max-width: none; }

  /* Field spans the full hero and drops back considerably: on a phone the
     type must win outright. */
  .field { inset: 0; width: 100%; opacity: 0.42; }
  .field__vignette {
    background:
      linear-gradient(180deg, var(--bg-global) 2%, rgba(1, 2, 4, 0.55) 30%, transparent 70%),
      radial-gradient(ellipse 80% 70% at 50% 50%, transparent 30%, var(--bg-global) 100%);
  }

  .hero__lanes { display: none; }
  .scroll-cue { display: none; }

  .chapter { padding-block: clamp(56px, 8vh, 80px); }

  /* Rail collapses to an inline number above the heading. */
  .chapter__grid,
  .chapter__grid--reverse { grid-template-columns: minmax(0, 1fr); gap: 32px; }
  .chapter__grid .chapter__rail,
  .chapter__grid--reverse .chapter__rail {
    grid-column: 1;
    grid-row: 1;
    flex-direction: row;
    align-items: center;
    justify-content: flex-start;
    gap: 12px;
  }
  .chapter__grid .chapter__lead,
  .chapter__grid--reverse .chapter__lead { grid-column: 1; grid-row: 2; }
  .chapter__grid .chapter__demo,
  .chapter__grid--reverse .chapter__demo { grid-column: 1; grid-row: 3; }
  .chapter__line {
    width: 100%;
    min-height: 0;
    height: 1px;
    transform: scaleX(0);
    transform-origin: left;
    background: linear-gradient(90deg, var(--border-accent), transparent);
    transition: transform 1.1s cubic-bezier(0.16, 1, 0.3, 1);
  }
  .chapter.is-in .chapter__line { transform: scaleX(1); }

  .statement, .lede { max-width: none; }

  .gate { grid-template-columns: minmax(0, 1fr); }
  .lifecycle { grid-template-columns: minmax(0, 1fr); }
  .lifecycle__step:last-child { grid-column: auto; }
  .ladder__step { margin-left: 0; }
}

@media (max-width: 640px) {
  /* The brand subtitle wraps to two lines at this width and doubles the
     header's height on the one screen that most needs to open clean. Scoped
     to the landing page — the authenticated shell keeps its full lockup. */
  .landing-body .apex-header .subtitle { display: none; }

  .display { font-size: clamp(34px, 10.5vw, 52px); }
  .headline { font-size: clamp(24px, 7vw, 32px); }

  /* Full-width, thumb-sized CTAs. */
  .hero__actions, .enter__actions { flex-direction: column; align-items: stretch; }
  .hero__actions .btn, .enter__actions .btn { width: 100%; padding-block: 17px; }

  .stream { grid-template-columns: 74px minmax(0, 1fr); gap: 10px; padding: 10px 8px; }
  .stream__state { display: none; }

  .ladder__step { grid-template-columns: minmax(0, 1fr); gap: 6px; }
  .verdict__levels { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px 12px; }
  .markets { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .market:last-child { grid-column: span 2; }
  .context-keys li { flex-direction: column; gap: 3px; }
  .context-keys__k { width: auto; }
  .hero__facts li { flex-direction: column; gap: 3px; }
  .hero__facts-k { width: auto; }
}

/* ═══════════════════════════════════════════════════════════════════
 * 19. REDUCED MOTION
 *
 * Everything arrives in its settled state. Nothing translates, draws,
 * counts or breathes. The canvas paints a single static frame (handled in
 * evidence-field.js) rather than being removed, so the composition survives.
 * ═══════════════════════════════════════════════════════════════════ */

@media (prefers-reduced-motion: reduce) {
  .reveal,
  .reveal.is-in {
    opacity: 1;
    transform: none;
    transition: none;
  }
  .chapter__line,
  .chapter.is-in .chapter__line { transform: none; transition: none; }
  .stream__trace path { stroke-dashoffset: 0; transition: none; }
  .stream__trace rect { opacity: 0.16; transition: none; }
  .converge__links path { stroke-dashoffset: 0; transition: none; }
  .converge__out circle { opacity: 0.9; transition: none; }
  .gate__arrow, .stack__link { transform: none; transition: none; }
  .gate__out { opacity: 1; transform: none; transition: none; }
  .lifecycle__step::before { transform: scaleX(1); transition: none; }
  .btn { transition: none; }
  .btn:hover { transform: none; }
  .market:hover, .ladder__step:hover { transform: none; }
  .scroll-cue { transition: none; }
}

/* ═══════════════════════════════════════════════════════════════════
 * V3.3 — THE SCROLL-FLOWN DESCENT  (Pinned Orbit + Session Dial)
 *
 * The hero becomes a bounded scroll-flown camera descent through the
 * day/night terminator: GLOBAL MARKETS -> TRADING INTELLIGENCE -> AI ->
 * REAL-TIME INFRASTRUCTURE. components/orbit-scrub.js drives the globe
 * camera and the caption beats; components/session-dial.js draws the
 * clock-derived session bezel. Everything below activates ONLY under
 * .hero--flight, which orbit-scrub adds after the WebGL planet mounts, so
 * the static-tier hero is untouched.
 * ═══════════════════════════════════════════════════════════════════ */

/* Invisible to layout until the flight arms: the static hero is unchanged. */
.hero__stage { display: contents; }
.hero__dial, .hero__telemetry, .hero__beats { display: none; }

.hero--flight {
  display: block;
  height: 300vh;
  min-height: 300vh;
  padding: 0;
  align-items: initial;
  /* The sticky stage must pin to the viewport, so the hero cannot be the
     overflow-clipped scroll-container that would trap it. The stage clips
     its own content instead. */
  overflow: visible;
}
.hero--flight .hero__stage {
  display: flex;
  align-items: center;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow: hidden;
}

/* The planet fills the stage; the camera (orbit-scrub) performs the motion.
   hero-globe sets the host transform inline (subtle pointer parallax), so we
   only set box + mask here and never write transform. */
.hero--flight .hero__globe {
  position: absolute;
  inset: 0;
  top: 0; right: 0; left: 0;
  width: 100%;
  height: 100%;
  aspect-ratio: auto;
  -webkit-mask-image: radial-gradient(circle at 54% 50%, #000 60%, rgba(0,0,0,.45) 78%, transparent 92%);
  mask-image: radial-gradient(circle at 54% 50%, #000 60%, rgba(0,0,0,.45) 78%, transparent 92%);
}

/* Opening copy = Band 1: fades and lifts out over the first tenth of scroll. */
.hero--flight .hero__inner {
  opacity: var(--intro, 1);
  transform: translateY(calc((1 - var(--intro, 1)) * -34px));
  transition: opacity 0.12s linear;
  will-change: opacity, transform;
}
.hero--flight.hero--introgone .hero__inner { pointer-events: none; }

/* ---- Session Dial: hugs the planet's lower-left limb ---- */
.hero--flight .hero__dial {
  display: block;
  position: absolute;
  left: clamp(24px, 5vw, 84px);
  bottom: clamp(28px, 8vh, 96px);
  width: clamp(150px, 17vw, 232px);
  aspect-ratio: 1 / 1;
  z-index: 4;
  opacity: 0;
  pointer-events: none;
  animation: hero-flight-in 1s var(--ease-out) 0.6s forwards;
}
@keyframes hero-flight-in { to { opacity: 1; } }
.sdial__svg { width: 100%; height: 100%; overflow: visible; }
.sdial__base { stroke: rgba(134,184,222,.16); }
.sdial__tick { stroke: rgba(211,231,247,.20); stroke-width: 1; }
.sdial__tick--major { stroke: rgba(211,231,247,.42); stroke-width: 1.4; }
.sdial__arc { stroke: rgba(120,140,170,.34); transition: stroke 0.4s ease; }
.sdial__arc.is-open { stroke: var(--accent, #86b8de); filter: drop-shadow(0 0 4px rgba(134,184,222,.55)); }
.sdial__label { fill: rgba(150,166,190,.6); font: 700 8px var(--font-mono, ui-monospace, monospace); letter-spacing: .1em; }
.sdial__label.is-open { fill: var(--accent-bright, #d3e7f7); }
.sdial__hand { stroke: rgba(211,231,247,.82); stroke-width: 1.4; }
.sdial__hub { fill: var(--accent-bright, #d3e7f7); }
.sdial__count { fill: var(--text-strong, #fff); font: 700 20px var(--font-display, system-ui, sans-serif); }
.sdial__count-label { fill: rgba(150,166,190,.72); font: 700 6px var(--font-mono, ui-monospace, monospace); letter-spacing: .18em; }
.sdial__src { fill: rgba(120,134,160,.55); font: 600 5.5px var(--font-mono, ui-monospace, monospace); letter-spacing: .16em; }

/* ---- Telemetry rail: the camera's own numbers, right edge ---- */
.hero--flight .hero__telemetry {
  display: flex;
  flex-direction: column;
  gap: 14px;
  position: absolute;
  right: clamp(20px, 3vw, 56px);
  top: 50%;
  transform: translateY(-50%);
  z-index: 4;
  opacity: 0;
  pointer-events: none;
  animation: hero-flight-in 1s var(--ease-out) 0.7s forwards;
}
.tel { display: flex; flex-direction: column; gap: 3px; text-align: right; }
.tel__k { font: 700 9px var(--font-mono, ui-monospace, monospace); letter-spacing: .18em; text-transform: uppercase; color: var(--dim); }
.tel__v { font-size: 15px; color: var(--text-strong, #fff); font-variant-numeric: tabular-nums; }

/* ---- The four caption beats: lit one at a time by --k ---- */
.hero--flight .hero__beats { display: block; }
.beat {
  position: absolute;
  left: 50%;
  bottom: clamp(96px, 18vh, 210px);
  width: min(560px, 74vw);
  transform: translate(-50%, calc((1 - var(--k, 0)) * 26px));
  opacity: var(--k, 0);
  z-index: 3;
  text-align: center;
  pointer-events: none;
  will-change: opacity, transform;
}
.beat.beat--cta.is-lit { pointer-events: auto; }
.beat__k {
  display: inline-block;
  font: 700 var(--fs-label, 11px) var(--font-mono, ui-monospace, monospace);
  letter-spacing: .28em;
  text-transform: uppercase;
  color: var(--accent, #86b8de);
  margin-bottom: 14px;
}
.beat__t {
  margin: 0 auto;
  max-width: 46ch;
  font-family: var(--font-display, system-ui, sans-serif);
  font-size: clamp(20px, 2.4vw, 30px);
  line-height: 1.28;
  font-weight: 500;
  letter-spacing: -0.01em;
  color: var(--text-strong, #fff);
  text-shadow: 0 2px 30px rgba(2, 4, 9, 0.7);
  text-wrap: balance;
}
.beat--cta .btn { margin-top: 22px; pointer-events: auto; }

.hero--flight .scroll-cue { left: 50%; right: auto; transform: translateX(-50%); bottom: 22px; }

/* Safety net: if reduced motion is on, no flight is armed (orbit-scrub bails),
   but should the class ever linger, force the hero back to its static form. */
@media (prefers-reduced-motion: reduce) {
  .hero--flight { height: auto; min-height: min(94vh, 900px); display: flex; align-items: center; padding-block: clamp(56px, 9vh, 120px) clamp(72px, 12vh, 150px); }
  .hero--flight .hero__stage { display: contents; position: static; height: auto; }
  .hero--flight .hero__dial, .hero--flight .hero__telemetry, .hero--flight .hero__beats { display: none; }
  .hero--flight .hero__inner { opacity: 1; transform: none; }
}

/* Small screens never get the flight (orbit-scrub gates on the WebGL globe,
   which hero-globe withholds below 980px), so the beats/rail/dial stay off. */
@media (max-width: 979px) {
  .hero__dial, .hero__telemetry, .hero__beats { display: none !important; }
}
