/* =============================================================================
   deck-slides.css
   EXA Cinematic Executive Presentation — /exa/deck
   Slide-level layout: Reveal.js section sizing, Deck Mode + Read Mode
   treatment, act-rail offset, placeholder-slide styling for Phase 2.

   This file is separate from deck-tokens.css by design — tokens/elevation/
   depth is the reusable foundation (Phase 2+), this file is what actually
   arranges content inside a <section>, which will grow substantially in
   Phase 3 as each slide gets its real build.
============================================================================= */

.reveal {
  width: 100%;
  height: 100%;
  font-size: 16px;
}

.reveal .slides {
  text-align: left;
}

/* Every slide sits above the act rail + mode toggle chrome */
.slide {
  position: relative;
  width: 100%;
  height: 100%;
  /* border-box added 2026-07-28: under the default content-box, the
     padding-top below was ADDED to min-height:100vh, making every slide
     864px tall in an 800px viewport. .slides/.reveal inherited that, and
     Reveal's .controls (position:absolute; bottom:8px against .reveal)
     were pushed to y=806–880 — permanently below the fold, which is why
     the deck appeared to have no next/prev affordance at all. Same
     content-box arithmetic as .slide-inner's 1100+96=1196 (see the
     .body-copy entry in the Build Ledger). */
  box-sizing: border-box;
  min-height: 100vh;
  background: var(--bg);
  display: flex; /* defeated by reveal.css's own !important — see the override below this file's overflow-y rule */
  align-items: center;
  padding-top: 64px; /* clears the fixed act rail */
  overflow-x: hidden;
  /* Deck Mode safety net (Phase 2 foundational fix #2, see Build Ledger):
     reveal.css unconditionally keeps slide sections position:absolute with
     a shared, viewport/percentage-driven height, regardless of the deck's
     own disableLayout:true — a content-dense slide can still exceed that
     shared height, and Deck Mode has no ancestor scroll container to reach
     the rest. Plain overflow-y:auto, no scroll-behavior/transition — this
     is native instant scrolling, nothing for the reduced-motion override
     to need covering. Reverted to hidden below for Read Mode specifically,
     where the ancestor scroll container already handles everything and an
     independent inner scrollbar on a scroll-snap child risks exactly the
     nested-scroll conflict this rule must not introduce. */
  overflow-y: auto;
}

/* Fixed 2026-07-28: the .slide rule above's `display:flex; align-items:
   center` never applied. reveal.css carries an unconditional
   `html:not(.print-pdf) .reveal .slides section { display:block
   !important }` — not scoped to scroll/Read view as it first appeared,
   it forces every slide section to block in both Deck and Read Mode.
   Beating an !important rule needs an !important rule of equal-or-
   higher specificity; matched here by mirroring reveal.css's own
   selector shape with `.slide` appended, which is both higher-
   specificity and later in the cascade. Without this, Slide 01 (and
   every centered slide) top-jams inside its section instead of
   vertically centering. See Build Ledger for the measured before/after. */
html:not(.print-pdf) .reveal .slides section.slide {
  display: flex !important;
  align-items: center !important;
}

.slide--void {
  background: var(--void);
}

/* Fixed 2026-07-28: this was written as two descendant-combinator rules
   (`.slide--center .slide-inner`, `.slide--narrow .slide-inner`) but in
   every actual usage the modifier class sits ON .slide-inner itself
   (class="slide-inner plane-focal slide--center"), never on an
   ancestor — so both rules matched zero elements. Folded into one rule
   on the class as it's actually used; `justify-content:center` (written
   for .slide as a flex row) is dropped as dead weight now that the
   centering lives on .slide-inner as an auto-height flex column. See
   Build Ledger for the full root-cause record. `.slide--narrow` stays
   a dead selector deliberately — fixing it changes Slide 02's measure,
   which is out of this fix's scope; logged as an open item instead. */
.slide-inner.slide--center {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--space-xl);
}

.slide--narrow .slide-inner {
  max-width: 720px;
}

/* Slide 01 specific rhythm */
.slide--subhead {
  color: var(--muted);
  font-size: 1.25rem;
  max-width: 46ch;
}

.slide--authority {
  color: var(--faint);
  max-width: 60ch;
  margin-top: var(--space-md); /* stacks with the 24px gap above → 36px = --space-2xl */
}

.slide--footer {
  position: absolute;
  bottom: 32px;
  left: 50%;
  transform: translateX(-50%);
}

/* Cold open scene rhythm — slow single-column reveal per script §02 */
.scene-line {
  margin-bottom: 20px;
}

.slide--pivot {
  margin-top: 32px;
  padding-top: 32px;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}

[data-nav-hint] {
  display: inline-block;
  margin-top: 32px;
}

/* Closer — deepest stage, depth by subtraction. One soft, still light —
   not the atmosphere's normal gradient mesh, and no animation of its own.
   Sits above the flat --void background, below the focal text. */
.closer-light {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: radial-gradient(900px 500px at 50% 45%, var(--glow-far), transparent 65%);
}

/* The one place chrome disappears entirely (moments/closer.js toggles
   this on body, on entering/leaving slide-18 — see .act-rail's own
   transition in deck-tokens.css). */
body.closer-active .act-rail,
body.closer-active .site-return,
body.closer-active .advance-control {
  opacity: 0;
  pointer-events: none;
}

