/* `hidden` must actually hide. The browser's default `[hidden] { display: none }`
   is the lowest-specificity rule there is, so ANY author rule setting `display`
   on the same element beats it and the attribute silently does nothing. This has
   bitten this app twice, both times on a flex container, and both times a
   passing assertion said the element was hidden while it was on screen.
   `!important` is deliberate: `hidden` means "not present", and nothing in a
   stylesheet should be able to overrule that. Pinned by test/hidden-guard.js. */
[hidden] { display: none !important; }
/* ─────────────────────────────────────────────────────────────────────────
   VENDORED, UNCHANGED, from datum/ui/public/app.css at commit 656614014ba7
   (2026-08-12). Served here from /demo/assets/app.css.
   ───────────────────────────────────────────────────────────────────────── */

/* TemplateForge report viewer.
   Sober, dense, printable. The audience is a chartered engineer with a
   worklist, not a visitor to a landing page.

   Colour tokens are the validated data-viz reference palette. The two series
   hues (blue #2a78d6 / orange #eb6834 light, #3987e5 / #d95926 dark) were run
   through the palette validator against these exact surfaces: all six checks
   pass in both modes. Do not substitute hues without re-running it. */

:root {
  color-scheme: light;

  --page:        #f9f9f7;
  --surface:     #fcfcfb;
  --surface-2:   #f3f2ee;
  --ink:         #0b0b0b;
  --ink-2:       #52514e;
  --muted:       #898781;
  --grid:        #e1e0d9;
  --axis:        #c3c2b7;
  --border:      rgba(11, 11, 11, 0.10);

  /* categorical: identity, not severity */
  --series-on:   #2a78d6;   /* slot 1, blue   — on a standard layer */
  --series-off:  #eb6834;   /* slot 2, orange — off standard        */
  --series-on-wash:  #cde2fb;
  --series-off-wash: #fbe0d5;

  /* status: state only, always paired with a word */
  --good:      #0ca30c;
  --warning:   #fab219;
  --serious:   #ec835a;
  --critical:  #d03b3b;
  --good-ink:  #006300;
  /* A status tint, kept separate from the categorical washes on purpose: a row
     highlighted for being a defect must not borrow the colour that means "off
     standard" in every bar on the page.
     `--critical` is a MARK colour (dots, rules) and is too light to read as text
     on these surfaces — 4.1:1 on the wash. `--critical-ink` is the text step, the
     same split `--good` / `--good-ink` already uses. Measured: 6.2:1 on the wash,
     6.5:1 on surface-2, 6.9:1 on the page. */
  --critical-wash: #fbe9e9;
  --critical-ink:  #a91d1d;

  --radius: 3px;
  --font: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --mono: ui-monospace, "Cascadia Mono", "Consolas", "Liberation Mono", monospace;
}

@media (prefers-color-scheme: dark) {
  :root:where(:not([data-theme="light"])) {
    color-scheme: dark;
    --page:      #0d0d0d;
    --surface:   #1a1a19;
    --surface-2: #222221;
    --ink:       #ffffff;
    --ink-2:     #c3c2b7;
    --muted:     #898781;
    --grid:      #2c2c2a;
    --axis:      #383835;
    --border:    rgba(255, 255, 255, 0.10);
    --series-on:  #3987e5;
    --series-off: #d95926;
    --series-on-wash:  #184f95;
    --series-off-wash: #6b2c13;
    --good-ink: #0ca30c;
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --page:      #0d0d0d;
  --surface:   #1a1a19;
  --surface-2: #222221;
  --ink:       #ffffff;
  --ink-2:     #c3c2b7;
  --muted:     #898781;
  --grid:      #2c2c2a;
  --axis:      #383835;
  --border:    rgba(255, 255, 255, 0.10);
  --series-on:  #3987e5;
  --series-off: #d95926;
  --series-on-wash:  #184f95;
  --series-off-wash: #6b2c13;
  --good-ink: #0ca30c;
  /* Dark mode gets its own step from the same ramp rather than an inverted
     light one: 7.2:1 on the wash, 8.2:1 on the surface. */
  --critical-wash: #3a1d1d;
  --critical-ink:  #ff9494;
}

/* ── base ──────────────────────────────────────────────────────────────── */

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--page);
  color: var(--ink);
  font: 15px/1.45 var(--font);
}

h1, h2, h3, h4 { margin: 0; font-weight: 600; letter-spacing: -0.01em; }
h1 { font-size: 1.55rem; }
h2 { font-size: 1.05rem; }
h3 { font-size: 0.95rem; }
p  { margin: 0; }
ul { margin: 0; padding: 0; }

