/* Hallmark · genre: editorial · macrostructure: Type Specimen (poster slides) · theme: studied-DNA (source: article-wavefont_1x1-*.png, author's own)
 * colours: dark oklch(24.6% 0.009 285.7) · blue oklch(56.2% 0.090 261.3) · gray oklch(94.6% 0.004 271.4) · white; red only for recording
 * type: Wavefont (bars) + Atkinson Hyperlegible Next (text) + Atkinson Hyperlegible Mono (labels, code) · footer: a slide
 */

@font-face {
  font-family: wavefont;
  src: url("../fonts/variable/Wavefont[ROND,YELA,wght].woff2") format("woff2");
  font-weight: 4 1000;
  font-display: block;
}

/* axes as typed properties: they inherit, transition, and default to thin square bars */
@property --wght { syntax: "<number>"; inherits: true; initial-value: 120; }
@property --rond { syntax: "<number>"; inherits: true; initial-value: 0; }
@property --yela { syntax: "<number>"; inherits: true; initial-value: 0; }

:root {
  /* four colours, sampled from the article images; red marks a recording, nothing else */
  --dark: oklch(24.6% 0.009 285.7);
  --blue: oklch(56.2% 0.090 261.3);
  --gray: oklch(94.6% 0.004 271.4);
  --white: oklch(100% 0 0);
  --red: oklch(66.3% 0.224 28.3);
  /* the layout overlay's, and nothing else's */
  --grid: oklch(62% 0.25 350);

  --font-wave: wavefont;
  --font-sans: "Atkinson Hyperlegible Next", ui-sans-serif, system-ui, sans-serif;
  --font-mono: "Atkinson Hyperlegible Mono", ui-monospace, "SF Mono", Menlo, monospace;

  /* the weight of the bars on the slides that lead in – the keys, the values, and where the axes set off from – in whole
     font units: narrower on a phone, but not too narrow, wider as the screen is */
  --wght-bars: 400;

  /* type: every size of text on the page is one of these */
  --text-label: 1rem;                                  /* labels, values, captions: status lines, axes, readouts */
  --text-body: 1.0625rem;                              /* running text */
  --text-lead: clamp(1rem, 0.72rem + 0.85vw, 1.5rem);  /* a line that leads: the features, a name under its bars */
  --text-big: clamp(1.5rem, 1rem + 1.5vw, 2.25rem);    /* a number read at a glance */
  /* the one label, in mono */
  --label: 500 var(--text-label)/1.4 var(--font-mono);

  --space-2xs: 0.25rem;
  --space-xs: 0.5rem;
  --space-sm: 0.75rem;
  --space-md: 1rem;
  --space-lg: 1.5rem;
  --space-xl: 2.5rem;
  --space-2xl: 4rem;

  /* Atkinson's ascent and descent, 984 and 316 of 1000 (hhea = typo, USE_TYPO_METRICS), centre its capitals in any
     line box: the baseline sits this far above the box's foot, the cap height as far below its top. As a margin, it
     sets text on a row line or hangs it from one, as text-box-trim would where it's supported */
  --sink: calc((0.668em - 1lh) / 2);

  /* every slide: these paddings, then a grid of twelve columns and twelve rows; content a cell in */
  --pad-x: clamp(1rem, 5vw, 6rem);
  --pad-y: clamp(1.5rem, 5svh, 4rem);
  --row: calc((100svh - 2 * var(--pad-y)) / 12);

  --radius-sm: 0.375rem;
  --radius-md: 0.75rem;
  --radius-pill: 999px;

  /* icons as masks, drawn in the ink of what holds them: copy, and the tick once done */
  --i-copy: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23000' stroke-width='1.4' stroke-linejoin='round'%3E%3Cpath d='M5.5 5.5h7v8h-7zM3.5 10.5V2.5h7'/%3E%3C/svg%3E");
  --i-done: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 8.5l3.2 3.2L13 4.8'/%3E%3C/svg%3E");

  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --dur-micro: 120ms;
  --dur-short: 220ms;
  --dur-long: 420ms;
}

/* papers: each derives what it needs from the four colours; --tint lifts what's picked or hovered */
.dark {
  --bg: var(--dark);
  --fg: var(--white);
  --dim: color-mix(in oklab, var(--white) 58%, var(--dark));
  --faint: color-mix(in oklab, var(--white) 14%, var(--dark));
  --tint: color-mix(in oklab, var(--white) 9%, transparent);
  --accent: color-mix(in oklab, var(--blue) 55%, var(--white));
  --played: var(--white);
  --unplayed: color-mix(in oklab, var(--white) 40%, var(--dark));
  --sel: var(--blue);
  --sel-ink: var(--white);
}
.blue {
  --bg: var(--blue);
  --fg: var(--white);
  --dim: color-mix(in oklab, var(--white) 72%, var(--blue));
  --faint: color-mix(in oklab, var(--white) 30%, var(--blue));
  --tint: color-mix(in oklab, var(--white) 22%, transparent);
  --accent: var(--white);
  --played: var(--white);
  --unplayed: color-mix(in oklab, var(--white) 55%, var(--blue));
  --sel: color-mix(in oklab, var(--white) 22%, var(--blue));
  --sel-ink: var(--white);
}
.gray, .white {
  --bg: var(--gray);
  --fg: var(--dark);
  --dim: color-mix(in oklab, var(--dark) 62%, var(--gray));
  --faint: color-mix(in oklab, var(--dark) 13%, var(--gray));
  --tint: color-mix(in oklab, var(--dark) 7%, transparent);
  --accent: var(--blue);
  --played: var(--dark);
  --unplayed: color-mix(in oklab, var(--dark) 45%, var(--gray));
  --sel: var(--blue);
  --sel-ink: var(--white);
}
.white { --bg: var(--white); }

*, *::before, *::after { box-sizing: border-box; }

html {
  overflow-x: clip;
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}
/* slides snap to a wheel or a trackpad; under a finger a snap fights the fling, and WebKit snaps again whenever a
   slide's text redraws – a game's every frame */
@media (pointer: fine) { html { scroll-snap-type: y proximity; } }

body {
  margin: 0;
  overflow-x: clip;
  background: var(--dark);
  color: var(--white);
  font: 400 var(--text-body)/1.55 var(--font-sans);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-synthesis: none;
}

::selection { background: var(--sel, var(--blue)); color: var(--sel-ink, var(--white)); }

a { color: inherit; text-decoration-thickness: 1px; text-underline-offset: 0.2em; text-decoration-color: color-mix(in oklab, currentColor 40%, transparent); }
a:hover { text-decoration-color: currentColor; }

