/* =============================================================================
   MAD BREWS — SPECIFIC GRAVITY
   -----------------------------------------------------------------------------
   Fermentation is invisible. You cannot photograph it; you can only measure it
   and then tell the truth about what you measured. So this site has no
   photographs and does not miss them: every image slot holds a numbered,
   matted, captioned PLATE, and a plate is a finished object rather than a
   placeholder waiting for a picture.

   THE LAWS THIS FILE ENFORCES
     1  PAINTED PIXELS. Ink + paper families >= 90% of any viewport. Amber <= 2%:
        exactly one solid amber element (the CTA) plus at most two amber marks
        under 12px. Teal at most once per page, and only where an experiment hit
        its limit.
     2  CONTRAST. Every colour token below carries its measured WCAG ratio.
        --amber on paper is 2.34:1 and is FORBIDDEN as text, border or icon on
        any paper surface; use --amber-dark (5.18:1). Same rule for teal.
     3  NO SHADOW, NO RADIUS. There is not one box-shadow in this file and no
        radius above 2px. Depth comes from four hairline weights, the 12px mat,
        the rim-light pair, and the lamp's vector slab.
     4  NOTHING IS CENTRED except one designated .statement per page.
     5  STANCE. Every section declares data-stance="a|b|c|d". No two vertically
        adjacent sections may share one.
     6  ONE ITALIC WORD per headline — the experimental variable. Never zero,
        never two. Markup concern, listed here so it is not forgotten.
     7  EVERY NUMBER IS AN INSTRUMENT READING. Mono, tabular, slashed zero, and
        its unit in a <span class="u"> at 0.7em / 45%.
     8  NO PLACEHOLDERS. Every image slot is a mounted plate.
     9  ANTI-PARALLAX. Only the rail, the header and the fire-once reveal
        observer respond to scroll. Reveal travel is capped at 14px.
    10  A HUMAN IN THE MARGIN on every page.
   ============================================================================= */

/* ---------------------------------------------------------------- 01 TOKENS */

:root {
  /* -- ink: the four licensed dark surfaces ------------------------------- */
  --ink:         oklch(0.18 0.015 50);
  --ink-2:       oklch(0.215 0.017 50);
  --ink-3:       oklch(0.26 0.02 50);
  --ink-4:       oklch(0.32 0.02 50);

  /* -- paper: the page ---------------------------------------------------- */
  --paper:         oklch(0.97 0.012 70);
  --paper-deep:    oklch(0.945 0.013 70);
  --paper-deeper:  oklch(0.915 0.014 70);
  --paper-deepest: oklch(0.875 0.015 70);

  /* -- the rationed accent ------------------------------------------------ */
  --amber:      oklch(0.72 0.15 70);   /* on ink 7.38:1 AA · on paper 2.34:1 FAIL — fills only */
  --amber-dark: oklch(0.52 0.15 70);   /* on paper 5.18:1 AA · on paper-deep 4.81:1 AA */
  --amber-dim:  oklch(0.62 0.07 70);   /* on paper 3.38:1 — large text and marks only */
  --amber-hair: oklch(0.72 0.15 70 / 0.16);

  /* -- the counterpoint, once per page ------------------------------------ */
  --teal:      oklch(0.72 0.15 195);   /* on ink 8.38:1 AA · on paper 2.06:1 FAIL */
  --teal-dark: oklch(0.50 0.13 195);   /* on paper 4.83:1 AA */

  --danger: oklch(0.55 0.15 30);       /* on paper 4.78:1 AA */

  /* -- text --------------------------------------------------------------- */
  --on-ink:         oklch(0.93 0.008 70);  /* 15.32:1 AA */
  --on-ink-muted:   oklch(0.78 0.012 60);  /*  9.39:1 AA */
  --on-ink-faint:   oklch(0.66 0.012 60);  /*  6.04:1 AA · on ink-2 5.63:1 AA */
  --on-paper:       oklch(0.20 0.015 50);  /* 16.62:1 AA */
  --on-paper-muted: oklch(0.44 0.014 50);  /*  7.14:1 AA */
  --on-paper-faint: oklch(0.50 0.012 50);  /*  5.12:1 AA on paper-deep */

  /* -- four hairline weights. This is the whole depth system. -------------- */
  --rule-hair:   oklch(0.90 0.012 70);
  --rule:        oklch(0.845 0.012 70);
  --rule-strong: oklch(0.72 0.014 60);
  --rule-ink:    oklch(0.42 0.016 50);
  --rule-d-hair:   oklch(0.245 0.017 50);
  --rule-d:        oklch(0.30 0.018 50);
  --rule-d-strong: oklch(0.40 0.02 50);

  /* -- type --------------------------------------------------------------- */
  --serif: "Cormorant Garamond", "Iowan Old Style", Georgia, serif;
  --sans:  "Jost", "Avenir Next", "Segoe UI", system-ui, sans-serif;
  --mono:  "IBM Plex Mono", ui-monospace, "SF Mono", Consolas, monospace;

  --t-display: clamp(2.9rem, 7.8vw, 6.75rem);
  --t-h1:      clamp(2.25rem, 5vw, 4rem);
  --t-h2:      clamp(1.75rem, 3.1vw, 2.7rem);
  --t-h3:      clamp(1.18rem, 1.08rem + 0.55vw, 1.55rem);
  --t-lede:    clamp(1.05rem, 1rem + 0.4vw, 1.28rem);
  --t-body:    clamp(1rem, 0.96rem + 0.16vw, 1.08rem);
  --t-small:   0.9rem;
  --t-label:   0.7rem;
  --t-micro:   0.625rem;

  /* -- rhythm. Paragraph spacing is half a baseline, not a full line. ------ */
  --s-1: .25rem; --s-2: .5rem;  --s-3: .75rem; --s-4: 1rem;
  --s-5: 1.5rem; --s-6: 2rem;   --s-7: 3rem;   --s-8: 4rem;
  --s-9: 6rem;   --s-10: 8rem;

  /* -- structure ---------------------------------------------------------- */
  --shell:   1320px;
  --gutter:  clamp(1.15rem, 3.2vw, 3rem);
  --rail:    0px;                  /* becomes 64px at >=1200px */
  --margin-col: 0px;               /* becomes 216px at >=1280px, for marginalia */
  --measure: 64ch;
  --mat:     12px;                 /* the plate mat. Permanent furniture. */

  /* -- the lamp. A fixed coordinate, not a cursor spotlight. -------------- */
  --lamp-x: 62%;
  --lamp-y: 24vh;

  /* -- motion ------------------------------------------------------------- */
  --ease-settle: cubic-bezier(0.33, 0.02, 0.18, 1);  /* things coming to rest */
  --ease-rise:   cubic-bezier(0.22, 1, 0.36, 1);     /* things arriving */
  --ease-light:  cubic-bezier(0.4, 0, 0.2, 1);       /* the room brightening */
  --ease-needle: cubic-bezier(0.16, 1.06, 0.3, 1);   /* a gauge overshooting */

  --d-fast: 180ms; --d-base: 380ms; --d-slow: 640ms; --d-draw: 900ms;

  --z-rail: 1; --z-head: 60;
}