a { color: var(--series-on); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { text-decoration-thickness: 2px; }

code, .path, .cmd { font-family: var(--mono); font-size: 0.86em; }

.muted { color: var(--muted); }
.small { font-size: 0.82rem; }

.skip {
  position: absolute; left: -9999px; top: 0; background: var(--surface);
  padding: 8px 12px; z-index: 10;
}
.skip:focus { left: 8px; top: 8px; }

:focus-visible { outline: 2px solid var(--series-on); outline-offset: 2px; }

/* ── chrome ────────────────────────────────────────────────────────────── */

.topbar {
  display: flex; align-items: center; gap: 20px; flex-wrap: wrap;
  padding: 10px 24px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  position: sticky; top: 0; z-index: 5;
}
.brand { display: flex; align-items: baseline; gap: 8px; margin-right: auto; }
.brand-name { font-weight: 650; letter-spacing: 0.01em; }
.brand-sub { color: var(--muted); font-size: 0.8rem; }

.runpick { display: flex; align-items: center; gap: 6px; font-size: 0.82rem; }
.runpick label { color: var(--muted); }
.runpick select {
  font: inherit; font-size: 0.82rem; padding: 3px 6px;
  background: var(--surface); color: var(--ink);
  border: 1px solid var(--axis); border-radius: var(--radius);
  max-width: 260px;
}

.topbar-actions { display: flex; gap: 6px; flex-wrap: wrap; }

.btn {
  font: inherit; font-size: 0.82rem; line-height: 1.2;
  padding: 5px 10px; cursor: pointer;
  background: var(--surface); color: var(--ink-2);
  border: 1px solid var(--axis); border-radius: var(--radius);
  text-decoration: none; white-space: nowrap;
}
.btn:hover { color: var(--ink); border-color: var(--ink-2); }

.crumb { padding: 12px 24px 0; max-width: 1180px; margin: 0 auto; font-size: 0.85rem; }

main { max-width: 1180px; margin: 0 auto; padding: 20px 24px 48px; }

.pagefoot {
  max-width: 1180px; margin: 0 auto; padding: 0 24px 40px;
  color: var(--muted); font-size: 0.78rem;
  border-top: 1px solid var(--border); padding-top: 14px;
}

/* ── lede ──────────────────────────────────────────────────────────────── */

.lede { margin-bottom: 20px; }
.lede-top { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.lede h1 { overflow-wrap: anywhere; }
.lede-line { color: var(--ink-2); font-size: 0.86rem; margin-top: 4px; }
.crumbline { font-size: 0.78rem; margin-bottom: 4px; }

/* The engine already wrote this sentence for a human. Lead with it. */
.headline {
  margin-top: 10px;
  font-size: 1.06rem; line-height: 1.5; font-weight: 500;
  color: var(--ink);
  border-left: 3px solid var(--series-on);
  padding: 2px 0 2px 12px;
  max-width: 78ch;
}

.path-line { margin-top: 6px; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.path { color: var(--muted); overflow-wrap: anywhere; }

/* ── badges ────────────────────────────────────────────────────────────── */

.badge {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 0.76rem; font-weight: 600; letter-spacing: 0.01em;
  padding: 3px 9px 3px 7px; border-radius: 999px;
  border: 1px solid var(--border); background: var(--surface-2); color: var(--ink);
  white-space: nowrap;
}
.badge-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--muted); }
.badge--critical .badge-dot { background: var(--critical); }
.badge--warning  .badge-dot { background: var(--warning); }
.badge--good     .badge-dot { background: var(--good); }

.flag {
  display: inline-block; margin-left: 8px;
  font-size: 0.72rem; color: var(--ink-2);
  border: 1px solid var(--axis); border-radius: var(--radius);
  padding: 1px 6px; white-space: nowrap;
}

.ok-mark   { color: var(--good-ink); }
.ok-mark::before   { content: "\2713\00a0"; }
.warn-mark { color: var(--ink-2); }
.warn-mark::before { content: "\26a0\00a0"; }

/* ── stat tiles ────────────────────────────────────────────────────────── */

.tiles {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 1px; background: var(--border);
  border: 1px solid var(--border); border-radius: var(--radius);
  overflow: hidden; margin-bottom: 22px;
}
.tile { background: var(--surface); padding: 12px 14px 14px; }
.tile-label { font-size: 0.76rem; color: var(--muted); text-transform: none; }
.tile-value { font-size: 1.85rem; font-weight: 600; line-height: 1.15; margin-top: 2px; }
.tile-of { font-size: 0.95rem; font-weight: 400; color: var(--muted); }
.tile-sub { font-size: 0.74rem; color: var(--muted); margin-top: 3px; line-height: 1.35; }

/* ── panels ────────────────────────────────────────────────────────────── */

.panel {
  background: var(--surface);
  border: 1px solid var(--border); border-radius: var(--radius);
  padding: 16px 18px 18px; margin-bottom: 20px;
}
.panel--quiet { background: var(--surface-2); }
.panel-head { margin-bottom: 10px; }
.panel-note { font-size: 0.8rem; color: var(--muted); margin-top: 3px; max-width: 88ch; }
.count {
  font-size: 0.78rem; font-weight: 600; color: var(--ink-2);
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: 999px; padding: 1px 8px; margin-left: 6px; vertical-align: 2px;
}
.panel--quiet .count { background: var(--surface); }

.empty-state {
  padding: 18px; text-align: center; color: var(--ink-2);
  border: 1px dashed var(--axis); border-radius: var(--radius);
}

.plain { list-style: none; }
.plain li { padding: 3px 0 3px 16px; position: relative; font-size: 0.86rem; color: var(--ink-2); line-height: 1.45; }
.plain li::before { content: "\2013"; position: absolute; left: 0; color: var(--muted); }

.exports { margin-top: 14px; font-size: 0.82rem; display: flex; gap: 18px; flex-wrap: wrap; }

/* ── the ratio bar: on standard vs off standard ────────────────────────── */

.legend {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-size: 0.76rem; color: var(--ink-2); margin-bottom: 8px;
}
.key { width: 10px; height: 10px; border-radius: 2px; display: inline-block; }
.key--on  { background: var(--series-on); }
.key--off { background: var(--series-off); margin-left: 14px; }

.ratio { display: block; width: 100%; }
.ratio-track {
  display: flex; gap: 2px;                 /* 2px surface gap, not a stroke */
  height: 9px; min-width: 3px;
}
.ratio--big .ratio-track { height: 16px; }
.seg { display: block; min-width: 2px; }
.seg--on  { background: var(--series-on); }
.seg--off { background: var(--series-off); }
.seg--empty { background: var(--grid); }
/* 4px rounded data-ends on the outside of the stack only */
.ratio-track > .seg:first-child { border-radius: 4px 0 0 4px; }
.ratio-track > .seg:last-child  { border-radius: 0 4px 4px 0; }
.ratio-track > .seg:only-child  { border-radius: 4px; }

/* ── hero ──────────────────────────────────────────────────────────────── */

.hero {
  display: grid; grid-template-columns: minmax(210px, 260px) 1fr; gap: 28px;
  align-items: center;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 18px 20px; margin-bottom: 20px;
}
.hero-label { font-size: 0.78rem; color: var(--muted); }
.hero-value {
  font-size: 3.1rem; font-weight: 600; line-height: 1.02; letter-spacing: -0.02em;
  /* proportional figures on purpose — tabular digits look loose this big */
}
.hero-sub { font-size: 0.82rem; color: var(--ink-2); margin-top: 2px; }
.hero-bar-labels { display: flex; justify-content: space-between; margin-top: 7px; font-size: 0.8rem; }
.lab { color: var(--ink-2); display: inline-flex; align-items: center; gap: 6px; }
.lab::before { content: ""; width: 8px; height: 8px; border-radius: 2px; }
.lab--on::before  { background: var(--series-on); }
.lab--off::before { background: var(--series-off); }

/* ── banners ───────────────────────────────────────────────────────────── */

.banner {
  border: 1px solid var(--border); border-left: 3px solid var(--axis);
  background: var(--surface-2); border-radius: var(--radius);
  padding: 11px 14px; margin-bottom: 16px; font-size: 0.88rem;
}
.banner--block { border-left-color: var(--serious); }
.banner--warn  { border-left-color: var(--warning); }
.banner .chips { margin-top: 8px; }

/* ── tables ────────────────────────────────────────────────────────────── */

/* A wide table scrolls inside its own box. The page itself never scrolls
   sideways — a report you have to drag horizontally is a report nobody reads. */
.tablewrap { overflow-x: auto; }

.grid { width: 100%; border-collapse: collapse; font-size: 0.86rem; }
.grid caption {
  text-align: left; font-size: 0.78rem; color: var(--muted);
  padding: 10px 0 5px; font-weight: 500;
}
.grid th {
  text-align: left; font-weight: 600; font-size: 0.76rem; color: var(--muted);
  padding: 6px 10px 6px 0; border-bottom: 1px solid var(--axis); white-space: nowrap;
}
.grid td {
  padding: 8px 10px 8px 0; border-bottom: 1px solid var(--grid);
  vertical-align: middle;
}
.grid tbody tr:last-child td { border-bottom: none; }
.c-num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; padding-left: 18px; }
.c-num--hot { font-weight: 600; }
.grid th.c-num:last-child, .grid td.c-num:last-child { padding-right: 0; }
.grid--portfolio th.c-num { min-width: 84px; }

