/* ══════════════════════════════════════════════════════════════
   CRE8TOR — immersive story stages (chapters 01–12)
   Pinning is CSS (sticky); GSAP only scrubs the copy layers.
   Spec: CRE8TOR_Website.md §1.3–1.5, §19, §20.
   ══════════════════════════════════════════════════════════════ */

:root {
  --tone-paper: #fcf9f6;
  --tone-charcoal: #111110;
  --orange: #ff5c00;
  --amber: #fc8a40;
}

/* Fixed colour veil behind every chapter — tweened across act boundaries */
.tone-veil {
  position: fixed;
  inset: 0;
  z-index: 0;
  background: var(--tone-paper);
  pointer-events: none;
}
/* The film: one fixed canvas above the veil, below every .chapter (story.js + film.js draw
   acts 01–04 on it at the frame the scroll asks for). Created by story.js, never in the markup. */
.film-layer {
  position: fixed;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}
/* Act 05 draws inside #cta-stage's ambient stage as its .stage__media (blur/opacity from there) */
.film-canvas { display: block; width: 100%; height: 100%; }

/* ── Chapter = scroll range; stage = the pinned viewport ── */
.chapter {
  position: relative;
  z-index: 1;
  height: 300svh;
  color: var(--ink);
}
.chapter--paper {
  --tone: var(--tone-paper);
  --scrim: rgba(252, 249, 246, 0.78);
  --ink: #1c1c1a;
  --body: #5b4137;
  --muted: rgba(28, 28, 26, 0.55);
  --line: rgba(28, 28, 26, 0.16);
  --panel: rgba(252, 249, 246, 0.72);
  --orange-text: #a73a00;
}
.chapter--charcoal {
  --tone: var(--tone-charcoal);
  --scrim: rgba(17, 17, 16, 0.72);
  --ink: #fcf9f6;
  --body: rgba(252, 249, 246, 0.66);
  --muted: rgba(252, 249, 246, 0.45);
  --line: rgba(252, 249, 246, 0.16);
  --panel: rgba(17, 17, 16, 0.55);
  --orange-text: #ff5c00;
}

.stage {
  position: sticky;
  top: 0;
  height: 100svh;
  overflow: hidden;
  background: transparent;
}
.stage__media {
  position: absolute;
  inset: 0;
  z-index: 0;
}
.stage__poster,
.stage__poster img,
.stage__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}
.stage__video {
  opacity: 0;
  transition: opacity 0.9s ease;
}
.stage__video.is-playing { opacity: 1; }

/* Edge treatment: paper clips render ~#e6e0d8 and charcoal ~#06–#21,
   so every stage fades into the chapter tone at top/bottom + a light vignette.
   --edge (1 → 0, story.js buildBridge) takes the outgoing chapter's veil and grain out
   with its copy at the start of its bridge: after the bridge its stage slides up over the
   incoming one, and a veil still painted there is a tone band with a hard bottom edge
   moving across the incoming stage. --grain (0 → 1) is the incoming grain's entry.
   Both are chapter variables so no layer's opacity is tweened by two timelines. */
.stage__veil {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    linear-gradient(to bottom, var(--tone) 0%, rgba(0, 0, 0, 0) 16%, rgba(0, 0, 0, 0) 84%, var(--tone) 100%),
    linear-gradient(to right, var(--scrim) 0%, rgba(0, 0, 0, 0) 58%),
    radial-gradient(ellipse 85% 75% at 50% 50%, rgba(0, 0, 0, 0) 55%, var(--tone) 100%);
  opacity: calc(0.92 * var(--edge, 1));
}
.stage__grain {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  opacity: calc(var(--grain, 1) * var(--edge, 1));
}
/* ── Bridge stages: the incoming chapter rides in BENEATH the outgoing one ──
   Its pinned range grows by the bridge length (--bin) at the start, the outgoing
   chapter's by the same (--bout) at its end, and the incoming chapter overlaps the
   outgoing by 100svh + --bin so it is pinned before the bridge scrub begins.
   story.js gives film chapters descending z-index. All .js-scoped: the reduced-motion
   and no-GSAP paths keep today's layout. */
