:root,[data-theme="obsidianGold"]{color-scheme:dark;--shade:0.5;--bg:#111418;--bg-deep:#0b0c0e;--surface:rgba(23,27,34,0.98);--border:rgba(150,158,163,0.18);--text:#f2f1ee;--muted:#b8b0a2;--accent:#cda85d;--accent-text:#e6c97a;--on-accent:#0b0c0e;--board:#E8E8E5;--line:rgba(44,49,52,0.24);--line-thick:#2C3134;--given-bg:#DEDEDA;--given:#33383A;--entered:#816328;--selected:rgba(208,172,101,0.529);--related:rgba(208,172,101,0.233);--same:rgba(230,201,135,0.505);--ring:rgba(159,114,39,0.693);--conflict-bg:#ffe3dd;--conflict:#8e2f2f;--key-bg:rgba(255,255,255,0.08);--key-border:rgba(255,255,255,0.14);--key-text:#FFFFFF}
[data-theme="luxe"]{color-scheme:dark;--shade:0.5;--bg:#0a0908;--bg-deep:#060605;--surface:rgba(26,22,15,0.98);--border:rgba(203,178,119,0.24);--text:#f4efe4;--muted:#bdb29a;--accent:#cbb277;--accent-text:#e6d6a4;--on-accent:#0a0805;--board:#f0e8d0;--line:rgba(92,76,47,0.22);--line-thick:#5a4a2f;--given-bg:#e7dcbf;--given:#40371f;--entered:#655426;--selected:rgba(189,166,110,0.680);--related:rgba(189,166,110,0.311);--same:rgba(228,212,154,0.505);--ring:rgba(156,127,52,0.693);--conflict-bg:#ffe3dd;--conflict:#8e2f2f;--key-bg:rgba(255,255,255,0.08);--key-border:rgba(203,178,119,0.3);--key-text:#FFFFFF}
[data-theme="nightFocus"]{color-scheme:dark;--shade:0.5;--bg:#111a2a;--bg-deep:#0e1320;--surface:rgba(30,40,60,0.98);--border:rgba(123,159,212,0.32);--text:#eaf1ff;--muted:#9fb0cd;--accent:#7B9FD4;--accent-text:#a9bee1;--on-accent:#0E1320;--board:#1d2940;--line:rgba(145,167,204,0.58);--line-thick:#d4e0f7;--given-bg:#263650;--given:#f0f5ff;--entered:#7B9FD4;--selected:rgba(114,179,255,0.454);--related:rgba(95,147,223,0.246);--same:rgba(134,188,255,0.467);--ring:rgba(114,179,255,0.731);--conflict-bg:rgba(255,123,138,0.34);--conflict:#ffd3da;--key-bg:rgba(24,33,50,0.94);--key-border:rgba(123,159,212,0.32);--key-text:#eaf1ff}
[data-theme="warmStudio"]{color-scheme:light;--shade:0.18;--bg:#f3ebdf;--bg-deep:#f8f2ea;--surface:rgba(255,253,249,0.99);--border:rgba(183,122,63,0.24);--text:#2a2118;--muted:#5f4d3b;--accent:#9d6329;--accent-text:#7d4822;--on-accent:#fffdf8;--board:#fffaf4;--line:rgba(120,94,68,0.38);--line-thick:#5b452f;--given-bg:#f4eee6;--given:#352515;--entered:#9c6836;--selected:rgba(168,102,47,0.446);--related:rgba(186,124,67,0.222);--same:rgba(169,105,49,0.428);--ring:rgba(111,61,29,0.611);--conflict-bg:#ffe4dc;--conflict:#8e3434;--key-bg:rgba(255,251,246,0.95);--key-border:rgba(183,122,63,0.24);--key-text:#3D2B1F}
[data-theme="minimalContrast"]{color-scheme:light;--shade:0.18;--bg:#eef0f3;--bg-deep:#f3f4f6;--surface:rgba(255,255,255,0.99);--border:rgba(51,65,85,0.18);--text:#111827;--muted:#475569;--accent:#334155;--accent-text:#1f2937;--on-accent:#ffffff;--board:#ffffff;--line:rgba(55,65,81,0.4);--line-thick:#111827;--given-bg:#f3f4f6;--given:#111827;--entered:#5e789d;--selected:rgba(51,65,85,0.423);--related:rgba(75,95,122,0.214);--same:rgba(71,85,105,0.412);--ring:rgba(51,65,85,0.562);--conflict-bg:#ffdfdf;--conflict:#8d1b1b;--key-bg:rgba(255,255,255,0.95);--key-border:rgba(51,65,85,0.18);--key-text:#1f2937}
[data-theme="roseForge"]{color-scheme:light;--shade:0.18;--bg:#f7eef1;--bg-deep:#fdf6f8;--surface:rgba(255,252,253,0.99);--border:rgba(178,116,96,0.30);--text:#2c1a22;--muted:#6a4150;--accent:#a8566b;--accent-text:#7d3446;--on-accent:#fffafc;--board:#fffafc;--line:rgba(150,92,88,0.34);--line-thick:#5d3546;--given-bg:#f8eef0;--given:#33202a;--entered:#a63c68;--selected:rgba(176,71,106,0.446);--related:rgba(210,104,140,0.222);--same:rgba(188,86,115,0.428);--ring:rgba(124,39,73,0.611);--conflict-bg:#ffe0dd;--conflict:#8e2f2f;--key-bg:rgba(255,250,252,0.95);--key-border:rgba(178,116,96,0.30);--key-text:#3a222c}
/* The theme tokens (--bg, --text, --accent, the board colours…) are generated above this
   file by build.mjs from THEMES in content.mjs, one block per app theme.
   Scales: radius 10 (chip) / 18 (card) / pill, spacing in quarter-rem steps, as in
   src/designTokens.js. Brass is signal, not decoration: the one call to action, the
   selected cell, the digit you entered, and the Smith's name.

   Motion rules for this file:
   - Feedback is on the press, at once. Movement that follows is a spring, never a fixed ease.
   - Things that open come out of what opened them and go back the same way.
   - Anything that moves, scales or blurs sits inside `prefers-reduced-motion: no-preference`.
     What is left for everyone else is colour and short cross-fades. */

@font-face {
  font-family: "Playfair Display";
  /* ponytail: the full TTF, compressed by the host. Subset to WOFF2 if font weight ever matters. */
  src: url("/assets/fonts/PlayfairDisplay-Bold.ttf") format("truetype");
  font-weight: 700;
  font-display: swap;
}

:root {
  /* Two real springs sampled into linear(), in Apple's terms: response 0.4 at damping 1
     (no overshoot, the default) and at damping 0.7 (one small bounce, for the struck digit only).
     A spring has no duration of its own; the times are when each one has settled. */
  --spring: linear(0, 0.067, 0.206, 0.359, 0.5, 0.62, 0.717, 0.792, 0.848, 0.891, 0.922, 0.945, 0.961, 0.972, 0.981, 0.987, 0.991, 0.994, 0.996, 0.997, 0.998, 0.999, 1);
  --spring-time: 0.59s;
  --bounce: linear(0, 0.087, 0.277, 0.489, 0.68, 0.829, 0.934, 0.999, 1.033, 1.045, 1.044, 1.037, 1.027, 1.018, 1.01, 1.005, 1.001, 0.999, 0.998, 0.998, 0.998, 0.999, 1);
  --bounce-time: 0.66s;
  --bezel: #1b1e23; /* the frame round a screenshot: hardware, so the same in every theme */
  interpolate-size: allow-keywords; /* lets the FAQ answers open by height where the browser can */
}

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-padding-top: 5rem;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 400 1.0625rem/1.6 system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
}

/* Tracking follows size: the larger the type, the tighter it sets. */
h1, h2, .display {
  margin: 0;
  font-family: "Playfair Display", Georgia, "Times New Roman", serif;
  font-weight: 700;
  letter-spacing: -0.01em;
  text-wrap: balance;
}
h1 { font-size: clamp(2.5rem, 1.6rem + 4.2vw, 4.5rem); line-height: 1.04; letter-spacing: -0.022em; }
h2 { font-size: clamp(1.75rem, 1.3rem + 2vw, 2.75rem); line-height: 1.12; letter-spacing: -0.015em; }
h3 { margin: 0; font-size: 1.125rem; font-weight: 700; line-height: 1.35; }
p { margin: 0; text-wrap: pretty; }
dl, dd, ol, ul { margin: 0; padding: 0; }
ol, ul { list-style: none; }

a { color: var(--accent-text); text-underline-offset: 0.2em; }
:focus-visible { outline: 2px solid var(--accent-text); outline-offset: 3px; border-radius: 4px; }
button { font: inherit; color: inherit; }
[hidden] { display: none !important; }

.wrap { width: min(100% - clamp(2rem, 8vw, 5rem), 72rem); margin-inline: auto; }
.eyebrow { font-size: 0.75rem; font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase; color: var(--accent-text); }
.lede { max-width: 34rem; font-size: clamp(1.125rem, 1rem + 0.5vw, 1.3125rem); line-height: 1.55; color: var(--muted); }
.muted { color: var(--muted); }
.small { font-size: 0.9375rem; }
.nb { white-space: nowrap; }
.flow > * + * { margin-top: 1rem; }

.skip { position: absolute; left: 1rem; top: -4rem; z-index: 20; padding: 0.5rem 1rem; border-radius: 10px; background: var(--accent); color: var(--on-accent); }
.skip:focus { top: 0.5rem; }

/* Buttons. The press answers in 80ms; letting go springs back. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 3rem;
  padding: 0.75rem 1.5rem;
  border: 0;
  border-radius: 999px;
  background: var(--accent);
  color: var(--on-accent);
  font-size: 1.0625rem;
  font-weight: 700;
  line-height: 1.2;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
}
.btn-ghost {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 2.75rem;
  padding: 0.5rem 1.25rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: none;
  color: var(--accent-text);
  font-weight: 600;
  line-height: 1.2;
  cursor: pointer;
}
.btn-small { min-height: 2.5rem; padding: 0.375rem 1rem; font-size: 0.9375rem; }
.link { padding: 0; border: 0; background: none; color: var(--accent-text); text-decoration: underline; text-underline-offset: 0.2em; cursor: pointer; }
.btn, .btn-ghost, .key, .swatch, .paddle { transition: transform var(--spring-time) var(--spring), background-color 0.15s ease, border-color 0.15s ease; }
:is(.btn, .btn-ghost, .key, .swatch, .paddle):active { transition-duration: 0.08s; transition-timing-function: ease-out; }
:is(.btn, .btn-ghost, .swatch, .paddle):active { transform: scale(0.97); }
@media (hover: hover) {
  a:hover { text-decoration-thickness: 2px; }
  .btn:hover { background: var(--accent-text); }
  .btn-ghost:hover, .paddle:hover { border-color: var(--accent); }
}

/* Header: a material, not a strip. The page scrolls under it, and its hairline is a scroll
   edge that only appears once something is actually underneath. */
.site-header {
  position: sticky;
  top: 0;
  z-index: 10;
  background: color-mix(in srgb, var(--bg-deep) 82%, transparent);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
  border-bottom: 1px solid var(--border);
}
@supports (animation-timeline: scroll()) {
  .site-header { border-bottom-color: transparent; animation: edge linear both; animation-timeline: scroll(); animation-range: 0 3rem; }
}
@keyframes edge { to { border-bottom-color: var(--border); } }
@media (prefers-reduced-transparency: reduce) {
  .site-header { background: var(--bg-deep); -webkit-backdrop-filter: none; backdrop-filter: none; }
}
@media (prefers-contrast: more) {
  .site-header { background: var(--bg-deep); -webkit-backdrop-filter: none; backdrop-filter: none; border-bottom-color: var(--text); animation: none; }
}
.bar { display: flex; align-items: center; gap: 1.25rem; min-height: 3.75rem; }
.brand { display: inline-flex; align-items: center; gap: 0.625rem; margin-right: auto; color: var(--text); font-size: 1.125rem; text-decoration: none; }
.brand img { border-radius: 7px; }
.brand span { white-space: nowrap; }
.site-nav { display: none; gap: 1.5rem; }
.site-nav a, .lang { color: var(--muted); font-size: 0.9375rem; text-decoration: none; transition: color 0.15s ease; }
@media (hover: hover) { .site-nav a:hover, .lang:hover { color: var(--text); text-decoration: none; } }
.lang { padding-block: 0.5rem; }
@media (min-width: 64rem) { .site-nav { display: flex; } }
/* Phones: the bar holds the mark, the language and the one button, in that order of survival. */
@media (max-width: 29.99rem) { .brand-sub { display: none; } }
@media (max-width: 22.49rem) { .bar .lang { display: none; } }

/* Hero: the copy, and the bench where the board sits under the lamp. */
.hero {
  display: grid;
  align-items: start; /* the bench grows when the ladder opens; the copy must not move with it */
  gap: 2.5rem;
  padding-block: clamp(2.5rem, 6vw, 5rem) clamp(3rem, 8vw, 6rem);
}
.hero-copy > * + * { margin-top: 1.25rem; }
.hero-copy .btn { margin-top: 0.5rem; }
@media (min-width: 60rem) {
  .hero { grid-template-columns: minmax(0, 1fr) minmax(0, 27.5rem); gap: 4rem; }
  .hero-copy { padding-top: clamp(1rem, 6vw, 5rem); }
}
.lamp { position: relative; isolation: isolate; }
.lamp::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: radial-gradient(42rem 30rem at 78% 0%, color-mix(in srgb, var(--accent) 11%, transparent), transparent 70%);
}

.bench {
  container-type: inline-size;
  display: flex;
  flex-direction: column;
  padding: 1rem;
  border: 1px solid var(--border);
  border-radius: 18px;
  background: var(--surface);
  /* A large surface reads as thick: the app's "floating" shadow, and a top edge that catches the lamp. */
  box-shadow: inset 0 1px 0 color-mix(in srgb, var(--text) 7%, transparent), 0 16px 32px rgb(0 0 0 / var(--shade));
}
.bench > .board, .bench > .bench-status { margin-top: 0.875rem; }
.smith-note { min-height: 4.5rem; padding-left: 0.875rem; border-left: 2px solid var(--accent); }
.smith-line { margin-top: 0.25rem; font-size: 1.125rem; line-height: 1.4; }

/* A fold opens and closes by height from where it sits, and takes no room when shut.
   Its inner box is padded and pulled back out so focus rings are not clipped. */
.fold { display: grid; grid-template-rows: 1fr; transition: opacity 0.25s ease, display 0.25s allow-discrete; }
.fold > * { min-height: 0; overflow: hidden; padding: 0 6px 6px; margin: 0 -6px -6px; }
.fold[hidden] { opacity: 0; }
@starting-style { .fold:not([hidden]) { opacity: 0; } }

.board {
  position: relative;
  container-type: inline-size;
  display: grid;
  grid-template-columns: repeat(9, 1fr);
  aspect-ratio: 1;
  overflow: hidden;
  border: 2px solid var(--line-thick);
  border-radius: 10px;
  background: var(--board);
}
/* The two thick lines each way, drawn over the cells so no cell needs to know its box. */
.board::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    linear-gradient(var(--line-thick), var(--line-thick)) calc(100% / 3) 0 / 2px 100% no-repeat,
    linear-gradient(var(--line-thick), var(--line-thick)) calc(200% / 3) 0 / 2px 100% no-repeat,
    linear-gradient(var(--line-thick), var(--line-thick)) 0 calc(100% / 3) / 100% 2px no-repeat,
    linear-gradient(var(--line-thick), var(--line-thick)) 0 calc(200% / 3) / 100% 2px no-repeat;
}
.cell {
  display: grid;
  place-items: center;
  aspect-ratio: 1;
  margin: 0;
  padding: 0;
  border: 0;
  border-right: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  border-radius: 0;
  background-color: transparent;
  color: var(--entered);
  font-size: 5.6cqw;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  line-height: 1;
  cursor: pointer;
}
.cell:nth-child(9n) { border-right: 0; }
.cell:nth-child(n + 73) { border-bottom: 0; }
.cell:focus-visible { outline-offset: -3px; border-radius: 0; }
.cell.given { background-color: var(--given-bg); color: var(--given); font-weight: 600; }
/* Washes sit on top of the cell's own colour, as they do in the app. */
.cell.related { background-image: linear-gradient(var(--related), var(--related)); }
.cell.same { background-image: linear-gradient(var(--same), var(--same)); }
/* The cell answers the pointer before the tap commits. */
@media (hover: hover) { [data-board] .cell:hover { background-image: linear-gradient(var(--related), var(--related)); } }
[data-board] .cell:active { background-image: linear-gradient(var(--selected), var(--selected)); }
/* On the selected cell every digit takes the given colour: three themes drop below 3:1 otherwise. */
.cell.selected { background-image: linear-gradient(var(--selected), var(--selected)); box-shadow: inset 0 0 0 2px var(--ring); color: var(--given); }
/* Last, so a wrong digit still reads as wrong while its cell is selected. */
.cell.wrong { background-color: var(--conflict-bg); background-image: none; color: var(--conflict); }
.cell.struck { animation: flash 0.4s ease-out; }
@keyframes flash { from { background-color: var(--accent); } }

.controls { display: grid; gap: 0.875rem; padding-top: 0.875rem; }
.keypad { display: grid; grid-template-columns: repeat(5, 1fr); gap: 0.375rem; }
@container (min-width: 25rem) { .keypad { grid-template-columns: repeat(10, 1fr); } }
.key {
  min-height: 2.75rem;
  padding: 0;
  border: 1px solid var(--key-border);
  border-radius: 10px;
  background: var(--key-bg);
  color: var(--key-text);
  font-size: 1.125rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
}
.key:active { transform: scale(0.94); background: color-mix(in srgb, var(--accent) 26%, var(--key-bg)); }
.ladder .btn-ghost { width: 100%; }
.ladder .fold > * { padding-top: 0.5rem; }
.ladder-panel { display: grid; gap: 0.5rem; padding: 0.875rem; border: 1px solid var(--border); border-radius: 10px; }
.ladder-step { font-size: 0.75rem; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }
.ladder-actions { margin-top: 0.25rem; }
.bench-status { min-height: 3em; font-size: 0.9375rem; line-height: 1.5; color: var(--muted); }
.solved { display: grid; justify-items: start; gap: 0.75rem; padding-top: 0.25rem; }
.solved .btn { white-space: normal; }
/* New words cross-fade in; with motion allowed they materialise (below). */
.arrive { animation: fade 0.3s ease; }
@keyframes fade { from { opacity: 0; } }

/* The gallery: real screens on a rail. It swipes on a phone, takes arrow keys when focused,
   and has paddles for a mouse. The frame is a plain rounded bezel, not a drawing of a phone. */
.gallery { padding-bottom: clamp(1rem, 4vw, 3.5rem); }
.gallery-head { display: flex; align-items: end; justify-content: space-between; gap: 2rem; }
.gallery-title { display: grid; gap: 1rem; max-width: 36rem; }
.paddles { display: none; gap: 0.5rem; }
@media (hover: hover) and (pointer: fine) and (min-width: 40rem) { .paddles { display: flex; } }
.paddle {
  width: 2.75rem;
  height: 2.75rem;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 50%;
  background: none;
  color: var(--text);
  font-size: 1.125rem;
  line-height: 1;
  cursor: pointer;
}
.paddle[aria-disabled="true"] { opacity: 0.35; cursor: default; }
.rail {
  display: flex;
  gap: clamp(1rem, 2.5vw, 2rem);
  margin-top: clamp(1rem, 3vw, 2rem);
  /* The same gutter as .wrap: the first screen lines up with the page, the rest run off its edge.
     The block padding is room for the shadows, which a scroller would otherwise clip. */
  padding: 1rem max(clamp(1rem, 4vw, 2.5rem), (100% - 72rem) / 2) 3rem;
  scroll-padding-inline: max(clamp(1rem, 4vw, 2.5rem), (100% - 72rem) / 2);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
}
.rail::-webkit-scrollbar { display: none; }
.rail:focus-visible { outline-offset: -4px; }
.rail > li { flex: none; width: clamp(13.5rem, 62vw, 16.5rem); scroll-snap-align: start; }
.rail figure { margin: 0; }
.phone {
  overflow: hidden;
  aspect-ratio: 600 / 1300;
  border: 5px solid var(--bezel);
  border-radius: 13% / 6%; /* the same corner in pixels on both axes */
  background: var(--bezel);
  box-shadow: 0 0 0 1px var(--border), 0 16px 32px rgb(0 0 0 / var(--shade));
}
.phone img { display: block; width: 100%; height: 100%; object-fit: cover; }
.rail figcaption { display: grid; gap: 0.25rem; margin-top: 1rem; }
.rail figcaption span { font-size: 0.9375rem; color: var(--muted); }

/* Sections: heading on the left, substance on the right. */
.section { padding-block: clamp(3.5rem, 8vw, 6.5rem); border-top: 1px solid var(--border); }
.split { display: grid; gap: 2rem; }
.split-head { display: grid; align-content: start; gap: 1rem; }
@media (min-width: 60rem) {
  .split { grid-template-columns: minmax(0, 20rem) minmax(0, 1fr); gap: clamp(3rem, 6vw, 6rem); }
  .split-head { position: sticky; top: 6rem; align-self: start; }
}

.rows > * { display: grid; gap: 0.375rem 2rem; padding-block: 1.25rem; border-top: 1px solid var(--border); }
.rows > *:last-child { border-bottom: 1px solid var(--border); }
@media (min-width: 44rem) {
  .rows > * { grid-template-columns: minmax(0, 11.5rem) minmax(0, 1fr); align-items: baseline; }
}
.ledger dt { font-size: 0.9375rem; color: var(--muted); }
.ledger dd { font-size: clamp(1.125rem, 1rem + 0.6vw, 1.375rem); line-height: 1.4; }
.inventory dt { font-family: "Playfair Display", Georgia, serif; font-weight: 700; font-size: 1.25rem; line-height: 1.3; }
.inventory dd { color: var(--muted); }
.after { margin-top: 1.5rem; color: var(--muted); }

.rungs { counter-reset: rung; }
.rungs li { counter-increment: rung; grid-template-columns: 3rem minmax(0, 1fr); align-items: start; }
.rungs li::before { content: counter(rung); font-family: "Playfair Display", Georgia, serif; font-weight: 700; font-size: 2.25rem; line-height: 1; color: var(--accent-text); }
.rungs p { margin-top: 0.25rem; color: var(--muted); }

.themes { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 1rem; }
.swatch {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  min-height: 2.75rem;
  padding: 0.375rem 0.875rem 0.375rem 0.5rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: none;
  color: var(--text);
  font-size: 0.9375rem;
  font-weight: 500;
  cursor: pointer;
}
.swatch[aria-pressed="true"] { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
.swatch i { width: 1.25rem; height: 1.25rem; border: 1px solid var(--border); border-radius: 50%; background: linear-gradient(135deg, var(--sw-bg) 50%, var(--sw-accent) 50%); }
.sample { width: 7.5rem; margin-top: 1rem; grid-template-columns: repeat(3, 1fr); }
.sample::after { content: none; }
.sample .cell { font-size: 18cqw; cursor: default; }
.sample .cell:nth-child(3n) { border-right: 0; }
.sample .cell:nth-child(n + 7) { border-bottom: 0; }

.plans { display: grid; gap: 2rem; }
@media (min-width: 40rem) { .plans { grid-template-columns: 1fr 1fr; } }
.plans ul { display: grid; gap: 0.5rem; margin-top: 0.75rem; }
.plans li { position: relative; padding-left: 1.25rem; color: var(--muted); }
.plans li::before { content: ""; position: absolute; left: 0; top: 0.75em; width: 0.5rem; height: 2px; background: var(--accent); }
.fine { margin-top: 2rem; }

.faq details { border-top: 1px solid var(--border); }
.faq details:last-child { border-bottom: 1px solid var(--border); }
.faq summary { display: flex; justify-content: space-between; gap: 1rem; padding-block: 1.125rem; font-weight: 600; cursor: pointer; list-style: none; }
.faq summary::-webkit-details-marker { display: none; }
/* The plus turns into a cross: the same mark opens the answer and closes it. */
.faq summary::after { content: "+"; flex: none; font-size: 1.375rem; font-weight: 400; line-height: 1.1; color: var(--accent-text); transition: transform var(--spring-time) var(--spring); }
.faq details[open] summary::after { transform: rotate(45deg); }
.faq details p { max-width: 40rem; padding-bottom: 1.25rem; color: var(--muted); }
.faq details::details-content { opacity: 0; transition: opacity 0.25s ease, content-visibility 0.25s allow-discrete; }
.faq details[open]::details-content { opacity: 1; }

.closing { display: grid; justify-items: center; gap: 1.25rem; text-align: center; }

/* Footer */
.site-footer { padding-block: 2.5rem; border-top: 1px solid var(--border); font-size: 0.9375rem; color: var(--muted); }
.site-footer .wrap { display: grid; gap: 1rem; }
.foot-links { display: flex; flex-wrap: wrap; gap: 0.5rem 1.5rem; }
.foot-links a { color: var(--text); text-decoration: none; }
@media (hover: hover) { .foot-links a:hover { text-decoration: underline; } }

/* Support, legal and 404 */
.page { padding-block: clamp(2.5rem, 6vw, 5rem) clamp(3.5rem, 8vw, 6rem); }
.narrow { max-width: 44rem; }
.page h1 { font-size: clamp(2.25rem, 1.6rem + 3vw, 3.5rem); }
.mail { font-size: clamp(1.25rem, 1rem + 1.2vw, 1.75rem); font-weight: 600; overflow-wrap: anywhere; }
.page .rows { margin-top: 2.5rem; }
.page .rows dt { font-weight: 700; }
.page .rows dd { color: var(--muted); }
.legal { overflow-wrap: break-word; }
.legal h1 { font-size: clamp(1.875rem, 1.4rem + 2vw, 2.75rem); }
.legal h3 { margin-top: 2.25rem; }
.legal ul { display: grid; gap: 0.375rem; padding-left: 1.25rem; list-style: disc; }
.legal li::marker { color: var(--accent); }
.legal .back { margin-top: 3rem; }

/* ---- Movement. Everything below is skipped for people who ask for reduced motion. ---- */
@media (prefers-reduced-motion: no-preference) {
  html, .rail { scroll-behavior: smooth; }
  @view-transition { navigation: auto; } /* pages cross-fade into each other */

  /* Arrival: the copy rises in order, the lamp comes on, the bench materialises under it. */
  .hero-copy > * { animation: rise var(--spring-time) var(--spring) backwards; }
  .hero-copy > :nth-child(2) { animation-delay: 0.06s; }
  .hero-copy > :nth-child(3) { animation-delay: 0.12s; }
  .hero-copy > :nth-child(4) { animation-delay: 0.18s; }
  .hero-copy > :nth-child(5) { animation-delay: 0.24s; }
  .lamp::before { animation: fade 1.6s ease-out backwards; }
  .bench { animation: materialise 0.8s var(--spring) 0.15s backwards; }
  .arrive { animation: materialise var(--spring-time) var(--spring); }
  @keyframes rise { from { opacity: 0; transform: translateY(1rem); } }
  /* Blur, scale and rise together, so a surface arrives as a material instead of fading in. */
  @keyframes materialise { from { opacity: 0; transform: translateY(0.75rem) scale(0.98); filter: blur(8px); } }

  /* Folds open by height on the default spring, and close the way they opened. */
  .fold { transition: grid-template-rows var(--spring-time) var(--spring), opacity 0.25s ease, display var(--spring-time) allow-discrete; }
  .fold[hidden] { grid-template-rows: 0fr; }
  @starting-style { .fold:not([hidden]) { grid-template-rows: 0fr; } }
  .faq details::details-content { block-size: 0; overflow: clip; transition: block-size var(--spring-time) var(--spring), opacity 0.25s ease, content-visibility var(--spring-time) allow-discrete; }
  .faq details[open]::details-content { block-size: auto; }

  /* A placed digit lands like the tile in the app icon: a touch large, then home, with the one bounce. */
  .cell.struck { z-index: 1; animation: flash 0.4s ease-out, land var(--bounce-time) var(--bounce); }
  @keyframes land { from { transform: scale(1.25); } }

  /* Solved: light runs corner to corner across the board, and one ring leaves it. */
  .is-solved .cell { animation: gleam 0.7s calc(var(--w, 0) * 40ms) ease-out backwards; }
  @keyframes gleam { 30% { background-color: color-mix(in srgb, var(--accent) 55%, var(--board)); } }
  .is-solved .board { animation: ring 1.2s ease-out; }
  @keyframes ring {
    from { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 55%, transparent); }
    to { box-shadow: 0 0 0 1.5rem transparent; }
  }
}

/* Scrolling is the gesture here: rows rise into place exactly as far as the page has been
   moved, and go back if it is moved back. Unsupported browsers simply show the page. */
@media screen and (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {
    /* Not the rail's own items: inside a sideways scroller a view timeline would never advance. */
    .split-head, .gallery-head, .rows > *, .plans > *, .faq details, .closing > *, .after, .fine {
      animation: rise linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 100%;
    }
  }
}

@media (prefers-reduced-motion: reduce) {
  .btn, .btn-ghost, .key, .swatch, .paddle, .faq summary::after { transition-duration: 0.1s; }
}