/* The certificate table is a tally, not a browsable list, so the row headings
   read as labels and the total is ruled off the way a printed schedule is. */
.grid--cert th[scope="row"] { text-align: left; font-weight: 500; white-space: nowrap; }
.grid--cert .c-note { color: var(--muted); padding-left: 18px; width: 100%; }
.grid--cert .cert-total th, .grid--cert .cert-total td {
  border-top: 2px solid var(--border); font-weight: 700; border-bottom: none;
}

/* Severity bands on the certificate. A row of counts rather than a bar chart:
   this page gets printed, and a proportional bar of six segments prints as six
   grey boxes. The number is the message. */
.sub { font-size: 0.95rem; margin: 22px 0 10px; }
.sevbar { display: flex; flex-wrap: wrap; gap: 10px; }
.sev {
  flex: 1 1 108px; padding: 10px 12px; border: 1px solid var(--border);
  border-radius: 8px; border-left-width: 4px;
}
.sev-count { display: block; font-size: 1.35rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.sev-label { display: block; font-size: 0.8rem; color: var(--muted); text-transform: lowercase; }
.sev--critical { border-left-color: var(--critical); }
.sev--high     { border-left-color: var(--serious); }
.sev--medium   { border-left-color: var(--warning); }
.sev--low      { border-left-color: var(--good); }
.sev--unscored, .sev--error { border-left-color: var(--muted); }

/* Drift. The variants column carries several values per row, so each is its own
   line rather than a comma list — the whole point of the page is comparing them
   at a glance, and a wrapped sentence defeats that. */
/* The drawings count is right-aligned and the standard value left-aligned, so
   without this they collide into one unreadable "40 11". */
.grid--drift .c-std { width: 90px; padding-left: 22px; }
.grid--drift th.c-num, .grid--drift td.c-num { padding-right: 8px; }
.grid--drift .c-variants { width: 46%; }
.variant { display: flex; gap: 10px; align-items: baseline; padding: 2px 0; }
.variant + .variant { border-top: 1px dotted var(--border); }
.variant-value {
  min-width: 52px; font-weight: 600; text-align: right;
  font-variant-numeric: tabular-nums;
}
.variant-count { min-width: 92px; color: var(--muted); white-space: nowrap; }
.variant-eg { color: var(--muted); font-size: 0.92em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.grid--portfolio tbody tr:hover { background: var(--surface-2); }
.grid--portfolio .c-name { min-width: 190px; }
.dwg { font-weight: 600; }
.c-pct { text-align: right; width: 92px; }
.pct { font-size: 1.05rem; font-weight: 600; font-variant-numeric: tabular-nums; }
/* A drawing with nothing scored has no percentage, and its cell must not be able
   to read as a good one. Same size so the column still aligns, but muted and
   unbolded so the eye does not collect it with the scores it sits between. */
.pct--none { color: var(--muted); font-weight: 400; }
.c-bar { width: 32%; min-width: 160px; padding-right: 18px; }
.c-bar .bar-label {
  display: inline-block; margin-top: 4px;
  font-size: 0.72rem; color: var(--muted); font-variant-numeric: tabular-nums;
}
.c-house { color: var(--ink-2); font-size: 0.8rem; white-space: nowrap; }
.row--dead .c-dead { color: var(--ink-2); font-style: italic; }

.grid th.c-mini, .grid td.c-mini { width: 90px; padding-left: 14px; }
.mini { display: block; height: 6px; background: var(--grid); border-radius: 3px; }
.mini > span { display: block; height: 100%; background: var(--series-on); border-radius: 3px; }

.grid--props .row--cont td { border-bottom: 1px solid var(--grid); }

.grid--index { margin-bottom: 18px; }
.grid--index tbody tr:hover { background: var(--surface-2); }
.grid--index td { padding-top: 5px; padding-bottom: 5px; }
.grid--index a { text-decoration: none; color: inherit; }
.grid--index a:hover { text-decoration: underline; }
.grid--index td:first-child a { color: var(--muted); font-weight: 600; }
.mini--off > span { background: var(--series-off); }

/* ── findings ──────────────────────────────────────────────────────────── */

.findings { display: flex; flex-direction: column; gap: 14px; }

.finding {
  border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--surface); padding: 14px 16px 16px;
}
.panel .finding { background: var(--page); }

.finding-head {
  display: grid; grid-template-columns: 34px 1fr auto; gap: 12px;
  align-items: start; padding-bottom: 12px; border-bottom: 1px solid var(--grid);
}
.rank {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; border-radius: 50%;
  background: var(--surface-2); border: 1px solid var(--border);
  font-size: 0.82rem; font-weight: 600; color: var(--ink-2);
  font-variant-numeric: tabular-nums;
}
.finding-id h3 { font-size: 1rem; }
.layer { font-size: 0.98rem; font-weight: 600; overflow-wrap: anywhere; }
.kind { font-size: 0.8rem; color: var(--muted); margin-top: 2px; }

.weight { text-align: right; min-width: 140px; }
.weight-n { font-size: 1.3rem; font-weight: 600; font-variant-numeric: tabular-nums; }
.weight-u { font-size: 0.76rem; color: var(--muted); margin-left: 5px; }
.weight-bar { display: block; height: 4px; background: var(--grid); border-radius: 2px; margin-top: 6px; }
.weight-bar > span { display: block; height: 100%; background: var(--series-off); border-radius: 2px; }

.finding-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 16px;
  padding: 13px 0 4px;
}
.kicker {
  font-size: 0.7rem; font-weight: 700; letter-spacing: 0.07em;
  text-transform: uppercase; color: var(--muted); margin-bottom: 5px;
}
/* The fix carries the same weight as the problem. */
.fix { border-left: 3px solid var(--series-on); padding-left: 12px; }
.fix--none { border-left-color: var(--warning); }
.fix-line { font-size: 1rem; font-weight: 500; line-height: 1.4; }
.fix--none .fix-line { font-weight: 600; }
.target {
  font-weight: 700; background: var(--series-on-wash); color: var(--ink);
  padding: 1px 6px; border-radius: var(--radius);
}
.fix-meta { font-size: 0.8rem; color: var(--ink-2); margin-top: 4px; line-height: 1.4; }
.why { border-left: 3px solid var(--grid); padding-left: 12px; }
.why p { font-size: 0.88rem; color: var(--ink-2); line-height: 1.5; }
.where { margin-top: 6px; color: var(--ink-2); }

