/* crowdsourcedtech
   One stylesheet. Tokens first; brand/DESIGN.md explains each decision.
   The family: bundled.consulting (red dot), applist.info (yellow dot), crowdsourcedtech.com (cyan dot), one shared ink. */

/* ---- Fonts: self-hosted, SIL OFL 1.1 (licences next to the files) ---- */
@font-face {
  font-family: "Host Grotesk";
  font-style: normal;
  font-weight: 300 800;
  font-display: swap;
  src: url("../fonts/HostGrotesk-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC,
    U+2122, U+2191, U+2193, U+2197, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Host Grotesk";
  font-style: normal;
  font-weight: 300 800;
  font-display: swap;
  src: url("../fonts/HostGrotesk-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+1E00-1E9F, U+20A0-20AB, U+20AD-20C4, U+A720-A7FF;
}
@font-face {
  font-family: "Host Grotesk Fallback";
  src: local("Arial");
  ascent-override: 96.69%;
  descent-override: 30.01%;
  line-gap-override: 0%;
  size-adjust: 104.98%;
}
@font-face {
  font-family: "Commit Mono";
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url("../fonts/CommitMono-latin.woff2") format("woff2");
}
@font-face {
  font-family: "Sofia Sans Extra Condensed";
  font-style: normal;
  font-weight: 760 860;
  font-display: swap;
  src: url("../fonts/sofia-sans-extra-condensed-latin.woff2") format("woff2");
}

/* ---- Tokens: light ---- */
:root {
  --bg: oklch(0.995 0.001 250);          /* #fdfdfe page (applist canvas) */
  --surface: oklch(0.975 0.003 250);     /* row hover, open row */
  --sunken: oklch(0.955 0.004 250);      /* screenshot track, empty board squares */
  --border: oklch(0.915 0.004 250);      /* hairlines */
  --border-strong: oklch(0.85 0.006 250);
  --field: oklch(0.64 0.008 250);        /* input and tick-box boundary, 3.3:1 */
  --fg: oklch(0.21 0.006 250);           /* ink #16191b */
  --fg-muted: oklch(0.43 0.008 250);
  --fg-subtle: oklch(0.52 0.008 250);
  --sheet: oklch(1 0 0);                 /* the form sheet */
  --dot: oklch(0.62 0.13 230);           /* #0093c5 THE DOT. Decorative only, never the sole indicator */
  --on-dot: oklch(0.21 0.006 250);
  --primary: var(--fg);
  --primary-hover: oklch(0.32 0.007 250);
  --primary-fg: var(--bg);
  --danger: oklch(0.55 0.2 27);
  --media-edge: oklch(0 0 0 / 0.08);
  --icon-edge: oklch(0 0 0 / 0.1);
  --sheet-shadow: 0 1px 0 oklch(0 0 0 / 0.04), 0 18px 32px -24px oklch(0.2 0.01 250 / 0.35);

  --f-text: "Host Grotesk", "Host Grotesk Fallback", ui-sans-serif, system-ui, sans-serif;
  --f-mono: "Commit Mono", ui-monospace, "SF Mono", Menlo, monospace;
  --f-display: "Sofia Sans Extra Condensed", "Host Grotesk", "Arial Narrow", sans-serif;

  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --fast: 120ms;
  --base: 200ms;
  --slow: 280ms;

  /* Load sequence: one shared timeline for the header wordmark and the hero board.
     Both start together: the board's squares fill in while the redaction over the wordmark dissolves, and the
     last pixels clear as the board's cyan period lands, so the two land at the same moment. */
  --intro-start: 150ms;
  --square-step: 9ms;                                                         /* 36 squares in the board's "c" */
  --square-in: 200ms;                                                         /* each board square */
  --dot-in: 260ms;                                                            /* the board's period */
  --intro-dot: calc(var(--intro-start) + 36 * var(--square-step) + 80ms);     /* board period starts (~550ms) */
  --logo-clear: 120ms;                                                        /* each pixel group fades */
  --logo-step: calc((var(--intro-dot) + var(--dot-in) - var(--intro-start) - var(--logo-clear)) / 17); /* 18 steps, the period's pixel last, with the board's period (~0.8s) */

  --frame: 60rem;      /* 960 */
  --gutter: 12.5rem;   /* 200 label gutter */
  --gap: 2.5rem;       /* 40 */
  --side: 16px;

  color-scheme: light;
  interpolate-size: allow-keywords;
}

/* ---- Tokens: dark (default via data-default-theme; keep both blocks identical) ---- */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --bg: oklch(0.17 0.004 250);
    --surface: oklch(0.205 0.005 250);
    --sunken: oklch(0.235 0.005 250);
    --border: oklch(0.29 0.006 250);
    --border-strong: oklch(0.36 0.007 250);
    --field: oklch(0.55 0.007 250);
    --fg: oklch(0.95 0.003 250);
    --fg-muted: oklch(0.78 0.006 250);
    --fg-subtle: oklch(0.68 0.007 250);
    --sheet: oklch(0.205 0.005 250);
    --dot: oklch(0.78 0.12 225);
    --primary-hover: oklch(0.86 0.004 250);
    --danger: oklch(0.68 0.18 27);
    --media-edge: oklch(1 0 0 / 0.1);
    --icon-edge: oklch(1 0 0 / 0.12);
    --sheet-shadow: 0 0 0 1px oklch(0.29 0.006 250);
  }
}
:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: oklch(0.17 0.004 250);
  --surface: oklch(0.205 0.005 250);
  --sunken: oklch(0.235 0.005 250);
  --border: oklch(0.29 0.006 250);
  --border-strong: oklch(0.36 0.007 250);
  --field: oklch(0.55 0.007 250);
  --fg: oklch(0.95 0.003 250);
  --fg-muted: oklch(0.78 0.006 250);
  --fg-subtle: oklch(0.68 0.007 250);
  --sheet: oklch(0.205 0.005 250);
  --dot: oklch(0.78 0.12 225);
  --primary-hover: oklch(0.86 0.004 250);
  --danger: oklch(0.68 0.18 27);
  --media-edge: oklch(1 0 0 / 0.1);
  --icon-edge: oklch(1 0 0 / 0.12);
  --sheet-shadow: 0 0 0 1px oklch(0.29 0.006 250);
}

