@font-face {
  font-family: "Instrument Sans";
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  src: url("/fonts/InstrumentSans-Regular.woff2") format("woff2");
}
@font-face {
  font-family: "Instrument Sans";
  font-weight: 500;
  font-style: normal;
  font-display: swap;
  src: url("/fonts/InstrumentSans-Medium.woff2") format("woff2");
}
/* Dreamcaster page. Tokens and sizes: DESIGN.md §2–§7. */
:root {
  /* Blue hour at Ribersborg, DESIGN.md §3 (2026-11-05): sampled from Sergio's photos of the cold bath house at dusk. */
  --bg: #F4F6F9;      /* haze: the page */
  --surface: #E6EBF2; /* mist: bands, the form */
  --night: #121A2B;   /* evening sea */
  --night-2: #172540;
  --dusk: #22385F;
  --sky: #2B4677;
  --sky-low: #3A5D9A; /* the sky above the horizon */
  --glow: rgba(216, 160, 115, .34); /* the peach horizon behind the object */
  --lamp: #F6D77A;    /* lamp light = the sun yellow */
  /* the sunset on the horizon (sampled 2026-11-05: #FEF5A1, #FEC77A, #FAAB7E, #E8A08A, deepened: the phone overexposed it) */
  --sun: #F6D77A;     /* big numbers, light buttons on the stage */
  --amber: #F2B05E;   /* small labels on the stage */
  --orange: #E8854A;  /* the band only */
  --ember: #C8503A;   /* the band only */
  --mauve: #8E6A7A;   /* where the sunset meets the blue */
  --rust: #A8432C;    /* labels on the light sections: 5.5:1 on haze, 5.0:1 on mist */
  --horizon: linear-gradient(90deg, var(--mauve) 0%, var(--ember) 22%, var(--orange) 42%, var(--amber) 60%, var(--sun) 76%, var(--sky-low) 100%);
  --on-night: #F1F3F7;
  --on-night-2: #C3CEE2;
  --rule-night: #2E4266;
  --ink: #121A2B;
  --ink-2: #465269;
  --line: #6F7B91;
  --rule: #CDD4DF;
  --seal: #A3271C;
  --error: #B3261E;
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  /* motion tokens, DESIGN.md §6: the only durations in this file */
  --dur-press: 140ms;
  --dur-ui: 180ms;
  --dur-arrive: 400ms;
  --stagger: 60ms;
  --dur-partial: 880ms; /* one partial refresh, measured at 20 MHz SPI */
  --dur-full: 2600ms;   /* full refresh, measured 2.4-2.8 s; script.js FULL matches */
  --margin: 20px;
  --section: 96px;
  color-scheme: light;
}
@media (min-width: 600px) { :root { --margin: 24px; } }
@media (min-width: 1200px) { :root { --margin: 64px; --section: 160px; } }

*, *::before, *::after { box-sizing: border-box; }
[hidden] { display: none !important; }

html { -webkit-text-size-adjust: 100%; -webkit-tap-highlight-color: transparent; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: "Instrument Sans", -apple-system, "Helvetica Neue", "Segoe UI", Inter, Arial, sans-serif;
  font-size: 16px;
  line-height: 25px;
  font-weight: 400;
}
@media (min-width: 600px) { body { font-size: 17px; line-height: 27px; } }

img { display: block; max-width: 100%; height: auto; }
figure { margin: 0; }
p { margin: 0 0 16px; }
strong { font-weight: 500; } /* two weights only, DESIGN.md §2 */
h1, h2, h3 { font-weight: 500; margin: 0; }

h1 { font-size: 40px; line-height: 44px; letter-spacing: -0.02em; margin-bottom: 16px; }
h2 { font-size: 26px; line-height: 32px; letter-spacing: -0.01em; margin-bottom: 16px; }
h3 { font-size: inherit; line-height: inherit; }
.lead { font-size: 18px; line-height: 27px; color: var(--ink-2); margin-bottom: 32px; }
.small, figcaption { font-size: 13px; line-height: 19px; color: var(--ink-2); }
@media (min-width: 600px) {
  h1 { font-size: 64px; line-height: 68px; }
  h2 { font-size: clamp(32px, 3.6vw, 48px); line-height: 1.08; letter-spacing: -.025em; }
  .lead { font-size: 20px; line-height: 30px; }
}

a { color: inherit; text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; }
:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.skip { position: absolute; left: 12px; top: -60px; z-index: 11; background: var(--ink); color: var(--bg); padding: 8px 12px; }
.skip:focus { top: 8px; }