.slide--closer .closer-line {
  font-family: var(--display);
  font-size: clamp(1.75rem, 3.5vw, 2.75rem);
  font-weight: 500;
  color: var(--ink);
  line-height: 1.35;
  max-width: 20ch;
}

.slide--closer .closer-line em {
  color: var(--blue);
}

/* DecayCascade — signature moment 1. Five stages recede into depth on the
   .plane-stage perspective established in deck-tokens.css (perspective:
   1200px). Month 0 nearest/lit; Month 18 farthest/darkest, resolving in a
   --red-glow halo. Depth uses only the existing navy-ramp tokens (void,
   deep, surface-1/2) per deck-tokens.css's own token-scope note — no new
   colors. The CSS default state below is the "ignited" end-state on its
   own (progressive enhancement): moments/decay-cascade.js dims the stages
   at runtime and animates them back in front-to-back; without JS, or
   under reduced motion, this same lit state is what renders. */
.decay-cascade {
  display: flex;
  gap: 16px;
  margin: 32px 0;
  flex-wrap: nowrap;
  transform-style: preserve-3d;
}

.decay-cascade__stage {
  position: relative;
  flex: 1 1 140px;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 20px 16px;
  border-radius: 8px;
  text-align: center;
  color: var(--body-text);
  font-family: var(--display);
  font-weight: 500;
  border: var(--edge-e1);
  box-shadow: var(--shadow-e1);
  transform-style: preserve-3d;
  transition: transform 0.2s ease-out;
}

/* Depth reads through background (darker = farther, per the navy ramp) and
   diminishing perspective scale — NOT through fading opacity, which on a
   card this close in tone to its own atmosphere would just erase the card.
   Text stays fully legible at every depth; that legibility is the whole
   point of a graphic arguing "you can still see exactly how this failed." */
.decay-cascade__month {
  color: var(--ink);
}

.decay-cascade__stage[data-stage="0"] {
  background: var(--surface-2);
  box-shadow: var(--shadow-e2);
  border-top-color: rgba(127, 212, 255, 0.14);
  transform: translateZ(0);
}
.decay-cascade__stage[data-stage="1"] { background: var(--surface-1); transform: translateZ(-70px); }
.decay-cascade__stage[data-stage="2"] { background: var(--deep); transform: translateZ(-140px); }
.decay-cascade__stage[data-stage="3"] { background: var(--deep); transform: translateZ(-210px); }

.decay-cascade__stage--terminal {
  background: var(--void);
  border-color: rgba(255, 107, 91, 0.28);
  transform: translateZ(-280px);
  color: var(--red);
}

.decay-cascade__glow {
  position: absolute;
  inset: -10px;
  border-radius: 14px;
  box-shadow: 0 0 44px 10px var(--red-glow);
  pointer-events: none;
}


/* =============================================================================
   ARCHSHIFT — signature moment 2 (Slide 04). Two full planes in 3D space:
   the static-library plane tilts back (<=8deg) and desaturates, dropping
   toward the atmosphere plane, as the Infrastructure-of-Intent plane rotates
   forward to face the viewer at E4 (.elev-4, reused as-is for the full rim
   treatment). CSS below is the resolved end-state on its own (progressive
   enhancement); moments/arch-shift.js plays the crossing motion on entry.
============================================================================= */

.arch-shift {
  display: flex;
  flex-wrap: nowrap;
  gap: 32px;
  margin: 32px 0;
  transform-style: preserve-3d;
}

.arch-shift__plane {
  position: relative;
  flex: 1 1 0;
  min-width: 0;
  padding: 28px 24px;
  border-radius: 10px;
  transform-style: preserve-3d;
}

.arch-shift__label {
  display: block;
  margin-bottom: 10px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.arch-shift__line {
  margin: 0;
  color: var(--ink);
  font-family: var(--display);
  font-weight: 500;
}

.arch-shift__plane--before {
  transform: rotateY(-8deg) translateZ(-60px);
  filter: grayscale(70%);
  opacity: 0.7;
}

.arch-shift__plane--after {
  transform: rotateY(0deg) translateZ(40px);
}


/* =============================================================================
   THREEPILLARS — Slide 05 (junction slide). Real navigable content, not a
   decorative graphic — no aria-hidden. Three cards on a lit stage floor
   (horizon-line gradient beneath), each at E2 (.elev-2, reused) rising to E3
   on hover (.interactive, reused) with an added forward tilt this graphic
   specifically calls for; a manifesto quote card at E4/glass (both reused
   as-is from deck-tokens.css).
============================================================================= */

.pillar-stage {
  display: flex;
  gap: 24px;
  margin: 24px 0 20px;
  padding-bottom: 20px;
  position: relative;
}

.pillar-stage::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--horizon), transparent);
}

.pillar-card {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 22px 20px;
  border-radius: 10px;
  color: var(--body-text);
  text-decoration: none;
  transform-origin: bottom;
}

.pillar-card.interactive:hover,
.pillar-card.interactive:focus-visible {
  transform: translateY(-2px) rotateX(-4deg);
}

.pillar-card__number {
  color: var(--muted);
}

.pillar-card__title {
  margin: 0;
}

.pillar-card__line {
  margin: 0;
  color: var(--body-text);
  font-size: 0.95rem;
}

.pillar-card__meta {
  margin-top: auto;
  padding-top: 10px;
  border-top: 1px solid rgba(255, 255, 255, 0.06);
  line-height: 1.45;
}

