/* 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. */

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;
  --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;
  --btn-ink: #06222c;
}
html[data-vision="colorblind"][data-theme="light"] {
  --cyan: #0072B2; --accent-ink: #005a8e;
  --err: #B24A00; --ok: #007a5e;
  --btn-ink: #ffffff;
}
html[data-vision="colorblind"][data-theme="dark"] {
  --cyan: #56B4E9; --accent-ink: #7cc4ee;
  --err: #E69F00; --ok: #66c2a4;
}

/* ---------- 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 ---------- */
.topbanner { background: var(--warn-bg); border-bottom: 1px solid var(--warn-line); padding: 8px 0; font-size: 0.88rem; }
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; }
/* 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; }
/* 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%);
}
.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; }
.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; }
.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; }
.iaband--ok { border-color: var(--ok); color: var(--ok); background: color-mix(in srgb, var(--ok) 8%, transparent); }
.iaband--ok::before { content: "✓"; font-weight: 800; }
.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); }
.youcard h3 { 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); }

/* ---------- glossary tooltips ---------- */
button.gloss {
  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 { border-bottom-style: solid; color: var(--accent-ink); }
.glosstip {
  position: absolute; z-index: 950; max-width: 320px;
  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 8px 24px rgba(0, 0, 0, 0.3);
}
@media print { button.gloss { border-bottom: none; } .glosstip { 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: baseline; gap: 7px;
  border: 1px solid var(--line); border-radius: 999px; padding: 5px 13px;
  font-size: 0.9rem; text-decoration: none; color: var(--fg);
}
.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; }
.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(--cyan); margin-right: 8px; }
/* 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; }

/* ---------- 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 {
  .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; }
}

/* 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 > h2 { font-size: 1.35rem; }
.youcard h3 { display: flex; align-items: center; margin-top: 18px; }
.youcard h3 .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--neutral { border-color: var(--line-strong, var(--line)); color: var(--muted); }
.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 (case-manager action layer) */
.ordersheet { border-left: 4px solid var(--cyan); }
/* Documentation card: a distinct accent so it never reads as more of the plan */
.doccard { border-left: 4px solid var(--warn-line); }
/* Open questions (decision blockers) sit between documentation and the depth */
.openq { border-left: 4px solid var(--line-strong, var(--line)); }
.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. */

/* ============================================================
   HMISForms additions (form renderer). Base chrome above is the
   ported HEAT stylesheet; do not fork shared chrome rules. */
