/* ==========================================================================
   Dutch IX Labs — site.css
   The component library. Everything the sheet is made of.

   tokens.css owns colour, type, space, motion and the layout primitives
   (.container .grid .sheet .page .margin .plate .columns .band, the type
   utilities). This file owns the components built on top of them, and it
   contains NO raw colour value of any kind — every hue is a var(--c-*).

   The world, in one line: a drawn country, one live layer, nothing else moves.

   Order:
      1. Page frame — the sheet border, its ticks, the field
      2. Nav
      3. The Margin — latitude rail, section index, coordinate readout
      4. Plate anatomy — eyebrow, title, lead, substance, the cut
      5. The Head and the Title Block
      6. The Legend
      7. The five-lab band set
      8. The lab sheet template
      9. The innovation chain
     10. The six verbs
     11. The Cyanotype plate and its opt-in theme
     12. The Revision block
     13. Buttons, links, lists, tables, stats, quotes
     14. Footer
     15. 404
     16. Reveals — PLOT and its reduced form
     17. Print
   ========================================================================== */


/* ==========================================================================
   1. PAGE FRAME
   The border is painted by tokens.css (.sheet::before) before any JS runs.
   The ticks along it are drawn by site.js; they are decorative reinforcement
   of the graticule, so a no-JS visitor loses nothing but the tick marks.
   ========================================================================== */

/* The tick strip rides the same fixed inset as the sheet border, so the two
   never disagree by a pixel at any viewport size. */
.sheet__ticks {
  position: fixed;
  inset: var(--sheet-inset);
  z-index: var(--z-margin);
  pointer-events: none;
}

.sheet__tick {
  position: absolute;
  inset-block-start: 0;
  inset-inline-start: calc(var(--at, 0) * 100%);
  inline-size: 1px;
  block-size: var(--s-2);
  background-color: var(--c-rule-2);
}
.sheet__tick--major { block-size: var(--s-3); }

/* Bottom edge carries the same ticks, mirrored — a plan sheet is ticked on
   both long edges so a measurement can be taken from either. */
.sheet__tick--bottom {
  inset-block-start: auto;
  inset-block-end: 0;
}

.sheet__tick-label {
  position: absolute;
  inset-block-start: var(--s-3);
  inset-inline-start: calc(var(--at, 0) * 100%);
  transform: translateX(-50%);
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: var(--track-mono);
  line-height: 1;
  color: var(--c-ink-4);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Longitude labels are the topmost thing on the sheet and would collide with
   the nav on a phone, where the sheet inset is 0 anyway. */
@media (max-width: 759px) {
  .sheet__ticks { display: none; }
}

/* The sheet number, printed at the top-right of the border like a real
   drawing. Language-independent, so it is never translated. */
.sheet__number {
  position: fixed;
  inset-block-start: calc(var(--sheet-inset) + var(--s-3));
  inset-inline-end: calc(var(--sheet-inset) + var(--s-4));
  z-index: var(--z-margin);
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-med);
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  color: var(--c-ink-4);
  font-variant-numeric: tabular-nums;
  pointer-events: none;
}
@media (max-width: 959px) { .sheet__number { display: none; } }

/* tokens.css underlines any link inside a <p>, <li>, <dd> or <td>, which is
   right for prose and wrong for a list of destinations. The chrome's link
   lists carry their own affordance — a rule, a border or a background step —
   so they opt out by name rather than by blanket reset. */
.nav__link, .drawer__list a, .legend__row, .footer__list a, .sheetlink, .btn,
.band__name a, .travel a { text-decoration: none; }

/* The field: the drawing area between the margins. */
.field {
  position: relative;
  z-index: var(--z-content);
}


/* ==========================================================================
   2. NAV
   Fixed, 60px. One hairline doing two jobs: the sheet's bottom boundary and
   the scroll progress bar, in the colour of the lab whose sheet you are on.
   ========================================================================== */

.nav {
  position: fixed;
  inset-block-start: 0;
  inset-inline: 0;
  z-index: var(--z-nav);
  block-size: var(--nav-h);
  background-color: color-mix(in srgb, var(--c-sheet) 88%, transparent);
  transition: transform var(--t-4) var(--ease-carriage);
}

/* Two queries, not one. Safari only shipped `backdrop-filter` unprefixed in
   18 — every iOS 17 and earlier has the effect and answers `no` to a query
   that does not name the prefix, so a single unprefixed test sent the whole
   iPhone install base down the fallback branch. */
@supports (backdrop-filter: blur(14px)) or (-webkit-backdrop-filter: blur(14px)) {
  .nav { -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px); }
}
/* Blur is the one sanctioned piece of glass on this site, and it is here for
   a functional reason: type must stay legible over a moving drawing. Where it
   is unsupported the bar is solid, never translucent. */
@supports not ((backdrop-filter: blur(14px)) or (-webkit-backdrop-filter: blur(14px))) {
  .nav { background-color: var(--c-sheet); }
}

/* Scroll down hides the bar, scroll up returns it. Never at scroll 0, never
   while anything inside it holds focus — a keyboard user must not be able to
   tab into a bar that has slid away. */
.is-motion .nav.is-hidden { transform: translateY(-100%); }
.nav:focus-within { transform: none !important; }

.nav__inner {
  display: flex;
  align-items: center;
  gap: var(--s-5);
  block-size: 100%;
  padding-inline: max(var(--pad-x), calc(var(--sheet-inset) + var(--s-4)));
}

.nav__brand {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 1px;
  color: var(--c-ink);
  flex: 0 0 auto;
}
.nav__wordmark {
  font-family: var(--font-display);
  font-variation-settings: "wdth" var(--wdth-annot), "wght" var(--fw-bold);
  font-weight: var(--fw-bold);
  font-size: var(--fs-md);
  text-transform: uppercase;
  letter-spacing: var(--track-annot);
  line-height: 1;
  color: var(--c-ink);
}
.nav__sub {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: var(--track-mono);
  line-height: 1;
  color: var(--c-ink-4);
}
@media (max-width: 1199px) { .nav__sub { display: none; } }

.nav__sheets {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  margin-inline-start: auto;
  list-style: none;
  padding: 0;
}

.nav__item { display: flex; }

/* Nav type is body, medium, small. Display type never enters the nav. */
.nav__link {
  display: flex;
  align-items: baseline;
  gap: var(--s-2);
  min-block-size: var(--target-min);
  padding-inline: var(--s-3);
  padding-block: var(--s-3);
  font-family: var(--font-body);
  font-weight: var(--fw-med);
  font-size: var(--fs-sm);
  color: var(--c-ink-2);
  border-block-end: 2px solid transparent;
  transition: color var(--t-2) var(--ease-register),
              border-color var(--t-2) var(--ease-register);
}
.nav__link:hover { color: var(--c-ink); }
.nav__link[aria-current="page"] {
  color: var(--c-ink);
  border-block-end-color: var(--c-lab);
}

/* The sheet numbers are the real identifiers in the set — they are in the URL
   and they do not translate. Mono, small, always secondary to the name. */
.nav__num {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-med);
  letter-spacing: var(--track-mono);
  color: var(--c-ink-4);
  font-variant-numeric: tabular-nums;
}
.nav__link[aria-current="page"] .nav__num { color: var(--c-lab); }

/* Annex sheets (the network and the join sheet) carry no ordinal, because
   they are not part of the numbered set of six. Below 1200px they leave the
   bar entirely rather than squeeze the numbered set — they are still one tap
   away in the disclosure and in the footer, and the six numbered sheets are
   what the nav is for. */
.nav__link--annex .nav__num { display: none; }
@media (max-width: 1439px) {
  .nav__sheets .nav__link--annex { display: none; }
}

/* The numbered set must never push the language switch off the bar. */
.nav__sheets { min-inline-size: 0; flex-wrap: nowrap; }

.nav__end {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  flex: 0 0 auto;
}

/* --- the language switch. Never collapses, at any breakpoint. --- */
.lang {
  display: flex;
  align-items: center;
  border: 1px solid var(--c-rule-2);
  border-radius: var(--r-pill);
  overflow: hidden;
}
.lang__btn {
  display: flex;
  align-items: center;
  justify-content: center;
  min-inline-size: var(--target-min);
  min-block-size: calc(var(--target-min) - var(--s-3));
  padding-inline: var(--s-3);
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-med);
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  color: var(--c-ink-3);
  background-color: transparent;
  transition: background-color var(--t-2) var(--ease-register),
              color var(--t-2) var(--ease-register);
}
.lang__btn:hover { color: var(--c-ink); }
.lang__btn.is-active,
.lang__btn[aria-pressed="true"] {
  background-color: var(--c-ink);
  color: var(--c-paper);
}

/* --- the Sheets disclosure, below 760px --- */
.nav__burger {
  display: none;
  align-items: center;
  gap: var(--s-2);
  min-block-size: var(--target-min);
  min-inline-size: var(--target-min);
  padding-inline: var(--s-3);
  font-family: var(--font-body);
  font-weight: var(--fw-med);
  font-size: var(--fs-sm);
  color: var(--c-ink);
  border: 1px solid var(--c-rule-2);
  border-radius: var(--r-2);
}
.nav__burger-glyph {
  display: block;
  inline-size: 14px;
  block-size: 1px;
  background-color: var(--c-ink);
  box-shadow: 0 4px 0 0 var(--c-ink), 0 -4px 0 0 var(--c-ink);
}