@media (min-width: 1200px) { :root { --rail: 64px; } }
@media (min-width: 1280px) { :root { --margin-col: 216px; } }

/* ------------------------------------------------------------ 02 BASE/RESET */

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

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--on-paper);
  font-family: var(--sans);
  font-weight: 300;
  font-size: var(--t-body);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

/* Paper with tooth. ~280 bytes, no JS, no canvas. */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 900;
  pointer-events: none;
  opacity: 0.3;
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23n)' opacity='0.4'/%3E%3C/svg%3E");
}

img, svg, canvas { display: block; max-width: 100%; }

h1, h2, h3, h4 {
  font-family: var(--serif);
  font-weight: 500;
  line-height: 1.02;
  letter-spacing: -0.014em;
  margin: 0 0 0.4em;
  text-wrap: balance;
}
h1 { font-size: var(--t-h1); }
h2 { font-size: var(--t-h2); }
h3 { font-size: var(--t-h3); line-height: 1.14; letter-spacing: -0.006em; }

/* Law 6: one italic word per headline — the thing that changed. */
h1 em, h2 em, h3 em, .display em {
  font-style: italic;
  font-weight: 400;
}

p { margin: 0 0 0.62em; }
p:last-child { margin-bottom: 0; }

a { color: var(--amber-dark); text-decoration: none; }
.on-ink a, .band a { color: var(--amber); }

.lnk {
  background-image: linear-gradient(currentColor, currentColor);
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0% 1px;
  transition: background-size var(--d-base) var(--ease-rise);
}
.lnk:hover, .lnk:focus-visible { background-size: 100% 1px; }

:focus-visible { outline: 2px solid var(--amber-dark); outline-offset: 3px; }
.band :focus-visible, .on-ink :focus-visible { outline-color: var(--amber); }

::selection { background: var(--amber); color: var(--ink); }

/* --------------------------------------------------------------- 03 TYPE */

.display {
  font-family: var(--serif);
  font-size: var(--t-display);
  font-weight: 500;
  line-height: 0.94;
  letter-spacing: -0.02em;
  margin: 0;
  text-wrap: balance;
}

/* Law 7. Every figure on this site is a reading off an instrument. */
.readout, .tbl td:first-child, .field input, .field select {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums slashed-zero;
  font-feature-settings: "zero" 1;
}
.readout { letter-spacing: 0.01em; }
.readout--xl {
  font-size: clamp(2.1rem, 5.2vw, 3.1rem);
  line-height: 1;
  letter-spacing: -0.015em;
}
.u {
  font-size: 0.7em;
  opacity: 0.45;
  letter-spacing: 0.06em;
  margin-left: 0.26em;
}

.label {
  font-family: var(--mono);
  font-size: var(--t-label);
  font-weight: 400;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--on-paper-faint);
  font-variant-numeric: tabular-nums slashed-zero;
}
.micro {
  font-family: var(--mono);
  font-size: var(--t-micro);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--on-paper-faint);
  font-variant-numeric: tabular-nums slashed-zero;
}
.band .label, .band .micro, .on-ink .label, .on-ink .micro { color: var(--on-ink-faint); }
.label--amber { color: var(--amber-dark); }
.band .label--amber, .on-ink .label--amber { color: var(--amber); }
.label--teal { color: var(--teal-dark); }
.band .label--teal, .on-ink .label--teal { color: var(--teal); }

.lede {
  font-size: var(--t-lede);
  line-height: 1.46;
  max-width: 40ch;
  color: var(--on-paper-muted);
}
.band .lede, .on-ink .lede { color: var(--on-ink-muted); }

.prose { max-width: var(--measure); }
.prose > * + * { margin-top: 0.62em; }
.prose h2 { margin-top: 1.6em; }
.prose h3 { margin-top: 1.3em; }
.prose ul, .prose ol { padding-left: 1.1rem; }
.prose li + li { margin-top: 0.35em; }
.prose li::marker { color: var(--amber-dark); }
.prose blockquote {
  margin: 1.4em 0;
  padding-left: 1.3rem;
  border-left: 1px solid var(--amber-dark);
  font-family: var(--serif);
  font-style: italic;
  font-size: 1.32em;
  line-height: 1.2;
  color: var(--on-paper);
}
.prose code {
  font-family: var(--mono);
  font-size: 0.85em;
  background: var(--paper-deeper);
  padding: 0.1em 0.34em;
}

/* Law 4: the single permitted centred element. */
.statement {
  font-family: var(--serif);
  font-style: italic;
  font-size: clamp(1.9rem, 5.6vw, 4.4rem);
  line-height: 1.02;
  letter-spacing: -0.02em;
  text-align: center;
  max-width: 19ch;
  margin-inline: auto;
  text-wrap: balance;
}

/* -------------------------------------------------------------- 04 LAYOUT */