:focus-visible { outline: 2px solid var(--accent, var(--blue)); outline-offset: 3px; }

/* controls and code take the page's fonts, not the browser's own */
button, code { font: inherit; color: inherit; }

[hidden] { display: none !important; }

/* for screen readers only */
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* ── the font ───────────────────────────────────────────── */

/* axes inherit, so a container can set them for its bars; spans re-read them, so each bar can differ */
.wf, .wf span, .wf tspan {
  font-variation-settings: "wght" var(--wght), "ROND" var(--rond), "YELA" var(--yela);
}
.wf {
  font-family: var(--font-wave);
  font-kerning: none;
  font-variant-ligatures: none;
  letter-spacing: var(--gap, 0.5ch);
  line-height: 1.6;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.wf::selection, .wf span::selection { background: var(--sel); color: var(--sel-ink); }

/* sound progress, painted over text without touching the DOM: CSS Custom Highlight API */
::highlight(played) { color: var(--played); }

/* ── atoms ──────────────────────────────────────────────── */

.label { margin: 0; font: var(--label); color: var(--dim); }

.code {
  margin: 0;
  font: 400 0.8125rem/1.65 var(--font-mono);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  color: var(--fg);
}
/* syntax: keywords and tags in the accent, strings between ink and accent, comments dim */
.code .k { color: var(--accent); }
.code .s { color: color-mix(in oklab, var(--fg) 60%, var(--accent)); }
.code .c { color: var(--dim); font-style: italic; }
.code .n { color: var(--accent); }

.btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  min-height: 2.75rem;
  padding: 0 var(--space-lg);
  border: 1px solid color-mix(in oklab, var(--fg) 40%, transparent);
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--fg);
  font-weight: 500;
  white-space: nowrap;
  cursor: pointer;
  transition: border-color var(--dur-short) var(--ease-out), background-color var(--dur-short) var(--ease-out);
}
@media (hover: hover) { .btn:hover { border-color: var(--fg); } }
.btn:active { background: var(--tint); }

.i { width: 1em; height: 1em; fill: currentColor; flex: none; }
/* a tool's button – copy, play: its icon, quiet till hovered; copy's a tick for a moment once done */
.copy, .play { display: grid; place-items: center; width: 3rem; height: 3rem; padding: 0; border: 0; border-radius: var(--radius-sm); background: none; color: var(--dim); font-size: 2rem; cursor: pointer; transition: color var(--dur-micro) var(--ease-out); }
.copy::after { content: ""; width: 1em; height: 1em; background: currentColor; mask: var(--i-copy) center / contain no-repeat; }
.copy.is-done::after { mask-image: var(--i-done); }
@media (hover: hover) { :is(.copy, .play):hover { color: var(--fg); } }
.i-pause { display: none; }
.is-playing .i-play { display: none; }
.is-playing .i-pause { display: inline; }

input[type="range"] {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 2.75rem;
  margin: 0;
  background: transparent;
  cursor: pointer;
  touch-action: pan-y;
}
input[type="range"]::-webkit-slider-runnable-track { height: 2px; background: var(--faint); }
input[type="range"]::-moz-range-track { height: 2px; background: var(--faint); }
input[type="range"]::-webkit-slider-thumb { -webkit-appearance: none; width: 1.25rem; height: 1.25rem; margin-top: calc(-0.625rem + 1px); border-radius: 50%; background: var(--fg); border: 0; }
input[type="range"]::-moz-range-thumb { width: 1.25rem; height: 1.25rem; border-radius: 50%; background: var(--fg); border: 0; }
input[type="range"]:focus-visible { outline-offset: 0; }

/* ── slides: the grid – twelve columns and twelve rows: a cell of margin all round, the stage, the status band in
   the eleventh row. What's in a cell stands on its foot or hangs from its top, never floats in its middle: text by
   its baseline or its cap height, bars by their ends ── */

.slide {
  position: relative;
  min-height: 100svh;
  padding: var(--pad-y) var(--pad-x);
  background: var(--bg);
  color: var(--fg);
  scroll-snap-align: start;
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  /* a row grows only when what's in it needs more */
  grid-template-rows: repeat(12, minmax(var(--row), auto));
  align-items: center;
  /* sized by its columns: a column is a twelfth of it, as a length for whatever inside needs one */
  container-type: inline-size;
  --col: calc(100cqw / 12);
}
/* the stage: the ten columns and nine rows a cell in from the edges, the slide's own, so what's on it starts where
   a column or a row does. (No containment on it or in it: a contained box can't share its parent's grid) */
.slide > .stage { grid-area: 2 / 2 / 11 / 12; align-self: stretch; display: grid; grid-template-columns: subgrid; grid-template-rows: subgrid; min-width: 0; }
/* what's on it: left-aligned, centred in its height, unless placed */
.stage > * { grid-column: 1 / -1; grid-row: 1 / -1; align-self: center; min-width: 0; }
/* the status line: what the slide reports, in the eleventh row, a cell in, standing on its foot */
.status { grid-area: 11 / 2 / 12 / 12; align-self: end; display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: var(--space-lg) var(--space-xl); font: var(--label); color: var(--dim); }
.status output, .status b { color: var(--fg); font-weight: inherit; font-variant-numeric: tabular-nums; }
.status > :is(output, span, p, a) { margin-bottom: var(--sink); }
/* tabs: tiles standing on the band's line, as the text's weights are – the one picked (or on) on white, in ink */
.tabs { display: flex; flex-wrap: wrap; gap: var(--space-2xs); font: var(--label); }
.tabs button {
  min-height: 2.75rem; padding: 0 0.75em; border: 0; border-radius: var(--radius-sm);
  background: none; color: var(--dim); font: inherit; cursor: pointer;
  transition: background-color var(--dur-micro) var(--ease-out), color var(--dur-micro) var(--ease-out);
}
@media (hover: hover) { .tabs button:hover { background: color-mix(in oklab, var(--white) 60%, transparent); color: var(--fg); } }
.tabs button:is([aria-checked="true"], [aria-pressed="true"]) { background: var(--white); color: var(--fg); }

/* out of view, a slide's animations hold where they are, whatever sets them going */
.slide.off, .slide.off * { animation-play-state: paused !important; }

