/*
 * Provinans case study — academic restyle of the scroll-journey house style.
 * Self-contained (no framework). Biome colors arrive as CSS variables set by
 * main.js. The geometry language is deliberately calm: straight drafting
 * planes, low-amplitude strata, hairline rules, rectangular cards. Accents are
 * desaturated archival hues; the parchment glow is the warmest thing on screen.
 */

/* Aeonik (CoType Foundry, commercial) loads from the app's shared /fonts/, the
   same source src/index.css uses. Those files are gitignored and excluded from
   the Space upload, so they are never redistributed; served from the app origin
   they render in dev, and a deploy without them falls through the stack below to
   a system grotesque. The bundled weights are Regular (400), Medium (500-600),
   and Bold (700); the page's lighter 300 headings render Regular. */
@font-face {
  font-family: "Aeonik";
  src: url("/fonts/Aeonik-Regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Aeonik";
  src: url("/fonts/Aeonik-Medium.woff2") format("woff2");
  font-weight: 500 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Aeonik";
  src: url("/fonts/Aeonik-Bold.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

/* Computer Modern Serif, self-hosted under ./fonts (the LaTeX face, so the page reads as a research
   paper). Roman/bold/italic/bold-italic; anything unbundled falls through to a system serif. */
@font-face {
  font-family: "Computer Modern";
  src: url("./fonts/cmunrm.woff") format("woff");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Computer Modern";
  src: url("./fonts/cmunbx.woff") format("woff");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Computer Modern";
  src: url("./fonts/cmunti.woff") format("woff");
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: "Computer Modern";
  src: url("./fonts/cmunbi.woff") format("woff");
  font-weight: 700;
  font-style: italic;
  font-display: swap;
}

/* The paper's body face and its label face. Computer Modern carries the prose, headings, and tables;
   Aeonik stays for the tracked uppercase micro-labels (eyebrows, station ticks), where Computer Modern's
   letterforms read oddly under wide tracking. */
:root {
  --serif: "Computer Modern", "Latin Modern Roman", Georgia, "Times New Roman", serif;
  --label: "Aeonik", "Helvetica Neue", Arial, sans-serif;
}

:root {
  color-scheme: dark;
  /* Defaults mirror the "home" (arrival) biome so the pre-JS paint matches. */
  --bg-top: #171a20;
  --bg-bottom: #0b0d11;
  --glow: #d9cfb8;
  --mote: #cfc5aa;
  --terrain: #12151b;
  --ink: rgba(255, 255, 255, 0.94);
  --ink-dim: rgba(255, 255, 255, 0.7);
  --ink-meta: rgba(255, 255, 255, 0.52);
  --card: rgba(8, 10, 13, 0.55);
  --hairline: rgba(255, 255, 255, 0.13);
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  font-family: var(--serif);
  color: var(--ink);
  background: var(--bg-bottom);
  overflow-x: hidden;
  /* Computer Modern is a hair light on a dark ground; a whisper of weight keeps the thin strokes legible. */
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  transition: background-color 900ms ease;
}

/* The light "paper" biome (main.js adds body.light) flips the ink to dark on the warm page, so the story
   moves from the dark archive into a lit page and back. */
body.light {
  --ink: rgba(28, 23, 16, 0.92);
  --ink-dim: rgba(28, 23, 16, 0.66);
  --ink-meta: rgba(28, 23, 16, 0.46);
  --card: rgba(255, 255, 255, 0.55);
  --hairline: rgba(28, 23, 16, 0.16);
  --bg-bottom: #e3dccb;
}

/* Custom properties do not transition, so transition color on the elements that read the ink; the dark to
   light change then rides the ~900ms backdrop crossfade instead of snapping. */
.eyebrow,
h1,
h2,
h3,
.prose p,
.prose li,
.hero-wordmark,
.hero-byline,
.hero-typed,
.intro-label,
.intro p,
blockquote.pull p,
.stats-sub,
.stats-foot,
.ctx-list,
.cap-list,
.ref-list,
.ledge span,
.ledge strong,
.study-table caption,
.study-table th,
.study-table td {
  transition: color 800ms ease;
}

/* ---------- Biome backdrop (two layers crossfade on biome change) ---------- */

.backdrop {
  position: fixed;
  inset: 0;
  z-index: -2;
  opacity: 0;
  transition: opacity 900ms ease;
  background:
    radial-gradient(58% 42% at 50% 10%, color-mix(in srgb, var(--l-glow) 14%, transparent), transparent 70%),
    linear-gradient(180deg, var(--l-top) 0%, var(--l-bottom) 100%);
}

.backdrop.active {
  opacity: 1;
}

.grain {
  position: fixed;
  inset: 0;
  z-index: 40;
  pointer-events: none;
  opacity: 0.05;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ------------------------------ Typography ------------------------------ */

.eyebrow {
  font-family: var(--label);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-meta);
  margin: 0 0 14px;
}

h1 {
  font-weight: 300;
  font-size: clamp(34px, 4.4vw, 54px);
  line-height: 1.12;
  letter-spacing: -0.01em;
  margin: 0 0 20px;
}

h2 {
  font-weight: 400;
  font-size: clamp(24px, 3vw, 34px);
  line-height: 1.18;
  margin: 0 0 18px;
}

p {
  line-height: 1.6;
}

/* ------------------- 1. Hero (aperture of drafting planes) ------------------- */

.hero {
  position: relative;
  min-height: 76vh;
  display: grid;
  place-items: center;
  overflow: hidden;
  padding: 13vh 24px 9vh;
}

/* A compact two-column title block: the paper's title and typed thesis on the left, an abstract on the
   right, rather than a full-screen centered hero. Conserves the first screen for reading. */
.hero-grid {
  position: relative;
  z-index: 3;
  width: min(1040px, 100%);
  display: grid;
  grid-template-columns: 1.4fr 1fr;
  column-gap: clamp(28px, 5vw, 64px);
  row-gap: 0;
  align-items: end;
}

/* The masthead: the Provinans mark and wordmark on their own line above the title block. Spans both
   columns so the two-column title/introduction sits beneath it. */
.hero-brand {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  gap: 13px;
  margin-bottom: clamp(26px, 4vh, 46px);
}
.hero-logo {
  width: clamp(34px, 3.4vw, 46px);
  height: auto;
  opacity: 0.96;
}
.hero-wordmark {
  font-family: var(--label);
  font-size: clamp(23px, 2.5vw, 31px);
  font-weight: 500;
  letter-spacing: 0.01em;
  color: var(--ink);
}

.hero-lede {
  min-width: 0;
}

.hero-lede h1 {
  font-size: clamp(29px, 3.5vw, 46px);
  margin: 0 0 16px;
}

.hero-typed {
  font-style: italic;
  font-size: clamp(16px, 1.6vw, 20px);
  line-height: 1.5;
  color: var(--ink-dim);
  max-width: 46ch;
  min-height: 1.5em;
  margin: 0 0 18px;
}

.hero-byline {
  font-family: var(--label);
  font-size: 12.5px;
  letter-spacing: 0.01em;
  color: var(--ink-meta);
  margin: 0;
}

/* The introduction sits in a ruled block (top and bottom rule, no box), the way a paper heads it. */
.intro {
  border-top: 1.5px solid color-mix(in srgb, var(--ink) 42%, transparent);
  border-bottom: 1.5px solid color-mix(in srgb, var(--ink) 42%, transparent);
  padding: 15px 0 17px;
}

.intro-label {
  font-family: var(--label);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-meta);
  margin: 0 0 10px;
}

.intro p:last-child {
  font-size: 14px;
  line-height: 1.62;
  color: var(--ink-dim);
  margin: 0;
}

/* The typewriter caret trailing the typed thesis (main.js drives the text; CSS blinks the bar). */
.type-caret {
  display: inline-block;
  width: 2px;
  height: 1em;
  margin-left: 2px;
  background: var(--glow);
  vertical-align: -0.12em;
  animation: type-blink 1s step-end infinite;
}
.type-caret.done {
  display: none;
}
@keyframes type-blink {
  0%,
  100% {
    opacity: 0.9;
  }
  50% {
    opacity: 0;
  }
}

@media (max-width: 820px) {
  .hero-grid {
    grid-template-columns: 1fr;
    gap: 26px;
    align-items: start;
  }
}

/* Aperture frame: four straight-edged planes, mat-board rather than cave rock. */
.cave {
  position: absolute;
  z-index: 2;
  background: var(--terrain);
  filter: brightness(0.82);
  transition: background-color 900ms ease;
}

.cave-tl {
  top: -12vh;
  left: -14vw;
  width: 50vw;
  height: 56vh;
  clip-path: polygon(0 0, 100% 0, 66% 28%, 30% 60%, 10% 84%, 0 96%);
}

.cave-tr {
  top: -12vh;
  right: -16vw;
  width: 52vw;
  height: 58vh;
  clip-path: polygon(0 0, 100% 0, 100% 100%, 76% 74%, 46% 44%, 18% 16%);
}

.cave-bl {
  bottom: -14vh;
  left: -12vw;
  width: 46vw;
  height: 50vh;
  clip-path: polygon(0 0, 28% 24%, 60% 54%, 100% 100%, 0 100%);
}

.cave-br {
  bottom: -14vh;
  right: -12vw;
  width: 48vw;
  height: 52vh;
  clip-path: polygon(100% 0, 100% 100%, 0 100%, 40% 62%, 72% 30%);
}

/* Light shafts: reading-room light through the aperture, dim and narrow. */
.rays {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
}

.rays span {
  position: absolute;
  top: -18%;
  left: 50%;
  width: 9vw;
  height: 84vh;
  background: linear-gradient(
    180deg,
    color-mix(in srgb, var(--glow) 15%, transparent),
    transparent 76%
  );
  transform-origin: top center;
  filter: blur(8px);
}

.rays span:nth-child(1) {
  transform: translateX(-74%) rotate(10deg);
}
.rays span:nth-child(2) {
  transform: translateX(-46%) rotate(3deg);
  width: 12vw;
}
.rays span:nth-child(3) {
  transform: translateX(2%) rotate(-7deg);
}

/* Dust motes: fewer, smaller, slower than fireflies. */
.motes {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
}

.mote {
  position: absolute;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--mote);
  box-shadow: 0 0 8px 1px color-mix(in srgb, var(--mote) 45%, transparent);
  opacity: 0;
  animation:
    mote-drift var(--dur, 14s) ease-in-out var(--delay, 0s) infinite alternate,
    mote-flicker calc(var(--dur, 14s) / 2.6) ease-in-out var(--delay, 0s) infinite alternate;
}

@keyframes mote-drift {
  from {
    transform: translate(0, 0);
  }
  to {
    transform: translate(var(--dx, 8px), var(--dy, -28px));
  }
}

@keyframes mote-flicker {
  0% {
    opacity: 0.1;
  }
  60% {
    opacity: 0.55;
  }
  100% {
    opacity: 0.25;
  }
}

.scroll-cue {
  position: absolute;
  bottom: 26px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 3;
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-meta);
  animation: cue-bob 2.6s ease-in-out infinite;
}

