:root{--bg:#04121f;--surface:#0e1b28;--surface-2:#182531;--line-soft:#1d2a35;--line:#36414c;--line-strong:#687179;--accent:#0284c7;--link:#2595cf;--focus:#6cb8df;--accent-wash:#026fa9;--bar-bg:rgba(4,18,31,.82);--ab-image:repeating-radial-gradient(circle at 0 0,#033958 0 1px,transparent 1px 24px);--ab-size:24px 24px

  /* type */
  --fs-xs:0.75rem;--fs-sm:0.8125rem;--fs-table:0.9375rem;--fs-base:1rem;--fs-lead:1.125rem;
  --fs-h3:1.25rem;
  --fs-h2:clamp(1.375rem,1.25rem + .5vw,1.625rem);
  --fs-h1:clamp(1.75rem,1.35rem + 1.8vw,2.375rem);
  --fs-stat:clamp(1.75rem,1.4rem + 1.6vw,2.25rem);

  /* space — 4px base */
  --s1:.25rem;--s2:.5rem;--s3:.75rem;--s4:1rem;--s5:1.5rem;--s6:2rem;--s7:3rem;

  /* shape */
  --r-sm:6px;--r-md:10px;--wrap:67.5rem;--gutter:1rem;--measure:66ch;--tap:1.5rem;--bar-h:3.25rem;

  /* ink */
  --ink:#e8ecea;--ink-2:#cfd8d5;--ink-3:#93a09c;

  /* status — GLOBAL, identical on all sixteen rooms */
  --ok-bg:#092b1e;--ok-ink:#6ee7b7;--ok-edge:#459273;
  --warn-bg:#29240c;--warn-ink:#fbbf24;--warn-edge:#7c6a2e;
  --stop-bg:#2f1217;--stop-ink:#fda4af;--stop-edge:#8b5a63;
  --flat-bg:#202a25;--flat-ink:#cfd8d5;--flat-edge:#394139;
}

/* PART 5d-ii — THE SITE'S OWN ABSTRACT. Its own fixed layer, its own repeating geometry, masked
   so it fades to nothing. Derived per site in abstractBackground() and measured from the PAINTED
   page, because a gradient wash with no geometry is not a drawing. */
.abstract{position:fixed;inset:0;z-index:0;pointer-events:none;background-repeat:repeat;
  background-size:var(--ab-size);background-image:var(--ab-image);
  -webkit-mask-image:linear-gradient(180deg,rgba(0,0,0,.34) 0%,rgba(0,0,0,.16) 55%,rgba(0,0,0,0) 100%);
  mask-image:linear-gradient(180deg,rgba(0,0,0,.34) 0%,rgba(0,0,0,.16) 55%,rgba(0,0,0,0) 100%)}
main,header.bar,footer{position:relative;z-index:1}
@media (min-width:40em){:root{--gutter:1.25rem}}
@media (min-width:80em){:root{--gutter:1.5rem}}
@media (pointer:coarse){:root{--tap:2.75rem}}

*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
body{margin:0;background:var(--bg);color:var(--ink-2);
  font:var(--fs-base)/1.6 system-ui,-apple-system,"Segoe UI",Roboto,sans-serif}
/* The abstract's properties live in ONE rule, near the top, where the per-site drawing is
   substituted. The second copy that stood here set position/inset/z-index/opacity and nothing
   else — harmless, but two rules for one layer is how a value ends up in the wrong one. */
.abstract{opacity:.85}

/* PART 3 — the family brand bar. Sticky, no nav. */
.bar{position:sticky;top:0;z-index:30;background:var(--bar-bg);
  -webkit-backdrop-filter:blur(14px) saturate(120%);backdrop-filter:blur(14px) saturate(120%);
  border-bottom:1px solid var(--line)}
@supports not (backdrop-filter:blur(1px)){.bar{background:var(--bg)}}
.brand{display:grid;grid-template-columns:auto minmax(0,1fr);column-gap:.625rem;align-items:center;
  min-height:var(--bar-h);max-width:var(--wrap);margin-inline:auto;padding:.5rem var(--gutter);
  text-decoration:none;color:var(--ink)}
