/* ==========================================================================
   SONARAE: main site styles
   1 fonts       2 tokens        3 base          4 layout        5 type
   6 header      7 buttons       8 datasheet     9 bands         10 home
   11 team       12 register     13 privacy      14 footer       15 motion
   16 pointer, reduced motion, forced colors, print
   ========================================================================== */

/* ---------- 1. fonts ----------
   Gloock (SIL Open Font License, fonts/Gloock-OFL.txt) is served from this website in two files: latin, which every page uses
   (and preloads), and latin-ext, which the browser only fetches if a headline ever uses a character from that range.
   Geist and Geist Mono come from a web font service; each page's head script adds that stylesheet so it never holds up the first paint. */
@font-face {
  font-family: 'Gloock';
  src: url('./fonts/gloock-v8-latin.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Gloock';
  src: url('./fonts/gloock-v8-latin-ext.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ---------- 2. tokens ---------- */
:root {
  color-scheme: light;

  /* the five core variables */
  --bg-color: #ffffff;
  --text-color: #000000;
  --border-color: #000000;
  --accent-yellow-light: #ffd400;   /* highlighter: a fill that always carries black type */
  --accent-yellow-dark: #a67c00;    /* rule: active nav, focus, input underline, selected path */

  /* supporting roles */
  --text-muted: #4d4d4d;
  --rule-soft: #cfcfcf;
  --surface: #f4f4f4;
  --error-color: #c40018;
  --focus-color: var(--accent-yellow-dark);

  /* what a black band swaps in (light theme: black band, white type) */
  --inv-bg: #000000;
  --inv-text: #ffffff;
  --inv-muted: #bdbdbd;
  --inv-rule: #4a4a4a;

  --font-display: 'Gloock', 'Times New Roman', Times, serif;
  --font-ui: 'Geist', 'Helvetica Neue', Helvetica, Arial, sans-serif;
  --font-mono: 'Geist Mono', 'Cascadia Mono', Consolas, 'Liberation Mono', Menlo, monospace;

  --fs-display: clamp(2.5rem, 1.4rem + 6vw, 6rem);
  --fs-title: clamp(2rem, 1.2rem + 3.8vw, 4rem);
  --fs-lead: clamp(1.25rem, 1.1rem + 0.7vw, 1.625rem);
  --fs-statement: clamp(1.5rem, 1.2rem + 1vw, 2.125rem);   /* the three Gloock statements beside the Home headline */
  --fs-body: 1.0625rem;
  --fs-small: 0.875rem;
  --fs-caption: 0.8125rem;
  --lh-body: 1.65;
  --lh-caption: 1.25rem;

  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --space-7: 48px;
  --space-8: 64px;
  --section-y: clamp(64px, 9vw, 128px);

  --gutter: clamp(16px, 4vw, 48px);
  --col-gap: clamp(16px, 2vw, 32px);
  --max: 1440px;
  --header-h: 64px;
  --tap: 44px;
  --measure: 65ch;

  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --dur-fast: 0.2s;
  --dur-reveal: 0.6s;
  --dur-wipe: 0.75s;
  --reveal-y: 24px;
}

[data-theme="dark"] {
  color-scheme: dark;

  --bg-color: #000000;
  --text-color: #ffffff;
  --border-color: #ffffff;
  --accent-yellow-light: #ffd400;
  --accent-yellow-dark: #d9a400;

  --text-muted: #b3b3b3;
  --rule-soft: #333333;
  --surface: #0f0f0f;
  --error-color: #ff6b6b;

  --inv-bg: #ffffff;
  --inv-text: #000000;
  --inv-muted: #4d4d4d;
  --inv-rule: #c8c8c8;
}

/* ---------- 3. base ---------- */
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  background: var(--bg-color);
  scroll-padding-top: calc(var(--header-h) + var(--space-5));
  scrollbar-color: var(--text-color) var(--bg-color);
}
html.nav-open, html.nav-open body { overflow: hidden; }

body {
  min-height: 100vh;
  min-height: 100dvh;
  margin: 0;
  display: flex;
  flex-direction: column;
  background: var(--bg-color);
  color: var(--text-color);
  font-family: var(--font-ui);
  font-size: var(--fs-body);
  font-weight: 400;
  line-height: var(--lh-body);
  font-synthesis: none;
  font-kerning: normal;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
main { flex: 1 0 auto; }
main:focus { outline: none; }

[hidden] { display: none !important; }

h1, h2, h3, p, ul, ol, dl, dd, figure, table, fieldset { margin: 0; }
ul, ol { padding: 0; list-style: none; }
fieldset { min-width: 0; padding: 0; border: 0; }
img, svg { display: block; max-width: 100%; }
button, input { font: inherit; color: inherit; }
button { cursor: pointer; }
a { color: inherit; }

::selection { background: var(--accent-yellow-light); color: #000000; }
/* #FFDE00 (and the near-identical --accent-yellow-light) reads at 1.34:1 against white, far short of the 3:1
   a non-text focus indicator needs under WCAG 2.1 SC 1.4.11; --focus-color is Rule Gold, the same token the
   rest of the site already verified at 3.82:1 on paper and 9.26:1 on ink. Bolder now: 3px and a 4px offset. */
:focus-visible { outline: 3px solid var(--focus-color); outline-offset: 4px; }
input { caret-color: var(--accent-yellow-dark); }

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  left: var(--gutter);
  top: -100px;
  z-index: 200;
  padding: 12px 16px;
  background: var(--accent-yellow-light);
  color: #000000;
  font-weight: 600;
  text-decoration: none;
  border: 1px solid #000000;
}
.skip-link:focus { top: 8px; outline-color: #000000; }

/* ---------- 4. layout ---------- */
.container {
  width: 100%;
  max-width: var(--max);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.grid {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  column-gap: var(--col-gap);
}
.section { padding-block: var(--section-y); }
.section--ruled { position: relative; }
.section--ruled::before {              /* the section rule, drawn as a line so it can be revealed */
  content: '';
  position: absolute;
  inset: 0 0 auto 0;
  height: 1px;
  background: var(--border-color);
  transform-origin: 0 50%;
  transition: transform 1s var(--ease-out);
}

/* ---------- 5. type ---------- */
.display, .title {
  font-family: var(--font-display);
  font-weight: 400;
  letter-spacing: -0.02em;
  text-wrap: balance;
  overflow-wrap: break-word;
}
.display { font-size: var(--fs-display); line-height: 0.96; }
/* 1.14 leaves a clear gap between Gloock's descenders (g, p, y drop 0.22em) and the capitals and ascenders of the next line */
.title { font-size: var(--fs-title); line-height: 1.14; }
.lead { font-size: var(--fs-lead); line-height: 1.35; }
.muted { color: var(--text-muted); }
p { text-wrap: pretty; }

.link {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
  transition: text-decoration-color var(--dur-fast) ease, text-decoration-thickness var(--dur-fast) ease;
}

/* The highlighter changes only the ground under the words: a marked word or figure keeps its parent's face, size and weight. */
mark,
.mark,
.highlight {
  display: inline-block;
  padding: 0 0.12em 0.06em;
  background: var(--accent-yellow-light);
  color: #000000;
  font-family: inherit;
  font-size: inherit;
  font-weight: inherit;
  line-height: inherit;
}
/* In a display headline the block leaves the same room above the ascenders as below the baseline (Gloock's ascenders
   stand 0.79em tall, and the 0.96 leading puts its baseline 0.855em into the line), so the word sits in the middle of it. */
.display .mark { padding: 0.04em 0.12em 0; }
/* a marked word or figure inside a headline stays shorter than the line pitch, so marks on neighbouring lines never touch */
.title .mark {
  padding: 0.04em 0.1em 0.02em;
  margin-block: 0.03em;
}
.title .line { display: block; }
/* A marked word with a descender (g, j, p, q, y) in a headline takes .mark--tail: the block deepens to hold the tail, so it
   never hangs below the yellow as black on a dark page. Gloock's descenders drop 0.22em below the baseline. */
.display .mark--tail { padding-bottom: 0.16em; }
.title .mark--tail { padding-bottom: 0.2em; }

/* ---------- 6. header + navigation ---------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--bg-color);
  border-bottom: 1px solid var(--border-color);
}
.site-header__inner {
  display: flex;
  align-items: stretch;
  gap: var(--space-5);
  max-width: var(--max);
  height: var(--header-h);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.brand {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-right: auto;
  font-family: var(--font-display);
  font-size: 1.375rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--text-color);
}
/* the logo mark sits to the left of the wordmark; its own colours read on both the white and the black sheet */
.brand__mark { display: block; flex: none; width: auto; height: 30px; }

.site-nav { display: flex; }
.site-nav__list { display: flex; align-items: stretch; gap: clamp(20px, 2.6vw, 40px); }
.site-nav__list li { display: flex; }
.site-nav a {
  position: relative;
  display: flex;
  align-items: center;
  padding-top: 2px;
  font-size: 0.9375rem;
  font-weight: 500;
  text-decoration: none;
  color: var(--text-color);
}
.site-nav a::after {                   /* 2px underline that overlaps the header rule */
  content: '';
  position: absolute;
  inset: auto 0 -1px 0;
  height: 2px;
  background: var(--text-color);
  transform: scaleX(0);
  transform-origin: right;
  transition: transform 0.35s var(--ease-out);
}
.site-nav a:focus-visible::after { transform: scaleX(1); transform-origin: left; }
.site-nav a[aria-current="page"]::after { background: var(--accent-yellow-dark); transform: scaleX(1); }

.header-tools { display: flex; align-items: center; gap: var(--space-3); }

.theme-toggle, .menu-toggle {
  height: var(--tap);
  padding: 0;
  background: transparent;
  color: var(--text-color);
  border: 1px solid var(--border-color);
  border-radius: 0;
  transition: background-color var(--dur-fast) ease, color var(--dur-fast) ease;
}
.theme-toggle { display: grid; place-items: center; width: var(--tap); }
.theme-toggle svg {
  grid-area: 1 / 1;
  width: 20px;
  height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.75;
  stroke-linecap: square;
  stroke-linejoin: miter;
  transition: opacity 0.3s var(--ease-out), transform 0.45s var(--ease-out);
}
.theme-toggle .icon-sun { opacity: 0; transform: rotate(-70deg) scale(0.6); }
[data-theme="dark"] .theme-toggle .icon-moon { opacity: 0; transform: rotate(70deg) scale(0.6); }
[data-theme="dark"] .theme-toggle .icon-sun { opacity: 1; transform: none; }

.menu-toggle {
  display: none;
  padding-inline: 14px;
  font-size: var(--fs-small);
  font-weight: 600;
  letter-spacing: 0.02em;
}

@media (max-width: 899px) {
  .js .menu-toggle { display: inline-flex; align-items: center; }
  .js .site-nav {
    position: fixed;
    inset: calc(var(--header-h) + 1px) 0 0 0;
    z-index: 99;
    display: block;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: var(--space-5) var(--gutter) var(--space-8);
    background: var(--bg-color);
    visibility: hidden;
    opacity: 0;
    transition: opacity 0.2s ease, visibility 0s linear 0.2s;
  }
  .js .site-header[data-nav-open] .site-nav {
    visibility: visible;
    opacity: 1;
    transition: opacity 0.25s ease;
  }
  .js .site-nav__list { flex-direction: column; gap: 0; }
  .js .site-nav__list li { display: block; }
  .js .site-nav a {
    display: block;
    padding: 20px 0 18px;
    border-bottom: 1px solid var(--border-color);
    font-family: var(--font-display);
    font-size: clamp(2rem, 9vw, 2.75rem);
    font-weight: 400;
    line-height: 1;
    letter-spacing: -0.01em;
  }
  .js .site-nav a::after { display: none; }
  .js .site-nav a[aria-current="page"] { border-bottom: 2px solid var(--accent-yellow-dark); padding-bottom: 17px; }

  /* without JavaScript the links stay visible and simply wrap under the brand */
  html:not(.js) .site-header__inner { height: auto; flex-wrap: wrap; padding-block: var(--space-2); row-gap: 0; }
  html:not(.js) .site-nav { order: 3; width: 100%; }
  html:not(.js) .site-nav__list { flex-wrap: wrap; column-gap: var(--space-5); }
  html:not(.js) .site-nav a { min-height: 44px; white-space: nowrap; }
  html:not(.js) .site-header { position: relative; }   /* the wrapped links make it taller: it scrolls away with the page instead of covering it */
}
html:not(.js) .theme-toggle { display: none; }   /* switching themes needs JavaScript: a button that cannot work is not shown */
@media (max-width: 380px) {
  .site-header__inner { gap: var(--space-3); }
  .header-tools { gap: var(--space-2); }
  .brand { gap: 8px; font-size: 1.25rem; letter-spacing: 0.12em; }
  .brand__mark { height: 26px; }
}

/* ---------- 7. buttons ---------- */
.btn {
  --btn-bg: var(--bg-color);
  --btn-fg: var(--text-color);
  --btn-border: var(--border-color);
  --btn-hover-bg: var(--text-color);
  --btn-hover-fg: var(--bg-color);
  /* the wipe (::before) does the visible work; the real background swaps when it lands, so the state never depends on it */
  --btn-in: color 0.25s var(--ease-out) 0.09s, background-color 0s linear 0.45s, transform 0.12s ease;
  position: relative;
  isolation: isolate;
  overflow: hidden;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  min-height: 52px;
  padding: 0 var(--space-6);
  background: var(--btn-bg);
  color: var(--btn-fg);
  border: 1px solid var(--btn-border);
  border-radius: 0;
  font-size: 1rem;
  font-weight: 600;
  line-height: 1;
  text-decoration: none;
  cursor: pointer;
  transition: color 0.25s var(--ease-out) 0.09s, transform 0.12s ease;
}
.btn::before {                         /* the hover fill wipes in from the left and leaves to the right */
  content: '';
  position: absolute;
  inset: -1px;
  z-index: -1;
  background: var(--btn-hover-bg);
  transform: scaleX(0);
  transform-origin: right;
  transition: transform 0.45s var(--ease-out);
}
.btn:focus-visible { color: var(--btn-hover-fg); background-color: var(--btn-hover-bg); transition: var(--btn-in); }
.btn:focus-visible::before { transform: scaleX(1); transform-origin: left; }
.btn:active { transform: translateY(1px); }
.btn__icon {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.75;
  transition: transform 0.3s var(--ease-out);
}
.btn:focus-visible .btn__icon { transform: translateX(3px); }

.btn--primary { --btn-bg: var(--accent-yellow-light); --btn-fg: #000000; --btn-border: #000000; }
.btn--solid {
  --btn-bg: var(--text-color);
  --btn-fg: var(--bg-color);
  --btn-hover-bg: var(--accent-yellow-light);
  --btn-hover-fg: #000000;
}

/* ---------- 8. datasheet parts ---------- */
.figure figcaption,
.table caption {
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  color: var(--text-muted);
}
.figure figcaption { padding-top: var(--space-3); }
.figure figcaption strong,
.table caption strong { color: var(--text-color); font-weight: 600; }

.table {
  width: 100%;
  border-collapse: collapse;
  font-variant-numeric: tabular-nums;
}
.table caption { caption-side: top; padding-bottom: var(--space-3); text-align: left; }
.table th, .table td {
  padding: var(--space-4) var(--space-5) var(--space-4) 0;
  text-align: left;
  vertical-align: top;
  border-top: 1px solid var(--border-color);
  line-height: 1.4;
}
.table th { width: 34%; font-size: var(--fs-small); font-weight: 600; }
.table td { font-weight: 400; overflow-wrap: anywhere; }
.table td:last-child { padding-right: 0; }
.table tr:last-child > * { border-bottom: 1px solid var(--border-color); }
.table--data td { font-family: var(--font-mono); font-size: 0.9375rem; }

/* Figure 1: raw records in, enriched leads out. Two drawings of the same figure: a left-to-right conveyor where the figure is
   wide enough for its labels to read at 12px or more, and a top-down version for narrower screens, where the records drop into
   their lanes and the outputs hang below. Both scale with the figure and never scroll sideways. Without motion (no JavaScript,
   reduced motion, print) each shows the raw records and the finished leads at once; home.js moves the raw squares along the
   lines and ends each run exactly on the finished leads, which it hides while it runs. */
.pipe { min-width: 0; overflow: hidden; border: 1px solid var(--border-color); background: var(--bg-color); }
.pipe__svg { display: block; width: 100%; max-width: 100%; height: auto; }
.pipe__svg--tall { display: none; max-width: 440px; margin-inline: auto; }
@media (max-width: 899px) {
  .pipe__svg--wide { display: none; }
  .pipe__svg--tall { display: block; }
}
.pipe__lines path, .pipe__brackets path { fill: none; stroke: var(--text-color); stroke-linejoin: miter; }
.pipe__lines path { stroke-width: 1.5; }
.pipe__lines .pipe__row { stroke: var(--rule-soft); }
.pipe__brackets path { stroke-width: 4; }
.pipe__slot { fill: var(--bg-color); stroke: var(--rule-soft); stroke-width: 1.5; }
.pipe__sq { fill: var(--text-color); stroke: var(--text-color); stroke-width: 1.5; }
.pipe__sq--on { fill: var(--accent-yellow-light); }
.pipe__text text { fill: var(--text-color); font-family: var(--font-ui); font-size: 15px; font-weight: 600; letter-spacing: 0.1em; }
.pipe__text .pipe__out { font-size: 24px; font-family: var(--font-display); font-weight: 400; letter-spacing: 0.04em; }
.pipe__svg--tall .pipe__text text { font-size: 14.5px; }
.pipe__svg--tall .pipe__text .pipe__out { font-size: 18px; }
html.g-on .pipe__done { display: none; }
@media print {
  html.g-on .pipe__done { display: inline; }
  .pipe__raw .pipe__sq { transform: none !important; opacity: 1 !important; fill: var(--text-color) !important; }
}

/* Figure 2: five batches of 25 */
.batch__rows { border-bottom: 1px solid var(--border-color); }
.batch__row {
  display: grid;
  grid-template-columns: 5.5rem minmax(0, 1fr) 6rem;
  align-items: center;
  gap: var(--space-4);
  padding-block: var(--space-3);
  border-top: 1px solid var(--border-color);
}
.batch__label { font-size: var(--fs-small); font-weight: 600; }
.batch__count { font-family: var(--font-mono); font-size: var(--fs-caption); text-align: right; color: var(--text-muted); }
.batch__cells {
  display: grid;
  grid-template-columns: repeat(25, minmax(0, 1fr));
  gap: clamp(2px, 0.3vw, 4px);
}
.batch__cells i {
  display: block;
  aspect-ratio: 1;
  background: var(--text-color);
  transition:
    opacity 0.3s var(--ease-out) calc(var(--n, 0) * 16ms + var(--row, 0) * 40ms),
    background-color var(--dur-fast) ease;
}
.batch__sum {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 0.6em;
  padding-top: var(--space-3);
  font-family: var(--font-mono);
  font-size: 0.9375rem;
}
.batch__sum .mark { padding: 0.15em 0.6em; }

/* Figures 3 and 4: wire diagrams (rows are 72px tall; the SVG stretches its 168 unit grid to 216px so paths meet the box centres) */
.mux { position: relative; }
.mux__radio { position: absolute; width: 1px; height: 1px; margin: 0; opacity: 0; pointer-events: none; }
.wire {
  display: grid;
  grid-template-columns: minmax(7.5rem, 11rem) minmax(2rem, 1fr) minmax(6rem, 10rem);
  align-items: center;
}
.wire--fan { grid-template-columns: minmax(6rem, 9rem) minmax(2rem, 1fr) minmax(9rem, 16rem); }
.wire__col { display: flex; flex-direction: column; justify-content: center; min-height: 216px; }
.wire__item, .wire__node {
  display: flex;
  align-items: center;
  padding-inline: 18px;
  border: 1px solid var(--border-color);
  font-size: 1rem;
  font-weight: 500;
  line-height: 1.15;
}
.wire__item {
  height: 52px;
  margin-block: 10px;
  background: var(--bg-color);
  transition: background-color var(--dur-fast) ease, color var(--dur-fast) ease;
}
label.wire__item { cursor: pointer; }
.wire__node { height: 52px; background: var(--text-color); color: var(--bg-color); font-weight: 600; }
.wire__svg { width: 100%; height: 216px; overflow: visible; }
.wire__path, .wire__out {
  fill: none;
  stroke: var(--border-color);
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
  shape-rendering: crispEdges;
  transition: stroke var(--dur-fast) ease;
}
.wire__out { stroke: var(--accent-yellow-dark); stroke-width: 3; }
/* A flat schematic reads as live, not printed, once a short dash keeps travelling along every line: a slow drift
   on the plain paths, a brisker current on the gold output line. Runs only once GSAP's own motion has taken over
   the page (html.g-on), which already means no reduced-motion preference is set. */
html.g-on .wire__path { stroke-dasharray: 1 5; animation: wireDrift 2.6s linear infinite; }
html.g-on .wire__out { stroke-dasharray: 6 6; animation: wireFlow 0.9s linear infinite; }
@keyframes wireDrift { to { stroke-dashoffset: -12; } }
@keyframes wireFlow { to { stroke-dashoffset: -12; } }

#provider-anthropic:checked ~ .wire label[for="provider-anthropic"],
#provider-gemini:checked ~ .wire label[for="provider-gemini"],
#provider-openai:checked ~ .wire label[for="provider-openai"] { background: var(--accent-yellow-light); color: #000000; }

#provider-anthropic:checked ~ .wire .wire__path--1,
#provider-gemini:checked ~ .wire .wire__path--2,
#provider-openai:checked ~ .wire .wire__path--3 { stroke: var(--accent-yellow-dark); stroke-width: 3; }

#provider-anthropic:focus-visible ~ .wire label[for="provider-anthropic"],
#provider-gemini:focus-visible ~ .wire label[for="provider-gemini"],
#provider-openai:focus-visible ~ .wire label[for="provider-openai"] { outline: 3px solid var(--focus-color); outline-offset: 4px; }

/* ---------- 9. bands ---------- */
.band--inverse {
  --bg-color: var(--inv-bg);
  --text-color: var(--inv-text);
  --border-color: var(--inv-text);
  --text-muted: var(--inv-muted);
  --rule-soft: var(--inv-rule);
  --surface: var(--inv-bg);
  --focus-color: var(--inv-text);
  background: var(--bg-color);
  color: var(--text-color);
}
.band--yellow {
  --bg-color: var(--accent-yellow-light);
  --text-color: #000000;
  --border-color: #000000;
  --text-muted: #2b2b2b;
  --rule-soft: #8a7200;
  --surface: var(--accent-yellow-light);
  --focus-color: #000000;
  background: var(--bg-color);
  color: var(--text-color);
}
.band--yellow ::selection { background: #000000; color: var(--accent-yellow-light); }
.band--yellow .btn--solid { --btn-hover-bg: #ffffff; --btn-hover-fg: #000000; }

/* ---------- 10. home ---------- */
.hero { padding-block: clamp(40px, 7vw, 96px) clamp(48px, 7vw, 96px); }
.hero__top { align-items: start; row-gap: var(--space-6); }
.hero__title { grid-column: 1 / span 8; }
.hero__aside { grid-column: 9 / -1; display: grid; gap: var(--space-5); }
.hero__sub { font-family: var(--font-display); font-size: var(--fs-statement); font-weight: 400; line-height: 1.15; }
.hero__sub > span { display: block; padding-block: 0.3em; border-top: 1px solid var(--rule-soft); text-wrap: balance; }
.hero__sub .mark { padding: 0.04em 0.12em 0.06em; }                   /* room above the ascenders */
.hero__sub .mark--tail { padding-bottom: 0.2em; }                     /* and below the tail of the y, so it never hangs black on black */
.hero__sub > span:first-child { padding-top: 0; border-top: 0; }
.hero__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-4) var(--space-5); }
.hero__status { font-size: var(--fs-small); line-height: var(--lh-caption); color: var(--text-muted); }
.hero__figure { margin-top: clamp(40px, 6vw, 80px); }
@media (max-width: 767px) {
  .hero__top { row-gap: var(--space-7); }
  .hero__aside { gap: var(--space-6); }
  .hero__sub > span { padding-block: 0.45em; }
  .hero__actions { gap: var(--space-5); }
  .hero__figure { margin-top: var(--space-8); }
}

/* section grids: every child names its columns with --col, and all of them collapse together */
.split { row-gap: var(--space-7); align-items: start; }
.split > * { grid-column: var(--col, 1 / -1); }
.split__lead { --col: 1 / span 8; }
.split__lead--band { --col: 1 / span 7; }
.split__lead--wide { --col: 1 / span 9; }
.split__lead--narrow { --col: 1 / span 6; }
.split__copy { --col: 1 / span 5; }
.split__figure { --col: 7 / -1; }
.split__figure--narrow { --col: 8 / -1; }
.split__figure--end { --col: 5 / -1; }
.split__figure--table { --col: 8 / -1; align-self: end; }
.split__figure--full { --col: 1 / -1; }
.split__figure--center { align-self: center; }
.split__aside { --col: 8 / -1; align-self: end; }
.split__body { max-width: 46ch; display: grid; gap: var(--space-4); font-size: var(--fs-lead); line-height: 1.4; }
.split__body strong { font-weight: 600; }
.intro__title, .intro__body { --col: 1 / span 7; }
.intro__kicker { font-size: 0.75rem; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-muted); }
.intro__mark {
  --col: 9 / -1;
  grid-row: 1 / span 2;
  align-self: center;
  justify-self: end;
  width: 100%;
  max-width: 280px;
  height: auto;
}

.close__cta { --col: 9 / -1; align-self: end; display: grid; gap: var(--space-3); justify-items: start; }
.close__status { font-size: var(--fs-small); line-height: var(--lh-caption); color: var(--text-muted); }

/* ---------- 10b. home data graphs ----------
   Flat, drawn with grid and rules only. One square is one thing. Everything reads from the palette tokens, so the inverse band and the
   dark theme redraw themselves. Numbers are Geist: they are data, and are set as data. */
.count { font-variant-numeric: tabular-nums; }

/* Figure 2: sources to reconcile */
.units { display: grid; }
.units__ruler, .units__row { display: grid; grid-template-columns: 8.5rem minmax(0, 1fr) 11rem; column-gap: var(--space-5); align-items: center; }
.units__ticks {
  display: flex; justify-content: space-between; height: 26px; padding-top: 2px;
  border-right: 1px solid var(--border-color); border-bottom: 1px solid var(--border-color);
  font-family: var(--font-mono); font-size: var(--fs-caption); line-height: 1.2;
}
.units__ticks b { position: relative; font-weight: 500; }
.units__ticks b::after { content: ''; position: absolute; top: calc(100% - 6px); left: 50%; height: 6px; border-left: 1px solid var(--border-color); }
.units__ticks b:not(:first-child) { text-align: right; }
.units__row { padding-block: var(--space-4); border-bottom: 1px solid var(--rule-soft); }
.units__row:last-child { border-bottom: 1px solid var(--border-color); }
.units__label { font-size: var(--fs-small); font-weight: 600; }
.units__cells { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: clamp(3px, 0.5vw, 6px); }
.units__cells i { display: block; aspect-ratio: 1; background: var(--text-color); }
.units__cells i.is-direct { background: var(--accent-yellow-light); outline: 1px solid var(--border-color); outline-offset: -1px; }
.units__cells i.is-ghost { background: none; outline: 1px solid var(--rule-soft); outline-offset: -1px; }
.units__value { display: flex; justify-content: flex-end; align-items: baseline; gap: 0.5em; font-size: var(--fs-small); }
.units__value .count { font-size: 1.75rem; font-weight: 600; line-height: 1; letter-spacing: -0.02em; }

/* Figure 3: coverage */
.coverage { display: grid; gap: var(--space-5); margin-top: var(--space-5); }
.coverage__panels { display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 4fr); gap: clamp(32px, 6vw, 96px); align-items: end; }
.coverage__panel { display: grid; gap: var(--space-4); }
.coverage__label { padding-bottom: var(--space-3); border-bottom: 1px solid var(--border-color); font-size: 0.75rem; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; }
.coverage__muni { display: grid; grid-template-columns: minmax(0, 1fr) clamp(48px, 7vw, 96px); gap: clamp(6px, 1vw, 12px); }
.coverage__cells { display: grid; grid-template-columns: repeat(10, minmax(0, 1fr)); gap: clamp(3px, 0.5vw, 6px); }
.coverage__cells i, .coverage__states i { display: block; aspect-ratio: 1; background: var(--text-color); }
.coverage__cells i.is-named { background: var(--accent-yellow-light); }
.coverage__plus { display: grid; place-items: center; border: 1px dashed var(--border-color); font-family: var(--font-ui); font-size: clamp(1.5rem, 3vw, 2.5rem); font-weight: 600; line-height: 1; }
.coverage__states { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: clamp(6px, 1vw, 12px); }
.coverage__value { display: flex; align-items: baseline; gap: 0.6em; font-size: var(--fs-small); }
.coverage__value .count { font-size: 1.75rem; font-weight: 600; line-height: 1; letter-spacing: -0.02em; }

/* Every square-grid figure answers a hover: a quick, tactile pop, never a delayed one (the stagger delays above are
   for the scroll entrance only, so this transition is declared separately and instant). Mouse and trackpad only,
   since a touch screen has no hover to fire it. */
@media (hover: hover) and (pointer: fine) {
  .units__cells i, .coverage__cells i, .coverage__states i, .batch__cells i, .tally__cells i {
    transition: transform 0.15s var(--ease-out), opacity 0.3s var(--ease-out) calc(var(--n, 0) * 16ms + var(--row, 0) * 40ms), background-color var(--dur-fast) ease;
  }
  .units__cells i:hover, .coverage__cells i:hover, .coverage__states i:hover, .batch__cells i:hover, .tally__cells i:hover {
    transform: scale(1.35);
    position: relative;
    z-index: 2;
  }
}
.key { display: flex; flex-wrap: wrap; gap: var(--space-3) var(--space-6); font-size: var(--fs-caption); line-height: var(--lh-caption); color: var(--text-muted); }
.key li { display: flex; align-items: center; gap: 8px; }
.key i { flex: none; width: 12px; height: 12px; background: var(--text-color); }
.key i.is-named { background: var(--accent-yellow-light); }
.key i.is-more { background: none; border: 1px dashed var(--border-color); }

/* Figure 4: two checks */
.matrix { width: 100%; border-collapse: collapse; font-size: var(--fs-small); }
.matrix th, .matrix td { padding: 14px var(--space-4) 14px 0; text-align: left; vertical-align: middle; border-top: 1px solid var(--rule-soft); line-height: 1.35; }
.matrix td:last-child { padding-right: 0; }
.matrix thead th { vertical-align: bottom; border-top: 1px solid var(--border-color); border-bottom: 1px solid var(--border-color); font-size: 0.75rem; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; }
.matrix tbody th { font-size: 1rem; font-weight: 600; }
.matrix tbody tr:last-child > * { border-bottom: 1px solid var(--border-color); }
.tick { display: inline-block; width: 14px; height: 14px; margin-right: 10px; vertical-align: -2px; }
.tick.is-pass { background: var(--text-color); }
.tick.is-fail { border: 1px solid var(--border-color); background: none; }
.matrix__hint {
  margin-bottom: var(--space-3);
  font-family: var(--font-mono);
  font-size: var(--fs-caption);
  color: var(--text-muted);
}
/* Every check is a real button: the table is not just read, it is tried. Flat at rest, an ink outline on hover
   and a proper focus ring, exactly the datasheet's own button language, just scaled down to fit a cell. */
.tick-toggle {
  display: inline-flex;
  align-items: center;
  margin: -6px -8px -6px -4px;
  padding: 6px 10px 6px 4px;
  background: none;
  border: 1px solid transparent;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
  transition: border-color var(--dur-fast) ease, background-color var(--dur-fast) ease;
}
.tick-toggle .tick { margin-right: 8px; }
@media (hover: hover) and (pointer: fine) {
  .tick-toggle:hover { border-color: var(--rule-soft); background: var(--surface); }
}
.verdict { display: inline-block; padding: 4px 10px; font-weight: 600; white-space: nowrap; }
.verdict--sent { background: var(--accent-yellow-light); color: #000000; }
.verdict--held { border: 1px solid var(--border-color); }
.tally { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-4); padding-top: var(--space-4); }
.tally__cells { display: flex; gap: 4px; }
.tally__cells i { display: block; width: 18px; height: 18px; border: 1px solid var(--border-color); }
.tally__cells i.is-sent { background: var(--accent-yellow-light); }
.tally__text { font-size: var(--fs-small); }
.tally__text .count { font-weight: 600; }

/* Figure 5: the batch run gets a ruler and a playhead */
.batch__axis { display: grid; grid-template-columns: 5.5rem minmax(0, 1fr) 6rem; gap: var(--space-4); padding-bottom: var(--space-2); }
.batch__ticks {
  display: flex; justify-content: space-between; height: 24px; padding-top: 2px;
  border-right: 1px solid var(--border-color); border-bottom: 1px solid var(--border-color);
  font-family: var(--font-mono); font-size: var(--fs-caption); line-height: 1.2; color: var(--text-muted);
}
.batch__ticks b { position: relative; font-weight: 500; }
.batch__ticks b::after { content: ''; position: absolute; top: calc(100% - 6px); left: 50%; height: 6px; border-left: 1px solid var(--border-color); }
.batch__ticks b:not(:first-child) { text-align: right; }
.batch__lanes { position: relative; }
.batch__track { position: absolute; inset: 0 calc(6rem + var(--space-4)) 0 calc(5.5rem + var(--space-4)); pointer-events: none; }
.batch__playhead { position: absolute; top: 0; bottom: 0; left: 0; width: 2px; margin-left: -1px; background: var(--accent-yellow-dark); opacity: 0; }

/* Figure 6: the packet that travels the chosen wire */
.wire__mid { position: relative; height: 216px; }
.wire__packet { position: absolute; left: 0; top: 0; width: 12px; height: 12px; margin: -6px 0 0 -6px; background: var(--accent-yellow-light); border: 1px solid var(--border-color); opacity: 0; pointer-events: none; }

/* GSAP layer (home.js): the hero waits for its sequence, split words rise through a clip, and the CSS transitions that the
   scroll reveal uses step aside so they never fight the timeline */
html.g-pending .hero__title, html.g-pending .hero__sub, html.g-pending .hero__actions, html.g-pending .hero__status, html.g-pending .hero__figure { visibility: hidden; }
.w { display: inline-block; clip-path: inset(-0.15em -0.08em -0.5em -0.08em); }
.w__i { display: inline-block; }
html.g-on .mark, html.g-on .batch__cells i { transition: none; }

/* ---------- 11. team ---------- */
/* team.js's own entrance: held invisible (not display:none, so layout and screen readers are unaffected) until its
   timeline sets the first frame, the same g-pending pattern home.js uses for the hero. */
html.t-pending #team-title, html.t-pending .profile__psych, html.t-pending .profile__lede,
html.t-pending .profile__body, html.t-pending .profile__subhead, html.t-pending .record,
html.t-pending .portrait__frame, html.t-pending .portrait__caption, html.t-pending .profile__contact,
html.t-pending .range__layer { visibility: hidden; }

/* The mountain plate (team.html only). Snow-topped ranges under a partly cloudy sky, drawn flat: posterized sky bands, stepped
   block clouds, hard white snowfields, and every shade face printed in a square halftone, the same square the site's figures
   count in. Blue exists nowhere else on the site; here it belongs to the picture, never to the interface, and every line of text
   sits in a frame of the page's own ground above it (the frames below), so the plate can be as vivid as it likes.
   Layering: the plate sits at z-index -1 in the root stacking context, under everything, so the header, the mobile menu, the
   text and every link stay above it and it never takes a click (pointer-events: none). A negative layer paints under an
   element's own background, so this page's body is transparent: html still paints the sheet colour behind the plate.
   Anchoring: fixed, pinned to the bottom edge and sized to the large viewport (100lvh), so the page scrolls over a picture
   that never moves; when a phone's toolbar slides in, the sky's top edge goes under it instead of the whole picture
   rescaling. background-attachment: fixed is not used: iPhones ignore it. The SVGs slice to cover from the bottom centre
   (xMidYMax), so the snowfields stay in frame from 320px phones to ultrawide screens, and the plate clips its own contents
   (overflow: hidden), so it can never add horizontal scroll. Dark mode is the same range at night, not an inversion: the
   sky goes to deep navy, the snow stays the brightest thing on screen, and square stars come out. */
body.page-team { background: transparent; }
.range {
  position: fixed;
  inset: auto 0 0 0;
  z-index: -1;
  height: 100vh;
  height: 100lvh;
  overflow: hidden;
  pointer-events: none;
  --mt-sky-1: #2878c0; --mt-sky-2: #4292d3; --mt-sky-3: #6ab0e0; --mt-sky-4: #a1cfe8;
  --mt-cloud: #ffffff; --mt-cloud-under: #c7dbea;
  --mt-far-lit: #a9bdd0; --mt-far-shade: #8ea4ba; --mt-far-dot: #6a839d;
  --mt-mid-lit: #5d6e80; --mt-mid-shade: #475769; --mt-mid-dot: #26313f;
  --mt-near-lit: #222933; --mt-near-shade: #10141b; --mt-near-dot: #000000;
  --mt-snow: #ffffff; --mt-snow-shade: #d6e3ee; --mt-snow-dot: #a8c2d6;
  --mt-star: #ffffff; --mt-stars: 0;
}
[data-theme="dark"] .range {
  --mt-sky-1: #050d1c; --mt-sky-2: #09162a; --mt-sky-3: #112239; --mt-sky-4: #1a324b;
  --mt-cloud: #3a4655; --mt-cloud-under: #273140;
  --mt-far-lit: #3e4c5d; --mt-far-shade: #2c394a; --mt-far-dot: #1b2433;
  --mt-mid-lit: #1d2735; --mt-mid-shade: #101826; --mt-mid-dot: #04070f;
  --mt-near-lit: #080b12; --mt-near-shade: #020306; --mt-near-dot: #000000;
  --mt-snow: #e0e9f1; --mt-snow-shade: #99aaba; --mt-snow-dot: #71859b;
  --mt-star: #f7f2e3; --mt-stars: 1;
}
.range__svg { position: absolute; inset: 0; width: 100%; height: 100%; max-width: none; }
.range pattern rect { shape-rendering: crispEdges; }                    /* halftone squares land on whole pixels: hard, not soft */
.mt-sky-1 { fill: var(--mt-sky-1); } .mt-sky-2 { fill: var(--mt-sky-2); } .mt-sky-3 { fill: var(--mt-sky-3); } .mt-sky-4 { fill: var(--mt-sky-4); }
.mt-cloud { fill: var(--mt-cloud); } .mt-cloud-under { fill: var(--mt-cloud-under); }
.mt-far-lit { fill: var(--mt-far-lit); } .mt-far-shade { fill: var(--mt-far-shade); } .mt-far-dot { fill: var(--mt-far-dot); }
.mt-mid-lit { fill: var(--mt-mid-lit); } .mt-mid-shade { fill: var(--mt-mid-shade); } .mt-mid-dot { fill: var(--mt-mid-dot); }
.mt-near-lit { fill: var(--mt-near-lit); } .mt-near-shade { fill: var(--mt-near-shade); } .mt-near-dot { fill: var(--mt-near-dot); }
.mt-snow { fill: var(--mt-snow); } .mt-snow-shade { fill: var(--mt-snow-shade); } .mt-snow-dot { fill: var(--mt-snow-dot); }
.mt-star { fill: var(--mt-star); opacity: var(--mt-stars); }
.team__grid {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  align-items: start;
  max-width: var(--max);
  min-height: calc(100vh - var(--header-h));
  min-height: calc(100svh - var(--header-h));
  margin-inline: auto;
}
.portrait {
  position: sticky;
  top: var(--header-h);
  display: flex;
  flex-direction: column;
  height: calc(100vh - var(--header-h));
  height: calc(100svh - var(--header-h));
  border-right: 1px solid var(--border-color);
}
.portrait__frame { position: relative; flex: 1 1 auto; min-height: 0; overflow: hidden; background: var(--surface); border: 1px solid var(--border-color); }
.portrait__frame img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 22%;
  filter: grayscale(1);
}
.portrait__monogram {
  position: absolute;
  inset: 0;
  display: none;
  place-items: center;
  font-family: var(--font-display);
  font-size: var(--fs-display);
  letter-spacing: -0.02em;
  color: var(--text-color);
}
.portrait.is-missing .portrait__frame img { display: none; }
.portrait.is-missing .portrait__monogram { display: grid; }

.portrait__caption {
  display: flex;
  justify-content: space-between;
  gap: var(--space-4);
  padding: 14px var(--gutter);
  background: var(--accent-yellow-light);
  color: #000000;
  border-top: 1px solid #000000;
  font-size: var(--fs-small);
  font-weight: 600;
}

/* The founder's own accent, sampled straight from the logo mark (gold, amber, ember), used nowhere else on the
   site: the Team page is the one place it gets to be warm instead of strictly black, white and highlighter yellow.
   The column itself has no ground of its own any more (the faint gold wash that used to sit here would only have muddied
   the sky): the plate shows through, and every line of text brings its own ground with it. */
.profile {
  position: relative;
  display: grid;
  align-content: center;
  gap: var(--space-5);
  max-width: 920px;
  padding: clamp(32px, 4.5vw, 64px) var(--gutter) clamp(96px, 24vh, 260px) clamp(24px, 5vw, 80px);   /* the deep bottom is the range's own stage: at the end of the page the mountains stand clear of every frame */
}
/* Text over the plate: every block of text sits in a hard frame, a flat field of the page's own ground inside a 1px rule.
   The colours are the theme tokens themselves (ink on paper, paper on ink), so both themes keep the sheet's own 21:1 no matter
   which part of the picture a block passes over, and the rule keeps each frame's edge crisp even where it crosses the white of
   a cloud or a snowfield. Frames hug their text (justify-self: start) and the reading blocks keep a shorter measure than the rest
   of the site, so the picture shows in the gaps and down the right-hand side rather than only at the page's edges.
   (Per-line highlighter strips were tried first: each line's strip painted over the descenders of the line above, and a cloned
   inline background leaves an unpainted notch at some line ends, so the frames are whole blocks.) */
.profile__title, .profile__psych, .profile__lede, .profile__body {
  justify-self: start;
  background: var(--bg-color);
  border: 1px solid var(--border-color);
}
.profile__title { padding: 0.14em 0.3em 0.1em; }   /* the same room above the ascenders as below the baseline */
.profile__psych { padding: 0.3em 0.4em 0.42em; text-wrap: balance; }
.profile__lede, .profile__body { max-width: 36rem; padding: var(--space-4) var(--space-5); text-wrap: pretty; }   /* one reading width for every frame (a rem, not a ch: Geist's figures run wide), so the frames stack on one right edge */
.nowrap { white-space: nowrap; }                                     /* keeps "16 years old?" together, so the question mark never starts a line alone */
.page-team .site-footer { background: var(--bg-color); }
@media (max-width: 480px) {
  .profile__lede, .profile__body { padding: var(--space-3) var(--space-4); }
}
.profile__title { font-size: clamp(2.25rem, 1.2rem + 3vw, 3.5rem); line-height: 1.14; }
.profile__psych { font-size: clamp(1.5rem, 1.1rem + 1.8vw, 2.25rem); line-height: 1.22; }
/* The swept highlighter: the yellow is a separate layer behind the word, never the word itself, so the text
   is always fully painted and readable regardless of whether the sweep has played, is mid-animation, or
   never runs at all (reduced motion, blocked GSAP, no JS). team.js animates .mark__fill's scaleX; nothing
   ever touches .mark--sweep's own opacity, visibility or clip-path. */
.mark--sweep {
  position: relative;
  isolation: isolate;
  padding: 0 0.14em 0.06em;
  background: none;
}
.mark--sweep .mark__fill {
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--accent-yellow-light);
  transform: scaleX(1);
  transform-origin: left center;
}
.profile__lede { font-size: clamp(1.125rem, 1rem + 0.5vw, 1.375rem); line-height: 1.35; }
/* "Track record" and its list read as one ruled ledger: the heading is the ledger's head row, the list its body, joined across
   the column's gap, so the list's hairlines are always drawn on the ground colour and never across the picture. */
.profile__subhead {
  width: 100%;
  max-width: 36rem;
  padding: var(--space-3) var(--space-4);
  background: var(--bg-color);
  border: 1px solid var(--border-color);
  border-bottom: 0;
  font-family: var(--font-ui);
  font-size: 1.125rem;
  font-weight: 600;
  line-height: 1.3;
}
.record { max-width: 36rem; margin-top: calc(var(--space-5) * -1); padding: 0 var(--space-4); background: var(--bg-color); border: 1px solid var(--border-color); }
.record li {
  position: relative;
  padding: var(--space-3) 0 var(--space-3) 28px;
  border-top: 1px solid var(--rule-soft);
  transition: padding-left 0.25s var(--ease-out), color 0.25s var(--ease-out);
}
.record li:first-child { border-top: 0; }
.record li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 1.2rem;
  width: 8px;
  height: 8px;
  background: var(--accent-yellow-dark);
  transition: left 0.25s var(--ease-out), width 0.25s var(--ease-out), height 0.25s var(--ease-out), top 0.25s var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .record li:hover { padding-left: 38px; }
  .record li:hover::before { left: -1px; width: 10px; height: 10px; top: calc(1.2rem - 1px); }   /* grows about its own centre, so it stays on the track */
}
/* The track in "Track record": a 2px founder-gold rule down the ledger's column of squares, from the first square's centre to
   the last (team.js measures --track-top and --track-h). team.js draws it with the scroll (--track, 0 to 1) and marks each row
   .is-hit as the rule reaches its square, which then stamps from hollow to solid. Without the scroll layer (reduced motion,
   no script, no ScrollTrigger) the ledger is exactly as it was: solid squares and no rule, since the rule only exists where
   team.js can measure it. The squares paint over the rule, and a hollow square keeps the ground colour inside, so the rule
   never shows through one. */
.record { position: relative; }
.record::before {
  content: '';
  position: absolute;
  top: var(--track-top, 1.45rem);
  left: calc(var(--space-4) + 3px);
  width: 2px;
  height: var(--track-h, 0px);
  background: var(--accent-yellow-dark);
  transform: scaleY(var(--track, 1));
  transform-origin: 50% 0;
}
.record.is-tracking li::before { background: var(--bg-color); border: 2px solid var(--accent-yellow-dark); }
.record.is-tracking li.is-hit::before { background: var(--accent-yellow-dark); animation: trackStamp 0.24s var(--ease-out); }
@keyframes trackStamp { from { transform: scale(1.75); } to { transform: none; } }
.profile__contact {                                                   /* a boxed label on the ground colour, as wide as its own line */
  justify-self: start;
  max-width: var(--measure);
  margin-top: var(--space-2);
  padding: var(--space-3) var(--space-4);
  background: var(--bg-color);
  border: 1px solid var(--border-color);
  font-size: var(--fs-small);
  font-weight: 600;
  line-height: var(--lh-caption);
  color: var(--text-color);
}
.profile__contact .link { text-decoration-color: var(--accent-yellow-dark); text-decoration-thickness: 2px; overflow-wrap: anywhere; }
/* ---------- 12. register ---------- */
.register { padding-block: clamp(48px, 8vw, 112px); }
.register__grid { row-gap: var(--space-7); align-items: start; }
.register__intro { grid-column: 1 / span 6; display: grid; gap: var(--space-6); }
.register__title { font-size: var(--fs-title); line-height: 1.14; }
.register__lead { max-width: 40ch; }
.register__panel { grid-column: 8 / -1; padding-top: clamp(0px, 3vw, 40px); }

.form { display: grid; gap: var(--space-5); }
.field { display: grid; gap: var(--space-1); }
.field__label { font-size: var(--fs-small); font-weight: 500; color: var(--text-muted); }
.field__input {
  display: block;
  width: 100%;
  padding: 12px 0 10px;
  background: transparent;
  color: var(--text-color);
  border: 0;
  border-bottom: 1px solid var(--border-color);
  border-radius: 0;
  outline: none;
  font-size: 1.125rem;
  line-height: 1.4;
  overflow-wrap: anywhere;
  transition: border-color var(--dur-fast) ease, box-shadow var(--dur-fast) ease;
}
.field__input:focus { border-bottom-color: var(--accent-yellow-dark); box-shadow: 0 1px 0 0 var(--accent-yellow-dark); }
.field__input[aria-invalid="true"] { border-bottom-color: var(--error-color); box-shadow: 0 1px 0 0 var(--error-color); }
.field__input:-webkit-autofill,
.field__input:-webkit-autofill:hover {
  -webkit-text-fill-color: var(--text-color);
  box-shadow: 0 0 0 100px var(--bg-color) inset;
}
.field__input:-webkit-autofill:focus {
  -webkit-text-fill-color: var(--text-color);
  box-shadow: 0 0 0 100px var(--bg-color) inset, 0 1px 0 0 var(--accent-yellow-dark);
}
.field__error {
  min-height: 1.3rem;                /* reserved so an error never shifts the layout */
  color: var(--error-color);
  font-size: var(--fs-small);
  font-weight: 500;
  line-height: 1.3;
}

.checks { display: grid; gap: var(--space-2); margin-top: var(--space-2); }
.check { display: grid; grid-template-columns: 24px minmax(0, 1fr); gap: 14px; align-items: start; cursor: pointer; }
.check__input { position: absolute; width: 1px; height: 1px; margin: 0; opacity: 0; pointer-events: none; }
.check__box {
  position: relative;
  width: 24px;
  height: 24px;
  margin-top: 1px;
  background: var(--bg-color);
  border: 1px solid var(--border-color);
  transition: background-color var(--dur-fast) ease, border-color var(--dur-fast) ease;
}
.check__box::after {
  content: '';
  position: absolute;
  left: 8px;
  top: 3px;
  width: 6px;
  height: 12px;
  border: solid #000000;
  border-width: 0 2.5px 2.5px 0;
  transform: rotate(45deg) scale(0);
  transition: transform 0.2s var(--ease-out);
}
.check__input:checked + .check__box { background: var(--accent-yellow-light); border-color: var(--border-color); }
.check__input:checked + .check__box::after { transform: rotate(45deg) scale(1); }
.check__input:focus-visible + .check__box { outline: 3px solid var(--focus-color); outline-offset: 4px; }
.check__input[aria-invalid="true"] + .check__box { border-color: var(--error-color); box-shadow: 0 0 0 1px var(--error-color); }
.check__label { font-size: 1rem; line-height: 1.45; }
.check__label a { text-underline-offset: 0.2em; }
.checks .field__error { padding-left: 38px; min-height: 1.3rem; }

.form__submit { width: 100%; justify-content: space-between; margin-top: var(--space-3); }
.form__note { font-size: var(--fs-small); line-height: var(--lh-caption); color: var(--text-muted); }

/* the one error line under the button: flat Error Red text, its mailto link in the same colour */
.form__status.is-error { color: var(--error-color); font-weight: 500; animation: err-in 0.3s var(--ease-out); }
.form__status.is-error .link { color: inherit; }

/* the ink shutter main.js sweeps across the whole form on success; created and removed by script, never focusable */
#register-form { position: relative; }
.form-cover {
  position: absolute;
  inset: -1px;
  z-index: 2;
  background: var(--text-color);
  pointer-events: none;
  transform: scaleX(0);
  transform-origin: 0 50%;
}

.form-success {
  display: grid;
  gap: var(--space-4);
  padding-block: var(--space-6);
  border-top: 1px solid var(--border-color);
  border-bottom: 1px solid var(--border-color);
}
.form-success__title { justify-self: start; font-size: var(--fs-title); line-height: 1.14; }
.form-success__title:focus { outline: none; }                    /* focus lands here only so screen readers announce it; it is not a control */
.form-success__sub { margin-top: var(--space-2); font-size: 1.125rem; font-weight: 600; line-height: 1.3; }
.form-success__text { max-width: 46ch; font-size: var(--fs-body); line-height: var(--lh-body); }

/* Without JavaScript the form posts itself, and the server redirects back here with a # naming the result. :target shows that one message,
   or the confirmation in place of the fields. Once main.js has taken the form over (data-enhanced), it shows every answer itself and a
   stray # in the address changes nothing. The confirmation overrides the [hidden] rule on purpose, which is why it carries !important. */
.form-flag {
  display: none;
  margin: 0 0 var(--space-5);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--error-color);
  color: var(--error-color);
  font-size: var(--fs-small);
  font-weight: 500;
  line-height: 1.45;
  scroll-margin-top: calc(var(--header-h) + var(--space-6));
}
.form-flag .link { color: inherit; }
#register-form:not([data-enhanced]) .form-flag:target { display: block; }
#register-form:not([data-enhanced]) #register-success:target { display: grid !important; scroll-margin-top: calc(var(--header-h) + var(--space-6)); }
#register-form:not([data-enhanced]):has(#register-success:target) #register-fields { display: none; }

