:root {
  color-scheme: light;

  --paper-tooth:
    repeating-linear-gradient(90deg, rgba(21,18,12,.028) 0 1px, transparent 1px 7px),
    repeating-linear-gradient(0deg, rgba(21,18,12,.018) 0 1px, transparent 1px 7px);

  --paper:   #efe8da;
  --paper-2: #e5dcc9;
  --ink:     #15120c;
  --ink-2:   #4b4336;
  --ink-3:   #8d8373;
  /* the one off-palette ink: a refused call, and nothing else */
  --refuse:  #1f6a5c;

  --serif:   "Newsreader", "Iowan Old Style", Georgia, "Times New Roman", serif;
  --display: "Fraunces", "Iowan Old Style", Georgia, "Times New Roman", serif;
  --mono:    ui-monospace, "SF Mono", Menlo, "Roboto Mono", monospace;

  --soft-display: "SOFT" 70, "WONK" 0, "opsz" 144;
  --soft-large:   "SOFT" 60, "WONK" 0, "opsz" 96;
  --soft-text:    "SOFT" 50, "WONK" 0, "opsz" 40;

  --t-display: clamp(56px, 8vw, 132px);
  --t-plate:   clamp(38px, 5.2vw, 84px);
  --t-head:    clamp(26px, 2.7vw, 38px);
  --t-lead:    clamp(20px, 1.6vw, 25px);
  --t-body:    19px;
  --t-mono:    13px;

  --rail: 240px;
  --rail-left: 16px;
  --rail-width: 204px;
  --rail-num: 24px;
  --rail-top: 0px;
  --rail-bottom: 0px;
  --step-gap: 48px;
  --lead: 0px;
  --pin: 72px;
  /* the plate's caption and controls switch on at this --fig; its head is printed at the pin */
  --chrome-a: 0;
  --stage-h: calc(100vh - 2 * var(--pin));

  --dur-base: var(--duration-base);
  --dur-slow: var(--duration-slow);
  /* a mark switches on at its --a and draws over a fixed time, whatever the scroll does */
  --dur-mark-fade: 280ms;
  --dur-mark-draw: 480ms;
  --ease-mark: cubic-bezier(0.3, 0, 0.2, 1);
}

/* ── motion: one --raw per chapter, published to its figures as --fig ── */

@property --raw { syntax: "<number>"; inherits: true;  initial-value: 0; }
@property --fig { syntax: "<number>"; inherits: true;  initial-value: 0; }
@property --a   { syntax: "<number>"; inherits: false; initial-value: 0; }
@property --on  { syntax: "<number>"; inherits: false; initial-value: 0; }
@property --t   { syntax: "<number>"; inherits: false; initial-value: 0; }
@property --e   { syntax: "<number>"; inherits: false; initial-value: 0; }
@property --el  { syntax: "<number>"; inherits: true;  initial-value: 0; }

@keyframes talk-raw { from { --raw: 0; } to { --raw: 1; } }

.chapter { timeline-scope: --ch; }
/* the inset is the stage's pin, so 0 is the frame pinning and 1 is it letting go */
@supports (animation-timeline: view()) and (timeline-scope: --t) {
  html:not(.driver-js) .steps { view-timeline: --ch block; view-timeline-inset: var(--pin); }
  html:not(.driver-js) .chapter {
    animation: talk-raw linear both;
    animation-timeline: --ch;
    animation-range: contain 0% contain 100%;
  }
}
/* --rested is talk.js's rest schedule over --raw, holding --fig on each
   step's rest so every step rests on a finished drawing */
.chapter-grid { --fig: var(--rested, var(--raw)); }

/* every ink mark is a switch at --a: scroll sets --on, and --t draws to it
   over a fixed time, back again if the scroll returns */
.ink { --on: clamp(0, (var(--fig) - var(--a)) * 1e6, 1);
       --t: var(--on);
       --e: calc(var(--t) * var(--t) * (3 - 2 * var(--t)));
       --el: var(--e);
       transition: --t var(--dur-mark-fade) var(--ease-mark); }