.vh {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.wrap { max-width: calc(1200px + 2 * var(--margin)); margin: 0 auto; padding: 0 var(--margin); }
.measure { max-width: 640px; }
.section { padding-top: var(--section); }

/* Nav */
.nav { display: flex; align-items: center; justify-content: space-between; height: 64px; gap: 16px; }
.wordmark { font-weight: 500; text-decoration: none; white-space: nowrap; min-height: 44px; display: flex; align-items: center; }
.wordmark-mark { width: 24px; height: 24px; margin-right: 10px; flex: none; }
.wm-short { display: none; }
.nav nav { display: flex; gap: 8px; }
.nav nav a { min-height: 44px; min-width: 44px; padding: 0 8px; display: flex; align-items: center; justify-content: center; text-decoration: none; }
@media (max-width: 599px) { .wm-place { display: none; } }
/* logo mark, long mark and both links need ~440 px (measured 2026-10-27); narrower phones get the short mark (PAGE-BRIEF §1) */
@media (max-width: 699px) { .wm-long { display: none; } .wm-short { display: inline; } } /* two links and the reserve button need the room (2026-11-05) */

/* Buttons */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 48px; padding: 0 24px; border: 0; border-radius: 4px;
  font: inherit; font-weight: 500; text-decoration: none; cursor: pointer;
}
.btn-seal { background: var(--seal); color: #FFFFFF; }
.btn-ink { background: var(--ink); color: var(--bg); }
.btn { transition: transform var(--dur-press) var(--ease-out); }
@media (prefers-reduced-motion: no-preference) {
  .btn:active:not(:focus-visible) { transform: scale(.97); }
}
@media (hover: hover) {
  a:hover { text-decoration-thickness: 2px; }
  .nav nav a:hover, .btn:hover { text-decoration: underline; }
}
.textlink { display: inline-flex; align-items: center; min-height: 44px; padding: 0 4px; }
button.textlink { border: 0; background: none; font: inherit; color: inherit; text-decoration: underline; text-underline-offset: 3px; cursor: pointer; }

/* Stage (DESIGN.md §3, §4): dark sections with one pool of light where the object or the art sits. */
.stage { background: var(--night); color: var(--on-night); --ink: var(--on-night); --ink-2: var(--on-night-2); --rule: var(--rule-night); }
.has-stage .nav-band { background: var(--night); color: var(--on-night); position: sticky; top: 0; z-index: 10; border-bottom: 1px solid var(--rule-night); }
html { scroll-padding-top: 72px; } /* anchors land below the sticky bar */
.nav nav { align-items: center; }
.nav nav a.btn-sm { min-height: 36px; padding: 0 14px; margin-left: 8px; font-size: 14px; } /* the bar's 36 px pill sits in a 44 px tap row */
.nav nav a.btn-sm { position: relative; }
.nav nav a.btn-sm::after { content: ""; position: absolute; inset: -4px 0; } /* 44 px hit area */
.has-stage .nav-band :focus-visible, .stage :focus-visible { outline-color: var(--amber); }
.has-stage .nav-band .wordmark-mark { filter: invert(1); }
.kicker { margin: 0 0 16px; letter-spacing: .02em; }
.display-2 { font-size: clamp(34px, 5.4vw, 76px); line-height: 1.02; letter-spacing: -.035em; margin-bottom: 24px; }

/* Hero */
.actions { display: flex; flex-wrap: wrap; align-items: center; gap: 24px; margin: 0; }
/* The stage is the blue hour: dark sky at the top, brighter above the horizon, a peach glow on the horizon where
   the object stands, the dark sea below. */
.stage { background: radial-gradient(ellipse 70% 26% at 50% 100%, rgba(232, 133, 74, .30) 0%, rgba(200, 80, 58, .14) 45%, transparent 75%), linear-gradient(180deg, var(--dusk) 0%, var(--night-2) 60%, var(--night) 100%); }
/* the horizon line: under the sticky bar and on top of every stage that follows a light section */
.has-stage .nav-band { border-bottom: 0; box-shadow: none; }
.has-stage .nav-band::after { content: ""; display: block; height: 2px; background: var(--horizon); }
.stage:not(.hero):not(.build-top) { border-top: 2px solid transparent; border-image: var(--horizon) 1; }
.kicker { color: var(--rust); }
.stage .kicker, .hero .kicker, .build-top .kicker { color: var(--amber); }
.stage .btn-ink { background: var(--sun); color: var(--night); }
/* The hero is the photo: blue sky, the sunset band on the horizon right behind the frame, the dark sea below. */
.hero { padding: 40px 0 24px; overflow-x: clip; text-align: center;
  background: radial-gradient(ellipse 38% 9% at 50% 71.5%, rgba(246, 215, 122, .55) 0%, rgba(232, 133, 74, .32) 45%, transparent 78%),
    linear-gradient(180deg, var(--night-2) 0%, var(--sky) 36%, var(--sky-low) 55%, #6E7096 63%, var(--mauve) 66.5%, var(--ember) 69%, var(--orange) 70.4%, var(--amber) 71.3%, var(--sun) 71.9%, var(--dusk) 73.2%, var(--night) 100%); }
.hero h1 { font-size: clamp(64px, 12vw, 168px); line-height: .9; letter-spacing: -.055em; margin: 0 0 20px; }
.hero .lead { max-width: 30ch; margin: 0 auto 32px; font-size: clamp(18px, 2vw, 24px); line-height: 1.35; }
.hero .actions { justify-content: center; }
.hero-figure { margin: 8px auto 0; max-width: 1200px; }
.hero-figure picture { display: block; }
.hero-figure figcaption { justify-content: center; padding-bottom: 16px; }
/* M1 arrival (Zaro lesson): heading and lead sharpen from a blur once, on load. "backwards": the end state is the
   element's own, so no filter layer lingers. M2 partial-refresh reveal: the render appears top to bottom in 8 bands
   over one measured partial refresh; no fade, no blur. Outside this query both are simply shown. */
@media (prefers-reduced-motion: no-preference) {
  .hero-text h1, .hero-text .lead { animation: arrive var(--dur-arrive) var(--ease-out) backwards; }
  .hero-text .lead { animation-delay: var(--stagger); }
  .hero-figure picture { animation: fade-soft var(--dur-rise) var(--ease-out) backwards; } /* 2026-11-05: a soft fade, no top-to-bottom wipe */
}
@keyframes arrive { from { opacity: 0; transform: translateY(8px); filter: blur(6px); } }
@keyframes reveal { from { clip-path: inset(0 0 100% 0); } to { clip-path: inset(0); } }

/* Editorial product summary: description beside a short list of measured/design facts. */
.product-intro { display: grid; gap: 32px; align-items: start; }
.product-intro-copy .measure { margin-bottom: 0; }
.product-facts { margin: 0; border-top: 1px solid var(--rule); }
.product-facts > div { display: grid; grid-template-columns: minmax(80px, .38fr) minmax(0, 1fr); gap: 16px; padding: 16px 0; border-bottom: 1px solid var(--rule); }
.product-facts dt { color: var(--ink-2); font-size: 13px; line-height: 19px; }
.product-facts dd { margin: 0; font-size: 18px; line-height: 27px; font-weight: 500; font-variant-numeric: tabular-nums; }
.product-facts dd span { display: block; color: var(--ink-2); font-size: 13px; line-height: 19px; font-weight: 400; }
@media (min-width: 900px) {
  .product-intro { grid-template-columns: minmax(0, 1.15fr) minmax(340px, .85fr); gap: 48px; align-items: center; }
}
/* M3 statement (Profound lesson): sharpens as it scrolls in, sharp once fully on screen; CSS only, no-op where unsupported */
@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {
    .statement { animation: sharpen linear backwards; animation-timeline: view(); animation-range: entry 0% entry 100%; }
  }
}
@keyframes sharpen { from { filter: blur(4px); } } /* blur only: opacity would drop the text below AA while it waits */

/* What it shows (#modes): one frame, every mode. All renders share the camera, so only the screen changes. */
.show { padding: var(--section) 0 calc(var(--section) / 2); background: var(--surface); }
.show-ui { display: grid; gap: 24px; margin-top: 48px; }
.show-stage { margin: 0; }
.show-imgs { position: relative; aspect-ratio: 16 / 10; }
.show-img { position: absolute; inset: 0; width: 100%; height: 100%; display: none; }
.show-img[data-mode="shanshui"] { display: block; }
.show-caps { display: block; min-height: 40px; margin-top: 0; }
.show-cap { display: none; }
.show-cap[data-mode="shanshui"] { display: inline; }
.show-cap em { font-style: normal; color: var(--ink-2); }
.show-render { margin-left: .4em; }
.modes { display: flex; flex-wrap: wrap; gap: 8px; margin: 0; padding: 0; border: 0; min-width: 0; }
.mode { position: relative; }
.mode span { display: grid; gap: 2px; min-height: 56px; padding: 8px 16px 8px 30px; border: 1px solid var(--line); border-radius: 4px; cursor: pointer; background: var(--bg); }
.mode b { font-weight: 500; }
.mode i { font-style: normal; font-size: 12px; line-height: 16px; color: var(--ink-2); }
/* the one red mark: the picked mode, like the one red button on the object (DESIGN.md §3) */
.mode span::before { content: ""; position: absolute; left: 12px; top: 50%; width: 9px; height: 9px; margin-top: -5px; border: 1px solid var(--line); border-radius: 2px; }
.mode input:checked + span { border-color: var(--ink); box-shadow: inset 0 0 0 1px var(--ink); }
.mode input:checked + span::before { background: var(--seal); border-color: var(--seal); }
.mode input:focus-visible + span { outline: 2px solid var(--ink); outline-offset: 2px; }
@media (min-width: 1000px) {
  .show-ui { grid-template-columns: minmax(0, 1fr) 220px; align-items: center; gap: 32px; }
  .modes { flex-direction: column; }
}
/* Without JS, :has() still switches the picture instantly. */
.show:has(input[value="birds"]:checked) .show-img[data-mode="birds"],
.show:has(input[value="poems"]:checked) .show-img[data-mode="poems"],
.show:has(input[value="photo"]:checked) .show-img[data-mode="photo"],
.show:has(input[value="assistant"]:checked) .show-img[data-mode="assistant"],
.show:has(input[value="departures"]:checked) .show-img[data-mode="departures"],
.show:has(input[value="home"]:checked) .show-img[data-mode="home"] { display: block; z-index: 2; }
.show:has(input[value="birds"]:checked) .show-cap[data-mode="birds"],
.show:has(input[value="poems"]:checked) .show-cap[data-mode="poems"],
.show:has(input[value="photo"]:checked) .show-cap[data-mode="photo"],
.show:has(input[value="assistant"]:checked) .show-cap[data-mode="assistant"],
.show:has(input[value="departures"]:checked) .show-cap[data-mode="departures"],
.show:has(input[value="home"]:checked) .show-cap[data-mode="home"] { display: inline; }
.show:has(.modes input:not([value="shanshui"]):checked) .show-cap[data-mode="shanshui"] { display: none; }
/* With JS (script.js marks .was and .now): the last picture stays under, the new one is drawn inside the screen
   polygon top to bottom in 8 steps over one measured partial refresh (M12). */
.show-img.was { display: block; z-index: 1; }
.show-img.now { display: block; z-index: 2; }
@media (prefers-reduced-motion: no-preference) {
  .show-img.now { animation: fade-soft var(--dur-rise) var(--ease-out) backwards; } /* the new screen fades in over the last */
}
@keyframes screen-refresh {
  from { clip-path: polygon(25.31% 20.35%, 77.48% 19.82%, 77.48% 19.82%, 25.31% 20.35%); }
  to { clip-path: polygon(25.31% 20.35%, 77.48% 19.82%, 77.18% 71.94%, 23.10% 69.54%); }
}

/* Statement band */
.band-statement { padding: var(--section) 0; }
.band-statement .display-2 { max-width: 18ch; margin-bottom: 64px; }
.big-facts { display: grid; gap: 0; margin: 0; border-top: 1px solid var(--rule); }
.big-facts > div { padding: 24px 0; border-bottom: 1px solid var(--rule); display: flex; flex-direction: column-reverse; gap: 8px; }
.big-facts dt { color: var(--ink-2); font-size: 15px; line-height: 22px; }
.big-facts dd { margin: 0; font-size: clamp(48px, 7vw, 96px); line-height: 1; letter-spacing: -.04em; font-weight: 500; font-variant-numeric: tabular-nums; }
@media (min-width: 900px) {
  .big-facts { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 24px; border-top: 0; }
  .big-facts > div { border-top: 1px solid var(--rule); border-bottom: 0; }
}

/* Inside the frame: a sticky stage while the parts come apart (M10 with data-turn-track). Only with motion.js
   and motion allowed (html.js-motion); otherwise a plain section. */
.inside { padding: var(--section) 0 0; }
.inside-grid { display: grid; gap: 32px; align-items: center; }
.inside-steps { margin: 0; padding: 0; list-style: none; counter-reset: step; }
.inside-steps li { counter-increment: step; padding: 14px 0 14px 2.2em; border-top: 1px solid var(--rule); position: relative; color: var(--ink-2); }
.inside-steps li::before { content: counter(step, decimal-leading-zero); position: absolute; left: 0; font-variant-numeric: tabular-nums; }
.inside-steps b { font-weight: 500; color: var(--ink); }
.inside-figure { margin: 0; }
@media (min-width: 900px) { .inside-grid { grid-template-columns: minmax(0, 4fr) minmax(0, 8fr); gap: 48px; } }
@media (min-width: 900px) and (min-height: 560px) {
  .js-motion .inside { height: 280vh; padding-top: 0; }
  .js-motion .inside-sticky { position: sticky; top: 64px; min-height: calc(100vh - 64px); display: flex; align-items: center; }
}
.js-motion .inside-steps li { transition: color var(--dur-ui) var(--ease-out); }
.js-motion .inside-steps li:not(.is-on) b { color: var(--ink-2); font-weight: 400; } /* dimmed but AA: --ink-2 is 7.5:1 */
.js-motion .inside-steps li.is-on { color: var(--ink); }
.js-motion .inside-steps li.is-on::before { color: var(--seal); }

/* Art */
.art-stage { margin-top: var(--section); padding: var(--section) 0; }
.art-stage .art-item img, .art-stage .band img { outline: 0; }
/* five styles: the first spans two columns, so the grid closes on both widths */
@media (min-width: 600px) { .art-grid .art-item:first-child { grid-column: span 2; } }
.band { margin: 0 0 48px; }
.band img { outline: 1px solid var(--rule); }
figcaption { margin-top: 12px; }
.art-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 40px 24px; }
.art-item { min-width: 0; border-top: 1px solid var(--rule); padding-top: 16px; }
.art-item img { width: 100%; aspect-ratio: 5 / 3; object-fit: contain; outline: 1px solid var(--rule); }
.art-item figcaption { display: grid; gap: 4px; margin-top: 14px; }
.art-item strong { color: var(--ink); font-size: 18px; line-height: 24px; font-weight: 500; }
.art-item figcaption span { color: var(--ink-2); font-size: 15px; line-height: 22px; }

/* Features */
.section-kicker { margin: 0 0 8px; }
.features { display: grid; gap: 48px 24px; } /* one ruled row of 3, DESIGN.md §7 */
.feature { min-width: 0; border-top: 1px solid var(--rule); padding-top: 16px; }
.feature-figure { margin: 0 0 20px; }
.feature-visual { display: grid; place-items: center; aspect-ratio: 5 / 3; }
.feature-visual img { max-width: 100%; max-height: 100%; object-fit: contain; }
.feature-figure figcaption { margin-top: 8px; }
.features h3 { margin-bottom: 8px; font-size: 20px; line-height: 27px; }
.feature p { color: var(--ink-2); margin: 0; }
@media (min-width: 900px) {
  .features { grid-template-columns: repeat(3, minmax(0, 1fr)); row-gap: 0; }
  /* subgrid lines up figure, heading and text across the row; without it each cell just stacks */
  .feature { display: grid; grid-row: span 3; grid-template-rows: subgrid; }
}
@media (max-width: 699px) { .art-grid { grid-template-columns: 1fr; } }

/* An 800 × 480 window onto the 1 800 px strip. --x = the window's left edge in strip px.
   No transition anywhere: e-paper moves in steps. */
.pane { position: relative; overflow: hidden; aspect-ratio: 5 / 3; outline: 1px solid var(--rule); }
.pane img { width: 225%; max-width: none; transform: translateX(calc(var(--x, 0) * -100% / 1800)); }

/* The whole 1 800 px strip, reduced, with a 2 px box on the 800 px window at --x. Boxes jump, never slide. */
.strip { position: relative; outline: 1px solid var(--rule); }
.strip-box, .ghost { position: absolute; top: 0; bottom: 0; left: calc(var(--x, 0) * 100% / 1800); width: calc(800 * 100% / 1800); }
.strip-box { border: 2px solid var(--ink); }

/* Time scale (Zaro lesson): native radios, the checked tick sets --x. Without :has() it stays on Now. */
.ts { --x: 864; display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 16px; align-items: start; }
.ts-strip { grid-column: 1 / -1; }
/* M5 ghost trail: one dashed box per tick, in tick order after the img (child 1); the solid .strip-box covers the selected one */
.ghost { left: calc(var(--o) * 100% / 1800); border: 1px dashed var(--ink-2); }
.ghost:nth-child(2) { --o: 864; }
.ghost:nth-child(3) { --o: 720; }
.ghost:nth-child(4) { --o: 576; }
.ghost:nth-child(5) { --o: 288; }
.ghost:nth-child(6) { --o: 0; }
.ts:has(input[value="720"]:checked) { --x: 720; }
.ts:has(input[value="576"]:checked) { --x: 576; }
.ts:has(input[value="288"]:checked) { --x: 288; }
.ts:has(input[value="0"]:checked) { --x: 0; }
.ts-ticks { margin: 0; padding: 0; border: 0; min-width: 0; }
.ts-ticks legend { padding: 0 0 4px; }
.tick { position: relative; display: block; }
.tick span {
  display: flex; align-items: center; min-height: 44px; padding: 0 4px 0 13px; cursor: pointer;
  border-left: 1px solid var(--rule); color: var(--ink-2); font-size: 13px; white-space: nowrap; font-variant-numeric: tabular-nums;
}
.tick input:checked + span { color: var(--ink); border-left: 2px solid var(--ink); padding-left: 12px; }
.tick input:focus-visible + span { outline: 2px solid var(--ink); outline-offset: 2px; }
@media (min-width: 900px) {
  /* one row of ticks under the window, so the cell stays close to its neighbours' height; the bottom rule marks the choice */
  .ts { grid-template-columns: minmax(0, 1fr); gap: 12px; }
  .ts-ticks { display: flex; }
  .tick { flex: 1 1 auto; }
  .tick span { justify-content: center; padding: 0 4px; border-left: 0; border-bottom: 1px solid var(--rule); }
  .tick input:checked + span { border-left: 0; padding-left: 4px; border-bottom: 2px solid var(--ink); }
}

/* Bench (Dabbit lesson): the lab's bench page rebuilt as a working simulation. Ruled, no cards.
   script.js sets --x on #bench and steps it. */
.bench { display: grid; gap: 32px; border-top: 1px solid var(--rule); padding-top: 24px; }
.bench-controls { margin: 0; padding: 0; border: 0; min-width: 0; }
.opts { display: flex; flex-wrap: wrap; gap: 0 20px; margin: 0 0 16px; padding: 0 0 8px; border: 0; border-bottom: 1px solid var(--rule); min-width: 0; }
.opts legend { padding: 0; margin-bottom: 4px; font-weight: 500; }
.opt { display: inline-flex; align-items: center; gap: 8px; min-height: 44px; cursor: pointer; font-variant-numeric: tabular-nums; }
.opt input { width: 20px; height: 20px; margin: 0; flex: none; accent-color: var(--ink); }
.bench-controls:disabled .opt { cursor: default; }
.bench-controls:disabled .speed { display: none; } /* no script, nothing plays: no slider */
/* playback speed (2026-11-05): a slider from real time to 3 600x */
.speed { display: grid; gap: 6px; padding-bottom: 14px; }
.speed label b { font-weight: 500; }
.speed output { color: var(--ink-2); margin-left: 6px; }
.speed input[type=range] { width: 100%; height: 44px; margin: 0; accent-color: var(--ink); }
.speed-scale { display: flex; justify-content: space-between; color: var(--ink-2); }
/* the last position, dashed, so each step reads as a jump (DESIGN.md §6 M6) */
.strip-prev { position: absolute; top: 0; bottom: 0; left: calc(var(--xp, 0) * 100% / 1800); width: calc(800 * 100% / 1800); border: 2px dashed var(--rust); display: none; }
.has-prev .strip-prev { display: block; }
.bench-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 24px; margin: 16px 0 0; }
.bench-view { min-width: 0; }
.bench-window { margin-top: 16px; }
.bench-window::after { content: ""; position: absolute; inset: 0; pointer-events: none; }
@media (prefers-reduced-motion: no-preference) {
  .bench-window.is-flash::after { animation: flash var(--dur-full) step-end; } /* full refresh: black, then white, then the picture */
}
@keyframes flash { 0% { background: var(--ink); } 50% { background: var(--bg); } }
.bench-readouts { margin: 24px 0 16px; }
@media (min-width: 900px) {
  .bench { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: 24px; }
  .bench-view { border-left: 1px solid var(--rule); padding-left: 24px; }
}
/* the window is always smaller than the 1 800 px strip, so the browser's downscale stands (DESIGN.md §5); phones see it first */
/* the view stays after the settings on phones too, so the keyboard order matches what you see */
@media (min-width: 600px) and (max-width: 899px) { .art-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* Specs */
.specs-layout { display: grid; align-items: start; gap: 32px; margin-bottom: 48px; }
.specs { width: 100%; max-width: none; border-collapse: collapse; margin: 0; }
.specs th, .specs td { text-align: left; vertical-align: top; padding: 12px 0; border-bottom: 1px solid var(--rule); }
.specs tr:first-child th, .specs tr:first-child td { border-top: 1px solid var(--rule); }
.specs th { font-weight: 400; color: var(--ink-2); width: 34%; padding-right: 16px; }
.specs td { font-weight: 500; font-variant-numeric: tabular-nums; }
.wide { margin: 0; }
.sub { margin-bottom: 16px; }
.limits { margin: 0; padding: 0; list-style: none; counter-reset: limit; }
.limits li { counter-increment: limit; position: relative; padding: 12px 0 12px 2em; border-bottom: 1px solid var(--rule); }
.limits li::before { content: counter(limit) "."; position: absolute; left: 0; font-variant-numeric: tabular-nums; color: var(--ink-2); }
.limits li:first-child { border-top: 1px solid var(--rule); }
@media (min-width: 900px) { .specs-layout { grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr); gap: 48px; } }