@media (max-width: 759px) {
  .nav__sheets { display: none; }
  .nav__burger { display: flex; }
  .nav__end { margin-inline-start: auto; }
}

.drawer {
  position: fixed;
  inset-block-start: var(--nav-h);
  inset-inline: 0;
  z-index: var(--z-overlay);
  background-color: var(--c-paper);
  border-block-end: 1px solid var(--c-rule-2);
  max-block-size: calc(100svh - var(--nav-h));
  overflow-y: auto;
  padding-block: var(--s-3);
}
.drawer__list { list-style: none; padding: 0; margin: 0; }
.drawer__list .nav__link {
  inline-size: 100%;
  padding-inline: var(--pad-x);
  border-block-end: 1px solid var(--c-rule);
  font-size: var(--fs-md);
}
.drawer__list .nav__num { min-inline-size: 2.2em; }

/* --- the progress hairline. Below 688px this is also what the margin rail
   would have shown, which is why no second progress element exists. --- */
.nav__progress {
  position: absolute;
  inset-block-end: 0;
  inset-inline: 0;
  block-size: 1px;
  background-color: var(--c-rule-2);
}
.nav__progress::before {
  content: "";
  position: absolute;
  inset-block: 0;
  inset-inline-start: 0;
  inline-size: calc(var(--progress, 0) * 100%);
  background-color: var(--c-lab);
}
@media (max-width: 759px) {
  .nav__progress, .nav__progress::before { block-size: 2px; }
}

/* Anything that sits under the fixed bar starts below it. */
.sheet { padding-block-start: var(--nav-h); }


/* ==========================================================================
   3. THE MARGIN
   The left rail: latitude ticks, the section index and scroll expressed as a
   coordinate. It is a grid column (tokens.css .page), never an overlay, so no
   content is ever printed underneath it.

   The rail maps the page onto the sheet's own latitude span, 53,70 N at the
   top of the document to 50,70 N at the bottom — the same bounds as the map's
   viewBox. Scrolling the page is therefore literally travelling south.
   ========================================================================== */

/* --margin-w resolves to 0 until roughly 1100px and to 32px at 1200px, so the
   rail has to know whether it has been given room: below ~48px its labels
   would print over the drawing field, and the margin is part of the grid
   precisely so that never happens. A container query asks the column itself
   rather than guessing from the viewport, so a change to the token moves the
   threshold with it. overflow-x: clip is the belt — unlike hidden it creates
   no scroll container, so the rail inside can still be sticky. */
.margin {
  position: relative;
  container-type: inline-size;
  overflow-x: clip;
  border-inline-end: 1px solid var(--c-rule);
}

@container (max-width: 4.5rem) {
  .margin__rail { display: none; }
}

.margin__rail {
  position: sticky;
  inset-block-start: var(--nav-h);
  block-size: calc(100svh - var(--nav-h));
  padding-block: var(--s-5);
  padding-inline-start: var(--s-2);
}

/* The tick column itself: a hairline with degree ticks crossing it. */
.margin__scale {
  position: relative;
  block-size: 100%;
  inline-size: 1px;
  margin-inline-start: var(--s-2);
  background-color: var(--c-rule);
}

.margin__tick {
  position: absolute;
  inset-inline-start: 0;
  inset-block-start: calc(var(--at, 0) * 100%);
  inline-size: var(--s-3);
  block-size: 1px;
  background-color: var(--c-rule-2);
}
.margin__tick--major { inline-size: var(--s-4); background-color: var(--c-ink-3); }

.margin__tick-label {
  position: absolute;
  inset-inline-start: calc(var(--s-4) + var(--s-1));
  inset-block-start: calc(var(--at, 0) * 100%);
  transform: translateY(-50%);
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: var(--track-mono);
  line-height: 1;
  color: var(--c-ink-4);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* The section index: one mark per plate, at that plate's position in the
   document. The mark is a square, the same primitive the map uses for a
   place — the margin and the drawing speak one language. */
.margin__mark {
  position: absolute;
  inset-inline-start: -2px;
  inset-block-start: calc(var(--at, 0) * 100%);
  inline-size: 5px;
  block-size: 5px;
  background-color: var(--c-ink-3);
  transform: translateY(-50%);
}
.margin__mark.is-current { background-color: var(--c-lab); inline-size: 7px; block-size: 7px; }

/* The cursor: where you are, as a coordinate. It is a readout, not an
   animation — under reduced motion it still tracks, it simply does not ease. */
.margin__cursor {
  position: absolute;
  inset-inline-start: -3px;
  inset-block-start: calc(var(--progress, 0) * 100%);
  inline-size: var(--s-4);
  block-size: 1px;
  background-color: var(--c-ink);
}
.is-motion .margin__cursor { transition: inset-block-start var(--t-1) linear; }

/* Offset from the scale so the readout never sits under the cursor or the
   section mark at scroll 0, and never under the sheet border. */
.margin__coord {
  position: absolute;
  inset-inline-start: var(--s-3);
  inset-block-start: calc(var(--progress, 0) * 100%);
  margin-block-start: var(--s-3);
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-med);
  letter-spacing: var(--track-mono);
  line-height: 1;
  color: var(--c-ink-3);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.is-motion .margin__coord { transition: inset-block-start var(--t-1) linear; }

/* There is no sideways caption on the rail. A vertical string in an 80px
   column either wraps into two columns of letters or collides with the
   coordinate readout, and it only restates the range the ticks already
   print. The ticks are the label. */


/* ==========================================================================
   4. PLATE ANATOMY
   Every plate is built from the same slots, which is what lets plates cut
   hard against each other without disorienting anyone.
   ========================================================================== */

.plate__head {
  display: flex;
  flex-direction: column;
  gap: var(--s-4);
  margin-block-end: var(--s-7);
}

/* Eyebrow + hairline, full field. The bracket is drawn with borders rather
   than typed as a character so no screen reader has to read a corner mark. */
.plate__eyebrow {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-med);
  text-transform: uppercase;
  letter-spacing: var(--track-eyebrow);
  line-height: var(--lh-mono);
  color: var(--c-ink-3);
}
.plate__eyebrow::before {
  content: "";
  flex: 0 0 auto;
  inline-size: 6px;
  block-size: 6px;
  border-inline-start: 1px solid var(--c-ink-3);
  border-block-start: 1px solid var(--c-ink-3);
}
.plate__eyebrow::after {
  content: "";
  flex: 1 1 auto;
  block-size: 1px;
  background-color: var(--c-rule-2);
}

/* Titles are left, always, under the eyebrow. Never centred — refuse list 5. */
.plate__title {
  font-family: var(--font-display);
  font-variation-settings: "wdth" var(--wdth-display), "wght" 800;
  font-weight: var(--fw-bold);
  font-size: var(--fs-d3);
  line-height: var(--lh-display);
  letter-spacing: var(--track-display);
  color: var(--c-ink);
  text-align: start;
  text-wrap: balance;
  hyphens: manual;
  max-inline-size: 22ch;
}
.plate__title--d2 { font-size: var(--fs-d2); font-variation-settings: "wdth" var(--wdth-display), "wght" 900; }

.plate__lead {
  font-size: var(--fs-xl);
  line-height: var(--lh-lead);
  color: var(--c-ink-2);
  max-inline-size: 54ch;
}

.plate__body { position: relative; }