/* layout overlay, for tuning while building: g, or the page opened with ?grid */
.grid-on .slide::after {
  content: "";
  position: absolute;
  inset: var(--pad-y) var(--pad-x);
  pointer-events: none;
  z-index: 50;
  outline: 1px solid color-mix(in oklab, var(--grid) 60%, transparent);
  /* twelve columns and twelve rows, no gutters */
  --line: color-mix(in oklab, var(--grid) 45%, transparent);
  background:
    repeating-linear-gradient(to right, var(--line) 0 1px, transparent 1px calc(100% / 12)),
    repeating-linear-gradient(to bottom, var(--line) 0 1px, transparent 1px calc(100% / 12));
}

/* ── hero: the name, set in itself, its bars five rows high; the letters standing on the row under them; what it
   does a row further down, a row each – on a phone, a line each, as far apart as the last slide's links ── */

.hero .stage { grid-row: 2 / 12; }
.mark {
  --n: 8;
  --bar-rows: 5;
  --size: min(calc(var(--bar-rows) * var(--row)), calc(var(--col) * 10 / (var(--n) * 0.265)));
  --wght: 500;
  --pitch: calc(var(--size) * 0.265);
  --adv: calc(var(--size) * 0.125);
  align-self: start;
  display: grid;
  grid-template-columns: subgrid;
}
.mark > * { grid-column: 1 / -1; }
.mark-bars {
  --yela: -100;
  /* at line-height 1 a bar standing on the floor stands on the foot of its box: the foot of the fifth row */
  margin-top: calc(var(--bar-rows) * var(--row) - var(--size));
  font-size: var(--size);
  letter-spacing: calc(var(--pitch) - var(--adv));
  line-height: 1;
  white-space: pre;
  caret-color: var(--fg);
  outline: none;
  cursor: text;
}
/* the bars don't show at their height first, to fall to the floor and rise: where a script is to set the intro going,
   they wait for it */
@media (scripting: enabled) { .mark:not(.is-set) .mark-bars { color: transparent; } }
/* a selection dims the bars it takes: the page's blue would fill the whole line box, taller than the bars */
.mark-bars::selection { background: none; color: var(--dim); }
/* one cell per bar, centred under it: cells start half a gap left of the first bar */
.mark-letters {
  display: flex;
  align-items: flex-end;
  height: var(--row);
  margin-left: calc((var(--adv) - var(--pitch)) / 2);
  font: 700 clamp(1.375rem, calc(var(--size) * 0.105), 3rem)/1 var(--font-sans);
  user-select: none; -webkit-user-select: none;
}
.mark-letters span { flex: none; width: var(--pitch); margin-bottom: var(--sink); text-align: center; }
/* what it does: a line each, as far apart as the last slide's links, and reaching as far above and below its line for
   a finger */
.facts {
  list-style: none; margin: var(--row) 0 0; padding: 0;
  display: grid; align-items: end; row-gap: var(--space-lg);
  font: 700 var(--text-lead)/1 var(--font-sans);
  letter-spacing: 0.3em;
}
.facts li { margin-bottom: var(--sink); }
.facts a { padding-block: var(--space-sm); margin-block: calc(-1 * var(--space-sm)); text-decoration: none; white-space: nowrap; }
.facts a:hover { color: var(--accent); }

/* ── latin+ core: the keys that draw bars – three lines of 26 across the ten columns, a key's bar standing on a row
   line, its name hanging from it in the row under; a row between the lines. The lowercase reach half the height the
   rest do: one row of bars is theirs ── */

.keys .stage { grid-row: 2 / 12; }
/* the bars in the deck's weight, two rows high – or, where the keys are close, no taller than a bar of that weight
   three quarters of a key's pitch wide is: a pitch is ten columns over twenty-six keys, and a bar of a weight is
   wght/4000 of its size wide */
.keymap { --wght: var(--wght-bars); --pitch: calc(10 * var(--col) / 26); align-self: start; display: grid; grid-template-rows: calc(2 * var(--row)) var(--row) calc(3 * var(--row)) var(--row) calc(3 * var(--row)); }
.keymap .line:nth-child(2) { grid-row: 3; }
.keymap .line:nth-child(3) { grid-row: 5; }
.keymap .line:first-child { grid-template-rows: var(--row) var(--row); }
.keymap .line { display: grid; grid-template-columns: repeat(26, minmax(0, 1fr)); grid-template-rows: calc(2 * var(--row)) var(--row); }
.keymap .k { grid-row: 1 / -1; display: grid; grid-template-rows: subgrid; justify-items: center; }
/* at line-height 1 a bar standing on the floor stands on the foot of its box */
.keymap .k b { --yela: -100; align-self: end; font-weight: normal; font-size: min(calc(2 * var(--row)), calc(3000 * var(--pitch) / var(--wght))); line-height: 1; }
.keymap .k i { align-self: start; margin-top: var(--sink); padding-top: var(--space-sm); font: var(--label); font-style: normal; color: var(--fg); }

/* ── 127 values: every bar in a grid across the ten inner columns, sixteen to a row of the slide's; 0 and 127 in
   the margin cells, on the lines of the first bar and the last; the picked one's value, character and code in the
   band ── */

.values .stage { grid-area: 2 / 1 / 12 / -1; }
.grid {
  /* a bar a sixteenth of ten columns wide and its row of the slide's high: the tallest, 1.27em, within it; eight
     rows of them, a row, then the readout */
  --w: calc(var(--col) * 10 / 16);
  --cell: min(var(--w), var(--row) / 1.3);
  grid-row: 1 / -1;
  align-self: stretch;
  display: grid;
  grid-template-columns: var(--col) repeat(16, var(--w)) var(--col);
  grid-template-rows: repeat(10, var(--row));
  align-items: end;
}
.grid .cell {
  --wght: var(--wght-bars);
  --yela: -100;
  display: grid; place-items: end center;
  height: 100%;
  padding: 0;
  border: 0; border-radius: 2px;
  background: none; color: var(--fg);
  font-family: var(--font-wave);
  font-variation-settings: "wght" var(--wght), "ROND" var(--rond), "YELA" var(--yela);
  font-size: var(--cell); line-height: 1;
  cursor: pointer;
  transition: background-color var(--dur-micro) var(--ease-out);
}
@media (hover: hover) { .grid .cell:hover { background: color-mix(in oklab, var(--tint) 55%, transparent); } }
.grid .cell[aria-pressed="true"] { background: var(--tint); }
.edge { margin-bottom: var(--sink); padding: 0 var(--space-sm); font: var(--label); color: var(--dim); }
.edge.from { grid-area: 1 / 1; justify-self: end; }
.edge.to { grid-area: 8 / 18; }
/* one line, never wrapped: the values at the size where the longest line they make fits its --span beside the copy
   button's 3rem – --ems wide, its characters at 0.632 em, Atkinson Hyperlegible Mono's advance (632 of its 1000
   units, hmtx, as Google Fonts serves it), and a gap before each item after the first, the button's too */
