/* Palette note ---------------------------------------------------------------

   The three judgement colours are a status scale, not a series palette, and
   they were checked rather than chosen by eye. A green-amber-red risk scale can
   never pass a colourblind separation test -- green against red measures a
   colour distance of about 4 under deuteranopia, where 8 is the floor -- and no
   re-picking of hues fixes that while keeping the meaning the client already
   reads in their report. So colour is never the only channel here: every band
   also carries a text label, a legend entry, a direct value, a table view, and
   an optional hatch pattern.

   The three contaminant series colours ARE a validated categorical set: blue,
   orange and aqua clear every separation gate against each other in both light
   and dark. A fourth contaminant folds into a grey "Other" rather than taking a
   generated hue, because a generated fourth hue would be indistinguishable from
   one of these under colourblindness.

   Amber sits below 3:1 against the light surface. That is allowed only because
   every amber mark is accompanied by a visible label or the table view.
---------------------------------------------------------------------------- */

:root {
  color-scheme: light;

  --surface-1: #fcfcfb;
  --plane: #f4f5f7;
  --ink: #0b0b0b;
  --ink-2: #52514e;
  --muted: #6f6e69;
  --grid: #e1e0d9;
  --baseline: #c3c2b7;
  --hairline: rgba(11, 11, 11, 0.10);

  --navy: #2a476b;
  --navy-ink: #ffffff;

  --band-adequate: #0ca30c;
  --band-marginal: #fab219;
  --band-over: #d03b3b;

  --band-adequate-ink: #0b6b0b;
  --band-marginal-ink: #7a5300;
  --band-over-ink: #9c2020;

  --series-1: #2a78d6;
  --series-2: #eb6834;
  --series-3: #1baf7a;
  --series-other: #898781;

  --radius: 12px;
  --font: system-ui, -apple-system, "Segoe UI", sans-serif;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --surface-1: #1a1a19;
    --plane: #0d0d0d;
    --ink: #ffffff;
    --ink-2: #c3c2b7;
    --muted: #a3a199;
    --grid: #2c2c2a;
    --baseline: #383835;
    --hairline: rgba(255, 255, 255, 0.10);

    --navy: #14243a;
    --navy-ink: #ffffff;

    --band-adequate-ink: #4cc44c;
    --band-marginal-ink: #fab219;
    --band-over-ink: #f08080;

    --series-1: #3987e5;
    --series-2: #d95926;
    --series-3: #199e70;
    --series-other: #898781;
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --surface-1: #1a1a19;
  --plane: #0d0d0d;
  --ink: #ffffff;
  --ink-2: #c3c2b7;
  --muted: #a3a199;
  --grid: #2c2c2a;
  --baseline: #383835;
  --hairline: rgba(255, 255, 255, 0.10);
  --navy: #14243a;
  --band-adequate-ink: #4cc44c;
  --band-marginal-ink: #fab219;
  --band-over-ink: #f08080;
  --series-1: #3987e5;
  --series-2: #d95926;
  --series-3: #199e70;
}

* { box-sizing: border-box; }

/* The browser's own [hidden] rule is `display: none` at UA priority, which any
   author `display` declaration outranks. .gate sets `display: grid`, so setting
   gate.hidden = true left the sign-in panel sitting on top of the dashboard at
   full height -- it looked like the code had been refused when in fact the data
   had loaded underneath. Author-level and !important so `hidden` means hidden
   regardless of what else an element is styled as. */
[hidden] { display: none !important; }

/* Holds the hatch patterns only; must not take up layout space. */
.defs-only { position: absolute; width: 0; height: 0; }

body {
  margin: 0;
  font-family: var(--font);
  background: var(--plane);
  color: var(--ink);
  -webkit-text-size-adjust: 100%;
}

h1, h2, h3 { margin: 0; font-weight: 700; letter-spacing: -0.01em; }