.ink-draw, .ink-wipe, .ink-grow, .ink-ride { transition-duration: var(--dur-mark-draw); }
/* a length, not a bare number: Gecko reads a unitless calc() here as no
   offset and prints the path whole. The stroke-opacity ramp keeps every
   engine from showing a stroke before it switches on. */
.ink-draw  { stroke-dasharray: 1; stroke-dashoffset: calc((1 - var(--e)) * 1px);
             stroke-opacity: clamp(0, var(--e) * 12, 1); }
.ink-fade  { opacity: var(--e); }
.ink-wipe  { transform-box: fill-box; transform-origin: 50% 100%;
             transform: scaleY(var(--e)); fill-opacity: clamp(0, var(--e) * 12, 1); }
.ink-enter { opacity: var(--e);
             transform: translateX(calc((1 - var(--e)) * -14px)); }
/* a mark that leaves again: nest it inside the mark that brought it in */
.ink-out   { opacity: calc(1 - var(--e)); }
.ink-close { transform: translateY(calc(var(--e) * var(--dy, 0px))); }
.ink-grow  { transform-box: fill-box; transform-origin: 0 50%; transform: scaleX(var(--e)); }
.ink-ride  { offset-distance: calc(var(--e) * 100%); offset-rotate: 0deg; }
.ink-dim   { opacity: calc(1 - .72 * var(--e)); }

.stage :is(figcaption, .fig-controls) {
  --a: var(--chrome-a);
  --on: clamp(0, (var(--fig) - var(--a)) * 1e6, 1);
  --t: var(--on);
  --e: calc(var(--t) * var(--t) * (3 - 2 * var(--t)));
  opacity: var(--e);
  transition: --t var(--dur-mark-fade) var(--ease-mark);
}

/* ── page ────────────────────────────────────────────────── */

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--serif);
  font-size: var(--t-body);
  font-weight: 420;
  line-height: 1.66;
  font-optical-sizing: auto;
  -webkit-font-smoothing: antialiased;
  background-image: var(--paper-tooth);
}

.wrap { max-width: 1716px; margin: 0 auto; padding-left: var(--rail); padding-right: 80px; }

/* ── progress hairline ───────────────────────────────────── */

.progress-rail { position: fixed; inset: 0 0 auto 0; height: 3px;
  background: rgba(21,18,12,.10); z-index: 40; }
.progress-ink { height: 100%; width: 100%; background: var(--sig);
  transform-origin: 0 50%; transform: scaleX(0); }
@supports (animation-timeline: scroll()) {
  html:not(.driver-js) .progress-ink { animation: grow linear both; animation-timeline: scroll(root block); }
}
@keyframes grow { from { transform: scaleX(0); } to { transform: scaleX(1); } }

/* ── rail: numbered index and the four lamps ─────────────── */

/* 16 + 204 = 220, 20px clear of the 240px rail column */
.index { position: fixed; left: var(--rail-left); top: var(--rail-top); bottom: var(--rail-bottom);
  margin: auto 0; height: fit-content; max-height: 100vh; overflow-y: auto;
  width: var(--rail-width); padding: 16px; background: var(--paper); border: 1px solid var(--ink-3);
  z-index: 30; font-family: var(--mono); font-size: var(--t-mono); letter-spacing: .02em; }
.index-head { display: block; color: var(--ink-2);
  border-bottom: 1px solid var(--ink-3); padding-bottom: 8px; margin-bottom: 14px; }
.index ol { list-style: none; margin: 0; padding: 0; }
.index li { margin: 0 0 10px; }
.index ol a { display: grid; grid-template-columns: var(--rail-num) 1fr; gap: 4px;
  color: var(--ink-2); text-decoration: none; line-height: 1.45; }
.index ol a::before { content: attr(data-mark); color: var(--ink-2); }
.index ol a:hover { color: var(--ink); }
.index ol li.on a { color: var(--ink); text-decoration: underline;
  text-underline-offset: 4px; text-decoration-color: var(--sig); }
.index ol li.on a::before { color: var(--sig-text); }

.lamps { list-style: none; margin: 18px 0 0; padding: 14px 0 0;
  border-top: 1px solid var(--ink-3); opacity: .38;
  transition: opacity var(--dur-slow) var(--ease-out); }