/* The plate's own coordinate, printed at the head's trailing edge. */
.plate__coord {
  margin-inline-start: auto;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: var(--track-mono);
  color: var(--c-ink-4);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* The map plate: the drawing at 10/16 and its key at 6/16. That exact split
   is the reason the grid is 16 columns and not 12. */
.plate--map .plate__body {
  display: grid;
  grid-template-columns: 10fr 6fr;
  column-gap: var(--gutter);
  align-items: start;
}
@media (max-width: 959px) {
  .plate--map .plate__body { grid-template-columns: minmax(0, 1fr); row-gap: var(--s-7); }
}

.plate__drawing { min-inline-size: 0; }
.plate__key { min-inline-size: 0; }

/* The projection statement, printed in the bottom margin of the map plate.
   It is what a plan sheet carries and it is true. */
.plate__projection {
  margin-block-start: var(--s-5);
  padding-block-start: var(--s-3);
  border-block-start: 1px solid var(--c-rule);
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  color: var(--c-ink-4);
}


/* ==========================================================================
   5. THE HEAD AND THE TITLE BLOCK
   ========================================================================== */

.head {
  position: relative;
  min-block-size: calc(100svh - var(--nav-h));
  display: grid;
  grid-template-columns: 6fr 10fr;
  column-gap: var(--gutter);
  align-items: center;
  padding-block: var(--s-8);
}
@media (max-width: 959px) {
  .head {
    grid-template-columns: minmax(0, 1fr);
    row-gap: var(--s-7);
    min-block-size: 0;
    padding-block: var(--s-8) var(--s-7);
  }
}

/* Stretched, not start-aligned: a start-aligned column flex item is sized to
   its own min-content, and one long Dutch compound at --fs-d1 is wider than
   the field. The claim must be bounded by its column, not by its longest
   word — each child caps itself with its own max-inline-size instead. */
.head__col {
  display: flex;
  flex-direction: column;
  gap: var(--s-5);
  align-items: stretch;
  min-inline-size: 0;
  container-type: inline-size;
}

/* The claim. The one d1 on the whole site. Sentence case, left, weight 900. */
.head__claim {
  font-family: var(--font-display);
  font-variation-settings: "wdth" var(--wdth-display), "wght" 900;
  font-weight: var(--fw-black);
  /* --fs-d1 is the sheet's largest lettering, but it is also 200px, and the
     claim lives in 6 of 16 columns. "infrastructuur" at 200px is 1100px wide
     and the column is 480 — so at the top of the scale the two rules in the
     bible contradict each other and the type wins by breaking a word in half.
     Every component is specced against its Dutch string first, so the claim is
     capped to its own column: 16cqi is the size at which the longest Dutch
     compound sets on one line. Below the cap --fs-d1 governs exactly. */
  font-size: min(var(--fs-d1), 16cqi);
  line-height: var(--lh-d1);
  letter-spacing: var(--track-d1);
  color: var(--c-ink);
  text-align: start;
  text-wrap: balance;
  hyphens: manual;
  max-inline-size: 100%;
}

.head__lead {
  font-size: var(--fs-xl);
  line-height: var(--lh-lead);
  color: var(--c-ink-2);
  max-inline-size: 40ch;
}

/* The map bleeds to the sheet border on the right. */
.head__map {
  min-inline-size: 0;
  margin-inline-end: calc(-1 * var(--pad-x));
}
@media (max-width: 959px) { .head__map { margin-inline-end: 0; } }

/* The hook line sits in the bottom margin, in the annotation register. */
.head__hook {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-5);
  grid-column: 1 / -1;
  padding-block-start: var(--s-5);
  border-block-start: 1px solid var(--c-rule);
  font-family: var(--font-display);
  font-variation-settings: "wdth" var(--wdth-annot), "wght" var(--fw-semi);
  font-weight: var(--fw-semi);
  font-size: var(--fs-lg);
  text-transform: uppercase;
  letter-spacing: var(--track-annot);
  line-height: var(--lh-d4);
  color: var(--c-ink-3);
  hyphens: manual;
}

.head__scroll {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  color: var(--c-ink-4);
  white-space: nowrap;
}

/* --- the title block. A real <dl>. The element that turns this from a
   website into a document, so it is specced against the longest Dutch key
   (UITVOERINGSPERIODE) and has no fixed widths anywhere. --- */
.titleblock {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  column-gap: var(--s-5);
  row-gap: var(--s-2);
  padding: var(--s-4) var(--s-5);
  border: 1px solid var(--c-rule-2);
  background-color: var(--c-sheet-up);
  inline-size: 100%;
  max-inline-size: 30rem;
  line-height: var(--lh-dense);
}

.titleblock dt {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-med);
  text-transform: uppercase;
  letter-spacing: var(--track-eyebrow);
  color: var(--c-ink-4);
  align-self: baseline;
}
.titleblock dd {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: var(--track-mono);
  color: var(--c-ink);
  font-variant-numeric: tabular-nums;
  margin: 0;
}

/* A row that spans both columns: the summary line at the foot of the block. */
.titleblock__span {
  grid-column: 1 / -1;
  margin-block-start: var(--s-2);
  padding-block-start: var(--s-3);
  border-block-start: 1px solid var(--c-rule);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: var(--track-mono);
  color: var(--c-ink-2);
  font-variant-numeric: tabular-nums;
}


/* ==========================================================================
   6. THE LEGEND
   The map's key and the lab index are one component. Each row is a real link
   to that lab's sheet, and the rows are the map's only tab stops.
   ========================================================================== */

/* The box takes the plate's own ground so that a row stepping to --c-sheet-up
   is a real step on every band the legend can sit on. */
.legend { border: 1px solid var(--c-rule-2); }

.legend__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-4);
  padding: var(--s-3) var(--s-4);
  border-block-end: 1px solid var(--c-rule-2);
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-med);
  text-transform: uppercase;
  letter-spacing: var(--track-eyebrow);
  color: var(--c-ink-3);
}

.legend__list { list-style: none; margin: 0; padding: 0; }
.legend__item + .legend__item { border-block-start: 1px solid var(--c-rule); }

/* Emphasis is ADDED — a background step and a 3px left rule. Never a lift,
   never a shadow, never a scale, and never a dim on the other four. */
.legend__row {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr) max-content;
  column-gap: var(--s-4);
  row-gap: var(--s-1);
  align-items: baseline;
  padding: var(--s-4);
  border-inline-start: 3px solid transparent;
  color: var(--c-ink-2);
  transition: background-color var(--t-3) var(--ease-register),
              border-color var(--t-3) var(--ease-register);
}
.legend__row:hover,
.legend__item:focus-within .legend__row,
.legend__item.is-active .legend__row {
  background-color: var(--c-sheet-up);
  border-inline-start-color: var(--c-lab);
}

/* The symbol cell renders the actual mark used on the map. Making the map's
   shapes learnable is the legend's whole job. */
.legend__symbol {
  grid-row: 1 / span 2;
  inline-size: 1.5rem;
  block-size: 1.5rem;
  color: var(--c-lab);
  align-self: start;
}
.legend__symbol svg { inline-size: 100%; block-size: 100%; }

.legend__name {
  font-family: var(--font-display);
  font-variation-settings: "wdth" var(--wdth-annot), "wght" var(--fw-semi);
  font-weight: var(--fw-semi);
  font-size: var(--fs-d4);
  text-transform: uppercase;
  letter-spacing: var(--track-annot);
  line-height: var(--lh-d4);
  color: var(--c-lab);
  hyphens: manual;
}
.legend__place {
  display: block;
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  font-weight: var(--fw-reg);
  text-transform: none;
  letter-spacing: var(--track-body);
  color: var(--c-ink-2);
}

/* Promoted mono paying off: on a wide sheet the coordinate is the second
   largest thing in the plate, which is right for an infrastructure document
   and wrong for a brochure. */
.legend__coord {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: var(--track-mono);
  color: var(--c-ink-3);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  text-align: end;
}
@media (min-width: 1200px) {
  .legend__coord { font-size: var(--fs-n2); line-height: var(--lh-num); letter-spacing: var(--track-num); color: var(--c-ink); }
}

/* Site count sits under the coordinate, register under the name: two rows,
   three columns, no cell fighting another for the same slot. */
.legend__count {
  grid-column: 3;
  grid-row: 2;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--c-ink-4);
  font-variant-numeric: tabular-nums;
  text-align: end;
  white-space: nowrap;
}

.legend__register {
  grid-column: 2;
  grid-row: 2;
  font-size: var(--fs-sm);
  line-height: var(--lh-dense);
  color: var(--c-ink-3);
}

/* The dark-fibre state, written out. Under reduced motion this text is the
   only place "live" is stated, because the traffic has been removed. */
.legend__live {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  text-transform: uppercase;
  letter-spacing: var(--track-eyebrow);
  color: var(--c-ink-3);
}
.legend__live::before {
  content: "";
  inline-size: var(--s-4);
  block-size: 2px;
  background-color: var(--c-lab-signal);
}

.legend__note {
  padding: var(--s-4);
  border-block-start: 1px solid var(--c-rule-2);
  font-size: var(--fs-sm);
  line-height: var(--lh-dense);
  color: var(--c-ink-3);
}

/* --- below 560px the drawing goes away and each row grows a position strip:
   50,7–53,7 N as a hairline with a tick at this lab's latitude. It preserves
   the one thing the map was giving you — where in the country this is. --- */
.legend__strip {
  position: relative;
  grid-row: 1 / span 2;
  inline-size: 1px;
  block-size: 2.5rem;
  margin-inline: var(--s-3) 0;
  background-color: var(--c-rule-2);
  display: none;
}
.legend__strip::after {
  content: "";
  position: absolute;
  inset-inline-start: -3px;
  inset-block-start: calc(var(--at, 0.5) * 100%);
  inline-size: 7px;
  block-size: 2px;
  background-color: var(--c-lab);
}
@media (max-width: 559px) {
  .legend__strip { display: block; }
  .legend__row { grid-template-columns: max-content max-content minmax(0, 1fr); }
  .legend__symbol, .legend__strip { grid-row: 1 / span 4; }
  .legend__name, .legend__coord, .legend__count, .legend__register {
    grid-column: 3;
    grid-row: auto;
    text-align: start;
  }
}


/* ==========================================================================
   7. THE FIVE-LAB BAND SET
   Not five cards. Five full-bleed bands cut hard against each other. This is
   the single most anti-generic decision in the library, so nothing here gets
   a radius, a shadow or a fill.
   ========================================================================== */