.btn {
  font: inherit;
  font-weight: 600;
  border-radius: 10px;
  border: 1px solid transparent;
  padding: 10px 16px;
  cursor: pointer;
}
.btn.primary { background: var(--navy); color: #fff; }
.btn.primary:disabled { opacity: 0.6; cursor: progress; }
/* Ghost buttons started life in the navy top bar, so they were white on a
   transparent ground. Once they appeared on light panels too -- "Separate" on
   the merge screen, "Hide from client" on the assessments screen -- that made
   them white on near-white and effectively invisible. The default now suits a
   light surface, and the top bar keeps its own. */
.btn.ghost {
  background: transparent;
  color: var(--ink-2);
  border-color: var(--baseline);
}
.btn.ghost:hover { background: var(--plane); }
.topbar .btn.ghost {
  color: var(--navy-ink);
  border-color: rgba(255, 255, 255, 0.45);
}
.topbar .btn.ghost:hover { background: rgba(255, 255, 255, 0.12); }
.btn:focus-visible { outline: 3px solid var(--series-1); outline-offset: 2px; }

/* ---- Gate ---------------------------------------------------------------- */

.gate {
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: 24px;
  background: var(--navy);
}
.gate-card {
  width: min(440px, 100%);
  background: var(--surface-1);
  border-radius: 16px;
  padding: 32px;
  display: grid;
  gap: 12px;
  box-shadow: 0 18px 50px rgba(0, 0, 0, 0.28);
}
.gate-brand {
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}
.gate-card h1 { font-size: 24px; }
.gate-lede { margin: 0; color: var(--ink-2); font-size: 15px; line-height: 1.5; }
.gate-label { font-size: 13px; font-weight: 700; margin-top: 8px; }
.gate-card input[type="password"] {
  font: inherit;
  padding: 12px 14px;
  border-radius: 10px;
  border: 1px solid var(--baseline);
  background: var(--surface-1);
  color: var(--ink);
  letter-spacing: 0.06em;
}
.gate-card input[type="password"]:focus-visible { outline: 3px solid var(--series-1); outline-offset: 1px; }
.gate-remember { font-size: 14px; color: var(--ink-2); display: flex; gap: 8px; align-items: center; }
.gate-error {
  margin: 0;
  padding: 10px 12px;
  border-radius: 8px;
  background: color-mix(in srgb, var(--band-over) 14%, var(--surface-1));
  color: var(--band-over-ink);
  font-size: 14px;
  font-weight: 600;
}
.gate-foot { margin: 4px 0 0; font-size: 12px; color: var(--muted); line-height: 1.5; }


.gate-card input[type="email"] {
  font: inherit;
  padding: 12px 14px;
  border-radius: 10px;
  border: 1px solid var(--baseline);
  background: var(--surface-1);
  color: var(--ink);
}
.gate-card input[type="email"]:focus-visible { outline: 3px solid var(--series-1); outline-offset: 1px; }
.linkish {
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  background: none;
  border: none;
  padding: 2px 0;
  color: var(--series-1);
  cursor: pointer;
  justify-self: start;
}
.linkish:hover { text-decoration: underline; }
.linkish:focus-visible { outline: 3px solid var(--series-1); outline-offset: 2px; }
.gate-note {
  margin: 0;
  padding: 10px 12px;
  border-radius: 8px;
  background: color-mix(in srgb, var(--series-1) 12%, var(--surface-1));
  color: var(--ink-2);
  font-size: 13.5px;
}


/* ---- Account mode banner --------------------------------------------------- */
.mode-bar {
  padding: 9px 24px;
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: 0.02em;
  text-align: center;
}
.mode-admin { background: #2a476b; color: #fff; }
.mode-demo { background: #fab219; color: #3d2900; }

/* ---- Shell --------------------------------------------------------------- */

.topbar { background: var(--navy); color: var(--navy-ink); }
.topbar-inner {
  max-width: 1100px;
  margin: 0 auto;
  padding: 18px 24px;
  display: flex;
  gap: 16px;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
}
.topbar-brand {
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  opacity: 0.75;
}
.topbar h1 { font-size: 22px; }
.topbar-actions { display: flex; gap: 8px; }

.filters {
  max-width: 1100px;
  margin: 0 auto;
  padding: 16px 24px 0;
  display: flex;
  gap: 14px;
  flex-wrap: wrap;
  align-items: end;
}
.filter { display: grid; gap: 5px; }
.filter label { font-size: 12px; font-weight: 700; color: var(--muted); }
.filter select {
  font: inherit;
  padding: 8px 12px;
  border-radius: 9px;
  border: 1px solid var(--baseline);
  background: var(--surface-1);
  color: var(--ink);
}
.filter-toggle { align-self: end; padding-bottom: 6px; }
.switch { display: flex; gap: 8px; align-items: center; font-size: 13px; color: var(--ink-2); font-weight: 600; }

/* minmax(0, 1fr) rather than the default `auto`: an auto track is floored at
   the min-content width of its widest item, so one wide data table stretched
   the whole column past the viewport and put a horizontal scrollbar on the
   page. Wide content scrolls inside its own box instead. */
.wrap {
  max-width: 1100px;
  margin: 0 auto;
  padding: 20px 24px 40px;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 20px;
}

.foot {
  max-width: 1100px;
  margin: 0 auto;
  padding: 0 24px 40px;
  color: var(--muted);
  font-size: 12px;
  line-height: 1.6;
}

/* ---- Summary & tiles ------------------------------------------------------ */

.summary {
  background: var(--surface-1);
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  padding: 18px 20px;
}
.summary p { margin: 0 0 8px; font-size: 16px; line-height: 1.55; color: var(--ink-2); }
.summary p:last-child { margin-bottom: 0; }
.summary strong { color: var(--ink); }
.summary-flag { color: var(--band-over-ink); font-weight: 700; }
.summary-scope { font-size: 13px; color: var(--muted); }

.tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(190px, 100%), 1fr));
  gap: 12px;
}
.tile {
  background: var(--surface-1);
  border: 1px solid var(--hairline);
  border-left: 4px solid var(--baseline);
  border-radius: var(--radius);
  padding: 14px 16px;
}
.tile-adequate { border-left-color: var(--band-adequate); }
.tile-marginal { border-left-color: var(--band-marginal); }
.tile-over { border-left-color: var(--band-over); }
.tile-label { font-size: 12px; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: 0.05em; }
.tile-value { font-size: 34px; font-weight: 700; line-height: 1.15; margin: 4px 0 2px; }
.tile-note { font-size: 12.5px; color: var(--ink-2); line-height: 1.4; }

/* ---- Figures -------------------------------------------------------------- */

.viz, .panel {
  background: var(--surface-1);
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  padding: 18px 20px 14px;
  margin: 0;
}
.viz-head { margin-bottom: 10px; }
.viz-head h3, .panel h3 { font-size: 17px; }
.viz-note { margin: 6px 0 0; font-size: 13px; color: var(--muted); line-height: 1.5; max-width: 74ch; }
.viz-plot { overflow-x: auto; }
.viz-plot svg { display: block; }
.viz-empty {
  margin: 0;
  padding: 18px 20px;
  background: var(--surface-1);
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  color: var(--muted);
  font-size: 14px;
}