@media (min-width: 40rem) {
  :root { --side: 24px; }
}

/* ---- Base ---- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; scroll-padding-top: 72px; }
@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}
body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font: 400 0.9375rem/1.5rem var(--f-text);
  font-variant-numeric: proportional-nums;
  -webkit-font-smoothing: antialiased;
}
img, svg { display: block; max-width: 100%; }
h1, h2, h3, p, ul, ol, dl, dd, figure { margin: 0; }
ul, ol { padding: 0; list-style: none; }
a { color: inherit; }
::selection { background: var(--dot); color: var(--on-dot); }
:focus-visible { outline: 2px solid var(--fg); outline-offset: 3px; border-radius: 2px; }

.sr-only {
  position: absolute !important; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; border: 0;
}
.skip {
  position: absolute; left: var(--side); top: 8px; z-index: 100; padding: 8px 12px;
  background: var(--fg); color: var(--bg); border-radius: 6px; font-weight: 600; text-decoration: none;
  translate: 0 -200%;
}
.skip:focus { translate: 0 0; }

.frame { width: 100%; max-width: calc(var(--frame) + 2 * var(--side)); margin-inline: auto; padding-inline: var(--side); }
.mono { font-family: var(--f-mono); font-variant-numeric: tabular-nums; }

/* ---- Wordmark: Host Grotesk 700, the "." drawn as a 0.2em square (applist #113), cyan here ---- */
.wordmark {
  display: inline-block;
  font: 700 28px/36px var(--f-text); letter-spacing: -0.02em; color: var(--fg); text-decoration: none; white-space: nowrap;
}
.wordmark__dot {
  display: inline-block; inline-size: 0.2em; block-size: 0.2em; margin-inline: 0.05em 0.04em;
  overflow: hidden; color: transparent; line-height: 0; vertical-align: baseline;
  border-radius: 0.02em; background-color: var(--dot);
}
/* The reveal (tools/build_wordmark.py): the crisp wordmark is on the page from the first frame, covered by a
   solid redaction bar (period-sized 0.2em pixels, scaled to close the gaps) in the text colour the height of the letters. The pixels clear from both ends of the
   name inward and converge on the period, so the real wordmark unpixelates in place; there is no crossfade. It runs on the
   hero board's timeline and finishes as the board's period lands. CSS only; with reduced motion no pixels show. */