@keyframes cue-bob {
  0%,
  100% {
    transform: translate(-50%, 0);
  }
  50% {
    transform: translate(-50%, 6px);
  }
}

/* ---------------------- 2. Descent (sediment strata) ---------------------- */

.descent {
  position: relative;
  min-height: 140vh;
  overflow: hidden;
  display: grid;
  place-items: center;
  padding: 18vh 24px;
}

/* Low-amplitude strata: long wavelengths, no peaks. Archive shelving, not mountains. */
.ridge {
  position: absolute;
  left: -10vw;
  width: 120vw;
  height: 42vh;
  background: var(--terrain);
  will-change: transform;
  transition: background-color 900ms ease;
}

.ridge-far {
  bottom: 30vh;
  opacity: 0.45;
  clip-path: polygon(0 66%, 18% 60%, 42% 66%, 66% 56%, 100% 62%, 100% 100%, 0 100%);
}

.ridge-mid {
  bottom: 12vh;
  opacity: 0.7;
  clip-path: polygon(0 56%, 22% 62%, 50% 52%, 78% 60%, 100% 54%, 100% 100%, 0 100%);
}

.ridge-near {
  bottom: -6vh;
  clip-path: polygon(0 60%, 30% 52%, 58% 60%, 84% 50%, 100% 56%, 100% 100%, 0 100%);
}