.shell {
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section { position: relative; padding-block: clamp(3.25rem, 8vw, 7rem); }
.section--tight { padding-block: clamp(2rem, 4.5vw, 3.5rem); }

/* Law 5: four stances, so no two neighbouring sections sit the same way.
   THE ONE THING A STANCE MAY NOT DO IS MOVE THE PAGE'S LEFT EDGE. Every section
   shares the same centred container and the same inset past the rail, so the
   left margin is dead straight from the header to the footer. A margin that
   shifts between sections does not read as variety, it reads as a mistake —
   and it only shows above 1200px, where the container stops filling the
   viewport, which is why it looked fine on a phone.
   The stances vary composition INSIDE that container instead. */
.section > .shell { padding-left: calc(var(--gutter) + var(--rail)); }

/* b — the annotated stance: a narrower measure, same left edge. */
[data-stance="b"] .section-head,
[data-stance="b"] .prose,
[data-stance="b"] .lede { max-width: 54ch; }

/* c — the instrument stance: the catalogue and the tools take the full width. */
/* a — the reading stance: its narrowness comes from .withmargin. */
/* d — the conversion band: full width on ink. */

.band { background: var(--ink); color: var(--on-ink); position: relative; overflow: hidden; }
.band h1, .band h2, .band h3 { color: var(--on-ink); }

/* The lamp: one warm pool at a fixed coordinate. Ink surfaces only. */
.band::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(
    62vw 52vh at var(--lamp-x) var(--lamp-y),
    oklch(0.72 0.15 70 / 0.10),
    transparent 70%
  );
  transition: opacity var(--d-slow) var(--ease-light);
}
.band.is-blup::before { opacity: 1.35; }

.grid { display: grid; gap: clamp(1rem, 2.2vw, 1.75rem); }
.grid--2 { grid-template-columns: repeat(2, 1fr); }
.grid--3 { grid-template-columns: repeat(3, 1fr); }
.grid--4 { grid-template-columns: repeat(4, 1fr); }
.grid--lean   { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); }
.grid--lean-r { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); }
@media (max-width: 1000px) {
  .grid--3, .grid--4 { grid-template-columns: repeat(2, 1fr); }
  .grid--lean, .grid--lean-r { grid-template-columns: 1fr; }
}
@media (max-width: 620px) { .grid--2, .grid--3, .grid--4 { grid-template-columns: 1fr; } }

.hr { border: 0; border-top: 1px solid var(--rule); margin: var(--s-8) 0; }
.band .hr { border-color: var(--rule-d); }

/* Section headers are batch-log entries, not "01 — THE WORKSHOP". */
.log {
  display: flex;
  align-items: baseline;
  gap: var(--s-4);
  border-top: 1px solid var(--rule-strong);
  padding-top: var(--s-3);
  margin-bottom: var(--s-5);
}
.band .log { border-color: var(--rule-d-strong); }
.log__day { color: var(--amber-dark); white-space: nowrap; }
.band .log__day { color: var(--amber); }
.log__sg { white-space: nowrap; }
.log__name { margin-left: auto; text-align: right; }

.section-head { margin-bottom: clamp(1.75rem, 3.5vw, 3rem); max-width: 54ch; }
.section-head h2 { margin-bottom: 0.24em; }

/* ------------------------------------------------------- 05 GRADUATED RAIL
   A specific-gravity scale down the left edge. Pure CSS ticks; only the scale
   translates, and only inside one rAF. It cannot desync because there is no
   path to desync. */

.rail {
  position: fixed;
  top: 0; left: 0;
  width: var(--rail);
  height: 100vh;
  z-index: var(--z-rail);
  pointer-events: none;
  display: none;
  border-right: 1px solid var(--rule-hair);
}
@media (min-width: 1200px) { .rail { display: block; } }

.rail__scale {
  position: absolute;
  top: -50vh; left: 0; right: 0;
  height: 300vh;
  will-change: transform;
  background-image:
    repeating-linear-gradient(180deg, var(--rule-strong) 0 1px, transparent 1px 40px),
    repeating-linear-gradient(180deg, var(--rule) 0 1px, transparent 1px 8px);
  background-size: 10px 40px, 6px 8px;
  background-position: right 14px top 0, right 14px top 0;
  background-repeat: repeat-y;
  opacity: 0.9;
}
.rail__head {
  position: absolute;
  top: 50vh; left: 0; right: 0;
  border-top: 1px solid var(--rule-ink);
}
.rail__read {
  position: absolute;
  top: 50vh; left: 8px;
  transform: translateY(-140%);
  font-family: var(--mono);
  font-size: var(--t-micro);
  letter-spacing: 0.08em;
  color: var(--on-paper-faint);
  font-variant-numeric: tabular-nums slashed-zero;
  min-width: 5ch;
}
.rail__unit {
  position: absolute;
  top: 50vh; left: 8px;
  transform: translateY(40%);
  font-family: var(--mono);
  font-size: var(--t-micro);
  letter-spacing: 0.14em;
  color: var(--on-paper-faint);
  opacity: 0.6;
}

/* below 1200px the rail becomes a ticked progress hairline */
.progress {
  position: fixed;
  top: 0; left: 0; right: 0;
  height: 2px;
  background: var(--amber-hair);
  z-index: calc(var(--z-head) + 1);
}
.progress__bar { height: 100%; width: 0; background: var(--amber); }
@media (min-width: 1200px) { .progress { display: none; } }

/* -------------------------------------------------------------- 06 HEADER */

.head {
  position: sticky;
  top: 0;
  z-index: var(--z-head);
  background: var(--ink);
  color: var(--on-ink);
  border-bottom: 1px solid var(--rule-d-hair);
}
.head__in {
  max-width: var(--shell);
  margin-inline: auto;
  padding: clamp(0.8rem, 1.3vw, 1.25rem) var(--gutter);
  display: flex;
  align-items: center;
  gap: var(--s-6);
  transition: padding var(--d-base) var(--ease-settle);
}
.is-condensed .head__in { padding-block: 0.55rem; }

.mark {
  font-family: var(--mono);
  font-size: 0.94rem;
  font-weight: 500;
  letter-spacing: 0.34em;
  /* trailing letter-space compensation, so the mark optically aligns left */
  margin-right: -0.34em;
  color: var(--on-ink);
  white-space: nowrap;
  transition: letter-spacing var(--d-slow) var(--ease-settle), color var(--d-fast) linear;
}
.is-condensed .mark { letter-spacing: 0.24em; margin-right: -0.24em; }
.mark:hover { color: var(--amber); }