.wordmark { position: relative; }
.wordmark__px {
  position: absolute; inset-block-start: 0; inset-inline-start: 0; max-width: none; overflow: visible;
  fill: currentColor; opacity: 0; pointer-events: none;
}
.wordmark__px .px-dot { fill: var(--dot); }
.wordmark__ink { display: inline-block; }
@media (prefers-reduced-motion: no-preference) {
  .wordmark--intro .wordmark__px { opacity: 1; }
  .wordmark--intro .wordmark__px rect {
    transform-box: fill-box; transform-origin: center;
    animation: px-clear var(--logo-clear) var(--ease-out) calc(var(--intro-start) + var(--k, 0) * var(--logo-step)) both;
  }
  /* One solid bar behind the squares hides their antialiased seams until the animation starts, then steps away. */
  .wordmark--intro .wordmark__px .px-bar { animation: px-bar-off 1ms steps(1) var(--intro-start) both; }
}
@keyframes px-bar-off { to { opacity: 0; } }
/* At rest each square is 1.3x the period (the pitch is 1.2x; the overlap hides antialiased seams), so the bar is solid. On its
   turn a square shrinks to exactly the period's size, then fades out. */
@keyframes px-clear {
  from { scale: 1.3; opacity: 1; }
  45% { scale: 1; opacity: 1; }
  to { scale: 0.6; opacity: 0; }
}

/* wordmark-groups (written by tools/build_wordmark.py) */
.wordmark__px .g1 { --k: 1; }
.wordmark__px .g2 { --k: 2; }
.wordmark__px .g3 { --k: 3; }
.wordmark__px .g4 { --k: 4; }
.wordmark__px .g5 { --k: 5; }
.wordmark__px .g6 { --k: 6; }
.wordmark__px .g7 { --k: 7; }
.wordmark__px .g8 { --k: 8; }
.wordmark__px .g9 { --k: 9; }
.wordmark__px .g10 { --k: 10; }
.wordmark__px .g11 { --k: 11; }
.wordmark__px .g12 { --k: 12; }
.wordmark__px .g13 { --k: 13; }
.wordmark__px .g14 { --k: 14; }
.wordmark__px .g15 { --k: 15; }
.wordmark__px .g16 { --k: 16; }
.wordmark__px .g17 { --k: 17; }
/* /wordmark-groups */

/* ---- Buttons and links ---- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-height: 44px; padding: 0 20px;
  border: 0; border-radius: 6px; background: var(--primary); color: var(--primary-fg);
  font: 600 0.9375rem/1 var(--f-text); text-decoration: none; cursor: pointer;
  transition: background-color var(--fast) var(--ease-out), scale 90ms var(--ease-out);
}
.btn:hover { background: var(--primary-hover); }
.btn:active { scale: 0.98; }
.btn--quiet { background: transparent; color: var(--fg); box-shadow: inset 0 0 0 1px var(--border-strong); }
.btn--quiet:hover { background: var(--surface); }

.link {
  color: var(--fg); text-decoration: underline; text-decoration-color: var(--border-strong);
  text-decoration-thickness: 1px; text-underline-offset: 0.2em;
  transition: text-decoration-color var(--fast) var(--ease-out);
}
.link:hover { text-decoration-color: var(--dot); text-decoration-thickness: 2px; }

/* ---- Cursor square: the same behaviour as bundled.consulting's, in cyan. A 10px square eases after a fine pointer,
   just past the end of the arrow's stem (offset in site.js). It flies into a hovered underline, the wordmark's
   period or a hero-board square. Over buttons and other controls without an underline it swells into a soft
   highlight; pressing shrinks it; over text fields it gets out of the caret's way. Decorative: aria-hidden,
   no pointer events, and the system cursor stays. ---- */