.chapter { --bin: 0px; --bout: 0px; }
.js .chapter[data-bridge],
.js .chapter[data-bridge-out] { height: calc(300svh + var(--bin) + var(--bout)); }
.js .chapter[data-bridge] { --bin: 100svh; margin-top: calc(-100svh - var(--bin)); }
.js .chapter[data-bridge-out] { --bout: 100svh; }
.stage.is-handed-off { pointer-events: none; }
/* An incoming chapter rides in beneath the outgoing one; it paints nothing until its
   bridge starts (story.js). Opacity, not visibility, so its copy stays Tab-reachable. */
.js .stage.is-queued { opacity: 0; }
/* Flow content between film chapters (.stage-band: the diagnostic CTA band after chapter 08)
   paints above the fixed film layer like the chapters do: a static block paints under a fixed
   z-index:0 canvas, which left the band's tone and heading invisible and its two paper
   neighbours' washed stage edges as hard borders against raw film at the 08 -> 09 seam. */
.stage-band { position: relative; z-index: 1; }

.stage__copy {
  position: absolute;
  inset: 0;
  z-index: 3;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 5.5rem 1.5rem 3.5rem;
}
@media (min-width: 1024px) {
  .stage__copy { padding: 6.5rem 3rem 4rem; }
}
.stage__inner {
  width: 100%;
  max-width: 80rem;
  margin: 0 auto;
}

/* ── No copy panel. The film is full-bleed behind every copy block at every width: no wash,
   no card, no radius on a copy layer (the palette is zero-radius). Legibility comes from the
   composition — the 9:16 A/G frames keep the scene in the bottom third under empty paper,
   the charcoal chapters have dark frames — plus the stage's own edge veil. (PR #5's
   .stage__block::before scrim painted an opaque rounded card over the top ~65% of the phone
   viewport; .stage__block stays in the markup as a hook with no rule.) ── */

/* ── Type inside stages (tone-aware, never recoloured by dark mode) ── */
.stage__tag {
  font-family: 'Space Mono', monospace;
  font-size: 0.65rem;
  text-transform: uppercase;
  letter-spacing: 0.2em;
  color: var(--orange-text);
  margin-bottom: 1.25rem;
}
.stage__h {
  font-family: 'Space Grotesk', sans-serif;
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: -0.03em;
  line-height: 0.95;
  font-size: clamp(2rem, 5vw, 4.5rem);
  color: var(--ink);
  margin: 0 0 1.25rem;
}
.stage__h--hero { font-size: clamp(2.6rem, 7.2vw, 5.6rem); line-height: 1.02; }
.stage__h .accent { color: var(--orange); }
.stage__p {
  font-size: clamp(1.05rem, 1.4vw, 1.35rem);
  line-height: 1.55;
  color: var(--body);
  max-width: 34rem;
}
.stage__mono {
  font-family: 'Space Mono', monospace;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.15em;
  color: var(--muted);
}
.stage__grid {
  display: grid;
  gap: 2rem;
  align-items: center;
}
@media (min-width: 1024px) {
  .stage__grid { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: 4rem; }
  .stage__grid--even { grid-template-columns: 1fr 1fr; }
}

/* Chapter 01 — hero */
#main-content .stage__copy { justify-content: center; }
.hero-copy { max-width: 42rem; }
.hero-line { display: block; will-change: transform; }
.hero-ctas { display: flex; flex-direction: column; gap: 1rem; margin: 2.25rem 0 2.5rem; }
@media (min-width: 640px) { .hero-ctas { flex-direction: row; } }
.hero-strip {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0;
  border-top: 1px solid var(--line);
  max-width: 42rem;
}
.hero-strip > div { padding: 1rem 1rem 0 0; border-left: 1px solid var(--line); padding-left: 1rem; }
.hero-strip > div:first-child { border-left: 0; padding-left: 0; }
.hero-strip .k {
  font-family: 'Space Grotesk', sans-serif;
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: -0.02em;
  font-size: 1.25rem;
  color: var(--ink);
}
.hero-strip .d { font-size: 0.8rem; line-height: 1.45; color: var(--body); margin-top: 0.25rem; }
@media (max-width: 639px) { .hero-strip .d { display: none; } }
.hero-transition {
  position: absolute;
  left: 1.5rem;
  right: 1.5rem;
  bottom: 18%;
  text-align: center;
  opacity: 0;
  pointer-events: none;
}
.hero-transition .stage__h { margin: 0; font-size: clamp(1.75rem, 4.5vw, 3.75rem); }
.hero-scroll {
  position: absolute;
  bottom: 1.5rem;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
}
.hero-scroll .mouse {
  width: 1.25rem; height: 2rem;
  border: 2px solid var(--line);
  border-radius: 9999px;
  display: flex; justify-content: center; padding-top: 0.35rem;
}
.hero-scroll .mouse span { width: 0.25rem; height: 0.5rem; background: var(--orange); border-radius: 9999px; }

