/* Self-hosted latin subsets, downloaded from Google Fonts (both SIL Open Font License):
   Anybody — variable, width 50–150 and weight 100–900: build names at 800 / width 150, chrome and prose at 100–112.
   Azeret Mono — variable, weight 100–900: spec lines, readouts, labels, figure text.
   Neither has an italic; glyphs outside the subset (arrows, ≤ ≥, Ω) fall back to the system face in each stack. */
@font-face {
  font-family: 'Anybody';
  font-style: normal;
  font-weight: 100 900;
  font-stretch: 50% 150%;
  font-display: swap;
  src: url('../fonts/anybody-var.woff2') format('woff2');
  unicode-range: U+0000-00D6, U+00D8-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+2212, U+2215, U+FEFF, U+FFFD;
}
/* Anybody's multiplication sign is a dot-sized glyph that makes 640×480 read as 640·480: borrow Azeret Mono's */
@font-face {
  font-family: 'Anybody';
  font-style: normal;
  font-weight: 100 900;
  font-stretch: 50% 150%;
  font-display: swap;
  src: url('../fonts/azeretmono-var.woff2') format('woff2');
  unicode-range: U+00D7;
}
@font-face {
  font-family: 'Azeret Mono';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('../fonts/azeretmono-var.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+2212, U+2215, U+FEFF, U+FFFD;
}
/* tokens.css — generated from packages/tokens/src/tokens.ts by `pnpm build`; edit the TypeScript, not this file.
   Contrast of each ink on each ground where it is used: ink-light on black 16.4 / walnut 14.4 · dim-light 8.1 / 7.1 · ink-dark on paper 15.6 / sand 13.2 / dusk 12.3 · dim-dark 6.6 / 5.5 / 5.2.
   Link underlines and meaning-bearing strokes use the dim ink (at least 3:1 everywhere). */
:root {
  color-scheme: light;
  --f-sans: "Anybody", "Segoe UI", system-ui, sans-serif; --f-mono: "Azeret Mono", "Cascadia Mono", Consolas, "SF Mono", Menlo, monospace;
  --g-black: #120E0B; --g-paper: #F3EEE4; --g-sand: #E7DBC3; --g-walnut: #241B15; --g-dusk: #E8D2AE;
  --ink-light: #F4ECDF; --ink-dark: #1C150F; --dim-light: #B3A796; --dim-dark: #5E5244;
  --g: var(--g-paper); --ink: var(--ink-dark); --dim: var(--dim-dark);
  --k-name: 1; --k-text: 1; --k-space: 1; --name-wdth: 150; --name-wght: 800;
  --t-name: calc(min(clamp(1.9rem, 6.1vw + .2rem, 6.25rem), (100vw - 2rem) / 11) * var(--k-name));
  --t-h2: calc(clamp(1.6rem, 2.9vw, 2.75rem) * var(--k-name));
  --t-lead: calc(clamp(1.1875rem, 1rem + .75vw, 1.625rem) * var(--k-text));
  --t-body: calc(clamp(1.0625rem, 1rem + .2vw, 1.1875rem) * var(--k-text));
  --t-small: calc(.9375rem * var(--k-text));
  --t-mono: calc(.8125rem * var(--k-text));
  --t-mono-s: calc(.75rem * var(--k-text));
  --pad: clamp(1rem, 1.4vw + .25rem, 1.75rem); --gut: clamp(1rem, 2vw, 2rem);
  --s1: calc(.5rem * var(--k-space)); --s2: calc(1rem * var(--k-space)); --s3: calc(1.5rem * var(--k-space)); --s4: calc(2.5rem * var(--k-space)); --s5: calc(4rem * var(--k-space)); --s6: calc(6.5rem * var(--k-space)); --s7: calc(10rem * var(--k-space));
  --ease: cubic-bezier(.2, .7, .2, 1); --k-motion: 1;
}
/* grounds: one per page (the page shell sets data-ground); on home, one per project band */
[data-ground="black"] { --g: var(--g-black); --ink: var(--ink-light); --dim: var(--dim-light); }
[data-ground="walnut"] { --g: var(--g-walnut); --ink: var(--ink-light); --dim: var(--dim-light); }
[data-ground="paper"] { --g: var(--g-paper); --ink: var(--ink-dark); --dim: var(--dim-dark); }
[data-ground="sand"] { --g: var(--g-sand); --ink: var(--ink-dark); --dim: var(--dim-dark); }
[data-ground="dusk"] { --g: var(--g-dusk); --ink: var(--ink-dark); --dim: var(--dim-dark); }
[data-ground] { --hair: color-mix(in srgb, var(--ink) 22%, var(--g)); }   /* decorative hairlines only */
/* the page's scroll bar on the page's ground; the dark grounds also switch the browser's own parts to dark */
html:has(> body[data-ground="black"]) { color-scheme: dark; scrollbar-color: var(--dim-light) var(--g-black); }
html:has(> body[data-ground="paper"]) { scrollbar-color: var(--dim-dark) var(--g-paper); }
html:has(> body[data-ground="sand"]) { scrollbar-color: var(--dim-dark) var(--g-sand); }
html:has(> body[data-ground="walnut"]) { color-scheme: dark; scrollbar-color: var(--dim-light) var(--g-walnut); }
html:has(> body[data-ground="dusk"]) { scrollbar-color: var(--dim-dark) var(--g-dusk); }
/* section 1, the tokens: generated from packages/tokens/src/tokens.ts */
/* styles.css — "Reel" (design context: .impeccable.md). The whole site's CSS, in the order it cascades.
   The home page introduces the person, then lists the work as bands, each on its project's ground; every other page is
   a normal scrolling page set on one warm ground with one ink. Build names are set wide (Anybody 800, width 150); everything else is small and
   quiet (Anybody 400 for prose, Azeret Mono for specs, labels and figures). The only saturated color is data: the
   red inside the XSIM frame and the bit field. Never: scrims or text over busy pixels, motion that runs on its own,
   information only on hover, a third family. None of the earlier monograph design's rules apply here. */

/* Each file below holds one component's rules, or one cross-cutting concern (responsive, motion, print).
   ORDER MATTERS: the list is the order of the original single stylesheet, and later rules win at equal specificity —
   e.g. global/responsive.css must come after every component it overrides. Add new files where their rules belong
   in that order, not alphabetically. (Cascade layers would let specificity lose to layer order, so none are used.) */

/* ---------- 2. Base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { font-kerning: normal; -webkit-font-smoothing: antialiased; text-size-adjust: 100%; }
body { margin: 0; background: var(--g); color: var(--ink); font: 400 var(--t-body)/1.6 var(--f-sans); font-stretch: 100%; font-variant-numeric: lining-nums proportional-nums; }
body[data-ground="black"], body[data-ground="walnut"] { line-height: 1.66; }   /* light type on a dark ground reads heavier: a little more air */
main { display: block; }
h1, h2, h3, h4 { text-wrap: balance; hyphens: none; margin: 0; }
p { margin: 0 0 var(--s3); text-wrap: pretty; }
p:last-child { margin-bottom: 0; }
ul, ol, dl, dd, figure { margin: 0; padding: 0; }
img { max-width: 100%; height: auto; display: block; }
sup { line-height: 0; }
code { font: inherit; }
.mono, .meta, figcaption, table, .sec__reading, .kicker, .note { font-family: var(--f-mono); font-variant-numeric: lining-nums tabular-nums; }
/* Azeret Mono's contextual alternates turn the x of 0x00 into ×, and its ligatures join f to i, t, f and j (first reads "fırst");
   the font shorthand resets the setting, so it is set on every element. Anybody's own fi/fl ligatures look the same either way. */
* { font-feature-settings: "calt" 0, "liga" 0; }
.col-prose .mono, .deck .mono, .row__title .mono, .nlist .mono, .rec .mono, .kit__text .mono, .pull .mono, .turn .mono { font-size: .86em; }
.col-prose .mono, .deck .mono, .row__title .mono, .nlist .mono, .rec .mono, .kit__text .mono, .turn .mono { white-space: nowrap; }
.nc { text-transform: none; }
.nb { white-space: nowrap; }
.vh { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* the wide voice: build names, page titles, section heads */
.wide, h1, h2.col-head, .turn a, .row h3, .band__name, .foot__h { font-family: var(--f-sans); font-weight: var(--name-wght); font-stretch: calc(var(--name-wdth) * 1%); letter-spacing: -.02em; }
/* ---------- 3. Links, focus ---------- */
a { color: inherit; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: .2em; text-decoration-color: var(--dim); transition: text-decoration-color calc(.16s * var(--k-motion)) ease; }
@media (hover: hover) { a:hover { text-decoration-color: currentColor; } }
:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; border-radius: 1px; }
.skip { position: absolute; left: -9999px; top: 0; }
.skip:focus-visible { position: fixed; left: .5rem; top: .5rem; z-index: 50; background: var(--g); color: var(--ink); padding: .5rem .75rem; border: 1px solid var(--ink); font: 400 var(--t-mono)/1 var(--f-mono); text-decoration: none; }
html { scroll-padding-top: calc(var(--head-h, 52px) + 1rem); }
/* ---------- 4. Grid + placement classes (the pages keep main's markup; the placements hang everything off the left edge) ---------- */
.page { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gut); max-width: 1680px; margin-inline: auto; padding-inline: var(--pad); }
.page > * { min-width: 0; }
.col-full   { grid-column: 1 / 13; }
.col-head   { grid-column: 1 / 11; }
.col-prose  { grid-column: 1 / 8; max-width: 64ch; }
.col-margin { grid-column: 9 / 13; }
.col-a      { grid-column: 1 / 7; }
.col-b      { grid-column: 7 / 13; }
.fig--right { grid-column: 4 / 13; }
.fig--bleed { grid-column: 1 / 13; }
.pull       { grid-column: 8 / 13; }
.prose-block, .row, .meta { display: grid; grid-template-columns: subgrid; grid-column: 1 / 13; }
.prose-block > *, .row > *, .meta > * { min-width: 0; }
@supports not (grid-template-columns: subgrid) {
  .prose-block, .row, .meta { grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gut); }
}
/* margin notes sit beside the paragraph that follows them */
.prose-block > .col-margin { grid-row: span 2; align-self: start; }
/* ---------- 5. Four-corner chrome ---------- */
.head { position: sticky; top: 0; z-index: 20; background: var(--g); color: var(--ink); display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: center; column-gap: var(--gut);
  padding: .85rem var(--pad) .8rem; max-width: 1680px; margin-inline: auto; font: 500 var(--t-small)/1.2 var(--f-sans); font-stretch: 112%; }