.cursor-dot {
  position: fixed; inset-block-start: 0; inset-inline-start: 0; z-index: 2147483000;
  inline-size: 10px; block-size: 10px; margin: -5px 0 0 -5px;
  pointer-events: none; opacity: 0;
  transition: opacity 200ms ease-out, inline-size 120ms var(--ease-out), block-size 120ms var(--ease-out), margin 120ms var(--ease-out);
}
/* A minute without input (applist.info's idle state): the square slowly grows; any input snaps it back in 120ms.
   Sized with width and height, not scale: the transform is the square's position. */
.cursor-dot.is-idle {
  inline-size: 14px; block-size: 14px; margin: -7px 0 0 -7px;
  transition: opacity 200ms ease-out, inline-size 600ms var(--ease-out), block-size 600ms var(--ease-out), margin 600ms var(--ease-out);
}
.cursor-dot.is-visible { opacity: 1; }
.cursor-dot__mark {
  display: block; inline-size: 100%; block-size: 100%; border-radius: 1px; background: var(--dot);
  transition: transform 220ms cubic-bezier(0.16, 1, 0.3, 1), opacity 220ms ease-out;
}
/* over buttons, switches and other controls without an underline: swell into a soft highlight */
.cursor-dot.is-active .cursor-dot__mark { transform: scale(2.2); opacity: 0.35; }
/* while pressing */
.cursor-dot.is-pressed .cursor-dot__mark { transform: scale(0.7); }
.cursor-dot.is-active.is-pressed .cursor-dot__mark { transform: scale(1.8); }
/* over text fields: get out of the way of the caret */
.cursor-dot.is-typing .cursor-dot__mark { opacity: 0; transform: scale(0.4); }
@media (prefers-reduced-motion: reduce) {
  .cursor-dot, .cursor-dot__mark { transition: none; }
}
.ext::after { content: "\2197"; margin-inline-start: 0.15em; font-family: var(--f-text); }

/* ---- Header: 56 tall in the 960 frame (applist #102); a hairline fades in once the page scrolls ---- */
.site-head { position: sticky; top: 0; z-index: 50; background: var(--bg); }
.site-head::after {
  content: ""; position: absolute; inset: auto 0 0; height: 1px; background: var(--border); opacity: 0;
}
@supports (animation-timeline: scroll()) {
  .site-head::after { animation: head-rule linear both; animation-timeline: scroll(root); animation-range: 0 48px; }
}
@supports not (animation-timeline: scroll()) {
  .site-head::after { opacity: 1; }
}
@keyframes head-rule { to { opacity: 1; } }
.site-head__row { display: flex; align-items: center; justify-content: space-between; gap: 16px; min-height: 56px; }
.site-nav { display: flex; align-items: center; gap: 24px; }
.site-nav ul { display: none; gap: 24px; }
.site-nav a {
  color: var(--fg-muted); text-decoration: underline; text-decoration-color: transparent; text-decoration-thickness: 2px;
  text-underline-offset: 0.2em; transition: color var(--fast) var(--ease-out), text-decoration-color var(--fast) var(--ease-out);
}
/* Like every other link, a hovered nav link shows a cyan underline, and the cursor square flies into it. */
.site-nav a:hover { color: var(--fg); text-decoration-color: var(--dot); }
@media (min-width: 48rem) {
  .site-nav ul { display: flex; }
}

/* The "Dark" tick box: bundled's printed switch, an ink square when ticked */
.switch {
  display: inline-flex; align-items: center; gap: 8px; height: 32px; padding: 0 12px;
  border: 1px solid var(--border); border-radius: 2px; color: var(--fg);
  font: 500 0.8125rem/1 var(--f-text); cursor: pointer; white-space: nowrap;
}
.switch input {
  appearance: none; flex: none; width: 14px; height: 14px; margin: 0; border: 1.5px solid var(--field);
  border-radius: 1px; background: transparent; cursor: pointer; display: grid; place-content: center;
  transition: border-color var(--fast) var(--ease-out);
}
.switch input::before {
  content: ""; width: 8px; height: 8px; border-radius: 0.5px; background: var(--fg); scale: 0;
  transition: scale var(--fast) var(--ease-out);
}
.switch input:checked { border-color: var(--fg); }
.switch input:checked::before { scale: 1; }
.switch:hover input { border-color: var(--fg); }
html:not(.js) .switch { display: none; }