.readout {
  --span: calc(10 * var(--col));
  --ems: calc(10 * 0.632 + 3 * 1.2);
  --v: min(var(--text-big), var(--row) * 0.5, (var(--span) - 3rem) / var(--ems));
  grid-area: 10 / 2 / 11 / 18; align-self: end; display: flex; align-items: flex-end; gap: calc(1.2 * var(--v));
}
/* each value selectable, and a click copies it; the copy button after them lights while one's hovered, its icon's
   middle on the values' capitals' middle – Atkinson's cap height is 0.668 of an em, the icon's box 3rem */
.readout [role="button"] { margin-bottom: var(--sink); font: 500 var(--v)/1 var(--font-mono); font-variant-numeric: tabular-nums; white-space: nowrap; cursor: copy; }
.readout .copy { margin: 0 0 calc(0.334 * var(--v) - 1.5rem) calc(var(--space-md) - 1.2 * var(--v)); }
@media (hover: hover) { .readout:has([role="button"]:hover) .copy { color: var(--fg); } }

/* ── 3 axes: the specimen across all twelve columns, four rows high from the third; the sliders on the columns in
   the middle, a row each, the last in the band ── */

.axes .stage { grid-area: 2 / 1 / 12 / -1; }
/* the first bar on the grid's left edge and the last on its right, at any weight: the gaps share what the bars leave */
.specimen {
  --n: 15;
  /* four rows, where the twelve columns allow: at line-height 1 the bars stand on a row line, hang from one or centre
     on one, whichever the alignment */
  --size: min(calc(4 * var(--row)), 100cqw / 3.75);
  grid-row: 2 / 6;
  font-size: var(--size);
  letter-spacing: calc((100cqw - var(--n) * var(--size) * var(--wght) / 4000) / (var(--n) - 1));
  line-height: 1;
  white-space: pre;
}
.sliders { grid-area: 8 / 2 / 11 / 12; align-self: stretch; display: grid; grid-template-columns: subgrid; grid-template-rows: subgrid; }
/* a slider a row, its track on the row's line and its name and value standing on it */
.axis { grid-column: 1 / -1; display: grid; grid-template-columns: subgrid; align-items: end; }
/* the track on the line, half the slider below it, over the next axis's label: it stays in reach */
.axis input { position: relative; z-index: 1; margin-bottom: -1.375rem; }
.axis .name, .axis output { margin-bottom: var(--sink); }
.axis .name { grid-column: 1 / 5; font: var(--label); color: var(--dim); cursor: help; }
.axis input { grid-column: 5 / 9; }
.axis output { grid-column: 9 / -1; font: var(--label); color: var(--fg); font-variant-numeric: tabular-nums; text-align: right; }

/* ── textual semantics: a document, as in the article – the title a third larger than the text, bars on one pitch
   per block, each weight a share of it, set in whole device pixels by the script (--w0…4, --s0…4) ── */

/* on the rows: the title in the first, then a row, then the text a line a row – half a row on upright screens. The
   text scales with the columns, so its paragraphs keep their lengths at any width – two lines and seven tenths, a
   line and a half – within a row's height; the title a third larger. The text's words are loud, to 127 where they
   reached 70, so it's set at 0.55 of that size, and smaller still where its line is under 1.6 of it, Wavefont's
   ascent and descent: a shorter line sets a selection's lines over each other */
.doc { --size: clamp(1.75rem, var(--col) * 0.43, var(--row) * 0.8); --lh: var(--row); position: relative; align-self: start; display: grid; grid-template-columns: minmax(0, 1fr); row-gap: var(--row); outline: none; cursor: text; }
.doc-title { --yela: 0; --wght: var(--w2); letter-spacing: var(--s2); font-size: calc(var(--size) * 1.33); line-height: var(--row); white-space: pre; }
.doc-body { --yela: 0; --wght: var(--w0); letter-spacing: var(--s0); font-size: min(var(--size) * 0.55, var(--lh) / 1.6); line-height: var(--lh); color: var(--fg); }
.doc .w0 { --wght: var(--w0); letter-spacing: var(--s0); }
.doc .w1 { --wght: var(--w1); letter-spacing: var(--s1); }
.doc .w2 { --wght: var(--w2); letter-spacing: var(--s2); }
.doc .w3 { --wght: var(--w3); letter-spacing: var(--s3); }
.doc .w4 { --wght: var(--w4); letter-spacing: var(--s4); }
.doc .wf::selection, .doc .wf span::selection { background: var(--blue); color: var(--white); }
/* the caret the page types with when it edits itself: the text isn't focused, so the keys still scroll the page */
.text .caret { position: absolute; width: 2px; margin-left: -1px; background: var(--fg); pointer-events: none; animation: caret 1s steps(1) infinite; }
@keyframes caret { 50% { opacity: 0; } }
.weights { display: flex; gap: var(--space-xs); }
.weights button {
  display: grid; place-items: center;
  width: 3.25rem; height: 3.25rem;
  border: 0; border-radius: var(--radius-sm);
  background: none; color: var(--fg); cursor: pointer;
  transition: background-color var(--dur-micro) var(--ease-out), transform var(--dur-micro) var(--ease-out);
}
.weights button[aria-pressed="true"] { background: var(--white); }
.weights button.is-pressed { background: var(--white); transform: scale(0.92); }
@media (hover: hover) { .weights button:hover { background: color-mix(in oklab, var(--white) 60%, transparent); } }
/* four bars on a quarter-em pitch: the heaviest fills it, a square */
.weights .wf { --yela: 0; font-size: 1.5rem; line-height: 1; white-space: pre; }

/* ── a chart, as the 60 fps slide and the game draw one: seven rows from the second over the ten inner columns –
   eight where what's under it keeps to a line – its scale's lines across them, each named in the first column,
   centred on its line; a line that counts in ink, named at its end ── */

.plot { --chart-h: calc(7 * var(--row)); grid-row: 1 / 9; align-self: start; margin: 0; display: grid; grid-template-columns: subgrid; }
.plot > * { grid-row: 1; height: var(--chart-h); }
.scale { grid-column: 2 / 12; position: relative; pointer-events: none; font: var(--label); color: var(--dim); }
.scale > span { position: absolute; left: 0; right: 0; bottom: calc(var(--at) * 100%); border-bottom: 1px solid var(--faint); }
.scale b { position: absolute; right: calc(100% + var(--space-md)); bottom: 0; transform: translateY(50%); font-weight: inherit; white-space: nowrap; font-variant-numeric: tabular-nums; }
/* over the bars; a label over it cuts it out from behind itself */
.scale .frame { border-bottom: 2px solid var(--fg); color: var(--fg); z-index: 1; }
/* its name at the end of its line, standing on it */
.scale i { position: absolute; right: 0; bottom: var(--space-xs); margin-bottom: var(--sink); padding-left: 0.3em; background: var(--bg); font-style: normal; white-space: nowrap; }
/* lines of bars over each other, standing on the floor; a step is a hundredth of the size, so the size is the
   chart's height over the steps it spans, --top */
