/* ground.css — the kit, standing on the page.

   spektralab.app is a launch page: one product, one action, and an atmosphere (aurora, glass,
   lift) to carry them. This site is a record of work, so it keeps the kit's materials and
   drops the atmosphere. Load order: tokens.css, kit.css, ground.css. The two kit files are
   copied unchanged; everything this site does differently is in this file.

   Against the kit's six rules:
     1 Colour belongs to the content.     Kept, and stricter. No aurora, no gradient type, no tint dots.
     2 Depth is soft and layered.         Replaced. Nothing floats: no shadow, no lift on hover.
     3 Glass needs something behind it.   Nothing is behind it any more, so there is no glass.
     4 Corners grow with the object.      Kept, lower half only: 14 for pictures, 10 for small things.
     5 Type carries the structure.        Kept, set left against a rail. Hairlines are the grid.
     6 Motion arrives and stops.          Nothing arrives. A hover changes a colour, and that is all,
                                          but for the light table (see 9), which moves when it is moved.

   Not used from kit.css, on purpose: .aurora .blob .glass .grad .dot .eyebrow--pill .hero
   .callout .card .bento .chip .badge .seg .steps .list .tile .frame--float .frame--settle .reveal .nav.
   Chips in particular: a row of pills under a name is how a person gets sold like a product.

   Taken from spektralab.app itself, at the owner's request, and only on SpektraLab's own page:
   the app's window as the site shows it, its icon before its name (10), and its spectrum of
   Kodak Portra 400 (11). They are content, so they come in flat: no glow, no glass, no shadow.

     1 Tokens        5 Sections              9 Pictures       13 Small screens
     2 Rail          6 Work                 10 Case pages
     3 Top bar       7 Words and numbers    11 Charts
     4 Masthead      8 Tables               12 Footer */

/* ══════════════════════════════════════════════════════════════════ 1 Tokens */
:root {
  --shadow-1: none; --shadow-2: none; --shadow-3: none;   /* nothing floats */
  --fs-display: clamp(2.5rem, 5.6vw, 4.5rem);             /* 40 to 72 px: a sentence, not a slogan */
  --fs-title: clamp(1.75rem, 3.2vw, 2.5rem);              /* 28 to 40 px */
  --space-section: clamp(64px, 8vw, 112px);
  --rule: var(--line-3);                                  /* the line a section stands on */
  --row: var(--line-2);                                   /* the lines between rows */
}

/* ════════════════════════════════════════════════════════════════════ 2 Rail */
/* Twelve columns. The first two are the rail, which names things and holds nothing else.
   The other ten are the text column. Below 900 px the rail lies down above its content. */
.sheet { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gap); align-items: start; }
.sheet > .rail { grid-column: 1 / span 2; min-width: 0; }
.sheet > .main { grid-column: 3 / -1; min-width: 0; }

/* A row inside the text column, on the same ten columns. Each child says how many it takes. */
.cols { display: grid; grid-template-columns: repeat(10, minmax(0, 1fr)); column-gap: var(--gap); row-gap: 28px; align-items: start; }
.cols > * { grid-column: 1 / -1; min-width: 0; }
.cols > .span-1 { grid-column: span 1; }
.cols > .span-2 { grid-column: span 2; }
.cols > .span-3 { grid-column: span 3; }
.cols > .span-4 { grid-column: span 4; }
.cols > .span-5 { grid-column: span 5; }
.cols > .span-6 { grid-column: span 6; }
.cols > .span-7 { grid-column: span 7; }

/* Blocks down the text column. A heading keeps what it introduces close. */
.flow > * + * { margin-top: var(--space-head); }
.flow > .title + * { margin-top: clamp(20px, 2.4vw, 28px); }

/* ═════════════════════════════════════════════════════════════════ 3 Top bar */
/* Solid, with a line under it. It stays at the top; it does not frost. */
.top { position: sticky; top: 0; z-index: 50; background: var(--bg); border-bottom: 1px solid var(--row); }
.top__inner { display: flex; align-items: center; justify-content: space-between; gap: 20px; height: var(--nav-h); }
.top__mark { display: block; flex: none; color: var(--ink); }
.top__mark svg { width: auto; height: 22px; fill: currentColor; }
.top__links { display: flex; align-items: center; gap: clamp(14px, 2.4vw, 30px); font-size: var(--fs-small); font-weight: 500; color: var(--ink-2); }
.top__links a { padding-block: 8px; white-space: nowrap; transition: color var(--dur-fast); }
.top__links a:hover, .top__links a[aria-current] { color: var(--ink); }
.top__links [lang="en"] { margin-left: 0.45em; font-weight: 400; color: var(--ink-3); }