.formhead h1 { margin: 8px 0 2px; }
.formsub { color: var(--muted); margin: 0 0 12px; font-size: 1.05rem; }
.statusbanner { display: inline-block; font-size: 0.78rem; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; padding: 3px 10px; border-radius: 999px; border: 1px solid var(--line-strong); color: var(--muted); }
.statusbanner--draft { border-color: var(--warn-line); color: var(--fg); background: var(--warn-bg); }
.formmeta { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 8px 20px; margin: 12px 0; padding: 0; }
.formmeta div { display: flex; gap: 8px; align-items: baseline; }
.formmeta dt { font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--muted); margin: 0; white-space: nowrap; }
.formmeta dd { margin: 0; font-size: 0.92rem; }
.formactions { display: flex; gap: 10px; flex-wrap: wrap; margin: 12px 0 4px; }
.sectitle { border-bottom: 2px solid var(--cyan); padding-bottom: 6px; margin: 30px 0 6px; }
.secintro { color: var(--muted); max-width: var(--measure); margin: 0 0 14px; }
.qcard { background: var(--card-bg); border: 1px solid var(--line); border-left: 3px solid var(--cyan); border-radius: 12px; padding: 16px 18px; margin: 0 0 14px; }
.qhead { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; flex-wrap: wrap; }
.qnum { font-weight: 700; color: var(--muted); font-size: 0.9rem; min-width: 1.6em; }
.qheadtext { flex: 1 1 auto; }
.qelname { font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--muted); }
.elchip { font-size: 0.75rem; font-weight: 700; border: 1px solid var(--line-strong); border-radius: 6px; padding: 1px 7px; color: var(--muted); }
.senschip { font-size: 0.75rem; font-weight: 700; border: 1px solid var(--warn-line); background: var(--warn-bg); border-radius: 6px; padding: 1px 7px; }
.ask { font-size: 1.06rem; font-weight: 600; max-width: var(--measure); margin: 6px 0 10px; }
.asklabel { display: inline-block; font-size: 0.7rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; color: var(--cyan); border: 1px solid var(--cyan); border-radius: 5px; padding: 0 6px; margin-right: 6px; vertical-align: 2px; }
.layer { margin: 6px 0; border: 1px solid var(--line); border-radius: 8px; background: var(--bg); }
.layer summary { cursor: pointer; padding: 7px 12px; font-size: 0.88rem; font-weight: 600; color: var(--muted); }
.layer[open] summary { color: var(--fg); border-bottom: 1px solid var(--line); }
.layer p, .layer ul { margin: 8px 12px; font-size: 0.92rem; max-width: var(--measure); }
.layer--why summary::before { content: "Why  "; color: var(--cyan); font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.06em; border: 1px solid var(--cyan); border-radius: 5px; padding: 0 6px; margin-right: 6px; }
.layer--staff summary::before { content: "Staff  "; color: var(--muted); font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.06em; border: 1px solid var(--line-strong); border-radius: 5px; padding: 0 6px; margin-right: 6px; }
.layer--map summary::before { content: "Record  "; color: var(--muted); font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.06em; border: 1px solid var(--line-strong); border-radius: 5px; padding: 0 6px; margin-right: 6px; }
.optlist, .optgroup { margin: 8px 0; }
.optgroup__label { font-size: 0.78rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--muted); margin: 10px 0 4px; }
.opt { display: flex; align-items: baseline; gap: 8px; padding: 4px 2px; max-width: var(--measure); }
.opt input { flex: none; }
.opttext { font-size: 0.95rem; }
.dqrow { display: flex; flex-wrap: wrap; gap: 2px 18px; border-top: 1px dashed var(--line); margin-top: 8px; padding-top: 6px; }
.dqrow .opt { padding: 2px; }
.dqrow .opttext { font-size: 0.85rem; color: var(--muted); }
.qualbox { border: 1px dashed var(--line-strong); border-radius: 8px; padding: 8px 12px; margin-top: 10px; }
.qualbox__label { font-size: 0.78rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--muted); margin-bottom: 4px; }
.writein { border: none; border-bottom: 1.5px solid var(--line-strong); background: transparent; color: var(--fg); font: inherit; padding: 2px 4px; min-width: 220px; }
.writein--short { min-width: 90px; }
.writein:focus { outline: none; border-bottom-color: var(--cyan); }
.writeinrow { display: block; margin: 8px 0; font-size: 0.92rem; }
.namegrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 10px; margin: 8px 0; }
.namefield { display: flex; flex-direction: column; gap: 2px; font-size: 0.85rem; color: var(--muted); }
.datebox { margin: 8px 0; }
.datebox label { font-size: 0.9rem; display: flex; flex-direction: column; gap: 2px; max-width: 320px; }
.dateslots { display: none; }
.srctable { border: 1px solid var(--line); border-radius: 8px; overflow: hidden; margin: 10px 0; }
.srcrow { display: grid; grid-template-columns: 1fr 52px 52px 150px; align-items: center; gap: 6px; padding: 5px 10px; border-top: 1px solid var(--line); font-size: 0.92rem; }
.srcrow:first-child { border-top: none; }
.srcrow--head { font-size: 0.75rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--muted); background: var(--bg); }
.srcrow span[role="cell"] { text-align: center; }
.srcrow .srclabel { text-align: left; }
.qflag { background: none; border: none; color: var(--muted); font-size: 0.8rem; text-decoration: underline; cursor: pointer; padding: 4px 0 0; }
.qflag:hover, .qflag:focus-visible { color: var(--cyan); }
.introcard p { max-width: var(--measure); }
.libgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(290px, 1fr)); gap: 14px; margin: 16px 0; }
.libcard { display: flex; flex-direction: column; gap: 6px; background: var(--card-bg); border: 1px solid var(--line); border-radius: 12px; padding: 18px; }
.libcard h3 { margin: 0; }
.libcard .libmeta { font-size: 0.8rem; color: var(--muted); }
.libcard--planned { opacity: 0.75; border-style: dashed; }
.libcard .cta { margin-top: auto; align-self: flex-start; }
.plannedchip { display: inline-block; font-size: 0.72rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--muted); border: 1px dashed var(--line-strong); border-radius: 999px; padding: 1px 8px; }

@media (max-width: 560px) {
  .srcrow { grid-template-columns: 1fr 40px 40px 110px; font-size: 0.85rem; }
}

@media print {
  .topbanner, .sitenav, .prefs, .backtop, .noprint, .qflag { display: none !important; }
  body { background: #fff; color: #000; }
  .qcard, .card, .layer { border-color: #999; background: #fff; break-inside: avoid; }
  .layer summary { color: #000; }
  .ask { color: #000; }
  .writein { border-bottom-color: #555; min-height: 1.3em; }
  .sectitle { border-bottom-color: #000; }
  .statusbanner--draft { background: #fff; border: 1.5px solid #000; color: #000; }
  a { color: #000; text-decoration: none; }
  .dateslots { display: inline-flex; gap: 30px; font-size: 0.7rem; color: #555; }
}