.plot .bars { grid-column: 2 / 12; position: relative; touch-action: pan-y; user-select: none; -webkit-user-select: none; outline: none; }
.plot .line { --yela: -100; position: absolute; left: 0; bottom: 0; width: 100%; font-size: calc(var(--chart-h) * 100 / var(--top, 100)); line-height: 1; white-space: pre; letter-spacing: var(--gap); pointer-events: none; }

/* ── vertical shifts: marks after a bar move it up or down, a step or ten, so a bar stands anywhere: a range, a note,
   a value either side of a line. The slide: two waves in one line of characters, every bar of its own height, lift,
   width and roundness, across the slide on the six rows in its middle; a bar pressed is read out in the band, as the
   127 values' grid reads one, and dragged, moves ── */

.shifts .stage { grid-column: 1 / -1; }
/* the waves on the six rows in the slide's middle, across all twelve columns: the script sizes and places their bars.
   A bar can be dragged to the slide's edges, and pressed wherever it is; a finger anywhere else scrolls the page */
.waves { grid-column: 1 / -1; grid-row: 3 / 9; align-self: stretch; position: relative; }
.shifts.is-over { cursor: grab; }
.shifts.is-dragging { cursor: grabbing; user-select: none; -webkit-user-select: none; }
.waves .wave { --yela: -100; position: absolute; bottom: 0; line-height: 1; white-space: pre; letter-spacing: 0; }
/* the readout in the band: the character with its marks stacked over it, then its code points – the longest, a bar
   and nine marks of each kind, 'U+0164 U+0302 ×9 U+0301 ×9' */
.shifts .readout { --ems: calc(27 * 0.632 + 2 * 1.2); grid-area: 11 / 2 / 12 / 12; }

/* ── a game: a bird between pipes, every one a bar hanging from the ceiling or lifted to stand on the floor, the
   bird a short one lifted to its height; each pipe heavier than the last, till they make a cave. The field the whole
   slide, edge to edge, the pipes hanging from its very top; a round's count, once it ends, over the middle of it on
   the paper's own ── */

.game .stage { grid-area: 1 / 1 / -1 / -1; display: block; margin: calc(-1 * var(--pad-y)) calc(-1 * var(--pad-x)); }
.game .plot { --chart-h: 100svh; display: block; }
.flappy .bars { overflow: hidden; cursor: pointer; touch-action: manipulation; }
.flappy .is-lit { color: var(--accent); }
.flappy .score { position: absolute; top: 50%; left: 50%; translate: -50% -50%; padding: 0.25em 0.6em; border-radius: var(--radius-pill); background: var(--bg); font: 500 var(--text-big)/1 var(--font-mono); color: var(--fg); font-variant-numeric: tabular-nums; white-space: nowrap; pointer-events: none; }
.flappy .score:empty { display: none; }

/* past the last pipe, ॐ: stripes the field's height, each a line of bars set vertically, as Japanese is, the bars
   turned on their sides, centred on the line and square – a bar's height the stripe's width there. The glyph a link */
.flappy .end { position: absolute; top: 0; left: 0; height: 100%; }
.flappy .om { --yela: 0; --rond: 0; height: 100%; writing-mode: vertical-lr; text-orientation: sideways; white-space: pre; color: var(--fg); pointer-events: none; }
.flappy .prize { position: absolute; border-radius: var(--radius-md); }

/* ── 60 fps: what drawing an hour of speech costs, milliseconds on a log scale, the five ways for one operation ── */

.speed .stage { grid-column: 1 / -1; }
/* two rows to a decade, 0.1 ms on the floor and 1 s at the top; the frame at 60 fps, 16.7 ms, the line that counts,
   named by its rate.
   The five ways over the scale's ten columns, two each; a bar in the middle of each, its time standing on it, a couple
   of pixels clear so the fill behind the time never touches the bar, its name hanging from the floor. Each bar in
   its name's colour – wavefont's in ink, the others dim – but its plain values in the accent */
.lanes { grid-column: 2 / 12; position: relative; display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); }
.col { position: relative; display: grid; justify-items: center; align-content: end; height: var(--chart-h); }
.glyph { --yela: -100; font-size: var(--chart-h); line-height: 1; height: var(--chart-h); white-space: pre; letter-spacing: 0; color: var(--dim); }
.is-text .glyph { color: var(--fg); }
.is-ours .glyph { color: var(--accent); }
.col .ms { position: absolute; z-index: 2; bottom: calc(var(--h, 0) * var(--chart-h) + var(--space-xs) + 2px); margin-bottom: var(--sink); padding: 0 0.3em; background: var(--bg); font: var(--label); color: var(--fg); font-variant-numeric: tabular-nums; white-space: nowrap; }
.col.is-ours .ms { color: var(--accent); font-weight: 700; }
.col .name { position: absolute; top: calc(100% + var(--space-sm) + var(--sink)); font: var(--label); color: var(--dim); white-space: nowrap; }
.col.is-text .name { color: var(--fg); }
/* names wider than their columns: every other one a line lower */
.col:nth-child(even) .name { margin-top: calc(1lh + var(--space-xs)); }

/* ── voice messages: pills, round-capped bars close together, the time beside them – as the reference ── */

/* the chat on the columns in the middle, as many as a phone's width needs: the thread in the rows above the band,
   the composer in it */