.copy-card {
  position: relative;
  z-index: 2;
  max-width: 540px;
  background: var(--card);
  border: 1px solid var(--hairline);
  border-radius: 12px;
  padding: 34px 36px;
  backdrop-filter: blur(10px);
}

.copy-card p:last-child {
  color: var(--ink-dim);
  margin-bottom: 0;
}

/* --------------------------- Prose and quotations --------------------------- */

.prose {
  max-width: 680px;
  margin: 0 auto;
  padding: 8vh 24px;
}

.prose h2 {
  margin: 0 0 26px;
}

.prose p {
  font-size: 17px;
  line-height: 1.75;
  color: var(--ink-dim);
  margin: 0 0 28px;
}

.prose p:last-child {
  margin-bottom: 0;
}

/* Pull quote: hairline rule with a brighter head tick, Light weight, no chrome. */
blockquote.pull {
  margin: 46px 0;
  padding: 4px 0 4px 30px;
  position: relative;
  border-left: 1px solid color-mix(in srgb, var(--glow) 55%, transparent);
  transition: border-color 900ms ease;
}

blockquote.pull::before {
  content: "";
  position: absolute;
  left: -1px;
  top: 0;
  width: 1px;
  height: 36px;
  background: var(--glow);
  transition: background-color 900ms ease;
}

