/* HEAT shared design system. One look for every page.
   Themes via html[data-theme] (set pre-paint by theme-init.js; default follows
   the system). Color-vision variant via html[data-vision="colorblind"]
   (Okabe-Ito accents; off by default). No state is ever color-only. */

/* --warn-line is a RULE colour and --warn-ink is its readable twin, the same
   split --cyan and --accent-ink already make. A 4px amber border needs 3:1 and
   gets it; an amber glyph sitting beside a full-contrast word needs to look
   like it belongs to that word, and #d9b96a on white does not. The older amber
   glyphs (.zone--yellow, .iaband--caution, .evd__sens--moderate) deliberately
   still take --warn-line: two of them are on the page written to the person
   being assessed, which is out of scope for the status-colour pass. */
html[data-theme="light"] {
  color-scheme: light; /* native controls must follow the CHOSEN theme, not the OS */
  --cyan: #0099CC;
  --accent-ink: #007399;
  --fg: #1a1a1a; --muted: #4a4a4a; --bg: #fafaf7; --card-bg: #ffffff;
  --line: #d5d2cb; --line-strong: #767470;
  --err: #b3244a; --ok: #1c7a43;
  --warn-bg: #fdf3e3; --warn-line: #d9b96a; --warn-ink: #7a5f14;
  --btn-ink: #06222c;
}
html[data-theme="dark"] {
  color-scheme: dark;
  --cyan: #01CCFF;
  --accent-ink: #4fd6ff;
  --fg: #e8e6df; --muted: #b3b0a6; --bg: #0f1419; --card-bg: #1a2129;
  --line: #3d454e; --line-strong: #6b7681;
  --err: #ff8fa8; --ok: #5fd39a;
  --warn-bg: #2a2314; --warn-line: #8a7434; --warn-ink: #e0c070;
  --btn-ink: #06222c;
}
/* Colour-vision variant. --warn-line is remapped here as well as --err,
   because the amber family became load-bearing wayfinding on the worker
   result (documentation and data quality) at the same time as the red one
   (safety). Okabe-Ito puts --err on the ORANGE slot, and the default amber
   (#d9b96a / #8a7434) is an orange neighbour, so the two families sat one
   hue apart for a deuteranope. Amber moves to the palette's YELLOW slot
   instead, darkened on light backgrounds because #F0E442 on white is 1.2:1
   and this variable is drawn as a glyph, not only as a rule. Every one of
   these states also carries an icon and a word, so colour is confirming a
   distinction the markup already makes; this only keeps it from confirming
   the wrong one. */
html[data-vision="colorblind"][data-theme="light"] {
  --cyan: #0072B2; --accent-ink: #005a8e;
  --err: #B24A00; --ok: #007a5e;
  --warn-line: #8a6d00; --warn-ink: #7a6100;
  --btn-ink: #ffffff;
}
html[data-vision="colorblind"][data-theme="dark"] {
  --cyan: #56B4E9; --accent-ink: #7cc4ee;
  --err: #E69F00; --ok: #66c2a4;
  --warn-line: #F0E442; --warn-ink: #F0E442;
}

/* ---------- base ---------- */
:root {
  /* THE READING MEASURE, in one place, in pixels on purpose. A ch-based cap
     gives every text size its own right edge (78ch of 15.6px help text ends
     90px short of 78ch of 17px body text), so a page of mixed sizes has a
     ragged stack of right edges no one can name. One pixel measure gives every
     paragraph on the page the same right edge, whatever its size: 900px is 88
     characters of 17px body text and 96 of the smaller help text, both inside
     the range that keeps a reader from losing the start of the next line. */
  --measure: 900px;
}
* { box-sizing: border-box; margin: 0; }
/* Nothing on this site is sticky, so an anchor only needs to clear the viewport
   edge rather than a fixed header; 24px is the gap that keeps a section's
   hairline rule from landing flush against the top of the screen. */
html { scroll-padding-top: 24px; }
/* In-page jumps animate, so a reader can see WHERE they were moved to. Anyone
   who has asked their system for less motion gets the instant jump instead. */