.manifesto-quote {
  margin: 0;
  padding: 22px 28px;
  border-radius: 14px;
}

.manifesto-quote p {
  margin: 0;
  font-family: var(--display);
  font-size: 1.125rem;
  color: var(--ink);
}

/* Placeholder-slide marker — Phase 2 scaffold only, removed slide-by-slide
   as Phase 3 builds each section against its script + Visual Language spec. */
.placeholder-slide .slide-inner {
  max-width: 900px;
}

.placeholder-note {
  margin-top: 24px;
  color: var(--faint);
  font-style: italic;
}


/* =============================================================================
   TOKENCASCADE — signature moment 4 (Slide 06), the deck's one Tier-2 WebGL
   scene. The SVG (.token-cascade__fallback) is the default, always-present
   DOM state — same node grammar as the WebGL scene, fully lit, instant,
   requires no JS. The canvas starts invisible and non-interactive; JS (see
   moments/token-cascade.js / token-cascade-scene.js) flips
   [data-cascade-mode] on the container to cross-fade between the two. If
   that JS never runs at all — reduced motion, no WebGL2, script failure —
   the SVG is simply what's shown, permanently, exactly like the no-JS state
   of DecayCascade/ArchShift above.
============================================================================= */

.token-cascade {
  position: relative;
  height: 320px;
  margin: 28px 0;
}

.token-cascade__fallback,
.token-cascade__canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  transition: opacity 0.3s ease-out;
}

.token-cascade__fallback {
  /* Overrides the generic `[data-reduced-motion-fallback] { display: none }`
     default in deck-tokens.css — that generic rule assumes a fallback that's
     hidden until reduced motion forces it on. This one is the reverse: it's
     the always-visible default, hidden only once JS successfully swaps the
     canvas in (see [data-cascade-mode="canvas"] below). Same specificity,
     later in cascade order, so this wins for `display` without needing
     !important. */
  display: block;
  opacity: 1;
}

.token-cascade__canvas {
  opacity: 0;
  pointer-events: none;
}

.token-cascade[data-cascade-mode="canvas"] .token-cascade__canvas {
  opacity: 1;
}

.token-cascade[data-cascade-mode="canvas"] .token-cascade__fallback {
  opacity: 0;
}

.token-cascade__node--root {
  fill: var(--glow-core);
  filter: drop-shadow(0 0 10px var(--glow-mid));
}

.token-cascade__node--r1 {
  fill: var(--glow-core);
  opacity: 0.85;
}

.token-cascade__node--r2 {
  fill: var(--surface-3);
  opacity: 0.9;
}

.token-cascade__edge--r1 {
  stroke: var(--glow-mid);
  stroke-width: 1.5;
}

.token-cascade__edge--r2 {
  stroke: var(--glow-mid);
  stroke-width: 1;
  opacity: 0.6;
}


/* =============================================================================
   SAMEGRID — signature moment 3 (Slide 08). A 24-cell operator grid on a
   gently tilted stage plane. CSS default state below is the resolved
   "governed" end-state (progressive enhancement, same convention as
   DecayCascade/ArchShift/TokenCascade): the CLOSED cell already risen
   with its glow. moments/same-grid.js dims it flat at runtime and animates
   it back to this same end-state on entry.
============================================================================= */

.same-grid {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 10px;
  margin: 28px 0;
  padding: 24px;
  border-radius: 10px;
  background: var(--deep);
  transform: rotateX(10deg);
  transform-style: preserve-3d;
}

.grid-cell {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 10px 8px;
  border-radius: 6px;
  background: var(--surface-1);
  border: var(--edge-e1);
  transform-style: preserve-3d;
}

.grid-cell__label {
  color: var(--muted);
  font-size: 0.68rem;
}

.grid-cell__status {
  color: var(--body-text);
  font-size: 0.76rem;
}

.grid-cell--closed {
  background: var(--void);
  border-color: rgba(255, 107, 91, 0.35);
  box-shadow: var(--shadow-e2);
  transform: translateZ(50px);
}

.grid-cell--closed .grid-cell__status {
  color: var(--red);
  font-weight: 600;
}

.grid-cell__glow {
  position: absolute;
  inset: -6px;
  border-radius: 10px;
  box-shadow: 0 0 28px 6px var(--red-glow);
  pointer-events: none;
}


/* =============================================================================
   GOVERNEDBOUNDARY — Slide 07. Tier-1 CSS/SVG, no moments/ file (same
   precedent as Slide 05's pillar stage — Visual Language v2.0 only calls
   for perspective staging here, not a choreographed ignite). A wireframe
   boundary volume (two offset rectangles + connecting edges, suggesting a
   receded back face) with agent light-points scattered inside it — nothing
   ever drawn outside the wall.
============================================================================= */

.governed-boundary {
  margin: 28px 0;
  max-width: 480px;
}

.governed-boundary__face {
  fill: none;
  stroke: var(--glow-mid);
  stroke-width: 1.5;
}

.governed-boundary__edge {
  stroke: var(--glow-mid);
  stroke-width: 1;
  opacity: 0.5;
}

.governed-boundary__point {
  fill: var(--glow-core);
}


/* =============================================================================
   CAPABILITY LIST — Slide 07's four core capabilities. Collapsed titles +
   one-line descriptions only (see index.html comment: expansion copy lives
   at /exa/intelligence, not available in this repo, so the interactive
   expand affordance is deferred rather than guessed at).
============================================================================= */