.index.in-ch .lamps { opacity: 1; }
/* --cap is a mount's ceiling on a lamp, so it can stay dark until its figure allows */
.lamps li { --el: min(var(--e), var(--cap, 1));
  display: grid; grid-template-columns: 9px 1fr; gap: 8px;
  align-items: center; margin: 0 0 9px;
  color: color-mix(in srgb, var(--ink-2), var(--ink) calc(var(--el) * 100%)); }
.lamps li::before { content: ""; width: 9px; height: 9px;
  background: color-mix(in srgb, transparent, var(--sig) calc(var(--el) * 100%));
  outline: 1px solid var(--ink-3); }

/* the panel reverses to ink while an ink plate passes behind it */
/* the fade rides a class set only around a toggle: a standing transition re-rasters the rail's text */
.index.fade, .index.fade :is(.index-head, ol a, .lamps li) {
  transition: background-color var(--dur-slow) var(--ease-out), color var(--dur-slow) var(--ease-out),
    border-color var(--dur-slow) var(--ease-out); }
.index.fade ol a::before, .index.fade .lamps li::before {
  transition: color var(--dur-slow) var(--ease-out), outline-color var(--dur-slow) var(--ease-out); }
.index.on-dark { background: var(--ink); border-color: color-mix(in srgb, var(--paper) 35%, transparent); }
.index.on-dark .index-head,
.index.on-dark .lamps { border-color: color-mix(in srgb, var(--paper) 35%, transparent); }
.index.on-dark .index-head,
.index.on-dark ol a,
.index.on-dark ol a::before { color: color-mix(in srgb, var(--paper) 55%, transparent); }
.index.on-dark ol a:hover,
.index.on-dark ol li.on a { color: var(--paper); }
.index.on-dark ol li.on a::before { color: var(--sig); }
.index.on-dark .lamps li { color: color-mix(in srgb, var(--paper) 55%, var(--paper) calc(var(--el) * 45%)); }
.index.on-dark .lamps li::before { outline-color: color-mix(in srgb, var(--paper) 35%, transparent); }

/* ── cover ───────────────────────────────────────────────── */

.cover { min-height: 100vh; display: flex; align-items: center;
  padding: 120px 0 80px; border-bottom: 2px solid var(--ink); }
.folio { font-family: var(--mono); font-size: var(--t-mono); letter-spacing: .05em;
  color: var(--ink-2); margin: 0 0 40px; }
.display { font-family: var(--display); font-weight: 600;
  font-variation-settings: var(--soft-display); font-size: var(--t-display);
  line-height: .94; letter-spacing: -.018em; margin: 0; text-wrap: balance; }
.display em { font-style: italic; font-weight: 500; color: var(--sig-text); margin-right: .07em; }
.cover-rule { display: block; width: 100%; height: 82px; margin: 34px 0 36px; }
.deck { font-family: var(--display); font-weight: 500; font-style: italic;
  font-variation-settings: var(--soft-large); font-size: clamp(23px, 2.3vw, 33px);
  line-height: 1.24; margin: 0 0 34px; max-width: 18ch; }
.course { max-width: var(--course-max, none); font-family: var(--mono); font-size: 13px; letter-spacing: .04em;
  color: var(--ink-2); margin: 0; }
.dot { color: var(--sig-text); padding: 0 .3em; }
.scroll-cue { margin: 56px 0 0; font-family: var(--mono); font-size: var(--t-mono);
  letter-spacing: .06em; color: var(--ink-2); }
.cue-run::after { content: " ↓"; color: var(--sig-text); }
.cue-still { display: none; }

/* ── plate: the full-bleed chapter separator ─────────────── */

.plate { position: relative; background: var(--ink); color: var(--paper);
  padding: 108px 0 116px; overflow: hidden; }
.plate-inner { position: relative; z-index: 2; }
.plate-folio { font-family: var(--mono); font-size: var(--t-mono);
  letter-spacing: .12em; text-transform: uppercase; color: var(--sig); margin: 0 0 22px; }
