/* Glyph kit site. The visual language of traykov.cc: printed paper, one ink, square corners,
   Departure Mono for headings, labels and every character grid (it draws block and box characters
   at exactly one cell), Geist Sans for reading. Steps inside, curves across; no blur, no slide. */
@font-face { font-family: "Departure Mono"; src: url("fonts/DepartureMono-Regular.woff2") format("woff2"); font-display: block; }
@font-face { font-family: "Geist Sans"; src: url("fonts/geist-sans-latin-400-normal.woff2") format("woff2"); font-weight: 400; font-display: swap; }
@font-face { font-family: "Geist Sans"; src: url("fonts/geist-sans-latin-500-normal.woff2") format("woff2"); font-weight: 500; font-display: swap; }

:root {
  color-scheme: light;
  --ink: #080808;
  --paper: #fbfbf8;
  --panel: rgba(8, 8, 8, 0.035);
  --line: rgba(8, 8, 8, 0.16);
  --edge-strong: rgba(8, 8, 8, 0.28);
  --text-soft: rgba(8, 8, 8, 0.72);
  --text-caption: rgba(8, 8, 8, 0.68);
  --signal-ok: #2f743e;
  --signal-fail: #651b13;
  --pixel: "Departure Mono", ui-monospace, Menlo, monospace;
  --sans: "Geist Sans", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --px-11: 11px; --px-22: 22px; --px-33: 33px; --px-44: 44px; --px-66: 66px;
  --space-1: 6px; --space-2: 10px; --space-3: 14px; --space-4: 18px; --space-5: 28px; --space-6: 42px; --space-7: 72px;
  --hairline: 1px;
  --tap: 44px;
  --measure: 1180px;
  --step: 120ms;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --ink: #f4f2ea; --paper: #0c0c0b; --panel: rgba(244, 242, 234, 0.06); --line: rgba(244, 242, 234, 0.24);
    --edge-strong: rgba(244, 242, 234, 0.34); --text-soft: rgba(244, 242, 234, 0.78); --text-caption: rgba(244, 242, 234, 0.74);
    --signal-ok: #89f1b5; --signal-fail: #dc7351;
  }
}
:root[data-theme="dark"] {
  color-scheme: dark;
  --ink: #f4f2ea; --paper: #0c0c0b; --panel: rgba(244, 242, 234, 0.06); --line: rgba(244, 242, 234, 0.24);
  --edge-strong: rgba(244, 242, 234, 0.34); --text-soft: rgba(244, 242, 234, 0.78); --text-caption: rgba(244, 242, 234, 0.74);
  --signal-ok: #89f1b5; --signal-fail: #dc7351;
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; -webkit-tap-highlight-color: transparent; }
/* Touch: a tap answers at once (no double-tap wait), and a held control never selects its label. */
button, a, summary, input, textarea, [role="tab"] { touch-action: manipulation; }
button, summary, .chip, .button, [role="tab"] { -webkit-user-select: none; user-select: none; }
/* Press: the control steps down one notch while held. Instant, like the kit's steps; no easing. */
button:active:not(:disabled), .button:active, summary:active { transform: scale(0.97); }
body { margin: 0; overflow-x: clip; background: var(--paper); color: var(--ink); font: 400 16px/1.6 var(--sans); -webkit-font-smoothing: antialiased; }
a { color: inherit; text-underline-offset: 3px; }
:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
img { display: block; max-width: 100%; height: auto; }
h1, h2, h3 { margin: 0; font-family: var(--pixel); font-weight: 400; }
p { margin: 0; }

.shell { width: min(var(--measure), 100% - 2 * var(--space-4)); margin: 0 auto; }
.label { color: var(--text-caption); font: 400 var(--px-11)/1.4 var(--pixel); text-transform: uppercase; }

/* Header */
.top { position: sticky; top: 0; z-index: 2; background: var(--paper); border-bottom: var(--hairline) solid var(--ink); }
.top .shell { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); min-height: 56px; }
.brand { display: flex; white-space: nowrap; align-items: center; gap: var(--space-2); text-decoration: none; font: 400 var(--px-22)/1 var(--pixel); }
.brand .mark { letter-spacing: 0; } /* the logo: ░▒▓█ touching, at the 22 px the name is set in (docs/brand.md) */
.nav { display: flex; gap: var(--space-4); margin-left: auto; font-size: .9rem; }
.nav a { white-space: nowrap; text-decoration: none; padding-block: var(--space-1); border-bottom: 2px solid transparent; }
.nav a[aria-current="page"] { border-bottom-color: var(--ink); }
@media (hover: hover) and (pointer: fine) { .nav a:hover { border-bottom-color: var(--ink); } }
/* Theme and feedback: square buttons on a hairline, their icons drawn on the logo's pixel grid. The
   hit area reaches 40 px to a mouse and 44 px to a finger; 14 px between keeps the two apart. */
.tools { display: flex; gap: var(--space-3); }
.icon-button { position: relative; flex: none; display: grid; place-items: center; width: 32px; height: 32px; padding: 0; border: var(--hairline) solid var(--ink); border-radius: 0; background: var(--paper); color: var(--ink); cursor: pointer; }
.icon-button::after { content: ""; position: absolute; inset: -4px; }
.icon-button--small { width: 28px; height: 28px; }
.icon-button--small::after { inset: -6px; }
@media (hover: hover) and (pointer: fine) { .icon-button:hover { background: var(--ink); color: var(--paper); } }
.pixel-icon { display: block; }
.glyph-icon { display: block; font: 400 var(--px-11)/14px var(--pixel); letter-spacing: 0; }
/* A footer link that opens something rather than going somewhere. */
.link-button { padding: 0; border: 0; background: none; color: inherit; font: inherit; text-decoration: underline; text-underline-offset: 3px; cursor: pointer; }

/* Feedback: one dialog, opened from the header and the footer. It appears at once, like a step. */
.feedback { width: min(520px, 100% - 2 * var(--space-4)); max-height: calc(100dvh - 2 * var(--space-4)); padding: 0; overflow: auto; overscroll-behavior: contain; border: var(--hairline) solid var(--ink); border-radius: 0; background: var(--paper); color: var(--ink); }
.feedback::backdrop { background: rgba(8, 8, 8, 0.45); }
.feedback__form { display: grid; gap: var(--space-4); padding: var(--space-5); }
.feedback__head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); }
.feedback h2 { font-size: var(--px-22); line-height: 1.2; }
.feedback__fields { display: grid; gap: var(--space-4); }
.field { display: grid; gap: var(--space-1); }
.field > span { color: var(--text-caption); font: 400 var(--px-11)/1.4 var(--pixel); text-transform: uppercase; }
.field textarea, .field input { width: 100%; padding: var(--space-2) var(--space-3); border: var(--hairline) solid var(--ink); border-radius: 0; background: var(--paper); color: var(--ink); font: 400 16px/1.5 var(--sans); }
.field textarea { min-height: 7.5em; resize: vertical; }
.field :is(textarea, input):focus-visible { outline-offset: 0; }
.feedback__trap { position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden; }
.feedback__status:empty { display: none; }
/* The anti-spam check takes no room until it needs a click. */
.feedback__check:not([data-asking]) { height: 0; margin-top: calc(-1 * var(--space-4)); overflow: hidden; }
.feedback__status { font-size: .9rem; }
.feedback__status[data-tone="problem"] { color: var(--signal-fail); }
.feedback__status[data-tone="good"] { color: var(--signal-ok); }
.feedback__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3) var(--space-5); }
.feedback__done { display: none; }
.feedback__form[data-state="sent"] :is(.feedback__fields, .feedback__actions) { display: none; }
.feedback__form[data-state="sent"] .feedback__done { display: block; }