.messages .stage { grid-row: 2 / 12; }
/* everything in the chat in one unit, a rem and a fifth: it scales as one */
.chat { --u: 1.2rem; font-size: calc(1.0625 * var(--u)); align-self: stretch; display: grid; grid-template-columns: minmax(0, 1fr); grid-template-rows: minmax(0, 1fr) var(--row) var(--row); }
.composer { grid-row: 3; align-self: end; }
/* no scrolling box: the thread keeps as many whole messages as fit */
.thread { position: relative; list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; justify-content: flex-end; gap: calc(0.75 * var(--u)); overflow: hidden; }
.msg { display: grid; grid-template-columns: minmax(0, 1fr); justify-items: start; }
.msg.out { justify-items: end; }
.bubble {
  --played: var(--dark);
  --rond: 100;
  display: flex; align-items: center; gap: calc(0.55 * var(--u));
  max-width: 100%;
  padding: calc(0.7 * var(--u)) calc(1.2 * var(--u)) calc(0.7 * var(--u)) calc(1.1 * var(--u));
  border-radius: var(--radius-pill);
  background: var(--gray);
  color: var(--dark);
}
.msg.out .bubble { --played: var(--white); background: var(--blue); color: var(--white); }
.msg.fresh .bubble { animation: arrive var(--dur-long) var(--ease-out); }
@keyframes arrive { from { opacity: 0; transform: translateY(calc(0.5 * var(--u))); } }
.bubble.textual { padding: calc(0.65 * var(--u)) calc(1.1 * var(--u)); border-radius: calc(1.35 * var(--u)); max-width: calc(22 * var(--u)); font-size: calc(1.0625 * var(--u)); line-height: 1.4; overflow-wrap: anywhere; }
.bubble .pp { display: grid; place-items: center; width: calc(1.4 * var(--u)); height: calc(2.5 * var(--u)); flex: none; padding: 0; border: 0; background: none; color: inherit; font-size: calc(1.25 * var(--u)); cursor: pointer; }
.bubble .wave, .composer-tape { --yela: 0; font-size: calc(2.6 * var(--u)); line-height: 1; white-space: pre; letter-spacing: var(--gap); }
.bubble .wave { color: inherit; cursor: pointer; min-width: 0; overflow: hidden; }
/* playing, the bars ahead dim; the played ones take the ink back */
.bubble.is-playing .wave { color: color-mix(in oklab, currentColor 40%, transparent); }
.bubble .dur { font: 500 calc(0.875 * var(--u))/1.4 var(--font-mono); font-size: calc(0.8125 * var(--u)); opacity: 0.75; font-variant-numeric: tabular-nums; }
/* the other side, recording: its bars come in behind a red dot */
.bubble.live .wave { cursor: default; }
.bubble .rec, .composer-dot { width: calc(0.55 * var(--u)); height: calc(0.55 * var(--u)); flex: none; border-radius: 50%; background: var(--red); animation: blink 1s var(--ease-in-out) infinite alternate; }
.bubble .rec { margin: 0 calc(0.4 * var(--u)); }
@keyframes blink { to { opacity: 0.25; } }
.composer { display: flex; gap: calc(0.5 * var(--u)); align-items: center; }
.composer-field { flex: 1; min-width: 0; display: flex; align-items: center; gap: calc(0.75 * var(--u)); height: calc(3.25 * var(--u)); padding: 0 var(--u); border-radius: var(--radius-pill); background: var(--gray); color: var(--dim); overflow: hidden; }
.composer-input { flex: 1; min-width: 0; height: 100%; padding: 0; border: 0; background: none; color: var(--fg); font: inherit; outline: none; }
.composer-input::placeholder { color: var(--dim); }
.composer-field:focus-within { box-shadow: 0 0 0 2px var(--blue); }
.composer-tape { --rond: 100; flex: 1; min-width: 0; overflow: hidden; display: none; justify-content: flex-end; color: var(--dark); }
.composer-tape > span { flex: none; }
.composer-time { font: 500 calc(0.875 * var(--u))/1.4 var(--font-mono); font-variant-numeric: tabular-nums; }
.composer-dot { display: none; }
.composer.is-on .composer-input { display: none; }
.composer.is-on .composer-tape, .composer.is-on .composer-dot { display: flex; }
.mic { display: grid; place-items: center; width: calc(3.25 * var(--u)); height: calc(3.25 * var(--u)); flex: none; border: 0; border-radius: 50%; background: var(--blue); color: var(--white); font-size: calc(1.25 * var(--u)); cursor: pointer; }
.mic .i-send, .mic .i-stop, .composer.has-text .mic .i-mic, .composer.is-on .mic .i-mic { display: none; }
.composer.has-text .mic .i-send, .composer.is-on .mic .i-stop { display: inline; }
.composer.is-on .mic { background: var(--red); }
/* the triangle and the pause bars have round corners, as the bars have round caps */
.round { stroke: currentColor; stroke-width: 2; stroke-linejoin: round; }

/* ── Voice Memos, fitted to the screen: name, the waveform band under a fixed playhead, ruler, time, transport, record ── */

/* a device of its own, edge to edge, on the slide's rows: the name hanging from the second, the band over the next
   five, the ruler under it, the time standing on the ninth, the transport on the tenth; then the record button
   centred on the last two rows, as a phone keeps it at the bottom; a note beside it, on the floor */