.nav { display: flex; align-items: center; gap: clamp(0.7rem, 1.4vw, 1.4rem); margin-left: auto; }
.nav a {
  position: relative;
  font-family: var(--mono);
  font-size: var(--t-label);
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--on-ink-muted);
  padding: 0.4rem 0;
  transition: color var(--d-fast) linear;
}
.nav a::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  width: 100%; height: 1px;
  background: var(--amber);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--d-base) var(--ease-rise);
}
.nav a:hover, .nav a:focus-visible { color: var(--on-ink); }
.nav a:hover::after, .nav a:focus-visible::after { transform: scaleX(1); }
.nav a.is-active { color: var(--amber); }
.nav a.is-active::after { transform: scaleX(1); background: var(--rule-d-strong); }

.lang {
  font-family: var(--mono);
  font-size: var(--t-label);
  letter-spacing: 0.13em;
  color: var(--on-ink-muted);
  border: 1px solid var(--rule-d);
  padding: 0.28rem 0.58rem;
  transition: border-color var(--d-fast) linear, color var(--d-fast) linear;
}
.lang:hover, .lang:focus-visible { border-color: var(--amber); color: var(--amber); }

/* the airlock keeps ticking in the header once you are past the hero */
.head__lock {
  width: 22px; height: 26px;
  opacity: 0;
  transform: translateY(-4px);
  transition: opacity var(--d-base) var(--ease-rise), transform var(--d-base) var(--ease-rise);
}
.is-condensed .head__lock { opacity: 1; transform: none; }

.burger {
  display: none;
  margin-left: auto;
  background: none;
  border: 1px solid var(--rule-d);
  color: var(--on-ink);
  font-family: var(--mono);
  font-size: var(--t-label);
  letter-spacing: 0.13em;
  padding: 0.45rem 0.78rem;
  cursor: pointer;
  min-height: 44px;
}
@media (max-width: 940px) {
  .burger { display: block; }
  .head__lock { display: none; }
  .nav {
    display: none;
    order: 3;
    width: 100%;
    margin-left: 0;
    flex-direction: column;
    align-items: flex-start;
    gap: 0;
    margin-top: var(--s-3);
    padding-top: var(--s-2);
    border-top: 1px solid var(--rule-d-hair);
  }
  .nav.is-open { display: flex; }
  .nav a { font-size: 0.78rem; padding: 0.62rem 0; width: 100%; }
  .nav a::after { display: none; }
  .lang { margin-top: var(--s-3); }
}

/* ------------------------------------------------------ 07 THE INK FLOOD CTA
   Solid amber at rest, because this button carries a 38 EUR kit. On hover the
   ink floods up from the baseline and the label resurfaces in amber. */

.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  isolation: isolate;
  overflow: hidden;
  min-height: 48px;
  padding: 1rem 1.85rem;
  border: 1px solid var(--amber);
  background: var(--amber);
  color: var(--ink);                    /* 7.38:1 AA */
  font-family: var(--mono);
  font-size: var(--t-label);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  cursor: pointer;
  transition: color 180ms linear 140ms;
}
.btn::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--ink);
  transform: scaleY(0);
  transform-origin: 0 100%;
  transition: transform var(--d-base) var(--ease-settle);
}
/* the meniscus flash at the instant the flood tops out */
.btn::after {
  content: "";
  position: absolute;
  left: 0; right: 0; top: 0;
  height: 1px;
  z-index: -1;
  background: oklch(0.62 0.09 74);
  opacity: 0;
}
/* .band a would otherwise win on specificity and paint the label amber on amber */
.band .btn, .on-ink .btn { color: var(--ink); }
.btn:hover, .btn:focus-visible,
.band .btn:hover, .band .btn:focus-visible,
.on-ink .btn:hover, .on-ink .btn:focus-visible { color: var(--amber); }
.btn:hover::before, .btn:focus-visible::before { transform: scaleY(1); }
.btn:hover::after, .btn:focus-visible::after { animation: meniscus 200ms var(--ease-light) 300ms; }
.btn:active::before { transform: scaleY(0.97); transition-duration: 120ms; }

@keyframes meniscus { from { opacity: 1; } to { opacity: 0; } }

/* the quiet one. There is only ever one filled CTA on screen. */
.btn--ghost {
  background: transparent;
  border-color: var(--rule-strong);
  color: var(--on-paper);
}
.btn--ghost::before { background: var(--on-paper); }
.btn--ghost:hover, .btn--ghost:focus-visible { color: var(--paper); }
.band .btn--ghost, .on-ink .btn--ghost { border-color: var(--rule-d-strong); color: var(--on-ink); }
.band .btn--ghost::before, .on-ink .btn--ghost::before { background: var(--on-ink); }
.band .btn--ghost:hover, .band .btn--ghost:focus-visible,
.on-ink .btn--ghost:hover, .on-ink .btn--ghost:focus-visible { color: var(--ink); }

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

/* --------------------------------------------------------------- 08 PLATES
   Law 8. Permanent furniture: ground, 12px mat, asymmetric letterpress frame,
   caption rule, mono caption. Only the contents of the mat ever change — which
   is how a photograph can drop in later without anything being redesigned. */

.plate { display: block; color: inherit; }

.plate__mount {
  position: relative;
  background: var(--paper-deep);
  padding: var(--mat);
  /* the asymmetric letterpress frame — light from the upper left */
  border-top: 1px solid var(--rule-strong);
  border-left: 1px solid var(--rule-strong);
  border-right: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
}
.band .plate__mount, .on-ink .plate__mount {
  background: var(--ink-2);
  border-top-color: var(--rule-d-strong);
  border-left-color: var(--rule-d-strong);
  border-right-color: var(--rule-d);
  border-bottom-color: var(--rule-d);
}