/* Theme change: a circle opens from the tick box (site.js). Only the new snapshot animates. */
::view-transition-old(root), ::view-transition-new(root) { animation: none; mix-blend-mode: normal; }

/* ---- Hero ---- */
.hero { display: grid; gap: 40px; padding-block: 40px 56px; }
@media (min-width: 56rem) {
  .hero { grid-template-columns: minmax(0, 1fr) 380px; align-items: center; gap: var(--gap); padding-block: 72px 96px; }
}
.hero h1 {
  font: 800 clamp(3rem, 7.4vw, 5.75rem)/0.94 var(--f-display); letter-spacing: -0.005em; text-wrap: balance; max-width: 11ch;
}
/* The headline's full stop is the brand's square period: the size and spacing of Sofia's own "." (0.16em on the
   baseline), in cyan. The character stays in the text for copying and screen readers. */
.hero-dot {
  display: inline-block; inline-size: 0.16em; block-size: 0.16em; margin-inline: 0.035em 0.03em;
  overflow: hidden; color: transparent; line-height: 0; vertical-align: baseline;
  border-radius: 0.015em; background-color: var(--dot);
}
.hero .lead { margin-top: 24px; max-width: 34rem; color: var(--fg-muted); font-size: 1.0625rem; line-height: 1.75rem; text-wrap: pretty; }
.hero .actions { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 20px; margin-top: 32px; }
.hero .meta { margin-top: 32px; color: var(--fg-subtle); font-size: 0.8125rem; line-height: 1.125rem; }
.hero .meta span + span::before { content: "\00B7"; margin-inline: 0.6em; }

/* The board: 11 x 8 squares. The crowd fills in a "c", the cyan period lands last. */
.board-wrap { justify-self: start; width: min(100%, 380px); }
@media (min-width: 56rem) { .board-wrap { justify-self: end; } }
.board {
  display: grid; grid-template-columns: repeat(11, 1fr); gap: 6px; width: 100%;
  touch-action: manipulation; user-select: none; -webkit-user-select: none;
}
.board i {
  position: relative; aspect-ratio: 1; border-radius: 1px; background: var(--sunken); cursor: pointer;
  transition: background-color var(--fast) var(--ease-out), scale 90ms var(--ease-out);
}
.board i:hover { background: var(--border-strong); }
.board i:active { scale: 0.9; }
.board i.on { cursor: default; }
.board i.on::after { content: ""; position: absolute; inset: 0; border-radius: inherit; background: var(--fg); }
.board i.on:hover { background: var(--sunken); }
.board i.dot { grid-column: 10 / span 2; grid-row: 7 / span 2; aspect-ratio: auto; background: var(--dot); cursor: default; }
.board i.added { background: var(--fg-muted); }
@media (prefers-reduced-motion: no-preference) {
  .board--intro i.on::after {
    animation: square-in var(--square-in) var(--ease-out) backwards;
    animation-delay: calc(var(--intro-start) + var(--i, 0) * var(--square-step));
  }
  .board--intro i.dot { animation: dot-in var(--dot-in) var(--ease-out) var(--intro-dot) backwards; }
  .board i.added { animation: square-in 200ms var(--ease-out); }
}
@keyframes square-in { from { opacity: 0; scale: 0.4; } }
@keyframes dot-in { from { opacity: 0; translate: 0 -40%; scale: 0.6; } 60% { opacity: 1; } }

