/* kiznis.studio — KS-001 publisher record. World: standards manual (DESIGN.md).
   Hero: natural-flow grid — same composition at every width; no absolute collage. */

/* The two voices, self-hosted (assets/fonts/README.md carries provenance + the OFL).
   They used to come from fonts.googleapis.com, which put TWO extra origins on the critical
   path — a stylesheet round-trip to googleapis, then a fresh DNS+TCP+TLS handshake to gstatic
   before one glyph could be requested. Measured 2026-08-29 as an A/B between two Cloudflare
   Pages PREVIEW deploys (same edge, same code but for this change; 4 x 7 cold runs, medians):
   last font byte 700-1080ms -> 169-180ms, document.fonts.ready 813-1116ms -> 542-583ms,
   first-contentful-paint 592-756ms -> 564-584ms. The ranges for the font path do not overlap.
   Fonts now land before first paint, so the record paints in Archivo instead of swapping into
   it, and the page reaches no third party but Cloudflare's own beacon.
   unicode-range values are Google's own, verbatim: latin-ext stays off the wire until a page
   actually contains one of its characters. */
@font-face {
  font-family: 'Archivo'; font-style: normal; font-weight: 400 700; font-stretch: 100%;
  font-display: swap;
  src: url(/assets/fonts/archivo-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Archivo'; font-style: normal; font-weight: 400 700; font-stretch: 100%;
  font-display: swap;
  src: url(/assets/fonts/archivo-latin-ext.woff2) format('woff2');
  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;
}
@font-face {
  font-family: 'Fragment Mono'; font-style: normal; font-weight: 400;
  font-display: swap;
  src: url(/assets/fonts/fragment-mono-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Fragment Mono'; font-style: normal; font-weight: 400;
  font-display: swap;
  src: url(/assets/fonts/fragment-mono-latin-ext.woff2) format('woff2');
  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;
}
:root {
  --paper: #FAFAF8;
  --ink: #111111;
  --accent: #EB3708;
  --hairline: #C9C7C4;
  --grey: #828282;
  --soft: #3d3d3b;
  --grotesque: 'Archivo', 'Helvetica Neue', Helvetica, Arial, sans-serif;
  --mono: 'Fragment Mono', 'SFMono-Regular', Consolas, monospace;
}
* { margin: 0; padding: 0; box-sizing: border-box; }
html { background: var(--paper); scrollbar-color: var(--ink) var(--paper); }
body { font-family: var(--grotesque); color: var(--ink); background: var(--paper); -webkit-font-smoothing: antialiased; }
::selection { background: var(--accent); color: var(--paper); }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
img { max-width: 100%; }

.sheet { max-width: 1536px; margin: 0 auto; }
.comp-frame { position: relative; padding: 0 42px 26px; }

/* masthead */
.masthead { display: flex; align-items: center; justify-content: space-between; gap: 20px; height: 84px; margin: 0 -42px; padding: 0 42px; border-bottom: 2px solid var(--ink); }
.wordmark { font-size: 16px; font-weight: 600; letter-spacing: 0.42em; white-space: nowrap; }
.doc-code { font-family: var(--mono); font-size: 12.5px; letter-spacing: 0.08em; white-space: nowrap; }
.mast-nav { display: flex; gap: 26px; }
.mast-nav a { font-family: var(--mono); font-size: 12px; color: var(--soft); text-decoration: none; white-space: nowrap; }
.mast-nav a:hover { color: var(--accent); }

/* headline */
.headline-wrap { position: relative; padding: clamp(20px, 2.5vw, 40px) 0 clamp(18px, 2.2vw, 34px); }
.headline { font-size: clamp(64px, 9.4vw, 148px); line-height: 1.03; font-weight: 500; letter-spacing: -0.022em; max-width: 15ch; }
.headline .sec-no { color: var(--accent); font-weight: 500; }
.dimtick { position: absolute; left: -34px; top: 38%; font-family: var(--mono); font-size: 9px; color: var(--grey); writing-mode: vertical-rl; letter-spacing: 0.1em; }

/* registration crop marks */
.cropmark { position: absolute; width: 16px; height: 16px; }
.cropmark::before, .cropmark::after { content: ''; position: absolute; background: var(--ink); }
.cropmark::before { width: 16px; height: 1px; top: 8px; }
.cropmark::after { width: 1px; height: 16px; left: 8px; }
.cm-tl { top: 92px; left: 10px; } .cm-tr { top: 92px; right: 10px; }
.cm-bl { bottom: 10px; left: 10px; } .cm-br { bottom: 10px; right: 10px; }

/* ── the spec row: three columns, natural heights ── */
.spec-row { display: grid; grid-template-columns: 29% 1fr 33%; }
.spec-col { padding: 0 28px; display: flex; flex-direction: column; }
.spec-col:first-child { padding-left: 0; }
.spec-col:last-child { padding-right: 0; }
.spec-col + .spec-col { border-left: 1px solid var(--hairline); }
.sec-label { font-family: var(--mono); font-size: 15px; letter-spacing: 0.02em; line-height: 1.3; color: var(--ink); border-top: 1px solid var(--ink); padding-top: 6px; margin-bottom: 14px; }
.sec-label .sec-no { color: var(--accent); font-weight: 700; margin-right: 10px; }
.sec-label-strong { border-top: none; }

.fig { display: block; object-fit: contain; }
.fig-map { width: min(100%, 360px); margin: 6px auto 18px 0; }
.fig-glyph { width: 92px; }
.fig-loop { width: min(100%, 380px); margin: 0 auto; }
.loop-wrap { position: relative; margin-bottom: 16px; }
.loop-center { position: absolute; left: 50%; top: 46%; transform: translate(-50%, -50%); font-family: var(--mono); font-size: 14px; letter-spacing: 0.08em; line-height: 1.5; text-align: center; }

/* portal stats */
.stat-rows { margin-top: auto; }
.stat-rows div { display: grid; grid-template-columns: 32px minmax(92px, max-content) 1fr; column-gap: 14px; align-items: center; border-bottom: 1px solid var(--hairline); padding: 13px 0 12px; }
.stat-rows div:first-child { border-top: 1px solid var(--hairline); }
.stat-rows dt { font-size: 23px; font-weight: 450; letter-spacing: -0.01em; font-variant-numeric: tabular-nums; color: #2c2c2a; }
.stat-rows dd { font-family: var(--mono); font-size: 12px; color: #6b6b69; }
.stat-ic { width: 17px; height: 17px; stroke: #555; fill: none; stroke-width: 1.3; }

/* products */
.prod-grid { display: grid; grid-template-columns: 92px 1fr; gap: 18px 24px; align-items: start; }
.product h2 { font-size: 18px; font-weight: 700; letter-spacing: 0.04em; }
.product h2 a { color: var(--ink); text-decoration: none; border-bottom: 2px solid var(--accent); padding-bottom: 1px; }
.product h2 a:hover { color: var(--accent); }
.product-role { font-family: var(--mono); font-size: 11px; margin-top: 3px; }
.product-line { font-size: 13px; line-height: 1.4; color: var(--soft); margin-top: 6px; border-bottom: 1px solid var(--hairline); padding-bottom: 8px; }
.mini-spec { width: 100%; border-collapse: collapse; margin-top: 6px; }
.mini-spec th { text-align: left; font-family: var(--mono); font-weight: 400; font-size: 11px; padding: 3px 0; color: var(--soft); }
.mini-spec td { text-align: right; font-size: 12.5px; font-weight: 600; font-variant-numeric: tabular-nums; }

/* machine leader table */
.leader-table { width: 100%; border-collapse: collapse; margin-top: auto; }
.leader-table tr { border-bottom: 1px solid var(--hairline); }
.leader-table tr:first-child { border-top: 1px solid var(--ink); }
.leader-table th { text-align: left; font-family: var(--mono); font-weight: 400; font-size: 11px; padding: 6px 0 5px; color: #6b6b69; }
.leader-table td { text-align: right; font-size: 12px; font-weight: 600; font-variant-numeric: tabular-nums; color: #444; }

/* family */
.family { margin-top: 40px; }
.chips { display: grid; grid-template-columns: repeat(4, 1fr) minmax(96px, 130px); gap: 14px; align-items: start; }
.chip { display: block; color: #fff; text-decoration: none; transition: transform .25s cubic-bezier(.16,1,.3,1); }
.chip:hover, .chip:focus-visible { transform: translateY(-2px); }
.chip .bar { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 9px 14px; transition: filter .25s; }
.chip:hover .bar { filter: brightness(1.08); }
.chip b { font-size: 16px; font-weight: 600; letter-spacing: -0.01em; }
.chip span { font-family: var(--mono); font-size: 10.5px; }
.chip i { display: block; font-style: normal; font-family: var(--mono); font-size: 10px; margin-top: 8px; color: var(--soft); }
.chip:hover i, .chip:focus-visible i { color: var(--accent); }
.chip-blue .bar { background: #1C4E9C; }
.chip-green .bar { background: #1E7A46; }
.chip-purple .bar { background: #5B2D8F; }
/* Blue/green/purple are dark fills (white on them is 8.0/5.4/9.5:1); the accent is a mid-tone
   and white on it is only 4.13:1. The Accent-Ground Rule applies here too — ink, 4.57:1. */
.chip-accent .bar { background: var(--accent); color: var(--ink); }
a.chip-more { font-family: var(--mono); font-size: 12px; line-height: 1.4; color: var(--ink); text-decoration: none; align-self: center; }
a.chip-more:hover { color: var(--accent); }

/* footer spec strip */
.specstrip { display: flex; align-items: center; gap: 18px; margin: 44px -42px 0; padding: 14px 42px 0; border-top: 1px solid var(--ink); font-family: var(--mono); font-size: 11.5px; color: #2c2c2a; flex-wrap: wrap; }
.specstrip .sep { width: 1px; height: 16px; background: var(--hairline); }
.specstrip .barcode { margin-left: auto; width: 92px; height: 26px; background: repeating-linear-gradient(90deg, var(--ink) 0 2px, transparent 2px 4px, var(--ink) 4px 5px, transparent 5px 8px); }

/* ── responsive ── */
@media (max-width: 1080px) {
  .comp-frame { padding: 0 22px 26px; }
  .masthead { margin: 0 -22px; padding: 0 22px; height: 64px; }
  .mast-nav, .cropmark, .dimtick { display: none; }
  .spec-row { grid-template-columns: 1fr; }
  .spec-col { padding: 0; }
  .spec-col + .spec-col { border-left: none; margin-top: 34px; }
  .stat-rows, .leader-table { margin-top: 0; }
  .fig-map { margin-bottom: 14px; }
  .chips { grid-template-columns: 1fr 1fr; gap: 12px; }
  .specstrip { margin: 34px -22px 0; padding: 14px 22px 0; gap: 10px 14px; }
  .specstrip .barcode { display: none; }
}
/* The erratum sheet's spec row, above the collapse. Its middle column is the only PROSE in a
   grid whose 29%/1fr/33% tracks were sized for the record's hero, and the prose was never
   fitted to them: measured 2026-08-30, .nf-note drew 322px / 43 characters a line at 1081 —
   NARROWER than the same prose at 390 (346px / 44) — and reached its 46ch cap only at 1323, so
   across most laptop widths the erratum was the worst-set document the studio ships.
   The rule below states the prose track's REQUIREMENT instead of a width: 470px is the 414px
   cap plus the column's 56px of gutters, and grid takes that out of the two spec tables only
   when the row is too narrow to give it away for free. So nothing changes from ~1280 up (the
   tracks resolve to the same 393/515/447 at 1440 as before), and below it the sides give back
   what they were never using — they hold six link labels and five mono spec rows, none of
   which wraps at the tightest resulting width. Measured after: 56 characters a line at every
   width from 700 up, no wrap, no overflow.
   Two alternatives were measured and rejected: a fixed re-proportion (24.7%/1fr/28.1%) fixed
   the dip but narrowed the tables at EVERY width, wrapping the E.2 label at 1440 where it had
   not wrapped; and stacking the row until 1323, as the record does at 1080, was captured and
   read — it strands the leader table across 1116px of paper to win 92px for the prose. */
@media (min-width: 1081px) {
  #erratum .spec-row { grid-template-columns: minmax(0, 29%) minmax(470px, 1fr) minmax(0, 33%); }
}
@media (max-width: 560px) {
  .doc-code { display: none; }
  .wordmark { letter-spacing: 0.3em; font-size: 15px; }
  .chips { grid-template-columns: 1fr; }
}

/* ── bands (sections 4.0–7.0): same spec language ── */
.band { max-width: 1452px; margin: 0 auto; padding: 72px 42px 24px; }
.band-rule { border-top: 1px solid var(--ink); margin-top: 48px; }
.band-label { font-family: var(--mono); font-size: 15px; margin-bottom: 34px; }
.band-label .sec-no { color: var(--accent); font-weight: 700; margin-right: 10px; }
.cols-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 56px; }
.band h2 { font-size: 26px; font-weight: 500; letter-spacing: -0.015em; margin-bottom: 14px; }
.band h2 .sec-no { color: var(--accent); font-family: var(--mono); font-size: 15px; font-weight: 700; vertical-align: 3px; margin-right: 8px; }
.band p { font-size: 16px; line-height: 1.55; color: #2c2c2a; max-width: 58ch; }
.band p + p { margin-top: 12px; }
.band .fine { font-family: var(--mono); font-size: 12px; color: #6b6b69; margin-top: 14px; }
.band a { color: var(--ink); text-decoration-color: var(--accent); text-underline-offset: 3px; }
.band a:hover { color: var(--accent); }

.clauses { list-style: none; display: grid; grid-template-columns: 1fr 1fr; gap: 26px 56px; }
/* The 58ch cap is unconditional, not a mobile rule. Measured 2026-08-30: uncapped, the desktop
   two-up ran 75–83 characters a line at the 1536px sheet — the widest measure on the record,
   wider than the 58ch body prose directly above it. The cap is the record's own body constant,
   and it lives on the LI rather than on the track because `.cols-2` and `.index-grid` are both
   `1fr 1fr` at a 56px gap: narrowing the tracks would move column two off the document's
   column axis, so the leftover measure is left as trailing white exactly as `.band p` does. */
.clauses li { font-size: 15.5px; line-height: 1.5; color: #2c2c2a; border-top: 1px solid var(--hairline); padding-top: 14px; max-width: 58ch; }
.clauses b { display: block; font-weight: 600; color: var(--ink); margin-bottom: 4px; }

.index-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.index-table th { font-family: var(--mono); font-weight: 400; font-size: 11px; text-align: left; color: #6b6b69; border-bottom: 1px solid var(--ink); padding: 0 10px 8px 0; }
.index-table td { border-bottom: 1px solid var(--hairline); padding: 9px 10px 8px 0; }
.index-table td:nth-child(1), .index-table td:nth-child(5) { font-family: var(--mono); font-size: 12px; color: var(--accent); width: 44px; }
.index-table td:nth-child(4), .index-table td:nth-child(8) { font-family: var(--mono); font-size: 12px; color: #6b6b69; width: 44px; }
.index-table a { font-weight: 600; text-decoration: none; color: var(--ink); border-bottom: 1px solid var(--hairline); }
.index-table a:hover { color: var(--accent); border-color: var(--accent); }
.index-more { font-family: var(--mono); font-size: 12.5px; color: #6b6b69; margin-top: 18px; }


.page-foot { max-width: 1452px; margin: 64px auto 0; padding: 22px 42px 46px; border-top: 2px solid var(--ink); display: flex; gap: 18px; align-items: center; font-family: var(--mono); font-size: 12px; color: #2c2c2a; }
.page-foot .foot-right { margin-left: auto; }
/* the printed sheet is the only place the reader has no address bar to read */
.print-url { display: none; }

/* focus + selection carry the design (craft floor: browser surfaces) */
:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
html { scrollbar-color: var(--ink) var(--paper); }

/* ── motion: one authored grammar — sections stamp in, rules draw ── */
@media (prefers-reduced-motion: no-preference) {
  .band, .page-foot { opacity: 0; transform: translateY(14px); transition: opacity .7s cubic-bezier(.16,1,.3,1), transform .7s cubic-bezier(.16,1,.3,1); }
  .band.stamped, .page-foot.stamped { opacity: 1; transform: none; }
  .band-rule { background: linear-gradient(var(--ink), var(--ink)) no-repeat top left / 0% 1px; border-top-color: transparent; }
  .band-rule.stamped { background-size: 100% 1px; transition: background-size 1s cubic-bezier(.16,1,.3,1) .15s; }
}

/* states: chips + links carry hover/focus in-world */
.chip { transition: transform .25s cubic-bezier(.16,1,.3,1); }
.chip:hover, .chip:focus-visible { transform: translateY(-2px); }
.chip:hover i, .chip:focus-visible i { color: var(--accent); }
.chip .bar { transition: filter .25s; }
.chip:hover .bar { filter: brightness(1.08); }



/* product exits carry the document voice, not browser blue */
.product h2 a { color: var(--ink); text-decoration: none; border-bottom: 2px solid var(--accent); padding-bottom: 1px; }
.product h2 a:hover { color: var(--accent); }
a.chip-more { color: var(--ink); text-decoration: none; }
a.chip-more:hover { color: var(--accent); }

/* positioning + actions (the landing's voice and exits) */
.position-line { font-family: var(--mono); font-size: 13.5px; line-height: 1.6; color: var(--soft); max-width: 78ch; margin-top: clamp(14px, 1.6vw, 26px); }
.position-line .sec-no { color: var(--accent); font-weight: 700; margin-right: 10px; }
.hero-actions { display: flex; gap: 34px; flex-wrap: wrap; margin-top: clamp(14px, 1.5vw, 22px); }
.hero-actions a { font-family: var(--mono); font-size: 13px; color: var(--ink); text-decoration: none; border-bottom: 2px solid var(--accent); padding-bottom: 3px; }
.hero-actions a:hover { color: var(--accent); }
@media (max-width: 1080px) { .cols-2 { grid-template-columns: 1fr; } }


/* full catalogue: two half-tables side by side, stacked on mobile (all 154 links render everywhere) */
.index-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0 56px; align-items: start; }
@media (max-width: 1080px) { .index-grid { grid-template-columns: 1fr; gap: 0; } .index-grid table + table { margin-top: -1px; } .index-grid table + table thead { display: none; } }

/* 6.1 SaaS portfolio cards + 6.2 topic column */
.sub-label { font-family: var(--mono); font-size: 14px; font-weight: 400; letter-spacing: 0.02em; border-top: 1px solid var(--ink); padding-top: 6px; margin-bottom: 22px; }
.sub-label .sec-no { color: var(--accent); font-weight: 700; margin-right: 10px; }
.sub-label-gap { margin-top: 46px; }
.saas-cards { display: grid; grid-template-columns: 1fr 1fr; gap: 26px; }
.saas-card { display: flex; flex-direction: column; gap: 7px; text-decoration: none; color: var(--ink); border: 1px solid var(--ink); padding: 22px 24px 18px; transition: transform .25s cubic-bezier(.16,1,.3,1); }
.saas-card:hover { transform: translateY(-2px); }
.saas-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.saas-head b { font-size: 21px; font-weight: 700; letter-spacing: 0.04em; border-bottom: 2px solid var(--accent); padding-bottom: 2px; }
.saas-status { font-family: var(--mono); font-size: 10.5px; color: var(--accent); letter-spacing: 0.08em; }
.saas-role { font-family: var(--mono); font-size: 11.5px; color: var(--soft); }
.saas-line { font-size: 14.5px; line-height: 1.5; color: var(--soft); max-width: 52ch; }
.saas-go { font-family: var(--mono); font-size: 12.5px; margin-top: 8px; }
.saas-card:hover .saas-go, .saas-card:hover .saas-head b { color: var(--accent); }
.index-table td.topic { font-family: var(--mono); font-size: 11px; color: #6b6b69; letter-spacing: 0.02em; }
@media (max-width: 1080px) { .saas-cards { grid-template-columns: 1fr; } }

/* FIG.1 — the counted portfolio (one mark per portal; chip families keep their colors) */
.fig-count-link { display: block; margin: 4px 0 20px; text-decoration: none; }
.fig-count { width: 100%; height: auto; display: block; }
.fc-label { font-family: var(--mono); font-size: 10.5px; fill: #6b6b69; letter-spacing: 0.04em; }
.fc-count { font-family: var(--mono); font-size: 11px; fill: var(--ink); font-weight: 700; }
.fig-count-link:hover .fc-label { fill: var(--accent); }

/* products: typographic records, no figures */
.prod-stack { display: flex; flex-direction: column; gap: 22px; }
.prod-stack .product + .product { border-top: 1px solid var(--hairline); padding-top: 18px; }

/* ── v2 hero: primary CTA · product micro-figures · typographic loop + gates ── */
/* The accent is a MID-tone (L 0.204): paper on it is 3.95:1, ink on it is 4.57:1. So wherever
   the accent is the ground, the type is ink — see DESIGN.md §Colors, The Accent-Ground Rule.
   Hover brightens (the chip-bar grammar) rather than darkening: a darker accent would flip the
   legible text colour back to paper, and a button that swaps ink for paper on hover is a tell. */
.cta-primary { background: var(--accent); color: var(--ink) !important; border-bottom: none !important; padding: 10px 18px !important; font-weight: 700; }
.cta-primary:hover { filter: brightness(1.08); color: var(--ink) !important; }
.hero-actions { align-items: center; }

.eu-grid { display: grid; grid-template-columns: repeat(6, 44px); gap: 6px; margin-top: 10px; }
.eu-grid span { font-family: var(--mono); font-size: 11px; border: 1px solid var(--ink); text-align: center; padding: 7px 0 6px; letter-spacing: 0.06em; }
.eu-grid span:nth-child(2) { background: var(--accent); color: var(--ink); border-color: var(--accent); }
.fig-caption { font-family: var(--mono); font-size: 10.5px; color: #6b6b69; margin-top: 8px; letter-spacing: 0.03em; }

.cite-tree { display: flex; flex-direction: column; gap: 4px; margin-top: 10px; font-family: var(--mono); font-size: 12px; }
.cite-tree .ct-root { font-weight: 700; font-size: 14px; }
.cite-tree .ct-branch i { font-style: normal; color: #6b6b69; margin-left: 8px; font-size: 10.5px; }

.fig-loop-svg { width: min(100%, 340px); display: block; margin: 4px auto 0; }
.loop-num text { font-family: var(--mono); font-size: 13px; font-weight: 700; fill: var(--accent); text-anchor: middle; }
.loop-word text { font-family: var(--mono); font-size: 11px; fill: var(--ink); text-anchor: middle; letter-spacing: 0.08em; }
.loop-mid { font-family: var(--mono); font-size: 12px; fill: var(--ink); text-anchor: middle; letter-spacing: 0.12em; }

.gate-strip { border-top: 1px solid var(--ink); margin-top: 14px; padding-top: 10px; }
.gate-title { font-family: var(--mono); font-size: 10.5px; color: #6b6b69; letter-spacing: 0.08em; margin-bottom: 8px; }
.gate-strip ul { list-style: none; display: grid; grid-template-columns: 1fr 1fr; gap: 7px 16px; }
.gate-strip li { font-family: var(--mono); font-size: 11px; letter-spacing: 0.05em; padding-left: 18px; position: relative; }
.gate-strip li::before { content: ''; position: absolute; left: 0; top: 2px; width: 10px; height: 10px; background: var(--ink); }
@media (max-width: 560px) { .eu-grid { grid-template-columns: repeat(4, 44px); } }

/* v3: register stagger + machine band lead */
@media (prefers-reduced-motion: no-preference) {
  .fig-count rect { opacity: 0; transition: opacity .3s ease-out; transition-delay: var(--d, 0ms); }
  .fig-count.counted rect { opacity: 1; }
}
/* `.band p` (0,1,1) outranks a bare `.machine-lead` (0,1,0), so this lead had been rendering at
   16px/#2C2C2A/58ch — body text — instead of the 19–26px ink lead it declares. Section 4 is the
   thing the record is proudest of and its lead paragraph was silently demoted. Qualified to
   match the rule it has to beat. */
.band p.machine-lead { font-size: clamp(19px, 2vw, 26px); line-height: 1.45; font-weight: 500; letter-spacing: 0; max-width: 34ch; color: var(--ink); margin-bottom: 30px; }
/* 700, not 600: at 390 the lead clamps to 19px, and accent-on-paper is 3.95:1 — which clears AA
   only as large text (>=18.66px AND >=700). One weight step buys the emphasis its legibility. */
.machine-lead b { color: var(--accent); font-weight: 700; }

/* ── final cosmetics: rhythm, 7.x titles, accent closing band ── */
/* one vertical rhythm for all bands */
.band { padding: 64px 42px 28px; }
.band-rule { margin-top: 56px; padding-top: 64px; }
.machine-lead { margin-bottom: 34px; }
.saas-cards { gap: 32px; }

/* 7.x sub-titles: deliberate, in the grotesque voice, generous air */
.band h2.sub-label { font-family: var(--grotesque); font-size: 24px; font-weight: 500; letter-spacing: -0.015em; border-top: 1px solid var(--ink); padding-top: 14px; margin: 0 0 28px; }
.band h2.sub-label .sec-no { font-family: var(--mono); font-size: 14px; vertical-align: 3px; }
.sub-label-gap { margin-top: 64px !important; }

/* 8.0 — the accent closing band (full-bleed). Ink on accent, per the Accent-Ground Rule: this
   band carries the publisher identity, the Wikidata ID and the contact address, so it is the one
   surface on the record that must not be marginal. Paper on accent was 3.95:1, the faded sec-no
   3.20:1 and the translucent fine line 2.89:1 — all below AA at their sizes; every run is now
   4.57:1. There is no soft-ink on this ground (prose ink is 3.39:1), so hierarchy inside the
   band is carried by size, weight and the mono voice alone — not by fading the ink. */
.band-accent { background: var(--accent); color: var(--ink); max-width: none; margin-top: 64px; padding: 72px max(42px, calc((100% - 1368px) / 2)) 64px; }
.band-accent .band-label, .band-accent h2, .band-accent p, .band-accent b { color: var(--ink); }
.band-accent .band-label .sec-no, .band-accent h2 .sec-no { color: var(--ink); opacity: 1; }
.band-accent .fine { color: var(--ink); }
.band-accent a { color: var(--ink); text-decoration: underline; text-decoration-thickness: 1.5px; text-underline-offset: 4px; text-decoration-color: rgba(17, 17, 17, 0.55); }
.band-accent a:hover { color: var(--ink); text-decoration-color: var(--ink); }
/* the focus ring inherits the accent, which on this ground is 1:1 — invisible. Four links in
   this band (Wikidata, the contact address, both products) had no visible focus at all. */
.band-accent :focus-visible { outline-color: var(--ink); }
.band-accent ::selection { background: var(--ink); color: var(--paper); }
.page-foot { margin-top: 0; border-top: none; padding-top: 34px; }
@media (max-width: 1080px) {
  .band { padding: 44px 22px 12px; }
  .band-rule { margin-top: 36px; padding-top: 44px; }
  /* the one two-column region that never got the house collapse (.cols-2, .saas-cards,
     .index-grid and .spec-row all break here). Measured 2026-08-30: at 390 the clause
     column was 145px wide — a real 15 characters a line, so "4.2 — It learns permanently."
     wrapped twice and a two-sentence clause ran to 14 line boxes. The 58ch cap that keeps
     the single column off ~115 characters now lives on `.clauses li` unconditionally. */
  .clauses { grid-template-columns: 1fr; }
  .band-accent { padding: 52px 22px 46px; margin-top: 44px; }
  .band h2.sub-label { font-size: 21px; }
  .sub-label-gap { margin-top: 46px !important; }
}

/* ── E404 erratum sheet (404.html): the record's furniture, its own E.x numbering ── */
.wordmark-link { color: var(--ink); text-decoration: none; }
.wordmark-link:hover { color: var(--accent); }
.nf-req { font-family: var(--mono); font-size: 12px; letter-spacing: 0.03em; color: #6b6b69; margin-top: 14px; word-break: break-all; }
.nf-req span { color: var(--accent); }
.nf-note { font-size: 15px; line-height: 1.55; color: #2c2c2a; max-width: 46ch; }
.nf-note + .nf-note { margin-top: 12px; }
.nf-note-fine { font-size: 13px; color: #6b6b69; margin-top: 18px; }
.nf-map tr:first-child { border-top: 1px solid var(--ink); }
.nf-map th { font-family: var(--grotesque); font-size: 15px; font-weight: 600; color: var(--ink); padding: 11px 0 10px; }
.nf-map th a { color: inherit; text-decoration: none; border-bottom: 1px solid var(--hairline); }
.nf-map th a:hover { color: var(--accent); border-color: var(--accent); }
.nf-map td { font-family: var(--mono); font-size: 12px; font-weight: 400; color: var(--accent); }
.nf-status tr { border-bottom: 1px solid var(--hairline); }
.nf-status tr:first-child { border-top: 1px solid var(--ink); }
.nf-status th, .nf-status td { padding: 9px 0 8px; }
.nf-foot { border-top: 2px solid var(--ink); margin-top: 56px; }
@media (max-width: 1080px) { .nf-foot { margin-top: 40px; } }

/* the page foot is a single flex row; at 390 it crushed its three facts into three narrow
   columns (found reading the E404 mobile slices, 2026-08-29 — same defect on the record). */
@media (max-width: 700px) {
  .page-foot { flex-wrap: wrap; gap: 8px 14px; line-height: 1.5; }
  .page-foot .foot-right { margin-left: 0; flex-basis: 100%; }
  .page-foot .sep { width: 1px; height: 13px; background: var(--hairline); }
}

/* ============================================================================
   PRINT — the record on paper (2026-08-29)

   Measured before written (.work/print baselines), and the measurements changed the job:

   1. The bands stamp in on IntersectionObserver, so a reader who hits Ctrl+P WITHOUT
      scrolling printed eleven pages of which eight were BLANK — sections 4.0 through 8.2,
      including the whole 154-portal catalogue and the contact block, still occupied paper
      at opacity 0. Print is the finished state, exactly as `prefers-reduced-motion: reduce`
      is; everything is stamped unconditionally below.
   2. Chrome's print dialog ships with "Background graphics" OFF. Backgrounds do not print
      under that default — but BORDERS and SVG fills do. Every surface whose legibility
      depended on a painted background (the 8.0 accent band, the family chips, the primary
      CTA, the six gate markers) was invisible or ghosted on the default printout. Each is
      re-expressed here in ink and rule weight rather than fill.
   3. A printed link is a dead end. In-document navigation is dropped; external links carry
      their address in the mono footnote voice — and the catalogue prints each portal's real
      domain (nine are .co.uk, not .com, which the slug alone does not say).
   ============================================================================ */
@media print {
  @page { size: A4; margin: 14mm 13mm; }

  /* 1 — the finished state */
  .band, .page-foot, .band-rule {
    opacity: 1 !important; transform: none !important; transition: none !important;
  }
  .band-rule { background: none !important; border-top: 1px solid var(--ink) !important; }
  .chip { transition: none !important; }

  /* ink on white: the paper tint is a screen ground; on paper it prints as a tinted panel
     inside white margins, i.e. a visible box edge that is not part of the document */
  html, body, .band, .band-accent { background: #fff !important; }
  body { -webkit-print-color-adjust: economy; print-color-adjust: economy; }

  /* furniture that means nothing on paper: in-document nav, registration marks, the
     decorative barcode (a gradient — it would not print under the default anyway) */
  .mast-nav, .cropmark, .dimtick, .specstrip .barcode { display: none !important; }

  /* 2 — surfaces that were painted, re-drawn as rules */
  .cta-primary {
    background: none !important; color: var(--ink) !important;
    border: 2px solid var(--ink) !important; padding: 8px 14px !important;
  }
  .chip .bar {
    background: none !important; border: 1px solid var(--ink);
    padding: 7px 10px; filter: none !important;
  }
  .chip, .chip b { color: var(--ink) !important; }
  .chip span { color: #6b6b69 !important; }
  .gate-strip li::before {
    background: none; border: 1.2px solid var(--ink); width: 9px; height: 9px;
  }
  /* FIG.2's home market: an accent fill behind white type, i.e. a blank cell on paper.
     The accent border already says "this one is different" — the type returns to ink. */
  .eu-grid span:nth-child(2) {
    background: none !important; color: var(--ink) !important;
    border-width: 2px; font-weight: 700;
  }
  .band-accent {
    color: var(--ink) !important; margin-top: 0;
    padding: 26px 0 24px; border-top: 2px solid var(--ink); border-bottom: 2px solid var(--ink);
  }
  .band-accent .band-label, .band-accent h2, .band-accent b { color: var(--ink) !important; }
  .band-accent p { color: #2c2c2a !important; }
  .band-accent .fine { color: #6b6b69 !important; }
  /* the accent returns to its rationed role here — section numbers, as everywhere else */
  .band-accent .band-label .sec-no, .band-accent h2 .sec-no {
    color: var(--accent) !important; opacity: 1;
  }
  .band-accent a { color: var(--ink) !important; text-decoration-color: var(--accent) !important; }

  /* 3 — links carry their address */
  .hero-actions a[href^="http"]::after,
  .band p:not(.fine) a[href^="http"]::after {
    content: " (" attr(href) ")";
    /* inline-block, not inline: text-decoration propagates from the link into inline
       descendants and cannot be switched off there — an atomic box is not underlined */
    display: inline-block;
    font-family: var(--mono); font-size: 10.5px; color: #6b6b69; word-break: break-all;
  }
  /* the catalogue and the chips print the real domain instead of a parenthetical: the slug
     is not the address for the nine UK portals, and a 154-row table has no width to spare */
  .index-table a[href$=".com"]::after, .chip[href$=".com"] b::after { content: ".com"; }
  .index-table a[href$=".co.uk"]::after { content: ".co.uk"; }
  .index-table a::after { font-weight: 400; color: #6b6b69; }
  /* carries its own separator: a bare .sep span would be a visible hairline on screen with
     nothing after it — the print-only fact must not leave furniture behind on the page */
  .print-url {
    display: inline-block; margin-left: 18px; padding-left: 18px;
    border-left: 1px solid var(--hairline);
  }
  /* the colophon's separators are 1px painted rectangles — they vanish with the backgrounds,
     leaving the facts floating in unexplained gaps. A border draws the same 1px on paper. */
  .specstrip .sep, .page-foot .sep {
    background: none !important; width: 0; border-left: 1px solid var(--hairline);
  }

  /* 4 — pagination: nothing orphaned, nothing split mid-thought */
  h1, h2, h3, .sec-label, .band-label, .gate-title, .fig-cap { break-after: avoid-page; }
  .cols-2 > *, .clauses li, .saas-card, .chip, .gate-strip, .stat-rows > div, figure,
  .mini-spec, .specstrip, .page-foot, .eu-grid, .cite-tree { break-inside: avoid; }
  p { orphans: 3; widows: 3; }
  thead { display: table-header-group; }
  tr, .fig-count-link { break-inside: avoid; }

  /* screen gutters are doubled by the @page margin */
  .comp-frame { padding: 0 0 18px; }
  .masthead { margin: 0; padding: 0 0 0; height: auto; padding-bottom: 14px; }
  .band { padding: 28px 0 12px; max-width: none; }
  .band-rule { margin-top: 26px; padding-top: 26px; }
  .page-foot { padding: 16px 0 0; margin-top: 26px; max-width: none; }
}