/* Sections */
main { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-7); padding-block: var(--space-6) var(--space-7); }
.section { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-5); }
.heading { display: grid; justify-items: start; gap: var(--space-3); }
.heading h2 { font-size: var(--px-33); line-height: 1.1; }
.heading > p:not(.label) { max-width: 62ch; color: var(--text-soft); }
.kicker { color: var(--text-caption); font: 400 var(--px-11)/1.4 var(--pixel); }

.visually-hidden { position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* Hero: the name fills the width ("Glyph kit." is 6.36 em wide in Departure Mono), then the line and the showcase. */
.hero { position: relative; isolation: isolate; display: grid; gap: var(--space-4); overflow-x: visible; overflow-y: clip; padding-bottom: var(--space-4); }
/* The dither field behind the hero (parallax.js): faint, and drawn by the script only. */
/* The field breathes: its opacity rises and falls very gently, in small steps. */
@keyframes field-breathe { 0%, 100% { opacity: .05; } 50% { opacity: .1; } }
.hero__field { animation: field-breathe 7s steps(14, end) infinite; }
@media (prefers-reduced-motion: reduce) { .hero__field { animation: none; } }
.hero__field { position: absolute; top: calc(var(--space-6) * -1); left: calc(50% - 50vw); width: 100vw; z-index: -1; margin: 0; overflow: hidden; color: var(--ink); opacity: .07; font: 400 22px/1 var(--pixel); letter-spacing: 0; white-space: pre; pointer-events: none; }
.hero h1 { font-size: calc(min(var(--measure), 100vw - 2 * var(--space-4)) / 6.5); line-height: .9; white-space: nowrap; }
.hero__body { display: grid; grid-template-columns: minmax(0, .75fr) minmax(0, 1.25fr); gap: var(--space-6); align-items: center; }
.hero__inner { display: grid; gap: var(--space-4); }
.hero__copy { display: grid; justify-items: stretch; align-content: center; gap: var(--space-5); }
.prompt--hero textarea { min-height: 84px; }
.lead { max-width: 52ch; font-size: clamp(1.25rem, 2.2vw, 1.75rem); line-height: 1.3; letter-spacing: -.01em; }

/* Install: a full-width strip under the hero, its columns aligned with the page. */
.strip { position: relative; z-index: 1; display: grid; width: 100vw; margin-inline: calc(50% - 50vw); padding-inline: max(var(--space-4), (100vw - var(--measure)) / 2); border-block: var(--hairline) solid var(--ink); background: color-mix(in srgb, var(--ink) 3.5%, var(--paper)); }
/* One row per way to install: label, the commands in one fixed-width column, a note. */
.strip__row { display: grid; grid-template-columns: 10rem auto minmax(0, 1fr); gap: var(--space-2) var(--space-4); align-items: center; padding-block: var(--space-2); }
.strip__row + .strip__row { border-top: var(--hairline) solid var(--line); }
.strip__cmds { display: flex; flex-wrap: wrap; gap: var(--space-2); min-width: 0; }
.strip__cmds .cmd { min-width: 0; }
.strip__cmds .button { justify-self: start; }
.strip__note { color: var(--text-caption); font-size: .78rem; }
.cmd { display: inline-flex; align-items: stretch; max-width: 100%; border: var(--hairline) solid var(--line); background: var(--paper); }
.cmd code { min-width: 0; padding: 5px var(--space-2); white-space: pre-wrap; overflow-wrap: anywhere; font: 400 .74rem/1.5 ui-monospace, Menlo, monospace; }
.cmd button { flex: none; display: grid; place-items: center; width: 30px; border: 0; border-left: var(--hairline) solid var(--line); background: transparent; color: var(--text-caption); cursor: pointer; }
.cmd button:focus-visible { color: var(--ink); box-shadow: inset 0 -2px 0 var(--ink); }
@media (hover: hover) and (pointer: fine) { .cmd button:hover { color: var(--ink); box-shadow: inset 0 -2px 0 var(--ink); } }
.cmd button[data-done] { color: var(--signal-ok); }
.icon { width: 14px; height: 14px; }
.cmd .icon--done, .cmd button[data-done] .icon--copy { display: none; }
.cmd button[data-done] .icon--done { display: block; }
.cmd__for { color: var(--text-caption); font-size: .8rem; }

/* Buttons: one primary per view, quiet text links otherwise. */
.actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3) var(--space-4); }
.button { display: inline-flex; align-items: center; gap: var(--space-2); min-height: var(--tap); padding: 0 var(--space-4); border: var(--hairline) solid var(--ink); background: var(--ink); color: var(--paper); font-weight: 500; text-decoration: none; }
@media (hover: hover) and (pointer: fine) { .button:hover { background: var(--paper); color: var(--ink); } }
.button--quiet { background: var(--paper); color: var(--ink); }
@media (hover: hover) and (pointer: fine) { .button--quiet:hover { background: var(--ink); color: var(--paper); } }
.button:disabled { opacity: .5; cursor: progress; }
.text-link { font-weight: 500; text-decoration: none; border-bottom: 2px dotted var(--ink); padding-bottom: 2px; }
@media (hover: hover) and (pointer: fine) { .text-link:hover { border-bottom-style: solid; } }

/* Framed demos */
.demo { margin: 0; display: grid; grid-template-rows: auto 1fr auto; border: var(--hairline) solid var(--edge-strong); background: var(--paper); }
.demo__bar { display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--space-2); padding: var(--space-3); border-bottom: var(--hairline) solid var(--line); }
.demo figcaption { padding: var(--space-3); border-top: var(--hairline) solid var(--line); color: var(--text-soft); font-size: .85rem; line-height: 1.55; }

/* Character grids: one cell per glyph, lines join, air comes from padding. */
.grid-figure { margin: 0; padding: var(--space-5); background: var(--panel); color: var(--ink); font: 400 var(--px-11)/1.25 var(--pixel); font-variant-ligatures: none; letter-spacing: 0; white-space: pre; }
.live { padding: var(--space-6) var(--space-5); }
.gk-e { opacity: .45; } .gk-m, .gk-m1, .gk-m2, .gk-m3, .gk-m4 { opacity: .28; } .gk-f { color: var(--text-caption); } .gk-x { color: var(--signal-fail); } .gk-ok { color: var(--signal-ok); }
.gl-ok { color: var(--signal-ok); } .gl-fail { color: var(--signal-fail); } .gl-mute { color: var(--text-caption); }
/* Skeletons: the structure faint, the content as dim placeholder cells. */
.sk { opacity: .32; } .sk-line { opacity: .5; }