.plate-title { font-family: var(--display); font-weight: 600;
  font-variation-settings: var(--soft-large); font-size: var(--t-plate);
  line-height: .98; letter-spacing: -.014em; margin: 0 0 28px; color: var(--paper); }
.plate-claim { font-family: var(--serif); font-size: clamp(19px, 1.5vw, 23px);
  line-height: 1.55; max-width: 46ch; margin: 0;
  color: color-mix(in srgb, var(--paper) 78%, var(--ink)); }
.plate-hatch { position: absolute; left: 0; right: 0; bottom: 0; width: 100%;
  height: 160px; z-index: 1; opacity: 0; transform: translateY(46%); }
.plate-hatch line { stroke: var(--sig); stroke-width: var(--hatch-w, 2); }
.plate.in .plate-hatch { transform: translateY(0); opacity: .85;
  transition: transform var(--dur-mark-draw) var(--ease-out), opacity var(--dur-mark-draw) var(--ease-out); }
@supports (animation-timeline: view()) {
  html:not(.driver-js) .plate-hatch { animation: hatch-rise linear both;
    animation-timeline: view(); animation-range: entry 10% cover 45%; }
}
@keyframes hatch-rise {
  from { transform: translateY(46%); opacity: 0; }
  to   { transform: translateY(0);   opacity: .85; }
}

/* ── chapter: prose steps beside the pinned stage ────────── */

.chapter { padding: 96px 0 40px; }
/* the stage track's 720px floor is the figure viewBox, so a plate prints at scale 1 */
.chapter-grid { display: grid; grid-template-columns: minmax(340px, 440px) minmax(720px, 1fr);
  gap: 0 56px; align-items: start; }
.chapter-head { font-family: var(--display); font-weight: 600;
  font-variation-settings: var(--soft-text); font-size: var(--t-head);
  line-height: 1.12; letter-spacing: -.012em; margin: 0 0 8px; padding-bottom: 18px;
  border-bottom: 2px solid var(--ink); }
.chapter-head .num { color: var(--sig-text); }

/* the one allowance: enough track below the last step for its middle to
   reach the reading line, the window's middle, as the stage lets go.
   --tail is half that step's height, measured by talk.js. */
.steps { padding-bottom: var(--step-last, max(0px, calc(var(--stage-h) / 2 - var(--tail, 0px)))); }
.steps > .step:first-of-type { margin-top: var(--lead); }
.step { padding: calc(var(--step-gap) / 2) 0; border-bottom: 1px solid var(--paper-2); opacity: .34;
  transition: opacity var(--dur-slow) var(--ease-out); }
.step.on { opacity: 1; }
.step:last-child { border-bottom: 0; }
.step-mark { font-family: var(--mono); font-size: var(--t-mono); letter-spacing: .06em;
  color: var(--sig-text); margin: 0 0 14px; }
.step .lead { font-family: var(--display); font-weight: 550;
  font-variation-settings: var(--soft-text); font-size: var(--t-lead);
  line-height: 1.32; letter-spacing: -.006em; margin: 0 0 18px; }
.step p { margin: 0 0 16px; max-width: 56ch; }
.step code { font-family: var(--mono); font-size: .88em; background: var(--paper-2);
  padding: 1px 5px; border-bottom: 1px solid var(--sig); }

/* the frame is centred in the window; the svg is the part that gives when
   controls and a caption leave less than its own height */
.stage { position: sticky; top: var(--pin); margin: 0; padding: 0;
  height: var(--stage-h); display: flex; flex-direction: column; justify-content: center; }
.stage-inner { width: 100%; display: flex; flex-direction: column; min-height: 0; }
.stage svg { display: block; width: 100%; height: auto; min-height: 0; max-height: calc(100vh - 208px); }
.stage figcaption { font-family: var(--mono); font-size: var(--t-mono);
  letter-spacing: .02em; line-height: 1.45; color: var(--ink-2); margin-top: 16px;
  padding-top: 10px; border-top: 1px solid var(--paper-2); }
.cap-mark { color: var(--sig-text); letter-spacing: .04em; margin-right: 10px; }

.margin { font-family: var(--mono); font-size: 12.5px; line-height: 1.5;
  letter-spacing: .02em; color: var(--ink-2); max-width: 44ch;
  border-left: 2px solid var(--sig); padding: 2px 0 2px 14px; margin: 0 0 16px; }