.plate__win {
  position: relative;
  overflow: hidden;
  background: var(--paper-deeper);
  aspect-ratio: 16 / 10;
}
.band .plate__win, .on-ink .plate__win { background: var(--ink-3); }
.plate__win--product { aspect-ratio: 4 / 5; }
.plate__win--recipe  { aspect-ratio: 1 / 1; }
.plate__win--article { aspect-ratio: 3 / 2; }
.plate__win--wide    { aspect-ratio: 21 / 9; }
.plate__win > svg, .plate__win > canvas { width: 100%; height: 100%; }

/* the photo endgame: it drops inside the same mat and the curve stays on top */
.plate__photo {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
}
.plate__win--has-photo > svg { position: absolute; inset: 0; }

.plate__cap {
  margin-top: var(--s-3);
  padding-top: var(--s-2);
  border-top: 1px solid var(--rule);
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem 0.9rem;
  font-family: var(--mono);
  font-size: var(--t-micro);
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--on-paper-faint);
  font-variant-numeric: tabular-nums slashed-zero;
}
.band .plate__cap, .on-ink .plate__cap { border-top-color: var(--rule-d); color: var(--on-ink-faint); }
.plate__cap .is-illustrative { opacity: 0.75; letter-spacing: 0.16em; }
.plate__cap .is-terminated { color: var(--danger); }
.band .plate__cap .is-terminated { color: oklch(0.72 0.13 30); }

/* Plate A — the gravity curve */
.curve { width: 100%; height: 100%; overflow: visible; }
.curve__grid { fill: none; stroke: var(--rule-hair); stroke-width: 0.5; }
.band .curve__grid { stroke: var(--rule-d-hair); }
.curve__axis { fill: none; stroke: var(--rule); stroke-width: 1; }
.band .curve__axis { stroke: var(--rule-d); }
.curve__area { fill: var(--on-paper); opacity: 0.06; }
.band .curve__area { fill: var(--on-ink); opacity: 0.08; }
.curve__line {
  fill: none;
  stroke: var(--on-paper);
  stroke-width: 1.5;
  stroke-linejoin: round;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
}
.band .curve__line { stroke: var(--on-ink); }
.curve--terminated .curve__line { stroke: var(--danger); stroke-dasharray: 4 3; }
.curve__tick {
  font-family: var(--mono);
  font-size: 7px;
  letter-spacing: 0.06em;
  fill: var(--on-paper-faint);
  font-variant-numeric: tabular-nums slashed-zero;
}
.band .curve__tick { fill: var(--on-ink-faint); }
.curve__head { fill: var(--amber); }
/* Each dot is a reading that was actually taken. Nothing is claimed between them. */
.curve__pt { fill: var(--on-paper); }
.band .curve__pt { fill: var(--on-ink); }
.curve--terminated .curve__pt { fill: var(--danger); }
.curve__lead { fill: none; stroke: var(--rule-strong); stroke-width: 1; }
.band .curve__lead { stroke: var(--rule-d-strong); }

/* --- the bench --------------------------------------------------------------
   What is fermenting today. Ruled rows rather than cards, because a batch on
   the floor is a log entry, not a product. */
.bench { display: grid; gap: 1.4rem; }
.bench__b {
  border-top: 1px solid var(--rule-d);
  padding-top: 1rem;
}
.band .bench__b { border-top-color: var(--rule-d); }
.bench__b h3 {
  font-family: var(--serif);
  font-size: var(--t-h3);
  font-weight: 600;
  margin: .3rem 0 .5rem;
}
.bench__list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.bench__list li {
  border-top: 1px solid var(--rule);
  padding: .7rem 0;
  display: flex;
  flex-wrap: wrap;
  gap: .3rem .8rem;
  align-items: baseline;
}
.bench__list li:last-child { border-bottom: 1px solid var(--rule); }
/* The blank state carries real information, so it is set as prose and not as
   an apology in small grey type. */
.bench__none {
  border-left: 2px solid var(--rule-strong);
  padding-left: 1.1rem;
  margin: 0;
  max-width: 60ch;
  color: var(--on-paper-muted);
}

/* --- search ----------------------------------------------------------------
   A panel rather than a tenth nav item: the nav is already the longest thing in
   the header, and search is a mode you enter, not a place you go. */
.srch__open {
  font: inherit;
  font-family: var(--mono);
  font-size: var(--t-label);
  letter-spacing: .11em;
  text-transform: uppercase;
  background: none;
  border: 1px solid var(--rule-d);
  color: var(--on-ink-muted);
  padding: .34rem .6rem;
  cursor: pointer;
  margin-left: auto;
}
.srch__open:hover { color: var(--on-ink); border-color: var(--rule-d-strong); }
.srch__open:focus-visible { outline: 2px solid var(--amber); outline-offset: 2px; }

.srch {
  border-top: 1px solid var(--rule-d);
  background: var(--ink-2);
}
.srch__in {
  max-width: 62rem;
  margin: 0 auto;
  padding: 1.1rem var(--gutter) 1.6rem;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: .7rem .8rem;
}
.srch__lbl {
  grid-column: 1 / -1;
  font-family: var(--mono);
  font-size: var(--t-micro);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--on-ink-faint);
}
.srch__q {
  font: inherit;
  font-size: var(--t-lede);
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--rule-d-strong);
  color: var(--on-ink);
  padding: .45rem 0;
  min-width: 0;
}
.srch__q::placeholder { color: var(--on-ink-faint); }
.srch__q:focus-visible { outline: none; border-bottom-color: var(--amber); }
.srch__close {
  font-family: var(--mono);
  font-size: var(--t-micro);
  letter-spacing: .11em;
  text-transform: uppercase;
  background: none;
  border: 1px solid var(--rule-d);
  color: var(--on-ink-faint);
  padding: .4rem .6rem;
  cursor: pointer;
}
.srch__close:hover { color: var(--on-ink); }
.srch__close:focus-visible { outline: 2px solid var(--amber); outline-offset: 2px; }