/* board-order (written by tools/build_board.py) */
.board i:nth-child(3) { --i: 14; }
.board i:nth-child(4) { --i: 25; }
.board i:nth-child(5) { --i: 21; }
.board i:nth-child(6) { --i: 32; }
.board i:nth-child(13) { --i: 31; }
.board i:nth-child(14) { --i: 3; }
.board i:nth-child(15) { --i: 23; }
.board i:nth-child(16) { --i: 17; }
.board i:nth-child(17) { --i: 6; }
.board i:nth-child(18) { --i: 34; }
.board i:nth-child(23) { --i: 2; }
.board i:nth-child(24) { --i: 27; }
.board i:nth-child(25) { --i: 9; }
.board i:nth-child(28) { --i: 20; }
.board i:nth-child(29) { --i: 8; }
.board i:nth-child(30) { --i: 13; }
.board i:nth-child(34) { --i: 24; }
.board i:nth-child(35) { --i: 29; }
.board i:nth-child(45) { --i: 26; }
.board i:nth-child(46) { --i: 15; }
.board i:nth-child(56) { --i: 35; }
.board i:nth-child(57) { --i: 18; }
.board i:nth-child(58) { --i: 11; }
.board i:nth-child(61) { --i: 7; }
.board i:nth-child(62) { --i: 1; }
.board i:nth-child(63) { --i: 33; }
.board i:nth-child(68) { --i: 30; }
.board i:nth-child(69) { --i: 5; }
.board i:nth-child(70) { --i: 10; }
.board i:nth-child(71) { --i: 4; }
.board i:nth-child(72) { --i: 16; }
.board i:nth-child(73) { --i: 0; }
.board i:nth-child(79) { --i: 28; }
.board i:nth-child(80) { --i: 22; }
.board i:nth-child(81) { --i: 12; }
.board i:nth-child(82) { --i: 19; }
/* /board-order */

/* ---- Sections: label gutter + content column (applist frame) ---- */
.section { display: grid; gap: 16px; padding-block: 56px; border-top: 1px solid var(--border); }
@media (min-width: 56rem) {
  .section { grid-template-columns: var(--gutter) minmax(0, 1fr); column-gap: var(--gap); padding-block: 80px; }
}
.section__label { color: var(--fg-subtle); font-size: 0.8125rem; line-height: 1.125rem; }
.section__label .mono { margin-inline-start: 6px; }
@media (min-width: 56rem) {
  .section__label { position: sticky; top: 80px; align-self: start; padding-top: 10px; }
}
.section h2 { font-weight: 600; font-size: 2rem; line-height: 2.25rem; letter-spacing: -0.015em; text-wrap: balance; max-width: 22ch; }
.section .intro { margin-top: 12px; max-width: 38rem; color: var(--fg-muted); font-size: 1.0625rem; line-height: 1.75rem; text-wrap: pretty; }

/* ---- How we build: hairline rows ---- */
.rows { margin-top: 32px; border-top: 1px solid var(--border); }
.rows > li { display: grid; gap: 8px; padding-block: 24px; border-bottom: 1px solid var(--border); }
@media (min-width: 40rem) { .rows > li { grid-template-columns: 15rem minmax(0, 1fr); gap: 24px; } }
.rows h3 { font-weight: 600; font-size: 1.0625rem; line-height: 1.5rem; }
.rows p { color: var(--fg-muted); max-width: 32rem; text-wrap: pretty; }

/* ---- The suggestion form: a printed sheet with ruled boxes (bundled) ---- */
.sheet {
  margin-top: 32px; max-width: 40rem; background: var(--sheet); border-radius: 2px; box-shadow: var(--sheet-shadow);
  border-top: 4px solid var(--dot);
}
.sheet__head {
  display: flex; justify-content: space-between; align-items: baseline; gap: 16px; padding: 16px 20px;
  border-bottom: 1px solid var(--border-strong); font-size: 0.8125rem;
}
.sheet__title { font-weight: 600; }
.sheet__no { color: var(--fg-subtle); }
.boxes { display: grid; grid-template-columns: 1fr; }
@media (min-width: 40rem) { .boxes { grid-template-columns: 1fr 1fr; } }
.box { position: relative; display: grid; border-bottom: 1px solid var(--border-strong); }
@media (min-width: 40rem) { .box:nth-child(odd):not(.box--wide) { border-inline-end: 1px solid var(--border-strong); } }
.box--wide { grid-column: 1 / -1; }
.box label { padding: 10px 20px 0; color: var(--fg-subtle); font-size: 0.75rem; line-height: 1rem; }
/* Required marks are the brand cyan; the asterisk shape and the note under the form carry the meaning, not the colour. */
.box label .req, .sheet__foot .req { color: var(--dot); font-weight: 600; }
.box input, .box select, .box textarea {
  width: 100%; min-height: 44px; padding: 4px 20px 12px; border: 0; border-radius: 0; background: transparent; color: var(--fg);
  font: 400 1rem/1.5rem var(--f-text); outline: none; appearance: none;
}
.box select {
  background-image: linear-gradient(45deg, transparent 50%, var(--fg-subtle) 50%), linear-gradient(-45deg, transparent 50%, var(--fg-subtle) 50%);
  background-position: calc(100% - 26px) 50%, calc(100% - 21px) 50%; background-size: 5px 5px; background-repeat: no-repeat; cursor: pointer;
}
.box textarea { min-height: 160px; resize: vertical; field-sizing: content; }
.box::after {
  content: ""; position: absolute; inset: auto 0 -1px; height: 2px; background: var(--fg); scale: 0 1; transform-origin: left;
  transition: scale var(--base) var(--ease-out);
}
.box:focus-within::after { scale: 1 1; }
.box:has(:user-invalid)::after { scale: 1 1; background: var(--danger); }
.sheet__foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 16px; padding: 20px; }
.sheet__foot p { color: var(--fg-subtle); font-size: 0.8125rem; max-width: 22rem; }
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.alert { margin-top: 24px; max-width: 40rem; padding: 12px 16px; border-left: 2px solid var(--danger); background: var(--surface); }
.alert:empty { display: none; }