/* ── handles ───────────────────────────────────────────────────────────── */

.handles { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--grid); }
.chips { list-style: none; display: flex; flex-wrap: wrap; gap: 5px; margin-top: 6px; }
.chip {
  font: inherit; cursor: pointer; padding: 2px 8px;
  background: var(--surface-2); color: var(--ink);
  border: 1px solid var(--axis); border-radius: var(--radius);
}
.chip:hover { border-color: var(--series-on); }
.chip.copied { border-color: var(--good); }
.chips--quiet { gap: 4px; }
.chips--quiet li {
  font-family: var(--mono); font-size: 0.78rem; color: var(--ink-2);
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 1px 6px;
}

.cmds { margin: 12px 0 0; display: grid; grid-template-columns: max-content 1fr; gap: 6px 16px; align-items: start; }
.cmds dt { font-size: 0.78rem; color: var(--muted); padding-top: 4px; white-space: nowrap; }
.cmds dd { margin: 0; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.cmd {
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 3px 8px;
  overflow-wrap: anywhere; max-width: 100%;
}
.cmd-note { font-size: 0.76rem; color: var(--muted); flex-basis: 100%; }

.copy {
  font: inherit; font-size: 0.72rem; cursor: pointer; padding: 2px 8px;
  background: var(--surface); color: var(--ink-2);
  border: 1px solid var(--axis); border-radius: var(--radius);
}
.copy:hover { color: var(--ink); border-color: var(--ink-2); }
.copy.copied { color: var(--good-ink); border-color: var(--good); }

/* ── housekeeping (deliberately subordinate) ───────────────────────────── */

.housekeeping .sub { margin-top: 16px; }
.housekeeping .sub:first-of-type { margin-top: 6px; }
.sub h3 { font-size: 0.9rem; color: var(--ink); }
.sub-note { font-size: 0.8rem; color: var(--muted); margin-top: 3px; max-width: 90ch; line-height: 1.45; }
.housekeeping .grid { margin-top: 8px; }
.housekeeping .grid td { padding-top: 6px; padding-bottom: 6px; }

/* Progressive disclosure for the report's evidence.
   The counts that make the report trustworthy - what was scanned, what was
   deliberately not scored, which exact objects were counted - are what made it
   unreadable at a glance. They are not removed: they are one click away, and
   the summary line carries the headline numbers so a sceptic can see the proof
   exists before deciding to open it. A hidden count reads as absent; a labelled
   one reads as available. */
.disclosure > summary {
  cursor: pointer;
  list-style: none;
  padding: 2px 0;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 10px;
}
.disclosure > summary::-webkit-details-marker { display: none; }
.disclosure > summary::before {
  content: '▸';
  color: var(--muted);
  font-size: 0.8rem;
  transition: transform 0.12s ease;
}
.disclosure[open] > summary::before { content: '▾'; }
.disclosure > summary h2 { display: inline; margin: 0; }
.disclosure > summary:hover .disclosure-hint { color: var(--ink); }
.disclosure-hint { font-size: 0.8rem; color: var(--muted); }
.disclosure[open] > summary { margin-bottom: 10px; }
.disclosure--tight { margin-top: 10px; }
.disclosure--tight > summary::before { font-size: 0.75rem; }

.fold { margin-top: 8px; }
.fold summary {
  cursor: pointer; font-size: 0.8rem; color: var(--ink-2);
  padding: 3px 0; width: fit-content;
}
.fold summary:hover { color: var(--ink); }
.fold[open] summary { margin-bottom: 6px; }

.scope-cols { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 8px 28px; }
.scope-cols > * { min-width: 0; }
/* min-width:0 on the value column: without it a long value forces the grid
   track wider than its container and the whole row overflows the page. */
.facts { margin: 0; display: grid; grid-template-columns: 1fr minmax(0, max-content); gap: 0 12px; align-content: start; }
.facts dt { font-size: 0.82rem; color: var(--ink-2); padding: 4px 0; border-bottom: 1px solid var(--grid); }
.facts dd {
  margin: 0; font-size: 0.82rem; text-align: right; padding: 4px 0;
  border-bottom: 1px solid var(--grid); font-variant-numeric: tabular-nums;
  min-width: 0; overflow-wrap: anywhere;
}
.facts dt:last-of-type, .facts dd:last-of-type { border-bottom: none; }

.notes .plain li { color: var(--ink-2); }

/* ── coverage & trust ──────────────────────────────────────────────────── */
/* The exclusion sits with the number it qualifies, not in a panel further down
   — by then the reader has already believed the percentage. */

.banner--info { border-left-color: var(--series-on); }
.coverage { margin-bottom: 16px; }
.coverage p + p { margin-top: 5px; }
.coverage--clear { font-size: 0.82rem; color: var(--muted); margin: -8px 0 16px; }

.trust { margin-bottom: 12px; }
.trust--yes { font-size: 0.84rem; color: var(--ink-2); margin-bottom: 12px; }
.trust code { background: var(--surface); padding: 0 4px; border-radius: var(--radius); }

.btn-count { color: var(--muted); font-variant-numeric: tabular-nums; }
.flag--stop { border-color: var(--critical); color: var(--critical-ink); }
.flag--warn { border-color: var(--warning); }

/* ── external references ───────────────────────────────────────────────── */

.grid--xrefs td { vertical-align: top; }
.xref-name { font-weight: 600; overflow-wrap: anywhere; }
.xref-tags { display: block; font-size: 0.74rem; color: var(--muted); }
.inserted-on { display: inline-block; margin-right: 6px; }
.off-standard {
  background: var(--series-off-wash); color: var(--ink);
  padding: 1px 5px; border-radius: var(--radius);
}
.c-path { max-width: 26ch; }
.c-path .path { overflow-wrap: anywhere; }
.c-xref { white-space: nowrap; }
.xref-cell .flag { margin-left: 6px; }

.stat { font-size: 0.82rem; white-space: nowrap; }
.stat--good::before    { content: "\2713\00a0"; color: var(--good-ink); }
.stat--warning::before { content: "\26a0\00a0"; }
.stat--warning { color: var(--ink-2); }
.stat--muted { color: var(--muted); }
/* A missing reference is a defect on the project, not a caveat about the run,
   and it is the one status in this table that must not read as a shrug. */
.stat--critical { color: var(--critical-ink); font-weight: 600; }
.stat--critical::before { content: "\2717\00a0"; }
.stat-note {
  display: block; white-space: normal; font-size: 0.74rem;
  color: var(--muted); margin-top: 2px; max-width: 32ch;
}
.banner--critical { border-left-color: var(--critical); }
.row--missing { background: var(--critical-wash); }
.facts dt.indent { padding-left: 14px; color: var(--muted); }

/* ── object layers: the recurrence cause ───────────────────────────────── */
/* No new mark is drawn here on purpose. Every quantity in this section is a
   count between 0 and ~70, and a count is read faster as a number than as a
   bar; the one gulf worth seeing at a glance (56 objects against 0) is stated in
   words in the evidence row. Colour is the existing "off standard" wash on the
   layer new objects actually land on, and the existing "target" wash on the
   layer the standard names — the same two meanings they carry everywhere else on
   the page, so nothing is re-encoded. */

.objectlayers .ol-lead {
  font-size: 0.95rem; line-height: 1.5; color: var(--ink);
  margin-bottom: 14px; max-width: 88ch;
}
.objectlayers .scope-cols { margin-bottom: 10px; }
.ol-where { color: var(--ink-2); }

/* The objects the score calls correct and a setting still misplaced. It is a
   sentence, not a mark: the count is small and the reason it matters — they are
   inside the compliant share and no finding names them — is not something a bar
   can say. It gets the warning rule rather than the critical one because the
   engine deliberately does not deduct them, and a red block beside a figure
   nothing was subtracted from would be its own kind of lie. No new colour. */
.ol-invisible {
  border-left: 3px solid var(--warning);
  padding: 4px 0 4px 12px; margin: 0 0 14px;
  font-size: 0.86rem; color: var(--ink-2); max-width: 88ch;
}
.ol-invisible strong { color: var(--ink); }

/* Why a row is NOT linked to a finding. Reads as prose in the evidence row and
   inherits its colour; the label is what makes it scannable down a column of
   rows that all end in the same empty cell. */
.ol-why-not strong { color: var(--ink); }

.ol-group { margin-top: 18px; }
.ol-group h3 { display: flex; align-items: baseline; flex-wrap: wrap; gap: 8px; }
.ol-group .stat { font-weight: 600; }

.grid--objectlayers td { vertical-align: top; }
.grid--objectlayers .ol-type { font-weight: 600; }
/* The slack goes to the two layer columns — those are the pair a reader compares.
   Left to itself the table gives it to the count column and opens a hand's width
   of nothing between "the standard says" and the number it is being weighed
   against. */
.grid--objectlayers th:first-child { width: 3ch; }
.grid--objectlayers th:last-child  { width: 11ch; }
.ol-sub { display: block; font-size: 0.74rem; color: var(--muted); margin-top: 2px; }
.ol-modifier { font-size: 0.76rem; color: var(--ink-2); margin-left: 6px; white-space: nowrap; }
.ol-also { font-size: 0.8rem; }
/* The evidence line: the sentence that makes a setting a fact rather than a
   complaint about a checkbox. It spans the table because it is prose. */
.ol-evidence td {
  font-size: 0.8rem; color: var(--ink-2); line-height: 1.5;
  padding-top: 0; border-bottom: 1px solid var(--grid);
}
.ol-evidence code { background: var(--surface-2); padding: 0 3px; border-radius: var(--radius); }
.panel .ol-evidence code { background: var(--surface-2); }

.c-ol { white-space: nowrap; }
.ol-cell .flag { margin-left: 6px; }

/* Inside a finding card: the cause, at the same width as the fix and the why,
   because a worklist item that comes back is a different job from one that does
   not. */
.cause {
  border-left: 3px solid var(--warning);
  padding: 2px 0 2px 12px; margin-top: 4px;
}
.cause-line { font-size: 0.86rem; color: var(--ink-2); line-height: 1.5; }
.cause-meta { font-size: 0.78rem; color: var(--muted); margin-top: 4px; }

/* ── the standard's provenance ─────────────────────────────────────────── */

.plain--roomy li { padding: 6px 0 6px 16px; }
.facts--wide { grid-template-columns: max-content minmax(0, 1fr); }
.facts--wide dd { text-align: left; }
.grid--extnotes td { vertical-align: top; }
.grid--extnotes td:first-child { white-space: nowrap; }
.scope-foot { margin-top: 10px; }

/* ── fix plans (read-only, always) ─────────────────────────────────────── */

.readonly { border-left-color: var(--series-on); }
.grid--fixitems td { vertical-align: top; }
.c-why { color: var(--ink-2); max-width: 40ch; }

/* Refusals carry the same weight as the actions: same panel, same heading
   scale, same count chip. They are what makes the rest of it trustworthy. */
.panel--refusals { border-left: 3px solid var(--warning); }
.refusals { list-style: none; display: flex; flex-direction: column; gap: 10px; }
.refusal {
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 10px 12px;
}
.refusal-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.refusal-action { font-size: 0.78rem; color: var(--muted); }
.refusal-reason { font-size: 0.86rem; color: var(--ink-2); line-height: 1.5; margin-top: 5px; max-width: 92ch; }

.safety-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 16px 28px; }
.safety-item { min-width: 0; border-left: 3px solid var(--grid); padding-left: 12px; }
.safety-line { font-size: 0.9rem; line-height: 1.45; }
.safety-item .cmds { grid-template-columns: 1fr; }