/* ════════════════════════════════════════════════════════════════ 4 Masthead */
/* The person is the byline, in the rail. The title is what the work claims. */
.mast { padding-block: clamp(36px, 5vw, 64px) var(--space-section); }
.mast__facts { display: grid; gap: 14px; padding-top: 0.6em; font-size: var(--fs-small); line-height: 1.45; }
.mast__facts > p > [lang="en"] { display: block; font-size: var(--fs-caption); color: var(--ink-2); }
.mast__facts a { color: var(--ink-2); transition: color var(--dur-fast); }
.mast__facts a:hover { color: var(--ink); }
.mast__claim { margin-top: 10px; color: var(--ink-2); }
.mast__leads { margin-top: clamp(22px, 2.6vw, 32px); }
.mast__figure { margin-top: var(--space-head); }
.mast .stats { margin-top: clamp(40px, 5vw, 64px); padding-top: 22px; border-top: 1px solid var(--row); }

/* ════════════════════════════════════════════════════════════════ 5 Sections */
/* Every section stands on a line across the page, with its name in the rail under it. */
.sec, .pager { padding-bottom: var(--space-section); }
.sec > .wrap, .pager > .wrap { padding-top: 18px; border-top: 1px solid var(--rule); }
.label { display: flex; flex-wrap: wrap; align-items: baseline; column-gap: 0.5em; font-size: var(--fs-ui); line-height: 1.5; letter-spacing: 0; font-weight: 600; color: var(--accent-ink); }
.label__n, .label [lang="en"] { font-weight: 400; color: var(--ink-2); font-variant-numeric: tabular-nums; }