.viz-legend {
  list-style: none;
  margin: 0 0 10px;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 6px 18px;
  font-size: 12.5px;
  color: var(--ink-2);
  font-weight: 600;
}
.viz-legend li { display: flex; align-items: center; gap: 7px; }
.swatch { width: 13px; height: 13px; border-radius: 4px; background: var(--baseline); flex: none; }
.swatch-adequate { background: var(--band-adequate); }
.swatch-marginal { background: var(--band-marginal); }
.swatch-over { background: var(--band-over); }
.swatch-nd { background: var(--surface-1); border: 2px dashed var(--muted); }

/* Chart ink: axis furniture recedes, values do not. Text never wears the
   series colour except for the value labels, which sit alone on the surface. */
.viz-grid { stroke: var(--grid); stroke-width: 1; }
.viz-row { stroke: var(--grid); stroke-width: 1; stroke-dasharray: 2 4; }
.viz-ref { stroke: var(--ink-2); stroke-width: 2; }
.viz-ref-soft { stroke: var(--muted); stroke-width: 1.5; stroke-dasharray: 6 4; }
.viz-tick { fill: var(--muted); font-size: 11px; font-variant-numeric: tabular-nums; }
.viz-label { fill: var(--ink-2); font-size: 12.5px; font-weight: 600; }
.viz-axis-title { fill: var(--muted); font-size: 11.5px; font-weight: 600; }
.viz-ref-label { font-size: 11px; font-weight: 700; fill: var(--ink-2); }
.viz-ref-soft-label { fill: var(--muted); font-weight: 600; }
.viz-series-label { fill: var(--ink-2); font-size: 12px; font-weight: 600; }
.viz-value { font-size: 12px; font-weight: 700; font-variant-numeric: tabular-nums; fill: var(--ink-2); }
.viz-value-over { fill: var(--band-over-ink); }
.viz-value-marginal { fill: var(--band-marginal-ink); }
.viz-value-adequate { fill: var(--band-adequate-ink); }
.viz-seg-value { font-size: 11.5px; font-weight: 700; fill: #fff; }
.viz-seg-value-marginal { fill: #3d2900; }

.viz-dot { stroke: var(--surface-1); stroke-width: 2; cursor: default; }
.viz-dot:focus-visible { outline: none; stroke: var(--ink); stroke-width: 2.5; }
.viz-dot-nd { stroke-dasharray: 3 2; }
.viz-seg { stroke: var(--surface-1); stroke-width: 0; }
.viz-seg:focus-visible { outline: none; stroke: var(--ink); stroke-width: 2; }

.viz-table { margin-top: 12px; border-top: 1px solid var(--hairline); padding-top: 8px; }
.viz-table summary {
  cursor: pointer;
  font-size: 13px;
  font-weight: 700;
  color: var(--ink-2);
  padding: 4px 0;
}
.viz-table table, .data-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
  margin-top: 8px;
}
.viz-table th, .viz-table td, .data-table th, .data-table td {
  text-align: left;
  padding: 7px 10px;
  border-bottom: 1px solid var(--grid);
}
.viz-table th, .data-table th {
  font-size: 11.5px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
}
.viz-table td, .data-table td { color: var(--ink-2); font-variant-numeric: tabular-nums; }
.table-wrap { overflow-x: auto; }
.data-table .num { text-align: right; }

.chip {
  display: inline-block;
  padding: 3px 9px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 700;
  border: 1px solid;
}
.chip-adequate { color: var(--band-adequate-ink); border-color: var(--band-adequate); background: color-mix(in srgb, var(--band-adequate) 12%, var(--surface-1)); }
.chip-marginal { color: var(--band-marginal-ink); border-color: var(--band-marginal); background: color-mix(in srgb, var(--band-marginal) 20%, var(--surface-1)); }
.chip-over { color: var(--band-over-ink); border-color: var(--band-over); background: color-mix(in srgb, var(--band-over) 12%, var(--surface-1)); }

/* ---- Sites index ---------------------------------------------------------- */

.summary-flag-inline { color: var(--band-over-ink); font-weight: 700; }

.site-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
  gap: 14px;
}
.site-card {
  font: inherit;
  text-align: left;
  display: grid;
  gap: 8px;
  align-content: start;
  padding: 18px 20px;
  border-radius: var(--radius);
  border: 1px solid var(--hairline);
  border-left: 5px solid var(--baseline);
  background: var(--surface-1);
  color: var(--ink);
  cursor: pointer;
}
.site-card-adequate { border-left-color: var(--band-adequate); }
.site-card-marginal { border-left-color: var(--band-marginal); }
.site-card-over { border-left-color: var(--band-over); }
.site-card:hover { border-color: var(--series-1); }
.site-card:focus-visible { outline: 3px solid var(--series-1); outline-offset: 2px; }
.site-card-head { display: flex; gap: 10px; align-items: center; justify-content: space-between; flex-wrap: wrap; }
.site-name { font-size: 18px; font-weight: 700; }
.site-detail { font-size: 13px; color: var(--ink-2); line-height: 1.5; }
.site-stats { display: flex; gap: 16px; flex-wrap: wrap; font-size: 12.5px; color: var(--ink-2); }
.site-stats strong { font-size: 15px; color: var(--ink); }
.site-last { font-size: 12px; color: var(--muted); }

/* ---- Site header & tabs ---------------------------------------------------- */

.site-head { display: grid; gap: 12px; }
.crumb {
  justify-self: start;
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  background: none;
  border: none;
  padding: 4px 0;
  color: var(--ink-2);
  cursor: pointer;
}
.crumb:hover { color: var(--series-1); text-decoration: underline; }
.crumb:focus-visible { outline: 3px solid var(--series-1); outline-offset: 2px; }