.head::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; border-bottom: 1px solid var(--hair); }
.head a { text-decoration: none; }
@media (hover: hover) { .head a:hover { text-decoration: underline; text-decoration-color: currentColor; } }
.head__name { font-weight: 600; justify-self: start; padding-block: .5rem; }
.head__nav { display: flex; align-items: center; gap: 0 1.4rem; flex-wrap: wrap; }
.head__nav a { padding-block: .5rem; }
.head__nav a[aria-current] { text-decoration: underline; text-decoration-color: currentColor; }
.head__end { margin-left: auto; }
/* ---------- 6. Page header (case studies, index pages) ---------- */
.cs { padding-top: var(--s6); }
.kicker { font-size: var(--t-mono); line-height: 1.4; color: var(--dim); margin: 0 0 var(--s2); }
h1 { font-size: var(--t-name); line-height: .9; }
.cs h1 { margin-bottom: var(--s4); }
.deck { font: 400 var(--t-lead)/1.35 var(--f-sans); letter-spacing: -.01em; max-width: 40ch; }
.cs .deck { margin-bottom: var(--s4); }
.cs .fig { margin-block: var(--s3) 0; }
/* ---------- 7. Sections ---------- */
.sec { margin-top: var(--s6); }
.sec__rule { border: 0; border-top: 1px solid var(--hair); margin: 0 0 var(--s2); height: 0; }
.sec__reading { font-size: var(--t-mono); line-height: 1.4; color: var(--dim); margin: 0; grid-column: 1 / 13; }
h2.col-head { font-size: var(--t-h2); line-height: 1; margin: var(--s5) 0 var(--s3); }
.sec > h2.col-head { margin-top: var(--s2); }
h3 { font: 700 1.25rem/1.25 var(--f-sans); font-stretch: 112%; }
/* ---------- 8. Metadata row (case studies, notes, footer) ---------- */
.meta { border-top: 1px solid var(--ink); padding-block: var(--s2); row-gap: var(--s3); margin-top: var(--s5); font-size: var(--t-mono); line-height: 1.55; }
.meta__cell:nth-child(1) { grid-column: 1 / 4; } .meta__cell:nth-child(2) { grid-column: 4 / 7; }
.meta__cell:nth-child(3) { grid-column: 7 / 10; } .meta__cell:nth-child(4) { grid-column: 10 / 13; }
.meta dt { color: var(--dim); margin-bottom: .3rem; }
.meta dd { margin: 0; overflow-wrap: anywhere; }
.meta dd a { display: inline-block; padding-block: .125rem; }
.meta a[href^="mailto:"], .meta a[href^="http"] { font-family: var(--f-sans); font-size: 1.08em; }
/* ---------- 9. Figures: drawn in the page's ink on the page's ground ---------- */
.fig { margin-block: var(--s5); container-type: inline-size; }
.fig__scroll { overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: thin; scrollbar-color: var(--dim) transparent; }
.tmds__why { display: none; white-space: pre-line; }
@container (max-width: 739.98px) {
  .fig:has(.fig__scroll) figcaption::after { content: " · scrolls sideways"; }
  .tmds__why { display: block; margin-top: .25rem; }
}
.fig svg { display: block; height: auto; width: 100%; color: var(--ink); fill: none; stroke: currentColor; stroke-width: 1; stroke-linecap: square; }
.fig svg { min-width: 740px; max-width: 1000px; }
.fig svg path, .fig svg line, .fig svg rect, .fig svg circle { vector-effect: non-scaling-stroke; }
.fig svg text { font-family: var(--f-mono); font-size: 13px; stroke: none; fill: var(--dim); font-variant-numeric: lining-nums tabular-nums; }
.fig svg .t-ink { fill: var(--ink); }
.fig svg .t-ramp { fill: var(--ink); }
.fig svg .t-state { font-size: 14px; fill: var(--ink); }
.fig svg .s-ramp, .fig svg .s-cu { stroke: var(--ink); }
.fig svg .s-rule { stroke: var(--hair); }
.fig svg .s-axis { stroke: var(--dim); }
.fig svg .f-cu { fill: var(--ink); stroke: none; }
.fig svg .f-hatch { fill: url(#hatch); }
.fig svg .crisp { shape-rendering: crispEdges; }
.fig svg .geo { shape-rendering: geometricPrecision; }
figcaption { font-size: var(--t-mono); line-height: 1.5; color: var(--dim); margin-top: var(--s2); max-width: 70ch; }
.fig__no { color: var(--ink); }
.fig img.fig__img { display: block; width: auto; max-width: 100%; height: auto; }
.fig img.fig__img--portrait { width: auto; max-width: 100%; max-height: min(80vh, 44rem); }
.plate { max-width: 800px; }
/* the XSIM frame inside its 800×525 timing envelope: blanking hatched in the dim ink */
.envelope { container-type: inline-size; aspect-ratio: 800 / 525; position: relative; max-width: 800px; border: 1px solid var(--dim); background: repeating-linear-gradient(45deg, transparent 0 10px, var(--dim) 10px 11px); }
.envelope img { position: absolute; left: 0; top: 0; width: 80%; height: calc(480 / 525 * 100%); image-rendering: pixelated; }
.envelope__lbl { position: absolute; margin: 0; font: 400 var(--t-mono-s)/1 var(--f-mono); color: var(--ink); background: var(--g); padding: .2rem .35rem; white-space: nowrap; }
.envelope__lbl--right { left: 80%; top: 0; margin: .5rem 0 0 .5rem; writing-mode: vertical-rl; }
.envelope__lbl--bottom { left: 0; top: calc(480 / 525 * 100%); margin: .5rem 0 0 .5rem; }
@container (max-width: 520px) { .envelope__x { display: none; } }
@container (max-width: 300px) { .envelope__lbl { display: none; } }
.scale { position: relative; max-width: 800px; margin-top: var(--s2); }
.scale__bar { display: block; width: 100%; height: 28px; overflow: visible; fill: none; stroke: var(--dim); stroke-width: 1; }
.scale__bar line { vector-effect: non-scaling-stroke; }
.fig .scale__bar { min-width: 0; max-width: none; height: 28px; stroke: var(--dim); }
.scale__lbl { position: absolute; top: 14px; font: 400 var(--t-mono-s)/1 var(--f-mono); color: var(--dim); font-variant-numeric: lining-nums tabular-nums; }
.scale__lbl--0 { left: 0; } .scale__lbl--256 { left: 32%; } .scale__lbl--512 { left: 64%; } .scale__lbl--640 { left: 80%; } .scale__lbl--800 { right: 0; } /* the 3D board (HiFi page): a still render until three.js draws the model over it; the canvas is transparent, so the ground shows through */
.board__stage { position: relative; aspect-ratio: 2 / 1; max-width: 100%; }
.board__poster { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; }
.board__stage canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; cursor: grab; }
.board__stage canvas:active { cursor: grabbing; }
.board__stage.is-live .board__poster { visibility: hidden; }
.board__bar { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: baseline; gap: var(--s1) var(--s3); margin: var(--s1) 0 0; font: 400 var(--t-mono)/1.5 var(--f-mono); color: var(--dim); }
.board__reset { font: inherit; color: var(--ink); background: none; border: 0; padding: .25rem 0; cursor: pointer; text-decoration: underline; text-decoration-thickness: 1px; text-decoration-color: var(--dim); text-underline-offset: .2em; }
@media (hover: hover) { .board__reset:hover { text-decoration-color: currentColor; } }
/* the TMDS demo (HDMI page): controls drawn by the site in the page's ink */
.tmds__ctl { display: flex; flex-wrap: wrap; gap: var(--s2) var(--s4); margin-bottom: var(--s2); font: 400 var(--t-mono)/1.6 var(--f-mono); color: var(--ink); font-variant-numeric: lining-nums tabular-nums; }
.tmds__ctl label { display: inline-flex; align-items: center; gap: var(--s1); white-space: nowrap; }
.tmds__ctl input { accent-color: var(--ink); margin: 0; }
.tmds__ctl input[type="range"] { appearance: none; -webkit-appearance: none; width: 12rem; max-width: 45vw; height: 24px; background: transparent; cursor: pointer; }
.tmds__ctl input[type="range"]::-webkit-slider-runnable-track { height: 1px; background: var(--dim); }
.tmds__ctl input[type="range"]::-moz-range-track { height: 1px; background: var(--dim); }
.tmds__ctl input[type="range"]::-webkit-slider-thumb { -webkit-appearance: none; width: 10px; height: 20px; margin-top: -9.5px; border: 0; border-radius: 0; background: var(--ink); }
.tmds__ctl input[type="range"]::-moz-range-thumb { width: 10px; height: 20px; border: 0; border-radius: 0; background: var(--ink); }
.tmds__ctl input:disabled { cursor: default; }
.tmds__ctl input[type="range"]:disabled::-webkit-slider-thumb { background: var(--dim); }
.tmds__ctl input[type="range"]:disabled::-moz-range-thumb { background: var(--dim); }
.tmds__ctl input[type="checkbox"] { appearance: none; -webkit-appearance: none; width: 12px; height: 12px; border: 1px solid var(--ink); background: var(--g); display: inline-grid; place-content: center; cursor: pointer; }
.tmds__ctl input[type="checkbox"]::before { content: ""; width: 6px; height: 6px; background: var(--ink); opacity: 0; }
.tmds__ctl input[type="checkbox"]:checked::before { opacity: 1; }
.tmds__ctl input[type="checkbox"]:disabled { border-color: var(--dim); }
.tmds__ctl output { flex-basis: 100%; margin: 0; }
.tmds__check { font: 400 var(--t-mono)/1.6 var(--f-mono); color: var(--dim); margin: var(--s2) 0 0; font-variant-numeric: lining-nums tabular-nums; }
/* ---------- 10. Pull quote, margin note ---------- */
.pull { align-self: start; margin-block: var(--s4); font: 400 clamp(1.35rem, 2vw, 1.75rem)/1.2 var(--f-sans); font-stretch: 112%; letter-spacing: -.015em; text-wrap: balance; }
.pull__kicker { font: 400 var(--t-mono)/1.4 var(--f-mono); color: var(--dim); letter-spacing: 0; margin: 0 0 var(--s1); }
.pull p { margin: 0; }
.note { font-size: var(--t-mono); line-height: 1.55; color: var(--dim); margin: .35rem 0 0; font-variant-numeric: lining-nums tabular-nums; }
/* ---------- 11. Lists ---------- */
.col-prose > ul:not(.check), .entry__text > ul:not(.check) { list-style: none; padding-left: 1.25em; margin: 0 0 var(--s3); }
.col-prose > ul:not(.check) li, .entry__text > ul:not(.check) li { position: relative; }
.col-prose > ul:not(.check) li::before, .entry__text > ul:not(.check) li::before { content: "–"; position: absolute; left: -1.25em; color: var(--dim); }
/* a checklist of states in words, with a drawn box or tick (case studies: "What is not done") */
.check { list-style: none; padding: 0; margin: 0 0 var(--s3); font: 400 var(--t-mono)/1.6 var(--f-mono); }
.check li { padding: .3rem 0 .3rem 1.25rem; text-indent: -1.25rem; break-inside: avoid; border-top: 1px solid var(--hair); }
.check li:last-child { border-bottom: 1px solid var(--hair); }
.chk { width: 11px; height: 11px; vertical-align: -1px; margin-right: .55rem; stroke: currentColor; fill: none; stroke-width: 1.2; shape-rendering: crispEdges; }
.check__state { color: var(--dim); margin-right: .75rem; display: inline-block; min-width: 7.5em; text-indent: 0; }
/* status is only ever words plus the small open square; never color */
.status::before { content: ""; display: inline-block; width: 8px; height: 8px; margin-right: .5em; border: 1px solid currentColor; vertical-align: 0; }
/* entries with a mono kicker, a title and a paragraph (smaller builds, the log index) */
.nlist { list-style: none; margin: 0; padding: 0; }
.nlist li { border-top: 1px solid var(--hair); padding-block: var(--s3); }
.nlist li > p { max-width: 64ch; }
.nlist__kicker { font: 400 var(--t-mono)/1.4 var(--f-mono); color: var(--dim); margin: 0; }
.nlist__title { font: 700 1.15rem/1.3 var(--f-sans); font-stretch: 112%; margin: .35rem 0 .5rem; }
.nlist__title a { text-decoration-color: var(--dim); }
/* a plain list of links with a note each (404) */
.more { list-style: none; margin: 0; padding: 0; }
.more li { display: flex; flex-wrap: wrap; align-items: baseline; gap: .2rem 1rem; border-top: 1px solid var(--hair); padding-block: .6rem; }
.more li:last-child { border-bottom: 1px solid var(--hair); }
.more a { font: 700 1.3rem/1.2 var(--f-sans); font-stretch: 125%; letter-spacing: -.01em; text-decoration-color: var(--dim); }
.more span { font: 400 var(--t-mono)/1.4 var(--f-mono); color: var(--dim); }
/* ---------- 12. Work index rows (work/index.html) ---------- */
.row { border-top: 1px solid var(--ink); padding-block: var(--s3) var(--s4); row-gap: var(--s1); }
.row__no { grid-column: 1 / 2; font: 400 var(--t-mono)/1.9 var(--f-mono); color: var(--dim); margin: 0; font-variant-numeric: tabular-nums; }
.row__title { grid-column: 2 / 9; }
.row__meta { grid-column: 9 / 13; list-style: none; margin: 0; padding: 0; font: 400 var(--t-mono)/1.6 var(--f-mono); color: var(--dim); align-self: start; padding-top: .35rem; }
.row__meta li { margin: 0; }
.row h3 { font-size: clamp(1.6rem, 3.2vw, 3rem); line-height: .95; }
.row h3 a { text-decoration: none; }
@media (hover: hover) { .row h3 a:hover { text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: .12em; } }
.row__deck { margin: var(--s2) 0 0; max-width: 60ch; }
.row__notice { font-size: var(--t-small); line-height: 1.5; color: var(--dim); margin: .4rem 0 0; }
/* ---------- 13. Experience, education, kit (CV) ---------- */
.rec { position: relative; margin-bottom: var(--s4); }
.rec__entry { display: grid; grid-template-columns: 12rem 1fr; padding-block: var(--s2); border-top: 1px solid var(--hair); }
.rec__date { font: 400 var(--t-mono)/1.6 var(--f-mono); color: var(--dim); margin: 0; padding: .2rem var(--s2) 0 0; font-variant-numeric: lining-nums tabular-nums; }
.rec__role { font: 700 var(--t-body)/1.35 var(--f-sans); font-stretch: 112%; margin: 0; }
.rec__org { margin: .25rem 0 0; }
/* label beside text, one row each (CV skills and languages) */
.kit { margin-bottom: var(--s4); }
.kit__row { display: grid; grid-template-columns: 12rem 1fr; border-top: 1px solid var(--hair); padding-block: var(--s2); }
.kit__row:last-of-type { border-bottom: 1px solid var(--hair); }
.kit__label { font: 400 var(--t-mono)/1.4 var(--f-mono); color: var(--dim); margin: 0; padding: .3rem var(--s2) 0 0; }
.kit__text { margin: 0; }
.kit__parts { font: 400 var(--t-mono)/1.6 var(--f-mono); color: var(--dim); margin: var(--s2) 0 0; }
/* ---------- 14. Curriculum (notes) ---------- */
.cur { border-top: 1px solid var(--ink); padding-top: var(--s3); margin-top: var(--s4); }
.cur__year { display: flex; flex-wrap: wrap; gap: .25rem 1.25rem; align-items: baseline; font: 800 var(--t-h2)/1 var(--f-sans); font-stretch: 150%; letter-spacing: -.02em; margin: 0 0 var(--s3); }
.cur__year .mono { font: 400 var(--t-mono)/1.4 var(--f-mono); letter-spacing: 0; color: var(--dim); white-space: nowrap; }
.cur__q { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); column-gap: var(--gut); row-gap: var(--s3); }
.cur__qname { font: 400 var(--t-mono)/1.4 var(--f-mono); color: var(--dim); margin: 0; padding-block: .5rem; border-top: 1px solid var(--ink); }
.cur__list { list-style: none; margin: 0; padding: 0; }
.cur__course { display: grid; grid-template-columns: 4.5rem minmax(0, 1fr) 1.5rem; column-gap: .5rem; padding-block: .45rem; border-top: 1px solid var(--hair); font: 400 var(--t-small)/1.35 var(--f-sans); }
.cur__code, .cur__ects { font: 400 var(--t-mono)/1.5 var(--f-mono); color: var(--dim); font-variant-numeric: lining-nums tabular-nums; }
.cur__ects { justify-self: end; }
.cur__type { display: block; font: 400 var(--t-mono-s)/1.5 var(--f-mono); color: var(--dim); }
/* log entries and case-study bodies: measure and spacing after figures */
.entry__text > :not(.fig) { max-width: 64ch; }
.entry__body { margin-top: var(--s5); }
.prose-block > .fig + h2, .prose-block > .pull + h2, .prose-block > .fig + .pull { margin-top: var(--s3); }
/* ---------- 15. Prev / next: the next project's name, set wide on its own ground ---------- */
.turn { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); margin-top: var(--s6); border-top: 1px solid var(--ink); }
.turn a { display: block; padding: var(--s3) var(--pad) var(--s4); font-size: clamp(1.5rem, 3vw, 2.9rem); line-height: .95; text-decoration: none; background: var(--g); color: var(--ink); min-height: 9rem; transition: background-color calc(.3s * var(--k-motion)) var(--ease); }
.turn a:first-child { margin-left: calc(-1 * var(--pad)); }
.turn .turn__next { margin-right: calc(-1 * var(--pad)); text-align: left; }
.turn .mono { display: block; font: 400 var(--t-mono)/1.4 var(--f-mono); letter-spacing: 0; color: var(--dim); margin-bottom: var(--s2); }
@media (hover: hover) { .turn a:hover { text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: .12em; } }
.turn a:focus-visible { outline-offset: -8px; }   /* the ring goes inside the block, where the block's own ink contrasts */   /* ---------- 16. Contact (the footer of every page) ---------- */
.foot { margin-top: var(--s6); padding-block: 0 var(--s4); }
main:has(.turn) ~ .foot { margin-top: 0; }
.foot__h { font-size: var(--t-h2); line-height: 1; margin: var(--s2) 0 var(--s3); grid-column: 1 / 13; }
.foot .meta { margin-top: var(--s4); }
.foot .meta a { text-decoration-color: var(--dim); }
.foot__colophon { grid-column: 1 / 13; display: flex; justify-content: space-between; flex-wrap: wrap; gap: var(--s2); font: 400 var(--t-mono)/1.5 var(--f-mono); color: var(--dim); margin: var(--s5) 0 0; }
/* ---------- 17. Home: an introduction, then the work to choose from ----------
   The intro is about the person (name, lead, about, facts) on paper. Below it every project is a band on its own
   ground — the ground its case study is set on — with its name, one line, its status and a glimpse of its evidence.
   The whole band opens the case study; no project is the headline. */
