/* Breakwater Cyber — the visual system.
   📌 REBUILT 2026-08-02 against `0_BW_DESIGN-SPEC.md`. The previous system had
   ONE strong contrast pair and everything else was mush: the accent failed AA
   wherever it carried text (3.14:1), and the two "different" dark section
   grounds were 1.44:1 apart — the same colour. Structure now comes from
   HAIRLINES AND PANELS, ⛔ never from flooding a section with colour.

   ⛔ NO third-party host. NO CDN font, NO analytics, NO widget.
   ✅ Archivo is SELF-HOSTED and same-origin, so it fires no external request.
      The anonymity claim is untouched — verified against site_prepublish.py. */

/* ══ TYPE ════════════════════════════════════════════════════════════════
   🔴 THE UNLOCK WE NEVER USED. The site shipped on a system stack because
   "no external request" was over-read as "no font file". A self-hosted woff2
   is same-origin. Archivo carries a WIDTH axis (62–125) as well as weight,
   so display type gets real presence without a second file. */
@font-face{
  font-family:Archivo;
  src:url(fonts/Archivo.woff2) format("woff2");
  font-weight:100 900;
  font-stretch:62% 125%;
  font-display:swap;
}

:root{
  /* ── the system. Every shipping pair measured; 0 failures. ── */
  --ground:#FFFFFF;      /* the page */
  --surface:#F2F4F7;     /* a PANEL. ⛔ Never a full-bleed band */
  --ink:#0A0C10;         /* body and headings — 19.57:1 on ground */
  --ink-2:#474D57;       /* secondary ONLY — 8.51:1. ⛔ Never a whole paragraph */
  --rule:#D5D9E0;        /* hairlines — the structure device */
  --volt:#0037FF;        /* THE ACCENT. 7.02:1 BOTH ways — text on white AND
                            white on fill, both AAA. One value does every job */
  --volt-lift:#5B7BFF;--ink-rev-2:#9AA3B2;--err:#B3261E;   /* the accent on dark grounds ONLY — 5.33:1 on night */
  --night:#0A0C10;       /* an EVENT. ⛔ Not a rhythm. Once a page at most */

  --sans:Archivo,Inter,"Helvetica Neue",Helvetica,system-ui,-apple-system,Arial,sans-serif;
  --mono:ui-monospace,SFMono-Regular,"SF Mono",Menlo,Consolas,"Liberation Mono",monospace;

  /* ── the scale: FEWER STEPS, FURTHER APART ── */
  --t-mega:clamp(2.6rem,1rem + 6.6vw,6rem);      /* one per page, the hero only */
  --t-h1:clamp(2rem,1.25rem + 3.2vw,3.3rem);
  /* 🔴 THE HOMEPAGE DISPLAY SCALE. ⛔ NOT --t-h1: that is the PAGE h1 size and
     is correct everywhere else. The hero shrank on 2026-08-04 because the
     rebuilt homepage h1 was given --t-h1, copied from an interior page.
     🎯 Solved for 36px at 320 and 80px at 1440; clamped at 80 so it does not
     keep growing on a 1920 monitor. ⚠️ The SIZE is the decision — the words
     fit around it. */
  --t-display:clamp(2.25rem,1.464rem + 3.93vw,5rem);
  /* 🔴 ONE HERO SIZE FOR ALL ELEVEN PAGES. C-512, PASS N+150.
     ⛔ THERE WERE THREE WAYS OF SAYING TWO SIZES: `--t-display` inline on two pages,
     `--t-h1` inline on four, and `--t-h1` by default on four more. RECLASSING THE
     HEROES DID NOT CREATE THAT; IT MADE IT VISIBLE, because a common ground shows
     what a mixture of grounds hid.
     🎯 THE FLOOR IS THE POINT AND THE FLOOR IS WHAT MOVED. 390px went from 32.5px
     (six pages) and 38.7px (two) to 50.9px, ⛔ a 57% lift on the width this site's
     reader actually holds. The CEILING came DOWN from 69.8px to 68px, because a
     headline correct at 1180 and small at 390 is the common failure and this fixes
     the failure rather than the flattery.
     ⛔ MEASURED IN A BROWSER AT BOTH WIDTHS BEFORE INSTALLING, four candidates. */
  --t-hero:clamp(3rem,2.4rem + 3.2vw,4.25rem);
  /* 🔴 THE HERO LEAD ON NIGHT. C-513. ⛔ 13.26:1 against #0A0C10.
     ⛔ IT REPLACES TWO DIFFERENT ANSWERS, not one bad one: six heroes used
     `.lead.sub` at --ink-rev-2, which measures 7.69:1 and reads dark, and five used
     `.lead-para` which inherits #fff at 19.57:1 and competes with the headline.
     🎯 "THE SUB-HEADER READS TOO DARK" AND "IT MEASURES 7.69" WERE BOTH TRUE, and
     the reason is that they were about DIFFERENT PAGES. ⛔ THE TOKEN IS FIXED, NOT
     THE INSTANCE: lightening the homepage alone would have hidden the split. */
  --ink-rev-1:#CFD5DE;
  --t-h2:clamp(1.45rem,1.1rem + 1.6vw,2.2rem);
  --t-h3:clamp(1.05rem,.98rem + .4vw,1.25rem);
  --t-lead:clamp(1.1rem,1.02rem + .45vw,1.35rem);
  --t-body:clamp(1.0625rem,1rem + .25vw,1.15rem);
  --t-small:clamp(.85rem,.82rem + .15vw,.94rem);
  --t-label:.72rem;
  --t-figure:clamp(2.4rem,1.1rem + 5vw,4.8rem);

  /* ── rhythm. 🔴 HALVED. Was 320px between sections; the homepage ran 6.5
        screens. Structure comes from the hairline, ⛔ not from the gap. ── */
  --gap-section:clamp(2.25rem,1.1rem + 3vw,4.25rem);
  --gap-block:clamp(1.5rem,.9rem + 2vw,2.5rem);
  --pad-x:clamp(1.25rem,.6rem + 2.6vw,2.5rem);
  --wide:1180px;
  --measure:64ch;
}

*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0;background:var(--ground);color:var(--ink);
  font:400 var(--t-body)/1.55 var(--sans);
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
img,svg{max-width:100%}

h1,h2,h3{margin:0 0 .5em;font-weight:600;letter-spacing:-.035em;line-height:1.02;color:var(--ink)}
h1{font-size:var(--t-h1)}
h2{font-size:var(--t-h2)}
h3{font-size:var(--t-h3);letter-spacing:-.015em;line-height:1.25}
p{margin:0 0 1em}
a{color:var(--volt);text-underline-offset:.18em;text-decoration-thickness:1px}
a:hover{text-decoration:none}
strong{font-weight:600}
.measure{max-width:var(--measure)}
.small{font-size:var(--t-small);color:var(--ink-2)}
.lead-para{font-size:var(--t-lead);line-height:1.45;letter-spacing:-.012em}
.sub{color:var(--ink-2)}