.bands { display: block; }

/* tokens.css gives .band its 6px top rule in the lab's ink — the only place
   a lab colour appears at scale. Everything else in the band is ink. */
.band {
  padding-block: var(--s-6) var(--plate-y);
  border-radius: var(--r-0);
  box-shadow: none;
}

.band__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-5);
  margin-block-end: var(--s-6);
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-med);
  text-transform: uppercase;
  letter-spacing: var(--track-eyebrow);
  color: var(--c-ink-3);
  font-variant-numeric: tabular-nums;
}

.band__title {
  display: grid;
  grid-template-columns: minmax(0, 6fr) minmax(0, 10fr);
  column-gap: var(--gutter);
  row-gap: var(--s-4);
  align-items: start;
  margin-block-end: var(--s-6);
}
@media (max-width: 759px) {
  .band__title { grid-template-columns: minmax(0, 1fr); }
}

.band__name {
  font-family: var(--font-display);
  font-variation-settings: "wdth" var(--wdth-display), "wght" 900;
  font-weight: var(--fw-black);
  font-size: var(--fs-d2);
  line-height: var(--lh-display);
  letter-spacing: var(--track-display);
  color: var(--c-ink);
  hyphens: manual;
}
.band__name a { color: inherit; }
.band__name a:hover { color: var(--c-lab); }

.band__lead {
  font-size: var(--fs-xl);
  line-height: var(--lh-lead);
  color: var(--c-ink-2);
  max-inline-size: 46ch;
}

/* Venues are rule-separated columns — a departures board. .columns in
   tokens.css does the rules; this adds the venue's own anatomy. */
.venue { min-inline-size: 0; }

.venue__name {
  font-family: var(--font-display);
  font-variation-settings: "wdth" var(--wdth-annot), "wght" var(--fw-semi);
  font-weight: var(--fw-semi);
  font-size: var(--fs-md);
  text-transform: uppercase;
  letter-spacing: var(--track-annot);
  line-height: var(--lh-d4);
  color: var(--c-ink);
  padding-block-end: var(--s-3);
  margin-block-end: var(--s-3);
  border-block-end: 1px solid var(--c-rule);
  hyphens: manual;
}

.venue__facts { list-style: none; margin: 0; padding: 0; }
.venue__facts li {
  font-size: var(--fs-sm);
  line-height: var(--lh-dense);
  color: var(--c-ink-2);
}
.venue__facts li + li { margin-block-start: var(--s-2); }

/* Every measured thing in a band is mono, and it is allowed to be big. */
.venue__num {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--fs-n2);
  font-weight: var(--fw-med);
  line-height: var(--lh-num);
  letter-spacing: var(--track-num);
  color: var(--c-ink);
  font-variant-numeric: tabular-nums;
}

.band__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-4);
  margin-block-start: var(--s-6);
  padding-block-start: var(--s-4);
  border-block-start: 1px solid var(--c-rule-2);
}

/* The chain line uses that lab's own vocabulary where the source states one.
   Where it does not, the band prints the shared chain and says so. */
.band__chain {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--s-2) var(--s-3);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: var(--track-mono);
  color: var(--c-ink-2);
}
.band__chain-label {
  font-weight: var(--fw-med);
  text-transform: uppercase;
  letter-spacing: var(--track-eyebrow);
  color: var(--c-ink-4);
}
.band__chain-step + .band__chain-step::before {
  content: "\2192";
  margin-inline-end: var(--s-3);
  color: var(--c-ink-4);
}


/* ==========================================================================
   8. THE LAB SHEET TEMPLATE (sheets 02–06)
   Same margins, same border, same title block — with a city-scale statement.
   A lab sheet is never flooded with its own colour: only rules, marks and
   active states take it, and body copy stays ink on every sheet.
   ========================================================================== */

.labhead {
  display: grid;
  grid-template-columns: 6fr 10fr;
  column-gap: var(--gutter);
  row-gap: var(--s-7);
  align-items: center;
  padding-block: var(--s-8);
}
@media (max-width: 959px) {
  .labhead { grid-template-columns: minmax(0, 1fr); }
}

.labhead__name {
  font-family: var(--font-display);
  font-variation-settings: "wdth" var(--wdth-display), "wght" 900;
  font-weight: var(--fw-black);
  font-size: var(--fs-d1);
  line-height: var(--lh-d1);
  letter-spacing: var(--track-d1);
  color: var(--c-ink);
  hyphens: manual;
}
.labhead__full {
  font-size: var(--fs-xl);
  line-height: var(--lh-lead);
  color: var(--c-ink-2);
  max-inline-size: 34ch;
}
.labhead__coord {
  font-family: var(--font-mono);
  font-size: var(--fs-n2);
  line-height: var(--lh-num);
  letter-spacing: var(--track-num);
  color: var(--c-ink);
  font-variant-numeric: tabular-nums;
}

/* Facilities, partners and "travels to" are all plates on the same anatomy —
   what changes is the substance, never the frame. */
.facilities .columns > * { padding-block-start: var(--s-1); }

.partners {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2) var(--s-4);
  list-style: none;
  margin: 0;
  padding: 0;
  max-inline-size: var(--w-field);
}
.partners li {
  font-size: var(--fs-md);
  color: var(--c-ink-2);
}
.partners li + li::before {
  content: "\00B7";
  margin-inline-end: var(--s-4);
  color: var(--c-rule-2);
}

/* "Reist naar" — where a prototype goes next, in the source's own words. */
.travel {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr) max-content;
  column-gap: var(--s-5);
  row-gap: var(--s-2);
  align-items: baseline;
  padding: var(--s-5) 0;
  border-block-start: 1px solid var(--c-rule-2);
  color: var(--c-ink-2);
}
.travel:last-child { border-block-end: 1px solid var(--c-rule-2); }

.travel__lab {
  font-family: var(--font-display);
  font-variation-settings: "wdth" var(--wdth-annot), "wght" var(--fw-semi);
  font-weight: var(--fw-semi);
  font-size: var(--fs-d4);
  text-transform: uppercase;
  letter-spacing: var(--track-annot);
  line-height: var(--lh-d4);
  color: var(--c-lab);
}
.travel__quote {
  font-style: italic;
  font-size: var(--fs-lg);
  line-height: var(--lh-lead);
  color: var(--c-ink);
  max-inline-size: 44ch;
}
@media (max-width: 559px) {
  .travel { grid-template-columns: minmax(0, 1fr); }
}


/* ==========================================================================
   9. THE INNOVATION CHAIN
   Four labs, four vocabularies, one shared set of stages. A dotted track
   means "this lab does not state its own chain" and says so in words —
   candour is worth more than a tidy diagram.
   ========================================================================== */

.chain { display: block; }

.chain__stages {
  display: grid;
  grid-template-columns: max-content repeat(4, minmax(0, 1fr));
  column-gap: var(--gutter);
  padding-block-end: var(--s-3);
  border-block-end: 1px solid var(--c-rule-2);
}
.chain__stage {
  font-family: var(--font-display);
  font-variation-settings: "wdth" var(--wdth-annot), "wght" var(--fw-semi);
  font-weight: var(--fw-semi);
  font-size: var(--fs-sm);
  text-transform: uppercase;
  letter-spacing: var(--track-annot);
  line-height: var(--lh-d4);
  color: var(--c-ink);
  hyphens: manual;
}

.chain__track {
  display: grid;
  grid-template-columns: max-content repeat(4, minmax(0, 1fr));
  column-gap: var(--gutter);
  align-items: baseline;
  padding-block: var(--s-4);
  border-block-end: 1px solid var(--c-rule);
}

.chain__lab {
  font-family: var(--font-display);
  font-variation-settings: "wdth" var(--wdth-annot), "wght" var(--fw-semi);
  font-weight: var(--fw-semi);
  font-size: var(--fs-md);
  text-transform: uppercase;
  letter-spacing: var(--track-annot);
  color: var(--c-lab);
  min-inline-size: 5ch;
}

.chain__step {
  font-size: var(--fs-sm);
  line-height: var(--lh-dense);
  color: var(--c-ink-2);
}

/* MIX is the only lab that states numbers, so it is the only track that
   prints a TRL band. Inventing a common scale would be inventing facts. */
.chain__band {
  grid-column: span 2;
  display: flex;
  align-items: center;
  gap: var(--s-3);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: var(--track-mono);
  color: var(--c-ink);
  font-variant-numeric: tabular-nums;
}
.chain__band::before,
.chain__band::after {
  content: "";
  flex: 1 1 auto;
  block-size: 1px;
  background-color: var(--c-ink-3);
}

/* Dotted = this lab does not state its own chain. Line style, plus the label
   printed in full — never colour alone. */
.chain__track--shared .chain__step,
.chain__shared {
  grid-column: 2 / -1;
  display: flex;
  align-items: center;
  gap: var(--s-3);
  font-size: var(--fs-sm);
  color: var(--c-ink-3);
}
.chain__shared::after {
  content: "";
  flex: 1 1 auto;
  block-size: 0;
  border-block-start: 1px dotted var(--c-rule-2);
}