/* ---- Footer ---- */
.site-foot { padding-block: 40px 56px; border-top: 1px solid var(--border); color: var(--fg-muted); }
.site-foot__grid { display: grid; gap: 24px; }
@media (min-width: 56rem) { .site-foot__grid { grid-template-columns: var(--gutter) minmax(0, 1fr) auto; column-gap: var(--gap); align-items: start; } }
.site-foot .tile { width: 32px; height: 32px; border-radius: 3px; }
.site-foot ul { display: flex; flex-wrap: wrap; gap: 8px 24px; }
.site-foot a {
  color: var(--fg-muted); text-decoration: underline; text-decoration-color: transparent; text-decoration-thickness: 2px;
  text-underline-offset: 0.2em; transition: color var(--fast) var(--ease-out), text-decoration-color var(--fast) var(--ease-out);
}
.site-foot a:hover { color: var(--fg); text-decoration-color: var(--dot); }
.site-foot small { display: block; margin-top: 8px; color: var(--fg-subtle); font-size: 0.8125rem; }

/* ---- Brand page (/brand) ---- */
.brand-intro { border-bottom: 0; }
.brand-note { margin-top: 12px; color: var(--fg-subtle); font-size: 0.8125rem; }
.mark-dot {
  display: inline-block; inline-size: 0.2em; block-size: 0.2em; margin-inline: 0.05em 0.04em;
  overflow: hidden; color: transparent; line-height: 0; vertical-align: baseline; border-radius: 0.02em; background-color: var(--dot);
}

/* Name: right and wrong forms, marked with the same filled and empty squares as the hero board */
.usage { display: grid; gap: 10px; margin-top: 24px; }
.usage li { display: flex; align-items: center; gap: 12px; font-size: 1.0625rem; }
.usage__mark { flex: none; width: 12px; height: 12px; border-radius: 1px; background: var(--sunken); }
.usage__mark--yes { background: var(--dot); }
.usage li:not(:first-child) .mono { color: var(--fg-subtle); text-decoration: line-through; text-decoration-color: var(--border-strong); }