.capability-list {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 16px;
  margin: 24px 0;
  padding: 0;
  list-style: none;
}

.capability-item {
  padding: 16px 18px;
  border-radius: 8px;
  background: var(--surface-1);
  border: var(--edge-e1);
}

.capability-item__title {
  display: block;
  margin-bottom: 4px;
  color: var(--ink);
  font-weight: 500;
}

.capability-item__line {
  margin: 0;
  font-size: 0.9rem;
  color: var(--body-text);
}


/* =============================================================================
   CALLOUT — generic color-coded card (script calls for "blue top-bar" on
   Slide 07's loop closure, "green top-bar" on Slide 06's scenario callout
   — same component, different accent).
============================================================================= */

.callout {
  --callout-color: var(--blue);
  padding: 20px 24px;
  border-radius: 8px;
  background: var(--surface-2);
  border-top: 3px solid var(--callout-color);
}

.callout p {
  margin: 0;
  color: var(--body-text);
}

.callout p + p {
  margin-top: 10px;
}

.callout--blue {
  --callout-color: var(--blue);
}

.callout--green {
  --callout-color: var(--green);
}


/* =============================================================================
   OUTCOME GRID + PERSONA SELECTOR — Slide 09. Real navigable/interactive
   content, not a decorative duplicate — no aria-hidden, same precedent as
   Slide 05's pillar stage. Cards reuse .elev-2/.interactive/.contact-shadow
   as-is (same combo as .pillar-card). The persona chips/lines below are a
   markup contract only — the toggle logic already exists in
   deck-behavior.js §8, stubbed ahead of this slide.
============================================================================= */

.outcome-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 20px;
  margin: 28px 0;
}

.outcome-card {
  padding: 22px 20px;
  border-radius: 10px;
  color: var(--body-text);
}

.outcome-card__number {
  color: var(--muted);
}

.outcome-card__title {
  margin: 6px 0 8px;
}

.outcome-card__line {
  margin: 0;
  color: var(--body-text);
  font-size: 0.95rem;
}

.outcome-card--amber {
  border-top: 3px solid var(--amber);
  box-shadow: var(--shadow-e2), inset 0 -24px 32px -24px var(--amber-glow);
}

.persona-tray {
  margin: 8px 0 0;
  padding: 20px 24px;
  border-radius: 12px;
}

.persona-tray__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.persona-tray__line {
  margin: 16px 0 0;
  padding-top: 16px;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
  color: var(--ink);
}


/* =============================================================================
   QUOTE STAGE — Slide 11, the deck's second and final quote card. Full-
   bleed E4 glass panel, a slight static tilt, a single top-left key-light
   wash. Tier-1 CSS only, no moments/ file — a compositional flourish, not
   a choreographed depth cue.
============================================================================= */

.quote-stage {
  position: relative;
  margin: 32px 0;
  padding: 40px 48px;
  border-radius: 16px;
  transform: rotate(-1deg);
  overflow: hidden;
}

.quote-stage::before {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(600px 300px at 0% 0%, rgba(255, 255, 255, 0.08), transparent 60%);
  pointer-events: none;
}

.quote-stage p {
  position: relative;
  margin: 0;
  font-family: var(--display);
  font-size: clamp(1.5rem, 3vw, 2.25rem);
  font-weight: 500;
  color: var(--ink);
  line-height: 1.35;
}


/* =============================================================================
   LEDGER ROWS — Slide 10's third-party corroboration, attributed facts in
   a mono ledger-row treatment.
============================================================================= */

.ledger-rows {
  margin: 20px 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 0;
}

.ledger-row {
  padding: 12px 0;
  border-top: 1px solid rgba(255, 255, 255, 0.06);
  font-family: var(--mono);
  font-size: 0.82rem;
  line-height: 1.5;
  color: var(--body-text);
}

.ledger-row:first-child {
  border-top: none;
}


/* =============================================================================
   ECONOMICS CONSOLE — Slide 10, the deck's first live-recomputing
   interactive model. Vanilla JS (moments/economics-console.js) drives the
   [data-econ-input]/[data-econ-output] contract below; this file is
   presentation only. Glass/E4, same combo as the manifesto quote and
   persona tray.
============================================================================= */

.econ-console {
  position: relative;
  margin: 32px 0;
  padding: 28px 32px;
  border-radius: 16px;
}