/* ---------- 13. privacy and FAQ: an editorial document ----------
   Numbered parts and clauses so a reader can cite them, ruled tables for anything with more than one attribute, every answer written out.
   No accordions, no cards. */
.doc { padding-block: clamp(48px, 8vw, 112px); row-gap: var(--space-7); align-items: start; }
.doc__head { grid-column: 1 / -1; display: grid; gap: var(--space-6); padding-bottom: var(--space-6); border-bottom: 1px solid var(--border-color); }
.doc__title { font-size: var(--fs-display); line-height: 0.96; }
/* a marked word that wraps under another line (the FAQ title on a phone) keeps clear of that line's comma and the tail of its Q */
.doc__title .mark { margin-top: 0.08em; }
.doc__lead { max-width: 40ch; font-weight: 500; }

.facts { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); border-top: 1px solid var(--border-color); }
.facts > div { padding: var(--space-4) var(--space-5) var(--space-4) 0; }
.facts > div + div { padding-left: var(--space-5); border-left: 1px solid var(--rule-soft); }
.facts dt { font-size: 0.75rem; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-muted); }
.facts dd { margin: 4px 0 0; font-size: var(--fs-small); font-weight: 500; line-height: 1.35; }

.doc__index { grid-column: 1 / span 3; position: sticky; top: calc(var(--header-h) + var(--space-5)); }
.doc__index ol { border-top: 1px solid var(--border-color); }
.doc__index li { border-bottom: 1px solid var(--rule-soft); }
.doc__index a { display: grid; grid-template-columns: 2rem minmax(0, 1fr); align-items: baseline; padding: 12px 8px 12px 0; font-size: var(--fs-small); font-weight: 500; text-decoration: none; transition: background-color var(--dur-fast) ease; }
.doc__index a::before { content: attr(data-no); font-family: var(--font-mono); font-size: var(--fs-caption); color: var(--text-muted); }
.doc__index a[aria-current="true"] { background: var(--accent-yellow-light); color: #000000; }
.doc__index a[aria-current="true"]::before { color: #000000; }
.doc__body { grid-column: 4 / -1; display: grid; gap: clamp(64px, 9vw, 128px); min-width: 0; }

.part { display: grid; gap: var(--space-5); min-width: 0; scroll-margin-top: calc(var(--header-h) + var(--space-5)); }
.part__head { display: grid; grid-template-columns: 5.5rem minmax(0, 1fr); gap: var(--space-5); align-items: start; padding-top: var(--space-5); border-top: 1px solid var(--border-color); }
.part__no { justify-self: start; padding: 2px 12px 3px; background: var(--accent-yellow-light); color: #000000; font-family: var(--font-mono); font-size: 0.9375rem; font-weight: 500; line-height: 1.4; }
.part__head h2 { font-family: var(--font-display); font-size: var(--fs-title); font-weight: 400; line-height: 1.14; letter-spacing: -0.02em; text-wrap: balance; overflow-wrap: break-word; }
.part__lead { max-width: var(--measure); color: var(--text-muted); }
.prose__status { padding: var(--space-3) var(--space-4); background: var(--accent-yellow-light); color: #000000; font-size: var(--fs-small); font-weight: 500; }

.clause { display: grid; grid-template-columns: 5.5rem minmax(0, 1fr); gap: var(--space-5); padding-block: var(--space-5); border-top: 1px solid var(--rule-soft); scroll-margin-top: calc(var(--header-h) + var(--space-5)); }
.clause__no { font-family: var(--font-mono); font-size: var(--fs-caption); font-weight: 500; line-height: 1.9; text-decoration: none; }
.clause__no:hover, .clause__no:focus-visible { text-decoration: underline; text-decoration-color: var(--accent-yellow-dark); text-decoration-thickness: 2px; text-underline-offset: 0.2em; }
.clause__body { display: grid; gap: var(--space-4); min-width: 0; }
.clause__body h3 { font-size: 1.125rem; font-weight: 600; line-height: 1.35; }
.clause__body p, .part > p { max-width: var(--measure); }
.doc code {
  padding: 1px 6px;
  background: var(--surface);
  border: 1px solid var(--rule-soft);
  font-family: var(--font-mono);
  font-size: 0.875em;
  white-space: nowrap;
}
.points { display: grid; gap: var(--space-3); max-width: var(--measure); }
.points li { position: relative; padding-left: 22px; }
.points li::before { content: ''; position: absolute; left: 0; top: 0.62em; width: 8px; height: 8px; background: var(--text-color); }

.ledger { width: 100%; border-collapse: collapse; font-size: var(--fs-small); font-variant-numeric: tabular-nums; }
.ledger caption { caption-side: top; padding-bottom: var(--space-3); text-align: left; font-size: var(--fs-caption); line-height: var(--lh-caption); color: var(--text-muted); }
.ledger caption strong { color: var(--text-color); font-weight: 600; }
.ledger th, .ledger td { padding: 12px var(--space-4) 12px 0; text-align: left; vertical-align: top; border-top: 1px solid var(--rule-soft); line-height: 1.4; }
.ledger td:last-child { padding-right: 0; }
.ledger thead th { border-top: 1px solid var(--border-color); border-bottom: 1px solid var(--border-color); font-size: 0.75rem; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; }
.ledger tbody th { font-weight: 600; }
.ledger tbody tr:last-child > * { border-bottom: 1px solid var(--border-color); }
.ledger__note { display: block; margin-top: 2px; font-family: var(--font-mono); font-size: var(--fs-caption); font-weight: 400; color: var(--text-muted); overflow-wrap: anywhere; }
.tag { display: inline-block; padding: 2px 8px; background: var(--accent-yellow-light); color: #000000; font-size: 0.75rem; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; white-space: nowrap; }

.qagroup { display: grid; gap: var(--space-4); scroll-margin-top: calc(var(--header-h) + var(--space-5)); }
.qagroup__title { display: grid; grid-template-columns: 5.5rem minmax(0, 1fr); gap: var(--space-5); font-size: 1.125rem; font-weight: 600; line-height: 1.35; }
.qagroup__no { font-family: var(--font-mono); font-size: var(--fs-caption); font-weight: 500; line-height: 1.9; }
.qa { border-bottom: 1px solid var(--border-color); }
.qa__row { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: var(--space-5); padding-block: var(--space-5); border-top: 1px solid var(--border-color); scroll-margin-top: calc(var(--header-h) + var(--space-5)); }
.qa dt { font-size: 1.0625rem; font-weight: 600; line-height: 1.35; }
.qa dd { display: grid; gap: var(--space-3); max-width: var(--measure); }

.glossary { border-top: 1px solid var(--border-color); border-bottom: 1px solid var(--border-color); }
.glossary > div { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: var(--space-5); padding-block: var(--space-4); border-top: 1px solid var(--rule-soft); }
.glossary > div:first-child { border-top: 0; }
.glossary dt { font-weight: 600; }

/* ---------- 14. footer ---------- */
.site-footer { border-top: 1px solid var(--border-color); }
.site-footer__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2) var(--space-6);
  padding-block: var(--space-5);
  font-size: var(--fs-small);
  color: var(--text-muted);
}
.site-footer a { color: var(--text-color); }
.site-footer__links { display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-5); }

/* Section nav (home.html only): the same act-arrow language welcome.html uses, repurposed to step between sections. */
.section-nav { position: fixed; right: var(--gutter); bottom: max(var(--space-5), env(safe-area-inset-bottom)); z-index: 60; display: grid; transition: opacity var(--dur-fast) ease, visibility 0s linear; }
.section-nav.is-obscured { opacity: 0; pointer-events: none; visibility: hidden; transition-delay: 0s, var(--dur-fast); }
.section-nav__btn {
  display: grid; place-items: center; width: 44px; height: 44px; padding: 0; cursor: pointer;
  background: var(--bg-color); color: var(--text-color); border: 1px solid var(--border-color); border-radius: 0;
  transition: background-color 0.2s ease, color 0.2s ease, opacity 0.2s ease;
}
.section-nav__btn + .section-nav__btn { margin-top: -1px; }                    /* the two squares share one rule */
.section-nav__btn svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.75; stroke-linecap: square; stroke-linejoin: miter; }
.section-nav__btn[aria-disabled="true"] { opacity: 0.35; cursor: default; }
@media (hover: hover) and (pointer: fine) {
  .section-nav__btn:not([aria-disabled="true"]):hover { background: var(--text-color); color: var(--bg-color); }
}
@media (max-width: 480px) { .section-nav { right: 12px; } }
@media print { .section-nav { display: none; } }

/* ---------- responsive structure ---------- */
@media (min-width: 1441px) {
  .team__grid { border-inline: 1px solid var(--border-color); }
}

@media (max-width: 1099px) {
  .hero__title, .hero__aside { grid-column: 1 / -1; }
  .hero__aside { grid-template-columns: minmax(0, 1fr); }
  .split > * { grid-column: 1 / -1; }
  .intro__mark { grid-row: auto; justify-self: center; max-width: 220px; margin-top: 0; }
  .register__intro, .register__panel { grid-column: 1 / -1; }
  .doc__index { grid-column: 1 / -1; position: static; }
  .doc__index ol { display: flex; flex-wrap: wrap; gap: 0 var(--space-6); }
  .doc__index li { border-bottom: 0; }
  .doc__index a { grid-template-columns: auto minmax(0, 1fr); gap: var(--space-2); }
  .doc__body { grid-column: 1 / -1; }
}

@media (max-width: 899px) {
  .team__grid { grid-template-columns: minmax(0, 1fr); }
  .portrait { position: static; height: auto; border-right: 0; border-bottom: 1px solid var(--border-color); }
  .portrait__frame { flex: none; aspect-ratio: 4 / 5; max-height: 72vh; max-height: 72svh; width: 100%; }
  .profile { padding-left: var(--gutter); padding-bottom: max(36svh, 200px); max-width: none; }
}

@media (max-width: 899px) {
  .qa__row, .glossary > div { grid-template-columns: minmax(0, 1fr); gap: var(--space-3); }
  .coverage__panels { grid-template-columns: minmax(0, 1fr); gap: var(--space-7); }
  .split__aside { --col: 1 / -1; }
}
@media (max-width: 719px) {
  .facts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .facts > div:nth-child(odd) { padding-left: 0; border-left: 0; }
  .facts > div:nth-child(n + 3) { border-top: 1px solid var(--rule-soft); }
  .part__head, .clause, .qagroup__title { grid-template-columns: minmax(0, 1fr); gap: var(--space-2); }
  /* the units chart and the batch lanes put their label and value on one line and the squares under them */
  .units__ruler { grid-template-columns: minmax(0, 1fr); }
  .units__ruler > span { display: none; }
  .units__row { grid-template-columns: minmax(0, 1fr) auto; row-gap: var(--space-2); }
  .units__cells { grid-column: 1 / -1; grid-row: 2; }
  .batch__axis, .batch__track { display: none; }
  /* the matrix reads as labelled blocks, one per target */
  .matrix thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .matrix, .matrix tbody, .matrix tr, .matrix th, .matrix td { display: block; }
  .matrix caption { display: block; }
  .matrix tr { padding-block: var(--space-3); border-top: 1px solid var(--rule-soft); }
  .matrix tbody tr:first-child { border-top: 1px solid var(--border-color); }
  .matrix tbody tr:last-child { border-bottom: 1px solid var(--border-color); }
  .matrix th, .matrix td { padding: 3px 0; border: 0; }
  .matrix tbody tr:last-child > * { border-bottom: 0; }
  .matrix td { position: relative; padding-left: 8.5rem; }
  .matrix td::before { content: attr(data-label); position: absolute; left: 0; top: 3px; width: 8rem; font-weight: 600; color: var(--text-muted); }
  /* ledger tables become labelled blocks: one rule per row, each value named */
  .ledger thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .ledger, .ledger tbody, .ledger tr, .ledger th, .ledger td { display: block; }
  .ledger tr { padding-block: var(--space-3); border-top: 1px solid var(--rule-soft); }
  .ledger tbody tr:first-child { border-top: 1px solid var(--border-color); }
  .ledger tbody tr:last-child { border-bottom: 1px solid var(--border-color); }
  .ledger caption { display: block; }
  .ledger th, .ledger td { padding: 3px 0; border: 0; }
  .ledger tbody tr:last-child > * { border-bottom: 0; }                              /* the row itself carries the closing rule */
  .ledger td { position: relative; padding-left: 7rem; }                             /* the label hangs in the margin, the value keeps its own inline flow */
  .ledger td::before { content: attr(data-label); position: absolute; left: 0; top: 3px; width: 6.5rem; font-weight: 600; color: var(--text-muted); }
}

@media (max-width: 639px) {
  .batch__row { grid-template-columns: minmax(0, 1fr) auto; row-gap: var(--space-2); }
  .batch__cells { grid-column: 1 / -1; grid-row: 2; }
  .batch__count { grid-row: 1; grid-column: 2; }
  .table th { width: 40%; }
}

/* ---------- 15. motion ----------
   Content is visible by default. The inline script in every <head> adds html.reveal before first paint, and
   html.no-reveal when the tab is hidden or a script fails, so nothing flashes and nothing stays hidden.
   Everything below moves opacity, transform or clip-path only. */
[data-reveal] {
  transition:
    opacity var(--dur-reveal) var(--ease-out) calc(var(--i, 0) * 80ms),
    transform var(--dur-reveal) var(--ease-out) calc(var(--i, 0) * 80ms),
    clip-path var(--dur-wipe) var(--ease-out) calc(var(--i, 0) * 80ms);
}
[data-reveal="fine"] { --reveal-y: 16px; }
[data-reveal="fade"] { --reveal-y: 0px; }
[data-reveal="wipe"] { clip-path: inset(0 0 0 0); }

html.reveal:not(.no-reveal) [data-reveal]:not(.is-in) {
  opacity: 0;
  transform: translate3d(0, var(--reveal-y), 0);
}
html.reveal:not(.no-reveal) [data-reveal="wipe"]:not(.is-in) {
  opacity: 1;
  transform: none;
  clip-path: inset(0 0 100% 0);
}

/* the marker: a yellow block and its word appear together, wiped in from the left */
.mark { transition: clip-path var(--dur-wipe) var(--ease-out) 0.35s; }
html.reveal:not(.no-reveal) [data-reveal]:not(.is-in) .mark { clip-path: inset(-0.4em 100% -0.4em -0.1em); }
html.reveal:not(.no-reveal) [data-reveal].is-in .mark { clip-path: inset(-0.4em -0.1em -0.4em -0.1em); }

/* section rules are drawn */
html.reveal:not(.no-reveal) .section--ruled:not(.is-in)::before { transform: scaleX(0); }

/* the batch run: five rows print left to right at the same time */
html.reveal:not(.no-reveal) [data-observe]:not(.is-in) .batch__cells i { opacity: 0; }

/* form feedback */
.field__error:not(:empty) { animation: err-in 0.3s var(--ease-out); }
.form-success:not([hidden]) { animation: rise var(--dur-reveal) var(--ease-out) both; }
.form-success .mark { animation: mark-wipe var(--dur-wipe) var(--ease-out) 0.2s both; }
.form-success.is-animated, .form-success.is-animated .mark { animation: none; }   /* main.js's shutter sequence is running instead */
@keyframes err-in {
  from { opacity: 0; transform: translateY(-4px); }
  to { opacity: 1; transform: none; }
}
@keyframes rise {
  from { opacity: 0; transform: translateY(16px); }
  to { opacity: 1; transform: none; }
}
@keyframes mark-wipe {
  from { clip-path: inset(-0.4em 100% -0.4em -0.1em); }
  to { clip-path: inset(-0.4em -0.1em -0.4em -0.1em); }
}

/* theme switch: a same-document view transition crossfades the whole sheet */
@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
  ::view-transition-old(root), ::view-transition-new(root) { animation-duration: 0.35s; animation-timing-function: ease; }
}