.memo { padding-inline: 0; grid-template-columns: minmax(0, 1fr); }
.vm { --band-bg: color-mix(in oklab, var(--white) 6%, var(--dark)); --rec: min(4.25rem, var(--row)); grid-row: 2 / 13; align-self: stretch; display: grid; grid-template-columns: minmax(0, 1fr); grid-template-rows: subgrid; justify-items: center; }
/* all in the one column, placed: the note shares the record button's row rather than making a column of its own */
.vm > * { grid-column: 1; }
.vm button { border: 0; background: none; padding: 0; color: inherit; cursor: pointer; }
.vm button:disabled { cursor: default; }
.vm-top { grid-row: 1; align-self: start; display: grid; justify-items: center; padding: 0 var(--space-md); }
/* the name's capitals from the row's top line: the field's padding and half its leading above them */
.vm-title { width: min(100%, 22rem); margin-top: calc(var(--sink) - 0.1em); padding: 0.1em 0.35em; border: 0; border-radius: var(--radius-sm); background: none; color: inherit; font: 600 clamp(1.25rem, 1rem + 1vw, 1.75rem)/1.2 var(--font-sans); text-align: center; outline: none; }
.vm-title:focus-visible { outline: none; }
.vm-sub { display: flex; justify-content: center; gap: 0.6em; margin-top: 0.25em; font: var(--label); color: var(--dim); font-variant-numeric: tabular-nums; }
.vm-wave { grid-row: 2 / 7; position: relative; align-self: stretch; justify-self: stretch; background: var(--band-bg); overflow: hidden; touch-action: pan-y; user-select: none; -webkit-user-select: none; cursor: grab; outline: none; }
.vm-wave.is-dragging { cursor: grabbing; }
.vm-wave:focus-visible { box-shadow: inset 0 0 0 2px var(--blue); }
.vm[data-state="recording"] .vm-wave { cursor: default; }
.vm-bars {
  --yela: 0;
  --played: var(--white);
  position: absolute; top: 50%; left: 0;
  line-height: 1;
  white-space: pre;
  color: var(--dim);
  transform: translate(50vw, -50%);
  will-change: transform;
}
.vm[data-state="recording"] .vm-bars, .vm[data-state="paused"] .vm-bars { --played: var(--red); color: var(--red); }
.vm-head { position: absolute; left: 50%; top: 0.5rem; bottom: 0.5rem; width: 2px; margin-left: -1px; background: var(--blue); pointer-events: none; }
.vm-head::before, .vm-head::after { content: ""; position: absolute; left: 50%; width: 0.6rem; height: 0.6rem; margin-left: -0.3rem; border-radius: 50%; background: inherit; }
.vm-head::before { top: -0.3rem; }
.vm-head::after { bottom: -0.3rem; }
.vm[data-state="recording"] .vm-head, .vm[data-state="paused"] .vm-head { background: var(--red); }
.vm-ruler { grid-row: 7; position: relative; align-self: start; justify-self: stretch; height: 2.25rem; overflow: hidden; }
.vm-scale {
  position: absolute; top: 0; left: 0; height: 100%;
  /* a tick every quarter second, a taller one every second */
  background-image: repeating-linear-gradient(to right, var(--faint) 0 1px, transparent 1px var(--sec)), repeating-linear-gradient(to right, var(--faint) 0 1px, transparent 1px calc(var(--sec) / 4));
  background-size: 100% 0.6rem, 100% 0.3rem;
  background-repeat: no-repeat;
  will-change: transform;
}
.vm-scale span { position: absolute; top: 0.9rem; transform: translateX(-50%); font: var(--label); font-size: 0.75rem; color: var(--dim); font-variant-numeric: tabular-nums; }
.vm-time { grid-row: 8; align-self: end; margin-bottom: var(--sink); font: 500 clamp(2.5rem, 1.5rem + 4.5vw, 4.5rem)/1 var(--font-sans); font-variant-numeric: tabular-nums; letter-spacing: -0.01em; }
.vm-ctrl { grid-row: 9; align-self: end; display: flex; align-items: center; justify-content: center; gap: clamp(2.5rem, 10vw, 5rem); }
.vm-ctrl svg { display: block; fill: currentColor; }
.vm-ctrl text { font: 700 8px var(--font-sans); fill: currentColor; }
.vm-back svg, .vm-fwd svg { width: 1.75rem; height: 1.75rem; }
.vm-play svg { width: 2.1rem; height: 2.1rem; }
.vm-ctrl button { padding: 0.5rem; border-radius: 50%; }
.vm-ctrl button:disabled { color: var(--faint); }
/* the record button a row high where a row is less than its own size, in proportion */
.vm-foot { grid-row: 10 / 12; align-self: center; position: relative; display: flex; justify-content: center; align-items: center; width: min(100%, 30rem); height: var(--rec); }
.vm-rec { position: relative; display: grid; place-items: center; width: var(--rec); height: var(--rec); border-radius: calc(var(--rec) / 2); box-shadow: inset 0 0 0 calc(var(--rec) * 0.052) var(--white); transition: width var(--dur-short) var(--ease-out); }
.vm-rec span { display: block; width: calc(var(--rec) * 0.79); height: calc(var(--rec) * 0.79); border-radius: 50%; background: var(--red); transition: width var(--dur-short) var(--ease-out), height var(--dur-short) var(--ease-out), border-radius var(--dur-short) var(--ease-out); }
.vm[data-state="recording"] .vm-rec { width: calc(var(--rec) * 2.12); }
.vm[data-state="recording"] .vm-rec span { width: calc(var(--rec) * 0.45); height: calc(var(--rec) * 0.38); border-radius: 0; background: linear-gradient(to right, var(--red) 0 38%, transparent 38% 62%, var(--red) 62%); }
/* as in Voice Memos: Done shows while a recording is open */
.vm .vm-done { position: absolute; right: var(--space-lg); font-size: var(--text-body); color: var(--accent); visibility: hidden; }
.vm:not([data-state="idle"]) .vm-done { visibility: visible; }
/* a note from the second column of the other slides, standing on the floor beside the record button, clear of it */
.vm-note { --lead: calc(var(--pad-x) + (100cqw - 2 * var(--pad-x)) / 12); grid-row: 11; align-self: end; justify-self: start; max-width: calc(50% - var(--rec) - var(--lead)); margin: 0 0 var(--sink) var(--lead); font: var(--label); color: var(--dim); }

/* ── journey: the years in a line down the stage – those that brought something in blue, with what they brought, the
   rest in gray between – each year a row, and down the screen's left edge, beside them, the months' commits, a bar
   each ── */

.journey { --edge: calc(var(--pad-x) + var(--col)); }
.journey .stage { grid-row: 2 / 12; }
/* the years share the stage's height: each what it takes, and the rest in equal parts; the stage grows only when
   they take more than it has */
.milestones { grid-row: 1 / -1; align-self: stretch; list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: minmax(0, 1fr); }
/* the years and what they brought in the one label, as the other slides' small text is. A line of it at least, a year
   alone as tall as one with a line to say, so the years step evenly. A year the stage's first column – its first two on
   a phone, where its four digits are wider than one – what it brought the rest: columns as long as the slide's, not a
   subgrid of them: WebKit sizes a subgrid's row in a subgrid for its text a line shorter than it wraps to */
.milestones li { position: relative; display: grid; grid-template-columns: calc(2 * var(--col)) minmax(0, 1fr); align-content: start; align-items: baseline; font: var(--label); min-height: calc(1lh + var(--space-sm)); padding-bottom: var(--space-sm); }
.milestones time { margin-top: var(--sink); color: var(--dim); }
.milestones li:has(> span) time { color: var(--accent); }
.milestones li > span { grid-column: 2; margin-top: var(--sink); }
/* a year's months, in the blue of the years that brought something, bars standing on the screen's edge and reaching
   to the stage's, less a gap: a line set on its side, its floor to the left, as text turned a quarter goes; the script
   spaces the months evenly down the years */
.months { --yela: -100; position: absolute; left: calc(-1 * var(--edge)); writing-mode: vertical-lr; text-orientation: sideways; font-size: calc(var(--edge) - var(--space-md)); line-height: 1; white-space: pre; color: var(--accent); }
.milestones a { text-decoration-color: color-mix(in oklab, currentColor 35%, transparent); }
/* a version is a tag: white on blue */
.tag { display: inline-block; padding: 0 0.4em; border-radius: 2px; background: var(--accent); color: var(--white); font: var(--label); text-decoration: none; }
@media (hover: hover) { a.tag:hover { background: var(--fg); } }