.hashline { display: flex; align-items: center; gap: 8px; margin-top: 6px; flex-wrap: wrap; }
.hash-label { font-size: 0.72rem; color: var(--muted); min-width: 96px; }
.hash {
  font-size: 0.72rem; color: var(--ink-2); overflow-wrap: anywhere;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 1px 5px; min-width: 0; flex: 1 1 20ch;
}
.panel--quiet .hash { background: var(--page); }

.nextstep .cmds { margin-top: 4px; }
.grid--fixplans .c-name .small { display: block; }

/* ── narrow ────────────────────────────────────────────────────────────── */

/* Scoped to `screen`: an A4 page is ~794 CSS px wide, and the print layout
   must keep the bars rather than fall into the phone layout that drops them. */
@media screen and (max-width: 860px) {
  .hero { grid-template-columns: 1fr; gap: 14px; }
  .finding-grid { grid-template-columns: 1fr; }
  .finding-head { grid-template-columns: 28px 1fr; }
  .weight { grid-column: 2; text-align: left; }
  .weight-bar { max-width: 220px; }
  main, .topbar, .crumb, .pagefoot { padding-left: 14px; padding-right: 14px; }
  /* The bar column and its legend go together — one without the other is a
     key to nothing. The numbers stay, so no value is lost. */
  .grid--portfolio .c-bar, .page-portfolio .legend { display: none; }
  .safety-grid { grid-template-columns: 1fr; }
  .hash-label { min-width: 0; flex-basis: 100%; }
}