/* The two journeys are the argument, so they are drawn last and quoted
   verbatim — the same two the map draws, worded identically in both places. */
.chain__journeys {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(22rem, 100%), 1fr));
  gap: var(--s-6);
  margin-block-start: var(--s-7);
}
.chain__journey {
  padding-block-start: var(--s-4);
  border-block-start: 1px solid var(--c-rule-2);
}
.chain__journey-quote {
  font-family: var(--font-display);
  font-variation-settings: "wdth" var(--wdth-display), "wght" var(--fw-med);
  font-size: var(--fs-d4);
  line-height: var(--lh-d4);
  color: var(--c-ink);
  hyphens: manual;
}
.chain__journey-route {
  margin-block-start: var(--s-3);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  color: var(--c-ink-4);
}

@media (max-width: 759px) {
  .chain__stages { display: none; }
  .chain__track {
    grid-template-columns: minmax(0, 1fr);
    row-gap: var(--s-2);
  }
  .chain__band, .chain__shared { grid-column: 1; }
}


/* ==========================================================================
   10. THE SIX VERBS
   Six simultaneous functions, not a sequence — so they are not numbered.
   Six full-width rows separated by hairlines, verb in the annotation
   register, definition in body.
   ========================================================================== */

.verbs { border-block-start: 1px solid var(--c-rule-2); }

.verb {
  position: relative;
  display: grid;
  grid-template-columns: 4.5rem max-content minmax(0, 1fr);
  column-gap: var(--s-5);
  row-gap: var(--s-2);
  align-items: baseline;
  padding-block: var(--s-5);
  border-block-end: 1px solid var(--c-rule-2);
}

/* The glyph draws what the verb does to the flow. Ink hairline, no colour,
   and aria-hidden — the verb and its definition carry everything. */
.verb__glyph {
  grid-row: 1 / span 2;
  inline-size: 4.5rem;
  block-size: 2.25rem;
  color: var(--c-ink);
  align-self: center;
}
.verb__glyph svg { inline-size: 100%; block-size: 100%; overflow: visible; }

.verb__name {
  font-family: var(--font-display);
  font-variation-settings: "wdth" var(--wdth-annot), "wght" var(--fw-semi);
  font-weight: var(--fw-semi);
  font-size: var(--fs-d4);
  text-transform: uppercase;
  letter-spacing: var(--track-annot);
  line-height: var(--lh-d4);
  color: var(--c-ink);
  hyphens: manual;
  min-inline-size: 8ch;
}

.verb__def {
  font-size: var(--fs-lg);
  line-height: var(--lh-lead);
  color: var(--c-ink-2);
  max-inline-size: 52ch;
}

/* AGENDEERT is the one mark on the site permitted to cross the sheet border,
   because the verb means "toward Europe" and the sheet ends at the national
   boundary. One rule, broken once, in the only place where breaking it is
   the meaning.

   --edge-out is measured by site.js rather than derived here on purpose: a
   vw-based calc cannot see the margin rail's column or the scrollbar's width,
   and being wrong in that direction means a horizontal scrollbar on the one
   page element that is allowed to break the frame. It defaults to 0, so
   without JavaScript the mark simply stops at the field edge. */
.verb--edge { margin-inline-end: calc(-1 * var(--edge-out, 0px)); }
.verb--edge .verb__def { padding-inline-end: var(--s-6); }

@media (max-width: 559px) {
  .verb { grid-template-columns: 3rem minmax(0, 1fr); }
  .verb__glyph { grid-row: 1; inline-size: 3rem; block-size: 1.5rem; }
  .verb__def { grid-column: 2; }
}


/* ==========================================================================
   11. THE CYANOTYPE
   The one dark act. tokens.css swaps the token set for .plate--cyanotype and
   for [data-print="cyanotype"]; this is the plate's own layout, plus the
   theme's few structural corrections.
   ========================================================================== */

.plate--cyanotype {
  background-color: var(--c-sheet);
  color: var(--c-ink-2);
  padding-block: var(--plate-y-lg);
  /* The sheet has been re-printed: no margin ticks run through this plate. */
  border-block: 1px solid var(--c-rule-2);
}

.cyano__claim {
  font-family: var(--font-display);
  font-variation-settings: "wdth" var(--wdth-display), "wght" 900;
  font-weight: var(--fw-black);
  font-size: var(--fs-d2);
  line-height: var(--lh-display);
  letter-spacing: var(--track-display);
  color: var(--c-ink);
  max-inline-size: 20ch;
  hyphens: manual;
}

.cyano__drawing { margin-block: var(--s-7); }

/* The three consequences. Marks, not bullets — the sheet has no discs on it. */
.cyano__list { list-style: none; margin: 0; padding: 0; max-inline-size: 54ch; }
.cyano__list li {
  display: grid;
  grid-template-columns: var(--s-5) minmax(0, 1fr);
  align-items: baseline;
  font-size: var(--fs-lg);
  line-height: var(--lh-lead);
  color: var(--c-ink-2);
}
.cyano__list li + li { margin-block-start: var(--s-4); }
.cyano__list li::before {
  content: "\25B8";
  color: var(--c-ink-3);
}

/* The client's approved quote, verbatim, in both languages. Not improved. */
.cyano__quote {
  margin-block-start: var(--s-7);
  font-family: var(--font-display);
  font-variation-settings: "wdth" var(--wdth-display), "wght" var(--fw-med);
  font-size: var(--fs-d3);
  line-height: var(--lh-display);
  color: var(--c-ink);
  max-inline-size: 24ch;
  border-inline-start: 2px solid var(--c-ink-3);
  padding-inline-start: var(--s-5);
  hyphens: manual;
}

/* Under reduced motion the plate ships two stills instead of one animation:
   the marks off, then the marks on, each captioned. Nothing is lost, so the
   stills are markup that is simply not shown when motion is available. */
.cyano__still { display: none; }
.cyano__still-caption {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: var(--track-mono);
  color: var(--c-ink-3);
  margin-block-start: var(--s-3);
}
@media (prefers-reduced-motion: reduce) {
  .cyano__still { display: block; }
  .cyano__stills {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(20rem, 100%), 1fr));
    gap: var(--s-6);
  }
}

/* --- the opt-in reading theme. The site's answer to "where is dark mode":
   a dark that belongs to this project rather than a generic inversion. --- */
[data-print="cyanotype"] body { background-color: var(--c-sheet); color: var(--c-ink-2); }

/* Inside the theme the cyanotype plate is no longer an inversion, so it
   steps to the recessed ground instead — otherwise the one dark act would
   disappear into a dark page. */
[data-print="cyanotype"] .plate--cyanotype { background-color: var(--c-sheet-down); }

.printswitch {
  display: inline-flex;
  align-items: center;
  gap: var(--s-3);
  min-block-size: var(--target-min);
  padding-inline: var(--s-3);
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-med);
  text-transform: uppercase;
  letter-spacing: var(--track-eyebrow);
  color: var(--c-ink-3);
  border: 1px solid var(--c-rule-2);
  border-radius: var(--r-2);
  transition: color var(--t-2) var(--ease-register),
              border-color var(--t-2) var(--ease-register);
}
.printswitch:hover { color: var(--c-ink); border-color: var(--c-ink-3); }

/* The two states are two drawn squares — filled for the sheet, hollow for the
   blueprint. Shape carries it; the label states it. */
.printswitch__mark {
  inline-size: 10px;
  block-size: 10px;
  border: 1px solid currentColor;
  background-color: currentColor;
}
.printswitch[aria-pressed="true"] { color: var(--c-ink); }
.printswitch[aria-pressed="true"] .printswitch__mark { background-color: transparent; }


/* ==========================================================================
   12. THE REVISION BLOCK
   A dated future revision, explicitly not yet drawn. Status is line style
   plus a written label — the whole status system, at no cost in hue.
   ========================================================================== */

.revision { inline-size: 100%; }