/* Specimens: fixed light and dark panels, whatever the page theme, so each file is seen on the background it is for */
.specimens { display: grid; gap: 16px; margin-top: 28px; }
.specimens--marks { grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); }
.specimen { display: grid; gap: 24px; padding: 32px 24px 16px; border-radius: 2px; }
.specimen img { width: min(100%, 320px); height: auto; }
.specimens--marks .specimen img { width: 72px; }
.specimen--light { background: #fdfdfe; color: #16191b; box-shadow: inset 0 0 0 1px #e1e3e5; }
.specimen--dark { background: #0e1011; color: #edeff0; box-shadow: inset 0 0 0 1px #292c2e; }
.specimen__meta { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 8px 16px; font-size: 0.8125rem; opacity: 0.85; }
.specimen__files { display: flex; gap: 16px; }
.specimen .link { color: inherit; }

.sizes { display: flex; align-items: flex-end; gap: 24px; margin-top: 28px; }
.sizes figure { display: grid; justify-items: center; gap: 8px; }
.sizes figcaption { color: var(--fg-subtle); font-size: 0.75rem; }

/* Colour swatches: select one to copy its value */
.swatches { display: grid; grid-template-columns: repeat(auto-fill, minmax(13.5rem, 1fr)); gap: 8px 24px; margin-top: 28px; }
.swatch {
  display: grid; grid-template-columns: 40px 1fr; grid-template-rows: auto auto auto; column-gap: 14px; align-items: center;
  width: 100%; padding: 10px; margin-inline: -10px; border: 0; border-radius: 6px; background: transparent; color: var(--fg);
  font: inherit; text-align: start; cursor: copy; transition: background-color var(--fast) var(--ease-out);
}
.swatch:hover { background: var(--surface); }
.swatch__chip { grid-row: 1 / 4; width: 40px; height: 40px; border-radius: 1px; box-shadow: inset 0 0 0 1px var(--media-edge); }
.swatch__name { font-weight: 600; }
.swatch__value { color: var(--fg-muted); font-size: 0.8125rem; }
.swatch__role { color: var(--fg-subtle); font-size: 0.8125rem; line-height: 1.125rem; }
.swatch[data-copied] .swatch__value { color: var(--fg); }
.swatch__chip--cyan-deep { background: #0093c5; }
.swatch__chip--cyan { background: #51c7f1; }
.swatch__chip--ink { background: #16191b; }
.swatch__chip--night { background: #0e1011; }
.swatch__chip--paper { background: #fdfdfe; }
.swatch__chip--snow { background: #edeff0; }
.swatch__chip--muted { background: #4d5054; }
.swatch__chip--hairline { background: #e1e3e5; }

/* Type specimens */
.faces { margin-top: 28px; border-top: 1px solid var(--border); }
.faces li { display: grid; gap: 10px; padding-block: 24px; border-bottom: 1px solid var(--border); }
.face__sample { max-width: 36rem; text-wrap: balance; }
.face__sample--display { font: 800 clamp(2.25rem, 5vw, 3.5rem)/0.94 var(--f-display); }
.face__sample--text { font-size: 1.375rem; line-height: 1.75rem; }
.face__sample--mono { font: 400 1.0625rem/1.5rem var(--f-mono); font-variant-numeric: tabular-nums; }
.face__meta { display: flex; flex-wrap: wrap; gap: 4px 16px; color: var(--fg-subtle); font-size: 0.8125rem; }
.face__meta span:first-child { color: var(--fg-muted); }

@media (prefers-reduced-motion: reduce) { .motion-only { display: none; } }

/* ---- Simple pages (thanks, 404, privacy) ---- */
.page { padding-block: 56px 96px; }
@media (min-width: 56rem) { .page { display: grid; grid-template-columns: var(--gutter) minmax(0, 1fr); column-gap: var(--gap); padding-block: 80px 120px; } }
.page h1 { font: 800 clamp(2.75rem, 6vw, 4.5rem)/0.94 var(--f-display); text-wrap: balance; max-width: 14ch; }
.page .intro { margin-top: 20px; max-width: 38rem; color: var(--fg-muted); font-size: 1.0625rem; line-height: 1.75rem; }
.page .actions { display: flex; flex-wrap: wrap; gap: 12px 20px; align-items: center; margin-top: 32px; }
.ref {
  display: inline-flex; align-items: center; gap: 10px; margin-top: 28px; padding: 10px 14px; border: 1px solid var(--border-strong);
  border-radius: 2px; font-family: var(--f-mono); font-size: 1.0625rem;
}
.ref::before { content: ""; width: 10px; height: 10px; border-radius: 1px; background: var(--dot); }
.ref:empty { display: none; }
.prose { max-width: 40rem; margin-top: 32px; color: var(--fg-muted); }
.prose h2 { margin-top: 32px; color: var(--fg); font-weight: 600; font-size: 1.0625rem; line-height: 1.5rem; }
.prose p, .prose ul { margin-top: 8px; }
.prose ul { padding-inline-start: 1.1em; list-style: square; }