.srch__hint, .srch__count, .srch__none {
  grid-column: 1 / -1;
  font-family: var(--mono);
  font-size: var(--t-micro);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--on-ink-faint);
  margin: 0;
}
.srch__out { grid-column: 1 / -1; }
.srch__list {
  list-style: none;
  margin: .7rem 0 0;
  padding: 0;
  max-height: 58vh;
  overflow-y: auto;
}
.srch__hit {
  display: grid;
  gap: .12rem;
  padding: .7rem 0;
  border-top: 1px solid var(--rule-d-hair);
  text-decoration: none;
  color: var(--on-ink);
}
.srch__hit:hover { background: oklch(1 0 0 / 0.03); }
.srch__hit:focus-visible { outline: 2px solid var(--amber); outline-offset: -2px; }
.srch__where {
  font-family: var(--mono);
  font-size: var(--t-micro);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--amber);
}
.srch__title { font-size: 1.02rem; }
.srch__snip { font-size: .88rem; color: var(--on-ink-muted); }
.srch mark {
  background: var(--amber-hair);
  color: var(--on-ink);
  padding: 0 .1em;
}
@media (max-width: 640px) {
  .srch__in { grid-template-columns: minmax(0, 1fr); }
  .srch__close { justify-self: start; }
}

/* --- strains, as used ------------------------------------------------------
   A record of what each packet actually did here, so it reads as a log rather
   than as a product listing. */
.strains { display: grid; gap: 1.6rem; }
.strain__name { color: var(--on-paper-muted); margin: 0 0 .5rem; }
.strain__list { list-style: none; margin: 0; padding: 0; }
.strain__list li {
  border-top: 1px solid var(--rule-hair);
  padding: .55rem 0;
  display: flex;
  flex-wrap: wrap;
  gap: .25rem .7rem;
  align-items: baseline;
}
.strain__list li:last-child { border-bottom: 1px solid var(--rule-hair); }
.strain__end {
  font-family: var(--mono);
  font-size: .68rem;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--on-paper-faint);
}
/* the batches that cannot answer, stated rather than omitted */
.strain__gap {
  border-left: 2px solid var(--rule-strong);
  padding-left: 1.1rem;
  margin: .4rem 0 0;
  max-width: 58ch;
  color: var(--on-paper-muted);
  font-size: .95rem;
}

/* --- PLATE E: the whole archive on one axis ---------------------------------
   Same vocabulary as the single-batch curve, so the two read as one family.
   The 1.000 line is drawn heavier than the other gridlines because it is the
   line half this archive lands on, and that is the point of the plate. */
.arc { width: 100%; height: 100%; overflow: visible; }
.arc__grid { fill: none; stroke: var(--rule-hair); stroke-width: 0.5; }
.band .arc__grid { stroke: var(--rule-d-hair); }
.arc__ref { stroke: var(--amber-dark); stroke-width: 1; }
.band .arc__ref { stroke: var(--amber); }
.arc__axis { fill: none; stroke: var(--rule); stroke-width: 1; }
.band .arc__axis { stroke: var(--rule-d); }
.arc__span {
  fill: none;
  stroke: var(--on-paper);
  stroke-width: 1.5;
  stroke-linecap: round;
  opacity: 0.55;
  vector-effect: non-scaling-stroke;
}
.band .arc__span { stroke: var(--on-ink); }
/* the two that went the wrong way get the same red the terminated curve gets */
.arc__b--up .arc__span { stroke: var(--danger); opacity: 1; stroke-dasharray: 4 3; }
.arc__pt { fill: var(--on-paper); }
.band .arc__pt { fill: var(--on-ink); }
.arc__pt--og { opacity: 0.4; }
.arc__b--up .arc__pt { fill: var(--danger); opacity: 1; }
.arc__tick {
  font-family: var(--mono);
  font-size: 7px;
  letter-spacing: 0.06em;
  fill: var(--on-paper-faint);
  font-variant-numeric: tabular-nums slashed-zero;
}
.band .arc__tick { fill: var(--on-ink-faint); }
.arc__tick--foot { font-size: 6px; letter-spacing: 0.14em; }

/* self-inking on first sight */
.curve__line, .dwg-p {
  stroke-dasharray: 100;
  stroke-dashoffset: 100;
}
.is-drawn .curve__line, .is-drawn .dwg-p {
  animation: ink var(--d-draw) var(--ease-settle) forwards;
  animation-delay: calc(var(--i, 0) * 80ms);
}
.curve__anno, .dwg-anno { opacity: 0; }
.is-drawn .curve__anno, .is-drawn .dwg-anno {
  animation: fade 300ms var(--ease-rise) var(--d-draw) forwards;
}
@keyframes ink { to { stroke-dashoffset: 0; } }
@keyframes fade { to { opacity: 1; } }

/* Plate B — technical drawings */
.dwg { width: 100%; height: 100%; color: var(--on-paper-muted); overflow: visible; }
.band .dwg, .on-ink .dwg { color: var(--on-ink-muted); }
.dwg-p { fill: none; stroke: currentColor; stroke-width: 1.25; vector-effect: non-scaling-stroke; }
.dwg-dim { fill: none; stroke: var(--rule); stroke-width: 1; }
.band .dwg-dim { stroke: var(--rule-d); }
.dwg-fill { fill: var(--amber-hair); stroke: none; }
.dwg-label {
  font-family: var(--mono);
  font-size: 7px;
  letter-spacing: 0.12em;
  fill: var(--on-paper-faint);
  text-transform: uppercase;
}
.band .dwg-label { fill: var(--on-ink-faint); }

/* --------------------------------------------------------------- 09 CARDS */

.card {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--paper-deep);
  border-top: 1px solid var(--rule-strong);
  border-left: 1px solid var(--rule-strong);
  border-right: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
  transition: border-color var(--d-base) var(--ease-settle);
}
.card:hover, .card:focus-within { border-color: var(--amber-dim); }
.card__body { padding: clamp(1rem, 1.6vw, 1.5rem); display: flex; flex-direction: column; gap: 0.45rem; flex: 1; }
.card__body > h3 { margin: 0; }
.card__spacer { flex: 1; }
.band .card, .card--dark {
  background: var(--ink-2);
  border-top-color: var(--rule-d-strong);
  border-left-color: var(--rule-d-strong);
  border-right-color: var(--rule-d);
  border-bottom-color: var(--rule-d);
  color: var(--on-ink);
}
.band .card p, .card--dark p { color: var(--on-ink-muted); }
a.card { color: inherit; }
a.card h3 { transition: color var(--d-fast) linear; }
a.card:hover h3, a.card:focus-visible h3 { color: var(--amber-dark); }
.band a.card:hover h3 { color: var(--amber); }