@media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } }
body {
  font-family: Inter, system-ui, -apple-system, "Segoe UI", sans-serif;
  background: var(--bg); color: var(--fg);
  line-height: 1.55; font-size: 17px;
  padding-bottom: 76px; /* room for the floating flag button */
}
a { color: var(--accent-ink); text-decoration: underline; text-underline-offset: 2px; }
:focus-visible { outline: 3px solid #ffdd00; outline-offset: 2px; box-shadow: 0 0 0 6px #0b0c0c; border-radius: 4px; }
.skip { position: absolute; left: -9999px; top: 0; background: #ffdd00; color: #0b0c0c; padding: 10px 16px; font-weight: 700; z-index: 100; }
.skip:focus { left: 8px; top: 8px; }
/* One shared container, and the ONLY thing on the page that centres itself.
   Wide enough that grids, drawers and side-by-side cards can use the screen,
   narrow enough that one column of text inside it is not marooned: at 1080px
   the content box is 1040px and the 900px measure fills 87% of it. Prose is
   capped separately (see "readable measure" below) so a wide window never
   produces a 200-character line. */
.wrap { max-width: 1080px; margin: 0 auto; padding: 0 20px; }
/* Anything a person fills in stays a single readable column: question screens,
   the intro, the interstitials, and check-your-answers. */
.wrap--narrow { max-width: 760px; }
/* Results, including a sample result, are reading surfaces rather than forms:
   they get the full container so checklists and drawers can sit side by side.
   app.ts already publishes the current screen as html[data-heat-item], so this
   needs no extra plumbing. */
html[data-heat-item="results"] .wrap--narrow,
html[data-heat-item="sample"] .wrap--narrow { max-width: 1080px; }
/* ---------- alignment system: ONE RAIL ----------
   Every page has exactly ONE left rail: the container's own left padding edge.
   A heading, a paragraph, a card grid and a card all start at the same x on
   every page, at every width. Nothing between <main> and a block may cap or
   centre itself, and the audit script fails the build if anything does.

   This replaces a system with three competing widths: a 78ch paragraph cap
   inside a 1010px centred prose column inside a 1160px container. On the
   landing page that put the section heading and its intro on one rail and the
   card grid below them on another, 55px apart, which reads as two pages
   stacked; on every reading page it left a third of the width empty beside the
   text. Neither is visible while reading the CSS and both are the first thing
   anyone sees on a screenshot.

   .col is kept as a no-op class so the markup on a dozen pages did not have to
   change to make this true. It caps nothing and centres nothing. Do not give
   it back a width: the rail is the whole rule.

   The reading measure still exists, because a 1040px line is unreadable, but
   it now belongs to the text (--measure, one value, one right edge) instead of
   to a column that moved the text away from the rail. */
.col { width: 100%; }

/* ---------- banner + header ---------- */
/* Burnt orange + centered (Gaither 2026-08-31): the 911 line must draw
   the eye before anything else. Fixed color in both themes; white text
   on #A64500 is >= 4.5:1. */
.topbanner { background: #A64500; color: #fff; border-bottom: 1px solid #7c3300; padding: 8px 0; font-size: 0.88rem; text-align: center; }
.topbanner strong { color: #fff; }
header.site { padding: 10px 0; border-bottom: 1px solid var(--line); }
.headrow { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.brandmark { font-weight: 800; letter-spacing: 0.04em; color: var(--cyan); font-size: 1.2rem; text-decoration: none; }
.brandname { color: var(--muted); font-size: 0.85rem; margin-right: auto; }
.prefs { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.prefs fieldset { border: 0; padding: 0; display: flex; align-items: center; }
.prefs legend { position: absolute; left: -9999px; }
.seg { display: inline-flex; border: 1px solid var(--line-strong); border-radius: 10px; overflow: hidden; }
.seg label { display: inline-flex; align-items: center; justify-content: center; min-height: 44px; padding: 0 12px; cursor: pointer; font-size: 0.82rem; color: var(--muted); position: relative; }
.seg label + label { border-left: 1px solid var(--line); }
.seg input { position: absolute; opacity: 0; inset: 0; margin: 0; cursor: pointer; }
.seg input:checked + span { color: var(--fg); font-weight: 700; }
.seg label:has(input:checked) { background: var(--card-bg); box-shadow: inset 0 -3px 0 var(--cyan); }
.seg input:focus-visible + span { outline: 3px solid #ffdd00; outline-offset: 6px; }
/* Header preference icons: monitor / sun / moon / eye. They ride beside the
   labels, never instead of them, and take the brand accent when selected so
   the chosen option reads at a glance. */
.picon { flex: none; color: currentColor; }
.seg .picon { width: 15px; height: 15px; margin-right: 7px; }
.seg label:has(input:checked) .picon { color: var(--cyan); }
.cbtoggle { display: inline-flex; align-items: center; gap: 8px; min-height: 44px; padding: 0 14px; border: 1px solid var(--line-strong); border-radius: 10px; background: transparent; color: var(--muted); font-size: 0.82rem; cursor: pointer; }
.cbtoggle[aria-pressed="true"] { color: var(--fg); font-weight: 700; background: var(--card-bg); box-shadow: inset 0 -3px 0 var(--cyan); }
.cbtoggle .picon { width: 16px; height: 16px; }
.cbtoggle[aria-pressed="true"] .picon { color: var(--cyan); }
/* Narrow screens: the icons cost width the header row does not have, so the
   controls tighten by exactly what the icons add. Measured at 320-460px, the
   preference row occupies the same rows and the same height it did before the
   icons existed; labels stay visible and every target stays 44px. */
@media (max-width: 460px) {
  .prefs { gap: 8px; }
  .seg label { padding: 0 6px; font-size: 0.76rem; }
  .seg .picon { width: 13px; height: 13px; margin-right: 3px; }
  .cbtoggle { padding: 0 8px; gap: 5px; font-size: 0.76rem; }
  .cbtoggle .picon { width: 14px; height: 14px; }
}
/* ---------- site navigation ----------
   A second header row, identical on every surface, so no page is a dead end
   that has to be left through the front page. It borrows the segmented
   control's language rather than inventing a second one: muted by default,
   full-strength text plus a cyan underline for the current page. The row sits
   flush with the header's own bottom border (margin-bottom cancels the header
   padding), so the underline lands ON that line instead of floating above it.
   Links pad to 44px of height at every width and the row wraps to two lines
   when it has to; nothing is hidden behind a menu button. */
nav.sitenav { margin: 10px 0 -10px; border-top: 1px solid var(--line); }
nav.sitenav .wrap { display: flex; flex-wrap: wrap; padding-left: 10px; padding-right: 10px; }
nav.sitenav a {
  display: inline-flex; align-items: center; min-height: 44px; padding: 0 10px;
  font-size: 0.86rem; color: var(--muted); text-decoration: none;
  border-bottom: 3px solid transparent;
}
nav.sitenav a:hover { color: var(--fg); border-bottom-color: var(--line-strong); }
nav.sitenav a[aria-current="page"] { color: var(--fg); font-weight: 700; border-bottom-color: var(--cyan); }
/* Each destination carries a mark, in the same wire language as the preference
   icons: 24-unit box, 2px stroke, round caps, no fill. The mark inherits the
   link's colour rather than taking the brand accent, so the whole link (icon,
   word and underline) brightens together on the current page and stays muted
   everywhere else. It is always beside the word, never instead of it. */
nav.sitenav a .picon { width: 15px; height: 15px; margin-right: 7px; }
/* The header is now two rows tall, so a page that opens straight on its h1
   would start flush against the nav underline. The landing hero already buys
   its own 46px, so it is excluded; everything else gets a matching opening. */
main > .wrap > h1:first-child,
main > .wrap > .col:first-child:not(.hero) > h1:first-child,
main.wrap > .col:first-child:not(.hero) > h1:first-child { margin-top: 26px; }
/* Same reason on the assessment, which opens straight on a card. */
main.wrap--narrow { padding-top: 22px; }
@media (max-width: 460px) {
  nav.sitenav .wrap { padding-left: 12px; padding-right: 12px; }
  nav.sitenav a { padding: 0 8px; font-size: 0.8rem; }
  nav.sitenav a .picon { width: 13px; height: 13px; margin-right: 5px; }
}
/* Below this the icons cost a third wrap line, and a nav that grows a row is a
   worse trade than a nav without pictures. Labels never go: the words are the
   navigation, the marks are decoration that has to earn its width. Measured at
   320 and 390px, seven links wrap to exactly two rows with the icons hidden. */
@media (max-width: 400px) {
  nav.sitenav a .picon { display: none; }
}

/* ---------- content ---------- */
.card { background: var(--card-bg); border: 1px solid var(--line); border-radius: 12px; padding: 20px; margin-bottom: 14px; }
h1 { font-size: 1.35rem; line-height: 1.3; margin-bottom: 10px; }
/* Each screen moves focus to its own h1 so a screen reader announces the new
   page. A heading is not a control and is not reachable by Tab, so it must not
   also paint the focus ring: on arrival at the assessment and on every sample,
   the ring drew a heavy black box around the page title. Clearing the outline
   alone left the ring, because the ring is the box-shadow. */
h1:focus, h1:focus-visible { outline: none; box-shadow: none; }
h2 { font-size: 1.1rem; margin-bottom: 10px; font-weight: 680; }
h3 { font-size: 0.98rem; margin: 10px 0 4px; }
p { margin-bottom: 10px; }
ul, ol { padding-left: 20px; margin-bottom: 10px; }
li { margin-bottom: 5px; font-size: 0.93rem; }
/* ---------- readable measure ----------
   The container is wide so structure (grids, checklists, drawers, the SBAR
   record) can use the room. Running prose must not follow it: past roughly 90
   characters the eye loses the start of the next line. Cards, grids and
   sections keep their full width; only the text inside them is capped, and
   every capped block ends on the same right edge (see --measure). */
main p, main li, .card dd, .card blockquote, .zone, .qitem h3 { max-width: var(--measure); }

.modehint { color: var(--accent-ink); font-size: 0.85rem; font-style: italic; margin: 2px 0 6px; }
.help { color: var(--muted); font-size: 0.92rem; }
/* A boxed callout is a band, not running prose, so it spans its card like the
   status band it sits beside. Capping it at the reading measure gave a card
   three consecutive notices with two different right edges. */
.warn { background: var(--warn-bg); border: 1px solid var(--warn-line); border-radius: 8px; padding: 10px 12px; font-size: 0.92rem; }
main p.warn, main .warn { max-width: none; }
.backlink { display: inline-block; margin: 6px 0 10px; color: var(--accent-ink); background: none; border: none; font: inherit; font-size: 0.92rem; cursor: pointer; text-decoration: underline; text-underline-offset: 2px; padding: 10px 10px 10px 0; }

/* ---------- buttons ---------- */
button { font: inherit; cursor: pointer; border-radius: 10px; border: 1px solid var(--line-strong); }
.primary { display: block; width: 100%; min-height: 54px; padding: 13px; margin-top: 18px; background: var(--cyan); color: var(--btn-ink); font-weight: 700; border: none; font-size: 1.05rem; }
.primary:hover { opacity: 0.92; }
.secondary { display: block; width: 100%; min-height: 48px; padding: 11px; margin-top: 10px; background: transparent; color: var(--fg); font-size: 0.95rem; }
.cta { display: inline-flex; align-items: center; justify-content: center; min-height: 52px; padding: 12px 24px; background: var(--cyan); color: var(--btn-ink); font-weight: 700; border-radius: 10px; font-size: 0.98rem; text-decoration: none; }
.cta:hover { opacity: 0.92; text-decoration: none; }
/* Quiet twin of the primary button: the shadow pilot is the second door on
   the hero, offered without shouting. Outline style, same height and radius,
   so the pair reads as one control group. Wraps under the primary on phones. */
.cta--quiet { background: transparent; color: var(--accent-ink); border: 2px solid var(--cyan); }
.cta--quiet:hover { background: var(--card-bg); opacity: 1; }
.herocta { display: flex; flex-wrap: wrap; gap: 10px; }
/* The landing sample card borrows the result page's own chip classes so its
   color coding IS the sample page's color coding, not a lookalike: info for
   determinations and discuss-first, neutral for quieter states. Sized down to
   sit inside definition rows. */
.srow .chip { margin-bottom: 0; font-size: 0.88rem; padding: 4px 12px; }
.schips .chip { margin-bottom: 6px; }
/* On the wide screens a 100%-width button stops reading as a control and
   starts reading as a banner. Form screens keep the full-bleed button. */
html[data-heat-item="results"] .primary, html[data-heat-item="results"] .secondary,
html[data-heat-item="sample"] .primary, html[data-heat-item="sample"] .secondary { max-width: 560px; }

/* ---------- forms (assessment) ---------- */
/* Question progress: "N of about M", M = length of the currently active
   sequence. Branching changes M, so the wording never promises a fixed total. */
.qprogress { font-size: .8rem; color: var(--muted); margin-bottom: 6px; }
.qprogressbar { height: 3px; background: var(--line); border-radius: 2px; margin-bottom: 14px; }
.qprogressbar > span { display: block; height: 100%; background: var(--cyan); border-radius: 2px; }
/* WHO THIS ASSESSMENT IS ABOUT. One quiet line under the progress bar on every
   question screen and on check-your-answers. Six practitioner flags in one
   round (188/189/190/192/195, 2026-08-10) said the same thing: the mode is
   chosen once on the intro and then invisible, so a session that changes hands
   mid-way, or a page read later, has nothing on it saying who was answering.
   Quiet by design: it must be findable, never compete with the question. NOT
   .noprint, because the printed page is exactly where the question gets asked
   again. */
.modeline { font-size: .8rem; color: var(--muted); margin: -6px 0 14px; padding-left: 10px; border-left: 3px solid var(--line-strong); }
@media print { .modeline { color: #000; border-left-color: #000; } }
/* Button that reads as a link (inline quick-exit affordance on safety items). */
.linkbtn { background: none; border: none; padding: 4px 0; margin: 0; font: inherit; color: inherit; text-align: left; text-decoration: underline; text-underline-offset: 2px; cursor: pointer; }
.radios { display: grid; gap: 10px; margin: 14px 0 4px; }
.radio { display: flex; align-items: center; gap: 14px; min-height: 56px; padding: 8px 14px; border: 2px solid var(--line-strong); border-radius: 10px; cursor: pointer; background: var(--bg); }
/* Custom-drawn radio: identical in every browser and OS/theme combination.
   Unselected = empty ring; selected = filled dot. Never ambiguous. */
.radio input {
  appearance: none; -webkit-appearance: none;
  width: 26px; height: 26px; flex-shrink: 0; margin: 0; cursor: pointer;
  border: 2.5px solid var(--line-strong); border-radius: 50%;
  background: var(--card-bg);
}
.radio input:checked {
  border-color: var(--cyan);
  background: radial-gradient(circle, var(--cyan) 0 42%, transparent 48%);
}
/* Checkbox rows (multi-select items) reuse the row shell above and change
   only the control: a SQUARE that fills with a square, so "choose as many as
   fit" can never be mistaken for "choose one". Drawn with a background
   gradient rather than a pseudo-element, because ::after on an input is not
   reliable across browsers, and in theme variables rather than a fixed white
   tick, so it holds in light, dark and colorblind mode. */
.radio--check input { border-radius: 6px; }
.radio--check input:checked {
  border-color: var(--cyan);
  background: linear-gradient(var(--cyan), var(--cyan)) center / 58% 58% no-repeat, var(--card-bg);
}
.radio__icon { flex-shrink: 0; display: inline-flex; color: var(--muted); }
.radio__icon svg { width: 22px; height: 22px; }
.radio:has(input:checked) .radio__icon { color: var(--accent-ink); }
.radio span { font-size: 1rem; }
.radio:has(input:checked) { border-color: var(--cyan); border-width: 3px; padding: 7px 13px; background: var(--card-bg); }
.radio:hover { border-color: var(--cyan); }
.ordivider { color: var(--muted); font-size: 0.9rem; padding-left: 4px; font-weight: 700; }
.numrow { display: flex; gap: 12px; margin: 14px 0 4px; }
.numgroup { display: flex; flex-direction: column; gap: 4px; }
.numgroup label { font-size: 0.9rem; color: var(--muted); }
.textinput { padding: 12px; font: inherit; font-size: 1.05rem; border-radius: 8px; border: 2px solid var(--line-strong); background: var(--bg); color: var(--fg); min-height: 52px; }
.textinput.w4 { width: 7ch; } .textinput.w2 { width: 5ch; } .textinput.w6 { width: 10ch; }
.textinput[aria-invalid="true"] { border-color: var(--err); }
.errorsummary { border: 4px solid var(--err); border-radius: 10px; padding: 14px 16px; margin-bottom: 14px; }
.errorsummary h2 { color: var(--err); margin-bottom: 6px; }
.errorsummary a { color: var(--err); font-weight: 650; }
.fielderror { color: var(--err); font-weight: 650; font-size: 0.95rem; margin: 8px 0 0; border-left: 4px solid var(--err); padding-left: 10px; }
/* Phase label on the check-your-answers screen. It reuses the SBAR band
   heading (the site's existing "label inside a card" idiom) and only adds the
   space above it that a group heading needs. */
.sumgroup { margin-top: 20px; }
.sumgroup:first-of-type { margin-top: 10px; }
.sumrow { display: grid; grid-template-columns: 1fr auto; gap: 4px 12px; padding: 12px 0; border-bottom: 1px solid var(--line); align-items: start; }
.sumrow dt { font-size: 0.9rem; color: var(--muted); grid-column: 1; }
.sumrow dd { font-size: 0.98rem; grid-column: 1; margin: 0; }
.sumrow .change { grid-column: 2; grid-row: 1 / span 2; align-self: center; background: none; border: none; color: var(--accent-ink); text-decoration: underline; text-underline-offset: 2px; font-size: 0.92rem; min-height: 44px; min-width: 60px; }

/* ---------- results ---------- */
.chip { display: inline-flex; align-items: center; gap: 8px; padding: 6px 14px; border-radius: 999px; font-size: 0.95rem; font-weight: 650; margin-bottom: 10px; border: 2px solid var(--line-strong); }
.chip::before { font-weight: 800; }
.chip.ok { color: var(--ok); border-color: var(--ok); } .chip.ok::before { content: "✓"; }
.chip.info { color: var(--accent-ink); border-color: var(--accent-ink); } .chip.info::before { content: "●"; }
.chip.alert { color: var(--err); border-color: var(--err); } .chip.alert::before { content: "!"; }
.chip.neutral { color: var(--muted); } .chip.neutral::before { content: "○"; }
.opt { border-top: 1px solid var(--line); padding-top: 10px; margin-top: 10px; }
details summary { cursor: pointer; color: var(--accent-ink); font-size: 0.92rem; margin-bottom: 8px; min-height: 44px; display: flex; align-items: center; }

/* ---------- client card (chart header) ---------- */
.samplebanner { border: 2px dashed var(--line-strong); }
/* The persona's own mark, the same one on its switcher pill, replaces the
   generic ◉ that used to prefix every sample heading. */
.samplebanner h1 { display: flex; align-items: center; }
.samplebanner h1 .hicon { width: 26px; height: 26px; color: var(--accent-ink); }
/* One alignment story, on the screens that had two. The banner's heading and
   its two paragraphs used to hug the left edge of a 1120px card while the
   button and the back link sat centred, so the card read as two compositions
   stacked. From 700px up everything joins one centred group; the paragraph
   keeps its own measure so a centred line is never long. A phone is
   deliberately excluded: there the card is already the width of the text,
   centring would only make five lines of body copy ragged on both edges, and
   nothing is out of balance to begin with. */
@media (min-width: 700px) {
  .samplebanner { text-align: center; }
  .samplebanner h1 { justify-content: center; }
  .samplebanner p { max-width: 66ch; margin-left: auto; margin-right: auto; }
}
/* Below that breakpoint the card is a left-flowing card like any other, so its
   .cgroup (the call to action plus the back link) drops back into the left rail
   with the copy above it rather than centring against it. */
@media (max-width: 699px) {
  .samplebanner .cgroup { text-align: left; }
  .samplebanner .cgroup > * { margin-left: 0; margin-right: 0; }
}
.cardhead { border-top: 4px solid var(--cyan); }
.cardhead__top { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.cardhead__top h1 { margin-bottom: 4px; }
.cardhead__meta { display: flex; gap: 10px; align-items: center; color: var(--muted); font-size: 0.85rem; }
.modechip { border: 1px solid var(--line-strong); border-radius: 999px; padding: 3px 10px; font-weight: 650; color: var(--fg); }
.sbar { margin: 14px 0; }
.sbar__h { font-size: 0.78rem; color: var(--muted); letter-spacing: 0.06em; text-transform: uppercase; border-bottom: 1px solid var(--line); padding-bottom: 4px; margin-bottom: 8px; }
/* The SBAR band marks (2026-08-07). Small, because the label is small: these
   are landmarks on a long record, not headlines. */
.sbar__h .hicon { width: 14px; height: 14px; margin-right: 6px; vertical-align: -2px; }
.sbar__lede { font-size: 1.12rem; font-weight: 650; line-height: 1.45; }
.iaband { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; border-radius: 10px; padding: 12px 14px; margin: 14px 0; border: 2px solid; }
/* There is deliberately NO --ok band. The status band is exception-only (see
   buildClientCard): green never appears beside a housing crisis, so a green
   all-clear rule sitting unused in this sheet was a loaded gun. Removed
   2026-08-28 with the consistency sweep, along with an unused --neutral. */
.iaband--alert { border-color: var(--err); color: var(--err); background: color-mix(in srgb, var(--err) 10%, transparent); }
.iaband--alert::before { content: "!"; font-weight: 800; }
.iaband__label { font-size: 0.78rem; letter-spacing: 0.06em; text-transform: uppercase; opacity: 0.85; }
.iaband strong { font-size: 1.02rem; }
.arow { margin-bottom: 12px; }
.arow__head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 2px; }
.arow__name { font-weight: 650; font-size: 0.95rem; }
.arow .chip { margin-bottom: 0; font-size: 0.88rem; padding: 4px 10px; }
.steps { padding-left: 22px; }
.steps li { font-size: 0.95rem; margin-bottom: 8px; }
.confnote { border-top: 1px dashed var(--line); padding-top: 8px; margin-top: 4px; }
.flagchips { display: flex; flex-wrap: wrap; gap: 8px; margin: 10px 0; }
.flagchip { border: 1px solid var(--line-strong); border-radius: 999px; padding: 4px 12px; font-size: 0.85rem; color: var(--fg); background: var(--bg); }

/* ---------- contextual + floating flags ---------- */
.flagline { margin-top: 16px; font-size: 0.85rem; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.raterow { display: inline-flex; align-items: center; gap: 6px; }
.ratebtn { display: inline-flex; align-items: center; justify-content: center; width: 44px; height: 44px; background: transparent; color: var(--muted); border: 1px solid var(--line); border-radius: 10px; cursor: pointer; }
.ratebtn:hover { color: var(--accent-ink); border-color: var(--accent-ink); }
.ratebtn svg { width: 20px; height: 20px; }
.primary .radio__icon, .secondary .radio__icon { margin-right: 8px; vertical-align: -3px; }
.primary .radio__icon { color: inherit; }
.primary .radio__icon svg, .secondary .radio__icon svg { width: 18px; height: 18px; }
.gd-flag-trigger { min-height: 44px; display: inline-flex; align-items: center; }
.flagfab {
  position: fixed; left: 14px; bottom: 14px; z-index: 900;
  display: inline-flex; align-items: center; gap: 8px;
  min-height: 48px; padding: 0 18px;
  background: var(--card-bg); color: var(--fg);
  border: 2px solid var(--line-strong); border-radius: 999px;
  font-size: 0.9rem; font-weight: 650; cursor: pointer;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.25);
  text-decoration: none;
}
.flagfab:hover { border-color: var(--cyan); }
.flagfab .picon { width: 17px; height: 17px; color: var(--err); }

/* ---------- participant card + zones ---------- */
.youcard { border-top: 4px solid var(--ok); }
/* The participant card's own headings. It leads the client view, so its title
   is the page's h1 and its four sections are h2 (2026-08-07: the client view
   had no h1 at all, which left focusHeading() with nothing to move focus to
   after a view switch and the page with no top-level heading). */
.youcard h2 { margin-top: 12px; }
.zones { display: grid; gap: 8px; margin-top: 14px; }
.zone { border-left: 5px solid; border-radius: 6px; padding: 8px 12px; font-size: 0.93rem; background: var(--bg); }
.zone__glyph { margin-right: 8px; font-weight: 800; }
/* The zone mark takes the zone's own color, not the section-icon cyan. */
.zone__glyph .hicon { width: 17px; height: 17px; margin-right: 0; color: inherit; vertical-align: -3px; }
.zone--green { border-color: var(--ok); } .zone--green .zone__glyph { color: var(--ok); }
.zone--yellow { border-color: var(--warn-line); } .zone--yellow .zone__glyph { color: var(--warn-line); }
.zone--red { border-color: var(--err); } .zone--red .zone__glyph { color: var(--err); }

/* ---------- tooltips: ONE system for the whole site ----------
   Owner ruling 2026-08-28: one tooltip, "modern like gaithernews.com". Two
   kinds of trigger, one panel, one style, one dismissal model:
     button.gloss   a term wrapped automatically in prose by glossary.js
     [data-tip]     anything else that carries an explanation (see that file's
                    header for the three title= attributes this replaced)
   Colours come from the theme tokens, so the panel is correct in light, dark
   and both colourblind variants without a single per-theme override. */
button.gloss,
[data-tip]:not(button):not(a) {
  display: inline; padding: 0; margin: 0; border: none; background: none;
  font: inherit; color: inherit; cursor: help;
  border-bottom: 1.5px dotted var(--accent-ink);
  border-radius: 0;
}
button.gloss:hover, button.gloss:focus-visible,
[data-tip]:not(button):not(a):hover,
[data-tip]:not(button):not(a):focus-visible {
  border-bottom-style: solid; color: var(--accent-ink);
}
/* A trigger that keeps its own action (the quick-exit button, the sample
   switcher) is left entirely alone: it keeps its own look and its own
   pointer cursor, because it is still a button first and the panel is the
   thing it says about itself, not the thing it does. */

/* FIXED, not absolute: the panel is placed against the viewport by
   glossary.js, which is what lets one clamp keep it inside the gutters at
   390px and at 1440px without a second code path. */
.heattip {
  position: fixed; z-index: 950; max-width: 340px;
  background: var(--card-bg); color: var(--fg);
  border: 1px solid var(--line-strong); border-left: 4px solid var(--cyan);
  border-radius: 10px; padding: 10px 14px;
  font-size: 0.88rem; line-height: 1.5;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.35);
  opacity: 0; transform: translateY(2px);
  transition: opacity 0.12s ease, transform 0.12s ease;
}
.heattip.is-open { opacity: 1; transform: none; }
/* The caret is a rotated square wearing the panel's own border, with the two
   sides that face into the panel removed. glossary.js sets its left offset so
   it keeps pointing at the trigger after the panel has been clamped, and
   hides it when the clamp moved the panel too far for it to mean anything. */
.heattip__caret {
  position: absolute; width: 10px; height: 10px; margin-left: -5px;
  background: var(--card-bg); border: 1px solid var(--line-strong);
  transform: rotate(45deg);
}
.heattip[data-place="below"] .heattip__caret { top: -6px; border-right: 0; border-bottom: 0; }
.heattip[data-place="above"] .heattip__caret { bottom: -6px; border-left: 0; border-top: 0; }
/* Source line inside a tooltip: the primary document behind the definition.
   Same link treatment as everywhere else; its own line so the definition
   stays a plain sentence. */
.heattip__src { display: block; margin-top: 8px; font-size: 0.82rem; }
@media (prefers-reduced-motion: reduce) { .heattip { transition: none; } }
@media print {
  button.gloss, [data-tip] { border-bottom: none; }
  .heattip { display: none; }
}

/* ---------- questions review page ----------
   A question is a self-contained unit (wording, proxy wording, help, answer
   choices), so it is a card, not a row in a stack. Cards deal into two columns
   from 1000px up, which is what turns a 60-screen scroll of hairlines into a
   page that reads as designed for the width. Module headings are the only
   full-width members of the grid, so a module always starts a fresh row.
   Cards STRETCH to their row's height. align-items:start was the earlier
   choice and it is what put a hole under every short card: two questions side
   by side, one three lines and one eight, left five lines of nothing under the
   short one and a visibly broken row. Equal-height cards in a row is what a
   card grid means. */
.qgrid { display: grid; grid-template-columns: 1fr; gap: 14px; }
@media (min-width: 1000px) { .qgrid { grid-template-columns: repeat(2, 1fr); } }
/* A grid track's default minimum is its content's min-content width, so one
   long unbreakable string would widen the column past the viewport. */
.qgrid > *, .evdgrid > * { min-width: 0; }
.qgrid__head { grid-column: 1 / -1; margin: 16px 0 0; padding-top: 18px; border-top: 1px solid var(--line); font-size: 1.1rem; }
.qgrid__head:first-child { margin-top: 0; padding-top: 0; border-top: 0; }
/* How many questions are in this group, set as data rather than as part of the
   sentence: a reader scanning for "the short one" finds the number without
   reading the heading. */
.qgrid__count { font-weight: 400; font-size: 0.85rem; color: var(--muted); font-variant-numeric: tabular-nums; }
.qgrid__count::before { content: "· "; }
/* Who is asked this group and why. It spans the grid with its heading, so the
   note is read before the cards rather than beside the first one, and it keeps
   the page measure so it ends on the same right edge as every other paragraph
   on the site. */
.qgrid__note { grid-column: 1 / -1; margin: 6px 0 2px; max-width: var(--measure); color: var(--muted); font-size: 0.92rem; }
/* Equal-height cards leave slack inside the shorter one. The answer choices
   take it: they are the one row in the card that is a control rather than
   prose, so they sit on the card's floor and line up with the answers of the
   card beside them. A short card then reads as composed rather than as a card
   with a hole under it. */
.qitem { background: var(--card-bg); border: 1px solid var(--line); border-radius: 12px; padding: 16px 18px; display: flex; flex-direction: column; }
.qitem h3 { margin: 0 0 4px; font-size: 1rem; }
.qitem .qhelp { color: var(--muted); font-size: 0.88rem; margin-bottom: 6px; }
.qopts { display: flex; flex-wrap: wrap; gap: 6px; margin: 6px 0 0; }
.qitem .qopts { margin-top: auto; padding-top: 8px; }
.qopt { border: 1px solid var(--line); border-radius: 999px; padding: 3px 12px; font-size: 0.85rem; color: var(--muted); }
.qmeta { font-size: 0.8rem; color: var(--muted); }
.qproxy { font-size: 0.88rem; color: var(--muted); font-style: italic; }

/* ---------- questions page: jump menu ----------
   Eight groups and thirty-four cards is more than anyone should scroll blind,
   so the page carries its own table of contents under the introduction. It is
   a block on the page's single left rail like every other block (see ONE
   ALIGNMENT PER CONTAINER), and the links wear the same pill shape as the
   answer choices in the cards below, so the menu reads as part of the
   instrument rather than as a second navigation bar competing with the site
   nav in the header. */
.qjump { margin: 20px 0 4px; padding: 14px 16px; background: var(--card-bg); border: 1px solid var(--line); border-radius: 12px; }
.qjump__h { margin: 0 0 10px; font-size: 0.78rem; font-weight: 700; letter-spacing: 0.07em; text-transform: uppercase; color: var(--muted); }
.qjump__list { display: flex; flex-wrap: wrap; gap: 8px; margin: 0; padding: 0; list-style: none; }
.qjump__list li { margin: 0; }
.qjump__list a {
  display: inline-flex; align-items: center; gap: 7px;
  border: 1px solid var(--line); border-radius: 999px; padding: 5px 13px;
  font-size: 0.9rem; text-decoration: none; color: var(--fg);
}
/* The pill wears the same mark as the heading it jumps to (2026-08-07), at
   pill size: 15px, the size the nav icons run at, with the margin dropped
   because the flex gap already spaces it. */
.qjump__list a .hicon { width: 15px; height: 15px; margin-right: 0; vertical-align: 0; }
.qjump__list a:hover .hicon, .qjump__list a:focus-visible .hicon { color: currentColor; }
.qjump__list a:hover, .qjump__list a:focus-visible { border-color: var(--cyan); color: var(--cyan); }
.qjump__n { color: var(--muted); font-size: 0.8rem; font-variant-numeric: tabular-nums; }
.qjump__list a:hover .qjump__n, .qjump__list a:focus-visible .qjump__n { color: inherit; }

/* ---------- evidence register ----------
   Each entry is long (evidence, reason kept, alternatives, risks, what it
   changes, review status), so entries are cards and the cards deal into two
   columns from 1100px up: one column of 60 hairline-separated blocks was the
   shape that read as a narrow site stretched wide. Entries stretch to their
   row's height for the same reason the question cards do: a short entry beside
   a long one used to leave a hole the size of the difference. */
.evdgrid { display: grid; grid-template-columns: 1fr; gap: 14px; }
@media (min-width: 1100px) { .evdgrid { grid-template-columns: repeat(2, 1fr); } }
.evd { background: var(--card-bg); border: 1px solid var(--line); border-radius: 12px; padding: 16px 18px; }
/* Entry titles are machine ids (chronic_institution_stays), which have no break
   opportunity: an auto-sized grid track would widen to fit one and push the
   page sideways at 320px. The id may break; the layout may not. */
.evd h2 { font-size: 1.05rem; margin-bottom: 8px; overflow-wrap: anywhere; }
/* Sensitivity mark (2026-08-07): a level, so it is drawn as a level. Colour is
   a second cue only, never the cue: the bar count carries it, which is what
   keeps it readable in colorblind mode and in print. */
.evd h2 > .hicon { width: 18px; height: 18px; margin-right: 7px; vertical-align: -3px; }
.evd h2 > .evd__sens--low { color: var(--muted); }
.evd h2 > .evd__sens--moderate { color: var(--warn-line); }
.evd h2 > .evd__sens--high { color: var(--err); }
.evd p { margin-bottom: 8px; }
.evd p:last-child { margin-bottom: 0; }

/* ---------- footer ---------- */
footer.site { border-top: 1px solid var(--line); padding: 22px 0 30px; margin-top: 26px; font-size: 0.85rem; color: var(--muted); }
footer.site nav { display: flex; gap: 18px; flex-wrap: wrap; margin-bottom: 8px; }
.ver { font-variant-numeric: tabular-nums; }

/* ---------- landing extras ---------- */
/* The headline is display type, so it is allowed the whole container; the lede
   is running text, so it takes the same measure and the same right edge as
   every other paragraph on the site. It used to stop at 760px, which is where
   the hero read as a narrow site inside a wide one. */
.hero { padding: 46px 0 20px; }
.hero h1 { font-size: clamp(1.7rem, 4.5vw, 2.4rem); max-width: none; }
.hero h1 em { color: var(--cyan); font-style: normal; }
.hero .lede { margin-top: 14px; max-width: var(--measure); color: var(--muted); font-size: 1.05rem; }
/* On a wide window the hero owns the whole first screen with nothing beside
   it, so the lede takes a step up in size rather than sitting as small text in
   a large space. The measure is fixed, so the line count drops instead. */
@media (min-width: 1100px) { .hero .lede { font-size: 1.06em; } }
.badge { display: inline-block; margin-top: 18px; padding: 6px 12px; border: 1px solid var(--line); border-radius: 999px; font-size: 0.85rem; color: var(--muted); background: var(--card-bg); }
.badge b { color: var(--accent-ink); font-weight: 650; }
/* Four outputs, four cards. One row on a desktop window, 2x2 on a tablet,
   stacked on a phone. */
.cardgrid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 14px; }
@media (min-width: 1100px) { .cardgrid { grid-template-columns: repeat(4, 1fr); } }
@media (max-width: 640px) { .cardgrid { grid-template-columns: 1fr; } }
.cardgrid .card { margin-bottom: 0; }
.cardgrid h3 { margin-top: 0; }
.cardgrid h3 .n { color: var(--accent-ink); margin-right: 8px; } /* accent-ink, not cyan: bold 15.7px text needs 4.5:1 and light cyan on a white card is 3.27:1 */
/* Point lists FLOW down two columns instead of dealing into a two-column grid.
   A grid puts each pair of bullets in a row as tall as the taller of the two,
   so a two-line point beside a five-line point left three blank lines under
   the short one and the column lost its rhythm: the gaps between bullets in
   one column were 10px, 60px, 20px, which reads as broken spacing rather than
   as a list. Flowing gives every bullet the same 12px below it, whatever sits
   in the other column. Reading order becomes down-then-across, which is what a
   column of independent claims wants anyway. */
.plist { list-style: none; padding: 0; }
@media (min-width: 900px) {
  .plist { columns: 2; column-gap: 34px; }
  /* Never split one point across the fold. */
  .plist li { break-inside: avoid; }
  /* A list of one is not a column of one: any single-item list
     entry would otherwise stack a long dot-separated run down half the width
     with the other half empty. */
  .plist:has(li:only-child) { columns: 1; }
}
/* Inside a two-column list the cell is already the measure; the prose cap
   would only re-introduce a ragged right edge cell by cell. */
.plist li { font-size: 0.95rem; padding-left: 20px; position: relative; max-width: none; margin-bottom: 12px; }
.plist li::before { content: "◆"; color: var(--cyan); position: absolute; left: 0; font-size: 0.7rem; top: 5px; }
/* Two claims that answer each other ("how it is built" / "on bias") read as a
   pair, so on a wide screen they sit as a pair instead of one under the other
   with half the row empty. Same two-column rhythm as .plist, same breakpoint. */
.gstate { display: grid; grid-template-columns: 1fr; gap: 10px 34px; align-items: start; }
@media (min-width: 900px) { .gstate { grid-template-columns: repeat(2, 1fr); } }
.gstate p { max-width: none; margin-bottom: 0; }
/* A phase row is a label and a sentence, so the sentence obeys the same
   measure as every other sentence: the row ends where the paragraphs above it
   end rather than running the full container. */
.phaserow { display: flex; gap: 12px; align-items: baseline; font-size: 0.95rem; margin-bottom: 10px; max-width: var(--measure); }
.phase { flex-shrink: 0; width: 84px; font-weight: 650; color: var(--accent-ink); font-size: 0.85rem; }

/* ---------- landing page structure (2026-08-27 restructure) ----------
   Every section on the front page used to carry the same inline
   style="padding: 26px 0; border-top: 1px solid var(--line);", copied six
   times, which is how the spacing drifted: two of them had a different
   padding and nobody could see it in the markup. One class, one rule. The
   hairline is the only divider the page uses; sections are told apart by
   what is inside them, not by boxes around them. */
.sect { padding: 30px 0; border-top: 1px solid var(--line); }
/* The strip under the hero belongs to the hero, so it does not get a rule of
   its own above it: it is the evidence for the sentence directly above. */
.factstrip { padding: 10px 0 4px; }

/* THE SIGNATURE LINE. It was the h1 for months, which cost the page its one
   chance to say what the product IS above the fold. Demoted to a line and
   promoted to a mark: it is the promise the whole page is arguing for, so it
   is set larger than body text and carries the brand rule beside it. The
   border sits inside the box, so the element's left edge is still the page
   rail (see tools/alignment-audit.mjs). */
.signature {
  margin-top: 18px; padding-left: 15px; border-left: 3px solid var(--cyan);
  font-size: clamp(1.05rem, 2vw, 1.3rem); font-weight: 650; line-height: 1.4;
  color: var(--fg); max-width: var(--measure);
}

/* FACTS ROW. Numbers are tabular so the row lines up as a row, and each one
   sits directly above the words that say what it counts: a number with its
   label beside it reads as a sentence fragment, a number with its label under
   it reads as a fact. Four across on a desktop window, two across on a
   tablet, stacked on a phone. */
.facts { list-style: none; padding: 0; margin: 0; display: grid; gap: 18px 26px; grid-template-columns: repeat(2, 1fr); }
@media (min-width: 900px) { .facts { grid-template-columns: repeat(4, 1fr); } }
@media (max-width: 460px) { .facts { grid-template-columns: 1fr; gap: 14px; } }
.fact { margin: 0; max-width: none; padding-top: 12px; border-top: 2px solid var(--line-strong); }
.fact__n { display: block; font-size: clamp(1.6rem, 3.4vw, 2.1rem); font-weight: 700; line-height: 1.1; color: var(--cyan); font-variant-numeric: tabular-nums; }
.fact__l { display: block; margin-top: 5px; color: var(--muted); font-size: 0.88rem; line-height: 1.4; }
/* The caption is a footnote to the strip, not a fifth cell: on a phone the
   whole strip is one column and without this it ran straight on from the last
   label as if it belonged to it. */
.factstrip > .help { margin-top: 16px; }

/* THE SAMPLE RESULT CARD. A quotation of the real output, so it is styled
   like the real output: the cyan top rule the results page uses for its own
   header card, the same label-then-value rows, the same chips. It is a
   snapshot in the HTML and the engine owns its values; landing.test.ts fails
   if the two ever disagree, which is the only reason a static copy of a
   computed thing is allowed to exist here. */
.scard { background: var(--card-bg); border: 1px solid var(--line); border-top: 4px solid var(--cyan); border-radius: 12px; padding: 18px 20px; }
.scard__top { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; flex-wrap: wrap; margin-bottom: 10px; }
.scard__tag { font-size: 0.72rem; letter-spacing: 0.08em; text-transform: uppercase; font-weight: 700; color: var(--accent-ink); }
.scard__meta { color: var(--muted); font-size: 0.8rem; }
.scard__lede { font-size: 1.08rem; font-weight: 650; line-height: 1.45; margin-bottom: 14px; max-width: none; }
.srows { margin: 0; }
.srow { display: grid; grid-template-columns: 1fr; gap: 2px; padding: 10px 0; border-top: 1px solid var(--line); }
@media (min-width: 760px) { .srow { grid-template-columns: 220px 1fr; gap: 4px 20px; align-items: baseline; } }
.srow dt { color: var(--muted); font-size: 0.86rem; }
.srow dd { margin: 0; font-size: 0.98rem; font-weight: 650; }
.schips { display: flex; flex-wrap: wrap; gap: 6px; font-weight: 400; }
.schip { border: 1px solid var(--line-strong); border-radius: 999px; padding: 3px 11px; font-size: 0.85rem; color: var(--fg); background: var(--bg); }
/* glossary.js wraps defined terms in a <button>, and a button is an atomic
   inline-block whatever its display is set to, with a break opportunity on
   each side. Inside a chip on a phone that put "(PSH" at the end of one line
   and "): discuss first" at the start of the next, because the abbreviation
   is a glossary term and the brackets around it are not. The abbreviation and
   its brackets are marked as one unbreakable run in the markup instead. */
.nb { white-space: nowrap; }
.scard__why { margin-top: 14px; padding-top: 10px; border-top: 1px dashed var(--line); color: var(--muted); font-size: 0.9rem; max-width: none; }
.scard__go { margin: 0; }

/* One concrete line per output card, set apart from the description above it
   so a reader can tell the claim from the example without reading both. */
.exline { margin: 10px 0 0; padding-top: 8px; border-top: 1px dashed var(--line); font-size: 0.88rem; color: var(--muted); }
/* Four descriptions of different lengths put four examples at four different
   heights, and the eye reads that as four unrelated cards rather than one row
   of four. The example is pinned to the foot of its card so the row has a
   second baseline as well as a first. */
.cardgrid .card { display: flex; flex-direction: column; }
.cardgrid .exline { margin-top: auto; }
.exline b { color: var(--fg); font-weight: 650; }

/* THE BOUNDARY, TWO COLUMNS. Not a grid of equal cells: the left column is
   what the tool does and the right is what it refuses to do, so they carry
   different rules and different accents. They stack on a phone with the
   accents intact, because the accent is the argument. */
.twocol { display: grid; grid-template-columns: 1fr; gap: 16px; margin: 4px 0 16px; }
@media (min-width: 860px) { .twocol { grid-template-columns: 1fr 1fr; gap: 26px; } }
.tside { padding: 14px 0 0; border-top: 3px solid var(--line-strong); }
.tside--heat { border-top-color: var(--cyan); }
.tside h3 { margin: 0 0 8px; font-size: 0.78rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }
.tside--heat h3 { color: var(--accent-ink); }
.tlist { list-style: none; padding: 0; margin: 0; }
.tlist li { position: relative; padding-left: 20px; margin-bottom: 9px; font-size: 0.94rem; max-width: none; }
.tlist li::before { content: "◆"; position: absolute; left: 0; top: 4px; font-size: 0.62rem; color: var(--line-strong); }
.tside--heat .tlist li::before { color: var(--cyan); }

/* The four elevated claims are the same .plist as everywhere else, given room
   to be read: a two-column list of four points wants more air between the
   points than a list of six does. */
@media (min-width: 900px) { .plist--four li { margin-bottom: 16px; } }
.morelist { margin-top: 14px; padding-top: 12px; border-top: 1px dashed var(--line); }

/* The participant card is the one block on the page addressed to the person
   answering the questions rather than to the people running the assessment,
   so it is quieter: the safe-green top rule the results page gives their own
   copy of the record, and no cyan anywhere. */
.calmcard { border-top: 4px solid var(--ok); margin-bottom: 0; }
.calmcard h2 { margin-top: 0; }
/* A footnote to the section, not a section of its own. It carried a dashed
   rule for a moment: a rule that stops at the reading measure under a callout
   that spans the container reads as a line someone forgot to finish. Space
   does the same job and cannot be ragged. */
.roadline { margin-top: 22px; }

/* ---------- media ---------- */
@media (prefers-contrast: more) {
  .card, .radio, .textinput, .seg, .cbtoggle { border-width: 3px; }
}
@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
}
@media print {
  /* ---------- PAPER IS ALWAYS LIGHT (2026-08-07) ----------
     Every colour on this site comes from html[data-theme], and printing did
     not change it: a record printed from dark mode carried the dark palette
     onto the page. Body text was forced to #000 while the cards under it kept
     background: var(--card-bg), so the participant card's three zones printed
     black on near-black, the beta notice printed the same way, and every
     determination chip (var(--accent-ink), #4fd6ff in dark) came out at about
     1.6:1 on white once the browser dropped backgrounds, which it does by
     default. The handed-over page is the product, so the light palette is
     forced here for every theme and every colour-vision setting. The selector
     carries two attributes so it outranks html[data-vision][data-theme] above.
     Values are the light theme's, with paper-grade ink: white card, darker
     muted text and lines, because toner is not a screen. */
  html, html[data-theme][data-vision] {
    /* Native controls follow color-scheme, so the order-sheet checkboxes
       printed as solid dark squares (nothing to tick with a pen) whenever the
       reader was in dark mode. */
    color-scheme: light;
    --cyan: #0099CC;
    --accent-ink: #006487;
    --fg: #1a1a1a; --muted: #3f3f3f; --bg: #ffffff; --card-bg: #ffffff;
    --line: #999999; --line-strong: #555555;
    --err: #a4123c; --ok: #16643a;
    --warn-bg: #ffffff; --warn-line: #7a6420; --warn-ink: #6b5510;
    --btn-ink: #06222c;
  }
  .noprint, header.site, .topbanner, footer.site, .prefs, .flagline, .flagfab { display: none !important; }
  body { background: #fff; color: #000; padding-bottom: 0; }
  .card { border: 1px solid #999; }
  /* A checkable order, a zone or a determination row split across a page break
     is a line a worker has to reassemble by hand. Cards are deliberately NOT
     in this list: the audit trail is longer than a page and must be allowed to
     break. */
  .orders li, .zone, .arow, .opt, .sbar__h, .iaband { break-inside: avoid; }
  .sbar__h, .ordergroup { break-after: avoid; }
  /* A citation on paper is only a citation if the address is on the paper. */
  .steps a[href^="http"]::after {
    content: " (" attr(href) ")";
    font-size: 0.82em; word-break: break-all; color: #000;
  }
}

/* Quick exit (safety affordance) */
.quickexit {
  position: fixed; right: 16px; bottom: 16px; z-index: 60;
  display: inline-flex; align-items: center; gap: 8px;
  padding: 10px 16px; min-height: 44px;
  background: var(--card-bg); color: var(--fg);
  border: 1px solid var(--line-strong, var(--line)); border-radius: 8px;
  font: inherit; font-weight: 600; cursor: pointer;
}
/* The door-and-arrow mark carries the same weight as the words: this button
   is found under pressure, so it must be recognisable before it is read. */
.quickexit .radio__icon { color: inherit; }
.quickexit .radio__icon svg { width: 17px; height: 17px; }
.quickexit:hover, .quickexit:focus-visible { border-color: var(--cyan); }

/* Brand mark + section icons + back-to-top (2026 polish pass) */
.brandmark { display: inline-flex; align-items: center; gap: 8px; }
.brandmark .mark { width: 24px; height: 24px; color: var(--cyan); flex: none; }
.hicon { width: 20px; height: 20px; color: var(--cyan); vertical-align: -4px; margin-right: 8px; flex: none; }
h2 > .hicon { width: 22px; height: 22px; }
.card h3 .hicon { margin-right: 6px; }
.backtop {
  position: fixed; right: 16px; bottom: 16px; z-index: 55;
  width: 44px; height: 44px; border-radius: 50%;
  display: none; align-items: center; justify-content: center;
  background: var(--card-bg); color: var(--fg);
  border: 1px solid var(--line-strong, var(--line)); cursor: pointer;
}
/* Only the assessment has the "Leave quickly" button; lift back-to-top above
   it there. Everywhere else it sits even with the Feedback button (flag #69). */
body:has(.quickexit) .backtop { bottom: 76px; }
.backtop.show { display: inline-flex; }
.backtop:hover, .backtop:focus-visible { border-color: var(--cyan); color: var(--cyan); }
@media print { .backtop { display: none !important; } }

/* Results view toggle + upgraded client card */
.viewseg { padding: 14px 16px; }
.viewseg__row { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 8px; }
.viewbtn {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 10px 16px; min-height: 44px; font: inherit; font-weight: 600;
  background: transparent; color: var(--muted);
  border: 1px solid var(--line-strong, var(--line)); border-radius: 999px; cursor: pointer;
}
.viewbtn .hicon { width: 18px; height: 18px; margin-right: 0; color: currentColor; vertical-align: -3px; }
.viewbtn.active { color: var(--fg); border-color: var(--cyan); background: color-mix(in srgb, var(--cyan) 12%, transparent); }
.viewbtn:hover { border-color: var(--cyan); }
.youcard { border-left: 4px solid var(--cyan); }
.youcard > h1 { font-size: 1.35rem; }
.youcard h2 { display: flex; align-items: center; margin-top: 18px; }
.youcard h2 .hicon { width: 19px; height: 19px; }
.card > h2 { display: flex; align-items: center; }

/* Status band tiers (green all-clear reserved for people not in a housing crisis) */
.iaband--crisis { border-color: var(--err); color: var(--err); background: color-mix(in srgb, var(--err) 9%, transparent); }
.iaband--crisis::before { content: "!"; font-weight: 800; }
.iaband--caution { border-color: var(--warn-line); color: var(--fg); background: var(--warn-bg); }
.iaband--caution::before { content: "▲"; color: var(--warn-line); font-weight: 800; }
.iaband__sub { flex-basis: 100%; margin: 4px 0 0; font-size: 0.88rem; color: var(--muted); }

/* Exception-only emergency card */
.alertcard { border-color: var(--err) !important; border-width: 2px; }
.alertcard > h2 { color: var(--err); }
.alertcard > h2 .hicon { color: var(--err); }

/* Collapsible record drawers + iconed flag pills (consolidation pass) */
.dcard { padding: 0; }
.dcard > summary {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 14px 16px; cursor: pointer; list-style: none;
}
.dcard > summary::-webkit-details-marker { display: none; }
/* The chevron belongs to the title row. It is the last child of a wrapping
   flex row whose hint takes a full line, so without an explicit order it fell
   through to the hint's line and floated alone in the middle of the card. */
.dcard > summary::after {
  content: ""; margin-left: auto; width: 9px; height: 9px; flex: none;
  border-right: 2px solid var(--muted); border-bottom: 2px solid var(--muted);
  transform: rotate(45deg); transition: transform .15s;
  order: 1; align-self: center;
}
.dcard > summary .dhint { order: 2; }
.dcard[open] > summary::after { transform: rotate(225deg); }
.dcard > summary h2 { margin: 0; font-size: 1.02rem; display: flex; align-items: center; }
.dcard > summary:hover h2 { color: var(--cyan); }
.dcard__body { padding: 0 16px 14px; }
/* Evidence-quality line under a drawer verdict. Quiet by design: it qualifies
   the record, never competes with it, and never reads as doubt about anyone. */
.confline { margin: 0 0 10px; padding-left: 9px; border-left: 2px solid var(--line); font-size: 0.86rem; }
.flagchip { display: inline-flex; align-items: center; gap: 6px; }
.flagchip .hicon { width: 15px; height: 15px; margin-right: 0; color: currentColor; vertical-align: -2px; }
.flagchip--info { border-color: var(--cyan); color: var(--cyan); }
.flagchip--warnc { border-color: var(--warn-line); color: var(--fg); background: var(--warn-bg); }
.flagchip--warnc .hicon { color: var(--warn-line); }
@media print { .dcard { display: block; } .dcard:not([open]) > .dcard__body { display: block; } .dcard > summary::after { display: none; } }

/* Action-plan order sheet, documentation card and open questions used to
   carry three hand-placed left accents in three different colours. They now
   take them from the ONE wayfinding family system at the foot of this file
   (.wf--plan / .wf--doc / .wf--data), so the colours are declared together
   and a section cannot quietly acquire a fifth one. */
.openq ul { margin: 6px 0 0; padding-left: 20px; }
.openq li { margin: 3px 0; }
.orders { list-style: none; padding: 0; margin: 8px 0 4px; }
/* The row rule separates rows, so it spans the card; the order text inside it
   keeps the reading measure. Capping the row itself stopped every dashed rule
   140px short of the card edge for no reason a reader could see. */
.orders li { margin: 0; border-bottom: 1px dashed var(--line); max-width: none; }
.orders li:last-child { border-bottom: 0; }
.orders label { display: flex; gap: 10px; align-items: flex-start; padding: 9px 2px; cursor: pointer; line-height: 1.45; max-width: var(--measure); }
.orders input[type="checkbox"] { width: 18px; height: 18px; margin-top: 2px; flex: none; accent-color: var(--cyan); }
.orders input[type="checkbox"]:checked + * , .orders label:has(input:checked) { color: var(--muted); }
.orders label:has(input:checked) { text-decoration: line-through; text-decoration-color: var(--line-strong, var(--line)); }

/* Safety STOP interstitial */
.stopcard { text-align: left; }
.stopcard h1 { color: var(--err); margin-top: 0; }
.stopbig { font-size: 1.15rem; font-weight: 600; line-height: 1.5; }
a.stopcall, .stopcall { display: block; text-align: center; background: var(--err); border-color: var(--err); color: #fff; margin: 14px 0 10px; font-size: 1.1rem; }
.stopcall:hover { filter: brightness(1.1); }
.stopcard .secondary { display: block; width: 100%; margin-top: 8px; }
.dangerstrip { margin-bottom: 12px; }

/* Stop-after-diversion offer: the same full-screen interrupt as the safety
   stop, in the brand accent instead of the alert colour. Finding a safe place
   tonight is good news; it must never look like an emergency. */
.divertcard { border-color: var(--cyan); border-width: 2px; text-align: left; }
.divertcard h1 { margin-top: 0; }

/* In-their-own-words note */
.notebox { width: 100%; font: inherit; padding: 10px 12px; border-radius: 8px; border: 1px solid var(--line-strong, var(--line)); background: transparent; color: var(--fg); margin: 6px 0 10px; resize: vertical; }
.notebox:focus-visible { outline: 2px solid var(--cyan); outline-offset: 1px; }
.ownwords { font-style: italic; border-left: 3px solid var(--cyan); padding-left: 12px; }

/* Assessor judgment: the case-conference escalation marker. A plain checkbox
   row, deliberately unlike the radio rows above it, because it is a separate
   decision and not a sixth reason. */
.jflag { display: flex; align-items: center; gap: 10px; min-height: 44px; cursor: pointer; margin: 2px 0 8px; }
.jflag input { width: 20px; height: 20px; flex: none; accent-color: var(--cyan); }

/* Order groups, fine print */
.ordergroup { margin: 10px 0 2px; font-size: 0.8rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; color: var(--cyan); }
/* TODAY is the one thing a worker with 17 people waiting must not miss */
.ordergroup--today { display: inline-block; background: var(--cyan); color: var(--btn-ink); padding: 2px 10px; border-radius: 999px; }
/* Browsers drop backgrounds when printing: keep the chip legible on paper */
@media print { .ordergroup--today { background: transparent; color: #000; border: 1px solid #000; } }
.fine { font-size: 0.75rem; color: var(--muted); margin-top: 6px; }
.arow__name { display: inline-flex; align-items: center; }
.arow__name .hicon { width: 17px; height: 17px; }

/* Drawer hints */
.dhint { flex-basis: 100%; font-size: 0.84rem; color: var(--muted); font-weight: 400; }

/* "Want more detail?" divider between working mode and the collapsed depth */
.morehead { margin: 26px 0 4px; padding-top: 18px; border-top: 1px solid var(--line); }
.morehead h2 { margin: 0 0 4px; font-size: 1.05rem; }
.morehead .help { margin: 0; }

/* Sample switcher: the four personas as one row of pills above the result,
   reusing the view-toggle pill buttons. It is the only way between the four,
   so it leads the page and never scrolls out of reach. */
/* Smaller than the view toggle, but never below the 44px touch target */
.sampleswitch .viewbtn { padding: 8px 14px; font-size: 0.9rem; }
.sampleswitch .help { margin: 0 0 4px; }
.sampleswitch .viewbtn .hicon { width: 17px; height: 17px; }

/* ---------- wide-screen results layout ----------
   Results run in the full 1080px container. Two things went wrong there:
   anything with a width cap sat hard against the left edge of a 1120px card
   with a river of dead space beside it, and the Assessment section read as
   stacked paragraphs when it is really three or four separate determinations.
   Rules below fix exactly those two things. Running prose is never centered:
   a centered paragraph has a ragged left edge and is harder to read, so the
   Situation, Background and Next-steps text keeps its left rail. */

/* ---------- ONE ALIGNMENT PER CONTAINER ----------
   Within any card or section, every piece of content shares ONE flow, and the
   default flow is LEFT. Prose, lists, fine print and any button that shares a
   card with them all start on the same left rail. Buttons keep the 560px cap
   (a full-bleed button on a 1120px card reads as a banner rather than as a
   control) but they are NOT centred: a centred button between a left-aligned
   paragraph and a left-aligned footnote is three alignments in one card, which
   the eye reads as broken without being able to name why. That is the defect
   this section removes, and it removes it at the source rather than card by
   card.

   CENTRED flow exists only where an ENTIRE group centres as a unit, opted into
   explicitly with .cgroup. Exactly two places qualify: the end-of-page actions
   card (print / download / start over / feedback, which carries no prose) and
   the sample banner's call to action with its back link. Adding .cgroup
   anywhere a paragraph lives re-creates the defect.

   tools/alignment-audit.mjs enforces this mechanically. Run it before any UI
   release; it fails on any container that mixes centred and left children. */
.cgroup { text-align: center; }
/* Children with a width cap centre themselves; full-width children are unmoved. */
.cgroup > * { margin-left: auto; margin-right: auto; }
/* The feedback line is a control, not a sentence, so inside a centred group it
   follows the group and drops the prose measure in order to centre on the card
   rather than on an invisible left-hand text column. Everywhere else, including
   every question screen and every card with prose in it, it stays left. */
.cgroup .flagline { justify-content: center; max-width: none; }

@media screen and (min-width: 1000px) {
  /* ASSESSMENT: one small card per determination, side by side. 280px is the
     track floor because it holds three columns at every width from the 1000px
     breakpoint up (three fills a row; a fourth starts the next row at the same
     width) and never lets a fourth column open at 1080px. The card is now the
     measure, so the meaning line drops the prose measure inside it; outside
     these cards the cap is untouched. */
  html[data-heat-item="results"] .sbar--assess,
  html[data-heat-item="sample"] .sbar--assess {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: 12px;
  }
  html[data-heat-item="results"] .sbar--assess > .sbar__h,
  html[data-heat-item="sample"] .sbar--assess > .sbar__h { grid-column: 1 / -1; }
  html[data-heat-item="results"] .sbar--assess .arow,
  html[data-heat-item="sample"] .sbar--assess .arow {
    margin-bottom: 0;
    border: 1px solid var(--line); border-radius: 10px;
    padding: 14px; background: var(--bg);
  }
  /* The chip drops below the name inside its own card: at a third of the width
     a name and a chip on one line wrap into an awkward two-line head. */
  html[data-heat-item="results"] .sbar--assess .arow__head,
  html[data-heat-item="sample"] .sbar--assess .arow__head {
    flex-direction: column; align-items: flex-start; gap: 6px; margin-bottom: 6px;
  }
  html[data-heat-item="results"] .sbar--assess .arow .help,
  html[data-heat-item="sample"] .sbar--assess .arow .help { max-width: none; }
  /* A third of the row is narrower than some value labels, so the pill tightens
     to keep the common ones on one line. The longest still wrap to two lines,
     which is why the chip sits on its own row rather than beside the name. */
  html[data-heat-item="results"] .sbar--assess .arow .chip,
  html[data-heat-item="sample"] .sbar--assess .arow .chip { font-size: 0.83rem; padding: 4px 11px; }

  /* CLIENT VIEW: green / yellow / red read as three parallel states, so they
     sit as three columns rather than three stacked strips with dead space. */
  html[data-heat-item="results"] .zones,
  html[data-heat-item="sample"] .zones { grid-template-columns: repeat(3, 1fr); gap: 12px; }
  html[data-heat-item="results"] .zone,
  html[data-heat-item="sample"] .zone { max-width: none; }
}
/* Print is deliberately excluded above (@media screen): paper is one narrow
   column, where the stacked original is the right shape. */

/* ---------- STATUS COLOUR: THE STATE OF THE RECORD, NEVER A RANK ----------
   Owner design, 2026-08-28. Every colour on the worker result describes what
   condition the RECORD is in, the way a lab report flags a specimen. None of
   it ranks the person, and none of it may be read as a score.

   THE FOUR FAMILIES, and the one thing each of them says:

     red    (--err)        something is unsafe right now. Act.
     amber  (--warn-line)  the record needs a second look before it is trusted.
     green  (--ok)         this is settled, or this is what to DO next.
     cyan   (--cyan)       this is a stated fact or determination. Read it.

   THE HARD CONSTRAINT. A determination about a person (the HUD homeless
   category, the chronic-homelessness status, the support-planning band) gets
   ONE treatment for EVERY one of its values. Not one colour for "meets" and a
   quieter one for "does not meet": that is a ranking drawn in colour, and a
   reader learns the ranking long before they read the words. The chip kind for
   all three families is a single constant in app.ts (DETERMINATION_CHIP), and
   packages/test-scenarios/src/statusColors.test.ts fails the build if any
   value-dependent expression ever appears in its place.

   AMBER MAY NEVER TOUCH A DETERMINATION CHIP. Amber means "worker: look
   closer at this record". Put it on a person's category and it becomes
   "look closer at this person", which is the whole thing this system exists
   to prevent. Amber lives on documentation, on conflicting answers, on
   confidence, and on completeness: states of the paperwork, not of anyone.

   NOTHING HERE IS COLOUR-ONLY. Every state below carries a glyph AND a word.
   The two marks are the ones this design system already used: the caution
   triangle from .iaband--caution and the tick from .chip.ok. */

/* THE WAYFINDING ACCENT. One 4px rule down the left edge of a section, in its
   family's colour, plus the section's own icon in the same colour. It answers
   "what kind of thing am I looking at" before a word is read, which is the
   only job it has: it is not decoration and it never carries meaning alone,
   because the heading beside it says the same thing in words.

   The 4px is taken back out of the card's own left padding, so a section with
   an accent and a section without one still start their TEXT on the same rail.
   Without that, the accent quietly created a second left edge on the page,
   which is the exact defect tools/alignment-audit.mjs exists to catch. */
.wf { border-left: 4px solid var(--line-strong, var(--line)); padding-left: 16px; }
.wf.dcard { padding-left: 0; }
.wf.dcard > summary, .wf.dcard > .dcard__body { padding-left: 12px; }
.wf--safety { border-left-color: var(--err); }
.wf--doc,
.wf--data { border-left-color: var(--warn-line); }
.wf--plan { border-left-color: var(--ok); }
.wf--facts { border-left-color: var(--cyan); }
/* The family travels to the heading through the icon that is already there,
   rather than through a second rule under the title: one more line per card
   would turn wayfinding into ornament. Drawers are matched to plain cards. */
.wf--safety > h2 .hicon, .wf--safety > summary h2 .hicon { color: var(--err); }
.wf--doc > h2 .hicon, .wf--doc > summary h2 .hicon,
.wf--data > h2 .hicon, .wf--data > summary h2 .hicon { color: var(--warn-line); }
.wf--plan > h2 .hicon, .wf--plan > summary h2 .hicon { color: var(--ok); }
.wf--facts > h2 .hicon, .wf--facts > summary h2 .hicon { color: var(--cyan); }

/* AMBER CHIP. The completeness state of the record, and nothing else, ever.
   Text stays --fg: --warn-line is a rule and a glyph colour, not an ink
   (#d9b96a on white is 1.8:1), which is the same split .iaband--caution and
   .flagchip--warnc already make. */
.chip.flagged { color: var(--fg); border-color: var(--warn-line); background: var(--warn-bg); }
.chip.flagged::before { content: "\25B2"; color: var(--warn-ink); }

/* AMBER NOTE. A quiet flag pinned to a line of the record: conflicting
   answers, and the confidence line under a drawer verdict when it is anything
   short of high. Deliberately NOT .fielderror, which is red and belongs to a
   person's own form input being wrong. Nothing here is anyone's mistake. */
.dqflag {
  margin: 0 0 10px; padding: 7px 11px;
  border-left: 3px solid var(--warn-line); border-radius: 0 6px 6px 0;
  background: var(--warn-bg); font-size: 0.9rem;
}
/* margin, not a space inside content(): a trailing space in generated
   content collapses at the start of a line and the mark ran into the
   first word. */
.dqflag::before { content: "\25B2"; margin-right: 7px; color: var(--warn-ink); font-weight: 800; }
/* The confidence line keeps its own quiet shape and only changes family, so a
   drawer that gains a flag does not also gain a box. */
.confline--flag {
  border-left-color: var(--warn-line); border-left-width: 3px;
  background: var(--warn-bg); padding: 6px 10px; border-radius: 0 6px 6px 0;
}
.confline--flag::before { content: "\25B2"; margin-right: 7px; color: var(--warn-ink); font-weight: 800; }
@media print { .dqflag, .confline--flag { border-left-color: #7a6420; } }

/* DOCUMENTATION AS LAB FLAGS. The checklist the engine produces has exactly
   one state per item: needed. There is no "collected" field on it, no store,
   and nothing that could honestly report one, so nothing here invents a third
   state. What DOES exist is the worker's own tick on their own working copy,
   and that is what the green treatment reports: not "the system has this
   document" but "I have it in hand". The checkbox stays a real checkbox so the
   printed sheet is still tickable with a pen.

   Both words live in the markup and CSS shows one of them, so the state is
   readable with colour off, with CSS images off, and by a screen reader (the
   inactive word is display:none, which takes it out of the a11y tree too). */
.doclist .docflag {
  display: inline-flex; align-items: center; gap: 5px; flex: none;
  min-width: 6.4em; font-size: 0.74rem; font-weight: 700;
  letter-spacing: 0.05em; text-transform: uppercase;
}
.doclist .docflag--inhand { display: none; }
.doclist label:has(input:checked) .docflag--needed { display: none; }
.doclist label:has(input:checked) .docflag--inhand { display: inline-flex; }
.doclist .docflag--needed { color: var(--fg); }
.doclist .docflag--needed::before { content: "\25B2"; color: var(--warn-ink); }
.doclist .docflag--inhand { color: var(--ok); }
.doclist .docflag--inhand::before { content: "\2713"; }
/* On a phone the flag and the document were competing for one line and the
   flag won: a 6.4em status column left the longest checklist item running down
   a third of the width in nine ragged lines. Below 560px the flag rides ABOVE
   the text it describes instead, indented to clear the checkbox, so the
   document keeps the whole column and the status still reads first. */
@media (max-width: 560px) {
  .doclist label { flex-wrap: wrap; }
  .doclist .docflag { min-width: 0; }
  .doclist .ordertext { flex-basis: 100%; padding-left: 28px; }
}

/* .orders strikes a whole ticked row through. Left alone that draws a line
   across "IN HAND", which reads as the opposite of what the words say, so the
   rule moves off the row and onto the document text, which is the part
   actually being struck off the list. (An inline-flex box is atomic
   inline-level and the spec does not propagate decoration into one; Chrome
   paints through it anyway, so this is done in the cascade, not in a display
   value.) */
.doclist label:has(input:checked) { text-decoration: none; }
.doclist label:has(input:checked) .ordertext {
  text-decoration: line-through; text-decoration-color: var(--line-strong, var(--line));
}

/* ---- Public comment register (/register, 2026-08-05) ----------------
   Proposed changes go up here before anything is decided. Cards carry the
   vote tally so the page reads as a tally, not a suggestion box. */
.rg-list { list-style: none; padding: 0; margin: 20px 0 0; display: grid; gap: 14px; }
.rg-card { border: 1px solid var(--line); border-radius: 12px; padding: 16px 18px; background: var(--card-bg, transparent); }
.rg-card--detail { margin-bottom: 22px; }
.rg-card-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 8px; }
.rg-chip { display: inline-flex; align-items: center; gap: 5px;
  font-size: 12px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  padding: 3px 9px; border-radius: 999px; border: 1px solid var(--line); color: var(--muted); }
.rg-chip .picon { width: 13px; height: 13px; }
/* var(--ok), not a raw hex: green means "this is settled" everywhere else
   in the system, and a hand-placed #1f7a4d followed neither the dark theme
   nor the colour-vision variant. "Adopted" is exactly what settled means. */
.rg-chip--adopted { color: var(--ok); border-color: var(--ok); }
.rg-chip--declined { color: var(--muted); border-style: dashed; }
.rg-ref { font-size: 12px; color: var(--muted); }
.rg-title { font-size: 19px; line-height: 1.3; margin: 0 0 6px; }
.rg-title a { text-decoration: none; }
.rg-title a:hover, .rg-title a:focus-visible { text-decoration: underline; }
.rg-body { margin: 0 0 10px; }
.rg-current { margin: 0 0 10px; padding: 10px 12px; border-left: 3px solid var(--line);
  background: rgba(127,127,127,.06); font-size: 15px; }
.rg-current span { display: block; font-size: 12px; text-transform: uppercase;
  letter-spacing: .05em; color: var(--muted); margin-bottom: 3px; }
.rg-decision { margin: 0 0 10px; }
.rg-credit { margin: 0 0 10px; color: var(--muted); font-size: 14px; }
.rg-foot { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.rg-votes { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
/* 44px targets: this is voted on from a phone. */
.rg-vote { display: inline-flex; align-items: center; gap: 8px; min-height: 44px; padding: 8px 14px;
  border: 1px solid var(--line); border-radius: 999px; background: none; color: inherit;
  font: inherit; font-weight: 600; cursor: pointer; text-align: left; }
.rg-vote svg { width: 16px; height: 16px; flex: none; }
/* The label is the control now (the arrow was a shape a reader had to
   translate, on a page whose whole subject is wording), so it never wraps to
   a second line inside a pill. */
.rg-vote-label { white-space: nowrap; }
.rg-vote .rg-count { padding-left: 8px; margin-left: 2px; border-left: 1px solid var(--line);
  color: var(--muted); font-weight: 700; }
.rg-vote.is-on .rg-count { color: inherit; }
.rg-vote--yes.is-on { color: var(--ok); }
.rg-vote--no.is-on { color: var(--err); }
.rg-vote-hint { font-size: 13px; color: var(--muted); }
.rg-vote:hover, .rg-vote:focus-visible { border-color: currentColor; }
.rg-vote.is-on { border-color: currentColor; box-shadow: inset 0 0 0 1px currentColor; }
.rg-count { font-variant-numeric: tabular-nums; }
.rg-comments { text-decoration: none; font-weight: 600; }
.rg-back { margin: 16px 0 4px; }
.rg-h3 { margin: 22px 0 10px; font-size: 17px; }
.rg-comments-list { list-style: none; padding: 0; margin: 0 0 22px; display: grid; gap: 10px; }
.rg-comment { border: 1px solid var(--line); border-radius: 10px; padding: 12px 14px; }
.rg-comment p { margin: 0; }
.rg-when { margin-top: 6px !important; font-size: 12px; color: var(--muted); }
.rg-form { border-top: 1px solid var(--line); padding-top: 16px; }
.rg-label { display: block; font-weight: 700; margin-bottom: 4px; }
.rg-label--sm { margin-top: 14px; font-size: 14px; }
.rg-form textarea, .rg-form input[type=text] { width: 100%; box-sizing: border-box; padding: 10px 12px;
  border: 1px solid var(--line); border-radius: 8px; background: transparent; color: inherit; font: inherit; }
.rg-actions { display: flex; align-items: center; gap: 12px; margin-top: 12px; flex-wrap: wrap; }
.rg-status { color: var(--muted); font-size: 14px; }
.rg-consent { margin-top: 16px; padding: 12px 14px; border: 1px solid var(--line); border-radius: 10px; }
.rg-check { display: flex; align-items: flex-start; gap: 10px; font-weight: 700; cursor: pointer; }
/* 20px box, not the 13px default: this is a consent control and it has to be
   easy to hit and easy to see the state of. */
.rg-check input { width: 20px; height: 20px; margin: 1px 0 0; flex: 0 0 auto; }
.rg-consent .help { margin: 8px 0 0; }
.rg-consent input[type=text][disabled] { opacity: .55; cursor: not-allowed; }
.rg-callout { display: flex; align-items: center; gap: 16px; padding: 16px 18px;
  border: 1px solid var(--line); border-radius: 12px; text-decoration: none; color: inherit; }
.rg-callout:hover, .rg-callout:focus-visible { border-color: currentColor; }
.rg-callout-icon { flex: 0 0 auto; display: inline-flex; }
.rg-callout-icon svg { width: 26px; height: 26px; }
.rg-callout-text { display: block; }
.rg-callout-text strong { display: block; margin-bottom: 2px; }
.rg-callout-text .help { margin: 0; }
.rg-callout-go { margin-left: auto; flex: 0 0 auto; font-size: 20px; }
@media (max-width: 560px) { .rg-callout-go { display: none; } }

/* Assessment block on a register proposal (2026-08-05). Collapsed in the
   list so the cards stay scannable, open on the detail page where someone
   has come to actually weigh it up. */
.rg-analysis { margin: 0 0 12px; border: 1px solid var(--line); border-radius: 10px; overflow: hidden; }
.rg-analysis > summary { display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 10px 12px; cursor: pointer; font-weight: 600; list-style: revert; }
.rg-an-tag { display: inline-flex; align-items: center; gap: 5px; flex: none;
  font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  padding: 2px 8px; border-radius: 999px; border: 1px solid var(--line); color: var(--muted); }
.rg-an-tag .picon { width: 12px; height: 12px; }
.rg-an-verdict { font-weight: 700; }
.rg-an-body { padding: 0 12px 12px; }
.rg-an-summary { margin: 0 0 12px; }
.rg-an-cols { display: grid; gap: 14px; }
@media (min-width: 720px) { .rg-an-cols { grid-template-columns: 1fr 1fr; } }
.rg-an-h { margin: 0 0 6px; font-size: 13px; text-transform: uppercase; letter-spacing: .05em; }
.rg-an-h.is-for { color: #1f7a4d; }
.rg-an-h.is-against { color: #a4432f; }
.rg-an-cols ul { margin: 0; padding-left: 18px; }
.rg-an-cols li { margin-bottom: 6px; }
.rg-an-note { margin: 14px 0 0; padding: 10px 12px; border-left: 3px solid var(--line);
  background: rgba(127,127,127,.06); }
.rg-an-caveat { margin: 12px 0 0; font-size: 13px; color: var(--muted); }
/* Change-control class (2026-08-07). Sits with the verdict because the two
   answer different questions: the verdict is whether the idea is right, the
   class is how carefully it would have to be made. */
.rg-an-class { margin-left: auto; font-size: 11px; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; padding: 2px 8px; border-radius: 999px;
  border: 1px dashed var(--line); color: var(--muted); }
.rg-an-classnote { margin: 12px 0 0; padding: 10px 12px; border-left: 3px solid var(--line);
  background: rgba(127,127,127,.06); font-size: 14px; }

/* Register page intro (2026-08-07). The page asked people to vote without ever
   saying what a vote does, so the explanation is now part of the page rather
   than something a reader is expected to infer. */
.rg-sec { padding: 18px 0 0; }
.rg-sech { font-size: 19px; margin: 0 0 8px; }
.rg-sech .hicon { width: 20px; height: 20px; }
.rg-steps { margin: 0; padding-left: 22px; max-width: var(--measure); }
.rg-steps li { margin-bottom: 8px; }