/* Nothing on the site scrolls sideways. A figure is 11px where it fits; where its widest line (--cols,
   from the figure) is wider than its box, it shrinks to fill the box. At 11px a cell is 7px wide. */
.stage, .kind, .guide-figure, .pair__item { container-type: inline-size; }
:is(.kind, .guide-figure, .pair__item) .grid-figure { font-size: min(var(--px-11), (100cqi - 2 * var(--space-5)) * 11 / (7 * var(--cols))); }
/* A stage holds one figure in its middle. */
.stage { display: grid; place-items: center; min-width: 0; padding: var(--space-6) var(--space-5); background: var(--panel); }
.stage > .grid-figure { padding: 0; overflow: visible; background: transparent; font-size: min(var(--px-11), 100cqi * 11 / (7 * var(--cols))); }

/* The hero showcase: the dither press covers the whole frame between views. */
.showcase { position: relative; }
.showcase figcaption { display: flex; justify-content: space-between; align-items: center; gap: var(--space-3); }
.showcase figcaption .label { flex: none; line-height: 1; }
[data-showcase-state="pending"] [data-showcase-grid] { visibility: hidden; }
.showcase__press { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }

/* Measured readings */
.stats { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); border-top: var(--hairline) solid var(--ink); }
.stat { display: grid; align-content: start; gap: var(--space-3); padding: var(--space-5) var(--space-5) var(--space-5) 0; }
.stat + .stat { padding-left: var(--space-5); border-left: var(--hairline) solid var(--line); }
.stat strong { font: 400 var(--px-33)/1.1 var(--pixel); }
.stat > p:last-child { color: var(--text-soft); font-size: .9rem; line-height: 1.55; }
/* The study table fills its panel: at 11px a cell is 7px wide, so the size that fits --cols cells is
   100cqi × 11 / (7 × --cols), up to 22px. Below 679px the three measures side by side would go under
   11px (97 cells × 7px), so the stacked table, one measure at a time, shows instead. */
.study { container: study / inline-size; display: grid; justify-items: center; padding: var(--space-6) var(--space-5); background: var(--panel); }
.study .grid-figure { padding: 0; overflow: visible; background: transparent; font-size: min(var(--px-22), 100cqi * 11 / (7 * var(--cols))); line-height: 1.2; }
.study__stacked { display: none; }
@container study (width < 679px) { .study__wide { display: none; } .study__stacked { display: block; } }
.study .win { color: var(--signal-ok); } .study .lose { color: var(--text-caption); }
.stats-note { font: 400 var(--px-11)/1.6 var(--pixel); color: var(--text-caption); }

/* Release 0.3.0: four items, each a label, kit figures and one line. */
.highlights { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-6) var(--space-5); }
.highlights__item { display: grid; align-content: start; gap: var(--space-3); min-width: 0; padding-top: var(--space-4); border-top: var(--hairline) solid var(--ink); }
.highlights__item > p:last-child { max-width: 56ch; color: var(--text-soft); font-size: .92rem; }
.highlights figure { display: grid; gap: var(--space-1); min-width: 0; margin: 0; }
/* A figure that fits its box: 11px while it fits, smaller only when it doesn't (a cell is 0.64 em). */
.fit { position: relative; container-type: inline-size; display: grid; justify-items: center; min-width: 0; padding: var(--space-5); background: var(--panel); color: var(--ink); }
/* ↺ and Copy sit in the box's corners, clear of the figure. */
.fit .gk-replay-wrap { position: static; }
/* On touch, Copy is always shown, so it gets its own strip below the figure. */
@media (hover: none) { .fit.has-figure-copy { padding-bottom: calc(28px + 2 * var(--space-2)); } }
.fit .grid-figure { padding: 0; overflow: visible; background: transparent; color: var(--ink); font-size: min(var(--px-11), 100cqi / (0.64 * (var(--cols) + 1))); }
.fit[data-palette] .gk-d { color: var(--palette-data); }
.palettes { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-3) var(--space-2); }
.palettes .fit { padding: var(--space-4) var(--space-3); }
.edit { display: grid; justify-items: stretch; gap: var(--space-2); }
.edit .cmd { justify-self: center; }
.edits { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--space-1) var(--space-4); margin: 0; padding-top: var(--space-3); border-top: var(--hairline) solid var(--line); }
.edits dt { font: 400 var(--px-11)/1.9 var(--pixel); }
.edits dd { margin: 0; color: var(--text-soft); font-size: .9rem; }

/* Galleries */
.gallery { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 36rem), 1fr)); gap: var(--space-5); }
/* Two columns only at full width (2 × 576px and the gap fill the 1180px measure), so the types'
   figures keep 11px; narrower screens get one column. */