/* ---------- 16. pointer, reduced motion, forced colors, print ---------- */
@media (hover: hover) and (pointer: fine) {
  .link:hover { text-decoration-color: var(--accent-yellow-dark); text-decoration-thickness: 2px; }
  .site-nav a:hover::after { transform: scaleX(1); transform-origin: left; }
  .theme-toggle:hover, .menu-toggle:hover { background: var(--text-color); color: var(--bg-color); }
  .btn:hover { color: var(--btn-hover-fg); background-color: var(--btn-hover-bg); transition: var(--btn-in); }
  .btn:hover::before { transform: scaleX(1); transform-origin: left; }
  .btn:hover .btn__icon { transform: translateX(3px); }
  label.wire__item:hover { background: var(--surface); }
  .batch__row:hover .batch__cells i { background: var(--accent-yellow-light); }
  .doc__index a:hover { text-decoration: underline; text-decoration-color: var(--accent-yellow-dark); text-decoration-thickness: 2px; text-underline-offset: 0.2em; }
}
@media (hover: none) {
  .btn:active { color: var(--btn-hover-fg); background-color: var(--btn-hover-bg); transition: var(--btn-in); }
  .btn:active::before { transform: scaleX(1); transform-origin: left; }
}
@media (pointer: coarse) {                       /* touch: standalone text links get a full 44px target (links inside a sentence keep their line) */
  .site-footer a, .hero__actions .link { display: inline-flex; align-items: center; min-height: var(--tap); }
  .clause__no, .ledger td a.link { padding-block: 12px; margin-block: -12px; }   /* a bigger hit area with no change to the layout */
  .tick-toggle { padding-block: 14px; margin-block: -14px; }
}

