/* ascentbible.com — landing page
   Dark stage, luminous Scripture. Scroll-driven scenes; all motion is
   mapped to scroll position by main.js via the --p custom property or
   direct style writes. Design doc: docs/ascentbible-landing-design.md */

:root {
  --bg: #0B0C10;
  --ink: #F2F1EC;
  --mut: #9094A0;
  --faint: #5A5E68;
  --gold: #C8A96A;
  --green: #6FA08B;
  --grad: linear-gradient(92deg, #C8A96A, #6FA08B);
  --hairline: rgba(255, 255, 255, 0.10);

  /* app themes, reproduced faithfully inside the phone */
  --paper-bg: #FBF8F2; --paper-ink: #2B2A26; --paper-soft: #8A857A; --paper-accent: #3E5C50;
  --linen-bg: #F3EEE3; --linen-ink: #3A3327; --linen-soft: #94897A; --linen-accent: #7A4A2B;
  --dusk-bg: #14161C;  --dusk-ink: #E7E4DC;  --dusk-soft: #8B8E97;  --dusk-accent: #C8A96A;

  --sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --serif: Charter, Georgia, "Times New Roman", serif;
}

* { margin: 0; padding: 0; box-sizing: border-box; }
html { scroll-behavior: auto; }
body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
a { color: inherit; }
::selection { background: rgba(200, 169, 106, 0.35); }

/* ---------- progress rail (I–V) ---------- */
.rail {
  position: fixed;
  left: 1.75rem;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  flex-direction: column;
  gap: 1.4rem;
  z-index: 10;
  font-size: 0.75rem;
  letter-spacing: 0.12em;
  color: var(--faint);
  opacity: 0;
  transition: opacity 0.5s;
}
.rail.visible { opacity: 1; }
.rail a {
  color: inherit;
  text-decoration: none;
  transition: color 0.4s;
  padding: 0.2rem 0.4rem;
  margin: -0.2rem -0.4rem;
}
.rail a:hover { color: var(--mut); }
.rail a.active {
  color: transparent;
  background: var(--grad);
  -webkit-background-clip: text;
  background-clip: text;
  font-weight: 650;
}
@media (max-width: 900px) { .rail { display: none; } }

/* ---------- persistent off-ramp ---------- */
.corner-cta {
  position: fixed;
  top: 1.25rem;
  right: 1.5rem;
  z-index: 20;
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  padding: 0.5rem 1.15rem;
  border-radius: 999px;
  border: 1px solid rgba(200, 169, 106, 0.4);
  color: var(--ink);
  text-decoration: none;
  background: rgba(11, 12, 16, 0.7);
  box-shadow: 0 0 0 1px rgba(200, 169, 106, 0.08), 0 4px 24px rgba(200, 169, 106, 0.16);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.75s, color 0.3s, border-color 0.3s, box-shadow 0.3s;
}
.corner-cta.visible { opacity: 1; pointer-events: auto; }
.corner-cta:hover, .corner-cta:focus-visible {
  color: var(--ink);
  border-color: rgba(200, 169, 106, 0.85);
  box-shadow: 0 0 0 1px rgba(200, 169, 106, 0.2), 0 4px 28px rgba(200, 169, 106, 0.3);
}
.corner-cta .cta-short { display: none; }
@media (max-width: 900px) {
  .corner-cta {
    top: auto;
    bottom: calc(env(safe-area-inset-bottom) + 0.9rem);
    right: 0.9rem;
    font-size: 0.75rem;
    padding: 0.42rem 0.85rem;
    background: rgba(11, 12, 16, 0.7);
  }
  .corner-cta .cta-full { display: none; }
  .corner-cta .cta-short { display: inline; }
  /* mid-scroll the film owns the whole screen; the pill returns on rest */
  .corner-cta.scrolling { opacity: 0; pointer-events: none; }
}

/* ---------- shared scene scaffolding ---------- */
.scene { height: calc(var(--len, 4) * 100vh); position: relative; }
.stage {
  position: sticky;
  top: 0;
  height: 100vh;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}
.duo {
  display: grid;
  grid-template-columns: minmax(0, 30rem) auto;
  align-items: center;
  gap: 5vw;
  padding: 0 6vw;
  width: 100%;
  max-width: 78rem;
}
.copy { position: relative; min-height: 16rem; }
.copy > * { will-change: opacity, transform; }
.copy .stack { position: absolute; inset: 0; display: flex; flex-direction: column; justify-content: center; }

.numeral {
  font-size: 0.8125rem;
  font-weight: 650;
  letter-spacing: 0.22em;
  color: transparent;
  background: var(--grad);
  -webkit-background-clip: text;
  background-clip: text;
  margin-bottom: 0.875rem;
}
h2 {
  font-size: clamp(1.75rem, 3.2vw, 2.75rem);
  font-weight: 650;
  line-height: 1.15;
  letter-spacing: -0.02em;
  margin-bottom: 1.25rem;
}
.copy p { color: var(--mut); font-size: 1.0625rem; max-width: 26rem; }
.copy p + p { margin-top: 0.75rem; }
.copy p strong { color: var(--ink); font-weight: 550; }

[data-in] { opacity: 0; }

/* ---------- the phone ---------- */
.phone {
  width: min(340px, 42vw);
  aspect-ratio: 9 / 18.5;
  border-radius: 44px;
  border: 1px solid var(--hairline);
  background: #17181D;
  padding: 12px;
  box-shadow:
    0 40px 90px rgba(0, 0, 0, 0.55),
    0 0 120px rgba(200, 169, 106, 0.07);
  position: relative;
  will-change: transform, opacity;
}
.screen {
  width: 100%;
  height: 100%;
  border-radius: 34px;
  overflow: hidden;
  position: relative;
  background: var(--paper-bg);
  color: var(--paper-ink);
  transition: background 0.8s, color 0.8s;
  font-family: var(--serif);
}
.phone.linen .screen { background: var(--linen-bg); color: var(--linen-ink); }
.phone.dusk .screen { background: var(--dusk-bg); color: var(--dusk-ink); }

.chrome {
  position: absolute;
  left: 0; right: 0;
  padding: 0.9rem 1.25rem;
  font-family: var(--sans);
  font-size: 0.7rem;
  letter-spacing: 0.08em;
  color: var(--paper-soft);
  display: flex;
  justify-content: space-between;
  align-items: center;
  z-index: 3;
  transition: opacity 0.5s, transform 0.5s, color 0.8s;
}
.phone.linen .chrome { color: var(--linen-soft); }
.phone.dusk .chrome { color: var(--dusk-soft); }
.chrome.top { top: 0; }
.chrome.bottom { bottom: 0; justify-content: center; gap: 1.5rem; }
.chrome .pill {
  border: 1px solid currentColor;
  border-radius: 999px;
  padding: 0.1rem 0.65rem;
  opacity: 0.75;
}
.phone.chrome-hidden .chrome.top { opacity: 0; transform: translateY(-8px); }
.phone.chrome-hidden .chrome.bottom { opacity: 0; transform: translateY(8px); }

.pane {
  position: absolute;
  inset: 0;
  padding: 2.6rem 1.5rem;
  opacity: 0;
  will-change: opacity, transform;
}
.pane.on { opacity: 1; }

/* real-app footage: a canvas fills the screen slot; while it's active
   the DOM replica panes and the fake chrome are hidden */
.shot { position: absolute; inset: 0; width: 100%; height: 100%; display: none; }
.phone.footage .shot { display: block; }
.phone.footage .pane,
.phone.footage .chrome { display: none; }

/* tall-image pan: one real full-render capture translated smoothly,
   variant images stacked on top for dissolves (themes, focus states) */
.pan { position: absolute; inset: 0; overflow: hidden; display: none; }
.phone.footage .pan { display: block; }
.pan .strip { position: absolute; left: 0; top: 0; right: 0; will-change: transform; }
.pan img { position: absolute; left: 0; top: 0; width: 100%; display: block; }

/* reader text inside the phone */
.reader-col { will-change: transform; }
.v { font-size: 0.98rem; line-height: 1.72; margin-bottom: 0.55rem; }
.v sup {
  font-family: var(--sans);
  font-size: 0.58rem;
  opacity: 0.45;
  margin-right: 0.3rem;
}
.ps-title {
  font-family: var(--sans);
  font-size: 0.66rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  opacity: 0.5;
  margin: 1.3rem 0 0.8rem;
}

/* ---------- hero ---------- */
.hero {
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  position: relative;
  padding: 0 1.5rem;
}
.hero .anchor {
  font-family: var(--serif);
  font-style: italic;
  color: var(--mut);
  font-size: 1.0625rem;
  margin-bottom: 2.25rem;
}
.hero h1 {
  font-size: clamp(3rem, 9vw, 6.5rem);
  font-weight: 700;
  letter-spacing: -0.035em;
  line-height: 1.02;
}
.hero h1 .grad {
  color: transparent;
  background: var(--grad);
  -webkit-background-clip: text;
  background-clip: text;
}
.hero .elevator {
  margin: 2rem auto 0;
  max-width: 34rem;
  color: var(--mut);
  font-size: clamp(1.0625rem, 1.6vw, 1.25rem);
}
.hero .movements {
  margin-top: 2.75rem;
  font-size: 0.8125rem;
  font-weight: 650;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--gold);
}
.hero .hero-hint {
  margin-top: 0.9rem;
  font-size: 0.8125rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--mut);
}
.hero .cue {
  position: absolute;
  bottom: 2.25rem;
  left: 50%;
  transform: translateX(-50%);
  width: 1px;
  height: 3rem;
  background: linear-gradient(var(--faint), transparent);
  animation: cue 2.2s ease-in-out infinite;
}
.hero .cue-label {
  position: absolute;
  bottom: 100%;
  left: 50%;
  transform: translateX(-50%) translateY(6px);
  margin-bottom: 0.85rem;
  width: max-content;
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--gold);
  opacity: 0;
  transition: opacity 0.8s ease, transform 0.8s ease;
}
.hero .cue-label.show {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
  animation: cue-breathe 2.2s ease-in-out 0.8s infinite;
}
@keyframes cue-breathe {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.55; }
}
@keyframes cue {
  0%, 100% { transform: translateX(-50%) scaleY(0.6); opacity: 0.4; transform-origin: top; }
  50% { transform: translateX(-50%) scaleY(1); opacity: 1; }
}