/* ----------------------------------------------------- 10 THE CARD CATALOGUE
   Ruled rows, not rectangles. Index pages that must scale use this instead of
   a grid of tiles. */

.cat { border-top: 1px solid var(--rule-strong); }
.band .cat { border-top-color: var(--rule-d-strong); }
.cat__row { border-bottom: 1px solid var(--rule-hair); }
.band .cat__row { border-bottom-color: var(--rule-d-hair); }
.cat__row:nth-child(4n) { background: var(--paper-deep); }
.band .cat__row:nth-child(4n) { background: var(--ink-2); }

.cat__head {
  display: grid;
  grid-template-columns: 74px 1fr 124px 104px 84px;
  align-items: center;
  gap: var(--s-4);
  width: 100%;
  padding: 1.05rem 0.75rem;
  min-height: 62px;
  background: none;
  border: 0;
  text-align: left;
  font: inherit;
  color: inherit;
  cursor: pointer;
  transition: background-color var(--d-fast) linear;
}
.cat__head:hover { background: var(--paper-deep); }
.band .cat__head:hover { background: var(--ink-2); }
.cat__no { font-family: var(--mono); font-size: var(--t-micro); letter-spacing: 0.1em; color: var(--on-paper-faint); font-variant-numeric: tabular-nums slashed-zero; }
.band .cat__no { color: var(--on-ink-faint); }
.cat__title { font-family: var(--serif); font-size: 1.3rem; line-height: 1.14; letter-spacing: -0.008em; }
.cat__meta { font-family: var(--mono); font-size: var(--t-micro); letter-spacing: 0.11em; text-transform: uppercase; color: var(--on-paper-faint); font-variant-numeric: tabular-nums slashed-zero; }
.band .cat__meta { color: var(--on-ink-faint); }
.cat__abv { text-align: right; }

.cat__panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 720ms var(--ease-settle);
}
.cat__row[data-open="true"] .cat__panel { grid-template-rows: 1fr; }
.cat__panel > div { overflow: hidden; }
.cat__inner {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: var(--s-6);
  padding: 0 0.75rem var(--s-6);
}
@media (max-width: 900px) {
  .cat__head { grid-template-columns: 60px 1fr 74px; }
  .cat__style, .cat__date { display: none; }
  .cat__inner { grid-template-columns: 1fr; }
}

/* -------------------------------------------------------- 11 DATA & TABLES */

.tbl { width: 100%; border-collapse: collapse; font-size: var(--t-small); }
.tbl th {
  font-family: var(--mono);
  font-size: var(--t-label);
  font-weight: 400;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--on-paper-faint);
  text-align: left;
  padding: 0.45rem 0.8rem 0.45rem 0;
  border-bottom: 1px solid var(--rule-strong);
  white-space: nowrap;
}
.tbl td {
  padding: 0.58rem 0.8rem 0.58rem 0;
  border-bottom: 1px solid var(--rule-hair);
  vertical-align: top;
}
.tbl td:first-child { white-space: nowrap; font-size: 0.85rem; }
.tbl tr:last-child td { border-bottom: 0; }
.band .tbl th { color: var(--on-ink-faint); border-bottom-color: var(--rule-d-strong); }
.band .tbl td { border-bottom-color: var(--rule-d-hair); }
.tbl-wrap { overflow-x: auto; }

.batchline {
  font-family: var(--mono);
  font-size: var(--t-micro);
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--on-paper-faint);
  border-top: 1px solid var(--rule);
  padding-top: 0.5rem;
  margin-top: 0.55rem;
  font-variant-numeric: tabular-nums slashed-zero;
}
.band .batchline, .card--dark .batchline { color: var(--on-ink-faint); border-top-color: var(--rule-d); }

/* --------------------------------------------------------------- 12 FORMS */

.tool {
  background: var(--paper-deep);
  border-top: 1px solid var(--rule-strong);
  border-left: 1px solid var(--rule-strong);
  border-right: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
  padding: clamp(1.25rem, 2.8vw, 2.25rem);
}
.tool + .tool { margin-top: var(--s-6); }

.fields { display: flex; flex-wrap: wrap; gap: var(--s-5); margin-bottom: var(--s-5); }
.field { display: flex; flex-direction: column; gap: 0.3rem; flex: 1 1 10.5rem; min-width: 0; }
.field > label {
  font-family: var(--mono);
  font-size: var(--t-label);
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--on-paper-faint);
}
.field input, .field select {
  font-size: 1rem;
  padding: 0.7rem 0.15rem;
  border: 0;
  border-bottom: 1px solid var(--rule-strong);
  background: transparent;
  color: var(--on-paper);
  min-height: 44px;
  transition: border-color var(--d-base) var(--ease-rise);
}
.field input:focus, .field select:focus { outline: none; border-bottom-color: var(--amber-dark); }
.field .hint { font-size: 0.8rem; color: var(--on-paper-faint); }

.result { margin-top: var(--s-5); padding-top: var(--s-4); border-top: 1px solid var(--rule-strong); }
.result[hidden] { display: none; }
.result__value { margin: 0.3rem 0 0.45rem; color: var(--on-paper); }
.result__value .u { font-size: 0.4em; }
.result p { color: var(--on-paper-muted); font-size: var(--t-small); }
/* The error state reports; it does not scold. */
.result.is-error { border-top-color: var(--danger); }
.result.is-error .result__value { color: var(--danger); }