.areas { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 36rem), 1fr)); gap: var(--space-6) var(--space-5); }
.switch { display: grid; gap: var(--space-4); }
.switch__chips { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.switch__chips button { min-height: 40px; padding: 0 var(--space-3); border: var(--hairline) solid var(--line); background: transparent; color: var(--text-soft); font: 500 .9rem/1 var(--sans); cursor: pointer; }
@media (hover: hover) and (pointer: fine) { .switch__chips button:hover { color: var(--ink); border-color: var(--ink); } }
.switch__chips button[aria-selected="true"] { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.switch [role="tabpanel"][hidden] { display: none; }
.switch .stage { min-height: calc(var(--rows) * 1.25 * 11px + var(--space-6) * 2); }
.bento { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: var(--space-3); }
.bento__cell { position: relative; display: grid; grid-template-rows: auto auto 1fr; align-content: start; gap: var(--space-2); min-width: 0; padding: var(--space-3); border: var(--hairline) solid var(--line); background: var(--paper); transition: border-color 120ms; }
@media (hover: hover) and (pointer: fine) { .bento__cell:hover { border-color: var(--ink); } }
.bento__head { display: grid; gap: var(--space-1); }
.bento__head h3 { font-size: 1rem; line-height: 1.25; }
.bento__head a { color: inherit; text-decoration: none; }
.bento__head a::after { content: ""; position: absolute; inset: 0; }
.bento__head a:focus-visible { outline: none; }
.bento__cell:has(a:focus-visible) { outline: 2px solid var(--ink); outline-offset: 2px; }
.bento__peek { height: calc(var(--space-6) * 2.5); overflow: hidden; padding: var(--space-2); background: var(--panel); font: 400 var(--px-11)/1.25 var(--pixel); white-space: pre; color: var(--ink); -webkit-mask-image: linear-gradient(to right, #000 70%, transparent), linear-gradient(#000 70%, transparent); -webkit-mask-composite: source-in; mask-image: linear-gradient(to right, #000 70%, transparent), linear-gradient(#000 70%, transparent); mask-composite: intersect; }
.new { justify-self: start; padding: 2px 6px; background: var(--signal-ok); color: var(--paper); font: 400 var(--px-11)/1.2 var(--pixel); }
.area { display: grid; align-content: start; gap: var(--space-3); padding-top: var(--space-4); border-top: var(--hairline) solid var(--ink); }
.area h3 { font-size: var(--px-22); line-height: 1.2; }
.area > p { color: var(--text-soft); font-size: .88rem; }
.kind { display: grid; align-content: start; gap: var(--space-3); padding-top: var(--space-4); border-top: var(--hairline) solid var(--line); }
.kind h3 { font-size: var(--px-22); }
.kind__when { color: var(--text-soft); font-size: .92rem; }
.kind__watch { color: var(--text-caption); font-size: .85rem; }
.jump { position: sticky; top: var(--top-h, 57px); z-index: 1; display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-4); padding-block: var(--space-3); border-block: var(--hairline) solid var(--ink); background: var(--paper); font-size: .9rem; }
.jump a[aria-current="true"] { text-decoration: underline; text-underline-offset: 4px; }
.jump a { text-decoration: none; }
.jump__n { color: var(--text-caption); font-size: .8rem; }
@media (hover: hover) and (pointer: fine) { .jump a:hover { text-decoration: underline; } }

/* Guardrails and formats */
/* How to use: three steps on the home page; on the guide, one block per format. */
.steps { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr)); gap: var(--space-5); margin: 0; padding: 0; list-style: none; }
.steps > li { display: grid; align-content: start; justify-items: start; gap: var(--space-3); padding-top: var(--space-4); border-top: var(--hairline) solid var(--line); }
.steps > li > p:not(.label) { color: var(--text-soft); }
.asks { display: grid; gap: var(--space-2); margin: 0; padding: 0; list-style: none; color: var(--text-soft); }
.formats a { text-underline-offset: 3px; }
.guide { display: grid; gap: var(--space-6); }
/* Side by side only where both fit at 11px; otherwise one above the other. */
.pair { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, var(--cols) * 7px + 2 * var(--space-5)), 1fr)); gap: var(--space-4); min-width: 0; }
.pair__item { display: grid; align-content: start; gap: var(--space-2); min-width: 0; margin: 0; }
.pair__item .grid-figure { max-width: 100%; }
.guide-note { max-width: 62ch; color: var(--text-soft); }
.guide-figure { display: grid; justify-items: start; min-width: 0; }
.guide-figure .grid-figure { max-width: 100%; }
.guide-item { display: grid; grid-template-columns: minmax(0, 20rem) minmax(0, 1fr); gap: var(--space-5); padding-top: var(--space-5); border-top: var(--hairline) solid var(--line); scroll-margin-top: 80px; }
.guide-item__head { display: grid; align-content: start; gap: var(--space-3); }
.guide-item__head h3 { font-size: var(--px-22); }
.guide-item__head p { color: var(--text-soft); }
.guide-item__body { display: grid; align-content: start; gap: var(--space-2); min-width: 0; }
.guide-item__body .label:not(:first-child) { margin-top: var(--space-3); }
.ask-line { margin: 0; padding: var(--space-2) var(--space-3); border-left: 2px solid var(--ink); background: var(--panel); }
.cmds { display: grid; grid-template-columns: minmax(0, 1fr); justify-items: start; gap: var(--space-2); min-width: 0; }
.checks { display: grid; gap: var(--space-2); margin: 0; padding: 0; list-style: none; }
.checks li { position: relative; padding-left: 1.6em; color: var(--text-soft); }
.checks li::before { content: "■"; position: absolute; left: 0; color: var(--signal-ok); font-family: var(--pixel); }
.checks--big { grid-template-columns: repeat(auto-fit, minmax(min(100%, 22rem), 1fr)); gap: var(--space-3) var(--space-5); }
[id] { scroll-margin-top: 80px; }
/* Below 1000px the figure column would be narrower than the widest guide figure at 11px (616px). */
@media (max-width: 1000px) { .guide-item { grid-template-columns: minmax(0, 1fr); gap: var(--space-3); } }
.rules { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 22rem), 1fr)); gap: var(--space-5); margin: 0; padding: 0; list-style: none; }
.rules li { display: grid; gap: var(--space-2); padding-top: var(--space-3); border-top: var(--hairline) solid var(--line); color: var(--text-soft); font-size: .92rem; }
.rules strong { color: var(--ink); font-weight: 500; }

/* Changelog: CHANGELOG.md, one section a release. Lines stay at reading width; group names are labels. */
.heading > .prose { max-width: 62ch; color: var(--text-soft); }
.prose { display: grid; gap: var(--space-3); max-width: 72ch; }
.prose p, .prose ul { margin: 0; }
.prose h3 { margin-top: var(--space-4); color: var(--text-caption); font: 400 var(--px-11)/1.4 var(--pixel); text-transform: uppercase; }
.prose h3:first-child { margin-top: 0; }
.prose ul { display: grid; gap: var(--space-3); padding: 0; list-style: none; }
.prose li { position: relative; padding-left: 1.6em; color: var(--text-soft); }
.prose li::before { content: "■"; position: absolute; left: 0; color: var(--text-caption); font-family: var(--pixel); }
.prose strong { color: var(--ink); font-weight: 500; }
.prose a { text-underline-offset: 3px; }
.prose code { padding: 0 3px; background: var(--panel); font: 400 .86em/1 ui-monospace, Menlo, monospace; overflow-wrap: anywhere; }
.release + .release { padding-top: var(--space-6); border-top: var(--hairline) solid var(--ink); }
.release__head { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--space-2) var(--space-4); }
.release__head h2 { font-size: var(--px-33); line-height: 1.1; }
.release__head h2 a { text-decoration: none; }
@media (hover: hover) and (pointer: fine) { .release__head h2 a:hover { text-decoration: underline; text-underline-offset: 4px; } }
.release__head .text-link { margin-left: auto; font-size: .9rem; }
@media (max-width: 640px) {
  .release__head h2 { font-size: var(--px-22); }
  .release__head .text-link { margin-left: 0; }
}
.has-figure-copy { position: relative; }
.figure-copy { position: absolute; right: var(--space-2); bottom: var(--space-2); min-height: 28px; padding: 0 var(--space-2); border: var(--hairline) solid var(--line); background: var(--paper); color: var(--text-soft); font: 400 var(--px-11)/1 var(--pixel); cursor: pointer; opacity: 0; transition: opacity 120ms; }
.figure-copy:focus-visible, .figure-copy[data-done] { opacity: 1; }
@media (hover: hover) and (pointer: fine) { .has-figure-copy:hover .figure-copy { opacity: 1; } }
@media (hover: none) { .figure-copy { opacity: 1; } }
@media (hover: hover) and (pointer: fine) { .figure-copy:hover { color: var(--ink); border-color: var(--ink); } }
.outputs { display: grid; gap: var(--space-4); }
.outputs__bar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-3); }
.outputs__panel { position: relative; display: grid; }
.outputs__panel[hidden] { display: none; }
/* Each view fits its widest line to the panel, the same way as the study table (a cell is 7px at
   11px). Below 490px the drawing (70 cells) would go under 11px, so the narrower drawing shows. */