/* ════════════════════════════════════════════════════════════════════ 6 Work */
/* The list of work: a table of contents, not a grid of cards. */
.index { border-top: 1px solid var(--row); }
.index a { align-items: baseline; row-gap: 4px; padding-block: 18px 20px; border-bottom: 1px solid var(--row); }
.index__name { display: flex; align-items: baseline; gap: 14px; font-size: var(--fs-heading); font-weight: 600; line-height: 1.3; transition: color var(--dur-fast); }
.index__name > :last-child { text-wrap: balance; }
.index__what { font-size: var(--fs-ui); line-height: 1.6; color: var(--ink-2); text-wrap: pretty; }
.index__meta { font-size: var(--fs-caption); line-height: 1.6; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.index__go { justify-self: end; color: var(--ink-3); transition: color var(--dur-fast); }
.index a:hover .index__name, .index a:hover .index__go { color: var(--accent-ink); }
.num { font-size: var(--fs-caption); font-weight: 400; letter-spacing: 0; color: var(--ink-2); font-variant-numeric: tabular-nums; }

/* One piece of work. It starts on a line, like a section, one step quieter. */
.entry { padding-top: 22px; border-top: 1px solid var(--row); }
.entry .meta { margin-bottom: 8px; }
.entry .figure, .entry .plate { margin-top: 26px; }
.entry .figure + .cols { margin-top: 28px; }
.entry--sm { padding-top: 0; border-top: 0; }
.entry--sm .plate { margin-top: 0; }
.entry--sm .meta { margin-top: 22px; }
.entry--sm .title + p { margin-top: 12px; }
.title + p { margin-top: 16px; }
.lede + .title { margin-top: var(--space-head); }
.duo { row-gap: var(--space-head); }

/* Six steps and three notes: a small grid of things that each stand on their own line. */
.loop { row-gap: 36px; }
.loop li { padding-top: 14px; border-top: 1px solid var(--row); }
.loop .num { display: block; font-weight: 600; color: var(--accent-ink); }
.loop h4 { margin-top: 18px; font-size: 1.1875rem; font-weight: 600; }
.loop h4 [lang="en"] { margin-left: 0.55em; font-size: var(--fs-caption); font-weight: 400; color: var(--ink-2); }
.loop p { margin-top: 10px; font-size: var(--fs-ui); line-height: 1.7; text-wrap: pretty; }
.loop .note { margin-top: 8px; }
.notes { row-gap: 28px; }
.notes h3, .notes h4 { padding-top: 12px; border-top: 1px solid var(--row); font-size: var(--fs-caption); font-weight: 600; line-height: 1.5; letter-spacing: 0; color: var(--ink-2); }
.notes p { margin-top: 8px; font-size: var(--fs-ui); line-height: 1.7; text-wrap: pretty; }

/* ══════════════════════════════════════════════════════ 7 Words and numbers */
/* A heading in two beats: the name in ink, what it claims in grey. */
.title { font-size: var(--fs-title); line-height: var(--lh-title); letter-spacing: var(--track-title); font-weight: 700; text-wrap: balance; }
.title--sm { font-size: clamp(1.375rem, 2.2vw, 1.75rem); line-height: var(--lh-heading); }
.title__sub { display: block; color: var(--ink-2); }
.beat { display: block; }   /* one beat of a two-beat heading: its own line, balanced on its own */
.title a { transition: color var(--dur-fast); }
.title a:hover, a.title:hover { color: var(--accent-ink); }
.name { letter-spacing: -0.025em; }   /* a Latin name set large inside Chinese keeps the kit's tight tracking */

.lede--ink { color: var(--ink); }
.measure { max-width: var(--measure); text-wrap: pretty; }
.measure + .measure { margin-top: 1em; }
.measure a { color: var(--accent-ink); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
.small { font-size: var(--fs-ui); line-height: 1.7; }
.note { font-size: var(--fs-caption); line-height: 1.6; color: var(--ink-2); text-wrap: pretty; }
.meta { color: var(--ink-2); }   /* a date or a role is something the reader needs: the darker grey */
.nw { white-space: nowrap; }
.more { margin-top: 18px; font-size: var(--fs-ui); }
.arr { display: inline-block; width: 0.72em; height: 0.72em; margin-left: 0.4em; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; transition: transform var(--dur-fast); }
.arr--l { margin: 0 0.4em 0 0; }
a:hover .arr { transform: translateX(2px); }
a:hover .arr--ne { transform: translate(2px, -2px); }
a:hover .arr--l { transform: translateX(-2px); }

.facts { display: flex; flex-wrap: wrap; gap: 4px 20px; margin-top: 16px; font-size: var(--fs-small); color: var(--ink-2); }
.facts li { position: relative; padding-left: 13px; }
.facts li::before { content: ""; position: absolute; left: 0; top: calc(var(--lh-body) * 0.5em - 2px); width: 4px; height: 4px; border-radius: 50%; background: var(--ink-3); }

/* A short numbered list on lines. */
.chain { counter-reset: chain; margin-top: 12px; font-size: var(--fs-small); line-height: 1.5; }
.chain li { display: flex; gap: 14px; padding-block: 8px 9px; border-top: 1px solid var(--row); }
.chain li:last-child { border-bottom: 1px solid var(--row); }
.chain li::before { counter-increment: chain; content: counter(chain, decimal-leading-zero); color: var(--ink-2); font-variant-numeric: tabular-nums; }

/* A list on lines. A solid dot for what is done, a ring for what is not. */
.items-head { margin-bottom: 10px; font-size: var(--fs-caption); font-weight: 600; line-height: 1.5; letter-spacing: 0; color: var(--ink-2); }
.items { font-size: var(--fs-ui); line-height: 1.7; }
.items li { position: relative; padding: 10px 0 11px 18px; border-top: 1px solid var(--row); text-wrap: pretty; }
.items li:last-child { border-bottom: 1px solid var(--row); }
.items li::before { content: ""; position: absolute; left: 1px; top: calc(10px + 0.85em - 3px); width: 6px; height: 6px; border-radius: 50%; background: var(--ink); }
.items--no li::before { background: none; border: 1px solid var(--ink-2); }

/* The kit's numbers, with a label a reader can read, and a larger size for the masthead. */
.stats { row-gap: 28px; }
.stats dt { max-width: 22em; font-size: var(--fs-caption); line-height: 1.5; color: var(--ink-2); text-wrap: pretty; }
.stats dd span { font-size: 0.42em; }
.stats dd sup { font-size: 0.55em; line-height: 0; vertical-align: 0.7em; letter-spacing: 0; }
.stats--lg dd { font-size: clamp(2.25rem, 4vw, 3.25rem); }

/* ══════════════════════════════════════════════════════════════════ 8 Tables */
/* The kit has no table. A record of work is mostly tables, so this is the one real addition. */
.table { width: 100%; border-collapse: collapse; text-align: left; font-size: var(--fs-ui); line-height: 1.65; }
.table caption { caption-side: top; padding-bottom: 10px; text-align: left; font-size: var(--fs-caption); color: var(--ink-2); }
.table th, .table td { padding: 13px 20px 14px 0; vertical-align: top; border-top: 1px solid var(--row); font-weight: 400; }
.table th:last-child, .table td:last-child { padding-right: 0; }
.table thead th { padding-block: 0 10px; border-top: 0; font-size: var(--fs-caption); font-weight: 600; color: var(--ink-2); }
.table caption + thead th { padding-top: 9px; border-top: 1px solid var(--row); }
.table tbody th { width: 8.5em; font-size: var(--fs-caption); font-weight: 600; line-height: 1.9; }
.table tr:last-child > * { border-bottom: 1px solid var(--row); }
.table .n { white-space: nowrap; font-variant-numeric: tabular-nums; }
.table .hl { font-weight: 600; }   /* the column the page is about */
.table a { color: var(--accent-ink); white-space: nowrap; }
.table--fixed { table-layout: fixed; }
.table--fixed th:first-child { width: 8.5em; }
.table-wrap { overflow-x: auto; }
.ledger .who { display: block; font-size: var(--fs-body); font-weight: 600; line-height: 1.5; }

/* ════════════════════════════════════════════════════════════════ 9 Pictures */
/* A picture sits on the page with a hairline round it. It does not lift, tilt or zoom. */
.figure__media, .plate, .shots img { outline: 1px solid var(--line); outline-offset: -1px; }
.figure__media img { width: 100%; }
.figure:hover .figure__media img { transform: none; }
.figure--wide figcaption { flex-direction: row; flex-wrap: wrap; align-items: baseline; gap: 2px 16px; }
.figure figcaption span { color: var(--ink-2); }

/* A flat grey ground for a screen that is not the full width of its column. */
.plate { display: flex; align-items: flex-end; justify-content: center; gap: 5%; aspect-ratio: 16 / 10; padding: 7% 8% 0; overflow: hidden; border-radius: var(--r-m); background: var(--bg-2); }
.plate--flat { align-items: flex-start; justify-content: flex-start; padding: 7% 0 0 8%; }
.plate--flat img { width: 132%; max-width: none; border-radius: var(--r-s) 0 0 0; outline: 1px solid var(--line-2); }
.pad { width: 44%; overflow: hidden; border: 6px solid var(--ink); border-bottom: 0; border-radius: 20px 20px 0 0; background: var(--ink); }   /* a tablet, drawn: the only frame on the site */
.pad img { width: 100%; border-radius: 13px 13px 0 0; }

/* Three whole tablets side by side, each with its caption. */
.plate--pads { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); align-items: start; gap: 32px var(--gap); aspect-ratio: auto; padding: clamp(24px, 4.4vw, 56px) clamp(20px, 6vw, 80px); }
.plate--pads .pad { width: 100%; border-bottom: 6px solid var(--ink); border-radius: 20px; }
.plate--pads .pad img { border-radius: 13px; }

/* Photographs in rows of equal height: each column is as wide as its picture's aspect ratio. */
.photos { display: grid; gap: var(--gap); align-items: start; }
.photos + .photos { margin-top: 32px; }

/* A row of small pictures that are read in order: stages, versions, covers. --n is how many across. */
.shots { display: grid; grid-template-columns: repeat(var(--n, 3), minmax(0, 1fr)); gap: 28px var(--gap); }
.shots img { width: 100%; border-radius: var(--r-s); background: var(--bg-2); }
.shots--3x2 img { aspect-ratio: 3 / 2; object-fit: cover; }
.shots--stack img { aspect-ratio: 16 / 9; object-fit: cover; object-position: top; }   /* drafts are 16:9; the shipped window is cut to them from its title bar down */
.shots figcaption, .plate--pads figcaption { margin-top: 10px; font-size: var(--fs-caption); line-height: 1.6; color: var(--ink-2); text-wrap: pretty; }
.shots figcaption b, .plate--pads figcaption b { display: block; font-size: var(--fs-ui); font-weight: 600; color: var(--ink); }
.shots .num { display: block; font-weight: 600; color: var(--accent-ink); }
.shots figure > .num { margin-bottom: 8px; }
.icon-fig { display: flex; align-items: center; gap: 24px; }
.icon-fig img { flex: none; width: 104px; }
.icon-fig figcaption { font-size: var(--fs-ui); line-height: 1.7; text-wrap: pretty; }

/* Before and after, on one picture. The line is dragged; the range input is for keys and readers. */
.compare-stage { position: relative; overflow: hidden; border-radius: var(--r-m); background: var(--frame-bg); touch-action: pan-y; cursor: ew-resize; user-select: none; -webkit-user-select: none; }
.compare-stage img { width: 100%; pointer-events: none; }
.compare-a { position: absolute; inset: 0; height: 100%; object-fit: cover; clip-path: inset(0 calc(100% - var(--pos, 50%)) 0 0); }
.compare-line { position: absolute; top: 0; bottom: 0; left: var(--pos, 50%); width: 2px; margin-left: -1px; background: var(--on-scrim); pointer-events: none; }
.compare-line::after {
  content: ""; position: absolute; top: 50%; left: 50%; width: 36px; height: 36px; margin: -18px 0 0 -18px; border-radius: 50%;
  background: var(--on-scrim) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 36 36' fill='none' stroke='%231d1d1f' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M15 13l-5 5 5 5M21 13l5 5-5 5'/%3E%3C/svg%3E") center / 36px 36px no-repeat;
}
.compare-tag { position: absolute; top: 12px; padding: 4px 9px 5px; border-radius: 6px; background: var(--scrim); color: var(--on-scrim); font-size: var(--fs-micro); font-weight: 600; line-height: 1.3; pointer-events: none; }
.compare-tag-a { left: 12px; }
.compare-tag-b { right: 12px; }
.compare-range { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: ew-resize; }
.compare-stage:has(.compare-range:focus-visible) { outline: 3px solid var(--focus); outline-offset: 3px; }

/* The light table from spektralab.app, at the owner's request: film lying on a lit panel, each
   strip at its true size, moved sideways by hand. js/lighttable.js draws it with three.js. Over
   there it runs across the page; here it is a picture in the text column, with its caption under
   it and its two buttons drawn in line. It is the one thing on this site that moves, and it moves
   only when it is touched. */
.lt__stage {
  position: relative; height: clamp(340px, 56vh, 540px); height: clamp(340px, 56svh, 540px);
  overflow: hidden; border-radius: var(--r-m); background: var(--bg-2); cursor: grab;
  touch-action: pan-y; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; -webkit-tap-highlight-color: transparent;
}
.lt__stage::after { content: ""; position: absolute; inset: 0; border: 1px solid var(--line); border-radius: inherit; pointer-events: none; }
.lt__stage.is-dragging { cursor: grabbing; }
.lt__stage.is-loupe { cursor: none; }
.lt__canvas { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; transition: opacity 0.6s var(--ease-out); }
.lt__stage.is-ready .lt__canvas { opacity: 1; }
/* How to move it, said once: the same dark label as a chart's readout. */
.lt__hint { position: absolute; left: 50%; bottom: calc(var(--lt-floor, 56px) + 14px); transform: translateX(-50%); padding: 7px 10px 8px; border-radius: var(--r-s); background: var(--surface-inverse); color: var(--on-inverse); font-size: var(--fs-micro); line-height: 1.45; white-space: nowrap; pointer-events: none; opacity: 0; transition: opacity 0.3s; }
.lt__hint.is-on { opacity: 1; }
@media (hover: hover) { .lt__hint--touch { display: none; } }
@media (hover: none) { .lt__hint--fine { display: none; } }
.lt__bar { display: flex; align-items: center; justify-content: space-between; gap: 16px; min-height: 36px; margin-top: 12px; }
.lt__caption { min-width: 0; font-size: var(--fs-small); line-height: 1.6; color: var(--ink-2); }
.lt__caption strong { font-weight: 600; color: var(--ink); }
.lt__nav { display: flex; flex: none; align-items: center; gap: 8px; }
.lt__count { margin-right: 6px; font-size: var(--fs-caption); font-variant-numeric: tabular-nums; color: var(--ink-2); }
.lt__btn { display: grid; place-items: center; width: 36px; height: 36px; padding: 0; border: 1px solid var(--line-2); border-radius: var(--r-s); background: none; color: var(--ink); cursor: pointer; transition: border-color var(--dur-fast), background-color var(--dur-fast); }
.lt__btn svg { width: 12px; height: 12px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.lt__btn:hover { border-color: var(--line-3); background: var(--bg-2); }
.lt__btn[aria-disabled="true"] { border-color: var(--line); background: none; color: var(--ink-3); cursor: default; }
.lt__note { margin-top: 20px; }
.lt[hidden] ~ .lt__note .lt__only { display: none; }   /* said of the table, not of the gallery */
@media (prefers-reduced-motion: reduce) { .lt__canvas, .lt__hint { transition: none; } }

/* The same strips as plain pictures in the kit's columns: what a browser without WebGL shows.
   A panorama runs across all of them. The space under a picture is padding, because a margin
   at the foot of a column is dropped and the panorama would touch the caption above it. */
.gallery { column-gap: var(--gap); margin-bottom: -28px; }
.gallery > .figure { break-inside: avoid; padding-bottom: 28px; }
.gallery > .figure--wide { column-span: all; }

/* ══════════════════════════════════════════════════════════════ 10 Case pages */
/* A product's icon before its name, as on the product's own site. The tile sits inside a clear
   margin of its own, so the picture is pulled left by that margin to stand on the column. */
.app-name { display: flex; align-items: center; gap: 0.14em; }
.app-name img { flex: none; width: 1.08em; height: auto; margin-left: -0.11em; }

/* What a case is, at a glance: a short table of terms and values. */
.spec { font-size: var(--fs-small); line-height: 1.6; }
.spec > div { display: grid; grid-template-columns: 4.6em minmax(0, 1fr); gap: 0 16px; padding-block: 8px 9px; border-top: 1px solid var(--row); }
.spec > div:last-child { border-bottom: 1px solid var(--row); }
.spec dt { color: var(--ink-2); }
.spec a { color: var(--accent-ink); }
.spec a + a { margin-left: 1em; }

/* A decision on record: what was seen, what bound it, what was concluded, what it cost.
   The cell the decision turned on carries the accent. */
.record__head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 2px 24px; padding-block: 12px 14px; border-top: 1px solid var(--rule); }
.record__head h3 { font-size: var(--fs-body); font-weight: 600; line-height: 1.5; letter-spacing: 0; }
.record__head p { font-size: var(--fs-caption); color: var(--ink-2); font-variant-numeric: tabular-nums; }
.record { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0 var(--gap); }
.record--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.record > div { padding: 12px 0 24px; border-top: 1px solid var(--row); }
.record dt { display: flex; align-items: center; gap: 8px; font-size: var(--fs-caption); font-weight: 600; }
.record dt::before { content: ""; flex: none; width: 6px; height: 6px; border-radius: 50%; background: var(--ink-3); }
.record .key dt { color: var(--accent-ink); }
.record .key dt::before { background: var(--accent); }
.record dd { margin-top: 8px; font-size: var(--fs-ui); line-height: 1.75; text-wrap: pretty; }

/* The stages of a pipeline, named in code. */
.nodes { font-size: var(--fs-caption); line-height: 1.7; }
.nodes > div { display: grid; grid-template-columns: 8.5em minmax(0, 1fr); gap: 0 16px; padding-block: 9px 10px; border-top: 1px solid var(--row); }
.nodes > div:last-child { border-bottom: 1px solid var(--row); }
.nodes dt { font-weight: 600; }
.nodes dd { font-family: var(--mono); font-size: var(--fs-micro); line-height: 1.85; color: var(--ink-2); overflow-wrap: anywhere; }

/* A code excerpt: the kit's dark block, with where it comes from written above it. */
.listing { min-width: 0; }
.listing figcaption { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 2px 16px; margin-bottom: 10px; font-size: var(--fs-caption); color: var(--ink-2); }
.listing figcaption span:first-child { font-family: var(--mono); font-size: var(--fs-micro); line-height: 1.75; color: var(--ink); }
.code { border-radius: var(--r-m); }

/* A system drawn as boxes on the grid. The box the design turns on carries the accent. */
.dg { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0 var(--gap); font-size: var(--fs-caption); line-height: 1.55; }
.dg-cell { position: relative; padding: 12px 14px 15px; border: 1px solid var(--line-3); border-radius: var(--r-s); background: var(--bg); }
.dg-cell b { display: block; font-size: var(--fs-ui); font-weight: 600; }
.dg-cell span { color: var(--ink-2); }
.dg-wide { grid-column: span 2; }
.dg-key { border-color: var(--accent); background: var(--accent-soft); }
.dg-key span { color: var(--ink); }
.dg-link::after { content: ""; position: absolute; top: 50%; left: 100%; width: calc(var(--gap) + 2px); height: 1px; background: var(--line-3); }
/* The tool list reads both stores: a riser from its cell, a bus, two drops. */
.dg-gap { grid-column: 1 / -1; height: 28px; position: relative; }
.dg-gap i { position: absolute; background: var(--line-3); }
.dg-gap i:nth-child(1) { top: 0; left: calc(87.5% + var(--gap) * 0.375); width: 1px; height: 50%; }
.dg-gap i:nth-child(2) { top: 50%; left: calc(25% - var(--gap) * 0.25); right: calc(12.5% - var(--gap) * 0.375); height: 1px; }
.dg-gap i:nth-child(3), .dg-gap i:nth-child(4) { top: 50%; width: 1px; height: 50%; }
.dg-gap i:nth-child(3) { left: calc(25% - var(--gap) * 0.25); }
.dg-gap i:nth-child(4) { left: calc(75% + var(--gap) * 0.25); }

/* What was delivered, and what was stopped. */
.status { max-width: 46em; font-size: var(--fs-ui); line-height: 1.6; }
.status li { display: flex; justify-content: space-between; gap: 24px; padding-block: 12px 13px; border-top: 1px solid var(--row); }
.status li:last-child { border-bottom: 1px solid var(--row); }
.status li span:last-child { flex: none; font-size: var(--fs-caption); font-weight: 600; line-height: 1.85; }
.status .off span:last-child { font-weight: 400; color: var(--ink-2); }

/* The way to the next case. */
.pager .arr { width: 0.5em; height: 0.5em; margin-left: 0.3em; }

/* ════════════════════════════════════════════════════════════════ 11 Charts */
/* One series is the point and takes the accent; the other is the reference, in grey. Checked
   as a pair for colour-blind separation. The grey is under 3 : 1 on white, so every value is
   also printed beside its mark and in a table. Text never wears the series colour. */
.viz { --series-1: var(--accent-ink); --series-0: var(--line-3); }
.viz--bars { max-width: 44em; }
.viz-title { font-size: var(--fs-ui); font-weight: 600; line-height: 1.5; }
.viz-sub { font-size: var(--fs-caption); line-height: 1.6; color: var(--ink-2); text-wrap: pretty; }
.legend { display: flex; flex-wrap: wrap; gap: 4px 20px; margin-top: 12px; font-size: var(--fs-caption); line-height: 1.6; color: var(--ink-2); }
.legend i { display: inline-block; width: 14px; height: 8px; margin-right: 7px; border-radius: 0 4px 4px 0; background: var(--series-1); }
.legend .k0 i { background: var(--series-0); }
.bars { width: 100%; margin-top: 16px; border-collapse: collapse; font-size: var(--fs-caption); line-height: 1.4; }
.bars th, .bars td { padding: 12px 0; border-top: 1px solid var(--row); vertical-align: middle; text-align: left; font-weight: 400; }
.bars tr:last-child > * { border-bottom: 1px solid var(--row); }
.bars th { width: 9.5em; padding-right: 16px; }
.bars th b { display: block; font-size: var(--fs-ui); font-weight: 600; word-break: keep-all; }
.bars th span { font-size: var(--fs-micro); color: var(--ink-2); }
.bars .delta { width: 4.5em; text-align: right; font-weight: 600; font-variant-numeric: tabular-nums; }
.bar { display: flex; align-items: center; gap: 8px; height: 14px; font-size: var(--fs-micro); color: var(--ink-2); font-variant-numeric: tabular-nums; outline-offset: 2px; }
.bar + .bar { margin-top: 2px; }
.bar i { display: block; width: calc(var(--v) / var(--max) * (100% - 5.5em)); height: 12px; border-radius: 0 4px 4px 0; background: var(--series-0); transition: filter var(--dur-fast); }
.bar.now { color: var(--ink); font-weight: 600; }
.bar.now i { background: var(--series-1); }
.bar:hover i, .bar:focus-visible i { filter: brightness(0.9); }
.cadence { display: grid; grid-template-columns: repeat(21, minmax(0, 1fr)); align-items: end; height: 104px; margin-top: 20px; border-bottom: 1px solid var(--line-3); }
.cadence > div { display: flex; flex-direction: column-reverse; align-items: center; gap: 2px; height: 100%; padding-bottom: 5px; }
.rel { position: relative; display: block; flex: none; width: 24px; height: 14px; outline-offset: 1px; }
.rel::after { content: ""; position: absolute; top: -1px; left: 4px; width: 12px; height: 12px; box-sizing: content-box; border: 2px solid var(--bg); border-radius: 50%; background: var(--series-1); transition: transform var(--dur-fast); }   /* the border is a ring of surface, so dots that touch stay apart */
.rel:hover::after, .rel:focus-visible::after { transform: scale(1.3); }
.cadence-tag { margin-bottom: 4px; font-size: 0.6875rem; font-weight: 600; line-height: 1.2; white-space: nowrap; font-variant-numeric: tabular-nums; }
.cadence-axis { display: grid; grid-template-columns: repeat(21, minmax(0, 1fr)); margin-top: 6px; font-size: 0.6875rem; line-height: 1.4; color: var(--ink-2); text-align: center; font-variant-numeric: tabular-nums; }
.cadence-axis span { white-space: nowrap; }
/* spektralab.app's spectrum: Kodak Portra 400's three layers over the 81 wavelengths the engine
   works in, with the curves' data as that site draws it. The colours are the light's and the
   layers', which is why the accent stays out; the bar is flat here, without its shadow. */
.spectrum { max-width: 44em; }
.spectrum .legend i { width: 16px; height: 3px; border-radius: 2px; vertical-align: middle; }
.spectrum .legend .k-b i { background: #2f4fd0; }
.spectrum .legend .k-g i { background: #1f9a48; }
.spectrum .legend .k-r i { background: #cc3a35; }
.layers { display: block; width: 100%; height: 84px; margin: 14px 0 -8px; }   /* the curves stand on the bar */
.layers__fill { mix-blend-mode: multiply; }
.layers__line { fill: none; stroke-width: 1.5; stroke-opacity: 0.85; vector-effect: non-scaling-stroke; stroke-linejoin: round; }
.spectrum__bar {
  position: relative; height: 16px; border-radius: 8px;
  /* stops at (λ − 380) / 4 %: 400 violet, 450 blue, 490 cyan, 520 green, 575 yellow, 600 orange, 640 red, 700+ deep red */
  background: linear-gradient(90deg, #2a0f52 0%, #4a1fa6 5%, #3433d4 12.5%, #2361e6 20%, #1fa3e6 27.5%, #1fc0b0 31.25%, #26c55a 35%, #8ed22b 42.5%, #e9d93a 48.75%, #f6b12d 53.75%, #f27a2b 57.5%, #e63946 65%, #b81d2e 75%, #7a0f1c 87.5%, #3d0710 100%);
}
.spectrum__bar::after { content: ""; position: absolute; inset: 0; border-radius: inherit; background: repeating-linear-gradient(90deg, rgba(255, 255, 255, 0.4) 0 1px, transparent 1px calc(100% / 80)); }   /* 81 wavelengths, 80 steps */
.spectrum__ticks { position: relative; height: 1.4em; margin-top: 8px; font-size: 0.6875rem; line-height: 1.4; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.spectrum__ticks span { position: absolute; left: var(--at); transform: translateX(-50%); white-space: nowrap; }
.spectrum__ticks span:first-child { transform: none; }
.spectrum__ticks span:last-child { transform: translateX(-100%); }
.viz details { margin-top: 14px; font-size: var(--fs-caption); color: var(--ink-2); }
.viz summary { width: fit-content; cursor: pointer; }
.viz details .table { margin-top: 12px; font-size: var(--fs-caption); color: var(--ink); }
.viz details .table th, .viz details .table td { padding-block: 6px 7px; }
.viz details .table thead th { padding-top: 0; }
.tip { position: fixed; z-index: 60; top: 0; left: 0; max-width: 260px; padding: 7px 10px 8px; border-radius: var(--r-s); background: var(--surface-inverse); color: var(--on-inverse); font-size: var(--fs-micro); line-height: 1.45; pointer-events: none; opacity: 0; transition: opacity 0.1s; }
.tip.on { opacity: 1; }
.tip b { display: block; font-size: var(--fs-caption); font-variant-numeric: tabular-nums; }

/* ════════════════════════════════════════════════════════════════ 12 Footer */
.mail { display: inline-block; max-width: 100%; margin-top: 18px; font-size: clamp(1.75rem, 5.2vw, 3.5rem); font-weight: 700; line-height: 1.12; letter-spacing: -0.035em; overflow-wrap: anywhere; transition: color var(--dur-fast); }
.mail:hover { color: var(--accent-ink); }
.reach { margin-top: clamp(32px, 4vw, 48px); row-gap: 22px; }
.reach dt { padding-top: 12px; border-top: 1px solid var(--row); font-size: var(--fs-caption); color: var(--ink-2); }
.reach dd { margin-top: 4px; font-size: var(--fs-ui); font-weight: 600; }
.footer .notes h4 { padding-top: 0; border-top: 0; color: var(--ink); }
.footer .notes p { margin-top: 2px; font-size: var(--fs-caption); line-height: 1.6; color: var(--ink-2); }
.footer .notes a { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 2px; }
.footer .rail { font-size: var(--fs-caption); font-weight: 600; }

/* ═════════════════════════════════════════════════════════ 13 Small screens */
/* Where the rail (or half a phone) is narrower than a two-part fact, the dot between the parts
   becomes the line break. */
@media (min-width: 900px) and (max-width: 1235px), (max-width: 419px) {
  .mast__facts .sep { display: block; height: 0; overflow: hidden; }
}
@media (max-width: 1235px) {
  .index__name { font-size: 1.1875rem; }
}
@media (max-width: 1099px) {
  .record--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .dg { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px var(--gap); }
  .dg-link::after, .dg-gap { display: none; }
}
@media (max-width: 899px) {
  .sheet { display: block; }
  .sheet > .rail { margin-bottom: 20px; }
  .cols > [class*="span-"] { grid-column: 1 / -1; }
  .top__links [lang="en"] { display: none; }
  .mast__facts { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px var(--gap); padding-top: 0; }
  .index__go { display: none; }
  .footer .rail { margin-bottom: 16px; }
  .record { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 600px) {
  .stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .plate { aspect-ratio: 4 / 3; }
  .plate--pads { grid-template-columns: minmax(0, 1fr); aspect-ratio: auto; padding-inline: 18%; }
  .photos { grid-template-columns: minmax(0, 1fr) !important; gap: 24px; }
  .photos + .photos { margin-top: 24px; }
  .lt__stage { height: clamp(320px, 54vh, 440px); height: clamp(320px, 54svh, 440px); }
  .lt__bar { align-items: flex-start; }
  .lt__caption { min-height: 3.2em; }   /* two lines kept, so a long caption does not move the page */
  .lt__count { display: none; }
  @media (max-width: 359px) { .lt__caption { min-height: 4.8em; } }   /* the longest one takes three */
  .shots { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .shots--stack, .record, .record--4, .dg { grid-template-columns: minmax(0, 1fr); }
  .dg-wide { grid-column: auto; }
  .record > div { padding-bottom: 18px; }
  .icon-fig img { width: 72px; }
  .status li { flex-direction: column; gap: 0; }
  .table { font-size: var(--fs-small); }
  .table th, .table td { padding-right: 14px; }
  .table tbody th { width: 5.5em; }
  .bars th { width: 5.6em; padding-right: 10px; }
  .bars th span { display: none; }
  .bars .delta { width: 3.4em; }
  .rel { width: 100%; max-width: 24px; }
  .rel::after { left: 50%; margin-left: -7px; width: 10px; height: 10px; }
  .cadence-axis span:nth-child(even) { visibility: hidden; }
  /* A dated record becomes one block per row. */
  .ledger, .ledger tbody, .ledger tr, .ledger td { display: block; }
  .ledger thead { display: none; }
  .ledger tr { padding-block: 14px 16px; border-top: 1px solid var(--row); }
  .ledger tr:last-child { border-bottom: 1px solid var(--row); }
  .ledger td { padding: 0; border: 0 !important; }
  .ledger td + td { margin-top: 4px; }
  /* A comparison becomes one block per row: the first cell is the title, the others are
     labelled with their column heading (data-l). */
  .table--stack, .table--stack tbody, .table--stack tr, .table--stack tbody th, .table--stack td { display: block; }
  .table--stack thead { display: none; }
  .table--stack tr { padding-block: 12px 6px; border-top: 1px solid var(--row); }
  .table--stack tr > :first-child { width: auto; padding: 0 0 6px; border: 0 !important; font-size: var(--fs-small); font-weight: 600; line-height: 1.7; }
  .table--stack tr > :not(:first-child) { display: grid; grid-template-columns: var(--lw, 6.4em) minmax(0, 1fr); gap: 0 12px; padding: 8px 0 9px; border-top: 1px solid var(--line) !important; border-bottom: 0 !important; white-space: normal; }
  .table--stack tr > :not(:first-child)::before { content: attr(data-l); font-size: var(--fs-micro); font-weight: 400; line-height: 1.85; color: var(--ink-2); }
  .table--stack tr:last-child { border-bottom: 1px solid var(--row); }
}