.margin a { color: inherit; text-decoration: underline; text-decoration-color: var(--sig);
  text-underline-offset: 3px; }
.margin a:hover { color: var(--ink); }

.fig-controls { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--paper-2); }
.fig-row { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.fig-btn { font-family: var(--mono); font-size: var(--t-mono); letter-spacing: .06em;
  text-transform: uppercase; background: var(--paper); color: var(--ink);
  border: 1.5px solid var(--ink); padding: 9px 14px; cursor: pointer; }
.fig-btn:hover { background: var(--ink); color: var(--paper); }
.fig-btn[aria-pressed="true"] { background: var(--sig); border-color: var(--sig);
  color: var(--paper); }
.fig-btn[disabled] { color: var(--ink-3); border-color: var(--ink-3); cursor: default; }
.fig-btn[disabled]:hover { background: var(--paper); color: var(--ink-3); }
.fig-note { font-family: var(--mono); font-size: var(--t-mono); color: var(--ink-2);
  letter-spacing: .02em; margin: 10px 0 0; }
.fig-note:has(> .on) { display: grid; }
.fig-note:has(> .on) > * { grid-area: 1 / 1; }
.fig-note:has(> .on) > :not(.on) { visibility: hidden; }

/* ── out ─────────────────────────────────────────────────── */

.out { padding: 120px 0 96px; }
.out-ask { max-width: 52ch; margin: 34px 0 0; }
.out-ask + .out-ask { margin-top: 14px; }
.out-line { font-family: var(--display); font-weight: 500; font-style: italic;
  font-variation-settings: var(--soft-large); font-size: clamp(21px, 2.1vw, 30px);
  line-height: 1.32; max-width: 24ch; margin: 0 0 44px; }
.out-link { display: inline-grid; grid-template-columns: auto auto; align-items: end;
  gap: 0 18px; text-decoration: none; color: var(--ink);
  border-bottom: 3px solid var(--sig); padding-bottom: 12px; }
.out-link-label { grid-column: 1; font-family: var(--mono); font-size: 13px;
  letter-spacing: .04em; color: var(--ink-2); padding-bottom: 10px; }
.out-link-slug { grid-column: 1; font-family: var(--display); font-weight: 600;
  font-variation-settings: var(--soft-large); font-size: clamp(34px, 4.6vw, 72px);
  line-height: 1; letter-spacing: -.018em; }
.out-link-hash { grid-column: 1; font-family: var(--mono); font-size: 13px;
  letter-spacing: .04em; color: var(--sig-text); padding-top: 12px; }
.out-note { font-family: var(--mono); font-size: var(--t-mono); letter-spacing: .02em;
  line-height: 1.5; color: var(--ink-2); max-width: 60ch; margin: 22px 0 0; }
.out-arrow { grid-column: 2; grid-row: 1 / span 3; width: clamp(34px, 4vw, 58px);
  height: auto; color: var(--sig); transition: transform var(--dur-base) var(--ease-out); }
/* .end is the clicker's: a forward press past the last stop lifts the arrow */
.out-link:hover .out-arrow, .out-link.end .out-arrow { transform: translate(6px, -6px); }
.out-link:hover .out-link-slug, .out-link.end .out-link-slug { color: var(--sig-text); }
.colophon { font-family: var(--mono); font-size: var(--t-mono); letter-spacing: .02em;
  color: var(--ink-2); margin: 60px 0 0; padding-top: 16px; border-top: 1px solid var(--paper-2); }

/* ── engraving: the marks every figure is made of ────────── */

.f-mono   { font-family: var(--mono); font-size: 15px; letter-spacing: .02em; fill: var(--ink-2); }
.f-strong { fill: var(--ink); letter-spacing: .05em; }
.f-muted  { fill: var(--ink-2); font-size: 13.5px; letter-spacing: .03em; }
.f-tiny   { font-family: var(--mono); font-size: 12.5px; letter-spacing: .09em;
            text-transform: uppercase; fill: var(--ink-2); }
.f-sig    { fill: var(--sig-text); }
.f-code   { font-family: var(--mono); font-size: 13px; letter-spacing: .01em; fill: var(--ink); }
/* the second ink on a code line: .f-code sets fill, so this has to follow it */
.f-dim    { fill: var(--ink-2); }
.f-refuse { fill: var(--refuse); }
.f-serif  { font-family: var(--display); font-style: italic; font-weight: 500;
            font-variation-settings: var(--soft-text); font-size: 23px; fill: var(--ink); }

.f-rule      { stroke: var(--ink-3); stroke-width: 1; fill: none; }
.f-rule-sig  { stroke: var(--sig); stroke-width: var(--f-stroke, 1.6); fill: none; }
.f-draw      { fill: none; stroke: var(--ink); stroke-width: var(--f-stroke, 1.6); stroke-linecap: square; }
.f-ring      { stroke: var(--ink); stroke-width: calc(var(--f-stroke, 1.6) - .2); }
.f-plate     { stroke-width: 2.6; }
.f-station   { stroke-width: 1.4; }
.f-fill      { fill: var(--paper); }
.f-cartouche { stroke-width: 2.2; }
.f-thin      { stroke-width: 1.2; }
.f-lead      { stroke: var(--ink-2); stroke-width: 1.4; }
.f-lead-sig  { stroke: var(--sig); stroke-width: 2; }
.f-spine     { stroke: var(--sig); stroke-width: 2; }
.f-node      { fill: var(--sig); }
.f-refuse-s  { stroke: var(--refuse); stroke-width: 1.6; fill: none; }
.f-dot       { fill: var(--sig); stroke: var(--ink); stroke-width: 1.4; }
.f-paper     { fill: var(--paper-2); }
.f-arrow     { stroke: var(--ink-2); stroke-width: 1.4; fill: none; }
.f-arrow-sig { stroke: var(--sig); stroke-width: 1.8; fill: none; }

/* ── breakpoints: the rail goes below 1436, the stage floor below 1196,
   one column and the static plates at 860 ── */

@media (max-width: 1435px) {
  :root { --rail: 40px; }
  .index { display: none; }
  .wrap { padding-right: 40px; }
}
@media (max-width: 1195px) {
  .chapter-grid { grid-template-columns: minmax(0, 340px) minmax(0, 1fr); gap: 0 32px; }
}
@media (max-height: 860px) {
  :root { --pin: 40px; }
}
@media (max-width: 860px) {
  .chapter-grid { grid-template-columns: minmax(0,1fr); gap: 40px; }
  .stage { margin-top: 32px; }
  .step { padding: 22px 0; }
  .cover { padding: 80px 0 60px; }
  .out-link { max-width: 100%; grid-template-columns: minmax(0, 1fr) auto; }
  .out-link-slug { overflow-wrap: anywhere; }
}

/* ── static: narrow, reduced motion and print show every plate finished ── */

@media print, (prefers-reduced-motion: reduce), (max-width: 860px) {
  :root { scroll-behavior: auto; --dur-base: 0ms; --dur-slow: 0ms;
    --dur-mark-fade: 0ms; --dur-mark-draw: 0ms; }
  .chapter { animation: none !important; --raw: 1 !important; }
  .chapter-grid { --fig: 1 !important; }
  .lamps { transition: none !important; }
  .steps { view-timeline-name: none; padding-bottom: 0; }
  .steps > .step:first-of-type { margin-top: 0; }
  .stage { position: static; height: auto; }
  .stage svg { max-height: none; }
  .step { opacity: 1; }
  .index, .progress-rail { display: none; }
  .progress-ink, .plate-hatch { animation: none !important; transition: none !important; }
  .plate-hatch { transform: none; opacity: .85; }
  .cover { min-height: auto; }
  .cover-rule line { stroke-dashoffset: 0 !important; }
  .cue-run { display: none; }
  .cue-still { display: inline; }
  .out-arrow { transition: none; }
}
@media print {
  .plate { print-color-adjust: exact; -webkit-print-color-adjust: exact; break-before: page; }
  .stage, .plate { break-inside: avoid; }
  .fig-row { display: none; }
}