.econ-console__banner {
  display: inline-block;
  margin: 0 0 16px;
  padding: 6px 14px;
  border-radius: 999px;
  background: rgba(255, 198, 104, 0.14);
  border: 1px solid rgba(255, 198, 104, 0.35);
  color: var(--amber);
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.econ-console__assumptions {
  margin: 0 0 24px;
  color: var(--muted);
  font-size: 0.78rem;
}

.econ-console__inputs {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 20px 28px;
  margin-bottom: 28px;
}

.econ-input {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.econ-input__label {
  color: var(--muted);
  font-size: 0.8rem;
}

.econ-input__value {
  font-family: var(--mono);
  color: var(--ink);
  font-weight: 600;
}

.econ-input__note {
  color: var(--faint);
  font-size: 0.7rem;
}

/* Range sliders — no base browser styling existed at all before this
   (would have rendered as an unstyled OS-default control, out of place
   on the deck's dark canvas, and with a thumb well under the 44px touch
   target floor). Thumb is a real 44x44 hit area at every breakpoint —
   the touch-target risk is identical on desktop and mobile, this isn't
   mobile-only. */
input[type="range"] {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 44px;
  margin: 0;
  background: transparent;
  cursor: pointer;
}

input[type="range"]::-webkit-slider-runnable-track {
  height: 4px;
  border-radius: 2px;
  background: var(--surface-3);
}

input[type="range"]::-moz-range-track {
  height: 4px;
  border-radius: 2px;
  background: var(--surface-3);
}

input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 44px;
  height: 44px;
  margin-top: -20px; /* (44 - track-height) / 2, centers thumb on the 4px track */
  border-radius: 50%;
  background: var(--edge-light);
  border: 4px solid var(--bg);
  box-shadow: 0 0 0 1px rgba(127, 212, 255, 0.35), 0 2px 8px rgba(2, 5, 10, 0.5);
}

input[type="range"]::-moz-range-thumb {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--edge-light);
  border: 4px solid var(--bg);
  box-shadow: 0 0 0 1px rgba(127, 212, 255, 0.35), 0 2px 8px rgba(2, 5, 10, 0.5);
}

input[type="range"]:focus-visible {
  outline: none;
}

input[type="range"]:focus-visible::-webkit-slider-thumb {
  outline: 2px solid var(--edge-light);
  outline-offset: 3px;
}

input[type="range"]:focus-visible::-moz-range-thumb {
  outline: 2px solid var(--edge-light);
  outline-offset: 3px;
}

.econ-console__wells {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 20px;
  margin-bottom: 20px;
}

.econ-well {
  padding: 20px;
  border-radius: 10px;
  text-align: center;
}

.econ-well--governed {
  background: rgba(90, 160, 242, 0.08);
  border: 1px solid rgba(90, 160, 242, 0.24);
}

.econ-well--ungoverned {
  background: rgba(255, 107, 91, 0.08);
  border: 1px solid rgba(255, 107, 91, 0.28);
  box-shadow: 0 0 32px -8px var(--red-glow);
}

