/* ===========================================================================
   Mito Workshop — site styles
   Brand system per mito-workshop-brand-book.html: Archivo + IBM Plex Mono,
   Paper / Ink / Graphite grounds, one rationed accent. Fonts self-hosted
   (zero external requests — the whole property's thesis is "no calls out").
   Neighbor pattern (structure) lifted from gabbyhon: shared assets, no build
   step, header/footer duplicated per page.
   =========================================================================== */

/* ---------- fonts (local, no CDN) ---------- */
@font-face{font-family:'Archivo';font-weight:400;font-style:normal;font-display:swap;
  src:url(fonts/archivo-400.woff2) format('woff2')}
@font-face{font-family:'Archivo';font-weight:500;font-style:normal;font-display:swap;
  src:url(fonts/archivo-500.woff2) format('woff2')}
@font-face{font-family:'Archivo';font-weight:600;font-style:normal;font-display:swap;
  src:url(fonts/archivo-600.woff2) format('woff2')}
@font-face{font-family:'PlexMono';font-weight:400;font-style:normal;font-display:swap;
  src:url(fonts/plexmono-400.woff2) format('woff2')}
@font-face{font-family:'PlexMono';font-weight:600;font-style:normal;font-display:swap;
  src:url(fonts/plexmono-600.woff2) format('woff2')}

/* ---------- tokens ---------- */
:root{
  /* DARK ground is this property's PRIMARY — differentiates from russunger.com's
     light-blue "Frost" system (which also uses a near-identical blue + Archivo).
     Ground = Ink #15161A, a near-BLACK NEUTRAL (deliberately NOT navy, to stay
     clear of russunger's navy #0C1F3D); text = Paper (reversed near-white). */
  --paper:#101420;            /* ground — dark blue INK off-black (low-sat, not navy) */
  --paper-raised:#272F42;     /* raised panels — 1.37:1 off the ground so the surface is actually SEEN, not implied */
  --paper-sunken:#0B0E18;     /* deepest (footer) */
  --ink:#F6F5F1;              /* primary text + reversed marks */
  --ink-raised:#EDECE6;
  --ink-2:#DBD8D1;
  /* neutrals — secondary text on dark uses the brand's dark value */
  --graphite:#C6CAD3;         /* secondary text — brightened past the AA floor for real readability */
  --muted:#9EA0A8;
  --line:rgba(246,245,241,.13);   /* hairline on dark */
  --line-chip:rgba(246,245,241,.60); /* chip/pill stroke — 4.53:1 on --wash. A hairline
                                        reads as a smudge at pill size; a boundary this
                                        small has to be drawn, not implied. */
  /* Two washes, not two new colours: translucent tints of --ink and --accent, built the
     same way --line is. A wash lifts whatever it sits on by one step, so the same token
     reads correctly on --paper and on --paper-raised without a third ground being
     invented. Used for the small surfaces that sit INSIDE a raised panel — pills, and
     the pass-frequency list in the methodology band — where a solid ground would need a
     value the palette does not have. */
  --wash:#36415A;             /* nested step: chips, tags, list rows — 1.31:1 off a panel, solid so it reads on any ground */
  --wash-accent:#1E4C7E;      /* accent chips — solid, carries --ink at 8.5:1 */
  /* A nested step that must SEPARATE from the panel it sits on, where --wash
     (1.31:1) does not. Added 2026-09-22 for the Labs status bar, which shipped
     with this value hardcoded twice — a literal colour in a component, which
     is the one thing the card rule forbids. */
  --wash-raised:#455270;      /* 1.71:1 off --paper-raised, past the ~1.2:1 a step needs */
  /* Layout Blue — one hue, two values. Active value here is the on-ink (dark) one. */
  --accent:#5297DE;         /* Layout Blue, dark value (on ink) — active */
  /* ⛔ The accent is a PAGE-GROUND colour. The ladder measures it at 4.35:1 on
     --paper-raised, under AA, and the design system rules out "the accent as
     label text on a panel" in as many words. Anything that needs to read as
     the accent ON a panel takes this instead: same hue, 7.41:1 raised,
     10.18:1 on the page. */
  --accent-raised:#9EC5ED;
  /* --fault is a brand-book value and stays the mark/dot colour. As TEXT it is
     3.05:1 on a raised panel, so words take this: 7.24:1 raised, 10.44:1
     sunken. Brand keeps the mark, the floor keeps the copy. */
  --fault-text:#E9B2A8;

  /* ---------- spacing scale ----------
     The property was carrying 13 raw margin values across 84 inline
     declarations — 8, 10, 14, 16, 18, 20, 22, 24, 26, 28, 34, 38 — which is
     drift rather than thirteen decisions. These four steps sit within 2-4px of
     every one of them, and --space-flow is the one fluid step the hero and stub
     bodies already used. A value that is not on the scale should be a deliberate
     exception, not the default. */
  /* ---------- type scale ----------
     Nineteen sizes under 19px, nine of them half-pixels, is one decision made
     nineteen slightly different ways rather than nineteen decisions. Three
     steps, and a floor: nothing a person reads is under 13px. Thirty-one
     declarations used to sit below the 12px floor this property holds the
     hub's report to, the smallest at 9.5px.
     Headings are not here on purpose — they already scale with clamp(). */
  --fs-caption:13px;        /* labels, chips, eyebrows, table heads, meta */
  --fs-body:16px;           /* paragraphs and descriptions */
  --fs-lead:18px;           /* section heads and claims */

  --space-1:8px;
  /* ⛔ The half-step, named 2026-09-21 rather than invented. 12px was already
     the property's most-used off-scale margin at eighteen declarations, sitting
     between --space-1 and --space-2 where the scale had nothing. Naming what is
     in use costs no pixels; snapping those eighteen onto 8 or 16 would have
     moved every one of them, and movement is the thing worth avoiding. 11px and
     13px stay as exceptions for the same reason. */
  --space-1-5:12px;
  --space-2:16px;
  --space-3:24px;
  --space-4:34px;
  --space-flow:clamp(20px,3.5vw,34px);
  /* ⛔ Severity and the smallest-note value live HERE, not on .tool.
     They sat on .tool until 2026-09-21, which meant any consumer outside a
     tool surface resolved var(--sev-critical) to nothing and painted
     transparent. The design-system page proved it: its swatches for these
     five rendered invisible, and --field-note had been doing that unnoticed
     for as long as the page has documented it. Nothing redefines them, so the
     scope bought nothing and cost silence. */
  --sev-critical:#d24b34;   /* edges only — 3.05:1 as text on a raised card */
  --sev-serious:#e0803e;
  --sev-moderate:#d8b247;
  --sev-minor:#5297de;
  --field-note:#D4D7DE;     /* the smallest text (notes) — brightest muted, well past AA */
  --tick:var(--accent);     /* mark ticks + drawn descriptor */
  --fault:#C83E26;          /* status: fault / failure only (per brand book) */
  /* type + layout */
  /* The column a Labs tool lives in. Shared so the methodology panel lines up with the
     tool panel above it; they only have to agree now that both are drawn surfaces. */
  /* REPORT surface — no new colours. The report is a dark document like the
     rest of the site, built from tokens that already exist. An earlier version
     invented a greige (#DEDBD1) for a light document on a dark page; that was
     a colour the system never had, and it is gone.

     Measured on --paper-raised: ink 12.25:1, secondary 9.39:1, muted 8.14:1,
     and the card sits 1.37:1 off the page ground — exactly the bar
     --paper-raised is already held to. --accent is the ON-GROUND blue and only
     reaches 4.35:1 on a raised card, so links take a brightened value of the
     same hue at 6.94:1.

     ⛔ --wash-accent is NOT a document ground. It carries --ink at 8.05:1, but
     drops secondary to 6.17, muted to 5.35, and FAILS faint text (3.37) and
     links (2.86). The system documents it as a chip colour, and that is where
     it is used here: callouts and highlight moments carrying --ink only. */
  --report-link:#8CC0EF;      /* Layout Blue, brightened for a raised card */
  --report-critical:#FFAE9B;  /* 7.50:1 on card, 5.33:1 on its own chip tint */
  --report-warn:#E8B562;      /* 7.14:1 */
  --report-ok:#6FCF97;        /* 7.03:1 */
  --report-info:#AED4F7;      /* 5.67:1 on the wash-accent callout, 8.63:1 on a card */
  --tool-measure:780px;
  --sans:'Archivo',system-ui,-apple-system,sans-serif;
  --mono:'PlexMono',ui-monospace,'SFMono-Regular',monospace;
  --wrap:1120px;
}

*{box-sizing:border-box}
html{-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;scroll-behavior:smooth}
body{
  margin:0;background:var(--paper);color:var(--ink);
  font-family:var(--sans);font-weight:400;line-height:1.6;font-size:var(--fs-lead);
}
::selection{background:var(--accent);color:#fff}
svg{display:block}
a{color:inherit}
img{max-width:100%}

.wrap{max-width:var(--wrap);margin:0 auto;padding:0 clamp(22px,5vw,64px)}
.skip{position:absolute;left:-9999px}
.skip:focus{left:16px;top:12px;z-index:100;background:var(--ink);color:var(--paper);
  padding:10px 16px;border-radius:6px;font-family:var(--mono);font-size:var(--fs-caption)}
:focus-visible{outline:2px solid var(--accent);outline-offset:2px}

/* ---------- shared type ---------- */
.ey{font-family:var(--mono);font-size:var(--fs-caption);letter-spacing:.2em;text-transform:uppercase;
  color:var(--graphite);display:flex;gap:.9em;align-items:center}
.ey .idx{color:var(--accent)}
.ey.railed::after{content:"";height:1px;flex:1;background:var(--line);margin-left:.4em}
/* The lead carries a NARROWER measure than body prose — larger type wants a
   shorter line. The component owns it now instead of every instance setting
   it inline.

   ⛔ THE RULE SAID 24ch AND NOTHING RENDERED AT 24ch. Every .lead carried an
   inline max-width of 60-62ch, and inline beats a stylesheet, so the declared
   value had not applied anywhere in a long time — stripping the inline styles
   would have collapsed every lead to a 24-character column. 62ch is what the
   pages actually render; the rule now says so. */
.lead{font-size:clamp(22px,3.2vw,34px);line-height:1.28;letter-spacing:-.01em;
  font-weight:500;max-width:62ch}
h1,h2,h3,h4{font-family:var(--sans);font-weight:600;letter-spacing:-.01em;margin:.4em 0 .3em}
h2{font-size:clamp(22px,2.6vw,30px)}
h3{font-size:clamp(18px,2.1vw,22px)}
p{max-width:66ch}
.muted{color:var(--graphite)}
.spec{font-family:var(--mono);font-size:var(--fs-caption);letter-spacing:.03em;color:var(--muted)}

/* ---------- mark + lockup (DRAWN — the name is never typeset) ---------- */
/* The M/W mark is 170x142 (not square): size by height, let width follow.
   Its body inherits currentColor from the ground; the ticks use --tick so
   they carry Layout Blue's correct value per ground (light on paper, dark on ink). */
.mark{height:1.4em;width:auto;flex:0 0 auto;fill:currentColor}
.mark{display:block}
/* Full stacked lockup for the header. Above the 151px reduction threshold so
   the cut band stays open (MITO cap ~34px at this width). */
.brand-lockup{width:clamp(154px,17vw,166px);height:auto;display:block;color:var(--ink)}

/* ---------- buttons ---------- */
.btn{display:inline-flex;align-items:center;gap:.5em;font-family:var(--mono);font-size:var(--fs-caption);
  letter-spacing:.04em;text-decoration:none;padding:11px 18px;border-radius:7px;
  border:1px solid var(--ink);transition:background .18s ease,color .18s ease}
.btn-solid{background:var(--ink);color:var(--paper)}
.btn-solid:hover{background:var(--ink-raised)}
.btn-ghost{background:transparent;color:var(--ink);border-color:var(--line)}
.btn-ghost:hover{border-color:var(--ink)}
.btn .arw{transition:transform .18s ease}
.btn:hover .arw{transform:translateX(3px)}

/* =================================================== HEADER / NAV */
.site-head{position:sticky;top:0;z-index:50;background:var(--paper);
  border-bottom:1px solid var(--line)}
.site-head .bar{display:flex;align-items:center;justify-content:space-between;gap:20px;padding:22px 0}
.brand-link{display:flex;align-items:center;text-decoration:none;color:var(--ink)}
.nav{display:flex;gap:30px;align-items:center}
.nav a{font-family:var(--sans);font-size:var(--fs-body);font-weight:500;
  color:var(--graphite);text-decoration:none;padding:4px 2px;transition:color .18s ease}
.nav a:hover{color:var(--ink)}
.nav a[aria-current="page"]{color:var(--accent)}
.nav-toggle{display:none;background:none;border:0;cursor:pointer;padding:11px;color:var(--ink);min-width:44px;min-height:44px;align-items:center;justify-content:center}
.nav-toggle svg{width:22px;height:22px}

@media(max-width:720px){
  .nav-toggle{display:block}
  .nav{position:absolute;top:100%;left:0;right:0;flex-direction:column;gap:0;
    background:var(--paper);border-bottom:1px solid var(--line);
    max-height:0;overflow:hidden;transition:max-height .3s ease}
  .nav a{padding:15px clamp(22px,5vw,64px);width:100%;border-top:1px solid var(--line)}
  .site-head.open .nav{max-height:360px}
}

/* =================================================== SECTIONS */
/* Flat paper + hairline rules (per the brand mock). No warm-cream bands. */
.section{padding:clamp(48px,7vw,92px) 0}
.section.ruled{border-top:1px solid var(--line)}
.section.ink{background:var(--paper-raised)}  /* raised dark panel (optional) */

/* ---------- hero ---------- */
.hero{padding:clamp(52px,9vw,104px) 0 clamp(44px,6vw,76px)}
.hero-head{font-family:var(--sans);font-weight:600;letter-spacing:-.02em;
  font-size:clamp(38px,6vw,66px);line-height:1.04;max-width:15ch;color:var(--ink);margin:0}
.hero-sub{margin-top:var(--space-3);color:var(--graphite);max-width:52ch;
  font-size:clamp(17px,2vw,21px);line-height:1.5}
/* Home hero: copy left, drawn patent-style figure right (rotates on load). */
.hero-grid{display:grid;grid-template-columns:1fr minmax(0,44%);gap:clamp(28px,5vw,64px);align-items:center}
.hero-figure{color:rgba(246,245,241,.5)}   /* muted line colour for the drawing */
.hero-figure .fig{width:100%;height:auto;display:block}
.hero-figure .fig[hidden]{display:none}   /* let the rotation actually hide the rest */
.fig text{font-family:var(--mono);fill:#9EA0A8}
.fig .num text{fill:var(--accent)}
.fig .d{stroke-dasharray:5 5}
@media(max-width:860px){
  .hero-grid{grid-template-columns:1fr}
  .hero-figure{max-width:400px;margin-top:var(--space-1)}
}

/* ---------- stub / in-progress marker ---------- */
.stub{border:1px dashed var(--line);border-radius:10px;padding:clamp(24px,4vw,44px);
  background:var(--paper-raised)}
.stub .tag{font-family:var(--mono);font-size:var(--fs-caption);letter-spacing:.18em;text-transform:uppercase;
  color:var(--accent-raised);display:inline-block;margin-bottom:var(--space-2)}

/* ---------- status board placeholder ---------- */
/* Graphite, not --muted: #9EA0A8 fails 4.5:1 on any paper ground (ink-only value). */
.status-empty{font-family:var(--mono);font-size:var(--fs-caption);color:var(--graphite);
  border:1px solid var(--line);border-radius:10px;padding:28px;text-align:center}

/* =================================================== FOOTER */
.foot{background:var(--paper-sunken);color:var(--ink);padding:clamp(40px,6vw,64px) 0;
  border-top:1px solid var(--line)}
.foot .wrap{display:flex;flex-direction:column;gap:16px;align-items:flex-start;color:var(--ink)}
.foot .mark{height:36px}
/* On the dark footer: secondary text + separators = #9EA0A8 (6.93:1), links = near-white. */
.foot .fine{font-family:var(--mono);font-size:var(--fs-caption);letter-spacing:.03em;color:var(--muted);
  display:flex;flex-wrap:wrap;gap:.7em;align-items:center}
.foot .fine a{color:var(--ink);text-decoration:none;border-bottom:1px solid transparent;transition:border-color .18s ease}
.foot .fine a:hover{border-color:var(--accent)}
.foot .fine .sep{color:var(--muted)}

/* =================================================== FULL-BLEED PAGE HERO */
.page-hero{position:relative;width:100%;height:clamp(300px,52vh,540px);overflow:hidden;background:var(--paper-sunken)}
.page-hero img{width:100%;height:100%;object-fit:cover;object-position:center;display:block;transition:opacity .5s ease}
.page-hero .scrim{position:absolute;inset:0;
  background:linear-gradient(180deg,rgba(16,20,32,.15) 0%,rgba(16,20,32,.30) 55%,rgba(16,20,32,.82) 100%)}
.page-hero .cap{position:absolute;left:0;right:0;bottom:0}
/* Labs tool detail header — a duotone of the tool's own output, set at a slight angle */
.tool-hero{position:relative;width:100%;height:clamp(240px,42vh,440px);overflow:hidden;background:var(--paper-sunken)}
.tool-hero img{width:100%;height:100%;object-fit:cover;object-position:top center;display:block;transform:rotate(-1.5deg) scale(1.1);transform-origin:center}
.tool-hero .scrim{position:absolute;inset:0;background:linear-gradient(180deg,rgba(16,20,32,.82) 0%,rgba(16,20,32,.72) 38%,rgba(16,20,32,.94) 100%)}
.tool-hero .cap{position:absolute;left:0;right:0;bottom:0}
.tool-hero .cap .wrap{padding-bottom:clamp(24px,4vw,42px)}
.tool-hero .hero-head--sm{margin-top:var(--space-1)}

/* ============================================================================
   Labs tool surface (Compliance Checker first; reusable for future tools)
   Semantic severity colors are separate from the --accent brand hue.
   ============================================================================ */
.tool{margin-top:var(--space-1);max-width:var(--tool-measure)}
/* bounded panel: one step lighter than the page, the reusable tool-surface container */
.tool-panel{background:var(--paper-raised);border:1px solid var(--line);border-radius:16px;padding:clamp(22px,4vw,34px)}
.tool-panel + .tool-panel{margin-top:var(--space-2)}
.field{margin-top:var(--space-3)}
.field:first-child{margin-top:0}
.field-label{display:block;font-family:var(--mono);font-size:var(--fs-caption);letter-spacing:.09em;text-transform:uppercase;color:var(--graphite);margin-bottom:var(--space-1)}
.field-note{font-family:var(--sans);font-size:var(--fs-body);color:var(--field-note);margin:var(--space-1) 0 0;line-height:1.55}
.field-info{background:var(--paper-sunken);border:1px solid var(--line);border-radius:10px;padding:13px 16px;margin-top:var(--space-1);font-size:var(--fs-body);color:var(--field-note);line-height:1.55}
.tool-input{font-family:var(--sans);font-size:var(--fs-body);color:var(--ink);background:var(--paper-sunken);
  border:1px solid var(--line);border-radius:10px;padding:13px 15px;width:100%;transition:border-color .18s ease}
.tool-input::placeholder{color:var(--graphite)}
.tool-input:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px rgba(82,151,222,.30)}
.tool-select{font-family:var(--sans);font-size:var(--fs-body);color:var(--ink);width:100%;cursor:pointer;
  background:var(--paper-sunken) url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%239EA0A8' stroke-width='2'><path d='M2 4l4 4 4-4'/></svg>") no-repeat right 14px center;
  border:1px solid var(--line);border-radius:10px;padding:12px 40px 12px 15px;appearance:none;-webkit-appearance:none;transition:border-color .18s ease}
.tool-select:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px rgba(82,151,222,.30)}
.tool-textarea{min-height:92px;resize:vertical;line-height:1.55}
.field-label .opt{font-family:var(--sans);text-transform:none;letter-spacing:normal;font-size:var(--fs-caption);color:var(--field-note)}
.field-count{font-family:var(--mono);font-size:var(--fs-caption);color:var(--graphite);margin:var(--space-1) 0 0;font-variant-numeric:tabular-nums}
.field-count--ok{color:var(--accent)}
/* Ask the Books: starting-point questions. Same chip construction as .len-chip,
   --wash ground inside the panel with a --line-chip stroke (4.55:1, past the 3:1
   SC 1.4.11 wants of a control boundary, where the 13% hairline would sit at
   1.48:1). The face is sans rather than the mono a .pill takes: these are whole
   sentences, and mono at sentence length reads as a label rather than a question.
   Text is --ink on --wash at 9.28:1, so the chips clear the house 7:1 target and
   not just the AA floor.

   While a query runs the chips are ignored rather than removed, and the busy
   state is carried three ways so no one is relying on the dim alone: reduced
   opacity, a not-allowed cursor, and aria-disabled on each chip. They stay
   focusable on purpose. Disabling the button a keyboard user just pressed would
   throw focus back to the top of the document mid-answer. */