.brand .mark{grid-row:1 / span 2;width:26px;height:26px;display:block}
.brand .lbl{font-size:1rem;font-weight:650;letter-spacing:-.01em;line-height:1.15;white-space:nowrap}
.brand .fam{font-size:.6875rem;letter-spacing:.12em;line-height:1.1;color:var(--ink-3);
  min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
@media (min-width:30em){.brand{display:flex;gap:.625rem}.brand .fam{margin-left:auto;letter-spacing:.14em}}

main{position:relative;z-index:1;max-width:var(--wrap);margin-inline:auto;padding:var(--s5) var(--gutter) 0}
h1,h2,h3{color:var(--ink);max-width:var(--measure)}
h1{font-size:var(--fs-h1);line-height:1.15;letter-spacing:-.02em;margin:0 0 var(--s3)}
h2{font-size:var(--fs-h2);line-height:1.25;letter-spacing:-.01em;margin:var(--s6) 0 var(--s3)}
h3{font-size:var(--fs-h3);line-height:1.3;margin:var(--s5) 0 var(--s2)}
p,ul,ol{max-width:var(--measure);margin:0 0 var(--s4)}
li{margin-bottom:var(--s2)}
small,.meta{color:var(--ink-3);font-size:var(--fs-sm)}
a{color:var(--link);text-decoration:underline;text-decoration-thickness:.06em;
  text-underline-offset:.18em;transition:color 120ms linear,text-decoration-thickness 120ms linear}
a:hover{color:var(--focus);text-decoration-thickness:.14em}
a:active{color:var(--ink)}
:focus-visible{outline:3px solid var(--focus);outline-offset:2px;border-radius:2px}
::selection{background:var(--accent);color:#fff}

/* Breadcrumbs — a real list, so a screen reader does not read "slash" */
.crumbs{margin:var(--s4) 0 0}
.crumbs ol{display:flex;flex-wrap:wrap;align-items:center;list-style:none;margin:0;padding:0;
  font-size:var(--fs-sm);max-width:none}
.crumbs li{display:flex;align-items:center;margin:0}
.crumbs li + li::before{content:"/";margin:0 .4rem;color:var(--line-strong)}
.crumbs a,.crumbs [aria-current="page"]{display:inline-flex;align-items:center;
  min-height:var(--tap);padding:0 .3rem;border-radius:var(--r-sm)}
.crumbs a{color:var(--ink-3);text-decoration:none}
.crumbs a:hover{color:var(--link);text-decoration:underline}
.crumbs [aria-current="page"]{color:var(--ink-2)}

/* Stat row — the 1px grid gaps ARE the rules */
.stat{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:1px;background:var(--line);
  border:1px solid var(--line);border-radius:var(--r-md);overflow:hidden;margin:var(--s5) 0;max-width:none}
@media (min-width:40em){.stat{grid-template-columns:repeat(auto-fit,minmax(9rem,1fr))}}
.stat > div{background:var(--bg);padding:var(--s3) var(--s4);min-width:0}
.stat b{display:block;color:var(--ink);font-size:var(--fs-stat);font-weight:650;line-height:1.1;
  letter-spacing:-.02em;font-variant-numeric:tabular-nums}
.stat > div > span{display:block;margin-top:var(--s1);color:var(--ink-3);font-size:var(--fs-sm)}

/* Cards — the whole card is the hit area */
.cards{display:grid;gap:var(--s3);margin:var(--s5) 0;
  grid-template-columns:repeat(auto-fill,minmax(min(100%,15rem),1fr))}
.card{position:relative;background:var(--surface);border:1px solid var(--line);
  border-left:3px solid var(--accent);border-radius:var(--r-md);padding:var(--s3) var(--s4);
  transition:background 120ms linear,border-color 120ms linear}
.card > a{color:var(--ink);font-size:var(--fs-lead);font-weight:600;text-decoration:none}
.card > a::after{content:"";position:absolute;inset:0;border-radius:inherit}
.card:hover{background:var(--surface-2);border-color:var(--line-strong)}
.card:hover > a{text-decoration:underline}
.card:focus-within{outline:3px solid var(--focus);outline-offset:2px}
.card .meta{display:flex;flex-wrap:wrap;align-items:center;gap:.35rem;margin-top:var(--s2);
  color:var(--ink-3);font-size:var(--fs-sm)}

/* Tables — one pattern. The first column pins; the box scrolls; the PAGE never does. */
.table-scroll{position:relative;margin:var(--s4) 0;padding-block:2px;overflow-x:auto;
  overscroll-behavior-x:contain;-webkit-overflow-scrolling:touch;scrollbar-width:thin;
  scrollbar-color:var(--line-strong) transparent}
.table-scroll table{width:100%;border-collapse:separate;border-spacing:0;font-size:var(--fs-table)}
.table-scroll caption{caption-side:top;text-align:left;color:var(--ink-3);font-size:var(--fs-sm);
  padding:0 0 var(--s2)}
.table-scroll th,.table-scroll td{text-align:left;padding:.5rem .625rem;border-bottom:1px solid var(--line);
  white-space:nowrap;background:var(--bg)}
.table-scroll thead th{color:var(--ink-3);font-size:var(--fs-xs);font-weight:600}
.table-scroll .num{text-align:right;font-variant-numeric:tabular-nums}
.table-scroll .wrap{white-space:normal;min-width:11rem}
@media (max-width:56em){
  .table-scroll{border:1px solid var(--line);border-radius:var(--r-md)}
  .table-scroll th:first-child,.table-scroll td:first-child{position:sticky;left:0;z-index:1;
    max-width:42vw;overflow:hidden;text-overflow:ellipsis;border-right:1px solid var(--line)}
  .table-scroll thead th:first-child{z-index:2;background:var(--surface)}
}

/* Status pills — opaque fills, so the contrast is the contrast wherever they land,
   and a SECOND cue (dot / ring / square) so the state is not carried by hue alone. */
.pill{display:inline-flex;align-items:center;gap:.35rem;padding:.1rem .5rem .15rem .45rem;
  border-radius:999px;font-size:var(--fs-xs);font-weight:600;line-height:1.5;
  border:1px solid transparent;white-space:nowrap;vertical-align:baseline}
.pill::before{content:"";flex:none;width:.5rem;height:.5rem;border-radius:50%;background:currentColor}
.pill.pass{background:var(--ok-bg);color:var(--ok-ink);border-color:var(--ok-edge)}
.pill.cond{background:var(--warn-bg);color:var(--warn-ink);border-color:var(--warn-edge)}
.pill.closed{background:var(--stop-bg);color:var(--stop-ink);border-color:var(--stop-edge)}
.pill.other{background:var(--flat-bg);color:var(--flat-ink);border-color:var(--flat-edge)}
.pill.cond::before{background:none;border:2px solid currentColor}
.pill.closed::before{border-radius:1px}
/* Named severity, so a second room does not have to borrow kitchen-file's word "closed" to mean
   "most serious". These reuse the SAME global colour pairs the gate already measures, so the
   grammar is identical across rooms and no new unverified contrast enters the sheet. */
.pill.high{background:var(--stop-bg);color:var(--stop-ink);border-color:var(--stop-edge)}
.pill.high::before{border-radius:1px}
.pill.mid{background:var(--warn-bg);color:var(--warn-ink);border-color:var(--warn-edge)}
.pill.mid::before{background:none;border:2px solid currentColor}
.pill.low{background:var(--flat-bg);color:var(--flat-ink);border-color:var(--flat-edge)}
.pill.none{background:var(--flat-bg);color:var(--flat-ink);border-color:var(--flat-edge)}
.pill.none::before{opacity:.45}

/* Charts — the NOTE is visible HTML, not an SVG title nobody paints */
.chart{margin:var(--s6) 0}
.chart > h3{margin:0;font-size:var(--fs-sm);font-weight:600;letter-spacing:.02em;
  text-transform:uppercase;color:var(--ink-3);max-width:none}
.chart-note{margin:var(--s2) 0 var(--s3);max-width:var(--measure);font-size:var(--fs-sm);color:var(--ink-2)}
.chart-box{border:1px solid var(--line);border-radius:var(--r-md);overflow:hidden;
  background:var(--surface);padding:var(--s3)}
.chart-box > svg{display:block;width:100%;height:auto;max-width:820px;margin-inline:auto}
.chart-source{margin:var(--s2) 0 0;max-width:none;font-size:var(--fs-sm);color:var(--ink-3)}
.chart-source a{color:var(--link)}
.chart-hint{display:none;color:var(--ink-3);font-size:var(--fs-xs)}
@media (max-width:56em){
  .chart-box{overflow-x:auto;overscroll-behavior-x:contain;scrollbar-width:thin;
    scrollbar-color:var(--line-strong) transparent}
  .chart-box > svg{width:820px;max-width:none}
  .chart-hint{display:block}
}
svg text{font-family:system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;font-variant-numeric:tabular-nums}

/* Callout — the "read this correctly" box, and it is in the heading outline */
.callout{border:1px solid var(--line);border-left:3px solid var(--accent);border-radius:var(--r-md);
  background:var(--surface);padding:var(--s4);margin:var(--s5) 0;max-width:var(--measure)}
.callout > :last-child{margin-bottom:0}
.callout h2,.callout h3{margin-top:0}

/* Search — hidden without JS, so nobody sees an input that does nothing */
.search{margin:var(--s5) 0 0}
html:not(.js) .search{display:none}
.search-label{display:block;margin-bottom:var(--s2);color:var(--ink-3);font-size:var(--fs-sm)}
.search input[type=search]{display:block;width:100%;min-height:2.75rem;padding:.625rem .75rem;
  font:inherit;font-size:var(--fs-base);color:var(--ink);background:var(--surface-2);
  border:1px solid var(--line-strong);border-radius:var(--r-sm);appearance:none;
  transition:border-color 120ms linear}
.search input::placeholder{color:var(--ink-3)}
.search input:hover{border-color:var(--ink-3)}
.search input:focus-visible{outline:3px solid var(--focus);outline-offset:1px;border-color:var(--focus)}
.search-count{margin:var(--s2) 0 0;max-width:none;color:var(--ink-3);font-size:var(--fs-sm)}

/* Consent */
.consent{position:fixed;inset:auto 0 0 0;z-index:60;max-height:min(50vh,20rem);overflow-y:auto;
  background:var(--surface);border-top:1px solid var(--line);
  padding:var(--s4) var(--gutter) calc(var(--s4) + env(safe-area-inset-bottom));
  box-shadow:0 -8px 24px rgb(0 0 0 / .35)}
.consent-inner{max-width:var(--wrap);margin:0 auto;display:flex;gap:var(--s4);align-items:center;flex-wrap:wrap}
.consent p{margin:0;flex:1;min-width:15rem;max-width:var(--measure)}
.consent-btns{display:flex;gap:var(--s2)}
.consent button{min-height:2.75rem;padding:.6rem 1.15rem;border-radius:var(--r-sm);
  border:1px solid var(--line-strong);background:var(--accent);color:var(--ink);
  font:inherit;font-weight:650;cursor:pointer}
.consent button[data-consent="no"]{background:transparent;color:var(--ink-3)}
.consent button:hover{border-color:var(--focus)}
.consent button[data-consent="yes"]{color:var(--bg)}

footer{position:relative;z-index:1;max-width:var(--wrap);margin:var(--s7) auto 0;
  padding:var(--s5) var(--gutter) var(--s7);border-top:1px solid var(--line);
  color:var(--ink-3);font-size:var(--fs-sm)}
.foot-brand{display:flex;align-items:center;gap:.6rem;color:var(--ink);font-weight:600;
  margin-bottom:var(--s3);max-width:none}
.foot-links{display:flex;flex-wrap:wrap;align-items:center;gap:0 var(--s3);max-width:none}
.foot-links > *{display:inline-flex;align-items:center;min-height:var(--tap)}
.foot-links a,.cookie-door{color:var(--ink-3);text-decoration:none;background:none;border:0;
  font:inherit;cursor:pointer;padding:0}
.foot-links a:hover,.cookie-door:hover{color:var(--link);text-decoration:underline}
.foot-copy{margin-top:var(--s3);max-width:none}