.revision th:first-child,
.revision td:first-child {
  inline-size: 1%;
  white-space: nowrap;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  color: var(--c-ink);
}
.revision td:nth-child(3),
.revision th:nth-child(3) {
  font-family: var(--font-mono);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.revision__future td { border-block-start: 1px solid var(--c-rule-2); padding-block-start: var(--s-5); }

/* 2030 is the only number on the site set at --fs-n1. No count-up. Ever. */
.revision__year {
  font-family: var(--font-mono);
  font-size: var(--fs-n1);
  font-weight: var(--fw-med);
  line-height: var(--lh-num);
  letter-spacing: var(--track-num);
  color: var(--c-ink);
  font-variant-numeric: tabular-nums;
}

.status {
  display: inline-flex;
  align-items: center;
  gap: var(--s-3);
  white-space: nowrap;
  font-size: var(--fs-sm);
  color: var(--c-ink-2);
}
.status::before {
  content: "";
  inline-size: var(--s-5);
  block-size: 0;
  border-block-start: 2px solid var(--c-ink);
}
.status--drawn::before   { border-block-start-style: solid; }
.status--building::before { border-block-start-style: dashed; }
.status--undrawn::before  { border-block-start-style: dotted; border-block-start-color: var(--c-ink-3); }

/* The five ambitions: a real <dl> with disclosure, each expanding to the
   source's own sentence. */
.ambitions {
  display: grid;
  gap: 0;
  margin-block-start: var(--s-7);
  border-block-start: 1px solid var(--c-rule-2);
}
.ambition { border-block-end: 1px solid var(--c-rule); }
.ambition__trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  inline-size: 100%;
  min-block-size: var(--target-min);
  padding-block: var(--s-3);
  text-align: start;
  font-family: var(--font-display);
  font-variation-settings: "wdth" var(--wdth-annot), "wght" var(--fw-semi);
  font-weight: var(--fw-semi);
  font-size: var(--fs-d4);
  text-transform: uppercase;
  letter-spacing: var(--track-annot);
  line-height: var(--lh-d4);
  color: var(--c-ink);
  hyphens: manual;
}
.ambition__trigger::after {
  content: "";
  flex: 0 0 auto;
  inline-size: 10px;
  block-size: 10px;
  border-inline-end: 1px solid var(--c-ink-3);
  border-block-end: 1px solid var(--c-ink-3);
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform var(--t-3) var(--ease-register);
}
.ambition__trigger[aria-expanded="true"]::after { transform: rotate(225deg) translate(-2px, -2px); }
.ambition__body {
  padding-block-end: var(--s-4);
  font-size: var(--fs-lg);
  line-height: var(--lh-lead);
  color: var(--c-ink-2);
  max-inline-size: 54ch;
}

/* The signed note at the foot of the block, the way a drawing is signed. */
.signed {
  margin-block-start: var(--s-7);
  padding-block-start: var(--s-4);
  border-block-start: 1px solid var(--c-rule-2);
  font-family: var(--font-display);
  font-variation-settings: "wdth" var(--wdth-display), "wght" var(--fw-med);
  font-size: var(--fs-d4);
  line-height: var(--lh-d4);
  color: var(--c-ink);
  max-inline-size: 30ch;
  hyphens: manual;
}


/* ==========================================================================
   13. BUTTONS, LINKS, LISTS, TABLES, STATS, QUOTES
   ========================================================================== */

/* A button is a drawn box. Hover inverts it; nothing lifts, scales or glows. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-3);
  min-block-size: var(--target-min);
  padding-inline: var(--s-5);
  padding-block: var(--s-3);
  font-family: var(--font-body);
  font-weight: var(--fw-med);
  font-size: var(--fs-sm);
  color: var(--c-ink);
  background-color: transparent;
  border: 1px solid var(--c-ink);
  border-radius: var(--r-2);
  text-decoration: none;
  transition: background-color var(--t-2) var(--ease-register),
              color var(--t-2) var(--ease-register),
              border-color var(--t-2) var(--ease-register);
}
.btn:hover { background-color: var(--c-ink); color: var(--c-paper); }
.btn--solid { background-color: var(--c-ink); color: var(--c-paper); }
.btn--solid:hover { background-color: transparent; color: var(--c-ink); }
.btn--quiet { border-color: var(--c-rule-2); color: var(--c-ink-2); }
.btn--quiet:hover { border-color: var(--c-ink); background-color: var(--c-ink); color: var(--c-paper); }
.btn--sm { min-block-size: calc(var(--target-min) - var(--s-2)); padding-inline: var(--s-4); }

/* "Naar Sheet 0n" — a link with a drawn arrow, the sheet-set's own device. */
.sheetlink {
  display: inline-flex;
  align-items: baseline;
  gap: var(--s-2);
  min-block-size: var(--target-min);
  font-family: var(--font-body);
  font-weight: var(--fw-med);
  font-size: var(--fs-sm);
  color: var(--c-ink);
  border-block-end: 1px solid var(--c-rule-2);
  transition: color var(--t-2) var(--ease-register),
              border-color var(--t-2) var(--ease-register);
}
.sheetlink:hover { color: var(--c-lab); border-block-end-color: var(--c-lab); }
.sheetlink::after { content: "\25B8"; }
.sheetlink__num {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: var(--track-mono);
  color: var(--c-ink-4);
  font-variant-numeric: tabular-nums;
}

/* Marked list: the sheet's own bullet is a small triangle, never a disc. */
.marklist { list-style: none; margin: 0; padding: 0; max-inline-size: var(--w-prose); }
.marklist li {
  display: grid;
  grid-template-columns: var(--s-5) minmax(0, 1fr);
  align-items: baseline;
  line-height: var(--lh-body);
}
.marklist li + li { margin-block-start: var(--s-3); }
.marklist li::before { content: "\25B8"; color: var(--c-ink-4); }

/* A rule-separated stack — the same anti-card primitive as .columns, but
   vertical. Used for fact rows on the lab sheets. */
.rulelist { list-style: none; margin: 0; padding: 0; }
.rulelist > li {
  padding-block: var(--s-4);
  border-block-end: 1px solid var(--c-rule);
}
.rulelist > li:first-child { border-block-start: 1px solid var(--c-rule-2); }

/* Stats. Mono, promoted, with the label written out beneath. */
.stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(11rem, 100%), 1fr));
  gap: 0;
}
.stats > * + * {
  border-inline-start: 1px solid var(--c-rule-2);
  padding-inline-start: var(--s-5);
  margin-inline-start: var(--s-5);
}
.stat__value {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--fs-n2);
  font-weight: var(--fw-med);
  line-height: var(--lh-num);
  letter-spacing: var(--track-num);
  color: var(--c-ink);
  font-variant-numeric: tabular-nums;
}
.stat__label {
  display: block;
  margin-block-start: var(--s-2);
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  text-transform: uppercase;
  letter-spacing: var(--track-eyebrow);
  color: var(--c-ink-4);
}
@media (max-width: 559px) {
  .stats > * + * {
    border-inline-start: none;
    border-block-start: 1px solid var(--c-rule);
    padding-inline-start: 0;
    margin-inline-start: 0;
    padding-block-start: var(--s-4);
    margin-block-start: var(--s-4);
  }
}

/* A pull quote from the approved narrative. Display face, never uppercase. */
.pullquote {
  font-family: var(--font-display);
  font-variation-settings: "wdth" var(--wdth-display), "wght" var(--fw-med);
  font-size: var(--fs-d3);
  line-height: var(--lh-display);
  color: var(--c-ink);
  max-inline-size: 22ch;
  border-inline-start: 2px solid var(--c-lab);
  padding-inline-start: var(--s-5);
  hyphens: manual;
}
.pullquote__source {
  display: block;
  margin-block-start: var(--s-4);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: var(--track-mono);
  text-transform: none;
  color: var(--c-ink-3);
}

/* The candour block: the Masterplan's own admission, drawn as a recessed
   patch rather than hidden. Never smoothed over — refuse list 37. */
.candour {
  padding: var(--s-5);
  background-color: var(--c-sheet-deep);
  border-inline-start: 3px solid var(--c-ink-3);
  max-inline-size: var(--w-prose);
}
.candour__title {
  font-family: var(--font-display);
  font-variation-settings: "wdth" var(--wdth-annot), "wght" var(--fw-semi);
  font-weight: var(--fw-semi);
  font-size: var(--fs-md);
  text-transform: uppercase;
  letter-spacing: var(--track-annot);
  color: var(--c-ink);
  margin-block-end: var(--s-3);
}

/* The data table, for the accessible equivalents the map and the chain ship. */
.table--sheet { inline-size: 100%; }
.table--sheet caption {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  text-transform: uppercase;
  letter-spacing: var(--track-eyebrow);
  color: var(--c-ink-4);
}

/* A polite live region for REGISTER announcements — language and print
   changes are instant swaps, and an instant swap still has to be announced. */
.status-live {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}


/* ==========================================================================
   14. FOOTER — the full title block
   Set entirely in mono, dense. Where ministry credibility is banked, so
   every fact here comes from source-facts.md and nothing is invented.
   ========================================================================== */

.footer {
  border-block-start: 1px solid var(--c-rule-2);
  background-color: var(--c-sheet-down);
  padding-block: var(--s-8) var(--s-6);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  line-height: var(--lh-dense);
  letter-spacing: var(--track-mono);
  color: var(--c-ink-2);
}

.footer__brand {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  column-gap: var(--s-7);
  row-gap: var(--s-4);
  padding-block-end: var(--s-6);
}
@media (max-width: 759px) {
  .footer__brand { grid-template-columns: minmax(0, 1fr); }
}

.footer__wordmark {
  font-family: var(--font-display);
  font-variation-settings: "wdth" var(--wdth-annot), "wght" var(--fw-bold);
  font-weight: var(--fw-bold);
  font-size: var(--fs-d4);
  text-transform: uppercase;
  letter-spacing: var(--track-annot);
  line-height: var(--lh-d4);
  color: var(--c-ink);
}
.footer__claim {
  font-family: var(--font-body);
  font-size: var(--fs-lg);
  line-height: var(--lh-lead);
  letter-spacing: var(--track-body);
  color: var(--c-ink);
  max-inline-size: 40ch;
}