.outputs__view { container: outputs / inline-size; display: grid; justify-items: center; align-content: center; min-height: calc(var(--space-6) * 7); padding: var(--space-6) var(--space-5) calc(var(--space-6) + 40px); background: var(--panel); }
.outputs__view > .grid-figure { padding: 0; overflow: visible; background: transparent; font-size: min(var(--px-22), 100cqi * 11 / (7 * var(--cols))); line-height: 1.2; }
.outputs__text { justify-self: stretch; margin: 0; font: 400 min(var(--px-11), 100cqi * 11 / (7 * var(--cols)))/1.45 var(--pixel); white-space: pre; color: var(--ink); }
.outputs__narrow { display: none; }
@container outputs (width < 490px) { .outputs__wide { display: none; } .outputs__narrow { display: block; } }
.outputs__svg { width: min(100%, 880px); } .outputs__svg svg { width: 100%; height: auto; }
.outputs__copy { position: absolute; right: var(--space-4); bottom: var(--space-4); }
.outputs__also { color: var(--text-soft); font-size: .9rem; }
.gallery__note { display: grid; align-content: center; justify-items: start; gap: var(--space-4); padding: var(--space-5); }
.gallery__note h3 { font-size: var(--px-33); line-height: 1.1; }
.gallery__note > p:not(.label) { color: var(--text-soft); max-width: 44ch; }
.links { display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-5); }

/* Ask for one: an ask in, a figure out. The field is a hairline that inks on focus and flashes red
   twice when the ask can't be drawn. */
/* Demo: the ask and the examples on the left, the figure on the right. */
.try { display: grid; grid-template-columns: minmax(0, .8fr) minmax(0, 1.2fr); gap: var(--space-6); align-items: start; }
.try__form { display: grid; gap: var(--space-4); }
.try__out .stage { min-height: calc(var(--space-6) * 7); }
.try__hint { padding: var(--space-2) var(--space-3); border-top: var(--hairline) solid var(--line); color: var(--text-caption); font-size: .8rem; }
.try__hint[hidden] { display: none; }
.try__presets { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.try__presets button { min-height: 36px; padding: 0 var(--space-3); border: var(--hairline) solid var(--line); background: var(--paper); color: var(--ink); font: 500 .85rem/1 var(--sans); cursor: pointer; }
@media (hover: hover) and (pointer: fine) { .try__presets button:hover { border-color: var(--ink); box-shadow: inset 0 -3px 0 var(--ink); } }
.try__field { display: grid; gap: var(--space-2); }
.try__field textarea { min-height: 96px; padding: var(--space-2) 0; border: 0; border-bottom: var(--hairline) solid var(--line); border-radius: 0; background: transparent linear-gradient(var(--ink), var(--ink)) 0 100% / 0% 2px no-repeat; color: var(--ink); font: 400 1.05rem/1.45 var(--sans); resize: vertical; transition: background-size 160ms steps(4, end); }
.try__field textarea:focus { outline: 0; background-size: 100% 2px; }
.try__field textarea:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
.try__field textarea[data-invalid] { background-image: linear-gradient(var(--signal-fail), var(--signal-fail)); background-size: 100% 2px; animation: flash 480ms steps(1, end) both; }
@keyframes flash { 0%, 50% { background-size: 100% 2px; } 25%, 75% { background-size: 0% 2px; } 100% { background-size: 100% 2px; } }
.try__status { color: var(--text-soft); font-size: .92rem; }
.try__status[data-state="error"] { color: var(--signal-fail); }
.try__out summary { cursor: pointer; font-weight: 500; }
.try__spec { max-height: 18rem; margin: var(--space-3) 0 0; overflow: auto; color: var(--text-soft); font: 400 .78rem/1.6 ui-monospace, Menlo, monospace; white-space: pre-wrap; }

/* The note */
.note { display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); gap: var(--space-6); align-items: center; padding-top: var(--space-5); border-top: var(--hairline) solid var(--ink); }
.note img { border: var(--hairline) solid var(--line); }
.note__copy { display: grid; justify-items: start; gap: var(--space-4); }
.note__copy h2 { font-size: var(--px-44); line-height: 1.05; }
.note__copy > p:not(.label) { color: var(--text-soft); max-width: 46ch; }

footer { border-top: var(--hairline) solid var(--ink); padding-block: var(--space-5); color: var(--text-caption); font-size: .85rem; }
footer .shell { display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--space-3); }