.ask-set{display:flex;flex-wrap:wrap;gap:10px;margin-top:var(--space-2)}
.ask-chip{font-family:var(--sans);font-size:var(--fs-body);line-height:1.4;min-height:44px;text-align:left;color:var(--ink);
  background:var(--wash);border:1px solid var(--line-chip);border-radius:999px;
  padding:9px 17px;cursor:pointer;transition:border-color .18s ease,background .18s ease}
.ask-chip:hover{border-color:var(--accent);background:var(--wash-accent)}
.ask-set.is-busy{opacity:.55}
.ask-set.is-busy .ask-chip{cursor:not-allowed}
.ask-set.is-busy .ask-chip:hover{border-color:var(--line-chip);background:var(--wash)}
/* Subordinate to the chips it shuffles: no fill, so it reads as the quieter of
   the two controls while keeping a stroke strong enough to be seen (5.5:1). */
.ask-more{font-family:var(--mono);font-size:var(--fs-caption);letter-spacing:.04em;color:var(--ink);
  background:none;border:1px solid var(--line-chip);border-radius:8px;
  padding:8px 14px;margin-top:var(--space-1-5);cursor:pointer;transition:border-color .18s ease,background .18s ease}
.ask-more:hover{border-color:var(--accent);background:var(--wash-accent)}
@media (max-width:560px){
  /* Two lines inside a 999px radius turns the ends into lozenges that eat the
     measure, so the shape relaxes where the questions start wrapping. */
  .ask-chip{border-radius:14px}
}
/* Ask the Books: synthesised answer (sanitised HTML) + the chapters it drew on.
   The contract promises h2/p/ul/li/strong; production answers also emit h3
   sub-headings, so both heading levels are styled. */
.book-answer{color:var(--ink)}
.book-answer h2{font-family:var(--sans);font-weight:600;font-size:clamp(19px,2.4vw,24px);color:var(--ink);margin:0 0 var(--space-2);line-height:1.25}
.book-answer h3{font-family:var(--sans);font-weight:600;font-size:var(--fs-lead);color:var(--ink);margin:var(--space-3) 0 var(--space-1);line-height:1.3}
.book-answer h2:first-child,.book-answer h3:first-child{margin-top:0}
/* At a Glance: a summary the endpoint leads answer_html with. Present when the
   books cover the topic, absent on a decline. Re-coloured from the hub's blue
   chat styling to the Workshop palette; label follows the mono-uppercase idiom. */
.book-answer .at-a-glance-callout{background:var(--paper-raised);border:1px solid var(--line);border-left:3px solid var(--accent);border-radius:8px;padding:18px 20px;margin:0 0 var(--space-3)}
.book-answer .at-a-glance-callout h3{font-family:var(--mono);font-size:var(--fs-caption);font-weight:600;letter-spacing:.09em;text-transform:uppercase;color:var(--graphite);margin:0 0 var(--space-1)}
.book-answer .at-a-glance-callout ul{margin:0;padding-left:20px;max-width:none}
.book-answer .at-a-glance-callout li{color:var(--ink);font-size:var(--fs-body);line-height:1.55;margin:0 0 var(--space-1)}
.book-answer .at-a-glance-callout li:last-child{margin-bottom:0}
.book-answer .at-a-glance-callout > :last-child{margin-bottom:0}
.book-answer p{color:var(--ink);font-size:var(--fs-body);line-height:1.65;margin:0 0 var(--space-2);max-width:70ch}
.book-answer ul,.book-answer ol{margin:0 0 var(--space-2);padding-left:22px;max-width:70ch}
.book-answer li{color:var(--ink);font-size:var(--fs-body);line-height:1.6;margin:0 0 var(--space-1)}
.book-answer strong{color:var(--ink);font-weight:600}
.book-answer > :last-child{margin-bottom:0}
.book-sources{margin-top:var(--space-4);border-top:1px solid var(--line);padding-top:20px}
.book-sources h3{font-family:var(--mono);font-size:var(--fs-caption);letter-spacing:.09em;text-transform:uppercase;color:var(--graphite);margin:0 0 var(--space-1-5)}
/* Numbered so a [1] in the answer has a row to point at. The marker is mono
   like every other piece of metadata on the property, and --field-note (#D4D7DE
   on the #101420 ground, ~13:1) so a small number still reads BRIGHT. */
.book-source-list{list-style:decimal;margin:0;padding:0 0 0 28px}
.book-source-list>li::marker{font-family:var(--mono);font-size:var(--fs-caption);font-weight:600;color:var(--field-note)}
.book-source{font-size:var(--fs-body);color:var(--field-note);margin:0 0 var(--space-1);line-height:1.5}
.book-source-list>.book-source{padding-left:3px}
.book-source-list>.book-source:last-child{margin-bottom:0}
.book-source .bk{color:var(--ink);font-weight:600}
.book-source .ch{color:var(--field-note)}
/* radio groups (design system, scan mode) as accessible option cards */
.field-group{border:0;padding:0;margin:var(--space-3) 0 0;min-width:0}
.field-group legend{padding:0;font-family:var(--mono);font-size:var(--fs-caption);letter-spacing:.09em;text-transform:uppercase;color:var(--graphite);margin-bottom:2px}
.field-group legend .opt{font-family:var(--sans);text-transform:none;letter-spacing:normal;font-size:var(--fs-caption)}
.radio-card{display:flex;gap:13px;align-items:flex-start;border:1px solid var(--line);border-radius:12px;padding:14px 16px;margin-top:11px;cursor:pointer;transition:border-color .18s ease,background .18s ease}
.radio-card:hover{border-color:rgba(246,245,241,.3)}
.radio-card input{margin:2px 0 0;accent-color:var(--accent);width:17px;height:17px;flex:0 0 auto}
.radio-card .rc-body{display:flex;flex-direction:column;gap:3px}
.radio-card .rc-title{font-family:var(--sans);font-weight:600;font-size:var(--fs-lead);color:var(--ink)}
.radio-card .rc-desc{font-size:var(--fs-body);color:var(--field-note);line-height:1.55}
/* Selected takes the accent wash, the same nested step the accent pills use. The old
   hand-tuned #1a2336 was picked to sit just above the previous #191F2E panel (1.05:1,
   already under the ~1.2:1 seen threshold); against the current #272F42 panel it lands
   1.18:1 BELOW it, so the chosen option read recessed. --wash-accent sits 1.52:1 above
   the panel and carries --ink at 8.05:1, so selection reads as a lift on any ground the
   panel ever takes. */
.radio-card:has(input:checked){border-color:var(--accent);background:var(--wash-accent)}
.radio-card:has(input:disabled){opacity:.55;cursor:not-allowed}
.radio-card input:focus-visible{outline:2px solid var(--accent);outline-offset:3px}
.radio-card .tool-select{margin-top:var(--space-1-5)}
.ds-select{display:none}
.radio-card:has(input[value=specify]:checked) .ds-select{display:block}
.tool-actions{margin-top:var(--space-3);display:flex;gap:14px;flex-wrap:wrap;align-items:center}
.tool-actions .btn-solid{padding:14px 26px;font-size:var(--fs-body);border-radius:10px;cursor:pointer;border:1px solid var(--ink)}
.tool-actions .btn-solid[disabled]{opacity:.55;cursor:not-allowed}
.tool-actions .tool-sample{padding:14px 22px;font-size:var(--fs-body);border-radius:10px;cursor:pointer}
.scan-note{font-family:var(--sans);font-size:var(--fs-body);color:var(--field-note);margin:var(--space-2) 0 0;line-height:1.5}
.scan-note a{color:var(--accent-raised);text-decoration:underline}
/* status: progress / cooldown / busy / error */
.tool-status{margin-top:var(--space-3)}
.tool-status[hidden]{display:none}
.stage-row{display:flex;align-items:center;gap:12px;font-family:var(--mono);font-size:var(--fs-caption);color:var(--ink)}
.stage-row .spin{width:14px;height:14px;border:2px solid var(--line);border-top-color:var(--accent);border-radius:50%;animation:tool-spin .8s linear infinite;flex:0 0 auto}
@media (prefers-reduced-motion:reduce){.stage-row .spin{animation:none}}
@keyframes tool-spin{to{transform:rotate(360deg)}}
.stage-dots{display:flex;gap:6px;margin:var(--space-2) 0 0}
.stage-dots i{height:4px;flex:1;background:var(--line);border-radius:2px;transition:background .3s ease}
.stage-dots i.done{background:var(--accent)}
.stage-sub{font-family:var(--sans);font-size:var(--fs-body);color:var(--graphite);margin:var(--space-1) 0 0;max-width:62ch;line-height:1.5}
.tool-msg{border:1px solid var(--line);border-radius:12px;padding:18px 20px;background:var(--paper-raised)}
.tool-msg .tag{margin-bottom:var(--space-1)}
.tool-msg p{margin:0;color:var(--field-note);font-size:var(--fs-body);line-height:1.5}
.cooldown{font-family:var(--mono);font-size:var(--fs-body);color:var(--field-note)}
.tool-msg + .cooldown{margin-top:var(--space-2)}
.cooldown b{color:var(--ink);font-variant-numeric:tabular-nums}
/* results */
.tool-results{margin-top:var(--space-4)}
.tool-results[hidden]{display:none}
.score-summary{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin:0 0 var(--space-1)}
.score-cell{border:1px solid var(--line);border-radius:12px;padding:16px 12px;text-align:center;background:var(--paper-raised);border-top:3px solid var(--line)}
.score-cell[data-sev=critical]{border-top-color:var(--sev-critical)}
.score-cell[data-sev=serious]{border-top-color:var(--sev-serious)}
.score-cell[data-sev=moderate]{border-top-color:var(--sev-moderate)}
.score-cell[data-sev=minor]{border-top-color:var(--sev-minor)}
.score-cell .n{font-family:var(--sans);font-weight:600;font-size:clamp(26px,4vw,34px);color:var(--ink);font-variant-numeric:tabular-nums}
.score-cell .lbl{font-family:var(--mono);font-size:var(--fs-caption);letter-spacing:.07em;text-transform:uppercase;color:var(--graphite);margin-top:5px}
.result-meta{font-family:var(--mono);font-size:var(--fs-caption);color:var(--graphite);margin:var(--space-2) 0 0;display:flex;flex-wrap:wrap;gap:8px 18px}
.result-meta b{color:var(--ink)}
/* finding groups */
.finding-group{margin-top:var(--space-4)}
.group-head{font-family:var(--sans);font-weight:600;font-size:var(--fs-lead);color:var(--ink);margin:0 0 4px}
.group-note{font-family:var(--sans);font-size:var(--fs-body);color:var(--graphite);margin:0 0 var(--space-2);max-width:64ch;line-height:1.55}
.finding{border:1px solid var(--line);border-left:3px solid var(--line);border-radius:10px;padding:16px 18px;margin-top:var(--space-1-5);background:var(--paper-raised)}
.finding[data-sev=critical]{border-left-color:var(--sev-critical)}
.finding[data-sev=serious]{border-left-color:var(--sev-serious)}
.finding[data-sev=moderate]{border-left-color:var(--sev-moderate)}
.finding[data-sev=minor]{border-left-color:var(--sev-minor)}
.finding-top{display:flex;flex-wrap:wrap;align-items:baseline;gap:8px 12px}
.finding-title{font-family:var(--sans);font-weight:600;font-size:var(--fs-lead);color:var(--ink);margin:0;flex:1 1 60%}
/* Pills carry a ground rather than an outline. Outline-only, they were a hairline and
   11.5px of type floating on the same card colour as everything around them, which is
   what made REVIEW and FOUND IN X OF 3 PASSES hard to pick out. The accent ones take
   --ink for their text: accent-on-accent-wash measures 4.33:1, which clears the floor
   but not the house target on dark, so the accent stays as the border and the label
   reads at 12.20:1. */
.pill{font-family:var(--mono);font-size:var(--fs-caption);letter-spacing:.04em;text-transform:uppercase;padding:4px 10px;border-radius:999px;border:1px solid var(--line-chip);background:var(--wash);color:var(--ink);white-space:nowrap}
.pill--sev{color:var(--ink)}
.pill--freq{border-color:var(--accent);background:var(--wash-accent);color:var(--ink)}
.pill--confirmed{border-color:var(--accent);background:var(--wash-accent);color:var(--ink)}
.finding-measure{font-family:var(--mono);font-size:var(--fs-caption);color:var(--field-note);margin:var(--space-1) 0 0}
.finding-el{font-family:var(--mono);font-size:var(--fs-caption);color:var(--field-note);background:var(--paper-sunken);border:1px solid var(--line);border-radius:6px;padding:8px 11px;margin:var(--space-1) 0 0;overflow-x:auto;white-space:pre}
.finding-prose{margin:var(--space-2) 0 0}
.finding-prose dt{font-family:var(--mono);font-size:var(--fs-caption);letter-spacing:.06em;text-transform:uppercase;color:var(--graphite);margin-top:var(--space-1-5)}
.finding-prose dd{margin:4px 0 0;color:var(--ink);font-size:var(--fs-body);line-height:1.6}
.finding-wcag{font-family:var(--mono);font-size:var(--fs-caption);color:var(--graphite);margin-top:11px}
/* clean + offline states */
.result-clean{border:1px solid var(--accent);border-radius:12px;padding:22px 24px;background:var(--paper-raised);margin-top:var(--space-3)}
.result-clean h3{margin:0 0 var(--space-1);font-size:var(--fs-lead);color:var(--ink)}
.result-clean p{margin:0;color:var(--field-note);font-size:var(--fs-body);line-height:1.55}
.vision-offline{border:1px solid var(--line);border-left:3px solid var(--sev-moderate);border-radius:12px;padding:20px 22px;background:var(--paper-raised);margin-top:var(--space-3)}
.vision-offline h3{margin:0 0 var(--space-1);font-size:var(--fs-lead);color:var(--ink)}
.vision-offline p{margin:0 0 var(--space-2);color:var(--field-note);font-size:var(--fs-body);max-width:62ch;line-height:1.55}
/* export + screenshot */
.export-row{display:flex;gap:14px;flex-wrap:wrap;align-items:center;margin-top:var(--space-3)}
.tool-shot{margin-top:var(--space-4)}
.tool-shot .cap{font-family:var(--mono);font-size:var(--fs-caption);letter-spacing:.09em;text-transform:uppercase;color:var(--graphite);margin:0 0 var(--space-1)}
.tool-shot img{width:100%;max-width:100%;height:auto;border:1px solid var(--line);border-radius:10px;display:block}
/* methodology band
   A panel, not a rule and some text. Everything above it on a tool page sits on
   --paper-raised, so with only a border-top this section read as loose text dropped into
   the dark field rather than as the last part of the report. The type was never the
   problem: --graphite on --paper measures 11.19:1. What was missing was a surface. */
.how-it-works{margin-top:clamp(40px,6vw,64px);max-width:var(--tool-measure);
  padding:clamp(26px,4vw,38px) clamp(22px,3.4vw,34px);
  background:var(--paper-raised);border:1px solid var(--line);border-radius:14px}
.how-it-works h2{font-family:var(--sans);font-weight:600;font-size:clamp(20px,2.6vw,26px);color:var(--ink);margin:0 0 var(--space-2)}
.how-it-works h3{font-family:var(--sans);font-weight:600;font-size:var(--fs-lead);color:var(--ink);margin:var(--space-3) 0 var(--space-1)}
.how-it-works p{color:var(--graphite);font-size:var(--fs-body);line-height:1.6;margin:0 0 13px;max-width:66ch}
.how-it-works p:last-child{margin-bottom:0}
.how-it-works ul{list-style:none;padding:0;margin:var(--space-2) 0 0;display:flex;flex-direction:column;gap:8px;max-width:66ch}
/* The pass-frequency key is a legend for the pills, so it gets the pills' ground: one
   step up from the panel, using the same wash. */
.how-it-works li{font-size:var(--fs-body);color:var(--graphite);background:var(--wash);
  border:1px solid var(--line);border-radius:10px;padding:11px 14px;line-height:1.5}