blockquote.pull p {
  font-weight: 300;
  font-size: 21px;
  line-height: 1.55;
  color: var(--ink);
  margin: 0;
}

/* A single display sentence given a full beat of its own. */
.pivot {
  min-height: 64vh;
  display: grid;
  place-items: center;
  text-align: center;
  padding: 24px;
}

.pivot p {
  font-weight: 300;
  font-size: clamp(26px, 3.2vw, 40px);
  line-height: 1.28;
  max-width: 24ch;
  color: var(--ink);
  margin: 0;
}

/* Scroll reveal shared by quotes, pivots, and ledges. */
.reveal {
  opacity: 0;
  transform: translateY(20px);
  transition:
    opacity 700ms ease,
    transform 700ms ease;
}

.reveal.in {
  opacity: 1;
  transform: translateY(0);
}

/* ------------------------ Booktabs-style study tables ------------------------ */
/* A heavy top and bottom rule, a hairline under the header, no vertical lines: the LaTeX booktabs look that
   reads as a research paper. Numeric columns align right on tabular figures. */
.study-table {
  margin: 40px 0;
  max-width: 100%;
  overflow-x: auto;
}
.study-table table {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
  line-height: 1.5;
}
.study-table caption {
  caption-side: top;
  text-align: left;
  font-style: italic;
  font-size: 13px;
  color: var(--ink-meta);
  margin-bottom: 12px;
}
.study-table thead th {
  text-align: left;
  font-weight: 700;
  color: var(--ink);
  padding: 8px 18px 8px 0;
  border-top: 1.5px solid color-mix(in srgb, var(--ink) 58%, transparent);
  border-bottom: 1px solid var(--hairline);
  vertical-align: bottom;
  transition: border-color 900ms ease;
}
.study-table tbody th,
.study-table tbody td {
  padding: 11px 18px 11px 0;
  color: var(--ink-dim);
  vertical-align: top;
  border-bottom: 1px solid color-mix(in srgb, var(--hairline) 55%, transparent);
}
.study-table tbody th {
  font-weight: 700;
  color: var(--ink);
  white-space: nowrap;
}
.study-table tbody tr:last-child th,
.study-table tbody tr:last-child td {
  border-bottom: 1.5px solid color-mix(in srgb, var(--ink) 58%, transparent);
}
.study-table .num {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.study-table th:last-child,
.study-table td:last-child {
  padding-right: 0;
}

/* A paper screenshot as a captioned figure, constrained so it reads as a side exhibit rather than a wall. */
.paper-figure {
  margin: 40px auto;
  max-width: 360px;
  text-align: center;
}
.paper-figure img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 4px;
  border: 1px solid var(--hairline);
  box-shadow: 0 12px 34px rgba(0, 0, 0, 0.36);
}
.paper-figure figcaption {
  margin-top: 12px;
  font-style: italic;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--ink-meta);
}