.site-banner {
  display: flex;
  gap: 20px;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  padding: 18px 22px;
  border-radius: var(--radius);
  border: 1px solid var(--hairline);
  border-left: 6px solid var(--baseline);
  background: var(--surface-1);
}
.site-banner-adequate { border-left-color: var(--band-adequate); }
.site-banner-marginal { border-left-color: var(--band-marginal); }
.site-banner-over { border-left-color: var(--band-over); }
.site-banner-label { font-size: 11.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: var(--muted); }
.site-banner-head { font-size: 25px; font-weight: 700; line-height: 1.2; margin-top: 2px; }
.site-banner-adequate .site-banner-head { color: var(--band-adequate-ink); }
.site-banner-marginal .site-banner-head { color: var(--band-marginal-ink); }
.site-banner-over .site-banner-head { color: var(--band-over-ink); }
.site-banner-detail { margin: 6px 0 0; font-size: 13.5px; color: var(--ink-2); line-height: 1.5; max-width: 60ch; }
.site-banner-rate { text-align: right; }
.rate-num { display: block; font-size: 34px; font-weight: 700; line-height: 1; }
.rate-cap { display: block; font-size: 11.5px; color: var(--muted); max-width: 18ch; margin-top: 4px; }

.site-banner-action {
  margin: 8px 0 0;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--ink);
  max-width: 60ch;
}

/* Deliberately quiet: this qualifies the compliance finding, it does not
   compete with it. A limited-confidence result still needs the verdict read
   first, then the caveat. */
.confidence {
  padding: 12px 16px;
  border-radius: var(--radius);
  border: 1px solid var(--hairline);
  border-left: 4px solid var(--baseline);
  background: var(--surface-1);
}
.confidence-high { border-left-color: var(--band-adequate); }
.confidence-moderate { border-left-color: var(--band-marginal); }
.confidence-limited { border-left-color: var(--band-over); }
.confidence-head { display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap; }
.confidence-label {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted);
}
.confidence-level { font-size: 15px; font-weight: 700; }
.confidence-limited .confidence-level { color: var(--band-over-ink); }
.confidence-moderate .confidence-level { color: var(--band-marginal-ink); }
.confidence-high .confidence-level { color: var(--band-adequate-ink); }
.confidence-why { margin: 4px 0 0; font-size: 13px; color: var(--ink-2); line-height: 1.5; max-width: 70ch; }
.confidence-note {
  margin: 8px 0 0;
  font-size: 13px;
  color: var(--ink);
  line-height: 1.5;
  max-width: 70ch;
  padding-left: 12px;
  border-left: 2px solid var(--grid);
}

.tabbar {
  display: flex;
  gap: 4px;
  flex-wrap: wrap;
  border-bottom: 2px solid var(--grid);
  margin-bottom: -6px;
}
.tab {
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  background: none;
  border: none;
  border-bottom: 3px solid transparent;
  margin-bottom: -2px;
  padding: 10px 14px;
  color: var(--ink-2);
  cursor: pointer;
}
.tab:hover { color: var(--ink); }
.tab-on { color: var(--series-1); border-bottom-color: var(--series-1); }
.tab:focus-visible { outline: 3px solid var(--series-1); outline-offset: -3px; }

/* ---- Site reports --------------------------------------------------------- */

.report-picker {
  display: grid;
  /* A <select> is as wide as its longest option unless told otherwise, and
     these options carry a date, a site and a job number. Left alone it pushed
     the whole page wider than a phone screen. */
  grid-template-columns: minmax(0, 1fr);
  gap: 5px;
  max-width: 460px;
  margin: 12px 0 14px;
}
.report-picker label { font-size: 12px; font-weight: 700; color: var(--muted); }
.report-picker select {
  font: inherit;
  width: 100%;
  min-width: 0;
  padding: 9px 12px;
  border-radius: 9px;
  border: 1px solid var(--baseline);
  background: var(--surface-1);
  color: var(--ink);
}

.report-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(230px, 100%), 1fr)); gap: 12px; }
.report-card {
  font: inherit;
  text-align: left;
  display: grid;
  gap: 6px;
  align-content: start;
  padding: 14px 16px;
  border-radius: var(--radius);
  border: 1px solid var(--hairline);
  background: var(--plane);
  color: var(--ink);
  cursor: pointer;
}
.report-card:hover { border-color: var(--series-1); }
.report-card:focus-visible { outline: 3px solid var(--series-1); outline-offset: 2px; }
.report-title { font-weight: 700; font-size: 15px; }
.report-desc { font-size: 12.5px; color: var(--ink-2); line-height: 1.5; }
.report-tag {
  justify-self: start;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--band-adequate-ink);
  border: 1px solid var(--band-adequate);
  border-radius: 999px;
  padding: 2px 9px;
}
.report-tag-off { color: var(--muted); border-color: var(--baseline); }
.report-error {
  margin: 12px 0 0;
  padding: 10px 12px;
  border-radius: 8px;
  background: color-mix(in srgb, var(--band-marginal) 18%, var(--surface-1));
  color: var(--band-marginal-ink);
  font-size: 13.5px;
  font-weight: 600;
}

/* ---- Printable documents --------------------------------------------------
   Fixed overlay while on screen; on paper the chrome disappears and each
   .sheet takes its own page. Always light-on-white regardless of theme --
   these are printed, and a dark background would empty a toner cartridge. */

.print-view {
  position: fixed;
  inset: 0;
  z-index: 100;
  /* Both axes: an A4 sheet is 794px and a phone is 375px, and a document
     preview cannot be reflowed to fit without misrepresenting the printed
     page. So the sheet scrolls inside the overlay rather than dragging the
     page sideways behind it. */
  overflow: auto;
  background: #55585c;
  color-scheme: light;
}
body.printing { overflow: hidden; }