/* Reduced motion keeps the state changes and drops the travel: reveals become short fades, wipes and draws disappear. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  [data-reveal] { transition: opacity 0.4s ease; }
  html.reveal:not(.no-reveal) [data-reveal]:not(.is-in) { transform: none; }
  html.reveal:not(.no-reveal) [data-reveal="wipe"]:not(.is-in) { opacity: 0; clip-path: none; }
  .mark, html.reveal:not(.no-reveal) [data-reveal] .mark { clip-path: none !important; transition: none; }
  .section--ruled::before { transition: none; transform: none !important; }
  .batch__cells i { transition: opacity 0.4s ease, background-color var(--dur-fast) ease; }
  .btn, .btn::before, .btn__icon, .site-nav a::after, .theme-toggle svg, .check__box::after { transition-duration: 0.01ms; }
  .field__error:not(:empty), .form-success:not([hidden]), .form__status.is-error { animation: none; }
  .form-success .mark { animation: none; }
}

/* Windows high contrast removes backgrounds, so ink squares, marks and ticks are redrawn with system colours. */
@media (forced-colors: active) {
  .batch__cells i { forced-color-adjust: none; background: CanvasText; }
  .mark, .portrait__caption, .prose__status, .band--yellow { border: 1px solid CanvasText; }
  .wire__path, .wire__out { stroke: CanvasText; }
  .check__input:checked + .check__box::after { border-color: CanvasText; }
  .site-nav a::after { background: CanvasText; }
  .range { display: none; }                                         /* high contrast needs the words, not the scenery */
  .display, .title { line-height: 1.2; }                             /* high contrast paints a plate behind every line: at 0.96 each plate covered the line above */
  .record::before { forced-color-adjust: none; background: CanvasText; }
}

@media print {
  .site-header, .skip-link, .doc__index { display: none !important; }
  .doc__body { grid-column: 1 / -1; }
  .ledger tr, .qa__row, .clause, .glossary > div { break-inside: avoid; }
  .doc a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 0.85em; }
  [data-reveal], .mark, .batch__cells i { opacity: 1 !important; transform: none !important; clip-path: none !important; }
  .section--ruled::before { transform: none !important; }
  .portrait { position: static; height: auto; }
  .wire__path, .wire__out { animation: none; }
  .range { display: none !important; }                               /* SVG fills print even with backgrounds off: keep the plate on screen only */
  .record::before { transform: none !important; }
  .record.is-tracking li::before { background: var(--accent-yellow-dark) !important; }
}