/* Section 03 carries the light background itself (the paper biome), so the transparent specimen figure needs
   no card. It floats into the column and the closing prose wraps around it. */
.stats-tissue {
  max-width: 720px;
  margin: 6vh auto 0;
  overflow: hidden; /* contain the float so the wrapper spans the figure */
}
.tissue-figure {
  float: right;
  width: 248px;
  margin: 4px 0 16px 34px;
}
.tissue-figure img {
  display: block;
  width: 100%;
  height: auto;
}
.tissue-figure figcaption {
  margin-top: 12px;
  font-style: italic;
  font-size: 11.5px;
  line-height: 1.5;
  color: var(--ink-meta);
}
.stats-tissue .stats-foot {
  max-width: none;
  margin: 0;
}
@media (max-width: 640px) {
  .tissue-figure {
    float: none;
    width: 100%;
    max-width: 300px;
    margin: 0 auto 22px;
  }
}

/* ------------------------------ In-prose lists ------------------------------ */
.ctx-list,
.cap-list {
  color: var(--ink-dim);
  font-size: 16px;
  line-height: 1.7;
}
.ctx-list {
  margin: 22px 0 28px;
  padding-left: 22px;
}
.ctx-list li {
  margin: 0 0 12px;
  padding-left: 4px;
}
.ctx-list strong,
.cap-list strong {
  color: var(--ink);
  font-weight: 700;
}
.cap-list {
  margin: 14px 0 26px;
  padding-left: 22px;
}
.cap-list li {
  margin: 0 0 7px;
}
.cap-list.two-col {
  columns: 2;
  column-gap: 44px;
}
@media (max-width: 640px) {
  .cap-list.two-col {
    columns: 1;
  }
}

/* -------------------------------- References -------------------------------- */
.references {
  padding-bottom: 4vh;
}
.ref-list {
  margin: 6px 0 0;
  padding-left: 26px;
  color: var(--ink-dim);
  font-size: 14px;
  line-height: 1.62;
}
.ref-list li {
  margin: 0 0 12px;
  padding-left: 6px;
}

/* --------------------- Section 03 head and foot (stats) --------------------- */
.stats-head {
  max-width: 680px;
  margin: 0 auto 7vh;
}
.stats-sub {
  font-size: 17px;
  line-height: 1.72;
  color: var(--ink-dim);
  margin: 0 0 6px;
}
.stats-foot {
  max-width: 680px;
  margin: 7vh auto 0;
  font-size: 16px;
  line-height: 1.75;
  color: var(--ink-dim);
}

/* --------------------- The margin rail (paper companion) --------------------- */

/*
 * A persistent margin object beside the transcript: an argument timeline and a
 * paper stack that re-composes as [data-station] markers cross the viewport's
 * middle band (main.js sets data-scene on #rail). One traveling object, never
 * a teleport: every scene is a transform/opacity state of the same elements.
 * Supplementary only — hidden below 1100px, all content lives in the prose.
 */

.rail {
  display: none;
}

@media (min-width: 1100px) {
  .rail-track {
    display: grid;
    grid-template-columns: minmax(0, 680px) 220px;
    justify-content: center;
    column-gap: 56px;
  }
  .rail-flow {
    min-width: 0;
  }
  .rail {
    display: block;
    position: relative;
  }
  .rail-inner {
    position: sticky;
    top: 16vh;
    padding: 8px 0;
  }
}

/* The argument timeline: a spine of stations, filled as far as the story has gone. */
.rail-stations {
  list-style: none;
  margin: 0 0 30px;
  padding: 0 0 0 16px;
  border-left: 1px solid var(--hairline);
  display: grid;
  gap: 14px;
}