/* Chapter 02 — complexity */
.sys-field { position: absolute; inset: 0; pointer-events: none; }
.chip {
  position: absolute;
  font-family: 'Space Mono', monospace;
  font-size: 0.62rem;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  padding: 0.45rem 0.7rem;
  border: 1px solid var(--line);
  background: var(--panel);
  backdrop-filter: blur(6px);
  color: var(--ink);
  white-space: nowrap;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}
.chip .badge {
  min-width: 1.1rem; height: 1.1rem;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--orange); color: #fff;
  font-size: 0.55rem; padding: 0 0.3rem;
}
.chip--flow { border-color: rgba(255, 92, 0, 0.5); }
.chip--flow .status { color: var(--orange-text); font-size: 0.55rem; letter-spacing: 0.1em; }
.chip--dup { opacity: 0; }
.gesture {
  position: absolute;
  display: flex; align-items: center; gap: 0.5rem;
  font-family: 'Space Mono', monospace; font-size: 0.6rem; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--muted);
}
.gesture .dot { width: 0.4rem; height: 0.4rem; background: var(--orange); border-radius: 9999px; }
.gesture .lbl { border: 1px solid var(--line); padding: 0.35rem 0.6rem; background: var(--panel); color: var(--ink); }
#complexity .stage__inner { position: relative; z-index: 2; }
@media (max-width: 767px) {
  .sys-field { position: static; display: flex; flex-wrap: wrap; gap: 0.4rem; margin-bottom: 1.5rem; pointer-events: none; }
  .sys-field .chip, .sys-field .gesture { position: static; }
  .sys-field .chip--dup { display: none; }
  .sys-field .gesture { width: 100%; }
}

/* SVG diagrams (chapters 03, 05, 07) */
.diagram { width: 100%; height: auto; overflow: visible; }
.diagram .draw { fill: none; stroke: var(--orange); stroke-width: 1.5; stroke-linecap: square; }
.diagram .node rect { fill: var(--panel); stroke: var(--line); stroke-width: 1; }
.diagram .node text {
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  fill: var(--ink);
  text-anchor: middle;
  dominant-baseline: middle;
}
.diagram .node--ai rect { stroke: var(--orange); fill: rgba(255, 92, 0, 0.1); }
.diagram .node--ai text { fill: var(--orange-text); font-weight: 700; }
.map-mini { display: none; }
@media (max-width: 767px) {
  .map-full { display: none; }
  .map-mini { display: block; }
  .diagram { max-height: 38svh; }
}