/* ── get: bars of your own, and where the font is. A wave to take or draw on with a pencil, the screen's width: its
   bars standing on the fourth row's foot, four rows high, or hanging from it as deep; play and copy in the slide's top
   right cell; the links under it, as the features on the first slide; the credits and ॐ in the band ── */

.pad { --rows: 4; grid-area: 1 / 1 / 9 / -1; position: relative; margin-inline: calc(-1 * var(--pad-x)); }
/* the pencil draws the bar under its tip from the line to the tip, over the line or under it; a finger's tap or
   stroke across draws, its swipe up or down scrolls the page */
.pad-bars {
  --yela: -100;
  height: calc(2 * var(--rows) * var(--row));
  font-size: calc(var(--rows) * var(--row)); line-height: 1; white-space: pre; letter-spacing: var(--gap);
  touch-action: pan-y; user-select: none; -webkit-user-select: none;
  cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cpath d='M3 21l1.3-5L16.4 3.9a1.9 1.9 0 0 1 2.7 0l1 1a1.9 1.9 0 0 1 0 2.7L8 19.7z' fill='white' stroke='black' stroke-width='1.2' stroke-linejoin='round'/%3E%3Cpath d='M14.6 5.7l3.7 3.7M4.3 16l3.7 3.7' stroke='black' stroke-width='1.2'/%3E%3C/svg%3E") 3 21, crosshair;
}
/* play and copy: icons in the top right cell, as a slide's switch is, copy's ink on the grid's edge; over the pencil's
   line, which reaches the top row too */
.pad-tools { position: relative; z-index: 1; grid-area: 1 / 12 / 2 / 13; justify-self: end; align-self: center; display: flex; margin-right: -0.9rem; }

/* the links, as the first slide's features are: bold and spaced, each after its icon – on a phone, a column, a line
   each as far apart as the features are; on a wider screen, two columns, a row each, standing on the tenth row
   above the credits: the font's first, Google Fonts and Download, then the code's, GitHub and npm */
.links {
  grid-row: 8 / 10; align-self: end; list-style: none; margin: 0; padding: 0;
  display: grid; align-items: end; justify-items: start; row-gap: var(--space-lg);
  font: 700 var(--text-lead)/1 var(--font-sans); letter-spacing: 0.3em;
}
.links li { margin-bottom: var(--sink); }
.links li:nth-child(2) { order: 2; }
.links li:nth-child(3) { order: 1; }
/* a link reaches a little above and below its line, for a finger, in no room of its own */
.links a { display: inline-flex; align-items: center; gap: 0.6em; padding-block: var(--space-sm); margin-block: calc(-1 * var(--space-sm)); text-decoration: none; white-space: nowrap; }
@media (hover: hover) { .links a:hover { color: var(--accent); } }
/* who and under what, at the band's start */
.credits { margin: 0; }
.credits a { color: var(--fg); }
/* the sign itself, after the license, as quiet as the credits' words */
.credits .om { color: var(--dim); text-decoration: none; }

/* ── wider screens ──────────────────────────────────────── */

@media (min-width: 36rem) {
  /* two columns, the second standing under the fifth bar – the f; a row each */
  .facts { grid-template-columns: calc(4 * var(--pitch)) auto; grid-template-rows: repeat(3, var(--row)); grid-auto-flow: column; row-gap: 0; }
}

@media (width > 40rem) {
  .links { grid-template-columns: auto auto; grid-template-rows: repeat(2, var(--row)); justify-content: start; gap: 0 var(--space-2xl); }
  .links li:is(:nth-child(2), :nth-child(3)) { order: 1; }
}

@media (min-width: 48rem) {
  :root { --wght-bars: 500; }
  .chat { grid-column: 2 / 10; }
  /* a year its column on the stage */
  .milestones li { grid-template-columns: var(--col) minmax(0, 1fr); }
  /* sliders on the middle eight columns: names in two, values in one */
  .sliders { grid-column: 3 / 11; }
  .axis .name { grid-column: 1 / 3; }
  .axis input { grid-column: 3 / 8; }
  .axis output { grid-column: 8 / -1; }
}

@media (min-width: 64rem) {
  .chat { grid-column: 3 / 9; }
  /* the ways' names on one line, the band's tabs on one: the chart a row taller */
  .col:nth-child(even) .name { margin-top: 0; }
  .plot { --chart-h: calc(8 * var(--row)); }
}

@media (min-width: 90rem) {
  :root { --wght-bars: 600; }
  .chat { grid-column: 4 / 8; }
}

@media (max-width: 40rem) {
  /* the name narrower than its rows: three of them */
  .mark { --bar-rows: 3; }
  /* the wave a row shorter either way; the links a column under it, clear of the credits wrapping above the band, far
     enough apart for a finger */
  .pad { --rows: 3; grid-row: 1 / 7; }
  .links { grid-row: 7 / 9; }
  /* the chart a column narrower, its scale's lines named in the two columns left of it; the ways' times off it,
     the scale reads them */
  .scale, .lanes { grid-column: 3 / 12; }
  .scale b { right: calc(100% + var(--space-xs)); }
  .col .ms { display: none; }
  /* the operations only, one line from where the scale's longest names start – six characters and a gap before the
     chart – to the chart's end */
  .speed .browsers { display: none; }
  .speed .status { grid-column: 3 / 12; margin-left: calc(-1 * (var(--space-xs) + 6 * 0.632em)); }
  .speed .ops { flex: 1; flex-wrap: nowrap; justify-content: space-between; }
  .speed .ops button { padding: 0 0.35em; }
  /* the chat to the grid's edges */
  .messages .stage { grid-column: 1 / -1; }
  /* a readout the width of the slide, its copy button at the end of the line */
  .readout .copy { margin-left: auto; margin-right: -0.5rem; }
  .shifts .readout { --span: calc(12 * var(--col)); grid-column: 1 / -1; }
  /* the status wraps to lines: it may take the row above it too, still standing on the eleventh's foot. The weights
     and the count on one line */
  .status { grid-row: 10 / 12; column-gap: var(--space-md); }
  .weights { gap: var(--space-2xs); }
  .weights button { width: 2.25rem; height: 2.25rem; }
}

/* upright screens: a row is tall for a line of text, so it takes two */
@media (max-aspect-ratio: 1 / 1) {
  .doc { --lh: calc(var(--row) / 2); }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: 150ms !important; animation-iteration-count: 1 !important; transition-duration: 150ms !important; }
}