/* ══ THE LABEL — 🎯 THE TELL. A mono label on a hairline is what makes a
   section read as DESIGNED rather than as a paragraph with a heading. ══ */
.label,.eyebrow{
  display:block;margin:0 0 1.1rem;
  font:500 var(--t-label)/1.3 var(--mono);
  letter-spacing:.14em;text-transform:uppercase;color:var(--ink-2);
}

/* ══ LAYOUT ══════════════════════════════════════════════════════════════
   🔴 THE BUG THIS FIXES. `.wrap` carries `margin:0 auto`, which centres it
   inside a BLOCK parent — correct. But inside a COLUMN FLEX parent an auto
   cross-axis margin CANCELS `stretch`, so the nav collapsed to content width:
   414px nav against a 1120px body, in a 1425px viewport. `width:100%` restores
   it without giving up the centring. ⛔ Do not remove either declaration. */
.wrap{width:100%;max-width:var(--wide);margin:0 auto;padding-inline:var(--pad-x)}
.wrap-narrow{width:100%;max-width:760px;margin:0 auto;padding-inline:var(--pad-x)}

/* 🔴 A HAIRLINE SEPARATES SECTIONS. ⛔ NOT AN ALTERNATING BAND. Bands were
   survivable at 1.44:1; at real contrast they strobe. */
section{padding-block:var(--gap-section);border-top:1px solid var(--rule)}
section:first-of-type{border-top:0}

/* ── the 12-column grid, used ASYMMETRICALLY. 🎯 Asymmetry is what reads as
      designed. ⛔ No centred body text anywhere. ── */
.g{display:grid;grid-template-columns:repeat(12,1fr);gap:clamp(1rem,2.2vw,2.4rem)}
.c1-6{grid-column:1/7}   .c1-7{grid-column:1/8}   .c1-5{grid-column:1/6}
.c7-12{grid-column:7/13} .c5-12{grid-column:5/13} .c1-12{grid-column:1/13}
.c6-12{grid-column:6/13}
.c8-12{grid-column:8/13}
@media(max-width:860px){
  .c1-6,.c1-7,.c1-5,.c7-12,.c5-12,.c6-12,.c8-12{grid-column:1/13}
}
.cols{display:grid;gap:var(--gap-block);grid-template-columns:1fr}
@media(min-width:860px){ .cols-2{grid-template-columns:minmax(0,1fr) minmax(0,1fr)} }
.end{align-self:end}