/* ── print / PDF ───────────────────────────────────────────────────────── */

@page { margin: 12mm 10mm; }

@media print {
  /* Print is always the light palette on white — a dark-mode screenshot of a
     report is not what gets stapled to a site instruction. The theme-toggle
     selectors carry a specificity of (0,2,0), so these have to match it or a
     reader in dark mode prints black-on-black. */
  :root,
  :root[data-theme="dark"],
  :root[data-theme="light"] {
    color-scheme: light;
    --page: #ffffff; --surface: #ffffff; --surface-2: #ffffff;
    --ink: #000000; --ink-2: #333333; --muted: #555555;
    --grid: #cccccc; --axis: #999999; --border: rgba(0,0,0,0.25);
    --series-on: #2a78d6; --series-off: #eb6834;
    --series-on-wash: #e6effb;
    --critical: #b02020; --critical-wash: #f7e4e4; --critical-ink: #8f1a1a;
  }
  html, body { background: #fff; color: #000; font-size: 9.5pt; }

  .topbar, .crumb, .btn, .copy, .exports, .skip, .runpick { display: none !important; }

  main { max-width: none; padding: 0; }
  .pagefoot { padding: 8pt 0 0; border-top: 1px solid #ccc; }

  .panel, .finding, .hero, .tiles, .banner {
    border-color: #bbb; box-shadow: none;
    break-inside: avoid; page-break-inside: avoid;
  }
  .panel { padding: 8pt 0 6pt; border: none; border-top: 1px solid #999; border-radius: 0; }
  .tiles { border: 1px solid #bbb; }
  .finding { border: 1px solid #ccc; margin-bottom: 6pt; }
  .findings { gap: 6pt; }

  /* An unexpanded <details> in a printed report is a hole in it. app.js opens
     them all on beforeprint; this is the no-JavaScript fallback for engines
     that support ::details-content. */
  details > summary { display: none; }
  details::details-content { content-visibility: visible; block-size: auto; }

  /* Three columns of facts do not fit A4 portrait, and a clipped value is a
     wrong value. */
  .scope-cols { grid-template-columns: 1fr 1fr; }
  .facts dd { overflow-wrap: anywhere; }

  /* The portfolio table was 797px against a 779px A4 page box — measured, on
     both the 161-drawing run and the four-drawing one, and it predates the
     compliance work. On screen the wrapper scrolls; paper cannot, so the last
     column was being cut off the sheet. The housekeeping cell is the only one
     holding its width for no reason: it is "13 empty · 3 property", two facts
     that read the same stacked, and nothing lines up against it. Everything
     else in the row is a figure that must stay on one line.
     On a run that also carries the object-layer and xref columns it was 863,
     and those two cells are prose as well — "6 of 17 disagree", "12 not scored,
     2 refs" — so they wrap for the same reason. */
     The screen minimums go too: 190px for the name and 84px for each of the two
     count columns are comfortable at 1320px and are 274px of the 779 available
     on A4. A wrapped column heading costs nothing on paper; a cut-off column
     costs the reader the fact. */
  .grid--portfolio { table-layout: auto; }
  .grid--portfolio th { white-space: normal; }
  .c-house, .c-ol, .c-xref { white-space: normal; }
  .grid--portfolio .c-name { min-width: 0; }
  .grid--portfolio th.c-num { min-width: 0; }
  .c-bar { min-width: 0; }

  h1 { font-size: 15pt; }
  h2 { font-size: 11pt; }
  .hero-value { font-size: 30pt; }
  .headline { font-size: 10.5pt; }

  a { color: #000; text-decoration: none; }
  .cmd, .chip, .chips--quiet li { border: 1px solid #bbb; }

  /* Bars are data. Browsers strip backgrounds when printing unless told. */
  .seg, .mini > span, .weight-bar > span, .badge-dot, .key, .lab::before, .target {
    -webkit-print-color-adjust: exact; print-color-adjust: exact;
  }
  .mini, .weight-bar { background: #e6e6e6; -webkit-print-color-adjust: exact; print-color-adjust: exact; }

  .printblock--break { break-before: page; page-break-before: always; }
  .lede, .hero { break-after: avoid; page-break-after: avoid; }

  /* A refusal is part of the record. It has to survive being printed and
     stapled to the drawing it refers to. */
  .refusal, .safety-item, .grid--xrefs tr { break-inside: avoid; page-break-inside: avoid; }
  /* A setting and the sentence that proves it is live are one row of the
     checklist somebody works through in Edit Drawing Settings. Splitting them
     across a page break loses the evidence. */
  .ol-group { break-inside: auto; page-break-inside: auto; }
  .grid--objectlayers tr { break-inside: avoid; page-break-inside: avoid; }
  .grid--objectlayers thead { display: table-header-group; }
  .cause { border-left: 2pt solid #999; }
  .panel--refusals { border-left: 2pt solid #999; padding-left: 6pt; }
  /* Two columns of long-form prose plus a 64-character hash do not fit A4
     portrait — measured, the right-hand column lost its last character on every
     line. One column per page, and nothing is cut. */
  .safety-grid { grid-template-columns: 1fr; gap: 8pt; }
  .hash { border: 1px solid #ddd; word-break: break-all; }
  .off-standard, .stat--good::before, .row--missing {
    -webkit-print-color-adjust: exact; print-color-adjust: exact;
  }
}

/* "Carrying out the fix" — what is built vs what is being developed. The two
   halves are visually separated because the whole value of the box is that a
   reader can tell them apart at a glance. */
.roadmap-now { border-left: 3px solid var(--ok, #2e9e5b); padding-left: 14px; margin-bottom: 18px; }
.roadmap-next { border-left: 3px solid var(--line, #d8d5cd); padding-left: 14px; }
.roadmap-list { margin: 10px 0 0; }
.roadmap-list dt { font-weight: 640; margin-top: 12px; }
.roadmap-list dd { margin: 4px 0 0; opacity: .9; }