@media (max-width: 900px) {
  .hero__body, .note, .try, .highlights { grid-template-columns: minmax(0, 1fr); }
  .strip__row { grid-template-columns: minmax(0, 1fr); align-items: start; }
  .bento { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .study { padding-inline: var(--space-4); }
  .stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .stat:nth-child(3) { padding-left: 0; border-left: 0; }
  .stat:nth-child(n+3) { border-top: var(--hairline) solid var(--line); }
}
@media (max-width: 640px) {
  .heading h2 { font-size: var(--px-22); }
  .note__copy h2 { font-size: var(--px-33); }
  .fit { padding: var(--space-4) var(--space-3); }
  .stats { grid-template-columns: minmax(0, 1fr); }
  .bento { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .bento__cell { grid-column: auto; }
  .stat, .stat + .stat { padding: var(--space-4) 0; border-left: 0; }
  .stat + .stat { border-top: var(--hairline) solid var(--line); }
  .top .shell { flex-wrap: wrap; gap: 0 var(--space-2); padding-block: var(--space-2); }
  /* The two buttons sit beside the name; the links take the row below, and wrap rather than scroll
     sideways on the narrowest phones. */
  .tools { margin-left: auto; }
  .nav { order: 1; width: 100%; margin-left: 0; flex-wrap: wrap; justify-content: space-between; gap: var(--space-1) var(--space-3); font-size: .9rem; }
  /* Four fit a phone row evenly; Changelog stays on larger screens (and the footer). */
  .nav a[href$="/changelog/"], .nav__long { display: none; }
  .feedback__form { padding: var(--space-4); }
  .install__hand span { display: block; margin-top: var(--space-1); }
  .grid-figure, .live, .stage { padding: var(--space-4); }
  .outputs__view { padding-inline: var(--space-4); }
  .stage > .grid-figure { padding: 0; }
  :is(.kind, .guide-figure, .pair__item) .grid-figure { font-size: min(var(--px-11), (100cqi - 2 * var(--space-4)) * 11 / (7 * var(--cols))); }
}
@media (prefers-reduced-motion: reduce) {
  .try__field textarea { transition: none; }
  .try__field textarea[data-invalid] { animation: none; }
}

/* ── Builder: one preview, with the prompt docked over its bottom edge and the suggestions on top ─── */
.builder { --dock: 10.5rem; position: relative; z-index: 1; }
.builder__preview { position: relative; display: grid; grid-template-columns: minmax(0, 1fr); grid-template-rows: auto auto; margin: 0; border: var(--hairline) solid var(--ink); background: var(--paper); }
.builder__bar { display: flex; align-items: center; gap: var(--space-4); min-height: 48px; padding: 0 var(--space-4) 0 var(--space-2); border-bottom: var(--hairline) solid var(--line); }
.builder__title { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.builder__hint { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text-caption); font-size: .8rem; }
.builder__hint[hidden] { display: none; }
[data-try-stamp] { flex: none; }
[data-try-stamp][data-off] { visibility: hidden; }
.tabs { display: flex; }
.tabs button { min-height: 48px; padding: 0 var(--space-3); border: 0; background: transparent; color: var(--text-caption); font: 500 .88rem/1 var(--sans); cursor: pointer; }
.tabs button[aria-selected="true"] { color: var(--ink); box-shadow: inset 0 -2px 0 var(--ink); }
/* A fixed size: the figure scales into the space above the dock. */
.builder__canvas { height: clamp(460px, 68vh, 640px); background: var(--panel); }
.builder__canvas > .stage { container-type: size; height: 100%; padding: var(--space-5) var(--space-5) calc(var(--dock) + var(--space-5)); background: transparent; }
.builder__canvas > .stage[hidden], .builder__data[hidden] { display: none; }
/* The figure fits the stage: 11px when it fits, smaller when it's wider (a glyph is 0.6364em), so
   nothing is cut off or has to scroll on a phone. */
.builder__canvas > .stage > .grid-figure { font-size: min(var(--px-11), 100cqw / (var(--cols) * 0.6364)); }
/* The Data view scrolls only in the space above the dock, so nothing sits under the prompt. */
.builder__data { position: relative; display: grid; grid-template-columns: minmax(14rem, .9fr) minmax(0, 1.4fr); align-content: start; gap: var(--space-3) var(--space-6); height: calc(100% - var(--dock) - var(--space-5) * 2 - var(--space-3)); margin: 0; padding: var(--space-5); overflow: auto; color: var(--ink); font: 400 .92rem/1.5 var(--sans); }
.data__about, .data__body { display: grid; align-content: start; gap: var(--space-2); min-width: 0; }
.data__body > h4:first-child { margin-top: 0; }
.data__empty { grid-column: 1 / -1; }
.data__meta { display: grid; grid-template-columns: 5rem minmax(0, 1fr); gap: var(--space-2) var(--space-4); max-width: 60rem; margin: 0; }
.data__meta dt { padding-top: 3px; }
.data__meta dd { margin: 0; color: var(--text-soft); }
.builder__data h4 { margin: var(--space-3) 0 0; }
@media (max-width: 900px) { .builder__data { grid-template-columns: minmax(0, 1fr); } }
.data__table { width: max-content; max-width: 100%; border-collapse: collapse; font-variant-numeric: tabular-nums; }
.data__table th { padding: var(--space-1) var(--space-4) var(--space-1) 0; border-bottom: var(--hairline) solid var(--ink); color: var(--text-caption); font: 400 var(--px-11)/1.4 var(--pixel); text-align: left; text-transform: uppercase; }
.data__table td { padding: var(--space-1) var(--space-4) var(--space-1) 0; border-bottom: var(--hairline) solid var(--line); vertical-align: top; }
.data__table td.is-number { text-align: right; }
.data__group { display: grid; gap: var(--space-3); }
.data__part { display: grid; gap: var(--space-1); }
.data__part > h4 { margin: 0; }
.data__list { margin: 0; color: var(--text-soft); }
.data__empty { margin: auto 0; color: var(--text-caption); }
.data__copy { justify-self: start; min-height: 36px; margin-top: var(--space-3); padding: 0 var(--space-3); border: var(--hairline) solid var(--line); background: var(--paper); color: var(--ink); font: 500 .8rem/1 var(--sans); cursor: pointer; }
.data__copy:focus-visible { border-color: var(--ink); }
@media (hover: hover) and (pointer: fine) { .data__copy:hover { border-color: var(--ink); } }

/* History: one row per figure built, newest first, in the same frame as the data. */
.builder__history { grid-template-columns: minmax(0, 1fr); }
.history { display: grid; margin: 0; padding: 0; list-style: none; border-top: var(--hairline) solid var(--line); }
.history__item { display: grid; grid-template-columns: minmax(0, 1fr) auto; border-bottom: var(--hairline) solid var(--line); }
.history__open { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 2px var(--space-4); min-height: 44px; padding: var(--space-2) var(--space-2) var(--space-2) 0; border: 0; background: transparent; color: var(--ink); text-align: left; cursor: pointer; }
.history__open:focus-visible { box-shadow: inset 3px 0 0 var(--ink); padding-left: var(--space-2); }
@media (hover: hover) and (pointer: fine) { .history__open:hover { box-shadow: inset 3px 0 0 var(--ink); padding-left: var(--space-2); } }
.history__open strong { font-weight: 500; }
.history__ask { grid-column: 1; display: -webkit-box; overflow: hidden; -webkit-box-orient: vertical; -webkit-line-clamp: 2; color: var(--text-soft); font-size: .85rem; line-height: 1.45; }
.history__when { grid-column: 2; grid-row: 1; color: var(--text-caption); font: 400 var(--px-11)/1.6 var(--pixel); text-transform: uppercase; white-space: nowrap; }
.history__remove { width: 44px; border: 0; background: transparent; color: var(--text-caption); font-size: 1.1rem; cursor: pointer; }
.history__remove:focus-visible { color: var(--ink); }
@media (hover: hover) and (pointer: fine) { .history__remove:hover { color: var(--ink); } }
.history__clear { justify-self: start; min-height: 36px; padding: 0; border: 0; border-bottom: 2px dotted var(--ink); background: transparent; color: var(--ink); font: 500 .85rem/1 var(--sans); cursor: pointer; }
.history__clear[data-confirm] { border-bottom-style: solid; color: var(--signal-fail); border-color: var(--signal-fail); }
.history__privacy { color: var(--text-caption); font-size: .8rem; }

/* The figure being changed sits first in the chips, pressed, with an × to start a new one. */
.chip--editing { display: inline-flex; align-items: center; gap: var(--space-2); background: var(--ink); color: var(--paper); border-color: var(--ink); }
.chip__x { opacity: .7; }

/* Export: a small menu under its button; off until a finished figure is on screen. */
.export { position: relative; }
.export > summary { display: flex; align-items: center; min-height: 48px; padding: 0 var(--space-3); color: var(--ink); font: 500 .88rem/1 var(--sans); list-style: none; cursor: pointer; }
.export > summary::-webkit-details-marker { display: none; }
.export[data-disabled] > summary { color: var(--text-caption); cursor: default; }
.export[open] > summary { box-shadow: inset 0 -2px 0 var(--ink); }
.export__menu { position: absolute; top: 100%; right: 0; z-index: 3; display: grid; min-width: 16rem; border: var(--hairline) solid var(--ink); background: var(--paper); }
.export__row { display: grid; grid-template-columns: minmax(0, 1fr) auto; border-bottom: var(--hairline) solid var(--line); }
.export__row:last-child { border-bottom: 0; }
.export__save, .export__copy { min-height: 40px; padding: 0 var(--space-3); border: 0; background: transparent; color: var(--ink); font: 400 .88rem/1 var(--sans); text-align: left; cursor: pointer; }
.export__copy { border-left: var(--hairline) solid var(--line); color: var(--text-soft); }
/* When the bar wraps, Colours starts its row: its menu opens rightwards so it stays on screen. */
@media (max-width: 900px) { .palette .export__menu { right: auto; left: 0; } }
@media (pointer: coarse) { .palette__item, .export__save, .export__copy { min-height: var(--tap); } }
.palette__swatch { display: inline-flex; padding: 0 2px; outline: var(--hairline) solid var(--line); font: 400 var(--px-11)/1 var(--pixel); letter-spacing: 0; user-select: none; }
.export > summary .palette__swatch { margin-right: var(--space-2); }
.palette__item { display: flex; align-items: center; gap: var(--space-2); width: 100%; min-height: 40px; }
.palette__item[aria-pressed="true"]::after { content: "■"; margin-left: auto; font: 400 var(--px-11)/1 var(--pixel); }
.stage[data-palette] { background: var(--panel); color: var(--ink); }
.stage[data-palette] .gk-d { color: var(--palette-data); }
.export__save:focus-visible, .export__copy:focus-visible { background: var(--panel); }
@media (hover: hover) and (pointer: fine) { .export__save:hover, .export__copy:hover { background: var(--panel); } }
@media (max-width: 640px) {
  /* On a phone both menus open the full width of the frame, under the bar, never off screen. */
  .builder__bar { position: relative; }
  .export { position: static; }
  .export__menu, .palette .export__menu { right: -1px; left: -1px; min-width: 0; }
}

/* The dock: chips, then the prompt box, sitting on the preview. */
.builder__dock { position: absolute; right: 0; bottom: var(--space-5); left: 0; display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-2); width: min(46rem, 100% - 2 * var(--space-5)); margin-inline: auto; }
.chips { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.chip { min-height: 32px; padding: 0 var(--space-3); border: var(--hairline) solid var(--line); background: var(--paper); color: var(--ink); font: 500 .82rem/1 var(--sans); cursor: pointer; }
.chip:focus-visible { border-color: var(--ink); box-shadow: inset 0 -2px 0 var(--ink); }
@media (hover: hover) and (pointer: fine) { .chip:hover { border-color: var(--ink); box-shadow: inset 0 -2px 0 var(--ink); } }
.chip[aria-pressed="true"] { border-color: var(--ink); background: var(--ink); color: var(--paper); }
.prompt { display: grid; border: var(--hairline) solid var(--ink); background: var(--paper); }
.prompt:focus-within { outline: var(--hairline) solid var(--ink); outline-offset: 0; }
/* The field grows with the ask (up to six lines), so a suggestion reads in full on a wide screen. */
.prompt textarea { min-height: 56px; max-height: calc(6 * 1.5rem + 2 * var(--space-3)); field-sizing: content; padding: var(--space-3); border: 0; border-radius: 0; background: transparent; color: var(--ink); font: 400 1rem/1.5 var(--sans); resize: none; }
.prompt textarea:focus { outline: 0; }
.prompt textarea[data-invalid] { box-shadow: inset 0 -2px 0 var(--signal-fail); animation: prompt-flash 480ms steps(1, end) both; }
@keyframes prompt-flash { 0%, 50% { box-shadow: inset 0 -2px 0 var(--signal-fail); } 25%, 75% { box-shadow: none; } 100% { box-shadow: inset 0 -2px 0 var(--signal-fail); } }
.prompt__bar { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); padding: 0 var(--space-2) var(--space-2) var(--space-3); }
.prompt__status { min-width: 0; color: var(--text-caption); font-size: .8rem; line-height: 1.4; }
.prompt__status[data-state="error"] { color: var(--signal-fail); }
.prompt__send { flex: none; display: inline-flex; align-items: center; gap: var(--space-1); min-height: 36px; padding: 0 var(--space-3); border: var(--hairline) solid var(--ink); background: var(--ink); color: var(--paper); font: 500 .88rem/1 var(--sans); cursor: pointer; }
@media (hover: hover) and (pointer: fine) { .prompt__send:hover { background: var(--paper); color: var(--ink); } }
.prompt__send:disabled { opacity: .5; cursor: progress; }
.prompt__send:focus-visible { outline-offset: 2px; }
/* After the first build the frame splits: the conversation on the left, the figure on the right,
   a drawn divider between them. Before it, the prompt sits docked on the preview as above. */
.builder__thread[hidden], .builder__divider[hidden] { display: none; }
.builder[data-layout="split"] .builder__preview { grid-template-columns: minmax(15rem, 22rem) auto minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr) auto; grid-template-areas: "thread divider bar" "thread divider canvas" "dock divider canvas"; }
.builder[data-layout="split"] .builder__thread { grid-area: thread; }
.builder[data-layout="split"] .builder__divider { grid-area: divider; }
.builder[data-layout="split"] .builder__bar { grid-area: bar; }
.builder[data-layout="split"] .builder__canvas { grid-area: canvas; }
.builder[data-layout="split"] .builder__dock { grid-area: dock; position: static; width: auto; margin: 0; padding: var(--space-3); }
.builder[data-layout="split"] .chip:not(.chip--editing) { display: none; }
.builder[data-layout="split"] .builder__canvas > .stage { padding-bottom: var(--space-5); }
.builder[data-layout="split"] .builder__data { height: 100%; }
.builder__divider { margin: 0; overflow: hidden; color: var(--ink); font: 400 var(--px-11)/1.25 var(--pixel); font-variant-ligatures: none; white-space: pre; user-select: none; }
.builder__thread { display: grid; grid-template-rows: auto minmax(0, 1fr); min-height: 0; }
.thread__head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); min-height: 48px; padding: 0 var(--space-3); border-bottom: var(--hairline) solid var(--line); }
.thread__new { min-height: 32px; padding: 0; border: 0; border-bottom: 2px dotted var(--ink); background: transparent; color: var(--ink); font: 500 .85rem/1 var(--sans); cursor: pointer; }
.thread__new:focus-visible { border-bottom-style: solid; }
@media (hover: hover) and (pointer: fine) { .thread__new:hover { border-bottom-style: solid; } }
.thread { display: grid; align-content: start; gap: var(--space-2); min-height: 0; margin: 0; padding: var(--space-3); overflow-y: auto; list-style: none; }
.thread__you { padding: var(--space-2) var(--space-3); background: var(--panel); overflow-wrap: anywhere; }
.thread__kit { display: flex; gap: var(--space-2); align-items: baseline; width: 100%; min-height: 32px; padding: var(--space-1) 0; border: 0; background: transparent; color: var(--text-soft); font: 400 .88rem/1.45 var(--sans); text-align: left; cursor: pointer; }
.thread__kit::before { content: "›"; font-family: var(--pixel); }
.thread__kit:focus-visible { color: var(--ink); }
@media (hover: hover) and (pointer: fine) { .thread__kit:hover { color: var(--ink); } }
.thread__kit[aria-current="true"] { color: var(--ink); box-shadow: inset 2px 0 0 var(--ink); padding-left: var(--space-2); }
.thread__v { margin-left: auto; color: var(--text-caption); font: 400 var(--px-11)/1.4 var(--pixel); text-transform: uppercase; }
.thread__fail { color: var(--signal-fail); font-size: .88rem; line-height: 1.45; }
@media (max-width: 640px) {
  .builder[data-layout="split"] .builder__preview { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto; grid-template-areas: "thread" "divider" "bar" "canvas" "dock"; }
  .builder[data-layout="split"] .builder__thread { max-height: 15rem; }
}