/* Chapter 04 — opportunities */
.opp-rows { display: grid; gap: 0.35rem; margin: 1.5rem 0; }
.opp-row {
  display: flex; justify-content: space-between; align-items: center; gap: 1rem;
  font-family: 'Space Mono', monospace; font-size: 0.68rem; letter-spacing: 0.1em; text-transform: uppercase;
  padding: 0.5rem 0; border-bottom: 1px solid var(--line); color: var(--ink);
}
.opp-row .arrow { flex: 1; height: 1px; background: var(--line); position: relative; }
.opp-row .arrow::after {
  content: ''; position: absolute; right: 0; top: -2px; width: 5px; height: 5px; background: var(--orange);
}
.opp-row .tag { color: var(--orange-text); white-space: nowrap; }
.opp-cards { display: grid; gap: 0.75rem; }
@media (min-width: 1024px) { .opp-cards { grid-template-columns: repeat(3, 1fr); } }
.opp-card { border: 1px solid var(--line); background: var(--panel); padding: 1rem 1.1rem; backdrop-filter: blur(6px); }
.opp-card .k {
  font-family: 'Space Mono', monospace; font-size: 0.62rem; letter-spacing: 0.2em; text-transform: uppercase; color: var(--orange-text);
}
.opp-card .t { font-family: 'Space Grotesk', sans-serif; font-weight: 700; font-size: 1rem; line-height: 1.3; color: var(--ink); margin-top: 0.3rem; }
.funnel { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.75rem 1.5rem; margin-top: 1.5rem; }
.funnel .n {
  font-family: 'Space Grotesk', sans-serif; font-weight: 900; font-size: clamp(1.8rem, 3vw, 2.75rem); letter-spacing: -0.03em; color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.funnel .n.lit { color: var(--orange); }
.funnel .l { font-family: 'Space Mono', monospace; font-size: 0.6rem; letter-spacing: 0.15em; text-transform: uppercase; color: var(--muted); }
.funnel .sep { color: var(--orange); font-family: 'Space Mono', monospace; }
.funnel .note { flex-basis: 100%; }
@media (max-width: 767px) {
  /* The whole block must fit 100svh with the toolbar visible (390x664, iPhone 14 Safari):
     the stage clips the copy while the chapter is live, so anything below 664px — the
     diagnostic CTA — is never hit-testable. Cards become one row of chips, the funnel
     one line with its caption under it, and the CTA block loses its desktop air. */
  .opp-rows { margin: 0.75rem 0 0; gap: 0; }
  .opp-row { padding: 0.2rem 0; font-size: 0.6rem; }
  .opp-cards { display: flex; flex-wrap: wrap; gap: 0.4rem; }
  .opp-card { padding: 0.35rem 0.6rem; }
  .opp-card .t { display: none; }
  .funnel { gap: 0.25rem 0.6rem; margin-top: 0.75rem; align-items: flex-start; }
  .funnel > span:not(.sep):not(.note) { display: inline-flex; flex-direction: column; }
  .funnel .n { font-size: 1.15rem; line-height: 1.1; }
  .funnel .l { font-size: 0.55rem; letter-spacing: 0.08em; }
  .funnel .sep { line-height: 1.4; }
  .funnel .note { margin-top: 0.25rem; }
  #opportunities .opp-cta { margin-top: 0.75rem; }
  #opportunities .opp-cta .stage__p { margin-bottom: 0.5rem; }
}

/* Chapter 06 — agent */
.agent-words { display: grid; gap: 0.15rem; margin-top: 1.5rem; }
.agent-words span {
  font-family: 'Space Grotesk', sans-serif; font-weight: 900; text-transform: uppercase; letter-spacing: -0.03em;
  font-size: clamp(1.6rem, 3.4vw, 3rem); line-height: 1; color: var(--ink); opacity: 0.22;
}
.thread { border: 1px solid var(--line); background: var(--panel); backdrop-filter: blur(8px); padding: 1.25rem; }
.thread .who { font-family: 'Space Mono', monospace; font-size: 0.58rem; letter-spacing: 0.15em; text-transform: uppercase; color: var(--muted); margin-bottom: 0.4rem; }
.bubble { padding: 0.75rem 0.9rem; font-size: 0.9rem; line-height: 1.45; max-width: 90%; color: var(--ink); }
.bubble--in { background: rgba(255, 255, 255, 0.06); border: 1px solid var(--line); }
.bubble--out { background: rgba(255, 92, 0, 0.12); border: 1px solid rgba(255, 92, 0, 0.45); margin-left: auto; }
.trace { margin: 1rem 0; display: grid; gap: 0.3rem; }
.trace li {
  display: flex; align-items: center; gap: 0.6rem;
  font-family: 'Space Mono', monospace; font-size: 0.62rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted);
}
.trace li::before { content: ''; width: 0.45rem; height: 0.45rem; border: 1px solid var(--line); flex: none; }
.trace li.done { color: var(--ink); }
.trace li.done::before { background: var(--orange); border-color: var(--orange); }
.thread-chips { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.75rem; }
.thread-chips .chip { position: static; }
.case-links { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 1.25rem; align-items: center; }
.case-link {
  font-family: 'Space Mono', monospace; font-size: 0.6rem; letter-spacing: 0.15em; text-transform: uppercase;
  border: 1px solid rgba(255, 92, 0, 0.45); color: var(--orange-text); background: transparent;
  padding: 0.45rem 0.75rem; cursor: pointer; transition: background 0.3s, color 0.3s;
}
.case-link:hover, .case-link:focus-visible { background: var(--orange); color: #fff; }
/* clip-path cuts off an outside focus ring; draw it inside the button instead */
.stage__copy .clipped-hex:focus-visible { outline-color: currentColor; outline-offset: -5px; }
@media (max-width: 767px) {
  .trace li:nth-child(n+6) { display: none; }
  .agent-words { grid-template-columns: repeat(4, auto); gap: 0.75rem; margin-top: 0.75rem; }
  .agent-words span { font-size: 1.1rem; }
  /* fit 100svh at 390x664 (see chapter 04): a tighter thread, no decorative chips */
  .thread { padding: 0.85rem; }
  .thread .who { margin-bottom: 0.25rem; }
  .bubble { padding: 0.55rem 0.7rem; font-size: 0.85rem; line-height: 1.4; }
  .trace { margin: 0.6rem 0; gap: 0.15rem; }
  .thread-chips { display: none; }
  .case-links { margin-top: 0.5rem; gap: 0.35rem; }
  .case-link { padding: 0.35rem 0.6rem; }
}

/* Chapter 07 — agents */
.log { margin-top: 1.25rem; display: grid; gap: 0.35rem; }
.log-line {
  font-family: 'Space Mono', monospace; font-size: 0.66rem; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--body); clip-path: inset(0 100% 0 0);
}
.log-line::before { content: '› '; color: var(--orange); }
.log-line.strong { color: var(--ink); font-weight: 700; }
@media (max-width: 767px) { .log-line:nth-child(n+5):not(.strong) { display: none; } }