/* Reserve */
.reserve { background: var(--surface); margin-top: var(--section); padding: var(--section) 0; }
.reserve-grid { display: grid; gap: 32px; }
.reserve-figure { margin: 0; }
@media (min-width: 900px) {
  .reserve-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 640px); gap: 48px; align-items: start; }
  .reserve-figure { position: sticky; top: 120px; order: 2; } /* the frame stays beside the form while you fill it in */
}
@media (max-width: 899px) { .reserve-figure { max-width: 560px; } }
.field { margin: 0 0 24px; }
fieldset.field { border: 0; padding: 0; min-width: 0; }
legend { padding: 0; margin-bottom: 8px; font-weight: 500; }
.field > label { display: block; font-weight: 500; margin-bottom: 8px; }
.hint { display: block; margin: -4px 0 8px; }
input[type="email"], input[type="text"], textarea {
  display: block; width: 100%; min-height: 48px; padding: 10px 12px;
  font: inherit; color: var(--ink); background: var(--bg);
  border: 1px solid var(--line); border-radius: 4px;
}
textarea { resize: vertical; }
[aria-invalid="true"] { border-color: var(--error); }
.check { display: flex; align-items: flex-start; gap: 0; margin: 0 0 8px; }
.check input { width: 20px; height: 20px; margin: 12px 0 0; flex: none; accent-color: var(--ink); }
.check label { padding: 9px 0 9px 12px; min-height: 44px; cursor: pointer; flex: 1; font-weight: 400; margin: 0; display: block; }
.check.field { flex-wrap: wrap; margin-top: 24px; }
.check.field .error { flex-basis: 100%; }
.error { display: block; color: var(--error); font-weight: 500; }
.error:empty { display: none; }
.send-error { margin: 0 0 16px; }
.submit { display: flex; flex-wrap: wrap; align-items: center; gap: 16px 24px; margin: 8px 0 16px; }
.price { margin: 0; flex: 1 1 260px; }
.trap { position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden; }
.thanks h2:focus { outline: 2px solid var(--ink); outline-offset: 4px; }