/* The Data tab can be edited: the figure redraws here, with no call to the model. */
.data__input { width: 100%; min-width: 4ch; padding: 2px 0; border: 0; border-bottom: var(--hairline) dotted var(--line); background: transparent; color: var(--ink); font: inherit; }
@media (hover: hover) and (pointer: fine) { .data__input:hover { border-bottom-color: var(--ink); } }
.data__input:focus { outline: 0; border-bottom: 2px solid var(--ink); }
.data__input[aria-invalid="true"] { border-bottom: 2px solid var(--signal-fail); }
td.is-number .data__input { text-align: right; font-variant-numeric: tabular-nums; }
.data__row-remove { width: 32px; min-height: 32px; border: 0; background: transparent; color: var(--text-caption); cursor: pointer; }
.data__row-remove:focus-visible { color: var(--ink); }
@media (hover: hover) and (pointer: fine) { .data__row-remove:hover { color: var(--ink); } }
.data__add { justify-self: start; min-height: 36px; padding: 0; border: 0; border-bottom: 2px dotted var(--ink); background: transparent; color: var(--ink); font: 500 .85rem/1 var(--sans); cursor: pointer; }
.data__add:focus-visible { border-bottom-style: solid; }
@media (hover: hover) and (pointer: fine) { .data__add:hover { border-bottom-style: solid; } }
.data__note { color: var(--text-caption); font-size: .8rem; }
.data__error { color: var(--signal-fail); font-size: .85rem; }
.data__error:empty { display: none; }
.builder > .cf-turnstile:empty { display: none; }
.builder > .cf-turnstile { margin-top: var(--space-3); }