.rail-stations li {
  position: relative;
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-meta);
  transition: color 400ms ease;
}

.rail-stations li::before {
  content: "";
  position: absolute;
  left: -16px;
  top: 50%;
  width: 9px;
  height: 1px;
  background: var(--hairline);
  transition: background-color 400ms ease;
}

/* Passed stations brighten; the active station carries the glow. */
.rail[data-scene="2"] .rail-stations li:nth-child(-n + 1),
.rail[data-scene="3"] .rail-stations li:nth-child(-n + 2),
.rail[data-scene="4"] .rail-stations li:nth-child(-n + 3),
.rail[data-scene="5"] .rail-stations li:nth-child(-n + 4) {
  color: var(--ink-dim);
}

.rail[data-scene="1"] .rail-stations li:nth-child(1),
.rail[data-scene="2"] .rail-stations li:nth-child(2),
.rail[data-scene="3"] .rail-stations li:nth-child(3),
.rail[data-scene="4"] .rail-stations li:nth-child(4),
.rail[data-scene="5"] .rail-stations li:nth-child(5) {
  color: var(--glow);
}

.rail[data-scene="1"] .rail-stations li:nth-child(1)::before,
.rail[data-scene="2"] .rail-stations li:nth-child(-n + 2)::before,
.rail[data-scene="3"] .rail-stations li:nth-child(-n + 3)::before,
.rail[data-scene="4"] .rail-stations li:nth-child(-n + 4)::before,
.rail[data-scene="5"] .rail-stations li:nth-child(-n + 5)::before {
  background: var(--glow);
}

.rail-stack {
  display: block;
  width: 100%;
  height: auto;
  margin-bottom: 14px;
}

.rail-caption {
  font-size: 11px;
  letter-spacing: 0.04em;
  color: var(--ink-meta);
  min-height: 2em;
  margin: 0;
}

.rail-caption span {
  display: none;
}

.rail[data-scene="1"] [data-cap="1"],
.rail[data-scene="2"] [data-cap="2"],
.rail[data-scene="3"] [data-cap="3"],
.rail[data-scene="4"] [data-cap="4"],
.rail[data-scene="5"] [data-cap="5"] {
  display: inline;
}

/* ---- Stack drawing: stroke roles (shared with the traverse glyphs below) ---- */

.rail-stack *,
.layer-glyph * {
  vector-effect: non-scaling-stroke;
}

.rail-stack line,
.rail-stack rect,
.rail-stack path,
.layer-glyph line,
.layer-glyph rect,
.layer-glyph path {
  stroke-width: 1;
  fill: none;
  transition:
    stroke 900ms ease,
    fill 900ms ease;
}

.g-hair,
.rail-stack .s-base,
.rail-stack .t-grid line,
.rail-stack .t-bars line,
.rail-stack .sheet line {
  stroke: var(--hairline);
}

.g-outline,
.rail-stack .t-outline,
.rail-stack .t-bars rect,
.rail-stack .sheet rect {
  stroke: color-mix(in srgb, var(--ink) 45%, transparent);
}

/* Sheets are silhouette cards (the ledge recipe) so the fan occludes cleanly. */
.rail-stack .sheet rect {
  fill: var(--terrain);
}

.g-accent,
.rail-stack .t-break {
  stroke: color-mix(in srgb, var(--glow) 70%, transparent);
}

.g-fill,
.rail-stack .t-c1,
.rail-stack .t-c2,
.rail-stack .t-c3 {
  fill: color-mix(in srgb, var(--glow) 12%, transparent);
  stroke: none;
}

.g-shade {
  fill: color-mix(in srgb, var(--glow) 8%, transparent);
  stroke: none;
}

.g-dash,
.g-dashline,
.rail-stack .t-cdash {
  stroke: var(--ink-meta);
  stroke-dasharray: 3 4;
}

.rail-stack .s-x {
  stroke: var(--ink-dim);
}

.rail-stack .q {
  fill: var(--glow);
  font-size: 15px;
  font-weight: 300;
  transition:
    opacity 700ms ease,
    fill 900ms ease;
}