/* ══ NIGHT — an EVENT, ⛔ not a rhythm ═════════════════════════════════ */
.dark{background:var(--night);color:#fff;border-top:0}
.dark h1,.dark h2,.dark h3{color:#fff}
.dark .label,.dark .eyebrow,.dark .small,.dark .sub{color:var(--ink-rev-2)}
.dark a{color:var(--volt-lift)}

/* ── the staging banner. 🔴 Must not survive publish; the gate checks. ── */
.staging{background:var(--volt);color:#fff;font:500 .78rem/1.35 var(--sans);
  letter-spacing:.01em;padding:.6rem var(--pad-x);text-align:center}

/* ══ NAV ═════════════════════════════════════════════════════════════════
   📌 THE MENU IS COLLAPSED AT EVERY WIDTH, decided 2026-08-02. It was inline
   above 960px and the links crowded; a panel solves the spacing, keeps the bar
   clean, and lets items be added later without re-tuning the gaps.
   ⚠️ THE TRADE, STATED: a nav behind a control is used less than a nav on
   display. ✅ It is the right trade HERE because the nav is not the conversion
   path — the CTA is, and the CTA NEVER GOES IN THE MENU.

   🔴 THE MENU SHIPS OPEN AND SCRIPT COLLAPSES IT. A closed <details> cannot be
   re-opened by CSS — verified — so closing it in markup would strand a
   no-script visitor with no navigation at all. Same fail-visible inversion as
   `.rise`: script only ever takes away what already works. */
.site-head{position:sticky;top:0;z-index:40;background:var(--ground);
  border-bottom:1px solid var(--rule)}
.dark .site-head{background:var(--night);border-bottom-color:rgba(255,255,255,.18)}
.nav{display:flex;align-items:center;gap:clamp(.9rem,2vw,1.6rem);
  padding-block:.85rem;font-size:.95rem}
.nav .brand{margin-right:auto;display:flex;align-items:center;min-height:44px}
/* 🔴 THE LOCKUP IS FULL SIZE AT EVERY WIDTH. 27px, ⛔ no clamp. C-487, PASS N+142.
   ⛔ THIS UNDOES STEP ③ OF N+140, and it undoes it because step ③ was buying width
   for a button that is no longer in the header. ⛔ The button moved into the menu
   panel, and the header is now the lockup and the burger and nothing else.
   ⛔ MEASURED, header total against the viewport:
        lockup 27px x the 8:1 viewBox   216.0px
        summary (burger 19 + pad 3.2)    22.2px
        one gap, clamp(.9rem,2vw,1.6rem) 14.4px
        --pad-x, both sides              40.0px
        ────────────────────────────── TOTAL 292.6px
        at 390px  +97px spare      at 360px  +67px spare      at 344px  +51px spare
   ⚠️ ⛔ THIS IS ARITHMETIC FROM THIS STYLESHEET AND THE REAL ARCHIVO FACE.
   ⛔ IT IS NOT A RENDER AND IT IS NOT EVIDENCE THAT THE HEADER LOOKS RIGHT. */
.nav .brand img{height:27px;width:auto;display:block}
.nav .brand img.brand-mark{display:none}
.nav a{color:var(--ink);text-decoration:none;display:inline-flex;align-items:center;
  min-height:44px;font-weight:500;letter-spacing:-.008em}
.nav a:hover{color:var(--volt)}
.dark .nav a{color:#fff}
.dark .nav a:hover{color:var(--volt-lift)}
.nav-cta{min-height:44px;padding:.55rem 1.15rem;font-size:.95rem}

/* ── the disclosure, at EVERY width ── */
.navlinks{position:relative}
.navlinks > summary{display:inline-flex;align-items:center;gap:.55rem;
  min-height:44px;padding-right:.2rem;list-style:none;cursor:pointer;
  color:inherit;font:500 .95rem/1 var(--sans);letter-spacing:-.008em}
/* 🔴 THE WORD "Menu" IS HIDDEN VISUALLY AND KEPT FOR ASSISTIVE TECH. C-482.
   ⛔ It was 40px beside a burger that already says menu, and 40px is the difference
   between a brand name on a phone and a mark alone. ⛔ NOT DELETED: a <summary>
   containing only three drawn <i> bars has no accessible name at all. */
.vh{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;
  clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}
.navlinks > summary::-webkit-details-marker{display:none}
.navlinks > summary:hover{color:var(--volt)}
.dark .navlinks > summary:hover{color:var(--volt-lift)}
/* 🎯 THE BARS ARE DRAWN, ⛔ not a glyph — a glyph would be a font dependency
   and would not animate. Three rules that become a cross when open. */
.burger{display:block;width:19px;height:13px;position:relative;flex:0 0 auto}
.burger i{position:absolute;left:0;width:100%;height:1.75px;background:currentColor;
  transition:transform .18s ease,opacity .14s ease}
.burger i:nth-child(1){top:0}
.burger i:nth-child(2){top:5.6px}
.burger i:nth-child(3){top:11.2px}
.navlinks[open] .burger i:nth-child(1){transform:translateY(5.6px) rotate(45deg)}
.navlinks[open] .burger i:nth-child(2){opacity:0}
.navlinks[open] .burger i:nth-child(3){transform:translateY(-5.6px) rotate(-45deg)}
.navlinks .items{display:flex;flex-direction:column;align-items:flex-start;
  position:absolute;right:0;top:calc(100% + .85rem);min-width:230px;
  background:var(--ground);border:1px solid var(--rule);padding:.4rem 1.1rem .8rem;
  z-index:45}
.dark .navlinks .items{background:var(--night);border-color:rgba(255,255,255,.22)}
.navlinks .items > a{width:100%;padding-block:.15rem;font-size:1.02rem}
/* 🔴 THE CALL BUTTON LIVES IN THE PANEL NOW, FIRST. C-487.
   ⛔ It keeps .cta so it keeps the button's own weight, colour and 52px floor.
   ⛔ Full width because a button at content width, alone above six plain links,
   reads as a seventh link that somebody coloured in. */
.navlinks .items > .cta{width:100%;margin:.35rem 0 .7rem;order:-1}
/* 🔴 ONE BUTTON PER WIDTH, ⛔ NEVER TWO ON SCREEN AT ONCE. C-502, PASS N+146.
   ⛔ N+145 moved the call button into the panel at EVERY width, because the burger
   runs at every width and the move had no breakpoint in it. ⛔ THAT WAS A PHONE
   ARGUMENT APPLIED TO A DESKTOP: at 390 the button was competing with the brand name
   for 350px, and at 1180 it was competing with nothing.
   ⛔ There are now two instances in the markup and exactly one is ever displayed, so
   only one is ever in the accessibility tree. ⛔ 720px is the boundary because it is
   already the graphics breakpoint, ⛔ and a second number invents a second layout. */
.nav > .nav-cta{display:none}
@media(min-width:721px){
  .nav > .nav-cta{display:inline-flex}
  .navlinks .items > .cta{display:none}
}
/* 🔴 THE PANEL HANGS OFF THE HEADER, ⛔ NOT OFF THE VIEWPORT. C-499, PASS N+145.
   ⛔ IT WAS `position:fixed` WITH `top:auto`, and `auto` MEANS "THE STATIC POSITION".
   ⛔ MEASURED at five scroll offsets: the engine resolved that to a FROZEN 57.5938px
      and pinned the panel there forever — 57.6 at scrollY 0, and still 57.6 with the
      header's own rect forced to MINUS 2,800.
   🎯 SO THE PANEL WAS NEVER ATTACHED TO THE HEADER. It only LOOKED attached because
      Chrome's number happens to equal where the stuck header sits.
   ⛔ The static position of a child of a `position:sticky` ancestor is the one thing
      engines have no settled answer for. An engine resolving it against the DOCUMENT
      rather than the STUCK header places the panel at 57.6 minus the scroll, which is
      off the top of the screen: correct at the top of a page, gone after scrolling.
   ✅ `absolute` + `top:100%` against the already-sticky `.site-head` REMOVES THE
      QUESTION rather than tuning the answer. There is no static position to resolve.
   ⛔ `.navlinks` goes `static` so the containing block becomes `.site-head`, which is
      what gives `left:0;right:0` the full page width that `fixed` was being used for.
   ⚠️ NOT REPRODUCED IN CHROME. This is a hypothesis with a deploy attached. */
@media(max-width:560px){
  .navlinks{position:static}
  .navlinks .items{position:absolute;left:0;right:0;top:100%;min-width:0;border-left:0;
    border-right:0;padding:.5rem var(--pad-x) 1rem}
}
/* 🔴 BELOW 300px THE LOCKUP BECOMES THE MARK ALONE. C-489, ⛔ AND THE NUMBER HAS
   MOVED TWICE: 430 ➡️ 344 at N+140, ⛔ 344 ➡️ 300 here.
   ⛔ 430 WAS THE WIDTH AT WHICH THE LOCKUP STOPPED FITTING BEFORE THE HEADER WAS CUT
   DOWN. ⛔ 344 was measured against a header that still carried the call button.
   ⛔ THE BUTTON IS NOW IN THE PANEL BELOW 721, so the header is the lockup and the
   burger and nothing else: 216 + 22.2 + 14.4 + 40 = 292.6px, ⛔ which fits 300 with
   7px spare and fits nothing below it.
   🎯 EACH TIME THE OLD NUMBER SURVIVED ITS OWN REASON it was hiding the brand name
   on phones that had room for it, ⛔ which is §107 arriving twice at the same rule.
   ⚠️ Below 300 the mark alone is still correct: the alternative is a wrapped header,
   ⛔ and no phone in the fleet is under 320. */
@media(max-width:300px){
  .nav .brand img.brand-lockup{display:none}
  .nav .brand img.brand-mark{display:block;height:26px;width:auto}
}

/* ══ HERO ════════════════════════════════════════════════════════════════ */
.hero{padding-block:clamp(2.5rem,5vw,4.5rem) clamp(3rem,6vw,5rem);border-top:0}
/* 🔴 ONE HERO PATTERN. C-512. ⛔ Same structure, same tokens, same spacing, on all
   eleven. ⛔ THE ONE DECLARED VARIABLE IS THE CONTAINER: `.wrap` on the six wide
   pages and `.wrap-narrow` on the five narrow ones, ⛔ BECAUSE THE HERO MUST SHARE
   ITS PAGE'S LEFT EDGE. A `.wrap` hero over a `.wrap-narrow` body starts its text at
   40px while the prose below starts at 250px, and a headline that does not line up
   with its own page is a worse defect than two container names.
   ⛔ THE LABEL IS PRESENT WHERE THE PAGE'S NAME IS NOT THE HEADLINE: privacy, terms
   and 404 carry it, `about` does not, because its h1 already says About. That is a
   rule rather than drift, and it is why four of eleven have one. */
.hero h1{font-size:var(--t-hero);letter-spacing:-.032em;line-height:1.02;
  max-width:17ch;margin-bottom:.28em}
.hero .lead{font-size:var(--t-lead);max-width:52ch;color:var(--ink-2);margin-bottom:1.6rem}
.hero.dark .lead{color:var(--ink-rev-1)}
/* 🔴 `.terms` ON NIGHT WAS 2.30:1. C-515, ⛔ AND IT IS NOT A LEGIBILITY PREFERENCE.
   ⛔ `.terms` sets --ink-2 #474D57, which is a MID GREY FOR WHITE PAPER. On #0A0C10
   it measures 2.30:1 against a 4.5 floor, ⛔ and the paragraph it styles is the
   BILLING PARAGRAPH: the flat rate, the deposit, the minimum term.
   ⛔ IT TAKES --ink-rev-1, THE TOKEN STANDARDISED AT N+150, ⛔ NOT A NEW VALUE and
   ⛔ NOT PURE WHITE: at 19.57:1 white would sit level with the headline, and a
   billing note is secondary to a headline even when it must be readable. */
.dark .terms{color:var(--ink-rev-1)}
/* 🔴 THE CONTOURS SIT ON THE HERO PATTERN, ⛔ NOT ON ONE PAGE. C-510.
   ⛔ A background rather than eleven <img> tags: one rule, one file, and no element
   to keep out of the accessibility tree on every page. `bottom` keeps the deepest
   contours at the deepest edge, which is the only orientation a chart convention
   allows.
   🔴 THE SCRIM IS NOT DECORATION AND IT IS THE WHOLE FIX. `cover` alone was
   INSTALLED AND RENDERED FIRST, and on a short hero it scaled the drawing to the
   full height and RAN THE CONTOURS THROUGH THE LEAD PARAGRAPH ON SIX PAGES — the
   exact failure that got variant C rejected, arriving through geometry instead of
   opacity. ⛔ CAUGHT BY THE SCREENSHOT, ⛔ NOT BY THE RULE.
   ⛔ A night-to-transparent gradient over the top 58% hides the drawing behind all
   the type and reveals it only along the lower edge, at every hero height, without
   touching the artwork. */
.hero.dark{
  background-image:linear-gradient(to top,rgba(10,12,16,0) 0%,var(--night) 58%),
                   url(hero-bathymetric.svg);
  background-size:100% 100%,cover;
  background-position:center bottom,center bottom;
  background-repeat:no-repeat,no-repeat}
.hero-acts{display:flex;flex-wrap:wrap;gap:.8rem;align-items:center;margin:0}

/* ══ BUTTONS — 44px minimum, always. ⛔ No radius, no shadow, no gradient ══ */
.cta,.btn{display:inline-flex;align-items:center;justify-content:center;
  min-height:52px;padding:.9rem 1.7rem;border:0;cursor:pointer;
  font:600 clamp(1rem,.96rem + .2vw,1.08rem)/1.15 var(--sans);letter-spacing:-.012em;
  text-decoration:none;background:var(--volt);color:#fff;
  transition:background .16s ease}
.cta:hover,.btn:hover{background:var(--ink);color:#fff}
.cta:active{transform:translateY(1px)}
.cta[disabled],.btn[disabled]{background:var(--ink-2);cursor:not-allowed}
/* 🔴 THE BUTTON MUST WIN WHEREVER IT LANDS. `.nav a{color:var(--ink)}` and
   `.dark a{color:var(--volt-lift)}` are both (0,2,0); `.cta{color:#fff}` is
   (0,1,0), so BOTH beat it. Measured result: ink on volt 2.79:1 in the nav, and
   volt-lift on volt 1.91:1 in the night block — nearly invisible.
   🎯 SAME CLASS AS `.cite` AND `.field`: a SCOPED rule silently overriding a
   COMPONENT. A component that changes meaning depending on its container is not
   a component. ⛔ Do not fix this by weakening the scoped rules. */
.nav a.cta,.nav a.btn,.dark a.cta,.dark a.btn,
a.cta,a.btn{color:#fff}
.nav a.cta:hover,.dark a.cta:hover,a.cta:hover{color:#fff}
.dark a.cta{background:var(--volt)}
.dark a.cta:hover{background:#fff;color:var(--ink)}
/* 🔴 THE TWO BUTTON STYLES, NAMED. C-514, PASS N+151.
   ⛔ THEY HAD NO NAMES, WHICH IS WHY THEY DRIFTED: a hero link was a text link on one
   page and a bordered button on another, and nothing said which was which.
   ✅ PRIMARY   = `.cta` — filled volt, white text, 52px. ⛔ ONE PER VIEW.
   ✅ SECONDARY = `.btn-ghost` — transparent, 1.5px inset border, ink or white text.
      ⛔ Same size and same shape as primary; ⛔ only the fill differs, ⛔ so the pair
      reads as one control and one alternative rather than two competing offers.
   ⚠️ AND THERE IS ALREADY A THIRD, `.ghost`, WHICH IS SECONDARY AT UTILITY SIZE:
      44px instead of 52, small type, a --rule border instead of an ink one. It is
      used only by the readout's Copy link and Print. ⛔ NOT MERGED HERE, because
      merging it is a change nobody asked for and it would touch the one view that
      has never been seen by a stranger. ⛔ RECORDED so the next reader knows there
      are three and that two of them are the same idea at two sizes. */
.btn-ghost{background:transparent;color:var(--ink);box-shadow:inset 0 0 0 1.5px var(--ink)}
.nav a.btn-ghost,a.btn-ghost{color:var(--ink)}
.dark a.btn-ghost{color:#fff}
.btn-ghost:hover{background:var(--ink);color:#fff}
.dark .btn-ghost{color:#fff;box-shadow:inset 0 0 0 1.5px #fff}
.dark .btn-ghost:hover{background:#fff;color:var(--ink)}
.arrow{display:inline-flex;align-items:center;min-height:44px;font-weight:600}

/* 🔴 THE SERVICE LIST. C-507, PASS N+149. ⛔ SHAPE ONLY, ⛔ NO NEW TYPE.
   ⛔ Nine services were one run-on sentence with eight commas, which reads as ONE
   THING OF UNKNOWN SIZE. The list is the same nine words-for-words; what changes is
   that a reader can COUNT them, and the count is the argument.
   ⛔ NO DISPLAY SIZES, ⛔ NO INVERSION, ⛔ NO OFFSETS, ⛔ NO LETTERSPACING. Body type,
   the site's own hairline, and the measure it already uses.
   🎯 THE LESSON THIS RULE EXISTS TO RECORD: what improved the page was giving the
   content THE SHAPE IT ALREADY HAD. A treatment applied to it was rejected in the
   same pass. ⛔ STRUCTURE BEFORE TYPOGRAPHY. */
.svc{list-style:none;margin:0 0 1.4rem;padding:0;max-width:var(--measure)}
.svc li{border-bottom:1px solid var(--rule);padding:.62rem 0}
.svc li:last-child{border-bottom:0}
.svc .small{display:block;margin:.35rem 0 0}

/* 🔴 THE DATA TABLE HAD NO RULE AT ALL. C-496, PASS N+150.
   ⛔ `<table class="data rise">` shipped with NO `table` rule and NO `.data` rule
   anywhere in this stylesheet, so it rendered with the browser's own zero cell
   padding: "2023" and "30" ran together with nothing between them.
   ⛔ FOUND BY A SCREENSHOT AT 390, not by any gate — the markup is valid and the
   class is spelled correctly; it simply pointed at nothing.
   ⛔ Hairline rows and the site's own mono for figures. NO ZEBRA, no vertical rules:
   a three-row table does not need help being read, it needs space.
   ⚠️ `overflow-x:auto` on the wrapper is deliberate. `body{overflow-x:hidden}` means
   an overflow here is CLIPPED AND UNREACHABLE rather than scrollable, and a table
   that silently loses a column is worse than one that scrolls. */
table.data{width:100%;border-collapse:collapse;margin:1.2rem 0 0;
  font-size:var(--t-small);display:block;overflow-x:auto}
table.data caption{caption-side:bottom;margin-top:.7rem;text-align:left;
  font-size:var(--t-small);color:var(--ink-2)}
table.data th,table.data td{padding:.55rem .9rem .55rem 0;text-align:left;
  vertical-align:top;border-bottom:1px solid var(--rule)}
table.data th{font-weight:600;letter-spacing:-.008em}
table.data tbody td{font-family:var(--mono);font-feature-settings:"tnum" 1}
table.data tbody tr:last-child td{border-bottom:0}
.dark table.data th,.dark table.data td{border-bottom-color:rgba(255,255,255,.2)}
.dark .svc li{border-bottom-color:rgba(255,255,255,.2)}

/* 🔴 THE READOUT'S OWN CONTROLS. C-493, ⛔ AND THEY WERE THE ONLY VISIBLE BREAK IN
   THE SYSTEM: `Copy link` and `Print` rendered as the browser's DEFAULT ROUNDED
   GRADIENT BUTTONS, and the share field as a default inset box, ⛔ inside a
   stylesheet whose button comment says "⛔ No radius, no shadow, no gradient".
   ⛔ Seen for the first time at N+143, because until then nobody had opened the
   readout in a browser at all.
   🎯 `.ghost` IS NOT `.btn-ghost`: that one is a page-scale action at 52px with a
   1.5px inset rule. These two sit beside a text field in a utility row and are
   SECONDARY BY INTENT, so they take the same square shape and border language at
   the smaller size rather than a new one. ⛔ Same 44px touch floor as every other
   control on the site. */
.ghost{display:inline-flex;align-items:center;justify-content:center;min-height:44px;
  padding:.5rem 1rem;border:0;box-shadow:inset 0 0 0 1.5px var(--rule);
  background:transparent;color:var(--ink);cursor:pointer;
  font:500 var(--t-small)/1.2 var(--sans);letter-spacing:-.008em}
.ghost:hover{box-shadow:inset 0 0 0 1.5px var(--ink);color:var(--ink)}
.dark .ghost{color:#fff;box-shadow:inset 0 0 0 1.5px rgba(255,255,255,.3)}
.dark .ghost:hover{box-shadow:inset 0 0 0 1.5px #fff}
/* ⛔ The field is READONLY and exists to be selected and copied, ⛔ not typed into,
   so it reads as a monospace specimen of the link rather than as an input. */
.sharein{min-height:44px;padding:.5rem .7rem;border:0;
  box-shadow:inset 0 0 0 1.5px var(--rule);background:var(--surface);
  color:var(--ink-2);font:400 var(--t-small)/1.2 var(--mono);
  width:min(100%,26rem);max-width:100%;margin-right:.5rem;margin-bottom:.5rem}
.sharein:focus{color:var(--ink)}
:focus-visible{outline:3px solid var(--volt);outline-offset:3px}

/* ══ THE FIGURE — a number as an object ══════════════════════════════════ */
.fig{font:600 var(--t-figure)/.88 var(--mono);letter-spacing:-.045em;
  font-feature-settings:"tnum" 1;color:var(--ink);margin:0}
.fig.volt{color:var(--volt)}
.dark .fig.volt{color:var(--volt-lift)}
.fig-cap{font:500 var(--t-label)/1.35 var(--mono);letter-spacing:.13em;
  text-transform:uppercase;color:var(--ink-2);margin:.55rem 0 0}
.figs{display:flex;gap:clamp(1.8rem,5vw,4rem);flex-wrap:wrap;align-items:flex-end}

/* ══ THE MATRIX — a schedule, drawn ══════════════════════════════════════ */
.mx{width:100%;border-collapse:collapse;margin-top:var(--gap-block)}
.mx caption{text-align:left;font:500 var(--t-label)/1.3 var(--mono);
  letter-spacing:.14em;text-transform:uppercase;color:var(--ink-2);padding-bottom:.9rem}
.mx th{text-align:left;font:500 var(--t-label)/1.3 var(--mono);letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink-2);padding:0 1rem .8rem 0;
  border-bottom:1.5px solid var(--ink);white-space:nowrap}
.mx td{padding:.95rem 1rem .95rem 0;border-bottom:1px solid var(--rule);vertical-align:top}
.mx td:last-child{color:var(--ink);font-weight:600}
.mx .c{font:400 .82rem/1.45 var(--mono);color:var(--ink-2)}
.dark .mx th{color:var(--ink-rev-2);border-bottom-color:#fff}
.dark .mx td{border-bottom-color:rgba(255,255,255,.18)}
.dark .mx td:last-child{color:#fff}
.dark .mx .c{color:var(--ink-rev-2)}
@media(max-width:720px){
  .mx thead{position:absolute;left:-9999px}
  .mx tr{display:block;border-bottom:1px solid var(--rule);padding:.9rem 0}
  .mx td{display:block;border:0;padding:.15rem 0}
  .mx td:last-child{padding-top:.4rem}
}

/* ══ THE SPLIT — ours / yours ════════════════════════════════════════════ */
.split{display:grid;grid-template-columns:1fr 1fr;border:1.5px solid var(--ink);
  margin-top:var(--gap-block)}
.split > div{padding:clamp(1.1rem,2.4vw,1.8rem)}
.split > div:first-child{border-right:1.5px solid var(--ink)}
.split h3{font:500 var(--t-label)/1.3 var(--mono);letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink-2);margin-bottom:.9rem}
.split ul{margin:0;padding-left:1.05rem}
.split li{margin-bottom:.5rem;line-height:1.45}
/* 🔴 STACKED FIGURES. `.figs` is a flex ROW; in a half-width panel the three
   would overflow — measured: 92 + 184 + 92px of numerals plus two gaps of up
   to 64px against a 484px inner column, and each caption is 219–236px on its
   own. ⛔ NOT a scoped `.split .figs` override: a component whose appearance
   depends on where it sits is not a component (FAILURE-CLASSES §24). */
.figs-col{flex-direction:column;align-items:flex-start;
  gap:clamp(1.1rem,2.5vw,1.6rem)}
.figs-col .fig-cap{margin-top:.35rem}
.split .scope{margin:1.1rem 0 0;padding-top:.9rem;border-top:1px solid var(--rule);
  color:var(--ink-2);font-size:var(--t-small)}
.split .sum{margin:1.3rem 0 0;color:var(--ink-2);font-size:var(--t-small)}
.dark .split .scope{border-top-color:rgba(255,255,255,.18)}
.dark .split{border-color:#fff}
.dark .split > div:first-child{border-right-color:#fff}
@media(max-width:700px){
  .split{grid-template-columns:1fr}
  .split > div:first-child{border-right:0;border-bottom:1.5px solid var(--ink)}
  .dark .split > div:first-child{border-bottom-color:#fff}
}

/* ══ INCLUSION / EXCLUSION LISTS ═════════════════════════════════════════
   🔴 BOTH COLUMNS STAY AT BODY SIZE. Equal weight IS the message; a smaller
   exclusions list is the oldest tell there is. */
.incl{max-width:78ch}
.incl h3.grp{font:500 var(--t-label)/1.3 var(--mono);letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink);margin:1.8rem 0 .6rem}
.dark .incl h3.grp{color:#fff}
.incl h3.grp:first-child{margin-top:0}
.incl ul{margin:0 0 .2rem;padding-left:1.05rem}
.incl li{margin:0 0 .55rem;line-height:1.5}
.incl .cite{display:inline}
/* 🔴 ⛔ NO CSS `columns` HERE. Multi-column broke the grouped list wherever the
   browser chose: "Every year" jumped to column two while "The documents" stayed
   in column one, and items split mid-group. `break-inside:avoid` does not hold
   on long lists. ✅ A GRID, ONE CELL PER GROUP — the structure the content
   already has, used rather than fought. */
.incl{display:grid;gap:clamp(1.4rem,3vw,2.6rem);grid-template-columns:1fr;max-width:none}
@media(min-width:820px){
  .incl{grid-template-columns:repeat(auto-fit,minmax(240px,1fr))}
}
.incl-col{min-width:0}
.incl-col h3.grp{margin-top:0}

/* ══ THE CITATION ════════════════════════════════════════════════════════
   ⛔ NO `white-space:nowrap` HERE. It was added for the short page citations
   and made the TOOL's sentence-length citations 622px wide inside a 320px
   overlay. FAILURE-CLASSES §24. */
.cite{display:inline-block;font-family:var(--mono);font-size:.84em;
  letter-spacing:0;color:var(--ink-2)}
.cite a{color:var(--ink-2);text-decoration-color:var(--rule)}
.cite a:hover{color:var(--volt)}
.dark .cite,.dark .cite a{color:var(--ink-rev-2)}
.dark .cite a:hover{color:var(--volt-lift)}
.mono{font-family:var(--mono);font-feature-settings:"tnum" 1;letter-spacing:0}

/* ══ THE ACCORDION ═══════════════════════════════════════════════════════
   🔴 REMOVED AT N+145. ⛔ THIRTEEN RULES — `.qa`, `.qa details`, `.qa summary`, the
   `+`/`−` marker, the row borders, the dark variants — ⛔ AND `class="qa"` APPEARED
   NOWHERE IN THE SITE. Found by C-498's class gate, ⛔ which is the first thing here
   that ever compared the stylesheet to the markup.
   ⚠️ AND SAYING THE COST OUT LOUD: the seven questions on `compliance-package` are
   still `<details>`, so they now KEEP the browser's default grey triangle. ⛔ C-492
   IS NOT CLOSED BY THIS REMOVAL — it is one attribute away from closed in the other
   direction, by putting `class="qa"` on the container these rules were written for.
   ⛔ THE INSTRUCTION WAS TO REMOVE THEM AND THEY ARE REMOVED. ⛔ The alternative is
   recorded here rather than argued, because a deleted rule with no note is how the
   next person rewrites it from scratch. */


/* ══ THE CLAUSE — shown, ⛔ not described ════════════════════════════════ */
.clause{border-left:3px solid var(--ink);padding:1.3rem 0 .4rem 1.5rem;
  margin:var(--gap-block) 0;max-width:76ch}
.clause-head{font:500 var(--t-label)/1.3 var(--mono);letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink);margin-bottom:1rem}
.dark .clause{border-left-color:rgba(255,255,255,.30)}
.dark .clause-head{color:#fff}

/* ══ THE PULL QUOTE — reserved for the REGULATOR'S OWN WORDS ════════════ */
.pull{margin:0 0 1.4rem;padding:0 0 0 1.2rem;border-left:3px solid var(--ink)}
.pull p{font-size:var(--t-lead);line-height:1.4;letter-spacing:-.012em;margin:0 0 .5rem}
.pull .cite{display:block;font-size:var(--t-small)}
.dark .pull{border-left-color:rgba(255,255,255,.30)}

.photo{aspect-ratio:4/5;background:var(--surface);border:1px solid var(--rule);
  display:flex;align-items:center;justify-content:center;max-width:340px}

/* ══ GENERATED GRAPHICS ══════════════════════════════════════════════════
   🔴 Wide graphics scroll in THEIR OWN container below 720px; the page itself
   never side-scrolls. A 1000-unit viewBox squeezed into a 255px column renders
   13px labels at ~3px — decoration pretending to be data. */
figure.graphic{margin:var(--gap-block) 0 0}
figure.graphic svg{display:block;width:100%}
figure.graphic figcaption{margin-top:.8rem;font-size:var(--t-small);color:var(--ink-2)}
@media(max-width:720px){
  figure.graphic{overflow-x:auto;-webkit-overflow-scrolling:touch;padding-bottom:.5rem}
  figure.graphic svg{min-width:660px}
  figure.graphic::after{content:"Scroll to see all of it \2192";display:block;
    font:400 .8rem/1.4 var(--mono);color:var(--ink-2);margin-top:.45rem;
    position:sticky;left:0}
}

/* ══ FOOTER ══════════════════════════════════════════════════════════════ */
footer{border-top:1px solid var(--rule);padding-block:var(--gap-block);
  font-size:var(--t-small);color:var(--ink-2)}
footer a{color:var(--ink-2)}
footer a:hover{color:var(--volt)}
.frow{display:flex;flex-wrap:wrap;gap:1.2rem 2.5rem;justify-content:space-between}
footer p{margin:0 0 .3rem}

/* ══ PROGRESSIVE ENHANCEMENT ═════════════════════════════════════════════ */
.js-only{display:none}
.js .js-only{display:revert}
.js .nojs-only{display:none}

/* ══ MOTION — 🔴 THE FAIL-VISIBLE INVERSION. A bare `.rise` is opacity 1.
   Content is visible by default and script only ever REMOVES it to animate it
   back in. If the script dies, the page is complete. ⛔ Never the reverse. ══ */
.rise{opacity:1}
.js .rise.armed{opacity:0;transform:translateY(14px)}
.js .rise.in{opacity:1;transform:none;transition:opacity .5s ease,transform .5s ease}
@media(prefers-reduced-motion:reduce){
  .js .rise.armed,.js .rise.in{opacity:1;transform:none;transition:none}
}

/* ══════════════════════════════════════════════════════════════════════════
   THE INSTRUMENT. 🔴 Every class below is READ BY tool.js. ⛔ None may vanish.
   ══════════════════════════════════════════════════════════════════════════ */
.overlay{position:fixed;inset:0;z-index:100;display:none;flex-direction:column;
  background:var(--ground)}
.overlay.open{display:flex}
body.locked{overflow:hidden}
.ov-top{display:flex;align-items:center;justify-content:space-between;gap:1rem;
  padding:.7rem var(--pad-x);border-bottom:1px solid var(--rule);flex:0 0 auto}
/* 🔴 THE LOCKUP HAD NO SIZE RULE and rendered at natural size — a 173px-tall
   header that pushed the Close button off the right edge of the viewport. */
.ov-top img{height:26px;width:auto;display:block}
.ov-close{background:none;border:0;cursor:pointer;color:var(--ink);
  font:600 .95rem/1 var(--sans);min-height:44px;display:inline-flex;align-items:center;gap:.4rem}
.ov-close:hover{color:var(--volt)}
.bar{height:3px;background:var(--rule);flex:0 0 auto}
/* 🔴 `display:block` IS LOAD-BEARING. The fill is an <i>, which is inline by
   default, and width/height DO NOT APPLY to a non-replaced inline box. The
   rule set width and height and the element still measured 0x0. */
.bar .in{display:block;height:100%;background:var(--volt);width:0;
  transition:width .3s ease}
.ov-body{flex:1;overflow-y:auto;-webkit-overflow-scrolling:touch;padding:var(--pad-x)}
.ov-inner{max-width:720px;margin:0 auto;width:100%}
.ov-foot{flex:0 0 auto;padding:.7rem var(--pad-x);border-top:1px solid var(--rule)}
/* 🔴 `.ov-foot .inner` — DROPPED IN THE REWRITE AND CAUGHT BY THE CLASS AUDIT.
   It is what keeps the footer controls on the same 720px column as the question
   above them; without it Back sat hard against the viewport edge. */
.ov-foot .inner{max-width:720px;margin:0 auto;width:100%;display:flex;
  gap:.75rem;align-items:center}
.back{background:none;border:0;cursor:pointer;color:var(--ink-2);
  font:500 .95rem/1 var(--sans);min-height:44px;display:inline-flex;align-items:center;gap:.4rem}
/* 🔴 `display:inline-flex` BEATS the UA's `[hidden]{display:none}`, so the Back
   button showed on question 1 even though tool.js sets the hidden attribute.
   ⚠️ ANY component given an explicit display MUST restate [hidden]. */
.back[hidden],.ov-close[hidden]{display:none}
.back:hover{color:var(--volt)}
.spacer{flex:1}

/* ══ CLASSES THAT WERE IN THE MARKUP WITH NO RULE ═══════════════════════════
   🔴 Found by diffing every class in the HTML against every selector in this
   sheet. ⛔ None of them errored — unstyled markup renders, it just renders as
   browser default, which is why none of this was visible to any gate. */

/* the terms block sits directly under the $5,000 and was rendering at full body
   size, competing with the price it qualifies */
.terms{font-size:var(--t-small);color:var(--ink-2);max-width:60ch}

/* emphasis inside tool results */
.mailaddr{font-weight:600;color:var(--ink)}  /* 🔴 renamed from .em 2026-08-04 — it is tool.js's e-mail SELECTOR, not emphasis */

/* 🔴 THE NO-SCRIPT QUIZ. This is what a visitor with JavaScript off sees, and
   it is also what sits behind the overlay on subpart-f-check.html. It was
   rendering as a default <fieldset> — beveled browser border and inline radios. */
.flatq{border:1.5px solid var(--rule);padding:1.1rem 1.2rem;margin:0 0 1rem}
.flatq legend{font-weight:600;line-height:1.35;padding:0 .4rem}
.qn{font:600 var(--t-label)/1.3 var(--mono);letter-spacing:.1em;color:var(--ink-2);
  margin-right:.5rem}
.opts{display:grid;gap:.4rem;margin-top:.8rem}
.opts label{display:flex;align-items:center;gap:.55rem;min-height:34px;cursor:pointer}
.opts input{accent-color:var(--volt);width:18px;height:18px;flex:0 0 auto}
.qnum{font:500 var(--t-label)/1.3 var(--mono);letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink-2);margin:0 0 .7rem;display:block}
.qtext{font-size:clamp(1.25rem,1rem + 1.1vw,1.75rem);font-weight:600;
  letter-spacing:-.025em;line-height:1.18;margin:0 0 1.4rem}
.cards{display:grid;gap:.55rem;grid-template-columns:1fr}
@media(min-width:620px){ .cards.two{grid-template-columns:1fr 1fr} }
.card{display:flex;align-items:center;min-height:60px;padding:.95rem 1.2rem;
  background:var(--ground);border:1.5px solid var(--rule);cursor:pointer;
  font:500 var(--t-body)/1.35 var(--sans);color:var(--ink);text-align:left;
  transition:border-color .14s ease,background .14s ease}
.card:hover{border-color:var(--volt);background:var(--surface)}
/* 🔴 THIS RULE BROKE THE QUIZ COMPLETELY AND SHIPPED. It was `.step{display:none}`
   + `.step.open{display:block}` — a show/hide pair from the OLD tool, which
   rendered every step and toggled between them. ⛔ The rebuilt tool renders ONE
   step at a time into #ovin and NEVER adds `.open` to a step — `.open` goes on
   the OVERLAY. So every question was rendered and then hidden by CSS.
   🎯 THE CONTENT WAS ALWAYS THERE: 653 characters in #ovin, display:none.
   ⚠️ Class `.step` appears ONLY in tool.js — this is `OPEN-FINDINGS` 5.2, the
   shared-CSS-name sweep that was RUN once and never became a gate. */
.step{display:block}
.res .method{font:500 var(--t-label)/1.3 var(--mono);letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink-2);margin:0 0 .5rem}
.res .note,.res .flag{font-size:var(--t-small);color:var(--ink-2)}
.res .note{border-left:2px solid var(--rule);padding-left:.9rem;margin:1rem 0}
.res .flag{color:var(--volt);font-weight:600}
.band{margin-top:1.8rem}
/* 🔴 `display:flex` + `gap` — the band label and its date were ABUTTING:
   "ALREADY PASSEDFROM 12 JANUARY 2026". The .when span follows the label text
   with no whitespace in the markup, so an inline span had nothing to separate
   it. ⚠️ The ≤620px rule below resets this to display:block deliberately. */
.band > h3{display:flex;flex-wrap:wrap;align-items:baseline;gap:.2rem .8rem;
  font:500 var(--t-label)/1.35 var(--mono);letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink);border-bottom:1.5px solid var(--rule);
  padding-bottom:.5rem;margin-bottom:.2rem}
.band > h3 .when{color:var(--ink-2);font-weight:400}
.oblig{list-style:none;margin:0;padding:0}
/* 🔴 THE CHIP SPANS EVERY ROW. Pinned to rows 1-3, an item carrying a
   dependency line auto-placed that line into the CHIP's column and crushed the
   text into a 130px gutter. */
.oblig li{display:grid;grid-template-columns:minmax(78px,auto) minmax(0,1fr);
  gap:.2rem .9rem;padding:.85rem 0;border-bottom:1px solid var(--rule)}
.oblig li:last-child{border-bottom:0}
.oblig .txt,.oblig .cite,.oblig .dep{grid-column:2}
.oblig .state{grid-column:1;grid-row:1/-1;align-self:start;justify-self:start;
  margin-top:.24rem;min-height:1.1em;font:500 .66rem/1.3 var(--mono);
  letter-spacing:.1em;text-transform:uppercase;padding:.24rem .48rem;white-space:nowrap}
/* ⛔ REMOVED PASS N+134 (C-463): `.st-out{background:var(--volt);color:#fff}`.
   It was overridden by the readout-list block at the foot of this file, so it
   did nothing — and a dead rule that still LOOKS right is the shape someone
   restores by accident while tidying the override away. */
.st-done{background:var(--surface);color:var(--ink-2)}
.st-later{background:transparent;color:var(--ink-2);box-shadow:inset 0 0 0 1px var(--rule)}
.oblig .txt{line-height:1.45}
.oblig .cite{font-size:var(--t-small);line-height:1.4}
.oblig .dep{font-size:var(--t-small);color:var(--ink-2);line-height:1.4}
/* 🔴 AT NARROW WIDTHS THE CHIP GOES ABOVE THE TEXT, ⛔ NOT BESIDE IT. */
@media(max-width:560px){
  .oblig li{grid-template-columns:1fr;gap:.35rem}
  .oblig .state{grid-column:1;grid-row:auto;margin:0 0 .1rem}
  .oblig .txt,.oblig .cite,.oblig .dep{grid-column:1}
  .oblig .state:empty{display:none}
  .band > h3{display:block}
  .band > h3 .when{display:block;margin-top:.3rem}
}
.sendlist{background:var(--surface);padding:1.05rem 1.2rem;margin:0 0 1.5rem}
.sendlist .dot{color:var(--volt);font-weight:600}
.field{margin:0 0 1rem}
.field label{display:block;font:500 var(--t-small)/1.4 var(--sans);
  color:var(--ink-2);margin-bottom:.3rem}
.field input{width:100%;min-height:52px;padding:.8rem 1rem;border:1.5px solid var(--rule);
  background:var(--ground);color:var(--ink);font:400 var(--t-body)/1.3 var(--sans)}
.field input:focus{border-color:var(--volt);outline:none}
/* the honeypot — off-screen, ⛔ never display:none, so a bot still finds it */
.hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
.err{color:var(--err);font-size:var(--t-small);margin:.4rem 0 0}

/* ══ 🔴 C-284 — THE PRINT STYLESHEET. OPEN-FINDINGS 7.941. ═════════════════
   🎯 IT REPLACES PART OF WHAT THE REMOVED E-MAIL WAS FOR (C-283). A dated
   obligation list with its CFR citations is a document someone takes into a
   meeting, and at 230 operators that is worth more than an automated message
   nobody can confirm arrived.
   ⛔ THE OVERLAY IS A FIXED, SCROLLING PANEL ON SCREEN. Printed as-is it emits
   one clipped page, which is the silent-truncation class in ink. So print
   UNPINS it and lets the content flow. */
@media print {
  /* ⛔ Everything that is not the readout is removed, ⛔ not hidden behind it. */
  body > *:not(#ov) { display: none !important; }
  .ov-top, .ov-foot, .bar, [data-noprint], #s2, .share { display: none !important; }

  #ov {
    position: static !important; inset: auto !important;
    width: auto !important; height: auto !important; max-height: none !important;
    overflow: visible !important; transform: none !important;
    opacity: 1 !important; visibility: visible !important;
    background: #fff !important; box-shadow: none !important;
  }
  .ov-body, .ov-inner {
    position: static !important; overflow: visible !important;
    max-height: none !important; height: auto !important; padding: 0 !important;
  }

  /* ⛔ A BAND MUST NOT SPLIT ACROSS A PAGE. A heading with its obligations on the
     next sheet reads as two different requirements. */
  .band, .oblig li, .flag { break-inside: avoid; page-break-inside: avoid; }
  h2, h3 { break-after: avoid; page-break-after: avoid; }

  /* 🔴 THE CITATION IS THE POINT OF PRINTING IT. Nothing that carries a CFR
     section may be dimmed to grey on paper. */
  body, .res, .oblig li, .cite, .small, .method { color: #000 !important; }
  .passed { opacity: 1 !important; }

  /* ⛔ A LINK PRINTED WITHOUT ITS TARGET IS A DEAD REFERENCE ON PAPER. */
  .oblig a[href^="http"]::after { content: " (" attr(href) ")"; font-size: .75em; }

  @page { margin: 18mm 16mm; }
}

/* ══ THE READOUT LIST. PASS N+122. ═════════════════════════════════════════
   🔴 STRUCTURE FROM NOEL'S REFERENCE BUILD, ⛔ TOKENS FROM THIS SITE. The
   reference's --paper/--ink/--rule map to --ground/--ink/--rule, which already
   exist; ⛔ none of its literals is carried.
   🔴 `--volt` IS DELIBERATELY UNUSED HERE. Volt is for ACTIONS and nothing in a
   readout is one. ⛔ The old `.st-out` filled the chip with volt, which made the
   single loudest element on the page a thing the reader cannot act on. C-429.
   🎯 THE EMPHASIS RUNS TO WHAT IS UNRESOLVED, which is what a reader came for. */
.oblig .state{font-family:var(--mono);font-size:.6875rem;letter-spacing:.1em;
  text-transform:uppercase;white-space:nowrap;background:none;color:var(--ink-2);
  padding:0;border-radius:0;box-shadow:none}
.st-out{color:var(--ink);font-weight:600}
.st-done{color:var(--ink-2);opacity:.65}
.st-later{color:var(--ink-2)}
/* ⛔ `We did not ask` is quiet and PRESENT. It is not a finding about the reader. */
.st-unasked{color:var(--ink-2);opacity:.65}
.oblig li.done-row .txt{opacity:.65}
/* the citation is a third field that WRAPS UNDER on a narrow screen rather than
   clipping — the whole reason this is markup and not an image */
.oblig .cite{font-family:var(--mono)}
@media(max-width:560px){ .oblig .state:empty{display:inline} }