@media (max-width: 640px) {
  .builder { --dock: 14.5rem; }
  /* Two rows on a phone: the tabs and the two menus, then the title and the stamp. Colours shows
     as its swatch alone (its name stays for screen readers). */
  .builder__bar { flex-wrap: wrap; gap: 0; padding: 0; }
  .builder__bar::before { content: ""; position: absolute; top: 48px; left: 0; right: 0; border-top: var(--hairline) solid var(--line); }
  .tabs { order: 0; flex: 1 0 auto; }
  .tabs button { padding: 0 var(--space-2); }
  .palette { order: 1; }
  .export { order: 2; }
  .export > summary { padding: 0 var(--space-2); }
  .palette__name { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .export > summary .palette__swatch { margin-right: 0; }
  .builder__title { order: 3; flex: 1 1 60%; min-height: 36px; padding: 0 var(--space-2); line-height: 36px; }
  [data-try-stamp] { order: 4; padding-right: var(--space-2); line-height: 36px; }
  .builder__hint { order: 5; flex-basis: 100%; padding: 0 var(--space-2) var(--space-2); }
  .prompt textarea { max-height: calc(4 * 1.5rem + 2 * var(--space-3)); }
  .builder__dock { width: calc(100% - 2 * var(--space-3)); bottom: var(--space-3); }
  /* Four suggestions in two rows, so the prompt stays low and nothing scrolls sideways. */
  .chip:nth-child(n+5 of [data-preset]) { display: none; }
  .builder__canvas { height: 520px; }
  .builder__canvas > .stage { padding: var(--space-4) var(--space-3) calc(var(--dock) + var(--space-4)); }
  .builder__data { height: calc(100% - var(--dock) - var(--space-3) * 2); padding: var(--space-4) var(--space-3); }
  /* Records fill the panel's width instead of sizing to twenty-character fields. */
  .data__table { width: 100%; }
}
/* Fields a finger types into are 16px, so a phone doesn't zoom the page; small controls reach 44px. */
@media (pointer: coarse), (max-width: 640px) { .data__input { font-size: 16px; } }
@media (pointer: coarse) {
  .data__copy, .data__add, .thread__new, .thread__kit, .history__clear { min-height: var(--tap); }
  .data__row-remove { width: var(--tap); min-height: var(--tap); }
}
@media (prefers-reduced-motion: reduce) {
  .prompt textarea[data-invalid] { animation: none; }
}

#try { scroll-margin-top: calc(56px + var(--space-4)); }

/* Install, under the line in the hero: small commands with copy icons. */
.install { display: grid; grid-template-columns: minmax(0, 1fr); justify-items: start; gap: var(--space-1); }
.install .label { margin-top: var(--space-2); }
.install .label:first-child { margin-top: 0; }
.install .cmd { max-width: 100%; }
.install__hand { margin-top: var(--space-3); color: var(--text-caption); font-size: .78rem; }
.install__hand .text-link { margin-right: var(--space-2); color: var(--ink); font-size: .9rem; }
.hero__body { align-items: start; }
.hero__copy { align-content: start; }
.hero .showcase { margin-top: var(--space-2); }

/* iPhone safe areas: with the page under the status bar (viewport-fit=cover), keep content clear of
   the notch in landscape and the home indicator. The status bar itself takes the paper colour. */
.top { padding-top: env(safe-area-inset-top); }
.shell { padding-left: env(safe-area-inset-left); padding-right: env(safe-area-inset-right); }
footer { padding-bottom: calc(var(--space-5) + env(safe-area-inset-bottom)); }

/* Playback uses the same quiet, square control as the kit toolbar. */
/* Areas land below the sticky menu. On phones the menu wraps and stays at the top of the page, so
   it doesn't cover the screen. */
.jump ~ .section { scroll-margin-top: calc(var(--top-h, 57px) + 72px); }
@media (max-width: 640px) { .jump { position: static; } .jump ~ .section { scroll-margin-top: calc(var(--top-h, 57px) + var(--space-3)); } }

/* Touch: small controls keep their look but reach 44px to a finger. Each hit area grows only
   where nothing sits next to it (rows of chips have 10px between; the nav links have 14px). */
@media (pointer: coarse) {
  .nav a, .cmd button, .chip, .prompt__send { position: relative; }
  .nav a::after, .cmd button::after, .chip::after, .prompt__send::after, .figure-copy::after { content: ""; position: absolute; }
  .nav a::after { inset: -4px -6px; }
  .icon-button::after { inset: -6px; }
  .icon-button--small::after { inset: -8px; }
  .cmd button::after { inset: -8px -7px; }
  .chip::after { inset: -5px 0; }
  .prompt__send::after { inset: -5px 0; }
  .figure-copy::after { inset: -8px 0; }
}
