/* ============================================================================
   VIDEO SHELL — stage, HUD, chapter rail, transport.
   Scene-specific styling lives with each scene. Everything here is chrome.
   Colors, type, spacing and motion all come from tokens.css. No raw values.
   ========================================================================= */

*, *::before, *::after { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg-primary);
  color: var(--fg-primary);
  font-family: var(--font-body);
  /* The video is a fixed 16:9 stage; horizontal scroll is always a bug. */
  overflow-x: hidden;
}

/* ---- the fixed stage ---------------------------------------------------- */
/* Never scrolls. Scroll position is only a clock input, so framing is
   byte-identical across scroll, autoplay, and capture. */
.stage {
  position: fixed;
  inset: 0;
  overflow: hidden;
  background: var(--bg-primary);
  /* Depth for the ring planes. Children opt in with preserve-3d. */
  perspective: 1400px;
  perspective-origin: 50% 46%;
}

.scroll-space { /* height set by boot.js from the scene count */ }

/* ---- scenes -------------------------------------------------------------- */
.scenes { position: absolute; inset: 0; transform-style: preserve-3d; }

.scene {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  padding: var(--space-24) var(--space-16);
  /* Hidden until the master timeline brings it in. Opacity and visibility are
     both driven, so an off-screen scene can never steal a pointer event. */
  opacity: 0;
  visibility: hidden;
  transform-style: preserve-3d;
}

/* ---- HUD ----------------------------------------------------------------- */
.hud {
  position: absolute;
  top: 0; left: 0; right: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  gap: var(--space-4);
  /* space-4, not space-5: the chip and legend went from 12px to the 14px
     legibility floor, so the row grew — this holds it at its original height. */
  padding: var(--space-4) var(--space-8);
  pointer-events: none;
}

.hud__brand { display: flex; align-items: center; }

/* The chip is load-bearing: it is the standing statement that nothing has
   shipped. It must never be decorative or dismissible — and it must never be
   below the §5 legibility floor. It and the legend below were the only two
   sub-14px Equiti strings in the build, and they are on screen in every frame
   of every scene including capture. There is no chrome exemption from the
   floor; ring-scene.css says so on the vendor attribution label. */
.hud__chip {
  margin: 0;
  padding: var(--space-1) var(--space-3);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-full);
  background: var(--bg-secondary);
  color: var(--fg-secondary);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  line-height: var(--lh-sm);
  font-weight: 500;
  letter-spacing: .02em;
  white-space: nowrap;
}

.hud__legend {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  margin: 0 0 0 auto;
  padding: 0;
  list-style: none;
}

.hud__legend li {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  line-height: var(--lh-sm);
  color: var(--fg-muted);
  letter-spacing: .02em;
}

.hud__swatch {
  width: 8px; height: 8px;
  border-radius: var(--radius-full);
  background: currentColor;
  flex: none;
}
/* Pipeline and paused read as outlines, matching how their nodes render. */
.hud__swatch--hollow { background: none; box-shadow: inset 0 0 0 1.5px currentColor; }

/* ---- brand mark ---------------------------------------------------------- */
/* All that remains of the HUD. Sits in the corner every frame including
   capture, so it must never overlap scene content — scenes reserve the top
   band via .scene padding. */
.brand {
  position: absolute;
  top: var(--space-5);
  left: var(--space-8);
  z-index: 40;
  display: flex;
  align-items: center;
  pointer-events: none;
}

/* ---- the phase rail — vertical, LEFT edge (C3.2) -------------------------
   > "I really dislike how the timeline at the bottom is… Never put it on the
   >  bottom, not even towards the end. Keep it always in the same journey from
   >  top to bottom."

   This replaces BOTH the right-hand dot rail and the horizontal journey strip
   that ring-scene.js used to draw along y 826-896. One wayfinding element, on
   the left, running top to bottom in the map's own order: 1 Proactive
   detection, 2 Intelligent routing, 3 Self-service, 4 Connected calls,
   Measurement. Measurement is not numbered — it spans all four (C3.7), so it
   carries "ALL".

   WHY THE NAMES ARE SET VERTICALLY. Demo scenes put their title stack at
   x=96 in the 1600-wide canvas, and at capture size that is viewport x=96.
   "Intelligent routing" set horizontally at the 14px floor is ~135px wide, so
   a horizontal rail either collides with the scene or drops under the floor.
   Rotated, the whole rail is 64px and the gutter still clears. It also reads
   as the map's own downward journey rather than as a nav bar.

   PUSHED PARTLY OUT OF FRAME, deliberately: the spine runs the full viewport
   height so it exits top and bottom, and the row ticks are clipped by the left
   edge. It is context, not chrome — the quiet stages sit at 40% and only the
   current one is at full ink.

   NO TRANSITION ANYWHERE IN HERE. hud.js writes data-cur / data-on and the
   container's opacity on every EQV.onSeek, which is clock-driven; a transition
   would make the paint a function of wall-clock time since the attribute
   flipped, which is exactly what the single-clock rule forbids and what would
   smear under frame-stepped capture. */