/* ------------------------- Stack scenes (cumulative) ------------------------- */

.rail-stack .sheet {
  transform-box: fill-box;
  transform-origin: 50% 100%;
  transition:
    transform 700ms ease,
    opacity 700ms ease;
}

.rail-stack .stack-table,
.rail-stack .t-grid,
.rail-stack .t-bars,
.rail-stack .t-c1,
.rail-stack .t-c2,
.rail-stack .t-c3,
.rail-stack .t-cdash {
  transition:
    opacity 700ms ease,
    stroke-dasharray 700ms ease,
    stroke 900ms ease,
    fill 900ms ease;
}

/* Scene 1 — the archive: sheets fanned, no dataset in sight. */
.rail[data-scene="1"] .sheet-1 { transform: translate(-6px, 0) rotate(-10deg); }
.rail[data-scene="1"] .sheet-2 { transform: translate(-2px, 0) rotate(-4deg); }
.rail[data-scene="1"] .sheet-3 { transform: rotate(2deg); }
.rail[data-scene="1"] .sheet-4 { transform: translate(4px, 0) rotate(7deg); }
.rail[data-scene="1"] .sheet-5 { transform: translate(9px, 0) rotate(12deg); }
.rail[data-scene="1"] .stack-table { opacity: 0; }

/* Scene 2 — the turn: the dataset appears as a dashed ghost; sheets square up. */
.rail[data-scene="2"] .t-outline { stroke-dasharray: 3 4; stroke: var(--ink-meta); }
.rail[data-scene="2"] .t-grid { opacity: 0; }

/* Scene 3 — abstraction: one sheet crosses into the table; the first cell fills. */
.rail:is([data-scene="3"], [data-scene="4"], [data-scene="5"]) .sheet-3 {
  transform: translate(58px, -46px);
  opacity: 0;
}

/* Scene 4 — frameworks: a second sheet is consumed; the framework bars split. */
.rail:is([data-scene="4"], [data-scene="5"]) .sheet-2 {
  transform: translate(58px, -30px);
  opacity: 0;
}

/* Scene 5 — deterioration: the marked sheet raises its question. */
.rail[data-scene="5"] .sheet-5 { transform: translate(2px, -6px); }

/* Elements hidden until their scene arrives. */
.rail:is([data-scene="1"], [data-scene="2"]) .t-c1,
.rail:is([data-scene="1"], [data-scene="2"], [data-scene="3"]) .t-c2,
.rail:is([data-scene="1"], [data-scene="2"], [data-scene="3"]) .t-cdash,
.rail:is([data-scene="1"], [data-scene="2"], [data-scene="3"]) .t-bars,
.rail:not([data-scene="5"]) .t-c3,
.rail:not([data-scene="5"]) .q {
  opacity: 0;
}

/* -------------------- 3. Stats in terrain (light shaft) -------------------- */

.stats {
  position: relative;
  padding: 14vh 8vw 18vh;
  overflow: hidden;
}

.stats-title {
  margin: 0 0 16px;
}

.falls {
  position: absolute;
  top: 8vh;
  bottom: 0;
  left: 50%;
  width: 12vw;
  transform: translateX(-58%) skewX(-3deg);
  background: linear-gradient(
    180deg,
    color-mix(in srgb, var(--glow) 9%, transparent),
    color-mix(in srgb, var(--glow) 3%, transparent) 60%,
    transparent
  );
  filter: blur(2px);
}

.ledges {
  list-style: none;
  margin: 0 auto;
  padding: 0;
  max-width: 1100px;
  display: grid;
  gap: 6vh;
}

/* Findings cards: rectangular, hairline-bordered, with a short glow rule. */
.ledge {
  width: min(360px, 74vw);
  padding: 24px 28px 26px;
  background: var(--terrain);
  border: 1px solid var(--hairline);
  border-radius: 6px;
  opacity: 0;
  transform: translateY(28px);
  transition:
    opacity 600ms ease,
    transform 600ms ease,
    background-color 900ms ease;
}