.how-it-works li b{color:var(--ink);font-family:var(--mono);font-size:var(--fs-caption)}
@media (max-width:560px){.score-summary{grid-template-columns:repeat(2,1fr)}}

/* ---- Conference Proposal Drafter: five arrivals over ~75s ------------------
   Sections reuse .finding-group / .finding / .finding-prose / .result-meta.
   Only what the arrivals genuinely add is new: the elapsed clock, the picked
   title, the server-rendered rationale, and the reference excerpts. */
.stage-clock{font-family:var(--mono);font-size:var(--fs-caption);color:var(--graphite);margin-left:auto;font-variant-numeric:tabular-nums}
.title-option--pick{border-left-color:var(--accent)}
.proposal-draft{margin-top:var(--space-2)}
.proposal-draft > h2:first-child,.proposal-draft > h3:first-child{margin-top:0}
.book-answer h4{font-family:var(--sans);font-weight:600;font-size:var(--fs-body);color:var(--ink);margin:var(--space-3) 0 var(--space-1);line-height:1.35}
.book-answer h5{font-family:var(--mono);font-size:var(--fs-caption);letter-spacing:.08em;text-transform:uppercase;color:var(--graphite);margin:var(--space-3) 0 var(--space-1)}
.book-answer em{font-style:italic;color:var(--field-note)}
.book-answer hr{border:0;border-top:1px solid var(--line);margin:var(--space-3) 0}
/* rationale_html is server HTML; .rationale-section and .rationale-item are its
   own classes and the sanitiser keeps them, so they are styled here. */
.proposal-rationale .rationale-item{border:1px solid var(--line);border-left:3px solid var(--accent);
  border-radius:10px;padding:16px 18px;margin-top:var(--space-1-5);background:var(--paper-raised)}
.proposal-rationale .rationale-item > strong:first-child{display:block;font-family:var(--mono);font-size:var(--fs-caption);
  letter-spacing:.09em;text-transform:uppercase;color:var(--graphite);font-weight:400;margin-bottom:var(--space-1)}
.proposal-rationale blockquote{margin:0;padding:0 0 0 14px;border-left:2px solid var(--line);
  color:var(--ink);font-size:var(--fs-body);line-height:1.6}
.proposal-rationale p{color:var(--field-note);font-size:var(--fs-body);line-height:1.6;margin:var(--space-1-5) 0 0;max-width:70ch}
.proposal-rationale p strong{color:var(--graphite);font-family:var(--mono);font-size:var(--fs-caption);
  letter-spacing:.06em;text-transform:uppercase;font-weight:400}
.proposal-rationale em{font-style:italic;color:var(--ink)}

/* ---- Bio Writer: length set + one card per bio -----------------------------
   The endpoint writes every length in one call, so lengths are a checkbox set
   rather than a picker, and the comparison is the product. Five short numeric
   options read better as a wrapped row of chips than as five stacked cards,
   and the row survives 390px by wrapping.

   Selection uses the two grounds the option cards already use, --wash unchosen
   and --wash-accent chosen (1.31:1 and 1.52:1 off the panel), so a chosen chip
   reads as a lift on whatever ground the panel takes rather than as a hue
   swap. The stroke is --line-chip, which resolves to 4.53:1 against --wash and
   4.00:1 against --wash-accent: a chip stroke identifies a control, and SC
   1.4.11 wants 3:1 of that, which a 13% hairline (1.48:1) does not reach. The
   native checkbox stays visible so state is never carried by colour alone. */
.tool-panel > .field-group:first-child{margin-top:0}
.len-set{display:flex;flex-wrap:wrap;gap:10px;margin-top:var(--space-1-5)}
.len-chip{display:inline-flex;align-items:center;gap:9px;cursor:pointer;
  font-family:var(--mono);font-size:var(--fs-caption);color:var(--ink);
  border:1px solid var(--line-chip);border-radius:999px;padding:9px 15px 9px 12px;
  background:var(--wash);transition:border-color .18s ease,background .18s ease}
.len-chip input{margin:0;accent-color:var(--accent);width:16px;height:16px;flex:0 0 auto}
/* The range a length actually lands in, measured. It is a second number on an
   already-small chip, so it steps down in size but NOT into a dim grey: at 11.5px
   it needs the brightened --graphite (7.4:1 on --wash) to stay readable. */
.len-range{color:var(--graphite);font-size:var(--fs-caption);font-variant-numeric:tabular-nums}
.len-chip:hover{border-color:var(--ink)}
.len-chip:has(input:checked){border-color:var(--accent);background:var(--wash-accent)}
.len-chip input:focus-visible{outline:2px solid var(--accent);outline-offset:3px}
.bio-notes{min-height:150px}
/* The announcement region. The status region below it carries a per-second
   elapsed clock, which inside a live region would announce every second, so
   status is silent and these short discrete lines do the announcing. */
.tool-announce{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}
/* One bio, one card. The heading is the count that was WRITTEN; the count that
   was ASKED for is the secondary line. The hub now calibrates its request, so the
   two usually agree to within ten per cent, but a single run still lands 6 to 18
   words either side of its target and printing the request as the result would be
   a lie the page tells for the endpoint. */
.bio-card{border:1px solid var(--line);border-left:3px solid var(--accent);border-radius:10px;
  padding:18px 20px;margin-top:var(--space-2);background:var(--paper-raised)}
.bio-head{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 14px}
.bio-count{font-family:var(--sans);font-weight:600;font-size:var(--fs-lead);color:var(--ink);margin:0;
  font-variant-numeric:tabular-nums}
.bio-asked{font-family:var(--mono);font-size:var(--fs-caption);color:var(--graphite);font-variant-numeric:tabular-nums}
.bio-gap{font-family:var(--mono);font-size:var(--fs-caption);color:var(--graphite)}
.bio-body{margin-top:var(--space-2)}
.bio-foot{display:flex;flex-wrap:wrap;align-items:center;gap:12px;margin-top:var(--space-2)}
/* --ink rather than --accent on this label: the accent measures 4.35:1 on a
   raised panel, past the floor but short of the house target, and a
   confirmation is the last thing to make people squint at. */
.bio-copy{font-family:var(--mono);font-size:var(--fs-caption);letter-spacing:.04em;color:var(--ink);
  background:var(--wash);border:1px solid var(--line-chip);border-radius:8px;
  padding:9px 14px;cursor:pointer;transition:background .18s ease,border-color .18s ease}
.bio-copy:hover{border-color:var(--accent);background:var(--wash-accent)}
.bio-copy:disabled{opacity:.55;cursor:not-allowed}
.copy-note{font-family:var(--mono);font-size:var(--fs-caption);color:var(--ink)}
.bio-close{margin-top:var(--space-3)}
/* A quoted rule is prose, not a key, so it keeps the sans face rather than the
   mono treatment .how-it-works li b gives a label, and takes --ink for 9.34:1
   on the wash where --graphite would land at 6.21:1. */
.how-it-works li.rule{color:var(--ink)}
.similar-excerpt{margin:11px 0 0;padding:0 0 0 14px;border-left:2px solid var(--line);
  color:var(--field-note);font-size:var(--fs-body);line-height:1.6;max-width:70ch}
.similar-link{margin:var(--space-2) 0 0}
.similar-link .listing-link{color:var(--accent);border-bottom-color:transparent}
.similar-link .listing-link:hover{border-bottom-color:var(--accent)}
.proposal-close{margin-top:var(--space-4);padding-top:20px;border-top:1px solid var(--line)}

.page-hero .cap .wrap{padding-bottom:clamp(24px,4vw,46px)}
.page-hero .hero-head--sm{margin-top:var(--space-1)}
.hero-credit{position:absolute;right:clamp(16px,4vw,44px);bottom:12px;
  font-family:var(--mono);font-size:var(--fs-caption);letter-spacing:.06em;color:var(--muted);
  text-shadow:0 1px 3px rgba(0,0,0,.65)}

/* =================================================== LISTING (Launches / Labs) */
/* Sub-page hero: smaller than the home hero. */
.hero--sub{padding:clamp(48px,8vw,88px) 0 clamp(28px,4vw,44px)}
.hero-head--sm{font-size:clamp(30px,4.4vw,48px);max-width:20ch}

.listing{list-style:none;margin:0;padding:0;display:flex;flex-direction:column}
.listing-row{display:grid;grid-template-columns:minmax(0,40%) 1fr;gap:clamp(24px,4vw,56px);
  align-items:center;padding:clamp(30px,4vw,48px) 0}
.listing-row + .listing-row{border-top:1px solid var(--line)}
.listing-media{aspect-ratio:16/10;border:1px solid var(--line);border-radius:12px;
  background:var(--paper-raised);display:flex;align-items:center;justify-content:center;
  color:var(--graphite);font-family:var(--mono);font-size:var(--fs-caption);letter-spacing:.16em;text-transform:uppercase;
  overflow:hidden}
.listing-media img{width:100%;height:100%;object-fit:cover}
.listing-title{font-size:clamp(23px,2.7vw,32px);margin:0 0 var(--space-1)}
.listing-title a{color:inherit;text-decoration:none}
.listing-title a .arw{opacity:0;margin-left:.15em;transition:opacity .18s ease,transform .18s ease;display:inline-block}
.listing-title a:hover{color:var(--accent)}
.listing-title a:hover .arw{opacity:1;transform:translateX(3px)}
.listing-title a:focus-visible{outline:2px solid var(--accent);outline-offset:3px;border-radius:3px}
.listing-meta{font-family:var(--mono);font-size:var(--fs-caption);letter-spacing:.08em;text-transform:uppercase;
  color:var(--graphite);margin:0 0 var(--space-2)}
.listing-copy{color:var(--graphite);margin:0 0 var(--space-2);max-width:52ch}
.listing-link{font-family:var(--mono);font-size:var(--fs-caption);letter-spacing:.04em;color:var(--ink);
  text-decoration:none;display:inline-flex;align-items:center;gap:.5em;
  border-bottom:1px solid var(--line);padding-bottom:2px;transition:border-color .18s ease}
.listing-link:hover{border-color:var(--accent)}
.listing-link .arw{transition:transform .18s ease}
.listing-link:hover .arw{transform:translateX(3px)}
.listing-actions{display:flex;align-items:baseline;gap:22px;flex-wrap:wrap}
/* quiet, un-bylined depth link — deliberately lighter than Visit */
.listing-notes{font-family:var(--mono);font-size:var(--fs-caption);letter-spacing:.04em;color:var(--graphite);
  text-decoration:none;display:inline-flex;align-items:center;gap:.45em;transition:color .18s ease}
.listing-notes:hover{color:var(--ink)}
.listing-notes .arw{transition:transform .18s ease}
.listing-notes:hover .arw{transform:translateX(3px)}

/* Labs mirrors Launches: image-right / text-left, to signal a different content
   class (experiments, not launched properties) and lead with the idea. */
.listing--flip .listing-row{grid-template-columns:1fr minmax(0,40%)}
.listing--flip .listing-body{order:1}
.listing--flip .listing-media{order:2}

@media(max-width:720px){
  .listing-row{grid-template-columns:1fr;gap:18px}
  .listing--flip .listing-row{grid-template-columns:1fr}  /* body already order:1 → text-first */
}

/* =================================================== BRAND PAGE */
.section-head{max-width:60ch}
.section-head .lead{margin-top:var(--space-2)}
/* positioning: label / value pairs */
.def-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:0 48px;margin-top:var(--space-4)}
.def-item{padding:20px 0;border-top:1px solid var(--line)}
.def-item .k{font-family:var(--mono);font-size:var(--fs-caption);letter-spacing:.16em;text-transform:uppercase;color:var(--accent);margin:0 0 var(--space-1)}
.def-item .d{margin:0;color:var(--ink);max-width:46ch}
/* marks showcase */
.marks{display:flex;flex-wrap:wrap;gap:clamp(32px,5vw,64px);align-items:flex-end;margin-top:var(--space-4)}
.mark-demo{display:flex;flex-direction:column;gap:14px;color:var(--ink)}
.mark-demo .cap{font-family:var(--mono);font-size:var(--fs-caption);letter-spacing:.14em;text-transform:uppercase;color:var(--graphite)}
.mark-demo .lockup-lg{width:220px;height:auto}
.mark-demo .mark-lg{height:66px;width:auto;fill:currentColor}
.mark-demo .avatar-lg{width:66px;height:66px;color:var(--ink)}
/* palette swatches */
.swatches{display:grid;grid-template-columns:repeat(auto-fill,minmax(210px,1fr));gap:22px;margin-top:var(--space-4)}
.swatch .chip{height:60px;border-radius:8px;border:1px solid var(--line)}
.swatch .name{font-family:var(--mono);font-size:var(--fs-caption);letter-spacing:.02em;color:var(--ink);margin:var(--space-1-5) 0 0}
.swatch .role{font-size:var(--fs-caption);color:var(--graphite);margin:4px 0 0;max-width:30ch}
.swatch .ratio{font-family:var(--mono);font-size:var(--fs-caption);color:var(--muted);margin:4px 0 0}
/* type specimen */
.specimen{margin-top:var(--space-4);display:grid;gap:22px}
.specimen .big{font-family:var(--sans);font-weight:600;font-size:clamp(38px,6vw,64px);letter-spacing:-.01em;line-height:1;color:var(--ink)}
.specimen .mono{font-family:var(--mono);font-size:var(--fs-lead);color:var(--ink)}
.specimen .cap{font-family:var(--mono);font-size:var(--fs-caption);letter-spacing:.14em;text-transform:uppercase;color:var(--graphite);margin-bottom:var(--space-1)}
/* rationale */
.rationale{list-style:none;padding:0;margin:var(--space-4) 0 0;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:34px 48px}
.rationale .n{font-family:var(--mono);font-size:var(--fs-caption);letter-spacing:.1em;color:var(--accent)}
.rationale h3{margin:.35em 0 .3em}
.rationale p{color:var(--graphite);max-width:44ch;margin:0}
/* the rules (don'ts) */
.rules{list-style:none;padding:0;margin:var(--space-4) 0 0;display:grid;gap:15px;max-width:74ch}
.rules li{position:relative;padding-left:28px;color:var(--ink)}
.rules li::before{content:"\00D7";position:absolute;left:2px;top:-1px;color:var(--fault);
  font-family:var(--mono);font-size:var(--fs-body);line-height:1.4}
/* construction */
.construct{display:flex;flex-wrap:wrap;gap:clamp(28px,5vw,60px);align-items:center;margin-top:var(--space-1)}
.construct .mark-big{height:118px;width:auto;fill:currentColor;color:var(--ink)}
.spec-table{border-collapse:collapse;font-size:var(--fs-body);min-width:300px}
.spec-table td{padding:9px 0;border-top:1px solid var(--line);vertical-align:top}
.spec-table td:first-child{font-family:var(--mono);font-size:var(--fs-caption);letter-spacing:.06em;text-transform:uppercase;color:var(--graphite);padding-right:26px}
.spec-table td:last-child{color:var(--ink)}
/* clear space + sizing */
.clearspace{display:inline-block;padding:clamp(16px,4vw,32px);border:1px dashed var(--accent);border-radius:6px;margin-top:var(--space-3)}
.clearspace .inner{border:1px solid var(--line);padding:12px;display:flex}
.clearspace .mark{height:60px;width:auto;fill:currentColor;color:var(--ink)}
.size-row{display:flex;gap:clamp(24px,4vw,46px);align-items:flex-end;flex-wrap:wrap;margin-top:var(--space-4)}
.size-item{display:flex;flex-direction:column;align-items:center;gap:10px}
.size-item .mark{fill:currentColor;color:var(--ink);width:auto}
.size-item .cap{font-family:var(--mono);font-size:var(--fs-caption);letter-spacing:.1em;color:var(--graphite)}
/* variants */
.variant-tiles{display:grid;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:18px;margin-top:var(--space-4)}
.variant{border:1px solid var(--line);border-radius:10px;padding:28px 24px;display:flex;flex-direction:column;gap:18px;align-items:flex-start}
.variant .lockup-sm{width:150px;height:auto}
.variant .mark-sm{height:46px;width:auto;fill:currentColor}
.variant .vc{font-family:var(--mono);font-size:var(--fs-caption);letter-spacing:.12em;text-transform:uppercase;color:inherit;opacity:.62}
/* files */
.file-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:12px;margin-top:var(--space-3)}
.file-list a{display:flex;justify-content:space-between;gap:12px;align-items:center;font-family:var(--mono);
  font-size:var(--fs-caption);color:var(--ink);text-decoration:none;border:1px solid var(--line);border-radius:8px;
  padding:14px 16px;transition:border-color .18s ease}
.file-list a:hover{border-color:var(--accent)}
.file-list a .dl{color:var(--accent);font-size:var(--fs-caption);letter-spacing:.08em;white-space:nowrap}
/* neutral ramp table */
.ramp-table{border-collapse:collapse;font-size:var(--fs-caption);margin-top:var(--space-3);width:100%;max-width:760px}
.ramp-table th{font-family:var(--mono);font-size:var(--fs-caption);letter-spacing:.1em;text-transform:uppercase;color:var(--graphite);text-align:left;padding:0 18px 10px 0;font-weight:400}
.ramp-table td{padding:11px 18px 11px 0;border-top:1px solid var(--line);color:var(--ink);vertical-align:top}
.ramp-table td.sw{white-space:nowrap;font-family:var(--mono);font-size:var(--fs-caption)}
/* Swatch ring: --line-chip, not --line. A ramp swatch can be any value in the range, and
   the dark end of one goes invisible against the page on a --line hairline: #333333 is
   1.45:1 off the ground and #15161A is 1.02:1. The chip stroke gives those a 6.6:1 edge.
   It disappears on the light swatches instead, which is the harmless half of the trade,
   since those already read against the page at 6:1 or better on their own. */