/* Chapter 08 — before / after */
.ba { display: grid; grid-template-columns: 1fr 1fr; gap: 1.5rem; margin-top: 1.5rem; max-width: 60rem; }
.ba h3 { font-family: 'Space Mono', monospace; font-size: 0.65rem; letter-spacing: 0.2em; text-transform: uppercase; margin-bottom: 0.75rem; color: var(--muted); }
.ba--after h3 { color: var(--orange-text); }
.ba ul { display: grid; gap: 0.5rem; }
.ba li {
  font-family: 'Space Grotesk', sans-serif; font-weight: 700; text-transform: uppercase; letter-spacing: -0.01em;
  font-size: clamp(0.95rem, 1.6vw, 1.5rem); line-height: 1.2; color: var(--ink);
  padding: 0.6rem 0; border-top: 1px solid var(--line);
}
.ba--before li { color: var(--body); }
.ba--after li { color: var(--ink); }

/* Chapter 09 — impact */
#impact .stage__media { opacity: 0.4; }
.tiles { display: grid; gap: 0.75rem; margin-top: 1.5rem; }
@media (min-width: 640px) { .tiles { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .tiles { grid-template-columns: repeat(5, 1fr); } }
.tile {
  text-align: left; border: 1px solid var(--line); background: var(--panel); backdrop-filter: blur(8px);
  padding: 1.1rem 1.1rem 1rem; cursor: pointer; color: var(--ink);
  transition: border-color 0.3s, transform 0.3s;
  display: flex; flex-direction: column; gap: 0.35rem;
}
.tile:hover, .tile:focus-visible { border-color: var(--orange); transform: translateY(-3px); }
.tile .k { font-family: 'Space Mono', monospace; font-size: 0.58rem; letter-spacing: 0.2em; text-transform: uppercase; color: var(--orange-text); }
.tile .n { font-family: 'Space Grotesk', sans-serif; font-weight: 900; font-size: clamp(1.8rem, 2.6vw, 2.5rem); letter-spacing: -0.03em; line-height: 1; }
.tile .n small { font-family: 'Space Mono', monospace; font-size: 0.7rem; font-weight: 400; color: var(--muted); margin-left: 0.15rem; }
.tile .l { font-size: 0.8rem; line-height: 1.4; color: var(--body); }
.tile .c { font-family: 'Space Mono', monospace; font-size: 0.55rem; letter-spacing: 0.15em; text-transform: uppercase; color: var(--muted); margin-top: auto; padding-top: 0.5rem; }
@media (max-width: 639px) {
  .tiles { grid-template-columns: 1fr 1fr; gap: 0.5rem; margin-top: 1rem; }
  .tile { padding: 0.75rem 0.8rem 0.65rem; gap: 0.25rem; }
  .tile .l { display: none; }
  .tile .n { font-size: 1.7rem; }
  .tiles .tile:last-child { grid-column: 1 / -1; }
}

/* ── Ambient chapters (10–12): sticky video behind flowing content ── */
.chapter--ambient { height: auto; overflow: clip; color: inherit; }
.chapter--ambient.dark { color: #e5e2e0; }
.chapter--ambient .stage { margin-bottom: -100svh; z-index: 0; }
.chapter--ambient .stage__tone { position: absolute; inset: 0; z-index: 0; background: var(--ambient-bg); }
.chapter--ambient .stage__media { z-index: 1; opacity: 0.2; filter: blur(12px); transform: scale(1.06); }
.chapter--ambient .stage__veil { z-index: 2; opacity: 0.6; background: radial-gradient(ellipse 85% 75% at 50% 50%, rgba(0, 0, 0, 0) 55%, var(--tone) 100%); }
.chapter--ambient > section { position: relative; z-index: 1; background: transparent !important; }
.chapter--ambient.chapter--paper { --ambient-bg: #f6f3f1; --tone: #f6f3f1; }
html.dark .chapter--ambient.chapter--paper { --ambient-bg: #111110; --tone: #111110; }
.chapter--ambient.chapter--charcoal { --ambient-bg: #111110; }

/* ── Reduced motion: no pin, no scrub, posters only, copy fully visible ── */
@media (prefers-reduced-motion: no-preference) {
  .js .stage__copy [data-reveal] { opacity: 0; }
  .js .hero-transition { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .chapter { height: auto; }
  .stage { position: relative; height: auto; min-height: 100svh; }
  .chapter--ambient .stage { position: absolute; inset: 0; min-height: 0; height: 100%; margin: 0; }
  .stage__video { display: none; }
  .stage__copy { position: relative; }
  .stage__copy [data-reveal] { opacity: 1 !important; transform: none !important; }
  .hero-transition { position: static; opacity: 1; text-align: left; margin-top: 2rem; }
  .agent-words span { opacity: 1; }
  .chip--dup { display: none; }
  .log-line { clip-path: none; }
  .trace li { color: var(--ink); }
  .trace li::before { background: var(--orange); border-color: var(--orange); }
  .funnel .n { color: var(--orange); }
  .hero-scroll { display: none; }
}

/* Mobile chapter scroll range: 110% */
@media (max-width: 767px) {
  .chapter { height: 210svh; }
  /* Paper chapters: copy in the UPPER half. The regenerated 9:16 A/G clips keep the
     scene in the lower half with empty paper above, so the copy stops sitting on it.
     (#main-content is spelled out to beat its own justify-content rule.) */
  .chapter--paper .stage__copy,
  #main-content .stage__copy { justify-content: flex-start; padding-top: calc(6.5rem + env(safe-area-inset-top, 0px)); }
  .js .chapter[data-bridge],
  .js .chapter[data-bridge-out] { height: calc(210svh + var(--bin) + var(--bout)); }
  .js .chapter[data-bridge] { --bin: 70svh; }
  .js .chapter[data-bridge-out] { --bout: 70svh; }
  /* iOS Safari: the visible area grows past 100svh as the toolbar collapses, and the
     incoming chapter (pulled up beneath by its bridge margin) showed through the gap
     under the 100svh stage. The film layers run to the largest viewport, and while a
     film chapter is on screen (.is-live, story.js) its stage stops clipping them; the
     copy clips itself instead. .js-scoped: the reduced-motion path is unchanged. */
  .js .chapter:not(.chapter--ambient) .stage__media,
  .js .chapter:not(.chapter--ambient) .stage__veil,
  .js .chapter:not(.chapter--ambient) .stage__grain,
  .js .film-layer { height: 100lvh; }
  .js .chapter:not(.chapter--ambient) .stage.is-live { overflow: visible; }
  .js .chapter:not(.chapter--ambient) .stage.is-live .stage__copy { overflow: hidden; }
  .stage__copy { padding: 6.5rem 1rem 2.5rem; }
  /* Mobile rhythm: every film chapter's copy block must fit 100svh with the browser
     toolbar visible (390x664), so the tag/heading margins and the grid gap tighten. */
  .stage__tag { margin-bottom: 0.75rem; }
  .stage__h { margin-bottom: 0.75rem; }
  .stage__grid { gap: 1.25rem; }
  /* Mobile type scale, set ONCE here; the nine chapters inherit it. Proportional to desktop
     (headline >= 2x the paragraph, paragraph >= 16px) and shared by both languages:
     .stage__copy .stage__h outranks index.html's html.lang-zh h1/h2 sizes, and CJK gets its
     looser line-heights through the same variables. test/mobile-copy-fit.test.js asserts the
     floor (32px / 16px) and that every chapter still fits 390x664. */
  /* (index.html sets the mobile root at 14.4px: 2.5rem = 36px, 2.9rem = 41.8px, 1.125rem = 16.2px) */
  .chapter { --m-tag: 0.78rem; --m-h: 2.5rem; --m-h-hero: 2.9rem; --m-h-lh: 1; --m-p: 1.125rem; --m-p-lh: 1.6; }
  html.lang-zh .chapter { --m-h-lh: 1.15; --m-p-lh: 1.8; }
  .stage__copy .stage__tag { font-size: var(--m-tag); }
  .stage__copy .stage__h { font-size: var(--m-h); line-height: var(--m-h-lh); }
  .stage__copy .stage__h--hero { font-size: var(--m-h-hero); }
  .stage__copy .stage__p { font-size: var(--m-p); line-height: var(--m-p-lh); }
  /* Contrast floor over the film (CTO, 2026-09-25: paragraph >= 4.5:1, text >= 24 px >= 3:1,
     against the rendered frames; scripts/copy-contrast.mjs). On a phone the paragraphs span
     the full width over the frames' highlights: the charcoal chapters measured 1.5–3.2:1 at
     0.66 ink, #complexity 3.9:1 at 390x664. One shared rule: a halo in the chapter's tone on
     every headline and paragraph (a halo is not a panel), and charcoal paragraph ink at 1
     (0.9 left #agents at 4.34:1 at 390x664). Measured 4.9–14:1 with no scrim. A copy-band
     gradient was measured and rejected: at the
     owner's ceiling (peak 0.5) it still left #opportunities at 1.8:1 alone and 3.5:1 with the
     halo, and washed the frame for nothing. */
  .stage__copy .stage__h,
  .stage__copy .stage__p { text-shadow: 0 0 6px var(--tone), 0 0 14px var(--tone); }
  .chapter--charcoal .stage__copy .stage__p { color: var(--tone-paper); }
  /* .hero-strip's centered content can push its bottom row into .hero-scroll's
     fixed bottom band on short/narrow viewports (confirmed overlap at 390x844);
     the cue is already hidden under reduced-motion, so drop it here too. */
  .hero-scroll { display: none; }
  /* Hero slim (mobile only): clip A is being regenerated with the scene in the bottom third
     (empty paper to ~565 of 844 CSS px), so the hero copy block must end above ~520px. The
     secondary CTA becomes a text link with an arrow, the strip becomes one compact line, and
     the CTA margins tighten. Desktop hero unchanged. */
  .hero-ctas { gap: 0.75rem; margin: 1.25rem 0 1rem; }
  .hero-ctas > a:nth-child(2) {
    align-self: flex-start;
    border: 0;
    padding: 0.25rem 0;
    background: transparent;
    clip-path: none;
    box-shadow: none;
    color: var(--orange-text);
    text-decoration: none;
    font-size: 0.8rem;
  }
  .hero-ctas > a:nth-child(2)::after { content: " \2192"; }
  .hero-ctas > a:nth-child(2):hover { background: transparent; color: var(--orange-text); }
  /* clip-path is gone here, so the ring can sit outside the text again */
  .hero-ctas > a:nth-child(2):focus-visible { outline: 2px solid var(--orange); outline-offset: 3px; }
  .hero-strip { display: flex; align-items: baseline; gap: 0.75rem; padding-top: 0.5rem; }
  .hero-strip > div { padding: 0; border-left: 0; display: flex; align-items: baseline; gap: 0.75rem; }
  .hero-strip > div + div::before { content: "\00b7"; color: var(--orange); font-family: "Space Mono", monospace; font-size: 0.8rem; }
  .hero-strip .k { font-size: 0.85rem; letter-spacing: 0; }
  .hero-strip .d { display: none; }
}