.ledge::before {
  content: "";
  display: block;
  width: 28px;
  height: 2px;
  background: var(--glow);
  margin-bottom: 16px;
  transition: background-color 900ms ease;
}

.ledge.in {
  opacity: 1;
  transform: translateY(0);
}

/* Stagger the cascade: alternate cards step across the light shaft. */
.ledge:nth-child(odd) {
  margin-left: 12%;
}
.ledge:nth-child(even) {
  margin-left: 46%;
}
.ledge:nth-child(3n) {
  margin-left: 28%;
}

.ledge strong {
  display: block;
  font-weight: 300;
  font-size: clamp(36px, 4vw, 50px);
  line-height: 1;
  margin-bottom: 8px;
}

.ledge span {
  color: var(--ink-dim);
  font-size: 15px;
}

/* On a narrow screen the staggered cascade pushes a 74vw card (offset up to 46%)
   past the viewport edge and scrolls the page sideways. Below the layout
   breakpoint, drop the stagger and let each card sit flush and full-width. */
@media (max-width: 820px) {
  .ledge {
    width: 100%;
  }
  .ledge:nth-child(odd),
  .ledge:nth-child(even),
  .ledge:nth-child(3n) {
    margin-left: 0;
  }
}

/* ------------- 4. Descend-then-sideways rig (pin + translateX) ------------- */

.traverse-track {
  /* Vertical room for the sideways travel: 100vh pin + one viewport per extra panel. */
  height: calc(100vh * 3);
  position: relative;
}

.traverse-sticky {
  position: sticky;
  top: 0;
  height: 100vh;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.traverse-label {
  padding: 0 8vw;
}

.traverse-strip {
  display: flex;
  gap: 4vw;
  padding: 4vh 8vw;
  width: max-content;
  will-change: transform;
}

.layer-panel {
  width: 62vw;
  max-width: 720px;
  min-height: 52vh;
  flex: none;
  background: var(--card);
  border: 1px solid var(--hairline);
  border-radius: 12px;
  padding: 40px;
  backdrop-filter: blur(10px);
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
}

.layer-index {
  font-weight: 300;
  font-size: 54px;
  color: color-mix(in srgb, var(--glow) 65%, white);
  margin: 0;
  transition: color 900ms ease;
}

/* The glyph occupies the panel's dead middle space and takes the flex spring. */
.layer-glyph {
  display: block;
  width: min(280px, 70%);
  height: auto;
  margin: 20px 0 auto;
}

.layer-panel h3 {
  font-weight: 400;
  font-size: 26px;
  margin: 18px 0 10px;
}

.layer-panel p:last-child {
  color: var(--ink-dim);
  margin: 0;
  max-width: 52ch;
}

.traverse-progress {
  display: flex;
  gap: 8px;
  justify-content: center;
  padding-top: 4vh;
}

.traverse-progress i {
  width: 26px;
  height: 2px;
  background: var(--hairline);
  transition: background 300ms ease;
}

.traverse-progress i.on {
  background: var(--glow);
}

/* -------------------------------- Close -------------------------------- */

.study-footer {
  min-height: 56vh;
  display: grid;
  place-content: center;
  text-align: center;
  padding: 24px;
}

.close-line {
  font-weight: 300;
  font-size: clamp(24px, 3vw, 36px);
  line-height: 1.3;
  max-width: 26ch;
  margin: 0 auto;
  color: var(--ink);
}

/* ---------------------------- Reduced motion ---------------------------- */

@media (prefers-reduced-motion: reduce) {
  .mote,
  .scroll-cue {
    animation: none;
  }
  .mote {
    opacity: 0.35;
  }
  .ridge {
    transform: none !important;
  }
  .ledge,
  .reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }
  /* Rail scenes still key to scroll position, but state changes land instantly. */
  .rail-stack *,
  .rail-stations li,
  .rail-stations li::before {
    transition: none !important;
  }
  /* The rig degrades to a horizontally scrollable strip. */
  .traverse-track {
    height: auto;
  }
  .traverse-sticky {
    position: static;
    overflow-x: auto;
  }
  .traverse-strip {
    transform: none !important;
  }
}