.ramp-table td.sw i{display:inline-block;width:14px;height:14px;border-radius:3px;border:1px solid var(--line-chip);vertical-align:-2px;margin-right:var(--space-1)}
.ramp-table td.note{color:var(--graphite);line-height:1.5}
/* business cards */
.card-tiles{display:grid;grid-template-columns:repeat(auto-fill,minmax(290px,1fr));gap:18px;margin-top:var(--space-3)}
.card{aspect-ratio:85/55;border:1px solid var(--line);border-radius:10px;display:flex;flex-direction:column;justify-content:center;align-items:center;gap:14px;padding:26px;text-align:center}
.card .mark{height:44px;fill:currentColor;width:auto}
.card .cc{font-family:var(--mono);font-size:12px;letter-spacing:.05em;line-height:1.8}
.card .cc .u{color:var(--accent)}
.card .cardcap{font-family:var(--mono);font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--graphite)}
/* asset tag + packaging */
.asset-tag{display:inline-grid;grid-template-columns:auto auto;gap:8px 24px;border:1px solid var(--line);border-radius:8px;padding:18px 22px;margin-top:var(--space-3);font-family:var(--mono);font-size:12px}
.asset-tag dt{color:var(--graphite);letter-spacing:.08em;text-transform:uppercase;font-size:10px;align-self:center}
.asset-tag dd{margin:0;color:var(--ink)}
/* status board mini */
.board{border:1px solid var(--line);border-radius:10px;overflow:hidden;margin-top:var(--space-3);max-width:660px}
.board .row{display:grid;grid-template-columns:1fr auto minmax(120px,auto);gap:18px;align-items:center;padding:13px 18px;border-top:1px solid var(--line);font-size:var(--fs-body)}
.board .row:first-child{border-top:0}
.board .name{color:var(--ink)}
.board .kind{font-family:var(--mono);font-size:var(--fs-caption);letter-spacing:.08em;text-transform:uppercase;color:var(--graphite)}
.board .state{font-family:var(--mono);font-size:var(--fs-caption);color:var(--graphite);display:flex;gap:.6em;align-items:center;justify-content:flex-end}
.board .state .dot{width:7px;height:7px;border-radius:50%;flex:0 0 auto;background:var(--graphite)}
.board .live .dot{background:var(--accent)}
.board .fault{color:var(--fault-text)}
.board .fault .dot{background:var(--fault)}
/* at scale */
/* The deepest ground, so it uses the deepest ground token. #0C0F18 was a hand-typed
   duplicate of --paper-sunken, 1.006:1 apart, which is no colour at all. */
.scale-tile{background:var(--paper-sunken);border:1px solid var(--line);border-radius:12px;padding:clamp(36px,6vw,72px) clamp(28px,5vw,56px);margin-top:var(--space-3);display:flex;flex-direction:column;gap:24px}
.scale-tile .mark{height:clamp(56px,9vw,96px);fill:currentColor;color:var(--ink);width:auto}
.scale-tile .line{font-family:var(--mono);font-size:var(--fs-caption);letter-spacing:.12em;color:var(--accent)}
/* closing */
.closing{padding:clamp(54px,8vw,100px) 0}
.closing .big{font-family:var(--sans);font-weight:600;font-size:clamp(24px,3.4vw,38px);line-height:1.25;max-width:26ch;color:var(--ink);margin:0}
.closing p{color:var(--graphite);max-width:66ch;margin:var(--space-3) 0 0}

/* ---- applied mockups, re-themed dark (per the brand book compositions) ---- */
/* business cards as objects */
.cards-scene{margin-top:var(--space-4);padding:clamp(34px,6vw,64px) clamp(20px,4vw,40px);background:var(--paper-sunken);
  border-radius:12px;display:flex;gap:clamp(24px,4vw,60px);flex-wrap:wrap;justify-content:center;align-items:center}
.card3d{width:min(300px,82vw);aspect-ratio:85/55;border-radius:12px;display:flex;flex-direction:column;
  justify-content:center;align-items:center;gap:12px;padding:26px;box-shadow:0 26px 52px rgba(0,0,0,.5);transform:rotate(-3deg)}