.footer__cols {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--s-6) var(--gutter);
  padding-block: var(--s-6);
  border-block-start: 1px solid var(--c-rule);
}
/* Four columns only from 1200px. The deck's governance strings ("TNO —
   penvoerder", "Nationaal Groeifonds") are phrases, not labels, and four of
   them across a 960px sheet leaves each column too narrow to set them. */
@media (max-width: 1199px) { .footer__cols { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 559px) { .footer__cols { grid-template-columns: minmax(0, 1fr); } }

.footer__head {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-med);
  text-transform: uppercase;
  letter-spacing: var(--track-eyebrow);
  color: var(--c-ink-4);
  margin-block-end: var(--s-3);
}

.footer__list { list-style: none; margin: 0; padding: 0; }
.footer__list li { margin-block-end: var(--s-1); }
.footer__list a {
  display: inline-flex;
  align-items: center;
  min-block-size: var(--target-min);
  color: var(--c-ink-2);
}
.footer__list a:hover { color: var(--c-ink); text-decoration: underline; }
.footer__list .nav__num { margin-inline-end: var(--s-3); }

/* The key/value pairs — governance, programme, period. max-content on the
   key column so it sizes itself per language. */
/* Stacked by default and paired only when there is room. These keys are
   phrases, not the title block's single words, so a key column that refuses
   to shrink pushes the whole footer grid wider than its container. */
.footer__dl {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  row-gap: var(--s-1);
}
@media (min-width: 1440px) {
  .footer__dl {
    grid-template-columns: minmax(0, max-content) minmax(0, 1fr);
    column-gap: var(--s-4);
  }
}
.footer__note {
  margin-block-start: var(--s-4);
  color: var(--c-ink-3);
  max-inline-size: 44ch;
}

.footer__dl dt {
  font-size: var(--fs-2xs);
  letter-spacing: var(--track-eyebrow);
  color: var(--c-ink-4);
}
.footer__dl dd { color: var(--c-ink-2); font-variant-numeric: tabular-nums; }

/* The two stated lines: the mission and the projection. Annotation register
   for the first, mono for the second — one is a claim, one is a measurement. */
.footer__stated {
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  padding-block: var(--s-5);
  border-block-start: 1px solid var(--c-rule);
}
.footer__mission {
  font-family: var(--font-display);
  font-variation-settings: "wdth" var(--wdth-annot), "wght" var(--fw-semi);
  font-weight: var(--fw-semi);
  font-size: var(--fs-md);
  text-transform: uppercase;
  letter-spacing: var(--track-annot);
  color: var(--c-ink);
  hyphens: manual;
}
.footer__projection {
  font-size: var(--fs-2xs);
  text-transform: uppercase;
  letter-spacing: var(--track-eyebrow);
  color: var(--c-ink-4);
}

.footer__base {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  padding-block-start: var(--s-5);
  border-block-start: 1px solid var(--c-rule-2);
  font-size: var(--fs-2xs);
  color: var(--c-ink-4);
  font-variant-numeric: tabular-nums;
}
.footer__base a { color: var(--c-ink-3); min-block-size: var(--target-min); display: inline-flex; align-items: center; }
.footer__base a:hover { color: var(--c-ink); text-decoration: underline; }

.footer__legal { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-4); }


/* ==========================================================================
   15. 404
   ========================================================================== */

.notfound {
  display: flex;
  flex-direction: column;
  align-items: start;
  gap: var(--s-5);
  min-block-size: calc(100svh - var(--nav-h) - var(--s-11));
  justify-content: center;
  padding-block: var(--s-9);
}
.notfound__code {
  font-family: var(--font-mono);
  font-size: var(--fs-n1);
  font-weight: var(--fw-med);
  line-height: var(--lh-num);
  letter-spacing: var(--track-num);
  color: var(--c-ink-3);
  font-variant-numeric: tabular-nums;
}
.notfound__title {
  font-family: var(--font-display);
  font-variation-settings: "wdth" var(--wdth-display), "wght" 900;
  font-weight: var(--fw-black);
  font-size: var(--fs-d2);
  line-height: var(--lh-display);
  color: var(--c-ink);
  max-inline-size: 18ch;
  hyphens: manual;
}


/* ==========================================================================
   16. REVEALS — PLOT, and its reduced form
   A mark appears the way a plotter lays it down: opacity plus a 12px lift,
   staggered by a custom property rather than by a queue of timers.

   Note the polarity: the hidden state exists ONLY under .is-motion, which
   site.js adds after deciding motion is allowed. With JavaScript disabled the
   class never lands and every element is visible on first paint — that is the
   no-JS contract, enforced by the stylesheet rather than by a script.
   ========================================================================== */

.is-motion [data-reveal] {
  opacity: 0;
  transform: translateY(12px);
  transition:
    opacity var(--t-5) var(--ease-plot) var(--reveal-delay, 0ms),
    transform var(--t-5) var(--ease-plot) var(--reveal-delay, 0ms);
}
.is-motion [data-reveal].is-revealed { opacity: 1; transform: none; }

/* PLOT reduced: opacity only, 120ms, no translate, no stagger. site.js never
   builds the observer in this case, so this is the belt to that braces. */
@media (prefers-reduced-motion: reduce) {
  [data-reveal] {
    opacity: 1 !important;
    transform: none !important;
    transition: opacity 120ms linear !important;
  }
}

/* SURVEY: slow parallax of the map's base plate only. Never on marks,
   labels, conduits or text — the variable is read by exactly one element. */
.is-motion [data-parallax] { translate: 0 var(--parallax, 0px); }


/* ==========================================================================
   17. PRINT
   The jury will PDF this. tokens.css already flattens the palette; this
   removes the chrome that has no meaning on paper.
   ========================================================================== */

@media print {
  .nav, .drawer, .sheet__ticks, .sheet__number, .margin__rail, .printswitch, .lang { display: none !important; }
  .sheet { padding-block-start: 0; }
  .head, .labhead { min-block-size: 0; padding-block: var(--s-6); }
  .plate--map .plate__body { grid-template-columns: 10fr 6fr; }
  .legend, .titleblock { border-color: var(--c-rule-2); }
  .band, .verb, .travel, .revision tr { break-inside: avoid; }
  .footer { background: none; padding-block-start: var(--s-5); }
}


/* ==========================================================================
   The Head's map mount
   ==========================================================================
   The map component carries its own title and lead, which is right when it is
   the subject of its own plate. Inside the Head it is not: the claim is the
   subject, and two competing titles in adjacent columns read as two pages
   spliced together — the map's title even sits a few pixels higher, so it wins
   an argument it should not have been in. The mount keeps its hint and its
   accessible name; only the shouting goes.
   ========================================================================== */

.head__map .ixmap__title,
.head__map .ixmap__lead {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.head__map .ixmap__head {
  margin-block-end: var(--s-4);
}


/* ==========================================================================
   14. THE FILM BAND
   The one photographic surface on the sheet, and it is treated as a plate
   like every other: full field width, cut hard top and bottom, no radius and
   no fade into its neighbours.

   Footage is never dropped in raw. Three layers, always in this order:
     1. the frame itself, desaturated and pushed green (--media-filter)
     2. the wash and the vignette, which print it in the sheet's own ink
     3. grain, so it reads as a print and not as a stock library asset
   Type over a band sits in the chlorotype register — line on ground — because
   the band IS a dark plate, not a light one with a picture on it.
   ========================================================================== */

.plate--film {
  padding-block: 0;
  background-color: var(--cy-deep);
  color: var(--cy-line);
}

.film {
  position: relative;
  display: block;
  margin: 0;
  isolation: isolate;
}

.film__frame {
  position: relative;
  block-size: clamp(20rem, 42vw, 38rem);
  overflow: hidden;
  background-color: var(--cy-ground);
}

.film--tall .film__frame { block-size: clamp(26rem, 62vw, 46rem); }

.film__media {
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  filter: var(--media-filter);
}

/* The slow push. A plotter does not overshoot and neither does this: it is a
   single linear drift with no return, at a rate you notice only if you look
   for it. Motion is gated on the token, so it stops dead under reduced
   motion instead of being made faster. */
.film__media--photo {
  animation: film-push var(--t-kenburns) var(--ease-flow) both alternate infinite;
  transform-origin: 50% 55%;
}

@keyframes film-push {
  from { transform: scale(1.02); }
  to   { transform: scale(1.12); }
}

@media (prefers-reduced-motion: reduce) {
  .film__media--photo { animation: none; transform: scale(1.02); }
}

/* The grade. */
.film__frame::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image: var(--media-wash), var(--media-vignette);
  pointer-events: none;
}

/* The grain, over the grade, under the type. */
.film__frame::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  background-image: var(--media-grain-image);
  background-size: 180px 180px;
  opacity: var(--media-grain);
  pointer-events: none;
}

/* A band whose media never arrived is not a hole: it falls back to the
   drawing the rest of the site is made of — the graticule, ruled in the
   chlorotype. Nothing on this site is ever a grey box. */