/* the gauge */
.gauge { position: relative; margin-top: var(--s-4); height: 46px; }
.gauge__rule {
  position: absolute;
  left: 0; right: 0; top: 18px;
  height: 10px;
  background-image: repeating-linear-gradient(90deg, var(--rule-strong) 0 1px, transparent 1px 5%);
}
.gauge__major {
  position: absolute;
  left: 0; right: 0; top: 14px;
  height: 14px;
  background-image: repeating-linear-gradient(90deg, var(--rule-ink) 0 1px, transparent 1px 25%);
}
.gauge__needle {
  position: absolute;
  top: 8px;
  width: 1px; height: 26px;
  background: var(--amber-dark);
  transform: translateX(0);
  transition: transform 900ms var(--ease-needle);
  will-change: transform;
}
.gauge__needle::after {
  content: "";
  position: absolute;
  top: -4px; left: -2px;
  width: 5px; height: 5px;
  background: var(--amber);
}
.gauge__ceiling { position: absolute; top: 8px; width: 1px; height: 26px; background: var(--teal-dark); }
.gauge__scale {
  position: absolute;
  left: 0; right: 0; top: 32px;
  display: flex;
  justify-content: space-between;
  font-family: var(--mono);
  font-size: var(--t-micro);
  color: var(--on-paper-faint);
  font-variant-numeric: tabular-nums slashed-zero;
}

/* ------------------------------------------------------------- 13 CALLOUTS */

.note {
  border-top: 1px solid var(--rule);
  border-left: 1px solid var(--teal-dark);
  background: var(--paper-deep);
  padding: var(--s-4) var(--s-5);
  margin: var(--s-6) 0;
  font-size: var(--t-small);
  color: var(--on-paper-muted);
}
.note .label { display: block; margin-bottom: 0.3rem; color: var(--teal-dark); }
.band .note { background: var(--ink-2); border-top-color: var(--rule-d); border-left-color: var(--teal); color: var(--on-ink-muted); }
.band .note .label { color: var(--teal); }

/* --------------------------------------------------------- 14 MARGINALIA
   Law 10. A person in the margin of every page. */

.withmargin { display: grid; grid-template-columns: minmax(0, 1fr) var(--margin-col); gap: var(--s-6); }
@media (max-width: 1279px) { .withmargin { grid-template-columns: 1fr; } }

/* When the main column is a block that is currently hidden, the aside is all
   that is left; let it use the full width rather than hug a phantom column. */
.withmargin > .aside:only-child { grid-column: 1 / -1; max-width: 52ch; }

.aside {
  font-size: 0.86rem;
  line-height: 1.5;
  color: var(--on-paper-muted);
  border-left: 1px solid var(--rule);
  padding-left: var(--s-4);
  opacity: 0.72;
  transition: opacity var(--d-fast) linear, border-color var(--d-fast) linear;
}
.aside:hover, .aside:focus-within { opacity: 1; border-left-color: var(--amber-dark); }
.aside .label { display: block; margin-bottom: 0.4rem; }
.band .aside { color: var(--on-ink-muted); border-left-color: var(--rule-d); }
@media (max-width: 1279px) {
  .aside { border-left: 0; padding-left: 0; border-top: 1px solid var(--rule); padding-top: var(--s-3); margin-top: var(--s-5); opacity: 1; }
}

/* -------------------------------------------------------------- 15 FOOTER */

.foot {
  background: var(--ink);
  color: var(--on-ink-muted);
  padding-block: clamp(2.75rem, 5.5vw, 4.5rem) var(--s-5);
  border-top: 1px solid var(--rule-d);
  position: relative;
  overflow: hidden;
}
.foot__in {
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--gutter);
  display: grid;
  grid-template-columns: minmax(0, 1.7fr) repeat(2, minmax(0, 1fr));
  gap: var(--s-7) var(--s-6);
}
@media (max-width: 780px) { .foot__in { grid-template-columns: 1fr; } }
.foot .mark { display: inline-block; margin-bottom: 0.6rem; }
.foot__lockup { font-family: var(--serif); font-style: italic; font-size: 1.18rem; color: var(--on-ink); margin: 0 0 0.35rem; }
.foot nav { display: flex; flex-direction: column; gap: 0.45rem; align-items: flex-start; }
.foot nav a {
  font-family: var(--mono);
  font-size: var(--t-label);
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--on-ink-muted);
  transition: color var(--d-fast) linear;
}
.foot nav a:hover, .foot nav a:focus-visible { color: var(--amber); }

.foot__batch {
  max-width: var(--shell);
  margin: var(--s-6) auto 0;
  padding: var(--s-4) var(--gutter) 0;
  border-top: 1px solid var(--rule-d);
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 1.3rem;
  font-family: var(--mono);
  font-size: var(--t-micro);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--on-ink-faint);
  font-variant-numeric: tabular-nums slashed-zero;
}
.dot {
  display: inline-block;
  width: 4px; height: 4px;
  background: var(--amber);
  margin-right: 0.5rem;
  vertical-align: middle;
}

/* -------------------------------------------------------------- 16 REVEAL
   Law 9. A fade and at most 14px of lift. Fires once and never replays. */

.js .rv {
  opacity: 0;
  transform: translate3d(0, 14px, 0);
  transition: opacity var(--d-slow) var(--ease-rise), transform var(--d-slow) var(--ease-rise);
  transition-delay: calc(var(--i, 0) * 70ms);
}
.rv.is-in { opacity: 1; transform: none; }
.js .rv-line { transform: scaleX(0); transform-origin: left; transition: transform var(--d-slow) var(--ease-settle); transition-delay: calc(var(--i, 0) * 70ms); }
.rv-line.is-in { transform: scaleX(1); }

/* ------------------------------------------------------- 17 REDUCED MOTION */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
  }
  .rv { opacity: 1; transform: none; }
  .rv-line { transform: scaleX(1); }
  .curve__line, .dwg-p { stroke-dasharray: none; stroke-dashoffset: 0; }
  .curve__anno, .dwg-anno { opacity: 1; }
}

/* ------------------------------------------------------------ 18 UTILITIES */

.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}
.skip {
  position: absolute;
  left: var(--s-4); top: -100px;
  z-index: 200;
  background: var(--amber);
  color: var(--ink);
  font-family: var(--mono);
  font-size: var(--t-label);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  padding: 0.7rem 1.1rem;
  transition: top var(--d-fast) var(--ease-rise);
}
.skip:focus { top: var(--s-4); }
.stack > * + * { margin-top: var(--s-4); }
.stack-lg > * + * { margin-top: var(--s-6); }

@view-transition { navigation: auto; }