.card3d.rev{transform:rotate(3deg)}
.card3d.paper{background:#F6F5F1;color:#15161A;--tick:#2E71B9;--accent:#2E71B9}
.card3d.ink{background:#15161A;color:#F6F5F1;--tick:#5297DE;--accent:#5297DE}
.card3d .mark{height:44px;fill:currentColor;width:auto}
.card3d .cc{font-family:var(--mono);font-size:12px;letter-spacing:.05em;line-height:1.8;text-align:center}
.card3d .cc .u{color:var(--accent)}
/* packaging objects */
.pkg-scene{display:flex;flex-wrap:wrap;gap:20px;margin-top:var(--space-4);align-items:flex-end;justify-content:flex-start}
.pkg-obj{flex:0 1 auto;border:1px solid var(--line);border-radius:10px;padding:22px 18px;display:flex;flex-direction:column;
  gap:16px;align-items:center;justify-content:center;text-align:center;background:var(--paper-raised);position:relative}
.pkg-obj .mark{height:30px;fill:currentColor;color:var(--ink);width:auto}
.pkg-obj .lbl{font-family:var(--mono);font-size:9.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--graphite);line-height:1.5}
/* PRD booklet — portrait with a spine */
.pkg-obj.booklet{width:172px;aspect-ratio:89/128;justify-content:flex-end;padding-bottom:26px;border-left:3px solid var(--accent)}
.pkg-obj.booklet .mark{margin-bottom:auto;margin-top:var(--space-1)}
/* sticker sheet — a grid of die-cut marks */
.pkg-obj:not(.booklet):not(.box){width:210px;aspect-ratio:1/1}
.pkg-obj .stickers{display:grid;grid-template-columns:repeat(3,1fr);gap:16px 18px;width:100%;padding:0 6px}
.pkg-obj .stickers .mark{height:22px;margin:0 auto}
/* kraft mailer — a parcel with a lid seam and tape */
/* The mailer is lit, not coloured. Its old gradient (#2b3242 / #202633 / #161a24) was
   hand-tuned against the previous #191F2E panel, where it ran 1.28:1 ABOVE its booklet
   and sticker-sheet siblings for most of its face. Against the current #272F42 panel the
   same stops land 1.13:1 and 1.30:1 BELOW them, so the parcel read as a hole punched in
   the row. Rebuilt as a highlight and a shadow over the sibling ground, so it stays a lit
   object whatever the panel becomes: 1.31:1 up at the lit corner, 1.21:1 down in the
   shadow. */
.pkg-obj.box{width:220px;aspect-ratio:1/.8;overflow:hidden;justify-content:center;
  background:linear-gradient(160deg,rgba(246,245,241,.09) 0%,rgba(246,245,241,0) 42%,
    rgba(0,0,0,.30) 100%),var(--paper-raised)}
.pkg-obj.box .mark{color:var(--ink);opacity:.9}
.pkg-obj.box .lbl{position:relative;z-index:2}
/* Packing tape and lid seam. At 5% the tape measured 1.15:1 on the face, under the step
   the eye resolves, and its 12% edges then sat inside that so the whole detail was
   notional. Tape now reads 1.35:1 on the face with edges 1.45:1 on the tape, and the lid
   seam 1.53:1. Every value is an ink percentage over whatever the face is, so the detail
   travels with the ground. */
.pkg-obj.box::before{content:"";position:absolute;left:38%;right:38%;top:0;bottom:0;background:rgba(246,245,241,.10);border-left:1px solid rgba(246,245,241,.22);border-right:1px solid rgba(246,245,241,.22)}
.pkg-obj.box::after{content:"";position:absolute;left:0;right:0;top:34%;height:1px;background:rgba(246,245,241,.14)}
/* status board inside a browser window */
.browser{border:1px solid var(--line);border-radius:12px;overflow:hidden;margin-top:var(--space-4);max-width:780px;background:var(--paper-raised)}
.browser-bar{display:flex;align-items:center;gap:16px;padding:11px 15px;border-bottom:1px solid var(--line);background:var(--paper-sunken)}
.browser-bar .dots{display:flex;gap:7px;flex:0 0 auto}
.browser-bar .dots i{width:11px;height:11px;border-radius:50%;background:var(--line)}
.browser-bar .url{flex:1;font-family:var(--mono);font-size:12px;color:var(--graphite);background:var(--paper);border:1px solid var(--line);border-radius:6px;padding:6px 12px}
.browser-body{padding:clamp(22px,3vw,34px)}
.browser-body h4{font-family:var(--sans);font-weight:600;font-size:clamp(21px,2.6vw,28px);margin:0 0 var(--space-1);color:var(--ink);letter-spacing:-.01em}
.browser-body .bsub{color:var(--graphite);font-size:var(--fs-caption);margin:0 0 var(--space-3);max-width:54ch}
.browser-body .board{margin-top:0}
/* billboard against a twilight sky */
.billboard{margin-top:var(--space-4);border-radius:12px;overflow:hidden;position:relative;padding:clamp(40px,7vw,88px) clamp(24px,5vw,56px) clamp(64px,10vw,120px);
  background:linear-gradient(180deg,#16283f 0%,#101a2b 46%,#0b0e18 62%,#0b0e18 100%)}
.billboard .panel{max-width:600px;margin:0 auto;background:#101116;border:1px solid rgba(246,245,241,.14);border-radius:8px;
  padding:clamp(24px,4vw,40px) clamp(26px,5vw,48px);display:flex;align-items:center;justify-content:space-between;gap:28px;box-shadow:0 32px 64px rgba(0,0,0,.55)}
.billboard .panel .mark{height:clamp(40px,6vw,64px);fill:currentColor;color:var(--ink);width:auto;flex:0 0 auto}
.billboard .panel .line{font-family:var(--mono);font-size:12px;letter-spacing:.1em;color:var(--accent);text-align:right;line-height:1.7}
.billboard .posts{position:absolute;left:50%;transform:translateX(-50%);bottom:0;display:flex;gap:clamp(120px,20vw,220px)}
.billboard .posts i{width:9px;height:clamp(48px,8vw,96px);background:#0b0e18;border-left:1px solid rgba(246,245,241,.12);border-right:1px solid rgba(246,245,241,.12)}

@media(max-width:720px){
  .def-grid,.rationale{grid-template-columns:1fr}
  .def-item{padding:16px 0}
}

/* =================================================== DESIGN SYSTEM PAGE */
/* The surface ladder is drawn as the thing it documents: each ground is nested inside
   the one it sits on, so the measured step is printed at the boundary it measures.
   Captions take --ink and --graphite, never --accent, because the accent lands at
   4.35:1 on a raised panel and this page holds every value it prints to the same
   floor it asks of the rest of the property. */
.ladder{margin-top:var(--space-4);border:1px solid var(--line);border-radius:14px;
  padding:clamp(18px,2.8vw,28px);background:var(--paper)}
.ladder-raised{background:var(--paper-raised);border:1px solid var(--line);border-radius:12px;
  padding:clamp(16px,2.4vw,24px)}
.ladder-sunken{background:var(--paper-sunken);border:1px solid var(--line);border-radius:12px;
  padding:clamp(16px,2.4vw,24px);margin-top:var(--space-2)}
.ladder-cap{font-family:var(--mono);font-size:var(--fs-caption);letter-spacing:.09em;text-transform:uppercase;
  color:var(--graphite);margin:0 0 13px;display:flex;flex-wrap:wrap;gap:.35em 1.2em;align-items:baseline}
.ladder-cap .val,.ladder-cap .step{color:var(--ink)}
.ladder-cap .step{font-weight:600}
.ladder-chips{display:flex;flex-wrap:wrap;gap:10px;align-items:center}
.ladder-chips .lc{font-family:var(--mono);font-size:var(--fs-caption);letter-spacing:.07em;
  text-transform:uppercase;color:var(--graphite)}
/* Token and pairing tables reuse .ramp-table, and inherit its --line-chip swatch ring.
   These swatches only need to be bigger, because a surface value should read as a
   surface rather than as a dot. */
.ramp-table td.sw i.surf{width:26px;height:18px;border-radius:4px;vertical-align:-4px}
.ramp-table td.num{font-family:var(--mono);font-size:var(--fs-caption);color:var(--ink);
  font-variant-numeric:tabular-nums;white-space:nowrap}
/* Narrow: the table stacks. A stacked row loses its column headers, so a figure would
   read as a bare number with nothing saying which surface it measures. Cells carry their
   own label and print it here. */
@media(max-width:640px){
  .ramp-table,.ramp-table tbody,.ramp-table tr,.ramp-table td,.ramp-table th{display:block;width:100%}
  .ramp-table thead{display:none}
  .ramp-table tr{border-top:1px solid var(--line);padding:14px 0}
  .ramp-table td{border-top:0;padding:3px 0}
  .ramp-table td[data-l]::before{content:attr(data-l);display:inline-block;min-width:11em;
    font-family:var(--mono);font-size:var(--fs-caption);letter-spacing:.1em;text-transform:uppercase;
    color:var(--graphite)}
  .ramp-table td.sw{margin-bottom:var(--space-1)}
}

/* =================================================== PAIRS GALLERY (fleet.html) */
.pairs{display:flex;flex-direction:column;gap:clamp(30px,4vw,52px);margin-top:var(--space-4)}
.pair-label{font-family:var(--mono);font-size:var(--fs-caption);letter-spacing:.14em;text-transform:uppercase;
  color:var(--ink);margin:0 0 var(--space-1-5);display:flex;gap:.8em;align-items:baseline}
.pair-label .code{color:var(--accent)}
.pair-imgs{display:grid;grid-template-columns:1fr 1fr;gap:clamp(14px,2vw,24px)}
.pair-imgs figure{margin:0}
.pair-imgs img{width:100%;height:auto;display:block;border:1px solid var(--line);border-radius:10px}
.pair-imgs figcaption{font-family:var(--mono);font-size:var(--fs-caption);letter-spacing:.12em;text-transform:uppercase;
  color:var(--graphite);margin-top:var(--space-1)}
@media(max-width:640px){.pair-imgs{grid-template-columns:1fr}}

@media(prefers-reduced-motion:reduce){
  *{scroll-behavior:auto!important;transition:none!important}
}

/* ============================================================================
   Labs tool: Synthetic Research Personas. Every control on this surface is
   built from the roster at runtime, so the CSS styles shapes rather than a
   fixed number of options: five projects or six, four people or three, the
   layouts wrap.

   Grounds step the same way they do everywhere else on the bench. The page is
   --paper, a panel is --paper-raised, a nested row inside a panel is --wash,
   and the accent ground is --wash-accent. Nothing here picks a literal colour
   against a surface, which is what broke the selected-radio state before.
   ============================================================================ */
.tool-nojs{background:var(--paper-sunken);border:1px solid var(--line);border-radius:10px;
  padding:14px 16px;font-size:var(--fs-body);color:var(--field-note);line-height:1.55;margin:0 0 var(--space-3)}
html.js .tool-nojs{display:none}
.pq-loading{font-family:var(--mono);font-size:var(--fs-caption);color:var(--graphite);margin:var(--space-1-5) 0 0}
/* The synthetic disclosure. It sits in the form before anything is asked, at
   the top of the results, and again on every single answer, because a shared
   or screenshotted card has to carry it on its own. */
/* max-width:none, because the global 66ch on a <p> stops the RULE of a bordered
   box short of the panel it sits in and reads as a truncated card. */
.tool-disclosure{background:var(--paper-sunken);border:1px solid var(--line);border-left:3px solid var(--accent);
  border-radius:10px;padding:13px 16px;margin:0 0 4px;max-width:none;
  font-size:var(--fs-body);color:var(--field-note);line-height:1.55}
/* Third line inside a project card: how many people the research produced. */
.radio-card .rc-meta{font-family:var(--mono);font-size:var(--fs-caption);letter-spacing:.04em;color:var(--graphite);margin-top:5px}

/* Who answers. These checkboxes are the speed control as much as the cast
   list, so the cost rides on the control itself: a per-person chip on each
   card and a running total under the set, both in numbers rather than in a
   sentence above them. */
.pq-people{margin-top:var(--space-1-5)}
.pq-person{display:flex;gap:13px;align-items:flex-start;border:1px solid var(--line);border-radius:12px;
  padding:14px 16px;margin-top:11px;cursor:pointer;background:var(--wash);
  transition:border-color .18s ease,background .18s ease}
.pq-person:hover{border-color:var(--ink)}
.pq-person:has(input:checked){border-color:var(--accent);background:var(--wash-accent)}
.pq-person input{margin:2px 0 0;accent-color:var(--accent);width:17px;height:17px;flex:0 0 auto}
.pq-person input:focus-visible{outline:2px solid var(--accent);outline-offset:3px}
.pq-person .rc-body{display:flex;flex-direction:column;gap:3px;min-width:0}
.pq-person-top{display:flex;flex-wrap:wrap;align-items:baseline;gap:6px 10px}
/* The time each person adds, on the control that adds it. Mono and tabular so
   the four of them line up as a sum rather than as decoration. */
.pq-person-cost{font-family:var(--mono);font-size:var(--fs-caption);letter-spacing:.04em;color:var(--ink);
  background:var(--paper-sunken);border:1px solid var(--line-chip);border-radius:999px;
  padding:2px 9px;font-variant-numeric:tabular-nums;white-space:nowrap}
.pq-person-role{font-family:var(--sans);font-size:var(--fs-body);color:var(--ink-2);line-height:1.45}
.pq-person .rc-desc{font-size:var(--fs-body);color:var(--field-note);line-height:1.5}
/* Selected cards sit on --wash-accent, where the muted tokens fall to between
   5.35:1 and 6.17:1, short of the house target for text this small. That ground
   is built to carry --ink at 8.05:1, so the secondary lines step UP when the
   card is chosen rather than staying muted on a ground that cannot hold them.
   All four people are ticked by default, so this is the state most visitors
   read, not an edge case. */
.pq-projects .radio-card:has(input:checked) .rc-desc,
.pq-projects .radio-card:has(input:checked) .rc-meta,
.pq-person:has(input:checked) .pq-person-role,
.pq-person:has(input:checked) .rc-desc{color:var(--ink)}

/* The results: the question, then one card per person as each lands. */
.pq-results-head{margin-top:var(--space-1)}
.pq-question{font-family:var(--sans);font-size:var(--fs-lead);line-height:1.5;color:var(--ink);
  border-left:3px solid var(--line-chip);padding:2px 0 2px 16px;margin:var(--space-2) 0 0;max-width:64ch}
.pq-results-disclosure{font-family:var(--sans);font-size:var(--fs-body);color:var(--field-note);
  margin:var(--space-2) 0 0;line-height:1.55;max-width:64ch}
.persona-card{border:1px solid var(--line);border-left:3px solid var(--accent);border-radius:10px;
  padding:18px 20px;margin-top:var(--space-2);background:var(--paper-raised)}
.persona-head{display:flex;flex-wrap:wrap;align-items:baseline;gap:6px 12px}
.persona-name{font-family:var(--sans);font-weight:600;font-size:var(--fs-lead);color:var(--ink);margin:0}
/* A caveat chip rather than an endorsement, so it takes the recessed ground
   instead of the accent the confirmed pills use. */
.pill--synthetic{background:var(--paper-sunken);border-color:var(--line-chip);color:var(--ink-2)}
.persona-role{font-family:var(--sans);font-size:var(--fs-body);color:var(--field-note);margin:var(--space-1) 0 0;line-height:1.45}
.persona-body{margin-top:var(--space-2)}
.persona-sources{margin-top:var(--space-2);border-top:1px solid var(--line);padding-top:14px}
.persona-sources h5{font-family:var(--mono);font-size:var(--fs-caption);letter-spacing:.08em;text-transform:uppercase;
  color:var(--graphite);margin:0 0 var(--space-1)}
.persona-source-list{margin:0;padding-left:22px}
.persona-source{color:var(--ink);font-size:var(--fs-body);line-height:1.5;margin:0 0 var(--space-1)}
.src-kind{font-family:var(--mono);font-size:var(--fs-caption);letter-spacing:.05em;text-transform:uppercase;
  color:var(--graphite);margin-right:var(--space-1)}
.persona-synthetic-note{font-family:var(--sans);font-size:var(--fs-caption);color:var(--field-note);
  margin:var(--space-2) 0 0;line-height:1.5}

/* The comparison. Four answers are raw material; where they split is the
   product, so it gets its own band rather than a heading at the bottom of the
   answers: a wider surface, the accent stroke across the top, and the
   disagreements first and largest inside it. */
.pq-payoff{margin-top:var(--space-4);background:var(--paper-raised);border:1px solid var(--line);
  border-top:3px solid var(--accent);border-radius:14px;padding:clamp(20px,3.5vw,30px)}
.pq-payoff-head .ey{margin-bottom:var(--space-1)}
.pq-payoff-head-line{font-family:var(--sans);font-weight:600;font-size:clamp(22px,3.2vw,30px);
  color:var(--ink);margin:0 0 var(--space-1);line-height:1.2}
.pq-split{margin-bottom:var(--space-1)}
.pq-topic{background:var(--wash);border:1px solid var(--line);border-radius:12px;
  padding:16px 18px;margin-top:var(--space-2)}
.pq-topic-name{font-family:var(--sans);font-weight:600;font-size:var(--fs-lead);color:var(--ink);margin:0 0 4px;line-height:1.35}
.pq-positions{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:14px;margin-top:var(--space-2)}
.pq-position{border-left:2px solid var(--line-chip);padding-left:14px}
.pq-position-who{display:block;font-family:var(--mono);font-size:var(--fs-caption);letter-spacing:.05em;
  text-transform:uppercase;color:var(--ink);margin-bottom:var(--space-1)}
.pq-position-view{font-size:var(--fs-body);line-height:1.6;color:var(--ink);margin:0}
.pq-consensus-desc{font-size:var(--fs-body);line-height:1.6;color:var(--ink);margin:var(--space-1) 0 0;max-width:70ch}
.pq-unique-list,.pq-followups{margin:var(--space-1-5) 0 0;padding-left:20px}
.pq-unique-list li,.pq-followups li{color:var(--ink);font-size:var(--fs-body);line-height:1.6;margin:0 0 var(--space-1);max-width:70ch}
.pq-payoff .finding-group{margin-top:var(--space-3)}
.pq-payoff .tool-msg{margin-top:var(--space-2)}
.pq-close{margin-top:var(--space-3)}
@media(max-width:560px){
  .pq-person{padding:13px 14px}
  .pq-positions{grid-template-columns:1fr}
}

/* --- Labs tool: Heuristics Evaluator ------------------------------------- */

/* A tier we show and do not run. Deliberately not [disabled]: a disabled
   control leaves the tab order and screen readers skip it, which would hide
   the deeper tier from the people most likely to want it. */
.radio-card.is-gated { opacity: .78; }
.radio-card.is-gated,
.radio-card.is-gated input { cursor: not-allowed; }
.radio-card.is-gated .rc-title::after {
  content: " · on request";
  font-family: "IBM Plex Mono", monospace;
  font-size: .78em;
  letter-spacing: .02em;
  opacity: .95;
}
.radio-card.is-gated input:focus-visible { outline: 2px solid var(--wash-accent); outline-offset: 3px; }

.input-slot[hidden] { display: none; }
.tool-file { width: 100%; padding: .6rem 0; }

.cov-bucket.is-empty { opacity: .82; }
.cov-bucket.is-empty .cov-desc { margin-bottom: 0; }

/* The four stages, all named from the start. A short stage can begin and end
   between two polls, so naming only the current one leaves gaps in the story. */
.stage-list { list-style: none; margin: .75rem 0 .5rem; padding: 0; display: grid; gap: .3rem; }
.stage-step { display: flex; gap: .55rem; align-items: baseline; font-size: .92rem; }
.step-dot { width: .5rem; height: .5rem; border-radius: 50%; flex: 0 0 auto;
            background: var(--line-chip); transform: translateY(-.1em); }
.stage-step[data-state="done"] .step-dot { background: var(--wash-accent); }
.stage-step[data-state="current"] .step-dot { background: #fff; box-shadow: 0 0 0 3px var(--wash-accent); }
.stage-step[data-state="pending"] { opacity: .72; }
.stage-step[data-state="current"] .step-label { font-weight: 600; }

/* --- Heuristics report container -----------------------------------------
   The report is a dark document on a dark page, so there is no mat: the page
   ground IS the margin. The panel takes a radius, a hairline and a shadow so
   it reads as a distinct surface rather than bleeding into the page.

   No max-width (it caps itself at 896px and centres), padding at their 32px
   ceiling, and no fixed height: it runs to ~10,000px and scrolls with the
   page. */
.tool[data-widget="heuristics"] .tool-results,
.tool[data-widget="compliance"] .tool-results {
  margin-top: 2rem;
  border-radius: 14px;
  /* --line is rgba(...,.13), which on the dark page reads as black on black.
     A drawn edge at this size has to be drawn, the same reasoning --line-chip
     already carries in the system. */
  border: 1px solid var(--wash);
  box-shadow: 0 18px 48px rgba(0, 0, 0, .45);
  overflow: hidden;
  /* The report brings no padding of its own (measured: 0), so the panel owns
     the breathing room. More at the top than their 32px ceiling on the sides,
     because an h1 needs air above it, and a real gap at the bottom so the last
     block does not butt the edge. */
  padding: 48px 32px 56px;
  width: clamp(100%, 1024px, calc(100vw - 8rem));
  max-width: none;
}
@media (max-width: 640px) {
  .tool[data-widget="heuristics"] .tool-results,
  .tool[data-widget="compliance"] .tool-results { margin-top: 1.25rem; border-radius: 10px;
    padding: 28px 16px 32px; }
}

/* --- The report, inside our page -----------------------------------------

   Two jobs here, and they are not the same job.

   FIRST: stop our own globals leaking in. site.css styles bare elements —
   `p { max-width: 66ch }`, `h1,h2,h3,h4 {...}`, `a { color: inherit }` — which
   is fine for our pages and wrong for a document someone else laid out. The
   p rule alone capped every paragraph at 624px inside a 960px report, which is
   the white space on the right: copy on the left, a third of the card empty.
   These reset it to what the report's own stylesheet intends. This is undoing
   our interference, not restyling their report.

   SECOND: adopt our typography, deliberately, so it reads as a Mito Workshop
   document rather than a RAG4 one. Type family and weight only. Their layout,
   spacing, colour and component structure are left exactly as they are. */

/* 1. Undo our one real leak, and only that one.
      Our globals are bare element selectors (0,0,1). The report is styled with
      utility classes (0,1,0), which outrank them, so the only properties that
      actually leak are ones the report never sets. `max-width` on p is the
      confirmed case: 54 paragraphs capped at 624px inside a 960px report.
      An earlier version of this reset also used `revert` on the headings.
      That was wrong: revert rolls back to the BROWSER default, not to the
      other author stylesheet, so it threw their heading styles away instead
      of restoring them. */
.report-host p { max-width: none; }

/* 2. Our type, their layout. */
.report-host,
.report-host p,
.report-host li,
.report-host td,
.report-host th {
  font-family: var(--sans);
}
.report-host h1,
.report-host h2,
.report-host h3,
.report-host h4,
.report-host h5,
.report-host h6 {
  font-family: var(--sans);
  letter-spacing: -0.01em;
}
.report-host code,
.report-host pre,
.report-host .font-mono {
  font-family: var(--mono);
}

/* --- The report, in our colours ------------------------------------------
   Every colour in the hub's stylesheet reads from a role token with its own
   default, so we set 29 and the report becomes a Mito Workshop document with
   no override inside it.

   The report is DARK, matching the site rather than sitting on it as a light
   slab. Three surfaces, all existing tokens: --paper is the ground,
   --paper-raised the panel and its cards, --wash the nested step for callouts.

   Status colour keeps its meaning and takes values tuned for a dark card:
   critical 5.24:1, warn 7.14:1, ok 7.03:1, info 6.22:1. Tints are the
   translucent form of each so a callout lifts without a new ground.

   ⛔ --wash-accent appears only as a chip and callout ground carrying --ink,
   which is what the system documents it for. It fails faint text and links as
   a document ground, so it is not one. */
.report-host .heuristics-report,
.report-host .compliance-report {
  /* ---------- type roles for the hub report ----------
     The report gets its OWN scale, valued here. Six roles, requested by the
     Compliance contract §13 so the hub can ship roles instead of px literals —
     its sheet was carrying 79 px font-sizes, 59 of them under 12px, which is
     what made that report unstylable on this page.

     ⛔ EVERY VALUE IS 12px OR ABOVE. That floor is the hub's constraint for the
     report, not this property's: our own scale is whatever the design system
     approves and it goes below 12 where it has earned it. The report is held
     to the stricter rule because it is a document a stranger reads once.

     --hx-fs-code is a role rather than a folded-in caption because monospace is
     76 of our 136 sized rules — more than half the type here is mono, so it
     needs its own knob. It is NOT downsized: measured on our actual pair,
     Plex Mono's x-height is 98% of Archivo's and its caps are taller, so the
     usual "mono reads smaller" compensation would make it wrong. */
  /* Revalued 2026-09-14 after reading a real report rather than the numbers.
     The ramp was correct at the floor and wrong in the spread: 82 of 191 text
     nodes sat at 12px, which reads small for a document someone is asked to
     act on, while the title rendered at 60px and wrapped to two lines. The top
     comes down, the bottom goes up, and the report stops looking like a poster
     with footnotes. Caption stays above the hub's 12px floor. */
  --hx-fs-caption: var(--fs-caption);
  --hx-fs-code: var(--fs-caption);   /* code sits at caption size */
  --hx-fs-body: var(--fs-body);
  --hx-fs-lead: var(--fs-lead);
  /* head and display have NO site equivalent: this property does not
     tokenise heading sizes, they live in the component rules. These two
     stay scoped to the report on purpose. */
  --hx-fs-head: clamp(20px, 2.2vw, 24px);
  --hx-fs-display: clamp(26px, 3.4vw, 34px);

  --hx-text: var(--ink);
  --hx-text-secondary: var(--ink-2);
  --hx-text-muted: var(--graphite);
  --hx-text-faint: var(--muted);

  --hx-surface: var(--paper-raised);
  --hx-surface-subtle: var(--wash);
  --hx-surface-sunken: var(--paper);

  --hx-border: var(--line);
  --hx-border-strong: var(--line-chip);

  --hx-accent: var(--report-link);
  --hx-accent-text: var(--report-link);
  --hx-accent-tint: var(--wash-accent);
  --hx-accent-line: var(--report-link);

  /* ⛔ Base is the chip GROUND, not the bright hue.
     Their sheet maps .bg-amber-400 to --hx-warn and .text-amber-400 to
     --hx-warn-text, so a solid status chip takes BOTH from this block. Setting
     both to the same colour rendered "Measured" green-on-green and "Serious"
     amber-on-amber at 1.00:1 — invisible. On a dark card the ground has to be
     the dark tint and the text the bright hue.

     Measured on the chip: critical 5.49:1, warn 6.26:1, ok 6.13:1, info
     5.44:1, and each ground sits just off the card so the chip reads as a
     chip rather than floating. */
  --hx-critical: #4A1F17;
  --hx-critical-text: var(--report-critical);
  /* ⛔ SOLID, NOT A .16 TINT. A translucent tint inherits whatever is behind
     it, which our own ladder rules out in as many words: "a translucent tint
     standing in for a nested surface, when the same chip has to look the same
     on two different grounds". Measured 2026-09-14 on the Compliance report:
     the same badge read 5.33:1 on the card and 3.81:1 inside a .fix-section,
     which is solid --wash-accent. Eight of ten AA failures there were
     translucent grounds inheriting a parent.

     These four are the .16 tints composited over --paper-raised, so the card
     appearance is unchanged and the pairing now holds on ANY ground. The two
     that were already solid — info and accent — were the ones done right. */
  --hx-critical-tint: #4A4350;
  --hx-critical-line: var(--report-critical);

  --hx-warn: #4A3413;
  --hx-warn-text: var(--report-warn);
  --hx-warn-tint: #464447;
  --hx-warn-line: var(--report-warn);

  --hx-ok: #17402A;
  --hx-ok-text: var(--report-ok);
  --hx-ok-tint: #334950;
  --hx-ok-line: var(--report-ok);

  --hx-info: #1E3A57;
  --hx-info-text: var(--report-info);
  --hx-info-tint: var(--wash-accent);
  --hx-info-line: var(--report-info);

  /* Major had no token until the hub rendered severity as a colour (2026-09-10).
     Same shape as the others: dark ground, bright text. */
  --hx-major: #4A2C13;
  --hx-major-text: var(--report-warn);
  --hx-major-tint: #464447;
  --hx-major-line: #F0954B;

  /* ---------- the bright tier ----------
     Text on a TINT needs a lighter value than text on the card: the same token
     drops from 7+ to 5-ish the moment it sits on a tinted ground. These were
     being pasted as literal hexes across the report overrides — 34 literal
     colour values, which is the hand-tuned hex the ladder rules out, and it
     meant the same decision lived in six places.

     One tier, not two. The brighter of the two values in use covers both jobs
     and improves the weaker one (critical 5.90 -> 6.49, ok 5.45 -> 6.52 on the
     hardest ground either appears on). */
  --hx-critical-bright: #FFD4C8;
  --hx-warn-bright: #F0C98A;
  --hx-major-bright: #F0C98A;
  --hx-ok-bright: #B5EACB;
  --hx-info-bright: #CFE4FA;

  /* The chip's own ground: thin enough that the stroke and text do the work. */
  --hx-critical-chip: rgba(255, 174, 155, .04);
  --hx-warn-chip: rgba(232, 181, 98, .04);
  --hx-major-chip: rgba(232, 181, 98, .04);
  --hx-ok-chip: rgba(111, 207, 151, .04);
}

/* Their sheet sets font-family on `.heuristics-report` — the same specificity
   as our `.report-host`, and it loads AFTER ours, so it won on ORDER and 139
   elements rendered in system-ui. Paragraphs and headings escaped only because
   those selectors happen to be (0,1,1). Two classes settles the whole subtree. */
.report-host .heuristics-report,
.report-host .heuristics-report *,
.report-host .compliance-report,
.report-host .compliance-report * {
  font-family: var(--sans);
}
/* The report's own panel has NO padding: measured 0px, with the h1 sitting at
   0px from its top edge and the last block at 0px from its bottom. Padding on
   our container sits OUTSIDE that panel, which is why adding it there did not
   move the h1 — I had been measuring the gap between container and panel
   rather than between panel and its content. */
.report-host .heuristics-report,
.report-host .compliance-report { padding: 40px 36px 44px; }
@media (max-width: 640px) {
  .report-host .heuristics-report,
  .report-host .compliance-report { padding: 24px 18px 28px; }
}

/* The Total row carries padding-right: 1px where every body row carries 16px,
   so its figures sat 15px further right. The right EDGES always matched, which
   is why the cells measured aligned while the numbers plainly were not. */
.report-host .heuristics-report table tfoot td,
.report-host .heuristics-report table tr:last-child td,
.report-host .compliance-report table tfoot td,
.report-host .compliance-report table tr:last-child td { padding-right: 16px; }
/* The LAST column carries 1px on every body row, so forcing 16px everywhere
   fixed Examined and Failed and knocked Passed out of line instead. Match the
   body rows column for column rather than flattening them. */
.report-host .heuristics-report table tfoot td:last-child,
.report-host .heuristics-report table tr:last-child td:last-child,
.report-host .compliance-report table tfoot td:last-child,
.report-host .compliance-report table tr:last-child td:last-child { padding-right: 1px; }

/* Chips: prominence from a drawn edge, not a heavier ground.

   Raising the tint makes a chip louder and its text WORSE — at .32 alpha the
   critical chip drops to 3.07:1. So the tint stays low and the bright hue is
   spent on a border, which reads at 7:1 against the card and costs the text
   nothing. Composited properly, every status chip now clears AA on its own
   ground: critical 5.33:1, warn 5.15:1, ok 5.00:1, info 4.53:1.

   Critical was BELOW AA before this at 4.21:1, found by compositing the tint
   over the card instead of treating it as solid. */
.report-host [class*="bg-green-1"],
.report-host [class*="bg-emerald-1"],
.report-host [class*="bg-amber-1"],
.report-host [class*="bg-orange-1"],
.report-host [class*="bg-red-1"],
.report-host [class*="bg-rose-1"],
.report-host [class*="bg-blue-1"],
.report-host [class*="bg-cyan-1"],
.report-host [class*="bg-indigo-1"],
.report-host [class*="bg-gray-1"],
.report-host [class*="bg-slate-1"],
.report-host [class*="bg-gray-2"],
.report-host [class*="bg-slate-2"] {
  border: 1px solid currentColor;
  font-weight: 600;
}
/* A chip butted against the copy reads as part of the sentence. */
.report-host .inline-flex,
.report-host [class*="rounded"][class*="px-2"],
.report-host [class*="rounded"][class*="px-1"] { margin-left: .45rem; }

/* Right edges already line up on every row; the bold Total row LOOKS shifted
   because proportional digits are wider when bold. Tabular figures give every
   digit the same advance so the columns read as columns. */
.report-host .heuristics-report table,
.report-host .compliance-report table { font-variant-numeric: tabular-nums; }

.report-host .heuristics-report code,
.report-host .heuristics-report pre,
.report-host .compliance-report code,
.report-host .compliance-report pre { font-family: var(--mono); }

/* --- Labs charts, drawn from numbers -------------------------------------
   Replaces the server-rendered PNGs, whose text is baked into the pixels and
   lands near 4px on a phone once scaled to the column.

   ⛔ The state styling is the honesty layer, not decoration. Categories nothing
   reached KEEP THEIR STARTING SCORE — typically 8 of 10 sit at the baseline —
   so a chart that draws every point the same way turns a page we barely
   examined into a near-perfect shape. Measured is filled, checked is hollow,
   and the two absences are grey with an italic label. The two absences look
   the same on purpose: both are absence to the eye, and the difference between
   them belongs in words. */
.labs-chart { margin: 1.5rem 0 2rem; }
.labs-chart-title { font-weight: 600; font-size: 1rem; margin-bottom: .25rem;
                    color: var(--hx-text, #15161A); }
.labs-chart-desc { color: var(--hx-text-muted, #4E525C); margin: 0 0 .75rem; max-width: 62ch; }

/* Sized to the block rather than pinned small: it was 460px inside an 846px
   column. Text is text here, so it stays legible as it grows. */
.labs-radar { width: 100%; height: auto; max-width: 640px; display: block; margin: 0 auto; }
@media (min-width: 1100px) { .labs-radar { max-width: 720px; } }
/* --hx-border is a hairline meant for edges between surfaces; on the radar it
   vanished. The web needs to be seen to be read. */
.labs-radar-ring  { fill: none; stroke: #46516B; stroke-width: 1; }
.labs-radar-spoke { stroke: #3A4459; stroke-width: 1; }
.labs-radar-area  { fill: var(--hx-accent, #8CC0EF); fill-opacity: .18; stroke: none; }
.labs-radar-edge  { stroke: var(--hx-accent, #245C99); stroke-width: 2; fill: none; }
/* Dashed wherever the edge touches a vertex nothing reached, so the outline
   reads as partly assumed rather than measured all the way round. */
.labs-radar-edge.is-assumed { stroke: var(--hx-text-faint, #9EA0A8); stroke-width: 1.5;
                              stroke-dasharray: 4 3; }

.labs-radar-dot { fill: var(--hx-accent, #8CC0EF); stroke: var(--hx-surface, #272F42); stroke-width: 1.5; }
.labs-radar-dot[data-state="checked_nothing_found"] { fill: var(--hx-surface, #272F42);
                                                      stroke: var(--hx-accent, #8CC0EF); stroke-width: 2; }
.labs-radar-dot[data-state="not_examined"],
.labs-radar-dot[data-state="no_automated_check"] { fill: var(--hx-text-faint, #9EA0A8);
                                                   stroke: var(--hx-surface, #272F42); r: 2.5; }

.labs-radar-label { font-family: var(--sans); font-size: 10px; fill: var(--hx-text-secondary, #3F434C); }
.labs-radar-label[data-state="not_examined"],
.labs-radar-label[data-state="no_automated_check"] { fill: var(--hx-text-faint, #6B707B); font-style: italic; }

/* Vertex numbers on the compact radar. 11 SVG units in a 240-unit viewBox: at a
   390px viewport the SVG lands ~328px wide, so these render around 15px — above
   the 13px the prototype measured, and the reason the shape stays legible where
   spelled-out labels cannot fit. They carry state like the labels do, so the
   absences read as absences rather than only the dot knowing. */
/* 14 SVG units, not 11. Measured on the live page the compact SVG lands 226px
   wide inside the report card at a 390px viewport — a 0.94 scale, not the 1.46
   a full-width 240 viewBox would give — so 11 units rendered at 10.4px, under
   the 13px the hub's prototype achieved. 14 units lands at ~13.2px. The lesson
   is that an SVG font size is only meaningful against the width it actually
   gets, and the card's padding eats most of a phone screen. */
.labs-radar-num {
  font-family: var(--mono); font-size:var(--fs-body); font-weight: 600;
  fill: var(--hx-text-secondary, #3F434C); }
.labs-radar-num[data-state="not_examined"],
.labs-radar-num[data-state="no_automated_check"] {
  fill: var(--hx-text-faint, #6B707B); font-style: italic; }
.labs-radar--compact { max-width: 360px; }

.labs-legend { list-style: none; display: flex; flex-wrap: wrap; gap: .5rem 1rem;
               margin: .5rem 0 0; padding: 0; justify-content: center;
               font-size: .8rem; color: var(--hx-text-muted, #4E525C); }
.labs-legend li { display: flex; align-items: center; gap: .35rem; }
.labs-legend-key { width: 9px; height: 9px; border-radius: 50%;
                   background: var(--hx-accent, #245C99); flex: 0 0 auto; }
.labs-legend li[data-state="checked_nothing_found"] .labs-legend-key {
  background: var(--hx-surface, #272F42); box-shadow: inset 0 0 0 2px var(--hx-accent, #8CC0EF); }
.labs-legend li[data-state="not_examined"] .labs-legend-key,
.labs-legend li[data-state="no_automated_check"] .labs-legend-key {
  background: var(--hx-text-faint, #6B707B); }

.labs-bars { list-style: none; margin: 0; padding: 0; display: grid; gap: .5rem; }
.labs-bar-row { display: grid; grid-template-columns: minmax(9rem, 15rem) 1fr 2.5rem;
                gap: .6rem; align-items: center; }
.labs-bar-label { font-size: .9rem; color: var(--hx-text-secondary, #3F434C); }
.labs-bar-track { display: block; height: 12px; border-radius: 4px;
                  background: var(--hx-surface-sunken, #DEDBD1); overflow: hidden; }
.labs-bar-fill  { display: block; height: 100%; border-radius: 4px;
                  background: var(--hx-accent, #245C99); }
.labs-bar-value { font-family: var(--mono); font-size: .8rem; text-align: right;
                  color: var(--hx-text-muted, #4E525C); }
.labs-bar-state { grid-column: 1 / -1; font-size: .78rem;
                  color: var(--hx-text-muted, #4E525C); }
.labs-bar-row[data-state="checked_nothing_found"] .labs-bar-fill { opacity: .55; }
.labs-bar-row[data-state="not_examined"] .labs-bar-fill,
.labs-bar-row[data-state="no_automated_check"] .labs-bar-fill {
  background: var(--hx-text-faint, #6B707B); opacity: .45; }
.labs-bar-row[data-state="not_examined"] .labs-bar-label,
.labs-bar-row[data-state="no_automated_check"] .labs-bar-label { font-style: italic; }

/* Severity chips at the house standard (2026-09-12).

   AA is a floor. Measured on the live report, the chips sat at critical 5.33,
   major 5.15, moderate 5.15, strength 5.00 — passing 4.5 and still reading as
   dim colour-on-colour at 12px, which is the dark-on-dark tell we reject.

   ⛔ SCOPED TO THE CHIPS, NOT THE TOKENS. The obvious fix — drop --hx-*-tint so
   the ground darkens — is wrong: 87 rules in the hub stylesheet read those
   tokens. Every `bg-*-50/100/200` callout in the report takes its background
   from them, and `text-emerald-200` / `text-red-200` take their TEXT colour
   from them, so thinning the tint would flatten every callout and turn that
   text invisible. The chip is the thing that fails, so the chip is the thing
   that changes.

   Two moves per chip: thin its own ground to .04, and lift the text. Keeping
   the hue matters — bleaching the text alone reached 7:1 at #F3D9AD / #BAE8CD,
   which is pale enough that severity stops reading as severity.

   Measured live, all five, before -> after:
     critical  5.33 -> 8.28     major  5.15 -> 7.93
     moderate  5.15 -> 7.93     strength  5.00 -> 7.69
     minor    11.19 (unchanged)
   Strokes stay 5.38-6.91 against the new ground, above the 3:1 graphic floor.
   The stroke was always the thing separating these — the fill measured
   1.37-1.41 against the row, so thinning it costs nothing it was providing. */
.report-host .heuristics-report .hx-chip--critical {
  background: rgba(255, 174, 155, .04); color: #FFC7B8; }
.report-host .heuristics-report .hx-chip--major {
  background: rgba(232, 181, 98, .04); color: #F0C98A; }
.report-host .heuristics-report .hx-chip--moderate {
  background: rgba(232, 181, 98, .04); color: #F0C98A; }
.report-host .heuristics-report .hx-chip--strength {
  background: rgba(111, 207, 151, .04); color: #8FDCB0; }

/* The same badge drawn with Tailwind utilities rather than .hx-chip — the
   "Measured" and "Serious" pills on the finding cards. Same defect (5.00 and
   5.15), same fix, found by sweeping every pill-shaped element on the page
   instead of only the ones named chip.

   ⛔ PILL-SHAPED ONLY. `bg-green-100` is also the background of full callout
   BLOCKS, and thinning those flattens them. `.inline-flex.rounded` is what
   separates a badge from a block, so the callouts keep their .16 tint.

   Raising the -text tokens alone was tried first and tops out at 6.5-6.9 on a
   .16 ground, with the colour going pale on the way — the ground has to come
   down too.

   ⛔ !important HERE AND NOT ON THE CHIPS. The Tailwind utilities ship as
   `background-color: var(--hx-ok-tint,…) !important`, so no specificity wins
   against them — the first version of this block was five classes deep and
   changed nothing. `.hx-chip--*` carries no !important, which is why the same
   values landed there on specificity alone. */
.report-host .heuristics-report .inline-flex.rounded.bg-green-100,
.report-host .heuristics-report .inline-flex.rounded.bg-emerald-100,
.report-host .heuristics-report .inline-flex.rounded.bg-teal-100 {
  background-color: rgba(111, 207, 151, .04) !important; }
.report-host .heuristics-report .inline-flex.rounded.text-green-800,
.report-host .heuristics-report .inline-flex.rounded.text-emerald-800,
.report-host .heuristics-report .inline-flex.rounded.text-teal-800 { color: #8FDCB0 !important; }

.report-host .heuristics-report .inline-flex.rounded.bg-orange-100,
.report-host .heuristics-report .inline-flex.rounded.bg-amber-100,
.report-host .heuristics-report .inline-flex.rounded.bg-yellow-100 {
  background-color: rgba(232, 181, 98, .04) !important; }
.report-host .heuristics-report .inline-flex.rounded.text-orange-800,
.report-host .heuristics-report .inline-flex.rounded.text-amber-800,
.report-host .heuristics-report .inline-flex.rounded.text-yellow-800 { color: #F0C98A !important; }

.report-host .heuristics-report .inline-flex.rounded.bg-red-100,
.report-host .heuristics-report .inline-flex.rounded.bg-rose-100 {
  background-color: rgba(255, 174, 155, .04) !important; }
.report-host .heuristics-report .inline-flex.rounded.text-red-800,
.report-host .heuristics-report .inline-flex.rounded.text-rose-800 { color: #FFC7B8 !important; }

/* The hub's bar component, on our ground (2026-09-10).

   ⚠ CURRENTLY UNEXERCISED BY THE IMPACT SECTION. The hub rewrote the ranking
   into a TABLE on 2026-09-11 (`.hx-impact__t`, chips for severity), so no
   `.hx-bar-fill` renders there any more. Kept because the component still
   exists in their stylesheet and may render in another section or report state;
   if it does, these keep it visible rather than dark-on-dark. Delete only after
   confirming no report state emits `.hx-bar-fill` — a zero from one run is not
   that confirmation, which is the lesson of the stale selector in
   check_live_report.py.

   ⛔ WHY THESE OVERRIDES EXIST AT ALL. Their bar fills read the BASE tokens —
   `.hx-bar-fill--strength { background: var(--hx-ok) }`. In our sheet the base
   token is the dark chip GROUND (#17402A), not the bright hue, because a solid
   status chip takes its ground AND its text from that pair; setting the base to
   the bright colour is what once rendered "Measured" green-on-green at 1.00:1.
   So four of their six fills would paint dark-on-dark here and vanish. We remap
   the FILLS to the bright `-line` hues and leave the chip tokens alone.

   Their stylesheet loads after ours, so a two-class selector ties and loses on
   order. Three classes wins without !important. */
.report-host .heuristics-report .hx-bar-fill--critical { background-color: var(--hx-critical-line); }
.report-host .heuristics-report .hx-bar-fill--major { background-color: var(--hx-major-line); }
.report-host .heuristics-report .hx-bar-fill--warn,
.report-host .heuristics-report .hx-bar-fill--moderate { background-color: var(--hx-warn-line); }
.report-host .heuristics-report .hx-bar-fill--ok,
.report-host .heuristics-report .hx-bar-fill--strength { background-color: var(--hx-ok-line); }
.report-host .heuristics-report .hx-bar-fill--info { background-color: var(--hx-info-line); }
/* Minor and unassessed already resolve to readable neutrals through
   --hx-text-faint / --hx-border-strong, so they are left as the hub set them. */

.labs-radar-wrap { display: block; }
.labs-radar-wrap--compact { display: none; }
.labs-bars-fallback { display: none; }
.labs-bar-index { display: none; }

/* ⛔ THE RADAR MUST SURVIVE 390px — that was the whole reason for drawing it
   ourselves. Until 2026-09-11 this breakpoint HID it and showed only the list,
   which deleted the deliverable: the hub's PNG was illegible on a phone at 30%
   scale, and an SVG nobody can see is no better.

   So below 640px the LABELLED radar gives way to the COMPACT one — same
   geometry, vertices numbered instead of spelled out — and the list renders
   alongside it as the key rather than as a replacement. */
@media (max-width: 640px) {
  .labs-radar-wrap { display: none; }
  .labs-radar-wrap--compact { display: block; }
  .labs-bars-fallback { display: block; }
  .labs-bar-index {
    display: block; grid-area: idx; align-self: baseline;
    font-family: var(--mono); font-size: .78rem; font-variant-numeric: tabular-nums;
    color: var(--hx-text-muted, #C6CAD3); }
  .labs-bar-row { grid-template-columns: 1.4rem 1fr 2.5rem;
    grid-template-areas: "idx label value" "track track track" "state state state"; }
  .labs-bar-label { grid-area: label; }
  .labs-bar-value { grid-area: value; }
  .labs-bar-track { grid-area: track; }
  .labs-bar-state { grid-area: state; }
}



/* The coverage denominator under each radar title. With every spoke drawn —
   `categories` is the full framework again — the picture alone cannot say how
   much of it was reached, so the count says it. When the hub tells us the shape
   is not evidence, the same line carries rag4's own sentence verbatim so both
   renders of one report say the same thing. */
.labs-chart-coverage {
  margin: 0 0 .4rem; font-family: var(--mono); font-size: .78rem;
  color: var(--hx-text-muted, #C6CAD3); max-width: 62ch; }
.labs-chart-coverage[data-shape="not-evidence"] { color: var(--hx-warn-text, #E8B562); }


/* =================================================== LABS DETAIL STUB
   Eleven pages are generated from one template, so its spacing is a component
   decision made once rather than an inline style repeated eleven times. These
   replace 33 inline declarations. */
.stub-lead{margin:0 0 var(--space-2)}
.stub-body{margin:0 0 var(--space-flow)}
.stub-back{margin-top:var(--space-4)}
.stub-note{margin:0}
.stub{max-width:64ch}

/* A muted paragraph directly under a section eyebrow or head. Repeated on the
   brand and design-system pages, and previously inline on every instance. */
.section-note{margin:var(--space-2) 0 0}
.section-note--loose{margin:var(--space-3) 0 0}

/* The subtitle under a page hero head. Lighter than .lead's 500 — it is a
   subtitle, not a second headline. */
.page-lead{margin-top:var(--space-1);font-weight:400}

/* The icon sprite is defined once per page and never painted — it exists only
   so <use> can reference its symbols. Taking it out of flow is structural, not
   styling, which is why it had been inline on all twenty pages. */
.svg-sprite{position:absolute;width:0;height:0}

/* Section heads and closing blocks. These carried the last of the raw margins. */
/* The reading measure the property already used inline in three places on the
   brand page, at the two spacing steps it already used. The values were on the
   scale; only the declaration was loose. */
.measure-62{max-width:62ch}
.section-note--tight{margin-top:var(--space-1)}
/* The home hero paragraph carries the whole explanation of the property, so it
   runs longer than a subtitle and needs the measure to match. 52ch set for a
   two-line sub would break this one into a narrow column beside the figure. */
.hero-sub--long{max-width:60ch}
/* A second hero paragraph sits closer to the first than the first sits to the
   headline: --space-2 between paragraphs of one block, --space-3 from the head.
   Equal gaps would read as two separate blocks rather than one explanation. */
.hero-sub + .hero-sub{margin-top:var(--space-2)}
.block-top-3{margin-top:var(--space-3)}
.block-top-4{margin-top:var(--space-4)}
.block-flush{margin-top:0}
.hero-lede{margin:0 0 clamp(26px,4vw,42px);font-weight:400;max-width:62ch}
.measure-narrow{max-width:60ch}

/* The closing statement on a content page — one large line, its own step above
   the copy that precedes it. Was inline on four pages at two sizes. */
.closing-line{font-size:clamp(34px,6vw,60px);margin-top:var(--space-3)}
.closing-line--sm{font-size:clamp(32px,5vw,54px);margin-top:var(--space-3)}
/* A hero lede with no measure cap — the listing pages set their own column. */
.hero-lede--full{margin:0 0 clamp(26px,4vw,42px);font-weight:400}

/* =================================================== COMPLIANCE REPORT ON OUR LADDER
   The rederived sheet fixed contrast and type size. What was left is the part
   contrast cannot see: surfaces and typefaces that are not ours. Measured on a
   live report, 2026-09-14.

   ⛔ EXEMPT, DO NOT THEME: .color-sample and the 20px swatch spans render the
   SCANNED SITE's own colours. A contrast tool that repaints the colours it is
   reporting on is broken. Their inline values are the data. */

/* 1. Code blocks belong on the deepest ground, not on a severity slab.
      Two full-width <pre> were painting themselves --hx-critical (var(--hx-critical)) and
      --hx-ok (var(--hx-ok)) — chip grounds stretched to 1056px, which is not a step
      on our ladder. The ladder is explicit that code blocks sit on
      --paper-sunken inside a panel; severity belongs in the stroke. */
.report-host .compliance-report pre {
  background: var(--paper-sunken) !important;
  border-left: 3px solid var(--hx-border-strong);
  border-radius: 6px; }
.report-host .compliance-report .fix-original pre,
.report-host .compliance-report pre.original { border-left-color: var(--hx-critical-line); }
.report-host .compliance-report .fix-recommended pre,
.report-host .compliance-report pre.recommended { border-left-color: var(--hx-ok-line); }

/* 2. Our typefaces. Their sheet hardcodes "SF Mono", Monaco, Consolas in five
      rules and -apple-system in one, so the report was rendering in neither of
      our faces. */
.report-host .compliance-report code,
.report-host .compliance-report pre,
.report-host .compliance-report kbd,
.report-host .compliance-report samp,
.report-host .compliance-report .code-block,
.report-host .compliance-report .element-code,
.report-host .compliance-report .vr-wcag,
.report-host .compliance-report .color-codes { font-family: var(--mono) !important; }
.report-host .compliance-report,
.report-host .compliance-report p,
.report-host .compliance-report li,
.report-host .compliance-report h1,
.report-host .compliance-report h2,
.report-host .compliance-report h3 { font-family: var(--sans); }

/* 3. Inline light panels. These are light-theme islands in a dark document —
      a near-white 148px block and two light code chips, all set inline, so only
      an attribute selector reaches them. Matched on their literal values rather
      than on [style] broadly, so the exempt swatches above are untouched. */
.report-host .compliance-report div[style*="#f8fafc"],
.report-host .compliance-report div[style*="#F8FAFC"] {
  background: var(--paper-sunken) !important;
  border: 1px solid var(--hx-border); }
.report-host .compliance-report code[style*="#e2e8f0"],
.report-host .compliance-report code[style*="#E2E8F0"] {
  background: var(--wash) !important; color: var(--ink) !important; }
.report-host .compliance-report code[style*="#d1fae5"],
.report-host .compliance-report code[style*="#D1FAE5"] {
  background: var(--hx-ok-tint) !important; color: var(--hx-ok-text) !important; }

/* 4. The four remaining off-role sizes: inline code chips at 0.8125rem and the
      CSS-context note at 13px. */
.report-host .compliance-report code[style*="font-size"] { font-size: var(--hx-fs-code) !important; }
.report-host .compliance-report .fix-css-context,
.report-host .compliance-report .fix-css-context strong { font-size: var(--hx-fs-code); }

/* 5. Text that was written for those light panels.
      Darkening a ground without re-colouring what sits on it is how a fix
      becomes a regression — this one produced four new AA failures at 2.54,
      3.99, 3.51 and 2.54 the moment the panel went dark. The labels and
      verdicts carry inline colours chosen for #f8fafc, so they are remapped by
      their literal value.

      ⛔ STILL EXEMPT: .color-sample keeps its inline pair. It is the specimen. */
.report-host .compliance-report .fix-css-context {
  background: var(--paper-sunken) !important;
  border: 1px solid var(--hx-border);
  color: var(--hx-text-muted) !important; }
.report-host .compliance-report [style*="color: #475569"],
.report-host .compliance-report [style*="color: #1e293b"],
.report-host .compliance-report [style*="color: #64748b"] {
  color: var(--hx-text-muted) !important; }
.report-host .compliance-report [style*="color: #dc2626"],
.report-host .compliance-report [style*="color: #b91c1c"] {
  color: var(--hx-critical-text) !important; }
.report-host .compliance-report [style*="color: #047857"],
.report-host .compliance-report [style*="color: #059669"] {
  color: var(--hx-ok-text) !important; }
/* ⛔ NO EXEMPTION RULE HERE. An earlier attempt wrote
   `.color-sample[style] { color: unset !important }` to "protect" the specimen
   and destroyed it: `unset` makes colour INHERIT, so the swatch text went
   near-white on its white ground at 1.09:1. The inline declaration already wins
   on its own — the specimen needed no help, and the help broke it.

   The label inside the CSS-context panel is a hardcoded #1e1b4b in their sheet,
   which is 1.2:1 once that panel sits on our sunken ground. */
.report-host .compliance-report .fix-css-context strong { color: var(--hx-text) !important; }

/* 6. The last two holdouts, found by measuring rather than assuming the sweep
      above had caught everything: four bare <span> inside .color-codes still
      rendering "SF Mono" because the selector list reached .color-codes but not
      its children, and the CSS-context note carrying an inline 0.8125rem. */
.report-host .compliance-report .color-codes span,
.report-host .compliance-report .color-codes * { font-family: var(--mono) !important; }
.report-host .compliance-report .fix-css-context[style*="font-size"] {
  font-size: var(--hx-fs-code) !important; }


/* 7. The five things Russ named reading a live report, 2026-09-14.

   The title was an <h2> at 60px wrapping to two lines. Report titles carry a
   URL, so they are long by nature — display size is for a page, not for this. */
.report-host .compliance-report h2 { font-size: var(--hx-fs-display); line-height: 1.15; }
.report-host .compliance-report h3 { font-size: var(--hx-fs-head); }

/* The pass/fail labels were 5.72:1 and 5.36:1 — over AA, under our 7:1 bar, and
   at 12px. They take the brighter variants and the new caption size.

   ⛔ The first attempt at this guessed the class names (.fix-original-label,
   .ratio-fail) and silently did nothing — the size change landed, the colour
   did not, and only re-measuring caught it. The real hooks are .code-label
   inside .code-block.original / .fixed, and .color-ratio-fail / -pass. */
.report-host .compliance-report .color-ratio-fail,
.report-host .compliance-report .code-block.original .code-label { color: var(--hx-critical-bright) !important; }
.report-host .compliance-report .color-ratio-pass,
.report-host .compliance-report .code-block.fixed .code-label { color: var(--hx-ok-bright) !important; }

/* Visual Review rows had border-bottom: 0 and 8px of padding — no separation at
   all, which is what made that section read as a pile. */
.report-host .compliance-report .vr-item {
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--hx-border); }
.report-host .compliance-report .vr-item:last-child { border-bottom: 0; }

/* ⛔ No eye. Russ, 2026-09-14: "I don't want that eye icon in Visual Review."
   Hidden rather than removed, because the markup is the hub's. */
.report-host .compliance-report .vr-icon { display: none !important; }

/* =================================================== ONE CHIP, BOTH REPORTS
   Russ, 2026-09-14: "we put outlines on these because of the contrast with the
   background so that likely means we're not utilizing the shared CSS". Correct.
   Measured side by side with each report's current stylesheet:

     Heuristics .hx-chip     12px, 999px radius, 1px severity stroke, 7.69-11.19:1
     Compliance badges       13px, 4px AND 10px radius, NO stroke,     5.67-6.75:1

   Two components doing one job, and only one of them had been brought onto the
   system. The stroke is not decoration — the ladder requires 3:1 on anything
   identifying a control, and it is what lets a chip read on a tinted ground.

   So the chip is defined once here and both surfaces take it. */
.report-host .heuristics-report .hx-chip,
.report-host .compliance-report .impact-badge,
.report-host .compliance-report .confidence-badge,
.report-host .compliance-report .vr-badge,
.report-host .compliance-report [class*="vr-badge"] {
  font-family: var(--mono);
  font-size: var(--hx-fs-caption) !important;
  line-height: 1.35;
  padding: 3.2px 10.4px !important;
  border-radius: 999px !important;
  border: 1px solid currentColor !important;
  display: inline-block; }

/* Severity colours the text, and the stroke takes currentColor so the two can
   never disagree. Values are the bright variants that clear 7:1 on a tint. */
.report-host .compliance-report .impact-critical,
.report-host .compliance-report .confidence-critical { color: var(--hx-critical-bright) !important; }
.report-host .compliance-report .impact-serious,
.report-host .compliance-report .confidence-medium { color: var(--hx-warn-bright) !important; }
.report-host .compliance-report .impact-moderate { color: var(--hx-warn-bright) !important; }
.report-host .compliance-report .impact-minor,
.report-host .compliance-report .confidence-low { color: var(--hx-info-bright) !important; }
.report-host .compliance-report .confidence-high { color: var(--hx-ok-bright) !important; }

/* The low-contrast body Russ spotted: 13px graphite on --wash-accent at 5.35:1.
   Graphite is a card colour; on the blue wash it needs the brighter step. */
.report-host .compliance-report .ai-card p,
.report-host .compliance-report .ai-card li,
.report-host .compliance-report [class*="why-this"] p { color: var(--ink-2) !important; }

/* The Visual Review caption was breaking "model-cropped / evidence /
   (approximate)" across three lines in a narrow column. */
.report-host .compliance-report .vr-crop-caption {
  max-width: none; text-wrap: balance; line-height: 1.4; }

/* The last of the cross-check, 2026-09-14. Everything below was found by
   measuring both reports side by side under their CURRENT stylesheets — an
   earlier pass compared against a Heuristics sheet fetched four days before the
   chip component existed, which made the two look more alike than they were. */

/* Metadata under the report title, and the violation id, were graphite on the
   raised card and the blue wash: 6.21:1 and 5.87:1, over AA and under our bar. */
.report-host .compliance-report .date,
.report-host .compliance-report .profile,
.report-host .compliance-report .page-title,
.report-host .compliance-report .design-system-label,
.report-host .compliance-report .url,
.report-host .compliance-report .violation-id { color: var(--ink-2) !important; }

/* confidence-low took --hx-info-text on the accent wash at 5.67:1. */
.report-host .compliance-report .confidence-low,
.report-host .compliance-report .impact-minor { color: var(--hx-info-bright) !important; }

/* Heuristics' Tailwind text utilities on tinted callouts: amber 5.15, blue 5.67,
   gray-400 5.12. The same brightening the chips got. */
.report-host .heuristics-report .text-amber-800,
.report-host .heuristics-report .text-yellow-800 { color: var(--hx-warn-bright) !important; }
.report-host .heuristics-report .text-blue-800,
.report-host .heuristics-report .text-indigo-800 { color: var(--hx-info-bright) !important; }
.report-host .heuristics-report .text-gray-400,
.report-host .heuristics-report .text-gray-500 { color: var(--hx-text-muted) !important; }

/* "model-cropped evidence (approximate)" was breaking three ways inside a 130px
   thumbnail column. The column gets enough width for two. */
.report-host .compliance-report .vr-evidence { min-width: 176px; }
.report-host .compliance-report .vr-crop-caption { text-wrap: pretty; }

/* =================================================== BODY COPY: ONE VALUE, BOTH REPORTS
   Russ, 2026-09-14: "For body copy, I'll take the brighter one, every time; at
   my age contrast is more important."

   Heuristics was running --graphite and Compliance --ink for the same job. Both
   take --ink now. Measured, --ink holds everywhere the ladder puts body text:
   12.25:1 on the raised card, 9.34:1 on --wash, 8.05:1 on --wash-accent,
   17.66:1 on the sunken ground.

   ⛔ BODY COPY ONLY — running text. Captions, sources, meta labels and the
   evidence line keep their own step, because flattening every level to --ink
   removes the hierarchy that tells a reader which sentence is the finding and
   which is the provenance. Those are handled as their own tier. */
.report-host .heuristics-report p,
.report-host .heuristics-report li,
.report-host .compliance-report p,
.report-host .compliance-report li,
.report-host .compliance-report .violation-desc,
.report-host .compliance-report .ai-card p {
  color: var(--ink) !important; }

/* The exceptions that keep their step: provenance, captions and the small
   print. They are still lifted from where they were — see the tier below. */
.report-host .heuristics-report .hx-meta-label,
.report-host .compliance-report .vr-crop-caption,
.report-host .compliance-report .source-line,
.report-host .compliance-report [class*="source"],
.report-host .heuristics-report [class*="source"] { color: var(--ink-2) !important; }

/* =================================================== HUE MOVES TO THE EDGE
   Approved by Russ from a live before/after, 2026-09-14.

   The whole 4.5-7 band had one cause: every -text token was valued against the
   raised card and then used on a tint. Measured, the same value drops hard:
   link 6.94 -> 4.56, ok 7.03 -> 5.00, warn 7.14 -> 5.15, critical 7.50 -> 5.33.

   ⛔ THE TWO OBVIOUS FIXES BOTH FAIL, which is why this one is the answer:
   - Brightening the hues to clear 7:1 on --wash-accent lands them at #FFDFD7 /
     #CBEEDA / #F7E4C6. Near-pastel; severity stops reading as severity.
   - Darkening --wash-accent far enough (#12304C) drops its step above the
     raised panel to 1.01:1, under the ladder's ~1.2 threshold, so the panel
     becomes invisible. The two constraints fight directly.

   So we apply the rule the ladder already states: "the accent wash carries the
   accent as its border, and its label takes --ink". The hue is not lost, it
   moves from fill to edge, where threshold 02 only asks 3:1 of it.

   Measured on the same fragment: the 4.5-7 band goes 72 -> 43, AA unchanged. */
.report-host .compliance-report .ai-card-heading,
.report-host .compliance-report .fix-heading,
.report-host .compliance-report .fix-explanation,
.report-host .compliance-report .fix-explanation strong,
.report-host .compliance-report .stat-value,
.report-host .heuristics-report .text-lg.font-bold,
.report-host .heuristics-report .text-lg.font-semibold {
  color: var(--ink) !important; }

.report-host .compliance-report .ai-card {
  border-left: 3px solid var(--hx-info-line) !important; }
.report-host .compliance-report .ai-card.ai-fix {
  border-left-color: var(--hx-ok-line) !important; }
.report-host .compliance-report .fix-section,
.report-host .compliance-report [class*="suggested"] {
  border-left: 3px solid var(--hx-info-line) !important; }

/* =================================================== INDUSTRY PULSE
   Adjacent current discussion, rendered deliberately apart from "From the
   books". The answer's [n] markers point at chapters; these articles point at
   the internet. Putting them in one visual body would claim Reddit backs the
   books.

   So the separation is structural, not decorative: its own rule above it, a
   different heading treatment, and a list that reads as links out rather than
   as numbered citations. */
.pulse {
  margin-top: var(--space-4);
  padding-top: var(--space-3);
  border-top: 1px solid var(--line); }
.pulse h3 {
  font-family: var(--sans); font-size:var(--fs-lead); margin:0 0 var(--space-1); color: var(--ink); }
.pulse-note {
  font-family: var(--sans); font-size:var(--fs-body); color: var(--graphite);
  margin: 0 0 var(--space-3); max-width: 62ch; }

.pulse-list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-3); }
.pulse-item {
  display: grid; gap: 4px;
  padding-left: var(--space-2);
  border-left: 2px solid var(--line); }

/* ⛔ A COMMUNITY THREAD IS NOT A PUBLISHED ARTICLE, and a reader must be able to
   tell without clicking. Their weight differs and pretending otherwise is the
   dishonesty this platform exists to remove. The label says which, and the edge
   backs it up so the distinction survives a skim. */
.pulse-item[data-kind="community"] { border-left-color: var(--hx-warn-line, #E8B562); }
.pulse-item[data-kind="article"] { border-left-color: var(--hx-info-line, #AED4F7); }

.pulse-kind {
  font-family: var(--mono); font-size:var(--fs-caption); letter-spacing: .04em;
  text-transform: uppercase; }
.pulse-item[data-kind="community"] .pulse-kind { color: var(--hx-warn-text, #E8B562); }
.pulse-item[data-kind="article"] .pulse-kind { color: var(--hx-info-text, #AED4F7); }

.pulse-title {
  font-family: var(--sans); font-size:var(--fs-body); font-weight: 600;
  color: var(--ink); text-decoration: none; border-bottom: 1px solid transparent; }
.pulse-title:hover { border-bottom-color: var(--accent-raised); }
.pulse-title:focus-visible { outline: 2px solid var(--accent-raised); outline-offset: 3px; }
.pulse-summary {
  font-family: var(--sans); font-size:var(--fs-body); line-height: 1.55;
  color: var(--ink-2); margin: 2px 0 0; max-width: 68ch; }
.pulse-meta {
  font-family: var(--mono); font-size:var(--fs-caption); color: var(--graphite); margin: 2px 0 0; }

@media (max-width: 640px) {
  .pulse-summary, .pulse-note { max-width: none; }
}

/* A pulse title whose URL failed the scheme check renders as text, not a link.
   Better a title a reader can see than an anchor that lies about its target. */
.pulse-title--plain { border-bottom: 0; cursor: default; color: var(--ink-2); }

/* Contract Corpus (Labs) — a source you can open ---------------------------
   Reuses .score-summary / .score-cell / .result-meta from the Heuristics and
   Compliance results; only the source-opening behaviour is new here. */
.result-caveat{font-family:var(--mono);font-size:var(--fs-caption);line-height:1.6;color:var(--graphite);margin:var(--space-1) 0 0;padding:10px 12px;border-left:2px solid var(--line)}
.corpus-manifest{margin:var(--space-1) 0 0;padding-left:18px}
.corpus-manifest li{margin:0 0 var(--space-1);line-height:1.6}
.source-open{display:inline;text-align:left;background:none;border:0;padding:0;font:inherit;color:inherit;cursor:pointer;border-bottom:1px dotted var(--line)}
.source-open:hover .bk,.source-open:focus-visible .bk{color:var(--accent)}
.source-open[aria-expanded=true] .bk{color:var(--accent)}
.source-sim{font-family:var(--mono);font-size:var(--fs-caption);color:var(--graphite);margin-left:var(--space-1);font-variant-numeric:tabular-nums}
.doc-loading{font-family:var(--mono);font-size:var(--fs-caption);color:var(--graphite);margin:0}

/* Evidence sits on the claim it supports, not in a list at the bottom.
   ⛔ The stroke is --line-chip, not --line. A source chip is a LINK, and the
   ladder's Threshold 02 asks 3:1 of anything identifying a control: --line on
   --wash-accent measures 1.39:1, --line-chip measures 4.00:1. This is the same
   rule .pill and .ask-chip already follow — a boundary this small has to be
   drawn, not implied. */
.point-sources{display:flex;flex-wrap:wrap;gap:6px;margin-top:var(--space-1-5)}
.point-source{display:inline-flex;align-items:baseline;gap:6px;max-width:100%;text-align:left;
  background:var(--wash-accent);border:1px solid var(--line-chip);border-radius:999px;
  padding:5px 11px;font:inherit;font-size:var(--fs-caption);color:var(--ink);cursor:pointer}
.point-source:hover,.point-source:focus-visible{border-color:var(--accent-raised)}
.point-source[aria-expanded=true]{border-color:var(--accent-raised);background:var(--wash)}
/* All three spans read at 7.42:1 or better on --wash-accent. They used to be
   --accent-raised (4.88) and --graphite (5.35); the brackets, the mono face and
   the weight carry the distinction, so the colour does not have to. */
/* ⛔ No ch caps. 22ch and 26ch truncated BOTH spans of every citation on a
   1280px desktop — "Contract: HC1028-26-D-…" next to "Section H — Special
   Contract R…" — while the card they sit in was half empty. The chip already
   carries max-width:100%; min-width:0 is what lets the ellipsis fire at that
   edge instead of at a number typed in advance. */
.point-source .psn{font-family:var(--mono);font-size:var(--fs-caption);color:var(--ink-raised);flex:0 0 auto}
.point-source .pst{font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}
.point-source .pss{color:var(--ink-raised);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}
@media (max-width:560px){.point-source .pss{display:none}}

/* Contract Corpus — findings, built like Compliance's ----------------------
   ⛔ ONE card recipe, declared once. This block previously carried five
   copies of `background:var(--paper-raised);border:1px solid var(--line);
   border-radius:10px` — one per block type — which is five places to drift
   rather than one surface. The differences between the blocks are the left
   edge and the padding; those are the only things stated per-block below. */
.corpus-summary,
.corpus-finding,
.corpus-notfound,
.corpus-raw,
.corpus-doc-section{background:var(--paper-raised);border:1px solid var(--line);border-radius:10px}
.corpus-summary,.corpus-finding{padding:16px 18px}
.corpus-notfound,.corpus-raw{padding:14px 18px}

.corpus-summary{border-left:3px solid var(--accent);margin:0 0 var(--space-3)}
.corpus-summary-label{font-family:var(--mono);font-size:var(--fs-caption);letter-spacing:.09em;text-transform:uppercase;color:var(--graphite);margin:0 0 var(--space-1)}
.corpus-summary p{font-size:var(--fs-body);line-height:1.65;color:var(--ink);margin:0}
.corpus-section-head{font-family:var(--sans);font-size:var(--fs-lead);font-weight:600;color:var(--ink);margin:var(--space-3) 0 var(--space-1)}
.corpus-findings{display:flex;flex-direction:column;gap:12px}

/* Same construction as .finding: raised card, severity-coloured left edge.
   The severity hues are BOUNDARY colours only — each clears the 3:1 the ladder
   asks of a non-text boundary on --paper-raised (critical 3.05, serious 4.66,
   moderate 6.60, minor 4.35). ⛔ None of them may be used as TEXT on that
   ground: critical measures 3.05:1 and fails AA outright. The kind label is a
   .pill, so it reads --ink at 12.25:1 and names the severity in words. */
.corpus-finding{border-left:3px solid var(--line)}
.corpus-finding[data-sev=critical]{border-left-color:var(--sev-critical)}
.corpus-finding[data-sev=serious]{border-left-color:var(--sev-serious)}
.corpus-finding[data-sev=moderate]{border-left-color:var(--sev-moderate)}
.corpus-finding[data-sev=minor]{border-left-color:var(--sev-minor)}
.corpus-finding .finding-top{display:flex;flex-wrap:wrap;align-items:baseline;gap:8px 12px}
.corpus-claim{font-family:var(--sans);font-weight:600;font-size:var(--fs-lead);color:var(--ink);margin:0;flex:1 1 60%}
.corpus-detail{font-size:var(--fs-body);line-height:1.7;color:var(--ink);margin:var(--space-1) 0 0}
.corpus-notfound{border-left:3px solid var(--sev-moderate)}
/* Body copy takes --ink, not --graphite: 12.25:1 rather than 8.14:1. These are
   paragraphs a person reads, not labels beside them. */
.corpus-notfound p{font-size:var(--fs-body);line-height:1.7;color:var(--ink);margin:0}
.corpus-raw{margin-top:var(--space-2)}
.corpus-raw p{font-size:var(--fs-body);line-height:1.7;color:var(--ink);margin:0;white-space:pre-wrap}

/* ⛔ The bounding frame. The whole result lives inside one container with an
   edge, the way the Compliance report does, instead of loose on the page. The
   frame is RECESSED (--paper-sunken) so the raised cards inside it read as
   lifted off a surface rather than floating on the page background.

   ⛔ The edge is DRAWN, not stepped. --paper-sunken against --paper measures
   1.05:1, under the ladder's Threshold 01 (a surface step reads from about
   1.2:1), so the recess alone does not make this frame visible — a --line
   hairline at 1.42:1 was carrying the whole edge and the frame read as absent.
   --line-chip measures 6.61:1 against the page and 6.75:1 against the frame,
   well past the 3:1 Threshold 02 asks of a non-text boundary. Deepen the recess
   or keep the drawn stroke; do not go back to the hairline. */
.corpus-report{background:var(--paper-sunken);border:1px solid var(--line-chip);border-radius:14px;padding:22px 24px;margin-top:var(--space-1)}
@media (max-width:560px){.corpus-report{padding:16px 14px}}
.corpus-report-head{border-bottom:1px solid var(--line);padding-bottom:16px;margin-bottom:var(--space-3)}
.corpus-report-title{font-family:var(--sans);font-size:clamp(20px,2.4vw,26px);font-weight:700;color:var(--ink);margin:0 0 var(--space-1)}
.corpus-report-q{font-size:var(--fs-body);line-height:1.6;color:var(--ink);margin:0 0 var(--space-1)}
.corpus-report-meta{font-family:var(--mono);font-size:var(--fs-caption);color:var(--graphite);margin:0}
/* inside the frame the score grid no longer needs its own top gap */
.corpus-report .score-summary{margin-top:0}

/* Contract Corpus — the document view (its own page) ---------------------- */
.corpus-doc{max-width:none}
.corpus-doc-section{border-left:3px solid var(--line);padding:16px 18px;margin:0 0 var(--space-1-5)}
.corpus-doc-section h2{font-family:var(--sans);font-size:var(--fs-lead);font-weight:600;color:var(--ink);margin:0 0 var(--space-1)}
/* This is the whole document — the thing a citation sends you to read. It was
   --graphite at 8.14:1; body copy takes the brighter value. */
.corpus-doc-section p{font-size:var(--fs-body);line-height:1.7;color:var(--ink);margin:0;white-space:pre-wrap}
/* --accent is a page-ground colour and measures 4.35:1 on a raised card, under
   AA. The cited heading takes the raised value of the same hue: 7.42:1. The
   3px edge keeps --accent, where 4.35:1 clears the boundary bar. */
.corpus-doc-section.is-cited{border-left-color:var(--accent)}
.corpus-doc-section.is-cited h2{color:var(--accent-raised)}
/* a citation is a link now, not a disclosure control */
a.point-source{text-decoration:none}
a.source-open{color:inherit;text-decoration:none;border-bottom:1px dotted var(--line)}
a.source-open:hover .bk,a.source-open:focus-visible .bk{color:var(--accent)}

/* A Launches row points outward, and one small "Visit" was carrying it. The
   title and the image are links too now. The title gets the underline on hover
   so it reads as a link without shouting in the resting state; the image lifts
   its border, which is the only affordance an image can offer honestly. */
.listing-title-link { color: inherit; text-decoration: none;
  border-bottom: 1px solid transparent; }
.listing-title-link:hover { border-bottom-color: var(--accent-raised); }
.listing-title-link:focus-visible { outline: 2px solid var(--accent-raised); outline-offset: 4px; }
.listing-media a { display: block; border: 1px solid transparent; border-radius: 10px;
  overflow: hidden; transition: border-color .15s ease; }
.listing-media a:hover { border-color: var(--accent-raised); }

/* Shred-to-Sched — the one genuinely tabular section -----------------------
   121 requirements is a table, not 121 cards. Everything else on this tool
   reuses the Contract Corpus components unchanged. */
/* 121 rows unbounded is the forty-screen scroll the section picker exists to
   avoid. The table scrolls inside its own frame instead, both ways. */
.shred-table-wrap{overflow:auto;max-height:60vh;border:1px solid var(--line);border-radius:10px;background:var(--paper-raised)}
/* Fixed layout with proportional columns: an auto table let the requirement
   text claim the width and pushed Confidence off the right edge. */
.shred-table{width:100%;border-collapse:collapse;font-size:var(--fs-caption);table-layout:fixed}
.shred-table th:nth-child(1){width:56%}
.shred-table th:nth-child(2){width:13%}
.shred-table th:nth-child(3){width:21%}
.shred-table th:nth-child(4){width:10%}
.shred-table th{font-family:var(--mono);font-size:var(--fs-caption);letter-spacing:.07em;text-transform:uppercase;color:var(--graphite);text-align:left;padding:10px 12px;border-bottom:1px solid var(--line);white-space:nowrap;position:sticky;top:0;background:var(--paper-raised)}
.shred-table td{padding:10px 12px;border-bottom:1px solid var(--line);color:var(--ink);vertical-align:top;line-height:1.55}
.shred-table tr:last-child td{border-bottom:0}
/* The document id and section wrapped one value over four lines. They are
   identifiers, not prose: keep them on one line and let the wrapper scroll. */
.shred-table td:nth-child(2){white-space:nowrap}
/* the document id is an identifier: keep it whole, let it ellipsis if it must */
.shred-table td:nth-child(3){white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.shred-table td:last-child{font-variant-numeric:tabular-nums;color:var(--graphite);white-space:nowrap;text-align:right}
/* a scrollable table needs to look scrollable */
.shred-table-wrap{scrollbar-color:var(--line) transparent}
/* a chosen section reads as chosen */
.ask-chip[aria-pressed=true]{border-color:var(--accent-raised);background:var(--wash-accent)}

/* Shred-to-Sched — structure the original had and the first pass flattened */
.shred-facts{display:flex;flex-wrap:wrap;gap:4px 18px;margin:var(--space-1-5) 0 0;font-family:var(--mono);font-size:var(--fs-caption)}
.shred-facts dt{color:var(--graphite);letter-spacing:.07em;text-transform:uppercase;margin:0}
.shred-facts dd{color:var(--ink);margin:0 var(--space-1) 0 0}
.shred-badge{font-family:var(--mono);font-size:var(--fs-caption);letter-spacing:.08em;padding:2px 7px;border-radius:4px;border:1px solid var(--line);color:var(--graphite);white-space:nowrap}
.shred-badge--ucf{color:var(--accent-raised);border-color:var(--accent)}
/* Each badge follows --ucf above: the hue draws the border, a bright value of
   the same hue carries the word. Measured as TEXT on --paper-raised, the hues
   themselves read 4.35, 6.60 and 4.66 at 10.5px, and the first of those fails
   AA outright. The bright values read 7.42, 7.14 and 7.50. */
.shred-badge--primary{color:var(--accent-raised);border-color:var(--sev-minor)}
.shred-badge--sf30{color:var(--report-warn);border-color:var(--sev-moderate)}
.shred-badge--qaresp{color:var(--report-critical);border-color:var(--sev-serious)}
.shred-part-label{font-family:var(--mono);font-size:var(--fs-caption);letter-spacing:.08em;text-transform:uppercase;color:var(--graphite);margin:var(--space-2) 0 var(--space-1)}
.shred-part-list{margin:0;padding-left:20px}
.shred-part-list li{font-size:var(--fs-body);line-height:1.65;color:var(--ink);margin:0 0 var(--space-1)}
.shred-note{font-size:var(--fs-caption);line-height:1.6;color:var(--graphite);margin:var(--space-1-5) 0 0;padding-left:10px;border-left:2px solid var(--line)}

/* Shred-to-Sched — stacked sections, as the original presents them */
.shred-section{margin-top:var(--space-4)}
.shred-section:first-of-type{margin-top:var(--space-3)}
.shred-section-head{margin:0 0 var(--space-1-5)}
.shred-eyebrow{font-family:var(--mono);font-size:var(--fs-caption);letter-spacing:.09em;text-transform:uppercase;color:var(--accent-raised);margin:0 0 4px}
.shred-section-title{font-family:var(--sans);font-size:var(--fs-lead);font-weight:600;color:var(--ink);margin:0}

/* Image Studio: the style chips are a radiogroup, so they signal with
   aria-checked. Same look as the pressed chips above -- one appearance for
   "this one is selected", not two. */
.ask-chip[aria-checked=true]{border-color:var(--accent-raised);background:var(--wash-accent)}

/* Image Studio: the drawn picture, inside the same bounding frame the other
   tools use for their output. Width-capped rather than stretched, because the
   render is 1152x896 and upscaling it in the browser softens it. */
.studio-image { display: block; width: 100%; max-width: 1152px; height: auto;
  border-radius: 8px; border: 1px solid var(--line); }

/* Sound Studio: the player sits under the recipe inside the same frame the
   other tools use for their output. */
.studio-audio { display: block; width: 100%; margin: 18px 0 0; }

/* Sound Studio recipe: a two-column definition list, NOT .shred-table.
   That table is built for a four-column data grid -- its first column is 56%
   wide and its th is sticky with its own background, which turned the recipe
   labels into one solid block with the values flung to the far edge. */
.recipe-table{width:100%;border-collapse:collapse;margin-top:14px}
.recipe-table th{width:34%;text-align:left;vertical-align:top;
  font-family:var(--mono);font-size:var(--fs-caption);letter-spacing:.07em;
  text-transform:uppercase;color:var(--graphite);font-weight:400;
  padding:9px 14px 9px 0;border-bottom:1px solid var(--line);white-space:nowrap}
.recipe-table td{text-align:left;vertical-align:top;color:var(--ink);
  padding:9px 0;border-bottom:1px solid var(--line);line-height:1.5}
.recipe-table tr:last-child th,.recipe-table tr:last-child td{border-bottom:0}
@media (max-width:640px){
  .recipe-table th{width:40%;white-space:normal}
}

/* Office Hours — the Labs status line. House block: raised surface, hairline
   border, 10px radius, 3px left edge carrying the state. */
/* ---------------------------------------------------------------------------
   OFFICE HOURS BAR — the tool panel's own header.

   ⛔ NOT the bottom-right corner. That corner belongs to chat bubbles and
   cookie banners across the entire web, so anything parked there is read as
   one before it is read at all. Russ, 2026-09-22: "hard to find and looks
   like a chat agent... a 'warning, we accept cookies' type of thing."

   This is the top edge of the instrument instead: full column width, sitting
   on the tool panel, sticking under the nav while the visitor works. Central
   by construction, because it is attached to the thing they came for.

   It answers three questions at once, which is the other half of what was
   missing. Not just "is it free" but "what am I allowed" and "how many do I
   have left" -- the last as a row of pips, countable without reading.

   The departures from the flat system are now down to ONE, and it is the
   cheap one: motion, on the dot, only while there is something to wait for.
   Nothing else on this site moves but the run spinner.
   --------------------------------------------------------------------------- */
.labs-bar { max-width: var(--tool-measure);
  position: sticky; top: 113px; z-index: 40;     /* the header is sticky and 113px tall */
  display: flex; flex-wrap: wrap; align-items: center; gap: 12px 20px;
  justify-content: space-between;
  margin: 0 0 -1px;                              /* joins the panel below it */
  padding: 14px clamp(22px, 4vw, 34px);
  /* --wash-raised, not --wash: --wash is 1.31:1 against the panel below, so the bar
     had almost no edge of its own. This reads 1.71:1 and the object separates. */
  background: var(--wash-raised); border: 1px solid var(--line-chip);
  border-radius: 16px 16px 0 0;
  border-left: 5px solid var(--labs-ready); }

:root { --labs-ready: #8FE3A8; }   /* Measured on the DEPLOYED page: 5.09:1
                                        against the bar surface, up from the
                                        3.32:1 that made "ready" disappear.
                                        (6.66:1 was against the OLD darker
                                        surface -- this change lightened the
                                        surface too, so that figure never
                                        shipped. Measure the artifact, not the
                                        arithmetic.) Not the brand blue, which
                                        is the point: blue on blue was the
                                        defect. */
.labs-bar-main { display: flex; align-items: center; gap: 11px; min-width: 0; }
.labs-bar-dot { flex: 0 0 auto; width: 10px; height: 10px; border-radius: 50%;
  background: var(--labs-ready); }
.labs-bar-line { margin: 0; font-size: .95rem; color: var(--ink); }

/* THE METER — ten pips, one per run. A number has to be read; a row of pips
   is counted at a glance, and the moment one goes hollow the visitor knows
   the count is real rather than decorative. */
.labs-bar-meter { display: flex; align-items: center; gap: 12px; margin-left: auto; }
.labs-bar-pips { display: inline-flex; gap: 4px; }
.labs-bar-pip { width: 7px; height: 7px; border-radius: 50%;
  background: var(--labs-ready); }
.labs-bar-pip[data-spent="1"] { background: transparent;
  box-shadow: inset 0 0 0 1px var(--line-chip); }
.labs-bar-count { margin: 0; font-family: var(--mono); font-size: .76rem;
  letter-spacing: .04em; color: var(--field-note); white-space: nowrap; }

/* STATE — the dot carries it, and a waiting state also takes the left edge so
   it is legible without the sentence.
   ⛔ --sev-minor is the SAME blue as --accent and can never be the signal that
   a waiting state differs from a free one. */
.labs-bar[data-state="available"] { border-left-color: var(--labs-ready); }
.labs-bar[data-state="ours"],
.labs-bar[data-state="warming"],
.labs-bar[data-state="busy"] { border-left-color: var(--sev-moderate); }
.labs-bar[data-state="offline"] { border-left-color: var(--sev-critical); }
.labs-bar[data-state="ours"] .labs-bar-dot,
.labs-bar[data-state="warming"] .labs-bar-dot,
.labs-bar[data-state="busy"] .labs-bar-dot { background: var(--sev-moderate); }
.labs-bar[data-state="offline"] .labs-bar-dot { background: var(--sev-critical); }
.labs-bar[data-state="spent"] { border-left-color: var(--sev-serious); }
.labs-bar[data-state="spent"] .labs-bar-dot { background: var(--sev-serious); }

@keyframes labs-bar-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(216,178,71,.55); }
  70%      { box-shadow: 0 0 0 7px rgba(216,178,71,0); }
}
.labs-bar[data-state="ours"] .labs-bar-dot,
.labs-bar[data-state="warming"] .labs-bar-dot,
.labs-bar[data-state="busy"] .labs-bar-dot {
  animation: labs-bar-pulse 1.9s ease-out infinite; }

/* Motion is the attention mechanism, so it needs the opt-out that makes it
   legitimate. Nothing is announced by movement alone: the dot keeps its
   colour and the left edge keeps its state. */
@media (prefers-reduced-motion: reduce) {
  .labs-bar-dot { animation: none !important; }
}

/* On a phone the meter drops under the line rather than squeezing it. */
@media (max-width: 640px) {
  .labs-bar { position: static; align-items: flex-start; }
  .labs-bar-meter { margin-left: 0; }
}

/* The panel it sits on gives up its top corners, so the two read as one
   instrument rather than a note stacked on a box. */
.labs-bar + .tool-panel { border-top-left-radius: 0; border-top-right-radius: 0; }

/* ---------------------------------------------------------------------------
   Target comfort on touch. ⛔ NOT a 508 requirement — 508 incorporates WCAG
   2.0 A/AA, which has no target-size criterion at all. 44x44 is 2.1 AAA and
   24x24 is 2.2 AA. These are usability fixes, measured at 375px:
   nav-toggle was 38x38, ask-chips 42 tall, and these standalone nav links 21.
   The 16-17px checkboxes that also showed up are FALSE POSITIVES — every one
   sits inside a <label> whose real target is 258x41 or larger.
   --------------------------------------------------------------------------- */
@media (max-width: 640px) {
  .listing-notes, .site-foot a { display: inline-block; padding-block: 6px; }
}