.film[data-media="drawn"] .film__frame {
  background-color: var(--cy-ground);
  background-image:
    repeating-linear-gradient(90deg, var(--cy-rule) 0 1px, transparent 1px 5rem),
    repeating-linear-gradient(0deg, var(--cy-rule) 0 1px, transparent 1px 5rem);
}

.film[data-media="drawn"] .film__media { display: none; }

.film__cap {
  position: absolute;
  inset-block-end: 0;
  inset-inline: 0;
  z-index: 3;
  padding-block: var(--s-6);
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  pointer-events: none;
}

.film__eyebrow {
  color: var(--cy-mix);
  margin: 0;
}

.film__line {
  font-family: var(--font-display);
  font-variation-settings: "wdth" var(--wdth-display), "wght" 900;
  font-weight: var(--fw-black);
  font-size: var(--fs-d3);
  line-height: var(--lh-display);
  color: var(--cy-line);
  max-inline-size: 22ch;
  margin: 0;
  text-wrap: balance;
}

.film__line--2 { color: var(--cy-mix-signal); }

.film__meta {
  font-size: var(--fs-2xs);
  text-transform: uppercase;
  letter-spacing: var(--track-eyebrow);
  color: var(--cy-line-3);
  margin: var(--s-2) 0 0;
}

/* The band prints as a rule and its caption — a photograph is not paper. */
@media print {
  .film__frame { display: none; }
  .film__cap { position: static; color: var(--c-ink); }
  .film__line, .film__eyebrow, .film__meta { color: var(--c-ink); }
}

/* The strip: the same band at band scale, sat between a lab's header line and
   its name. Wider and shorter than the full band — it is a establishing shot,
   not a plate of its own. */
.film--strip {
  margin-block: var(--s-4) var(--s-6);
}

.film--strip .film__frame {
  block-size: clamp(9rem, 20vw, 15rem);
  border-block: 1px solid var(--c-rule-2);
}

.film__cap--strip {
  padding-block: var(--s-3);
  padding-inline: var(--s-4);
}

.film__cap--strip .film__meta { margin: 0; }

/* The strip's grade takes the lab's own colour rather than the neutral wash:
   five bands, five casts, one treatment. The frames are not all shot in the
   dark — a bright interior needs a harder pull than a black box does, or the
   caption over it stops passing — so the strip grades deeper than the plate.
   Measured against the palest frame in the set, not the darkest. */
.film--strip .film__media {
  filter: saturate(0.5) contrast(1.14) brightness(0.6) sepia(0.26) hue-rotate(76deg);
}

.film--strip .film__frame::after {
  background-image:
    linear-gradient(180deg,
      color-mix(in srgb, var(--c-lab) 30%, transparent) 0%,
      color-mix(in srgb, var(--cy-deep) 46%, transparent) 45%,
      color-mix(in srgb, var(--cy-deep) 92%, transparent) 100%),
    var(--media-vignette);
}

/* The one line of type on a strip carries its own ground, so it never depends
   on what the frame happens to be doing behind it. */
.film__cap--strip .film__meta {
  color: var(--cy-line);
}

/* The Head's scene. Not a hero image — the claim never sits on a photograph.
   The frame is graded, dropped to a wash, and masked out of the claim column
   entirely, so it reads as depth behind the drawing rather than as content. */
.head__scene {
  position: absolute;
  inset-block: 0;
  inset-inline: calc(-1 * var(--pad-x));
  z-index: var(--z-below);
  pointer-events: none;
  overflow: hidden;
  /* Two layers, blended: the frame supplies the luminance and a flat green
     supplies the hue. Filters alone cannot do this — sepia + hue-rotate on a
     bright interior lands on beige, which is the one cast this sheet must not
     have. `color` blending is exact and needs no second asset. */
  background-image:
    linear-gradient(0deg, var(--p-mix-signal) 0%, var(--p-mix-signal) 100%),
    url("../img/labs/shine.jpg");
  background-blend-mode: color, normal;
  background-size: cover, cover;
  background-position: center, 60% 45%;
  /* Blurred past recognition on purpose. A legible photograph behind the map
     competes with the drawing and reads as an accident; the same frame at 40px
     of blur is a green field of light, which is all this layer is for. The
     scale-up hides the blur's soft edge inside the box. */
  filter: saturate(0.9) contrast(1.04) brightness(1.02) blur(40px);
  transform: scale(1.15);
  opacity: 0.42;
  -webkit-mask-image: linear-gradient(90deg, transparent 0%, transparent 34%, rgb(0 0 0 / 0.55) 58%, rgb(0 0 0 / 0.9) 100%);
  mask-image: linear-gradient(90deg, transparent 0%, transparent 34%, rgb(0 0 0 / 0.55) 58%, rgb(0 0 0 / 0.9) 100%);
}

/* Below the two-column Head the claim and the map stack, so there is no column
   left to mask against and the wash would sit under everything. It goes. */
@media (max-width: 959px) {
  .head__scene { display: none; }
}

@media (prefers-contrast: more), print {
  .head__scene { display: none; }
}


/* ==========================================================================
   15. THE CYANOTYPE PLATE'S OWN LAYOUT
   It used to be one 54ch column stacked down the left of a 1500px plate, with
   an empty [data-ix-ghost] div holding a hole in the middle of the argument.
   The argument has four movements and they are laid out as four: the turn of
   the world, the gap and what follows from it, the answer, the close.
   ========================================================================== */

.cyano {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  row-gap: var(--s-9);
}

.cyano__row {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 9fr);
  column-gap: calc(var(--gutter) * 2);
  row-gap: var(--s-6);
  align-items: start;
}

.cyano__col {
  display: flex;
  flex-direction: column;
  gap: var(--s-5);
  min-inline-size: 0;
}

/* A frame inside a dark plate is inset, not full-bleed: full-bleed is the
   film BAND's job and this plate is not a band. Hairline, no radius. */
.film--inset {
  margin: 0;
  border: 1px solid var(--c-rule-2);
}

.film--inset .film__frame {
  block-size: clamp(14rem, 26vw, 22rem);
}

/* The gap sentence is the hinge of the whole plate, so it is set as a
   statement across the field rather than as another paragraph. */
.cyano__gap {
  border-block-start: 1px solid var(--c-rule-2);
  padding-block-start: var(--s-5);
}

.cyano__gaptext {
  font-family: var(--font-display);
  font-variation-settings: "wdth" var(--wdth-annot), "wght" var(--fw-med);
  font-size: var(--fs-d4);
  line-height: var(--lh-d4);
  color: var(--c-ink);
  /* 34ch broke "Nederland" across two lines. Auto hyphens are for body copy,
     never for a line set in the display face — the width gives way instead. */
  max-inline-size: 44ch;
  hyphens: manual;
  text-wrap: balance;
  margin: 0;
}

/* The three consequences: a ruled row of columns, the same departures-board
   register the venue lists use. They are three parallel facts, so they are
   printed as three, not as a stack with arrows down the left. */
.cyano__consequence {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 9fr);
  column-gap: calc(var(--gutter) * 2);
  row-gap: var(--s-5);
  align-items: start;
}

.cyano__conseqlabel { margin: 0; }

.cyano__list {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0 var(--gutter);
  list-style: none;
  margin: 0;
  padding: 0;
  max-inline-size: none;
}

.cyano__list li {
  display: block;
  padding-block-start: var(--s-3);
  padding-inline-end: var(--gutter);
  border-block-start: 1px solid var(--c-rule-2);
  font-size: var(--fs-md);
  line-height: var(--lh-dense);
  color: var(--c-ink-2);
}

.cyano__list li + li { margin-block-start: 0; }

.cyano__list li::before {
  content: none;
}

/* The turn gets the width the claim gave up. */
.cyano__row--turn {
  grid-template-columns: minmax(0, 9fr) minmax(0, 7fr);
  column-gap: calc(var(--gutter) * 2);
  border-block-start: 1px solid var(--c-rule-2);
  padding-block-start: var(--s-6);
}

.cyano__claim--turn {
  font-size: var(--fs-d3);
  max-inline-size: 16ch;
  margin: 0;
}

.cyano__answer {
  display: flex;
  flex-direction: column;
  gap: var(--s-5);
  min-inline-size: 0;
}

.cyano__row--close {
  border-block-start: 1px solid var(--c-rule-2);
  padding-block-start: var(--s-6);
}

.cyano__closetitle { margin: 0; }

/* The quote is the plate's last word, not its loudest: it sits a step below
   the turn, which is the line that has to carry the argument. */
.cyano__quote {
  margin-block-start: 0;
  font-size: var(--fs-d4);
  max-inline-size: 30ch;
}

/* Below the split every row is one column and the consequences go back to a
   stack — three 100px columns is not a departures board, it is a puzzle. */
@media (max-width: 959px) {
  .cyano { row-gap: var(--s-8); }

  .cyano__row,
  .cyano__consequence {
    grid-template-columns: minmax(0, 1fr);
  }

  .cyano__list { grid-template-columns: minmax(0, 1fr); }
  .cyano__list li + li { margin-block-start: var(--s-4); }
}