.print-bar {
  position: sticky;
  top: 0;
  z-index: 2;
  display: flex;
  gap: 16px;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  padding: 12px 20px;
  background: var(--navy);
  color: #fff;
}
.print-meta { display: block; font-size: 12px; opacity: 0.8; font-weight: 400; }
.print-bar-actions { display: flex; gap: 8px; }
.btn.ghost-dark { background: transparent; color: #fff; border-color: rgba(255, 255, 255, 0.5); }

.print-sheets { padding: 22px 16px 60px; display: grid; gap: 22px; justify-items: center; }

.sheet {
  width: 100%;
  max-width: 210mm;
  min-height: 260mm;
  padding: 18mm 16mm;
  background: #fff;
  color: #101010;
  font-size: 12.4px;
  line-height: 1.6;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.32);
}
.sheet h1 { font-size: 21px; margin: 2px 0 0; }
.sheet h2 { font-size: 14px; margin: 20px 0 6px; color: #2a476b; }
.sheet p { margin: 0 0 10px; }
.sheet-head { border-bottom: 3px solid #2a476b; padding-bottom: 10px; margin-bottom: 16px; }
.sheet-brand { font-size: 10.5px; font-weight: 800; letter-spacing: 0.14em; text-transform: uppercase; color: #6b6f74; }
.sheet-kind { font-size: 12px; font-weight: 700; color: #2a476b; margin-top: 6px; }
.sheet-sub { font-size: 11.5px; color: #55585c; margin: 4px 0 0; }
.letter-to { font-size: 16px; font-weight: 700; margin: 14px 0 12px; }
.letter-flag {
  padding: 10px 12px;
  border-left: 4px solid #d03b3b;
  background: #fbeaea;
  font-weight: 600;
}
.sheet-foot { margin-top: 22px; padding-top: 10px; border-top: 1px solid #ccc; font-size: 10.5px; color: #55585c; }
.sheet-confidential { font-weight: 700; color: #9c2020; }
.muted-note { color: #6b6f74; font-size: 11px; }

.sheet-table { width: 100%; border-collapse: collapse; margin: 8px 0 12px; font-size: 11.6px; }
.sheet-table th, .sheet-table td { border: 1px solid #b9bdc2; padding: 6px 8px; text-align: left; vertical-align: top; }
.sheet-table th { background: #2a476b; color: #fff; font-weight: 700; }

/* Status colour plus the word, never the colour alone — the same rule the
   charts follow, and doubly necessary on a page that may be photocopied. */
.band { display: inline-block; padding: 2px 8px; border-radius: 999px; font-weight: 700; font-size: 10.5px; border: 1.5px solid; }
.band-adequate { color: #0b6b0b; border-color: #0ca30c; background: #eaf7ea; }
.band-marginal { color: #7a5300; border-color: #fab219; background: #fdf3dd; }
.band-over { color: #9c2020; border-color: #d03b3b; background: #fbeaea; }


.letter-none { color: #9c2020; font-weight: 700; }
.letter-caveat {
  padding: 9px 12px;
  border-left: 4px solid #2a476b;
  background: #eef2f6;
  font-size: 11.6px;
}

.talk-lede { font-size: 11.5px; color: #55585c; font-style: italic; }
.talk-prompt { padding: 10px 12px; background: #eef2f6; border-left: 4px solid #2a476b; }
.talk-signoff { display: flex; gap: 16px; margin: 18px 0 8px; }
.talk-signoff > div { flex: 1; font-size: 10.5px; color: #55585c; }
.talk-signoff .rule { border-bottom: 1px solid #6b6f74; height: 22px; }
.attend-table td { height: 22px; }

.sheet-notice { text-align: center; }
.notice-head { border-bottom: 3px solid #2a476b; padding-bottom: 8px; }
.notice-kind { font-size: 13px; font-weight: 700; color: #2a476b; margin-top: 4px; }
.notice-where { font-size: 12px; color: #55585c; margin: 10px 0 0; }
.notice-headline { font-size: 30px; line-height: 1.2; margin: 12px 0 6px; }
.notice-strap { font-size: 15px; color: #33363a; margin-bottom: 18px; }
.notice-over .notice-headline { color: #9c2020; }
.notice-marginal .notice-headline { color: #7a5300; }
.notice-adequate .notice-headline { color: #0b6b0b; }
.notice-figures { display: flex; gap: 12px; margin: 16px 0 22px; }
.notice-fig { flex: 1; padding: 14px 8px; border-radius: 10px; border: 2px solid; }
.notice-fig-adequate { border-color: #0ca30c; background: #eaf7ea; }
.notice-fig-marginal { border-color: #fab219; background: #fdf3dd; }
.notice-fig-over { border-color: #d03b3b; background: #fbeaea; }
.notice-num { display: block; font-size: 40px; font-weight: 700; line-height: 1; }
.notice-cap { display: block; font-size: 11.5px; font-weight: 700; margin-top: 6px; }
.notice-table { text-align: left; }
.notice-foot { margin-top: 20px; padding-top: 12px; border-top: 1px solid #ccc; text-align: left; font-size: 11.5px; }
.notice-privacy { color: #55585c; font-style: italic; }


/* ---- Risk qualifications --------------------------------------------------
   The consultant's footnotes from the report's results summary. Rendered as a
   list rather than a table because the text is prose, and the mark is kept
   visible so a client can match it to the same mark in their report. */

.qual-list { list-style: none; margin: 12px 0 0; padding: 0; display: grid; gap: 10px; }
.qual {
  display: grid;
  grid-template-columns: 28px minmax(0, 1fr);
  gap: 12px;
  padding: 12px 14px;
  border-radius: 10px;
  border: 1px solid var(--hairline);
  border-left: 4px solid var(--baseline);
  background: var(--plane);
}
.qual-ppe, .qual-controls { border-left-color: var(--band-marginal); }
.qual-statistical, .qual-conditions { border-left-color: var(--series-1); }
.qual-mark {
  font-weight: 800;
  font-size: 15px;
  text-align: center;
  color: var(--ink-2);
  font-variant-numeric: tabular-nums;
}
.qual-head { font-size: 13.5px; font-weight: 700; }
.qual-text { margin: 3px 0 0; font-size: 13px; color: var(--ink-2); line-height: 1.5; }
.qual-where { margin: 5px 0 0; font-size: 12px; color: var(--muted); }


/* ---- Neutral site banner & counts ------------------------------------------
   The site line carries no verdict, so it takes no status colour. The three
   counts sit beside it and let the reader see the shape of the result without
   a headline telling them what to conclude. */
.site-banner-neutral { border-left-color: var(--series-1); }
.site-banner-counts { display: flex; gap: 18px; flex-wrap: wrap; }
.scount {
  display: grid;
  gap: 2px;
  font-size: 11.5px;
  font-weight: 600;
  color: var(--muted);
  text-align: right;
}
.scount strong { font-size: 26px; font-weight: 700; line-height: 1; color: var(--ink); }
.scount-over strong { color: var(--band-over-ink); }
.scount-marginal strong { color: var(--band-marginal-ink); }
.scount-adequate strong { color: var(--band-adequate-ink); }

.site-activities { color: var(--muted); font-size: 12px; }
.area-process { margin: 8px 0 0; font-size: 14px; line-height: 1.6; color: var(--ink-2); max-width: 75ch; }
.area-list { margin-top: 14px; }
.area-list h4 { margin: 0 0 4px; font-size: 13px; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: 0.05em; }
.area-list ul { margin: 0; padding-left: 20px; }
.area-list li { font-size: 13.5px; line-height: 1.6; color: var(--ink-2); margin-bottom: 4px; }
.muted-inline { font-size: 11px; color: var(--muted); }

/* ---- Opportunities for improvement ----------------------------------------- */

.ofi-list { list-style: none; margin: 12px 0 0; padding: 0; display: grid; gap: 10px; }
.ofi {
  padding: 12px 16px;
  border-radius: 10px;
  border: 1px solid var(--hairline);
  border-left: 4px solid var(--series-1);
  background: var(--plane);
}
.ofi-interim { border-left-color: var(--band-marginal); }
.ofi-monitoring { border-left-color: var(--series-3); }
.ofi-head { display: flex; gap: 10px; align-items: center; justify-content: space-between; flex-wrap: wrap; }
.ofi-kind {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
}
.ofi-area, .ofi-area-static {
  font: inherit;
  font-size: 12px;
  font-weight: 700;
  color: var(--series-1);
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  text-align: right;
}
.ofi-area:hover { text-decoration: underline; }
.ofi-area:focus-visible { outline: 3px solid var(--series-1); outline-offset: 2px; }
.ofi-area-static { color: var(--muted); cursor: default; }
.ofi-text { margin: 5px 0 0; font-size: 14px; line-height: 1.55; color: var(--ink); max-width: 80ch; }


/* ---- Qualifier chips -------------------------------------------------------
   Shown on every area card and in the area header, so a green "Compliant" chip
   is never seen without the caveats the report attached to it. Each carries its
   footnote mark where it has one, so it can be matched to the same mark in the
   client's report. */
.qual-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 2px; }
.qchip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 11px;
  font-weight: 700;
  padding: 3px 9px;
  border-radius: 999px;
  border: 1px solid var(--baseline);
  color: var(--ink-2);
  background: var(--surface-1);
  white-space: nowrap;
}
.qchip-mark {
  font-variant-numeric: tabular-nums;
  opacity: 0.75;
  border-right: 1px solid var(--baseline);
  padding-right: 5px;
}
.qchip-monitor, .qchip-warn { border-color: var(--band-marginal); color: var(--band-marginal-ink); }
.qchip-controls { border-color: var(--band-over); color: var(--band-over-ink); }
.qchip-ppe { border-color: var(--band-marginal); color: var(--band-marginal-ink); }
.qchip-statistical, .qchip-conditions { border-color: var(--series-1); color: var(--series-1); }
.site-banner-rating { margin-top: 6px; }


/* ---- Area photographs ------------------------------------------------------ */
.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(220px, 100%), 1fr));
  gap: 12px;
  margin-top: 12px;
}
.shot { margin: 0; }
.shot img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: 10px;
  border: 1px solid var(--hairline);
  background: var(--plane);
  display: block;
}
.shot figcaption { margin-top: 5px; font-size: 11.5px; color: var(--muted); word-break: break-word; }


/* ---- Results summary grid ---------------------------------------------------
   The report's own table. Status colours here are the fieldsheet's, not the
   dashboard's exposure bands, so the client sees the same fills they have in
   their report. Each cell carries a symbol as well as a colour. */
.grid-table { border-collapse: collapse; font-size: 12.5px; margin-top: 12px; }
.grid-table th, .grid-table td { border: 1px solid var(--baseline); padding: 6px 8px; }
.grid-corner { text-align: left; min-width: 170px; background: var(--plane); }
.grid-area {
  vertical-align: bottom;
  font-size: 11.5px;
  font-weight: 700;
  background: var(--plane);
  max-width: 90px;
  min-width: 70px;
}
.grid-area span { display: block; line-height: 1.25; }
.grid-row-head { text-align: left; font-weight: 600; font-size: 12.5px; background: var(--plane); }
.grid-cell { text-align: center; vertical-align: middle; white-space: nowrap; }
.grid-symbol { font-weight: 800; font-size: 14px; }
.grid-marks {
  font-size: 10px;
  font-weight: 700;
  vertical-align: super;
  margin-left: 3px;
  opacity: 0.85;
  font-variant-numeric: tabular-nums;
}
.grid-adequate { background: #a9d08e; color: #123d12; }
.grid-marginal { background: #f8cbad; color: #6b2f13; }
.grid-monitor  { background: #d9e1f2; color: #1b3a63; }
.grid-na       { background: #d9d9d9; color: #444; }
.grid-none     { background: var(--surface-1); }

.grid-legend { display: grid; gap: 8px; margin-top: 16px; }
.glegend {
  display: grid;
  grid-template-columns: 30px minmax(0, 1fr);
  gap: 10px;
  align-items: start;
  padding: 8px 10px;
  border-radius: 8px;
  border: 1px solid var(--hairline);
  border-left: 4px solid var(--baseline);
  background: var(--plane);
  font-size: 13px;
}
.glegend .grid-symbol { text-align: center; }
.glegend p { margin: 3px 0 0; font-size: 12.5px; color: var(--ink-2); line-height: 1.5; }
.glegend-adequate { border-left-color: #0ca30c; }
.glegend-marginal { border-left-color: #ec835a; }
.glegend-monitor  { border-left-color: var(--series-1); }
.glegend-na       { border-left-color: var(--baseline); }

.grid-footnotes { margin-top: 16px; padding-top: 10px; border-top: 1px solid var(--hairline); }
.grid-footnotes h4 { margin: 0 0 6px; font-size: 12px; text-transform: uppercase; letter-spacing: 0.05em; color: var(--muted); }
.grid-footnotes p { margin: 0 0 4px; font-size: 12.5px; color: var(--ink-2); }

.chip-monitor { color: var(--series-1); border-color: var(--series-1); background: color-mix(in srgb, var(--series-1) 12%, var(--surface-1)); }
.chip-na { color: var(--muted); border-color: var(--baseline); background: var(--plane); }
.chip-note { font-weight: 500; opacity: 0.75; }


/* ---- Action priorities ------------------------------------------------------ */
.action-list { margin: 12px 0 0; padding-left: 0; list-style: none; counter-reset: action; display: grid; gap: 12px; }
.action {
  counter-increment: action;
  position: relative;
  padding: 14px 16px 14px 52px;
  border-radius: 10px;
  border: 1px solid var(--hairline);
  border-left: 4px solid var(--baseline);
  background: var(--plane);
}
.action::before {
  content: counter(action);
  position: absolute;
  left: 14px;
  top: 13px;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-size: 13px;
  font-weight: 800;
  background: var(--surface-1);
  border: 1px solid var(--baseline);
  color: var(--ink-2);
}
.action-marginal { border-left-color: var(--band-marginal); }
.action-marginal::before { border-color: var(--band-marginal); color: var(--band-marginal-ink); }
.action-monitor { border-left-color: var(--series-1); }
.action-monitor::before { border-color: var(--series-1); color: var(--series-1); }
.action-head { display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap; }
.action-area {
  font: inherit;
  font-size: 15px;
  font-weight: 700;
  background: none;
  border: none;
  padding: 0;
  color: var(--series-1);
  cursor: pointer;
  text-align: left;
}
.action-area:hover { text-decoration: underline; }
.action-area:focus-visible { outline: 3px solid var(--series-1); outline-offset: 2px; }
.action-contaminants { font-size: 12.5px; color: var(--muted); }
.action-what { margin: 5px 0 0; font-size: 14px; font-weight: 600; color: var(--ink); line-height: 1.5; }
.action-also { margin: 4px 0 0; font-size: 13px; color: var(--ink-2); line-height: 1.5; }
.action-why { margin: 5px 0 0; font-size: 12.5px; color: var(--ink-2); line-height: 1.5; }

.clear-list { margin: 10px 0 0; padding: 0; list-style: none; display: flex; flex-wrap: wrap; gap: 8px 18px; }
.clear-list .action-area { font-size: 13.5px; font-weight: 600; }
.footnote-line { margin: 0 0 5px; font-size: 13px; color: var(--ink-2); line-height: 1.5; }
details.viz-table > summary { padding: 6px 0; }


/* ---- Action sections -------------------------------------------------------- */
.action-section { border-left: 4px solid var(--baseline); }
.action-section.action-marginal { border-left-color: var(--band-marginal); }
.action-section.action-monitor { border-left-color: var(--series-1); }
.action-section h3 { display: flex; align-items: center; gap: 10px; }
.action-rank {
  flex: none;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-size: 13px;
  font-weight: 800;
  background: var(--plane);
  border: 1px solid var(--baseline);
  color: var(--ink-2);
}
.action-marginal .action-rank { border-color: var(--band-marginal); color: var(--band-marginal-ink); }
.action-monitor .action-rank { border-color: var(--series-1); color: var(--series-1); }
.action-requirement {
  margin: 8px 0 0;
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--ink-2);
  max-width: 78ch;
}
.action-areas { list-style: none; margin: 12px 0 0; padding: 0; display: grid; gap: 8px; }
.action-areas li {
  display: flex;
  gap: 10px;
  align-items: baseline;
  flex-wrap: wrap;
  padding: 9px 12px;
  border-radius: 8px;
  background: var(--plane);
  border: 1px solid var(--hairline);
}


.action-group {
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 8px 0 -8px;
  padding-bottom: 6px;
  border-bottom: 2px solid var(--grid);
}
.action-section.action-adequate { border-left-color: var(--band-adequate); }
.action-adequate .action-rank { border-color: var(--band-adequate); color: var(--band-adequate-ink); }


/* ---- Merge names (administrators only) ------------------------------------ */

.btn-small { padding: 7px 12px; font-size: 13px; }
.summary .btn-small { justify-self: start; margin-top: 4px; }
.names-entry { margin: 0 0 4px; }

.names-scope { margin: 0; color: var(--muted); font-size: 13.5px; }

.names-list, .merge-list { list-style: none; margin: 12px 0 0; padding: 0; display: grid; gap: 2px; }

.names-list label {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: 10px;
  align-items: center;
  padding: 9px 10px;
  border-radius: 8px;
  cursor: pointer;
}
.names-list label:hover { background: var(--plane); }
.names-raw { font-weight: 600; overflow-wrap: anywhere; }
.names-count { color: var(--muted); font-size: 13px; white-space: nowrap; }

.merge-list li {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 12px;
  align-items: center;
  padding: 10px;
  border-radius: 8px;
  background: var(--plane);
}
.merge-from { display: block; color: var(--muted); font-size: 13px; overflow-wrap: anywhere; }

.merge-action { display: grid; gap: 10px; justify-items: start; }
.merge-choices { display: grid; gap: 4px; }
.merge-choices label { display: flex; gap: 8px; align-items: center; cursor: pointer; }
.merge-other {
  font: inherit;
  width: min(420px, 100%);
  padding: 10px 12px;
  border-radius: 10px;
  border: 1px solid var(--baseline);
  background: var(--surface-1);
  color: var(--ink);
}
.merge-other:focus-visible { outline: 3px solid var(--series-1); outline-offset: 1px; }

/* ---- Tooltip -------------------------------------------------------------- */

.viz-tip {
  position: fixed;
  z-index: 90;
  max-width: 280px;
  padding: 9px 12px;
  border-radius: 9px;
  background: var(--ink);
  color: var(--surface-1);
  font-size: 12.5px;
  line-height: 1.5;
  pointer-events: none;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.28);
}
.tip-band { display: inline-block; margin-top: 3px; font-weight: 700; }
.tip-band-adequate { color: #6ee06e; }
.tip-band-marginal { color: #fdd47a; }
.tip-band-over { color: #ff9d9d; }

/* ---- Accessibility & print ------------------------------------------------ */

@media (prefers-reduced-motion: no-preference) {
  .viz-dot { transition: r 120ms ease; }
  .viz-dot:hover { r: 8; }
}

/* forced-colors strips the fills that carry the bands, so the hatch patterns
   become the encoding rather than an option. */
@media (forced-colors: active) {
  .viz-dot, .viz-seg { forced-color-adjust: none; }
  .swatch { border: 1px solid CanvasText; }
}

@page { size: A4 portrait; margin: 0; }

@media print {
  body { background: #fff; }
  .no-print, .topbar-actions, .viz-tip { display: none !important; }
  .viz, .panel, .summary, .tile { break-inside: avoid; border: 1px solid #bbb; }
  .viz-table { display: none; }
  .wrap { max-width: none; padding: 0; }

  /* With a document open, the dashboard behind it must not print too. Hiding
     #app rather than un-parenting the overlay keeps the app's state intact, so
     closing the document returns to the same filters and scroll position. */
  body.printing > *:not(.print-view) { display: none !important; }
  .print-view {
    position: static;
    overflow: visible;
    background: #fff;
  }
  .print-sheets { padding: 0; display: block; }
  .sheet {
    max-width: none;
    min-height: 0;
    box-shadow: none;
    padding: 14mm 14mm;
    /* Each document is its own page; the last must not emit a blank one. */
    break-after: page;
  }
  .sheet:last-child { break-after: auto; }
  .sheet-table { break-inside: auto; }
  .sheet-table tr { break-inside: avoid; }
  .talk-attend, .notice-figures, .letter-flag { break-inside: avoid; }

  /* Backgrounds carry the judgement bands; without this most browsers drop
     them and every band prints as an identical white pill. */
  .band, .notice-fig, .letter-flag, .talk-prompt, .sheet-table th {
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }
}

@media (max-width: 640px) {
  .topbar-inner, .filters, .wrap, .foot { padding-left: 16px; padding-right: 16px; }
  .tile-value { font-size: 28px; }
  .viz, .panel { padding: 14px 14px 10px; }
}

/* ---- Assessments (administrators only) ------------------------------------ */

.assess-list { list-style: none; margin: 12px 0 0; padding: 0; display: grid; gap: 6px; }

.assess-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto auto;
  gap: 12px;
  align-items: center;
  padding: 11px 12px;
  border-radius: 10px;
  background: var(--plane);
  border-left: 4px solid var(--baseline);
}
/* Published is the state that carries consequence, so it is the one marked. */
.assess-row.is-published { border-left-color: var(--band-adequate); }

.assess-main { display: grid; gap: 2px; min-width: 0; }
.assess-title { font-weight: 700; overflow-wrap: anywhere; }
.assess-sub { color: var(--muted); font-size: 13px; }

.assess-stage, .assess-state { font-size: 12.5px; font-weight: 700; white-space: nowrap; }
.stage-done { color: var(--band-adequate-ink); }
.stage-open { color: var(--muted); }
.assess-state { color: var(--ink-2); }
.is-published .assess-state { color: var(--band-adequate-ink); }

@media (max-width: 700px) {
  .assess-row { grid-template-columns: minmax(0, 1fr); }
  .assess-stage, .assess-state { white-space: normal; }
}