/* Footer */
.footer { padding-top: 64px; padding-bottom: 64px; }
.footline { display: flex; flex-wrap: wrap; gap: 4px 24px; padding-top: 24px; border-top: 1px solid var(--rule); margin-bottom: 32px; }
.footline a, .footline span { display: inline-flex; align-items: center; min-height: 44px; min-width: 44px; }
.credits ul { list-style: none; margin: 0 0 32px; padding: 0; }
.credits li a { display: inline-flex; align-items: center; min-height: 44px; }
.privacy { font-size: 16px; line-height: 25px; color: var(--ink); }
@media (min-width: 600px) { .privacy { font-size: 17px; line-height: 27px; } }

/* More than art (#uses): two use cases being explored. Panels are 5:3 like the real screen; the photo is real 1-bit
   output (the browser dithers it), the assistant screens are labelled sketches with example values. */
.uses { display: grid; gap: 48px 24px; }
@media (min-width: 900px) { .uses { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.use { min-width: 0; border-top: 1px solid var(--rule); padding-top: 16px; }
.use h3 { margin-bottom: 8px; font-size: 20px; line-height: 27px; }
.use > p { color: var(--ink-2); margin: 0 0 12px; max-width: 60ch; }
.use-panel { position: relative; aspect-ratio: 5 / 3; background: var(--bg); outline: 1px solid var(--rule); overflow: hidden; }
.use-panel img, .use-panel canvas { display: block; width: 100%; height: 100%; image-rendering: pixelated; }
.use-actions { margin: 16px 0 12px; }
.use-actions .btn { cursor: pointer; }
#photo-file:focus-visible + * , .use-actions:has(#photo-file:focus-visible) .btn { outline: 2px solid var(--ink); outline-offset: 2px; }
/* A new picture on the panel arrives top to bottom in 8 bands: one partial refresh (M12). */
@media (prefers-reduced-motion: no-preference) {
  .use-panel.is-refresh > :not([hidden]), .ai-screen { animation: fade-soft var(--dur-rise) var(--ease-out) backwards; }
}
.ai { display: grid; gap: 16px; }
.ai-screen { position: absolute; inset: 0; display: none; padding: 5.5% 6.5%; color: #000; font-size: clamp(12px, 2.3vw, 17px); line-height: 1.35; }
.ai-screen p { margin: 0 0 .45em; }
.ai-head { display: flex; justify-content: space-between; padding-bottom: .5em; margin-bottom: .9em !important; border-bottom: 2px solid #000; font-weight: 500; }
.ai-big { font-size: 1.75em; line-height: 1.1; font-weight: 500; letter-spacing: -.01em; margin-bottom: .5em !important; }
.ai-screen:first-child { display: block; }
.ai:has(input[value="2"]:checked) .ai-screen:first-child, .ai:has(input[value="3"]:checked) .ai-screen:first-child { display: none; }
.ai:has(input[value="2"]:checked) #ai-2, .ai:has(input[value="3"]:checked) #ai-3 { display: block; }
.ai-asks { margin: 0; padding: 0; border: 0; min-width: 0; }
.ai-asks legend { padding: 0 0 4px; }
.ai-asks .tick span { white-space: normal; }
@media (min-width: 600px) { .ai-asks { display: flex; flex-wrap: wrap; } .ai-asks legend { width: 100%; } }
@media (prefers-reduced-motion: reduce) { * { transition: none !important; animation: none !important; scroll-behavior: auto !important; } }

/* ---- 2026-11-05 rebuild (DESIGN.md §7) ---- */
.hero-figure figcaption { text-align: center; padding-bottom: 16px; }
.hero .kicker { color: var(--amber); }
/* What it is: heading, then the two take-apart views side by side, then the text and the parts */
.what { display: grid; gap: 32px; }
.what-head .display-2 { max-width: 20ch; }
.what-views { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; background: var(--surface); border-radius: 6px; padding: 16px; }
.what-views figure { margin: 0; }
.what-views img { width: 100%; height: auto; }
.what-views figcaption { margin-top: 4px; }
.what-body { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 48px; align-items: start; }
.what-body .lead { margin: 0; }
.parts { margin: 0; border-top: 1px solid var(--rule); }
.parts > div { display: grid; grid-template-columns: 110px minmax(0, 1fr); gap: 16px; padding: 12px 0; border-bottom: 1px solid var(--rule); }
.parts dt { color: var(--ink-2); font-size: 14px; }
.parts dd { margin: 0; font-weight: 500; }
@media (max-width: 899px) { .what-body { grid-template-columns: 1fr; gap: 24px; } }
@media (max-width: 599px) { .what-views { grid-template-columns: 1fr; } }
/* Use cases: two groups, Today and Next */
.modes-group { margin: 6px 0 2px; font-size: 12px; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-2); width: 100%; }
.modes-group:first-of-type { margin-top: 0; }
/* The door to /build */
.yours-band { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 48px; align-items: end; }
.yours-band .lead { margin: 0 0 24px; }
@media (max-width: 899px) { .yours-band { grid-template-columns: 1fr; gap: 8px; } }
/* Lamp light marks numbers on the stage */
.stage .big-facts dd { color: var(--lamp); }
.js-motion .inside-steps li.is-on::before { color: var(--seal); }


/* /build: Make it yours (2026-11-05) */
.build-top { padding: clamp(56px, 8vw, 104px) 0 clamp(48px, 6vw, 80px); }
.build-head { display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); gap: 32px; align-items: center; }
.build-figure { margin: 0; }
.build-figure img { width: 100%; height: auto; }
.build-figure figcaption { color: var(--on-night-2); }
@media (max-width: 899px) { .build-head { grid-template-columns: 1fr; } }
.snippet { margin: 6px 0 0; padding: 10px 12px; border-radius: 4px; background: #0d1422; color: var(--on-night); font: 12px/1.5 ui-monospace, Menlo, Consolas, monospace; overflow-x: auto; }
.build-top h1 { font-size: clamp(44px, 7vw, 104px); line-height: .95; letter-spacing: -.05em; max-width: 12ch; margin-bottom: 20px; }
.build-top .lead { max-width: 50ch; }
.build-top .kicker { color: var(--amber); }
.build-steps { list-style: none; margin: 40px 0 0; padding: 0; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; counter-reset: bstep; }
.build-steps li { counter-increment: bstep; display: grid; gap: 8px; align-content: start; padding-top: 14px; border-top: 1px solid var(--rule-night); }
.build-steps li::before { content: counter(bstep, decimal-leading-zero); color: var(--amber); font-variant-numeric: tabular-nums; font-size: 14px; }
.build-steps b { font-weight: 500; font-size: 19px; color: var(--on-night); }
.build-steps span { color: var(--on-night-2); font-size: 15px; line-height: 1.45; }
.build-note { margin: 28px 0 0; color: var(--on-night-2); max-width: 70ch; }
@media (max-width: 899px) { .build-steps { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 559px) { .build-steps { grid-template-columns: 1fr; } }
.motion-grid { max-width: 760px; }
.motion-grid .feature { border-top: 0; padding-top: 0; }
.data-grid { display: grid; grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr); gap: 48px; align-items: start; }
.data-list { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--rule); }
.data-list li { display: grid; gap: 4px; padding: 14px 0; border-bottom: 1px solid var(--rule); }
.data-list span { color: var(--ink-2); }
@media (max-width: 899px) { .data-grid { grid-template-columns: 1fr; gap: 24px; } }

/* With script.js the classes decide; the :has() fallback above must not override them */
.js-show .show-img { display: none !important; }
.js-show .show-img.was, .js-show .show-img.now { display: block !important; }

@keyframes fade-soft { from { opacity: 0; } }