/* ---------- dwell: spotlight + hyper focus + write ---------- */
#dwell .v { transition: none; }
.hyper-verse { font-size: 1.35rem; line-height: 1.9; }
.hyper-verse .w { opacity: 0.22; transition: none; }
.hyper-verse .w.lit { opacity: 1; color: var(--paper-accent); font-weight: 500; }
.phone.dusk .hyper-verse .w.lit { color: var(--dusk-accent); }

/* grammar word specimens: choice verbs with their marks drawn on by
   scroll, in the app's dusk-theme mark colors (made for dark ground) */
.spec-slot {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  pointer-events: none;
}
.specimen { position: absolute; opacity: 0; max-width: 26rem; }
.spec-word {
  position: relative;
  display: inline-block;
  font-family: var(--serif);
  font-size: 2.4rem;
  color: var(--ink);
  padding: 0 0.2em 0.35em 0.1em;
}
.spec-mark {
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 0.45em;
  overflow: visible;
}
.spec-mark .sm-line { stroke-width: 3; stroke-linecap: round; fill: none; }
.spec-mark .sm-cmd { stroke: #E08A7E; }
.spec-mark .sm-cmd-f { fill: #E08A7E; }
.spec-mark .sm-ink { stroke: #C9C5BB; }
.spec-mark .sm-ink-f { fill: #C9C5BB; }
.spec-wash {
  position: absolute;
  inset: 0.08em 0 0.3em 0;
  background: #2A5A54;
  border-radius: 6px;
  transform: scaleX(0);
  transform-origin: left;
  z-index: -1;
}
.spec-cap { color: var(--mut); font-size: 1.0625rem; margin-top: 0.75rem; }
.spec-cap em { font-family: var(--serif); color: var(--gold); font-style: normal; }
.spec-cap strong { color: var(--ink); }

/* the written word beside write mode's footage */
.lift-word {
  position: absolute;
  left: 15vw;
  top: 42%;
  width: min(170px, 13vw);
  color: var(--gold);
  opacity: 0;
}

/* ---------- understand ---------- */
/* grammar view marks (bloom in via --b set by JS) */
.gv { font-size: 1.15rem; line-height: 2.1; }
.gv .mark { position: relative; white-space: nowrap; }
.gv .mark::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0.05em;
  height: 2px;
  transform: scaleX(var(--b, 0));
  transform-origin: left;
}
.gv .cmd::after { background: #A8433A; box-shadow: 0 3px 0 -1px #A8433A; }
.gv .ongoing::after { background: #3D6E9E; }
.gv .tag {
  position: absolute;
  top: -1.15em;
  left: 0;
  font-family: var(--sans);
  font-size: 0.5rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  opacity: 0;
  transform: translateY(3px);
}
.gv .cmd .tag { color: #A8433A; }
.gv .ongoing .tag { color: #3D6E9E; }

/* interlinear */
.il-verse { font-size: 1.1rem; line-height: 1.8; margin-bottom: 1.4rem; }
.hold-ring {
  display: inline-block;
  position: relative;
}
.hold-ring::after {
  content: "";
  position: absolute;
  inset: -0.45em -0.55em;
  border-radius: 999px;
  border: 1.5px solid var(--paper-accent);
  opacity: 0;
  transform: scale(0.8);
}
.il-rows { display: flex; flex-wrap: wrap; gap: 0.9rem 1.1rem; }
.il-pair {
  opacity: 0;
  transform: translateY(10px);
  will-change: opacity, transform;
}
.il-pair .en { font-size: 0.95rem; display: block; }
.il-pair .gk {
  display: block;
  font-size: 0.85rem;
  color: var(--paper-accent);
  margin-top: 0.15rem;
}
.il-pair .ps {
  display: block;
  font-family: var(--sans);
  font-size: 0.55rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  opacity: 0.45;
  margin-top: 0.15rem;
}
.il-hairline { border: 0; border-top: 1px solid rgba(0,0,0,0.1); margin: 0 0 1.2rem; }

/* mobile constellation veil: darkens the sheet below the verse line
   so the fragments can surface inside the phone (JS-driven opacity;
   only ever raised on narrow viewports) */
.und-veil {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, transparent 16%, rgba(11, 12, 16, 0.55) 30%, rgba(11, 12, 16, 0.94) 42%);
  opacity: 0;
  pointer-events: none;
}

/* strong's constellation (outside the phone) */
.echoes { position: absolute; inset: 0; pointer-events: none; }
.echoes svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.echoes path {
  fill: none;
  stroke: url(#arcGrad);
  stroke-width: 1.2;
  opacity: 0;
}
.echo {
  position: absolute;
  width: 15rem;
  max-width: 34vw;
  font-family: var(--serif);
  font-size: 0.9rem;
  line-height: 1.5;
  color: var(--ink);
  opacity: 0;
  transform: translateY(12px);
  will-change: opacity, transform;
}
.echo .ref {
  display: block;
  font-family: var(--sans);
  font-size: 0.65rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--gold);
  margin-bottom: 0.3rem;
}
.echo em { color: var(--gold); font-style: normal; }

/* ---------- keep ---------- */
#keep .stage { flex-direction: column; text-align: center; padding: 0 1.5rem; }
.keep-verse {
  font-family: var(--serif);
  font-size: clamp(1.6rem, 4vw, 2.9rem);
  line-height: 1.65;
  max-width: 46rem;
}
.keep-verse .w {
  transition: opacity 0.45s;
  border-bottom: 2px solid transparent;
}
.keep-verse .w.gone {
  opacity: 0.07;
  border-bottom-color: rgba(242, 241, 236, 0.18);
}
.keep-ref { margin-top: 1.5rem; color: var(--faint); font-size: 0.875rem; letter-spacing: 0.12em; }
.keep-note {
  margin-top: 2.5rem;
  color: var(--mut);
  font-size: 1.0625rem;
  max-width: 28rem;
}
.round-dots { display: flex; gap: 0.5rem; justify-content: center; margin-top: 1.25rem; }
.round-dots i {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--faint);
  opacity: 0.35;
  transition: opacity 0.3s, background 0.3s;
}
.round-dots i.on { opacity: 1; background: var(--gold); }
#keepNote { opacity: 0; will-change: opacity, transform; }

/* the real memory game, second act of the Keep scene */
.keep-phone {
  position: absolute;
  left: 50%;
  top: 44%;
  transform: translate(-50%, -50%);
  opacity: 0;
  width: min(300px, 38vw);
}
.keep-phone .screen { background: var(--dusk-bg); }
.keep-app-note {
  opacity: 0;
  position: absolute;
  left: 50%;
  bottom: 5%;
  transform: translateX(-50%);
  width: min(34rem, 88vw);
}
/* ---------- abide ---------- */
#abide .stage { flex-direction: column; text-align: center; padding: 0 1.5rem; }
.door-wrap { perspective: 1100px; will-change: transform, opacity; }
.door-frame {
  margin: 0 auto;
  width: 11rem; height: 17rem;
  border: 1.5px solid rgba(242, 241, 236, 0.5);
  border-radius: 7rem 7rem 0 0;
  position: relative;
  overflow: hidden;
  background: radial-gradient(ellipse at 50% 20%, rgba(200, 169, 106, 0.22), transparent 70%);
}
.door-leaf {
  position: absolute;
  inset: 0;
  background: #101116;
  border-radius: 7rem 7rem 0 0;
  border: 1.5px solid rgba(242, 241, 236, 0.35);
  transform-origin: left center;
  will-change: transform;
}
.door-leaf::after {
  content: "";
  position: absolute;
  right: 0.9rem; top: 52%;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: rgba(242, 241, 236, 0.6);
}
.abide-copy-top { margin-bottom: 2.5rem; }
.plan-card {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  opacity: 0;
  will-change: opacity, transform;
  padding: 0 1.5rem;
}
.plan-card .duo { text-align: left; }

/* one button, three states: open door → closed door → heart */
.door-stages {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-bottom: 1.5rem;
  color: var(--faint);
}
.door-stages .stg {
  width: 40px;
  height: 40px;
  border-radius: 999px;
  border: 1px solid var(--hairline);
  display: grid;
  place-items: center;
  transition: color 0.35s, border-color 0.35s, box-shadow 0.35s;
}
.door-stages .stg svg { width: 19px; height: 19px; }
.door-stages .stg.on {
  color: var(--gold);
  border-color: rgba(200, 169, 106, 0.55);
  box-shadow: 0 0 16px rgba(200, 169, 106, 0.18);
}
.door-stages .sep { width: 16px; height: 1px; background: var(--hairline); }
.plan-card .plan-name {
  font-size: 0.75rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--gold);
}
.plan-card .plan-day {
  font-family: var(--serif);
  font-size: clamp(1.75rem, 3.5vw, 2.5rem);
  margin-top: 0.75rem;
}
.plan-card .plan-refs { color: var(--mut); margin-top: 0.5rem; }
.plan-card .heart {
  margin-top: 2.25rem;
  width: 44px; height: 44px;
}
.plan-card .heart path {
  fill: rgba(200, 169, 106, 0);
  stroke: var(--gold);
  stroke-width: 1.5;
  transition: fill 0.6s;
}
.plan-card.done .heart path { fill: rgba(200, 169, 106, 0.85); }
.plan-card .after { margin-top: 1.5rem; color: var(--mut); max-width: 24rem; font-size: 1rem; }

/* the ring that points at the door/heart button in the real footage;
   positioned AND sized by JS with the same cover math the canvas
   draws with, so it hugs the button at any viewport */
.abide-ring {
  position: absolute;
  border-radius: 50%;
  border: 1.5px solid rgba(200, 169, 106, 0.9);
  box-shadow:
    0 0 14px rgba(200, 169, 106, 0.4),
    inset 0 0 10px rgba(200, 169, 106, 0.15);
  transform: translate(-50%, -50%);
  opacity: 0;
  pointer-events: none;
  z-index: 4;
  animation: abide-ring-breathe 2.6s ease-in-out infinite;
}
@keyframes abide-ring-breathe {
  0%, 100% { box-shadow: 0 0 10px rgba(200, 169, 106, 0.3), inset 0 0 8px rgba(200, 169, 106, 0.12); }
  50% { box-shadow: 0 0 20px rgba(200, 169, 106, 0.55), inset 0 0 12px rgba(200, 169, 106, 0.22); }
}
@media (prefers-reduced-motion: reduce) {
  .abide-ring { animation: none; }
}

/* the scene's last words: the one place the copy names the reward
   (see messaging.md) — inline with the closer, gold */
.abide-reward { color: var(--gold); }


/* ---------- the quiet ---------- */
#quiet .stage { flex-direction: column; text-align: center; padding: 0 1.5rem; }
.quiet-line {
  font-size: clamp(1.5rem, 3.4vw, 2.5rem);
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--faint);
  line-height: 1.9;
  will-change: opacity, color;
}
.quiet-free {
  margin-top: 3rem;
  font-size: clamp(1.75rem, 4vw, 3rem);
  font-weight: 700;
  letter-spacing: -0.025em;
  will-change: opacity, transform;
}
.quiet-free .grad {
  color: transparent;
  background: var(--grad);
  -webkit-background-clip: text;
  background-clip: text;
}
.quiet-sub { margin-top: 1rem; color: var(--mut); font-size: 1rem; }
.quiet-sub a { color: var(--green); text-decoration: none; }
.quiet-sub a:hover { text-decoration: underline; }


/* ---------- close / footer ---------- */
.close {
  min-height: 90vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 6rem 1.5rem 3rem;
}
.close h2 { font-size: clamp(2.25rem, 6vw, 4rem); font-weight: 700; letter-spacing: -0.03em; }
.close .sub { color: var(--mut); margin-top: 1.25rem; max-width: 28rem; }
.cta {
  display: inline-block;
  margin-top: 2.5rem;
  padding: 0.9rem 2.2rem;
  border-radius: 999px;
  background: var(--grad);
  color: #0B0C10;
  font-weight: 650;
  text-decoration: none;
  font-size: 1.0625rem;
}
footer {
  margin-top: 7rem;
  padding-top: 2rem;
  border-top: 1px solid var(--hairline);
  color: var(--faint);
  font-size: 0.8125rem;
  max-width: 40rem;
  line-height: 1.8;
}
footer a { color: var(--mut); text-decoration: none; }
footer a:hover { text-decoration: underline; }
footer .links { margin-top: 0.5rem; }
footer .links a { margin: 0 0.6rem; }

/* ---------- responsive: the mobile stage ----------
   ≤900px, duo scenes stop stacking (the column never fit a phone
   viewport). Instead: the app phone is a centered backdrop sized to
   always fit, and the copy becomes a caption in the dark band above
   it. Copy children are pinned with the `translate` property so the
   beat fader's inline `transform` still animates them. */
@media (max-width: 900px) {
  .duo {
    display: flex;
    flex-direction: column;
    align-items: center;
    height: 100%;
    width: 100%;
    max-width: none;
    gap: 0;
    padding: calc(env(safe-area-inset-top) + 0.75rem) 1.25rem 1rem;
    text-align: center;
  }
  .duo .copy {
    flex: none;
    position: relative;
    width: 100%;
    min-height: unset;
    height: 28svh;
  }
  .duo .copy .stack { position: absolute; inset: 0; display: block; }
  .duo .copy .stack > * {
    position: absolute;
    left: 0;
    right: 0;
    margin: 0;
  }
  .duo .copy .stack > .numeral { top: 0; }
  /* side padding keeps the headline clear of the corner pill's zone */
  .duo .copy .stack > h2 { top: 1.5rem; padding: 0 2.6rem; }
  .duo .copy .stack > p { top: 64%; translate: 0 -50%; max-width: none; }
  /* pinned to the top of the band so long paragraphs (centered at 64%)
     never climb up behind the icons */
  .duo .copy .stack > .door-stages {
    top: 0;
    translate: none;
    justify-content: center;
  }
  /* as large as the screen honestly allows: bounded by the height
     budget (band + paddings), by width via the aspect ratio (185vw
     ≈ height at which width hits ~90vw), and by a sanity cap */
  /* svh, not dvh: the URL bar's collapse mid-scroll must never resize
     the phone (it read as the phone growing between beats) */
  .duo .phone {
    flex: none;
    width: auto;
    height: min(65svh, 185vw, 700px);
    margin-top: 0.5rem;
  }
  .spec-slot { position: absolute; inset: 0; }
  .specimen { left: 0; right: 0; top: 64%; translate: 0 -50%; max-width: none; }
  .spec-word { font-size: 1.9rem; }
  .spec-cap { font-size: 0.9375rem; }
  .copy p { font-size: 0.9375rem; }
  h2 { font-size: 1.35rem; }
  .numeral { font-size: 0.7rem; }
  /* constellation, restaged: fragments surface inside the darkened
     sheet at the end of the descending thread (positions set by JS) */
  .echo { width: min(74vw, 300px); font-size: 0.875rem; }
  /* the written word rides the empty lower half of the write-mode
     frames — gold, matching the dusk footage's accent (same ink as
     desktop). Low enough to clear the passage text above it. */
  .lift-word {
    display: block;
    left: 50%;
    top: 72%;
    translate: -50% 0;
    width: 72px;
    z-index: 3;
    filter: none;
  }
  .keep-verse { font-size: clamp(1.35rem, 6vw, 1.8rem); }
  .keep-phone {
    width: auto;
    height: min(56svh, 165vw, 620px);
    top: 41%;
  }
  .keep-app-note { font-size: 0.9375rem; bottom: 3%; }
  .close { padding-bottom: calc(1.5rem + env(safe-area-inset-bottom)); }
}

/* svh: the *small* (stable) mobile viewport, so the URL bar's collapse
   mid-scroll never changes scene geometry or restages a scene under the
   visitor's finger (identical to vh on desktop; dvh — the dynamic
   viewport — resizes with the bar, which is exactly the jank) */
@supports (height: 100svh) {
  .scene { height: calc(var(--len, 4) * 100svh); }
  .stage { height: 100svh; }
  .hero { height: 100svh; }
}

/* ---------- reduced motion: static frames ---------- */
@media (prefers-reduced-motion: reduce) {
  .scene { height: auto; }
  .stage { position: relative; height: auto; min-height: 88vh; padding: 4rem 0; overflow: visible; }
  .hero .cue { animation: none; }
  .hero .cue-label.show { animation: none; }
}