.phaserail {
  position: absolute;
  left: -10px;
  top: 0; bottom: 0;
  width: 74px;
  z-index: 40;
  pointer-events: auto;
  opacity: 0;                 /* driven by hud.js from clock position */
}
/* The spine. Full height on purpose: it leaves the frame at both ends. */
.phaserail::before {
  content: '';
  position: absolute;
  left: 12px; top: 0; bottom: 0;
  width: 1px;
  background: var(--border-default);
  opacity: .55;
}
.phaserail__stack {
  position: absolute;
  left: 0; right: 0;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  flex-direction: column;
  align-items: stretch;       /* rows span the rail, so ticks land on the spine */
  gap: var(--space-5);
}
.phaserail__stage {
  position: relative;
  margin: 0; padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: center;        /* numeral over name, centred at x=37 of the rail */
  gap: var(--space-2);
  opacity: .4;
}
.phaserail__stage[data-cur="true"] { opacity: 1; }
/* The tick on the spine. The rail is at left:-10px and the spine at rail-local
   12px, so this sits at viewport x -2..7 — clipped by the frame edge, which is
   the "pushed partly out of frame" the change order asks for. */
.phaserail__tick {
  position: absolute;
  left: 8px; top: 3px;
  width: 9px; height: 9px;
  border-radius: var(--radius-full);
  background: var(--bg-primary);
  box-shadow: inset 0 0 0 1.5px var(--border-strong);
}
.phaserail__stage[data-cur="true"] .phaserail__tick {
  background: var(--fg-primary);
  box-shadow: inset 0 0 0 1.5px var(--fg-primary);
}
/* 14px — the §5 legibility floor. There is no chrome exemption from it. */
.phaserail__num {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: var(--text-sm);
  line-height: 1;
  letter-spacing: .1em;
  color: var(--fg-muted);
  font-variant-numeric: tabular-nums;
}
.phaserail__stage[data-cur="true"] .phaserail__num { color: var(--fg-primary); }
.phaserail__name {
  writing-mode: vertical-rl;      /* reads downward, with the journey */
  font-family: var(--font-body);
  font-weight: 500;
  font-size: var(--text-sm);
  line-height: 1;
  letter-spacing: .01em;
  color: var(--fg-muted);
  white-space: nowrap;
}
.phaserail__stage[data-cur="true"] .phaserail__name {
  font-weight: 600;
  color: var(--fg-primary);
}
.phaserail__stage:hover { opacity: .75; }
.phaserail__stage[data-cur="true"]:hover { opacity: 1; }
.phaserail__stage:focus-visible { outline: none; box-shadow: var(--shadow-focus-teal); }

/* ---- transport ----------------------------------------------------------- */
.transport {
  position: absolute;
  left: 50%;
  bottom: var(--space-6);
  transform: translateX(-50%);
  z-index: 40;
  display: flex;
  align-items: center;
  gap: var(--space-4);
  width: min(560px, 72vw);
  padding: var(--space-3) var(--space-5);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-full);
  background: color-mix(in srgb, var(--bg-primary) 82%, transparent);
  backdrop-filter: blur(12px);
  box-shadow: var(--shadow-lg);
  opacity: .35;
  transition: opacity var(--dur-base) var(--ease-standard);
}
.transport:hover, .transport:focus-within { opacity: 1; }

.transport__play {
  flex: none;
  width: 30px; height: 30px;
  display: grid; place-items: center;
  border: 0;
  border-radius: var(--radius-full);
  background: var(--equiti-black);
  color: var(--fg-inverse);
  font-size: var(--text-xs);
  line-height: 1;
  cursor: pointer;
}
.transport__play:focus-visible { outline: none; box-shadow: var(--shadow-focus-teal); }

.transport__scrub {
  flex: 1;
  appearance: none;
  height: 3px;
  border-radius: var(--radius-full);
  background: var(--border-default);
  cursor: pointer;
}
.transport__scrub::-webkit-slider-thumb {
  appearance: none;
  width: 13px; height: 13px;
  border: 0;
  border-radius: var(--radius-full);
  background: var(--equiti-teal);
  cursor: grab;
}
.transport__scrub::-moz-range-thumb {
  width: 13px; height: 13px;
  border: 0;
  border-radius: var(--radius-full);
  background: var(--equiti-teal);
  cursor: grab;
}
.transport__scrub:focus-visible { outline: none; box-shadow: var(--shadow-focus-teal); }

.transport__time {
  flex: none;
  min-width: 5ch;
  font-family: var(--font-body);
  font-size: var(--text-xs);
  line-height: var(--lh-xs);
  color: var(--fg-muted);
  /* Tabular figures so the readout does not jitter as it counts. */
  font-variant-numeric: tabular-nums;
  text-align: right;
}

/* ---- capture mode -------------------------------------------------------- */
/* Playwright drives window.__eqvSeek(t). The transport is operator chrome and
   must not appear in a frame. The phase rail is NOT hidden here — it is part
   of the picture the author asked for (C3.2), not an operator control, and it
   has to be in the exported video. */
.is-capturing .transport { display: none; }

/* ---- reduced motion ------------------------------------------------------ */
/* The clock snaps to section end states rather than scrubbing between them,
   so every section is still reachable and complete — just not animated. */
@media (prefers-reduced-motion: reduce) {
  .transport { transition: none; }
}