.intro { padding-top: var(--s6); padding-bottom: var(--s5); row-gap: 0; }
.intro h1 { margin: 0 0 var(--s4); }
.intro .deck { margin-bottom: var(--s4); }
.intro__about { grid-row: span 2; }
.intro__about p { max-width: 64ch; }
.intro__act { font: 400 var(--t-mono)/1.6 var(--f-mono); margin-top: var(--s3); }
.intro__facts { grid-column: 9 / 13; grid-row: 4 / span 2; align-self: start; }
/* a short list of facts in mono: the intro's, and the Lapyx 4 numbers on the Daedalus band */
.intro__facts, .spec { margin: 0; font: 400 var(--t-mono)/1.5 var(--f-mono); border-top: 1px solid var(--ink); }
.intro__facts > div, .spec > div { display: grid; grid-template-columns: 6.5rem minmax(0, 1fr); gap: .75rem; padding-block: .55rem; border-bottom: 1px solid var(--hair); }
.intro__facts dt, .spec dt { color: var(--dim); }
.intro__facts dd, .spec dd { margin: 0; }
/* the work to choose from: a heading, then one band per project on its own ground */
.choose__head { padding-bottom: var(--s3); }
.choose__head h2 { font-size: var(--t-h2); line-height: 1; margin: var(--s1) 0 0; }
.bands { list-style: none; margin: 0; padding: 0; }
.band { position: relative; background: var(--g); color: var(--ink); }
.band[data-ground="paper"] { box-shadow: inset 0 1px 0 var(--hair), inset 0 -1px 0 var(--hair); }
.band__in { min-height: clamp(17rem, 36vh, 24rem); padding-block: var(--s4); align-items: center; }
.band__text { grid-column: 1 / 8; align-self: center; }
.band__no { font: 400 var(--t-mono)/1.4 var(--f-mono); color: var(--dim); margin: 0 0 var(--s1); font-variant-numeric: tabular-nums; }
.band__name { font-size: min(clamp(2rem, 4.6vw, 4.5rem), (100vw - 2rem) / 11); line-height: .92; margin: 0; }   /* second term: see --t-name */
.band__name a { text-decoration: none; }
.band__name a::after { content: ""; position: absolute; inset: 0; z-index: 1; }   /* the whole band opens the case study */
.band__name a:focus-visible { outline: 0; }
.band:has(.band__name a:focus-visible) { outline: 2px solid var(--ink); outline-offset: -8px; }
@media (hover: hover) {
  .band:hover .band__name a { text-decoration: underline; text-decoration-thickness: .06em; text-underline-offset: .12em; }
}
.band__line { margin: var(--s2) 0 0; max-width: 58ch; }
.band__meta { margin: var(--s2) 0 0; font: 400 var(--t-mono)/1.5 var(--f-mono); color: var(--dim); }
.band__meta .status { color: var(--ink); }
.band__fig { grid-column: 8 / 13; margin: 0; justify-self: end; width: 100%; display: flex; justify-content: flex-end; }
.band__fig--env .envelope, .band__fig--spec .spec { width: min(100%, 26rem); }
.band__fig--board img { width: min(120%, 40rem); max-width: none; margin-right: calc(-1 * var(--pad)); }
.band__fig--photo img { width: auto; max-height: 20rem; }
.band__fig--draw svg { width: min(100%, 24rem); height: auto; display: block; color: var(--ink); fill: none; stroke: currentColor; stroke-width: 1; stroke-linecap: square; }
.band__fig svg path, .band__fig svg line, .band__fig svg rect { vector-effect: non-scaling-stroke; }
.band__fig svg text { font-family: var(--f-mono); font-size: 14px; stroke: none; fill: var(--dim); }
.band__fig svg .t-ink { fill: var(--ink); }
.band__fig svg .s-axis { stroke: var(--dim); }
.band__fig svg .f-hatch { fill: url(#hatch); }
.band__fig svg .crisp { shape-rendering: crispEdges; }
.band--team .band__in { min-height: clamp(13rem, 26vh, 18rem); }
/* the smaller builds as a line of links */
.builds { padding-block: var(--s4) 0; }
.builds__list { list-style: none; margin: var(--s1) 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: .4rem 2.4rem; }
.builds__list li { display: flex; flex-direction: column; padding-block: .3rem; }
.builds__list a { font: 700 1.15rem/1.25 var(--f-sans); font-stretch: 112%; text-decoration-color: var(--dim); }
.builds__list span { font: 400 var(--t-mono)/1.4 var(--f-mono); color: var(--dim); }
/* home breakpoints: they follow every home rule above, so they win at equal specificity */
@media (max-width: 1199.98px) {
  .intro__facts { grid-column: 1 / 10; grid-row: auto; margin-top: var(--s4); }
  .intro__about { grid-row: auto; }
}
@media (max-width: 899.98px) {
  .band__text, .band__fig { grid-column: 1 / -1; }
  .band__fig { justify-content: flex-start; margin-top: var(--s3); }
  .band__fig--board img { width: min(100%, 36rem); margin-right: 0; }
  .band__in { min-height: 0; }
}
/* ---------- 18. Breakpoints ---------- */
@media (max-width: 1199.98px) {
  .col-prose { grid-column: 1 / 10; }
  .col-margin { grid-column: 1 / 10; }
  .prose-block > .col-margin { grid-row: auto; margin-bottom: var(--s2); }
  .pull { grid-column: 1 / 10; }
  .fig--right { grid-column: 1 / 13; }
  .meta__cell:nth-child(1), .meta__cell:nth-child(3) { grid-column: 1 / 7; }
  .meta__cell:nth-child(2), .meta__cell:nth-child(4) { grid-column: 7 / 13; }
  .row__title { grid-column: 2 / 10; } .row__meta { grid-column: 10 / 13; }
}
@media (max-width: 899.98px) {
  .page { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  @supports not (grid-template-columns: subgrid) { .prose-block, .row, .meta { grid-template-columns: repeat(6, minmax(0, 1fr)); } }
  .col-margin, .col-head, .col-prose, .col-full, .col-a, .col-b, .fig--right, .fig--bleed, .pull, .prose-block, .row, .meta, .sec__reading, .foot__h, .foot__colophon { grid-column: 1 / -1; }
  .meta__cell:nth-child(odd) { grid-column: 1 / 4; } .meta__cell:nth-child(even) { grid-column: 4 / 7; }
  .row { grid-template-columns: 2.5rem minmax(0, 1fr); column-gap: var(--gut); }
  .row__no { grid-column: 1 / 2; } .row__title { grid-column: 2 / 3; }
  .row__meta { grid-column: 2 / 3; padding-top: 0; }
  .cur__q { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  :root { --head-h: 88px; }
  .head { grid-template-columns: minmax(0, 1fr); row-gap: .1rem; padding-block: .6rem .5rem; }
  .head__nav { gap: 0 1rem; }
  .turn { grid-template-columns: minmax(0, 1fr); }
  .turn a:first-child, .turn .turn__next { margin-inline: calc(-1 * var(--pad)); }
}
@media (max-width: 599.98px) {
  :root { --s6: 3.5rem; --s7: 5rem; --s5: 2.5rem; --head-h: 0px; }
  .head { position: static; }
  .page { grid-template-columns: minmax(0, 1fr); }
  @supports not (grid-template-columns: subgrid) { .prose-block, .row, .meta { grid-template-columns: minmax(0, 1fr); } }
  .meta__cell:nth-child(odd), .meta__cell:nth-child(even) { grid-column: 1 / -1; }
  .rec__entry, .kit__row { grid-template-columns: 1fr; }
  .rec__date { padding: 0 0 .15rem; }
  .row { grid-template-columns: minmax(0, 1fr); }
  .row__no, .row__title, .row__meta { grid-column: 1 / -1; }
  .cur__q { grid-template-columns: minmax(0, 1fr); }
  .foot__colophon { flex-direction: column; }
  h1 .nb { white-space: normal; }
  /* the name (home, CV) breaks into its three words here, so it can be set larger than other titles: the widest word,
     "Ferrero" (7em at width 150), sets the size; from 600px up the last two words share a line and --t-name applies */
  .intro h1, .cv h1 { font-size: calc(min(3rem, (100vw - 2rem) / 7.5) * var(--k-name)); }
  .envelope__x { display: none; }
  .envelope__lbl--bottom { top: auto; bottom: 0; margin: 0 0 0 .5rem; padding-block: 0; }
}
/* ---------- 19. Motion ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: 0s !important; transition-delay: 0s !important; animation: none !important; }
}
/* ---------- 20. Print: ink on white, whatever the ground ---------- */
@media print {
  :root, [data-ground] { --g: #fff; --ink: #000; --dim: #444; }
  body { background: #fff; color: #000; }
  .head { position: static; }
  .head::after, .skip, .head__nav { display: none; }
  .fig__scroll { overflow: visible; }
  .fig svg { min-width: 0; }
  a { color: inherit; text-decoration: none; }
  .fig, .row, .rec__entry, .meta, .pull { break-inside: avoid; }
  h2, h3 { break-after: avoid; }
  .turn, .tmds__ctl, .board__bar { display: none; }
  .envelope, .status::before { print-color-adjust: exact; -webkit-print-color-adjust: exact; }
  .head__name::after { content: " · gonnzalofr.github.io"; }
  .col-prose a[href^="http"]::after { content: " (" attr(href) ")"; font: 400 8pt/1 var(--f-mono); color: #444; }
  .board__stage.is-live .board__poster { visibility: visible; } .board__stage canvas { display: none; }
}
/* CV print (cv.html): no chrome or footer, A4 with 12mm margins, one page at 10pt */
@page { size: A4; margin: 12mm; }
@media print {
  body:has(.cv) .head, body:has(.cv) .foot, .cv__pdf, .cv .sec__reading { display: none; }
  .cv { font-size: 10pt; line-height: 1.22; }
  .cv .page { display: block; max-width: none; padding-inline: 0; }
  .cv .col-prose { max-width: none; }
  .cv .cs { padding-top: 0; }
  .cv .kicker { font-size: 7.5pt; margin: 0; }
  .cv h1 { font-size: 20pt; margin: 2pt 0 3pt; }
  .cv .deck { font-size: 10pt; margin: 0; }
  .cv .meta { display: flex; flex-wrap: wrap; gap: 2pt 14pt; margin-top: 3pt; padding-block: 3pt; font-size: 7.5pt; line-height: 1.3; border-bottom: 1px solid #999; }
  .cv .meta dt { font-size: 7pt; margin-bottom: 0; }
  .cv .sec { margin-top: 3pt; }
  .cv .sec__rule { display: none; }
  .cv h2 { font-size: 11pt; margin: 3pt 0 0; }
  .cv .rec { margin-bottom: 0; }
  .cv .rec__entry { grid-template-columns: 100pt 1fr; padding-block: 1pt; border-top: 0; }
  .cv .rec__date { font-size: 7.5pt; padding: 1pt 6pt 0 0; }
  .cv .rec__role { font-size: 10pt; line-height: 1.2; }
  .cv .rec__org { margin-top: 0; }
  .cv .kit { margin-bottom: 0; }
  .cv .kit__row { grid-template-columns: 100pt 1fr; padding-block: 1pt; border: 0; }
  .cv .kit__label { font-size: 7pt; padding-top: 2pt; }
  .cv .kit__parts { font-size: 7.5pt; line-height: 1.3; margin-top: 2pt; }
}