.econ-well__label {
  margin: 0 0 8px;
  color: var(--muted);
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.econ-well__value {
  margin: 0;
  font-family: var(--display);
  font-size: 1.75rem;
  font-weight: 700;
  color: var(--ink);
}

.econ-well--ungoverned .econ-well__value {
  color: var(--red);
}

.econ-well__sub {
  margin: 6px 0 0;
  color: var(--faint);
  font-size: 0.72rem;
}

.econ-ring {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 110px;
  height: 110px;
  border-radius: 50%;
  border: 2px solid var(--glow-mid);
  background: radial-gradient(circle at center, rgba(143, 194, 255, 0.12), transparent 70%);
}

.econ-ring__num {
  font-family: var(--display);
  font-size: 1.5rem;
  font-weight: 700;
  color: var(--ink);
}

.econ-ring__sub {
  margin-top: 4px;
  font-family: var(--mono);
  font-size: 0.6rem;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  text-align: center;
  line-height: 1.3;
}

.econ-console__delta {
  margin: 0;
  text-align: center;
  color: var(--body-text);
}

.econ-console__delta strong {
  color: var(--ink);
}


/* =============================================================================
   PLANE FLIP — Slide 12's operator/reviewer flip and the scorecard
   mini-flip (.plane-flip--sm modifier, same component). CSS default state
   is the resolved end-state: the back face (reviewer / NEW) forward
   (.plane-flip__inner sits at rotateY(180deg)). moments/operator-
   reviewer.js dims both to their front/before face at runtime and animates
   back to this same end-state on entry.
============================================================================= */

.plane-flip {
  perspective: 1200px;
  margin: 28px 0;
  max-width: 480px;
}

.plane-flip__inner {
  position: relative;
  min-height: 140px;
  transform-style: preserve-3d;
  transform: rotateY(180deg);
}

.plane-flip__face {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
  justify-content: center;
  padding: 24px 28px;
  border-radius: 12px;
  background: var(--surface-2);
  border: var(--edge-e1);
  box-shadow: var(--shadow-e2);
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}

.plane-flip__face--front {
  transform: rotateY(0deg);
}

.plane-flip__face--back {
  transform: rotateY(180deg);
  background: var(--surface-3);
  border-color: rgba(127, 212, 255, 0.22);
}

.plane-flip__label {
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.plane-flip__line {
  margin: 0;
  color: var(--ink);
  font-family: var(--display);
  font-weight: 500;
}

.plane-flip--sm {
  max-width: 320px;
}

.plane-flip--sm .plane-flip__inner {
  min-height: 100px;
}

.plane-flip--sm .plane-flip__face {
  padding: 16px 20px;
}

.plane-flip--sm .plane-flip__line {
  font-size: 0.9rem;
}


/* =============================================================================
   ROLE TRACKS — Slide 13. Two parallel platforms, Track B nearer/fully lit
   (elev-3), Track A a step deeper (elev-2) with the amber "working model"
   tag — reusing .elev-2/.elev-3/.contact-shadow as-is, same precedent as
   every other card grid in this deck. Real navigable-feeling content
   (no aria-hidden — this is the argument itself, not a duplicate of it).
============================================================================= */

.role-tracks {
  display: flex;
  gap: 24px;
  margin: 28px 0 16px;
  align-items: flex-end;
}

.role-track {
  flex: 1 1 0;
  min-width: 0;
  padding: 24px 22px;
  border-radius: 12px;
  color: var(--body-text);
}

.role-track--a {
  margin-top: 24px;
}

.role-track__tag {
  display: inline-block;
  margin-bottom: 10px;
  color: var(--blue);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.role-track--a .role-track__tag {
  color: var(--amber);
}

.role-track__title {
  margin: 0 0 6px;
}

.role-track__meta {
  margin: 0 0 10px;
  color: var(--muted);
  font-size: 0.82rem;
  font-style: italic;
}

.role-track__line {
  margin: 0;
  color: var(--body-text);
  font-size: 0.92rem;
}

.role-tracks-baseline {
  margin: 0;
  padding-top: 16px;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
  color: var(--muted);
  font-size: 0.78rem;
}


/* =============================================================================
   PROOF — Slide 15.
============================================================================= */

.proof-scene {
  margin: 24px 0 8px;
  padding: 22px 28px;
  border-left: 2px solid var(--glow-mid);
  background: rgba(255, 255, 255, 0.02);
}

.proof-scene p {
  margin: 0;
  font-family: var(--display);
  font-size: 1.05rem;
  font-style: italic;
  color: var(--ink);
  line-height: 1.6;
}

.proof-tag {
  margin: 0 0 20px;
  color: var(--faint);
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.proof-contrast {
  margin: 0 0 28px;
  color: var(--blue);
  font-size: 1rem;
}

.proof-other-cases {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
}

.proof-case-card {
  display: block;
  padding: 18px;
  border-radius: 10px;
  color: var(--body-text);
  text-decoration: none;
}

.proof-case-card__title {
  display: block;
  margin-bottom: 6px;
  color: var(--ink);
  font-weight: 500;
  font-size: 0.9rem;
}

.proof-case-card__line {
  margin: 0;
  font-size: 0.82rem;
  color: var(--body-text);
}


/* =============================================================================
   ENGAGEMENT STAGES — Slide 16. Three cards ascending in elevation only
   (elev-1/elev-2/elev-3) — no new 3D perspective staging attempted here,
   consistent with this being a batchable content slide.
============================================================================= */

.engagement-stages {
  margin: 28px 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.engagement-stage {
  display: flex;
  gap: 18px;
  padding: 20px 22px;
  border-radius: 12px;
  color: var(--body-text);
}

.engagement-stage__number {
  flex: 0 0 auto;
  color: var(--muted);
  font-size: 1.1rem;
}

.engagement-stage__title {
  margin: 0 0 8px;
  font-size: 1.05rem;
}

.engagement-stage__time {
  color: var(--muted);
  font-weight: 400;
  font-size: 0.85rem;
}

.engagement-stage__line {
  margin: 0 0 8px;
  font-size: 0.9rem;
  color: var(--body-text);
}

.engagement-stage__deliverable {
  margin: 0;
  font-size: 0.85rem;
  color: var(--faint);
}

.engagement-stage__deliverable strong {
  color: var(--ink);
}


/* =============================================================================
   CTA ROW — Slide 17. Reuses .interactive/.elev-1/.elev-2 as-is for hover
   feedback — no bespoke hover treatment.
============================================================================= */

.cta-row {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  margin-top: 28px;
}

.cta-button {
  display: inline-block;
  padding: 14px 24px;
  border-radius: 8px;
  font-family: var(--display);
  font-weight: 600;
  text-decoration: none;
  color: var(--ink);
}

.cta-button--primary {
  background: var(--blue);
  color: var(--void);
}


/* =============================================================================
   LADDER TIERS — Slide 14's real content: five tiers, real accessible
   text. The stair+rings graphic below duplicates this visually and is
   aria-hidden.
============================================================================= */

.ladder-tiers {
  margin: 28px 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 0;
}

.ladder-tier {
  padding: 14px 0;
  border-top: 1px solid rgba(255, 255, 255, 0.06);
}

.ladder-tier:first-child {
  border-top: none;
}

.ladder-tier__name {
  display: block;
  margin-bottom: 4px;
  color: var(--ink);
  font-family: var(--display);
  font-weight: 600;
}

.ladder-tier__meta {
  color: var(--muted);
  font-weight: 400;
  font-size: 0.85rem;
}

.ladder-tier__line {
  margin: 0 0 4px;
  color: var(--body-text);
  font-size: 0.9rem;
}

.ladder-tier__radius {
  margin: 0;
  color: var(--faint);
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}


/* =============================================================================
   CAREER LADDER — stair + blast-radius rings (Slide 14, aria-hidden). CSS
   default state is the resolved end-state: all five rings at full size/
   opacity. moments/career-ladder.js collapses them to near-zero at runtime
   and staggers them back out on entry.
============================================================================= */

.career-ladder {
  position: relative;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  height: 260px;
  margin: 32px 0;
  padding: 0 12px 24px;
  perspective: 1400px;
}

.career-ladder__step {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  transform-style: preserve-3d;
}

.career-ladder__step[data-tier="0"] { transform: translateY(0) translateZ(-40px); }
.career-ladder__step[data-tier="1"] { transform: translateY(-30px) translateZ(-20px); }
.career-ladder__step[data-tier="2"] { transform: translateY(-60px) translateZ(0); }
.career-ladder__step[data-tier="3"] { transform: translateY(-90px) translateZ(20px); }
.career-ladder__step[data-tier="4"] { transform: translateY(-120px) translateZ(40px); }

.career-ladder__platform {
  position: relative;
  z-index: 1;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--glow-core);
  box-shadow: 0 0 18px 4px var(--glow-mid);
}

.career-ladder__ring {
  position: absolute;
  border-radius: 50%;
  border: 1px solid var(--glow-mid);
  pointer-events: none;
}

.career-ladder__ring--0 { width: 60px; height: 60px; opacity: 0.5; }
.career-ladder__ring--1 { width: 110px; height: 110px; opacity: 0.45; }
.career-ladder__ring--2 { width: 170px; height: 170px; opacity: 0.4; }
.career-ladder__ring--3 { width: 240px; height: 240px; opacity: 0.32; }
.career-ladder__ring--4 {
  width: 320px;
  height: 320px;
  opacity: 0.24;
  border-color: var(--glow-far);
  box-shadow: 0 0 60px 20px var(--glow-far);
}


/* =============================================================================
   READ MODE — scroll-snap vertical stacking (Reveal's native scroll view)

   Both rules below were originally split across two selectors:
   `.reveal.has-vertical-scrollbar` / `.reveal[data-scroll-view]` for
   scroll-snap-align, `body.reveal-scroll` for the overflow override. The
   first pair is pre-existing (Phase 2) and never actually matched live
   Reveal 6.0.1 output — verified empirically (neither appears in the real
   DOM). `body.reveal-scroll` is the real marker Reveal sets. Fixed here:
   scroll-snap-align had likely never actually applied in Read Mode; reveal.css
   itself has zero scroll-snap CSS of its own (grepped — none), so the
   snap-to-slide behavior verified live earlier is Reveal's own JS scroll
   correction, not CSS — meaning this rule was probably dead weight from day
   one rather than a felt gap, but it's the same one-line fix as the
   dimension bug and worth doing rather than leaving broken CSS in place.
   Audited the rest of deck-slides.css/deck-tokens.css/deck-behavior.js for
   the same broken selector pattern — nothing else was silently relying on
   it; this was the only occurrence.
============================================================================= */

body.reveal-scroll .slide {
  scroll-snap-align: start;
  /* Read Mode's ancestor scroll container already handles all scrolling, so
     the Deck Mode safety net above (overflow-y: auto) must not reach here —
     an independent inner scrollbar on a scroll-snap child risks exactly the
     nested-scroll conflict this rule exists to prevent. */
  overflow-y: hidden;
}


/* =============================================================================
   MOBILE — 380px opening fold
============================================================================= */

@media (max-width: 640px) {
  .slide {
    padding-top: 56px;
    padding-bottom: 32px;
  }

  h1 {
    font-size: clamp(2rem, 9vw, 3rem);
  }

  .decay-cascade {
    flex-direction: column;
  }

  .arch-shift {
    flex-direction: column;
  }

  /* The rotateY tilt visually spills a card's rendered edge into the
     content below it once stacked in a single narrow column (transforms
     don't affect layout flow, so the skewed edge can overlap neighboring
     text) — flattened here, matching the depth-simplified mobile rule. */
  .arch-shift__plane--before,
  .arch-shift__plane--after {
    transform: none;
  }

  .pillar-stage {
    flex-direction: column;
  }

  .manifesto-quote {
    padding: 24px 20px;
  }

  .token-cascade {
    height: 220px;
  }

  .capability-list {
    grid-template-columns: 1fr;
  }

  .same-grid {
    grid-template-columns: repeat(3, 1fr);
    transform: none;
  }

  .outcome-grid {
    grid-template-columns: 1fr;
  }

  .econ-console__inputs {
    grid-template-columns: 1fr;
  }

  .econ-console__wells {
    grid-template-columns: 1fr;
  }

  .econ-ring {
    justify-self: center;
  }

  .role-tracks {
    flex-direction: column;
  }

  .role-track--a {
    margin-top: 0;
  }

  .proof-other-cases {
    grid-template-columns: 1fr;
  }

  .engagement-stage {
    flex-direction: column;
    gap: 8px;
  }

  /* The ascending horizontal stair (rings up to 320px wide) would badly
     overflow a narrow viewport as a row — stacks vertically instead,
     Designer at the bottom rising to Chief at the top, ring sizes scaled
     down to fit. [data-tier] (attribute-presence) matches the same
     specificity as the per-tier [data-tier="N"] rules above and comes
     later in the cascade, so this cleanly overrides them without
     !important. */
  .career-ladder {
    flex-direction: column-reverse;
    align-items: center;
    height: auto;
    gap: 20px;
    padding: 0;
    perspective: none;
  }

  .career-ladder__step[data-tier] {
    transform: none;
  }

  .career-ladder__ring--0 { width: 40px; height: 40px; }
  .career-ladder__ring--1 { width: 70px; height: 70px; }
  .career-ladder__ring--2 { width: 100px; height: 100px; }
  .career-ladder__ring--3 { width: 130px; height: 130px; }
  .career-ladder__ring--4 { width: 160px; height: 160px; }
}


/* =============================================================================
   APPENDIX DRAWER — Appendix A1, outside the narrative count. Collapsed
   by default, expand on demand. Glass/E4, same surface family as the
   econ console and persona tray (deck-tokens.css §4.1). Uses the shared
   .expandable / [data-expandable-trigger] contract (deck-behavior.js §7)
   — a static disclosure, not a choreographed moment, so no reduced-
   motion carve-out is needed beyond the global kill-switch.
============================================================================= */

.appendix-drawer {
  width: 100%; /* anticipated 2026-07-28 fix side effect: its parent .slide-inner
    is now a real flex column (see the Slide 01 fix), where align-items:center
    shrinks a child to its content width instead of the container's — this
    box was relying on being a plain block box under margin:auto. Without
    this it renders ~451px instead of its 640px max-width. */
  margin: 0 auto;
  max-width: 640px;
  padding: 28px 32px;
  border-radius: 16px;
  text-align: left;
}

/* h2 wraps the trigger button (the standard accessible accordion
   pattern — a heading for the section outline, the button for the
   interaction) so it needs the heading-level box reset; the visible
   typography still comes entirely from .eyebrow on the span inside. */
.appendix-drawer__heading {
  margin: 0;
  font: inherit;
  color: inherit;
  letter-spacing: normal;
  line-height: normal;
}

.appendix-drawer__trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  width: 100%;
  min-height: 44px; /* touch target floor */
  padding: 0;
  background: none;
  border: none;
  color: inherit;
  cursor: pointer;
  text-align: left;
}

.appendix-drawer__chevron {
  flex: none;
  width: 20px;
  height: 20px;
  fill: var(--muted);
  transition: transform 0.25s ease-out;
}

.appendix-drawer__trigger[aria-expanded="true"] .appendix-drawer__chevron {
  transform: rotate(180deg);
}

.appendix-drawer__content {
  margin-top: 20px;
  padding-top: 20px;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}

.appendix-drawer__copy {
  margin: 0 0 20px;
  color: var(--body-text);
  font-size: 0.92rem;
  line-height: 1.6;
}

.appendix-drawer__reading-label {
  margin: 0 0 12px;
}

.appendix-drawer__reading {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.appendix-drawer__reading a {
  font-family: var(--mono);
  font-size: 0.8rem;
  color: var(--faint);
  text-decoration: none;
  transition: color 0.2s ease-out;
}

.appendix-drawer__reading a:hover,
.appendix-drawer__reading a:focus-visible {
  color: var(--muted);
}

.appendix-drawer__reading-note {
  margin-left: 6px;
  opacity: 0.75;
}


/* =============================================================================
   DECAYCASCADE — REDUCED MOTION (instant, flat, fully lit)
   The 3D recede is itself a motion-adjacent depth cue, not just the GSAP
   ignite — so it is turned off here too, not only the timeline. The red
   halo on the terminal stage stays: it is a status signal (Month 18 /
   "architectural expiration"), not motion.
============================================================================= */

@media (prefers-reduced-motion: reduce) {
  .decay-cascade,
  .decay-cascade__stage {
    transform-style: flat;
  }

  .decay-cascade__stage {
    transform: none;
    opacity: 1;
    background: var(--surface-2);
    color: var(--body-text);
  }

  .decay-cascade__stage--terminal {
    color: var(--red);
  }
}


/* =============================================================================
   ARCHSHIFT — REDUCED MOTION (instant, flat, resolved two-state comparison)
   The 3D tilt/rotation is turned off, not just the GSAP crossing motion.
   The grayscale/opacity on the "before" plane and the elevated styling on
   the "after" plane both stay — that's the content-bearing before/after
   distinction, not motion.
============================================================================= */

@media (prefers-reduced-motion: reduce) {
  .arch-shift,
  .arch-shift__plane {
    transform-style: flat;
  }

  .arch-shift__plane--before,
  .arch-shift__plane--after {
    transform: none;
  }
}


/* =============================================================================
   SAMEGRID — REDUCED MOTION (instant, flat, governed state already resolved)
   The grid's tilt and the CLOSED cell's rise are both motion-adjacent depth
   cues, turned off here — not just the GSAP dim/rise timeline. The glow,
   color, and elevated shadow on the CLOSED cell all stay: that's the
   content-bearing governed/ungoverned distinction, not motion.
============================================================================= */

@media (prefers-reduced-motion: reduce) {
  .same-grid,
  .grid-cell {
    transform-style: flat;
  }

  .same-grid {
    transform: none;
  }

  .grid-cell--closed {
    transform: none;
  }
}


/* =============================================================================
   PLANE FLIP — REDUCED MOTION (both faces side by side, resolved)
   Different from every other moment's reduced-motion treatment above: the
   script explicitly calls for both faces visible at once here, not a
   single flattened face. Un-stacks the back face from its absolute/
   backface-hidden position so both faces fall into normal side-by-side
   flex flow instead.
============================================================================= */

@media (prefers-reduced-motion: reduce) {
  .plane-flip {
    perspective: none;
  }

  .plane-flip__inner {
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
    min-height: 0;
    transform: none;
    transform-style: flat;
  }

  .plane-flip__face {
    position: static;
    flex: 1 1 200px;
    backface-visibility: visible;
    transform: none;
  }
}


/* =============================================================================
   CAREER LADDER — REDUCED MOTION (flat stair, full five-ring state, instant)
   The ascending stair's 3D positioning is itself a motion-adjacent depth
   cue, flattened here — not just the GSAP stagger. The rings' default
   full size/opacity is untouched: they're already correct without JS.
============================================================================= */

@media (prefers-reduced-motion: reduce) {
  .career-ladder {
    perspective: none;
  }

  .career-ladder__step {
    transform: none;
    transform-style: flat;
  }
}
