/* CommissionIQ by Delmatic — dashboard styles.
   Same token system as the approved design mockup. The first visit follows
   the operating-system theme; the toolbar can then save an explicit choice. */

/* Brand palette lifted from delmatic.com's theme stylesheet:
   lime #96d045 (accent), charcoal #2f2f2f (ink), olive #637525 (deep green),
   white/#f6f6f6/#ececec greys. Light mode mirrors the website; dark mode is
   the same brand translated (their site is light-only). Chart marks use
   validated darker lime steps (#7fb232 light / #74a52e dark) — pure #96d045
   is too pale for colour-blind-safe marks and stays on chrome only. */
:root {
  --page:#f6f6f6; --card:#ffffff; --card2:#f2f2f2;
  --ink:#2f2f2f; --ink2:#555555; --muted:#6d6d6d;
  --line:#ececec; --line2:#d7d6d5;
  --accent:#96d045; --accent-ink:#637525; --focus:#006b56;
  --btn-ink:#263311;
  /* The bar and the track it sits in were 2.22 to 1 apart, so a floor bar was
     hard to tell from its own groove. */
  --data:#6c972a; --data-track:#edf3df;
  --fail:#d03b3b;
  /* Darkened from #e3ad3d, which reached only 2.04 to 1 on white and coloured
     the Attention figure on the Action Center. Amber on white is the classic
     way to lose a number. Measured, not judged: tests/test_theme_contrast.py. */
  --progress-mid:#b88c31;
  --info:#3b82f6;
  --chip-pass-bg:#eef6dd; --chip-pass-ink:#56701f;
  --chip-fail-bg:#f9e7e5; --chip-fail-ink:#a92f2f;
  --chip-na-bg:#efefef; --chip-na-ink:#6b6b6b;
  /* Amber. Selected Pending sat on --card2 in near-identical grey, so a
     chosen Pending was indistinguishable from an unchosen one. */
  --chip-warn-bg:#fdf0d2; --chip-warn-ink:#8a5a12;
  --shadow:0 1px 3px rgba(0,0,0,.06);
  --workspace-gutter:clamp(16px,2vw,36px);
  --workspace-gap:clamp(16px,1.5vw,24px);
  --workspace-section:clamp(20px,2vw,30px);
  /* The rail. It used to be charcoal whatever the theme said, which left a
     dark column beside a light application. These tokens are the whole of
     its colour, so each theme answers for its own rail.

     Light: a genuinely light rail that belongs to the light application. It
     is white against the grey page, so the boundary is the page, not a
     shadow. Text is the ordinary ink, measured in tests/test_theme_contrast.py. */
  --rail-bg:#ffffff; --rail-ink:#2f2f2f; --rail-ink2:#5d5d5d;
  --rail-line:#e2e2e2; --rail-edge:#d7d6d5;
  --rail-hover-bg:#f0f0f0; --rail-hover-ink:#1c1c1c;
  --rail-sel-bg:#eef6dd; --rail-sel-ink:#243206; --rail-mark:#637525;
  --rail-count-bg:#ececec; --rail-count-ink:#454545;
  --rail-brand-ink:#232323; --rail-brand-sub:#6d6d6d; --rail-brand-iq:#637525;
}

/* Engineer-only drawing and databasing workbench. */
.engineering-coverage {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 12px;
  margin: 0 0 18px;
}
.engineering-check-card { position:relative; min-height:150px; }
.engineering-check-card .chip { float: right; }
.engineering-check-card h3 { margin: 0 0 12px; max-width: 75%; font-size: 1rem; }
.engineering-check-count { display: block; color: var(--accent); font-size: 2rem; line-height: 1; }
.engineering-check-card small { display:block; color: var(--muted); }
.engineering-coverage-summary { margin-top:10px; font-variant-numeric:tabular-nums; }
.engineering-status-help { display:grid; grid-template-columns:repeat(auto-fit,minmax(210px,1fr)); gap:8px 16px; margin-top:9px; }
.engineering-status-help p { margin:0; color:var(--ink2); font-size:12px; }
.engineering-filters { align-items: center; }
.engineering-filters .filter-search { min-width: min(280px, 100%); flex: 1; }
.engineering-report-tools { display:flex; flex-wrap:wrap; align-items:center; gap:8px; margin:0 0 16px; }
.engineering-report-tools label, .engineering-report-tools small { color:var(--ink2); font-size:12px; }
.engineering-report-tools small { flex-basis:100%; }
#engineering-report-print {
  background:var(--accent); color:var(--btn-ink); border:none; border-radius:8px;
  padding:7px 13px; font:inherit; font-weight:650; cursor:pointer;
}
.engineering-report-check { break-inside:avoid; margin-bottom:15px; }
#engineering-report-doc[hidden] { display:none; }
.engineering-report-check h3 { margin:0 0 4px; font-size:14px; }
.engineering-report-finding { break-inside:avoid; border-top:1px solid var(--line); padding:9px 0; }
.engineering-report-finding h3, .engineering-report-finding p { margin:0 0 4px; }
.engineering-report-finding h3 { font-size:13px; }
.engineering-report-finding p { font-size:11px; color:var(--ink2); }
.engineering-findings { display: grid; gap: 12px; }
.engineering-finding {
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 16px;
  background: var(--card2);
}
.engineering-finding-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 16px;
}
.engineering-finding-head h3,
.engineering-finding-head p { margin: 0 0 6px; }
.engineering-finding-state { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 6px; }
.engineering-placements { list-style: none; margin: 12px 0 0; padding: 0; }
.engineering-placements li {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  padding: 9px 0;
  border-top: 1px solid var(--line);
}
.engineering-actions { display: flex; justify-content: flex-end; margin-top: 12px; }

@media (max-width: 620px) {
  .engineering-coverage { grid-template-columns: 1fr 1fr; gap: 8px; }
  .engineering-check-card { min-height: 150px; padding: 12px; }
  .engineering-finding-head,
  .engineering-placements li { align-items: stretch; flex-direction: column; }
  .engineering-finding-state { justify-content: flex-start; }
  .engineering-placements button { width: 100%; }
}
:root[data-theme="dark"] {
    --page:#171717; --card:#202020; --card2:#282828;
    --ink:#ededed; --ink2:#b5b5b5; --muted:#969696;
    --line:#2f2f2f; --line2:#3d3d3d;
    --accent:#96d045; --accent-ink:#a8db60; --focus:#6ee7b7;
    --btn-ink:#1c2408;
    --data:#74a52e; --data-track:#2b2f24;
    --fail:#e66767;
    --progress-mid:#e8c274;
    --info:#6aa9ff;
    --chip-pass-bg:#2c3618; --chip-pass-ink:#b9dd7d;
    --chip-fail-bg:#3a1f1d; --chip-fail-ink:#eb9a9a;
    --chip-na-bg:#2a2a2a; --chip-na-ink:#a0a0a0;
    --chip-warn-bg:#3d3016; --chip-warn-ink:#e8c274;
    --chip-info-bg:#192d46; --chip-info-ink:#8fc1ff;
    --shadow:0 1px 3px rgba(0,0,0,.4);
    /* Dark: a neutral rail, one step darker than the workspace so the two
       read as separate surfaces without a border doing the work. */
    --rail-bg:#111111; --rail-ink:#ededed; --rail-ink2:#9e9e9e;
    --rail-line:#2a2a2a; --rail-edge:#000000;
    --rail-hover-bg:#1e1e1e; --rail-hover-ink:#ffffff;
    --rail-sel-bg:rgba(150,208,69,.15); --rail-sel-ink:#ffffff; --rail-mark:#96d045;
    --rail-count-bg:#2a2a2a; --rail-count-ink:#dcdcdc;
    --rail-brand-ink:#ededed; --rail-brand-sub:#9e9e9e; --rail-brand-iq:#96d045;
}

/* ── The Delmatic theme ──────────────────────────────────────────────────────
   Light and dark are neutral. They are the tool getting out of the way, and
   they follow whatever the machine is set to.

   This one is the brand. The ground is not neutral grey: it is charcoal with
   green in it, mixed from the brand olive #637525, so the lime sits ON
   something rather than being dropped onto a grey card. The lime itself is
   unchanged — it is the one colour that must not drift — and it is asked to do
   structural work here, not decoration.

   Everything that carries MEANING keeps its meaning. Red is still failure,
   amber is still attention, blue is still information. A theme may change how a
   page feels; it may never change what a colour says. The grounds behind those
   colours are re-mixed for this darker, greener page, and every pair below was
   measured rather than judged by eye — see tests/test_theme_contrast.py.

   The printed report is untouched. @media print re-declares the light tokens
   for EVERY theme selector, at equal specificity, so a report looks the same
   whichever theme made it. */
:root[data-theme="delmatic"] {
  --page:#10140c; --card:#181e12; --card2:#212a19;
  --ink:#eef3e6; --ink2:#bcc7af; --muted:#8e9982;
  --line:#28321d; --line2:#3a4728;
  --accent:#96d045; --accent-ink:#b6e276; --focus:#b6e276;
  --btn-ink:#131d09;
  --data:#8cc63f; --data-track:#242d1a;
  --fail:#f08282;
  --progress-mid:#ecc673;
  --info:#82b8ff;
  --chip-pass-bg:#26331a; --chip-pass-ink:#bfe487;
  --chip-fail-bg:#3a201f; --chip-fail-ink:#f0a6a6;
  --chip-na-bg:#232a1c; --chip-na-ink:#96a189;
  --chip-warn-bg:#3a3018; --chip-warn-ink:#ecc673;
  --chip-info-bg:#1b2b41; --chip-info-ink:#9cc8ff;
  --shadow:0 1px 3px rgba(0,0,0,.55);
  /* Delmatic: the branded charcoal and green the rail always had. */
  --rail-bg:#0d0f0b; --rail-ink:#e5e8dc; --rail-ink2:#95a086;
  --rail-line:rgba(255,255,255,.08); --rail-edge:#000000;
  --rail-hover-bg:rgba(255,255,255,.06); --rail-hover-ink:#ffffff;
  --rail-sel-bg:rgba(150,208,69,.15); --rail-sel-ink:#ffffff; --rail-mark:#96d045;
  --rail-count-bg:rgba(255,255,255,.1); --rail-count-ink:#e5e8dc;
  --rail-brand-ink:#e9ece1; --rail-brand-sub:#95a086; --rail-brand-iq:#96d045;
}

/* ── Typefaces ────────────────────────────────────────────────────────────
   Held in the application, not fetched from the internet. An engineer works
   on site with no signal, so a font asked for at page load would silently
   fall back and the layout would shift with it. These files are in the
   service worker's shell list, so they are on the phone with everything
   else.

   Archivo carries headings and figures - a measure band is read at a
   glance, and its numbers need weight and tight spacing to read as numbers.
   Public Sans carries reading text. IBM Plex Mono carries device names,
   short addresses and codes, so an address looks like an address and
   columns of them line up.

   Every stack keeps a real fallback, so the application is still legible if
   a file ever fails to load. Licences: see fonts/LICENCES.md. */
@font-face {
  font-family:'Archivo'; font-style:normal; font-weight:400 700;
  font-display:swap; src:url('fonts/archivo-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family:'Archivo'; font-style:normal; font-weight:400 700;
  font-display:swap; src:url('fonts/archivo-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family:'Public Sans'; font-style:normal; font-weight:400 700;
  font-display:swap; src:url('fonts/public-sans-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family:'Public Sans'; font-style:normal; font-weight:400 700;
  font-display:swap; src:url('fonts/public-sans-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family:'IBM Plex Mono'; font-style:normal; font-weight:400;
  font-display:swap; src:url('fonts/plex-mono-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

* { box-sizing:border-box; }
html, body { margin:0; }
.environment-banner {
  position:sticky;
  inset-block-start:0;
  z-index:120;
  padding:5px 12px;
  border-block-end:1px solid color-mix(in srgb, var(--accent) 55%, var(--line));
  background:color-mix(in srgb, var(--accent) 15%, var(--bg));
  color:var(--ink);
  font-size:12px;
  font-weight:750;
  letter-spacing:.02em;
  text-align:center;
}
body {
  background:var(--page); color:var(--ink);
  font:15px/1.5 "Public Sans", "Segoe UI", system-ui, -apple-system, sans-serif;
}
a { color:var(--accent-ink); }

/* ── Buttons ──────────────────────────────────────────────────────────────
   The default button, from the reference mockup: a quiet bordered control
   that does not shout, so the one lime button on a page is obviously the
   one that acts.

   This is a bare element selector on purpose. It is the lowest specificity
   there is, so every existing class rule in this file still wins - the
   segmented controls, the device result buttons, the rail, the bottom
   navigation, the drawing viewer's own actions. It only reaches the 58
   buttons that had no styling at all and were falling back to the
   operating system's grey.

   It sits high in the file for the same reason: where specificity ties,
   the later rule wins, and everything specialised comes after this. */
button {
  display:inline-flex; align-items:center; justify-content:center; gap:7px;
  padding:7px 13px; border-radius:7px;
  border:1px solid var(--line2); background:var(--card); color:var(--ink);
  font:inherit; font-size:13.5px; font-weight:500;
  cursor:pointer; white-space:nowrap;
}
button:hover { background:var(--card2); border-color:var(--muted); }
/* A switched-off control shows the no-entry pointer, everywhere. It says the
   button is dead before the click rather than after it. Faded alone is not
   enough: fading reads as "quiet" at least as easily as it reads as "off". */
button:disabled { opacity:.55; cursor:not-allowed; }
button:disabled:hover { background:var(--card); border-color:var(--line2); }
[hidden] { display:none !important; }
/* Hidden for want of data, as opposed to [hidden] which a feature flag owns.
   Keeping them separate means neither can re-reveal what the other hid. */
.empty-hide { display:none !important; }

/* ── Login ─────────────────────────────────────────────────────────────── */
.login-wrap { min-height:100vh; display:grid; place-items:center; padding:20px; }
.login-card {
  background:var(--card); border:1px solid var(--line); border-radius:14px;
  box-shadow:var(--shadow); padding:34px 36px 30px; width:min(380px, 100%);
  display:flex; flex-direction:column;
}
.login-sub { margin:2px 0 22px; color:var(--muted); font-size:13px; }
.login-sub strong { color:var(--accent-ink); font-weight:650; }
.login-card label {
  font-size:11px; font-weight:600; letter-spacing:.08em; text-transform:uppercase;
  color:var(--muted); margin:12px 0 4px;
}
.login-card input {
  background:var(--card2); color:var(--ink); border:1px solid var(--line2);
  border-radius:8px; padding:9px 12px; font:inherit;
}
.login-card input:focus { outline:2px solid var(--accent); outline-offset:-1px; }
.login-card button {
  margin-top:22px; background:var(--accent); color:var(--btn-ink); border:none;
  border-radius:8px; padding:10px; font:inherit; font-weight:650; cursor:pointer;
}
.login-card button:disabled { opacity:.6; cursor:not-allowed; }
.login-card button:focus-visible { outline:2px solid var(--ink); outline-offset:2px; }
.login-error { color:var(--fail); font-size:13px; margin:12px 0 0; }
.login-message { color:var(--accent-ink); font-size:13px; margin:12px 0 0; }
.login-card .text-btn {
  margin-top:10px; padding:2px; background:none; color:var(--ink2);
  font-size:12.5px; font-weight:500; text-decoration:underline;
}

/* ── Chrome ────────────────────────────────────────────────────────────── */
/* CommissionIQ is the product. The company attribution stays smaller. The
   rounded tonal tile identifies digital product surfaces. */
.logo {
  display:flex; align-items:center; gap:10px; color:var(--ink); font-size:19px;
  font-family:'Archivo', "Segoe UI", system-ui, sans-serif;
}
.logo-mark { display:block; flex:0 0 auto; width:1.7em; height:1.7em; }
.logo-mark-digital { object-fit:contain; }
.brand-copy { display:flex; min-width:0; flex-direction:column; gap:1px; }
.brand-name {
  display:inline-flex; align-items:baseline; color:var(--ink);
  font-weight:700; line-height:1; letter-spacing:-.035em; white-space:nowrap;
}
.brand-iq { color:#96d045; font-style:normal; }
.rail-brand-text em { color:var(--rail-brand-iq); font-style:normal; }
.brand-attribution {
  color:var(--muted); font-family:'Public Sans', "Segoe UI", system-ui, sans-serif;
  font-size:.46em; font-weight:500; line-height:1.2; letter-spacing:0;
}
.logo.big { font-size:27px; gap:12px; }
.print-brand-lockup { display:inline-flex; align-items:baseline; gap:.55em; color:#1b2119; font-family:'Archivo',"Segoe UI",system-ui,sans-serif; }
.delmatic-wordmark { display:block; width:100%; height:auto; overflow:visible; }
.print-brand-product { width:114px; }
.print-brand-attribution { color:#596154; font:500 10px/1.1 'Public Sans',"Segoe UI",system-ui,sans-serif; white-space:nowrap; }
.print-brand-attribution b { color:#96d045; font:700 1.15em/1 'Archivo',"Segoe UI",system-ui,sans-serif; letter-spacing:-.025em; }
.print-brand-lockup.is-compact { gap:.35em; }
.print-brand-lockup.is-compact .print-brand-product { width:48px; }
.print-brand-lockup.is-compact .print-brand-attribution { font-size:6.5px; }
/* The toolbar follows the workspace reference. The brand now belongs to the
   rail, while the toolbar holds project context and workspace actions. */
header.top {
  min-height:56px; display:flex; align-items:center; gap:10px; flex-wrap:nowrap;
  padding:0 18px; position:sticky; top:0; z-index:6;
  background:color-mix(in srgb, var(--card) 92%, transparent);
  -webkit-backdrop-filter:blur(18px) saturate(145%);
  backdrop-filter:blur(18px) saturate(145%);
  border-bottom:1px solid var(--line);
}
.mobile-brand { display:none; }
.rail-toggle {
  flex:0 0 auto; width:34px; height:34px; padding:7px; border-color:transparent;
  background:none; color:var(--ink2);
}
.rail-toggle svg { width:19px; height:19px; }
.rail-toggle:hover { background:var(--card2); color:var(--ink); border-color:transparent; }
.project-context {
  min-width:0; max-width:290px; display:flex; align-items:center; gap:9px;
  padding:5px 11px 5px 9px; border:1px solid var(--line);
  border-radius:8px; background:var(--card2);
}
.project-context-dot {
  flex:0 0 auto; width:7px; height:7px; border-radius:50%;
  background:var(--accent); box-shadow:0 0 0 3px color-mix(in srgb, var(--accent) 16%, transparent);
}
.project-context-copy { min-width:0; display:flex; align-items:center; gap:7px; }
.project-context-status {
  flex:0 0 auto; color:var(--muted); font-size:10.5px; line-height:1.2;
  text-transform:capitalize; white-space:nowrap;
}
/* ── Workspace search ──────────────────────────────────────────────────────
   The field keeps the approved toolbar appearance: magnifier, the same
   placeholder sentence, the Ctrl K hint, and the quiet card ground. Every
   colour below is a token, so the control follows light, dark and Delmatic
   without a second set of rules. */
.workspace-search { position:relative; flex:1 1 320px; max-width:460px; min-width:190px; margin-inline:6px; }
.workspace-search-open { display:none; }
.workspace-search-field {
  display:flex; align-items:center; gap:8px; min-height:36px; padding:0 11px;
  border:1px solid var(--line); border-radius:8px; background:var(--card2);
}
.workspace-search-field:focus-within { border-color:var(--line2); background:var(--card); }
.workspace-search-icon { flex:0 0 auto; width:15px; height:15px; color:var(--muted); }
.workspace-search input[type="search"] {
  flex:1 1 auto; min-width:0; height:34px; padding:0; border:0; outline:0;
  background:none; color:var(--ink); font:400 13px/1.4 inherit;
}
.workspace-search input[type="search"]::placeholder { color:var(--muted); opacity:1; }
.workspace-search input[type="search"]::-webkit-search-cancel-button { display:none; }
.workspace-search kbd {
  flex:0 0 auto; padding:3px 5px; border:1px solid var(--line2); border-radius:4px;
  color:var(--muted); font:10.5px/1 'IBM Plex Mono', monospace;
}
.workspace-search-close {
  display:none; place-items:center; flex:0 0 auto; width:26px; height:26px;
  padding:0; border:1px solid transparent; border-radius:6px;
  background:none; color:var(--muted); cursor:pointer;
}
.workspace-search-close svg { width:15px; height:15px; }
.workspace-search-close:hover { border-color:var(--line2); background:var(--card2); color:var(--ink); }
.workspace-search[data-open="true"] .workspace-search-close { display:grid; }
.workspace-search[data-open="true"] kbd { display:none; }

.workspace-search-panel {
  position:absolute; z-index:120; top:calc(100% + 6px); right:0; left:auto;
  width:max(340px, 100%); max-width:min(460px, calc(100vw - 24px));
  max-height:min(70vh, 560px); overflow:auto; padding:6px;
  border:1px solid var(--line2); border-radius:10px;
  background:var(--card); box-shadow:var(--shadow);
}
.workspace-search-panel[hidden] { display:none; }
.workspace-search-status {
  margin:0; padding:6px 8px 4px; color:var(--muted); font-size:11.5px;
}
.workspace-search-foot {
  margin:0; padding:4px 8px 6px; color:var(--muted); font-size:11px;
  border-top:1px solid var(--line);
}
.workspace-search-foot[hidden] { display:none; }
.workspace-search-suggest[hidden] { display:none; }
.workspace-search-group-head {
  display:flex; align-items:baseline; justify-content:space-between; gap:8px;
  margin:6px 0 2px; padding:0 8px;
  color:var(--ink2); font-size:11px; font-weight:700; letter-spacing:.06em;
  text-transform:uppercase;
}
.workspace-search-recent-label {
  margin:0; padding:0 8px 4px; color:var(--ink2); font-size:11px; font-weight:700;
  letter-spacing:.06em; text-transform:uppercase;
}
.workspace-search-group-head small { color:var(--muted); font-size:10.5px; font-weight:600; letter-spacing:0; }
.workspace-search-option {
  display:grid; grid-template-columns:auto minmax(0,1fr) auto; align-items:center;
  gap:4px 10px; width:100%; padding:7px 8px; border:1px solid transparent;
  border-radius:8px; background:none; color:inherit; text-align:left; cursor:pointer;
}
/* The type of a result is a word and a shape, never colour alone: a reader who
   cannot separate the hues still reads "Device" beside a distinct outline. */
.workspace-search-badge {
  grid-row:1 / span 2; display:grid; place-items:center;
  width:26px; height:26px; border:1px solid var(--line2); border-radius:7px;
  color:var(--ink2); font-size:11px; font-weight:700;
}
.workspace-search-badge svg { width:14px; height:14px; }
.workspace-search-option b {
  min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
  color:var(--ink); font-size:13px; font-weight:650;
}
.workspace-search-option .workspace-search-type {
  justify-self:end; color:var(--muted); font-size:10.5px; font-weight:700;
  letter-spacing:.04em; text-transform:uppercase;
}
.workspace-search-option .workspace-search-context {
  grid-column:2 / span 2; min-width:0; overflow:hidden; text-overflow:ellipsis;
  white-space:nowrap; color:var(--muted); font-size:11.5px;
}
.workspace-search-option mark { background:none; color:inherit; font-weight:800; text-decoration:underline; }
.workspace-search-option:hover { background:var(--card2); }
/* Selection is a ground, a border AND a left bar, so it survives without
   colour. The bar is the part a monochrome screen still shows. */
.workspace-search-option[aria-selected="true"] {
  border-color:var(--line2); background:var(--card2);
  box-shadow:inset 3px 0 0 0 var(--accent-ink);
}
.workspace-search-option[aria-selected="true"] .workspace-search-badge { border-color:var(--accent-ink); }
/* The row at the foot of a cut group. Same shape as a result, so the arrow
   keys reach it without looking like a different kind of thing, but it reads
   as an action rather than a record. */
.workspace-search-more .workspace-search-badge { grid-row:auto; font-size:14px; }
.workspace-search-more b { grid-column:2 / span 2; color:var(--accent-ink); }
.workspace-search-empty { margin:0; padding:12px 8px; color:var(--ink2); font-size:12.5px; }
.workspace-search-scope { display:flex; flex-wrap:wrap; gap:6px; padding:2px 8px 8px; }
.workspace-search-scope span {
  padding:3px 8px; border:1px solid var(--line); border-radius:999px;
  color:var(--ink2); font-size:11px;
}
.workspace-search-recent { display:flex; flex-wrap:wrap; gap:6px; padding:0 8px 8px; }
.workspace-search-recent button {
  padding:4px 9px; border:1px solid var(--line); border-radius:999px;
  background:var(--card2); color:var(--ink2); font:inherit; font-size:11.5px; cursor:pointer;
}
.workspace-search-recent button:hover { border-color:var(--line2); color:var(--ink); }

/* The row a search sent you to. A steady outline plus the moved keyboard
   focus, so the destination is found without hunting and without relying on
   a colour that fades. */
.search-landed {
  outline:2px solid var(--accent-ink); outline-offset:2px; border-radius:6px;
  scroll-margin:120px;
}
/* ── One filter control, everywhere ──────────────────────────────────────
   Five of the six list filters used to be bare inputs while the module one
   had a magnifier, and the two magnifiers on the page were drawn at
   different radii and stroke widths. Filtering a list is one idea, so it is
   one control: same magnifier from the sprite, same border, same focus ring,
   same 40px height as every other field beside it. */
.icon-sprite { position:absolute; width:0; height:0; overflow:hidden; }
.filter-search {
  display:flex; align-items:center; gap:7px; min-height:40px;
  padding:0 10px; border:1px solid var(--line2); border-radius:8px;
  background:var(--card2); color:var(--muted);
}
.filter-search:focus-within { outline:2px solid var(--accent); outline-offset:-1px; }
.filter-search-icon { width:14px; height:14px; flex:none; }
.filter-search input[type="search"], .toolbar .filter-search input[type="search"] {
  min-width:0; width:100%; min-height:40px; padding:0; border:0; border-radius:0;
  background:transparent; outline:0; color:var(--ink); font:inherit;
  font-size:var(--field-font); font-weight:400; text-transform:none; letter-spacing:0;
}
.filter-search input[type="search"]::-webkit-search-cancel-button { display:none; }
#page-admin .toolbar .filter-search { flex:1 1 240px; max-width:340px; }

.top-right { margin-left:auto; display:flex; align-items:center; gap:8px; flex:none; }
.theme-toggle {
  display:grid; place-items:center; flex:0 0 auto; width:36px; min-width:36px;
  height:36px; min-height:36px; padding:7px; border:1px solid transparent;
  border-radius:8px; background:transparent; color:var(--ink2); cursor:pointer;
}
.theme-toggle:hover { border-color:var(--line2); background:var(--card2); color:var(--ink); }
.theme-toggle:active { transform:translateY(1px); }
.theme-icon { width:19px; height:19px; }
:root[data-theme="dark"] .theme-icon-sun,
:root[data-theme="dark"] .theme-icon-brand,
:root[data-theme="light"] .theme-icon-moon,
:root[data-theme="light"] .theme-icon-brand,
:root[data-theme="delmatic"] .theme-icon-sun,
:root[data-theme="delmatic"] .theme-icon-moon { display:none; }
/* Freshness of the data, beside the project it belongs to. Quieter than the
   project pill: it is context, not identity. */
/* Freshness reads as a state, not as a sentence: a quiet pill with a dot,
   the same shape the rest of the application uses for a state. */
.synced-chip {
  display:inline-flex; align-items:center; gap:7px;
  font-size:12px; font-weight:500; white-space:nowrap;
  padding:4px 11px; border-radius:999px; align-self:center;
  background:var(--chip-pass-bg); color:var(--chip-pass-ink);
}
.synced-chip::before {
  content:""; width:6px; height:6px; border-radius:50%;
  background:currentColor; flex:none;
}
@media (max-width:640px) { .synced-chip { display:none; } }

.project-context .proj-pill {
  display:block; min-width:0; max-width:250px; padding:0; border:0; border-radius:0;
  color:var(--ink); background:transparent; font:600 13.5px/1.25 'Public Sans', sans-serif;
  letter-spacing:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.project-context select.proj-pill { cursor:pointer; }
.project-context select.proj-pill:focus-visible { outline:2px solid var(--accent); outline-offset:2px; }
.project-context .proj-pill[hidden] {
  display:none;
}
.ghost-btn {
  background:none; border:1px solid var(--line2); border-radius:7px;
  color:var(--ink2); font:inherit; font-size:13.5px; padding:7px 13px; cursor:pointer;
}
.ghost-btn:hover { color:var(--ink); background:var(--card2); border-color:var(--muted); }

/* ── The primary action ──────────────────────────────────────────────────────
   There was no class for this. Green was applied either by hardcoded id
   (#ra-submit, #part-submit, #engineering-report-print) or, worse, by POSITION
   — `.snag-primary-actions button:first-child` — so the colour followed
   whichever verb happened to be first in an array. Change what a snag may do
   next and the emphasis silently moved to a different word.

   Only creating or confirming wears this. A status verb never does: green
   means passed and red means fault everywhere else in this application, and a
   button that says "Mark cleared" in the colour of Completed is telling the
   reader something untrue. Colour belongs to the badge, not to the verb.

   The colour is a token so the whole system can be changed in one line. Lime
   is the Delmatic accent and carries no pass or fail meaning on a create
   action; if it ever needs to move further from the status palette, charcoal
   (--ink) is the intended alternative and only these two values change. */
:root, [data-theme] { --btn-primary-bg:var(--accent); --btn-primary-ink:var(--btn-ink); }
.primary-btn {
  background:var(--btn-primary-bg); color:var(--btn-primary-ink);
  border:1px solid var(--btn-primary-bg); border-radius:8px;
  font:inherit; font-weight:650; padding:8px 16px; cursor:pointer;
}
.primary-btn:hover { filter:brightness(1.05); }
.primary-btn:disabled { opacity:.55; cursor:not-allowed; filter:none; }

main {
  width:100%; max-width:none; margin:0;
  padding:28px var(--workspace-gutter) 64px;
}
.eyebrow {
  font-size:11px; font-weight:600; letter-spacing:.09em; text-transform:uppercase;
  color:var(--muted); margin:0 0 2px;
}
h1, h2, h3, h4 {
  font-family:'Archivo', "Segoe UI", system-ui, sans-serif;
  letter-spacing:-.015em;
}
h2 { font-size:16.5px; margin:0 0 14px; letter-spacing:-.01em; text-wrap:balance; }
/* A measure is read at a glance rather than word by word, so its figure
   needs the weight and the tight fit of the display face. */
.dashboard-measure .v, .report-measure .v,
svg.trend .endlab { font-family:'Archivo', "Segoe UI", system-ui, sans-serif; }
.card {
  background:var(--card); border:1px solid var(--line); border-radius:12px;
  padding:20px 22px; box-shadow:var(--shadow);
}
.note { font-size:12px; color:var(--muted); margin:12px 0 0; }
section.block { margin-bottom:18px; }

/* ── Workspace shell ──────────────────────────────────────────────────────
   The rail and toolbar use the reference mockup's two-column structure.
   The document remains the scrolling element, so existing focus and drawing
   viewer behavior stays unchanged. */
:root { --rail-w:234px; --top-band:56px; }

/* ── Selection ───────────────────────────────────────────────────────────────
   One idiom for "this is the one you picked", used everywhere. A row in a
   list gets a tinted ground and a 3 px accent bar down its leading edge; a
   free-standing card gets the same tint with a one-pixel accent ring, because
   a card has no list edge to put a bar against. Nothing draws a second box
   inside its own border, which is what made the old selected project look
   like a badly fitted outline. */
:root {
  --sel-bg:color-mix(in srgb,var(--accent) 10%,var(--card2));
  --sel-bar:3px;
}
.is-picked {
  position:relative; background:var(--sel-bg); color:var(--ink); font-weight:650;
}
.is-picked::before {
  content:""; position:absolute; inset-block:0; inset-inline-start:0;
  width:var(--sel-bar); background:var(--accent); border-radius:0;
}
.is-picked-card {
  background:var(--sel-bg); border-color:var(--accent);
  box-shadow:0 0 0 1px var(--accent);
}



.app-shell {
  display:grid;
  grid-template-columns:var(--rail-w) minmax(0,1fr);
  align-items:start; min-height:100vh;
  transition:grid-template-columns 160ms ease;
}
.app-shell.rail-collapsed { --rail-w:64px; }
/* minmax(0,1fr) above and this below: without them a wide table inside a
   grid track refuses to shrink and pushes the whole page sideways. */
.app-stage { min-width:0; }

.app-rail {
  position:sticky; top:0; height:100vh; overflow:hidden;
  display:flex; flex-direction:column;
  padding:0; background:var(--rail-bg); color:var(--rail-ink);
  border-right:1px solid var(--rail-edge);
}

.rail-brand {
  flex:0 0 56px; display:flex; align-items:center; gap:9px;
  padding:0 16px; border-bottom:1px solid var(--rail-line);
}
.rail-brand .logo-mark { width:28px; height:28px; }
.rail-brand-text { min-width:0; }
.rail-brand-text b {
  display:block; color:var(--rail-brand-ink); font:700 15px/1.1 'Archivo', sans-serif;
  letter-spacing:-.035em; white-space:nowrap;
}
.rail-brand-text small {
  display:block; color:var(--rail-brand-sub); font-size:9.5px; letter-spacing:.01em;
}

/* The rail follows the active theme through the tokens above, so its
   buttons are written once and read correctly in all three. */
.app-rail nav.tabs {
  flex:1 1 auto; min-height:0; overflow-x:hidden; overflow-y:auto; flex-direction:column; gap:2px;
  padding:14px 10px 8px; scrollbar-width:thin;
}
.rail-group { display:flex; flex-direction:column; gap:2px; margin-top:15px; }
.rail-group-label {
  margin:0 0 4px 10px; font-size:10px; font-weight:600;
  letter-spacing:.12em; text-transform:uppercase; color:var(--rail-ink2);
}
/* A heading with nothing under it is worse than no heading. app.js hides
   the buttons a project or an account may not reach, so a whole group can
   empty itself - Setup does, for a Client. Where :has is unsupported the
   heading simply stays, which is untidy rather than broken. */
.rail-group:not(:has(button:not([hidden]))) { display:none; }
.app-rail nav.tabs button {
  position:relative; display:flex; align-items:center; justify-content:flex-start; gap:11px;
  width:100%; min-height:36px; text-align:left; padding:8px 10px; border:0; border-radius:7px;
  background:none; color:var(--rail-ink); font-size:14px; line-height:1.2;
}
/* The icon is a landmark, not decoration: it is what the eye returns to
   when picking a destination it has used before. It carries no meaning of
   its own, so it stays quiet until its row is the current one. */
.app-rail .rail-ico { flex:0 0 auto; width:18px; height:18px; opacity:.72; }
.app-rail nav.tabs button:hover .rail-ico { opacity:1; }
.app-rail nav.tabs button.on .rail-ico { opacity:1; color:var(--rail-mark); }
.app-rail nav.tabs button:hover { color:var(--rail-hover-ink); background:var(--rail-hover-bg); }
/* Selection is a bar, a fill AND a weight. Colour alone would not say it to
   somebody who cannot tell these two greens apart. */
.app-rail nav.tabs button.on {
  background:var(--rail-sel-bg); color:var(--rail-sel-ink); font-weight:600;
  box-shadow:none;
}
.app-rail nav.tabs button.on::before {
  content:""; position:absolute; left:-10px; top:6px; bottom:6px; width:3px;
  border-radius:0 3px 3px 0; background:var(--rail-mark);
}
.app-rail nav.tabs button[hidden] { display:none; }
.rail-count {
  margin-left:auto; padding:1px 6px; border-radius:999px;
  background:var(--rail-count-bg); color:var(--rail-count-ink);
  font-size:11px; font-weight:600; font-variant-numeric:tabular-nums;
}

/* Who is signed in, at the foot of the rail. On a shared site laptop the
   account decides what is on the screen, so it should not take a menu to
   find out which one is in use. */
.rail-foot {
  flex:0 0 auto; margin-top:auto; display:flex; align-items:center; gap:10px;
  padding:16px 18px; border-top:1px solid var(--rail-line);
}
.rail-avatar {
  flex:0 0 auto; width:28px; height:28px; border-radius:50%;
  /* Dark ink on the accent circle. --btn-ink is exactly that, per theme. */
  display:grid; place-items:center; background:var(--accent); color:var(--btn-ink);
  font-family:'Archivo', "Segoe UI", system-ui, sans-serif;
  font-weight:700; font-size:12px;
}
.rail-who { min-width:0; }
.rail-who b {
  display:block; font-size:13px; font-weight:600; color:var(--rail-brand-ink);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.rail-who small { display:block; font-size:11px; color:var(--rail-ink2); }
.rail-collapsed .rail-brand { justify-content:center; padding-inline:0; }
.rail-collapsed .rail-brand-text,
.rail-collapsed .app-rail nav.tabs button > span,
.rail-collapsed .rail-who { display:none; }
.rail-collapsed .rail-group-label { height:8px; margin:0; opacity:0; }
.rail-collapsed .app-rail nav.tabs button { justify-content:center; padding-inline:0; }
.rail-collapsed .rail-foot { justify-content:center; padding-inline:0; }
@media (prefers-reduced-motion:reduce) {
  .app-shell { transition:none; }
}
/* The Ctrl K hint is a desktop promise. A narrower window still has a real
   keyboard, but not the room, so the hint goes and the field stays. */
@media (max-width:1180px) {
  .workspace-search { flex:1 1 200px; min-width:150px; }
  .workspace-search kbd { display:none; }
}

/* ── Application workspace ────────────────────────────────────────────────
   Operational pages use the screen. Individual reading and form regions keep
   local width limits where they need them. The report has its own document
   rules and does not inherit the dashboard presentation below. */
.workspace-page { width:100%; max-width:none; }
.workspace-page h1 { margin:0 0 12px; font-size:26px; letter-spacing:-.025em; }
.workspace-heading {
  display:flex; align-items:flex-end; justify-content:space-between; gap:24px;
  min-height:62px; padding:0 0 20px; border-bottom:1px solid var(--line2);
  margin-bottom:0;
}
.workspace-heading h1 { margin:2px 0 0; font-size:26px; letter-spacing:-.025em; }
.admin-heading + .admin-tabs { margin-top:20px; }
.workspace-heading .ghost-btn { min-height:38px; padding-inline:16px; }
.workspace-heading-rich { flex-wrap:wrap; align-items:flex-start; }
.workspace-heading-rich > :first-child { min-width:0; flex:1 1 460px; }
.workspace-page-intro {
  max-width:76ch; margin:7px 0 0; color:var(--ink2); font-size:13.5px;
  line-height:1.55;
}
.workspace-heading-actions {
  display:flex; align-items:center; justify-content:flex-end; gap:8px; flex-wrap:wrap;
}
.workspace-heading-actions > button { min-height:38px; }
.workspace-heading-actions > button:not(.ghost-btn) {
  background:var(--accent); border-color:var(--accent); color:var(--btn-ink);
  font-weight:650;
}
.workspace-view-tabs {
  order:3; display:flex; align-items:center; gap:28px; width:100%; margin:4px 0 -20px;
  overflow-x:auto; border-top:1px solid var(--line); scrollbar-width:thin;
}
.workspace-view-tabs button {
  min-height:46px; padding:10px 1px 8px; border:0; border-bottom:2px solid transparent;
  border-radius:0; background:transparent; color:var(--ink2); font-weight:500;
}
.workspace-view-tabs button:hover { background:transparent; color:var(--ink); border-color:transparent; }
.workspace-view-tabs button.on {
  background:transparent; color:var(--ink); border-color:var(--accent); font-weight:650;
}
.workspace-scope {
  padding:14px 0; border-bottom:1px solid var(--line); margin:0;
}
.workspace-page > .card.block,
.workspace-page > section.card.block,
.workspace-page > #intelligence-content > .card.block {
  background:var(--card); border:1px solid var(--line); border-radius:10px;
  box-shadow:none; padding:14px 16px 16px; margin:0;
}
.workspace-page > .card.block > h1,
.workspace-page > .card.block > h2,
.workspace-page > #intelligence-content > .card.block > h2 {
  margin:0 -16px 14px; padding:0 16px 12px;
  border-bottom:1px solid var(--line);
}
.workspace-page > .card.block:first-child,
.workspace-page > section.card.block:first-child { padding-top:0; }
.workspace-page > .engineering-coverage { margin-top:var(--workspace-gap); }
.workspace-page .tbl-wrap,
.workspace-page .table-wrap { scrollbar-gutter:stable; }

/* The Overview measure band divides the available space between the measures
   that exist. Feature switches remove a measure and its grid track together. */
.dashboard-measures {
  display:grid; grid-template-columns:repeat(auto-fit,minmax(220px,1fr));
  gap:0; margin:0; overflow:hidden;
  background:var(--card); border:1px solid var(--line); border-radius:10px;
}
/* A band with no measures in it must not draw its own empty box. This only
   became visible once the band had a border: before, an empty band was
   invisible, so nothing said it was there. */
.dashboard-measures:empty { display:none; }
.dashboard-measure {
  min-width:0; padding:20px clamp(16px,1.6vw,26px);
  border-inline-start:1px solid var(--line);
}
.dashboard-measure:first-child { border-inline-start:0; }
.dashboard-measure.loading { grid-column:1 / -1; color:var(--muted); }
.dashboard-measure .v {
  font-size:32px; font-weight:680; letter-spacing:-.03em; line-height:1.1;
  font-variant-numeric:tabular-nums;
}
.dashboard-measure .v small { font-size:16px; color:var(--ink2); font-weight:500; }
.dashboard-measure .v small.unit { margin-left:3px; }
.dashboard-measure .v .ext { font-size:14px; vertical-align:super; }
.dashboard-measure .s { margin-top:4px; color:var(--ink2); font-size:12.5px; }
.dashboard-measure.link a { display:block; color:inherit; text-decoration:none; }
.dashboard-measure.link a:focus-visible { outline:2px solid var(--accent); outline-offset:5px; }

/* Scope and freshness under the project name. Two lines of quiet text: they
   say what the figures cover and how old they are, and neither is a measure. */
.overview-context {
  display:flex; flex-direction:column; gap:2px; margin:8px 0 0;
  color:var(--ink2); font-size:12.5px; line-height:1.5;
}
.overview-context:empty { display:none; }
.overview-evidence-line { font-variant-numeric:tabular-nums; }
/* The health sentence appears only when something is wrong, so it is allowed
   to be loud. A permanent green tick trains the eye to ignore the line. */
.overview-health {
  margin:8px 0 0; padding:7px 11px; border-radius:8px;
  border:1px solid var(--chip-warn-bg); background:var(--chip-warn-bg);
  color:var(--chip-warn-ink); font-size:12.5px; line-height:1.45;
  max-width:76ch;
}
.overview-health[data-state="unavailable"],
.overview-health[data-state="failed_latest"] {
  border-color:var(--chip-fail-bg); background:var(--chip-fail-bg);
  color:var(--chip-fail-ink);
}
/* The window the change figures cover, written out rather than implied. */
.overview-change-window {
  margin:0 0 6px; color:var(--ink); font-size:13px; font-weight:600;
  font-variant-numeric:tabular-nums;
}
.overview-change-measures {
  display:flex; flex-wrap:wrap; gap:8px; margin:10px 0 0;
}
.overview-change-measures:empty { display:none; }
.overview-change-measure {
  padding:5px 11px; border-radius:999px; background:var(--chip-pass-bg);
  color:var(--chip-pass-ink); font-size:12.5px; font-weight:600;
  font-variant-numeric:tabular-nums;
}
.overview-change-measure.regression {
  background:var(--chip-fail-bg); color:var(--chip-fail-ink);
}
/* Five work types, one project. Same row shape as the module hold-up bars, so
   a reader who has learned one has learned both. */
.worktype-bars { margin-top:12px; }

.overview-primary {
  display:grid; grid-template-columns:minmax(0,2fr) minmax(300px,.95fr);
  column-gap:var(--workspace-gap); align-items:start;
}
/* A grid item defaults to min-width:auto, so it refuses to shrink below its
   own content. The progress chart is an SVG with min-width:560px and its own
   scrolling wrapper — but the wrapper could never do its job, because the
   TRACK grew to 560px instead and pushed the whole page sideways. On a phone
   the document scrolled horizontally and the chart still did not fit.
   Invisible until a project had a progress history to draw. */
.overview-primary > *, .overview-summaries > * { min-width:0; }
.overview-primary:has(> #needs-attention[hidden]) { grid-template-columns:1fr; }

/* The summary band: Modules, Emergency and Snags side by side, each one a
   doorway to its own destination. Feature 013.

   auto-fit rather than a fixed column count, for the same reason the measure
   band uses it: a project can switch any of the three off, and a band that
   counted its columns would leave a gap where the missing one was. Three
   become two become one as the window narrows, with no breakpoint to keep in
   step with the rail. */
.overview-summaries {
  display:grid; grid-template-columns:repeat(auto-fit,minmax(300px,1fr));
  gap:var(--workspace-gap);
}
/* The tracks STRETCH — no align-items:start here, unlike .overview-primary
   above. Three panels of three different heights read as an accident, and the
   way through ends up on a different line in each one. Stretched, every
   doorway sits on the same line and the eye finds it in the same place. */
.overview-summary { display:flex; flex-direction:column; }
/* The way through sits at the foot of every panel, on the same line whatever
   the panel above it holds, so the eye finds it in the same place in all
   three. */
.overview-summary > .ghost-btn { margin-top:auto; align-self:flex-start; }
.overview-summary-lead { margin:12px 0 4px; color:var(--ink2); font-size:13px; }
.overview-summary-lead b { color:var(--ink); font-variant-numeric:tabular-nums; }
.overview-summary-notes {
  margin:10px 0 0; color:var(--ink2); font-size:12.5px;
}
.overview-summary-notes b { color:var(--ink); font-variant-numeric:tabular-nums; }
.overview-bars-head { margin:16px 0 6px; }
/* Three figures under the emergency bar, and two queues under the snag
   heading. Same shape: a number a person reads first, and a word saying what
   it counts. */
.overview-tallies, .snag-queues {
  display:flex; flex-wrap:wrap; gap:22px; margin:13px 0 4px;
}
.overview-tallies span, .snag-queues span { display:flex; flex-direction:column; gap:2px; }
.overview-tallies b, .snag-queues b {
  color:var(--ink); font-size:20px; font-weight:650; line-height:1.1;
  font-variant-numeric:tabular-nums;
}
.overview-tallies small, .snag-queues small {
  color:var(--muted); font-size:10.5px; font-weight:600;
  letter-spacing:.05em; text-transform:uppercase;
}
/* A figure that is a fault wears the fault colour. Nothing else in these
   panels is coloured, so the one that is carries real weight. */
.overview-tallies b.tone-fail, .overview-summary-notes b.tone-fail { color:var(--fail); }
/* Schedules get a line, not a panel, and only when something is missing. */
.overview-reference-line {
  display:flex; flex-wrap:wrap; align-items:center; gap:12px;
  margin:0; padding:12px 2px; color:var(--ink2); font-size:13px;
  border-top:1px solid var(--line);
}
.overview-reference-line b { color:var(--ink); font-variant-numeric:tabular-nums; }
/* Panels, from webapp-design/mockups/workspace-reference.html.
   These are NOT the heavy cards 008 removed: no shadow, a hairline border,
   a small radius, and a ruled head. The old card announced itself as a box;
   this one only holds its contents together, so the eye can find where a
   region ends on a wide screen. */
/* One rule for every workspace page. Six identical page-scoped copies of a
   flat treatment used to sit further down this file - one per page, each
   with an id selector that quietly beat this one. That is the duplication
   CLAUDE.md warns about when a shared style is lifted to a parent: the
   copies survive, and they win. */
.workspace-page .workspace-section {
  min-width:0; margin:0; padding:14px 16px 16px;
  background:var(--card); border:1px solid var(--line); border-radius:10px;
  box-shadow:none;
}
/* The head is the eyebrow and the title, ruled off from the body. The rule
   spans the whole panel, so the padding is pulled back for it. */
.workspace-page .workspace-section > h2,
.workspace-page .workspace-section > .section-heading {
  margin:0 -16px 14px; padding:0 16px 12px;
  border-bottom:1px solid var(--line);
}
.workspace-page .workspace-section > h2 { font-size:15px; }
.workspace-page .workspace-section > .eyebrow,
.workspace-page .workspace-section .section-heading .eyebrow { margin:0 0 3px; }
/* Panels stack with a gap between them instead of running together with
   rules, which is what makes each one read as its own region. */
.workspace-page {
  display:flex; flex-direction:column; gap:var(--workspace-gap);
}
/* NO inner scroll pane. It had max-height:480px and overflow-y:auto, which
   is the same fault the snag drawings tab had: a scrolling box inside a
   scrolling page hides how much there is, so a job with thirty floors looked
   like a job with twelve until somebody found the groove. A progress chart's
   LENGTH is information — it says how big the building is — and the page
   scrolls perfectly well on its own.

   The rows are sorted worst first, so the floors that need somebody are the
   ones at the top whatever the height. Feature 013, phase 4. */
.dashboard-floor-list { padding-inline-end:2px; }
.dashboard-floor-list .floor-row {
  grid-template-columns:minmax(140px,210px) minmax(120px,1fr) 52px;
  min-height:34px; border-bottom:1px solid var(--line);
}
.dashboard-floor-list .floor-row:last-child { border-bottom:0; }
.dashboard-floor-list .floor-row .nm { text-align:left; }
.needs-attention .section-heading { margin-bottom:12px; }
#page-dash #needs-attention-list { gap:0; }
/* A row carries its urgency in a stripe down its left edge, so the eye
   finds the line that needs somebody before reading any of the words. The
   colours are the same ones the rest of the application uses for a state. */
/* Rows, not buttons. They all opened the same unfiltered Action Center, so
   the chevron and the hover were promising a destination each that did not
   exist. The stripe stays: it is the part that was doing real work. */
#page-dash #needs-attention-list .attention-row {
  min-height:56px; padding:9px 12px 9px 9px; border:0;
  border-top:1px solid var(--line); border-left:3px solid transparent;
  border-radius:0; background:transparent; color:var(--ink);
  display:flex; align-items:center; gap:12px; width:100%; text-align:left;
}
#page-dash #needs-attention-list .attention-row:first-child { border-top:0; }
#page-dash #needs-attention-list .attention-row.urgent { border-left-color:var(--fail); }
#page-dash #needs-attention-list .attention-row.attention { border-left-color:var(--chip-warn-ink); }
#page-dash #needs-attention-list .attention-row.routine { border-left-color:var(--line2); }
#page-dash #needs-attention-list .txt { min-width:0; flex:1; }
#page-dash #needs-attention-list .txt b {
  display:block; font-size:13.5px; font-weight:600; line-height:1.3;
}
#page-dash #needs-attention-list .txt small { color:var(--muted); font-size:12px; }
#page-dash #needs-attention-list .cnt {
  font-family:'Archivo', "Segoe UI", system-ui, sans-serif;
  font-size:18px; font-weight:600; font-variant-numeric:tabular-nums;
}
#page-dash #needs-attention-list .attention-row b { font-size:18px; font-variant-numeric:tabular-nums; }
#page-dash #needs-attention-list .attention-row small {
  grid-column:1 / -1; color:var(--muted); font-size:11.5px;
}
#page-dash #needs-attention-note { margin:12px 0 0; }
.overview-trend .trend-wrap { margin-top:12px; }
.overview-trend .trend { min-height:230px; }

/* Phase 5 starts with Overview. Its sections already share the flat workspace
   panel treatment; keep the remaining furniture just as deliberate. Table
   regions get one bounded surface, and every page-level control settles at the
   same desktop height. These selectors stay under #page-dash so the frozen
   report and the pages still waiting for their own treatment cannot inherit. */
#page-dash :is(.tbl-wrap, .table-wrap) {
  overflow-x:auto; border:1px solid var(--line); border-radius:10px;
  background:var(--card);
}
#page-dash :is(.tbl-wrap, .table-wrap) th { background:var(--card2); }
#page-dash :is(.tbl-wrap, .table-wrap) tbody tr:last-child td { border-bottom:0; }
#page-dash .workspace-heading .ghost-btn,
#page-dash .section-heading .ghost-btn,
#page-dash .toolbar :is(input, select, button) {
  box-sizing:border-box; min-height:40px;
}
#page-dash .toolbar .seg { min-height:40px; align-items:stretch; }
#page-dash .toolbar .seg button { display:inline-flex; align-items:center; }

@media (max-width:1050px) {
  .overview-primary { grid-template-columns:1fr; }
  #page-dash .overview-primary > .overview-trend { padding-inline-end:0; }
  /* Needs attention goes FIRST once the two stop sitting side by side. It is
     the only thing on Overview that says do something, and stacked in source
     order it landed under a 230px chart — so on a laptop or a phone the one
     actionable panel was the one you had to scroll for. The markup order is
     unchanged, because the element contract records it and because on a wide
     screen the reading order is already correct. Feature 013, phase 4. */
  #page-dash .overview-primary > .needs-attention {
    order:-1;
    border-inline-start:0; border-bottom:1px solid var(--line); border-top:0;
    padding-inline-start:0;
  }
}

@media (max-width:700px) {
  main { padding:20px var(--workspace-gutter) 54px; }
  .workspace-heading { align-items:stretch; flex-direction:column; gap:12px; }
  .workspace-heading-rich > :first-child { flex:0 1 auto; }
  .workspace-heading .ghost-btn { width:100%; min-height:44px; }
  .workspace-heading-actions { width:100%; justify-content:stretch; }
  .workspace-heading-actions > * { flex:1 1 100%; min-height:44px; }
  .workspace-view-tabs { gap:20px; margin-top:0; }
  .workspace-view-tabs button { flex:0 0 auto; min-height:44px; }
  .dashboard-measures { grid-template-columns:repeat(auto-fit,minmax(150px,1fr)); }
  .dashboard-measure { padding:16px 12px; }
  .dashboard-measure:nth-child(odd) { border-inline-start:0; }
  .dashboard-measure .v { font-size:28px; }
  .dashboard-floor-list { padding-inline-end:0; }
  .dashboard-floor-list .floor-row {
    grid-template-columns:minmax(92px,130px) minmax(80px,1fr) 46px;
    gap:8px;
  }
  .overview-trend .trend { min-height:180px; }
}


/* When one side of the row is switched off, the remaining card takes the full
   width instead of leaving the other track standing empty. */

/* ── Floor bars ────────────────────────────────────────────────────────── */
.floor-row {
  display:grid; grid-template-columns:190px 1fr 52px; gap:12px;
  align-items:center; padding:4.5px 0; cursor:default;
}
.floor-row .nm {
  font-size:13px; color:var(--ink2); white-space:nowrap;
  overflow:hidden; text-overflow:ellipsis; text-align:right;
}
.floor-row .track { height:14px; background:var(--data-track); border-radius:4px; overflow:hidden; }
.floor-row .fill { height:100%; background:var(--data); border-radius:0 4px 4px 0; }
/* One red-amber-green scale, shared by every progress bar on screen and on
   paper. The band classes come from scoreBand() in app.js, so the screen and
   the report cannot drift apart. A bar with no score carries no band. */
.fill.band-low { background:var(--fail); }
.fill.band-mid { background:var(--progress-mid); }
.fill.band-high { background:var(--data); }
.floor-row .pc { font-size:12.5px; font-variant-numeric:tabular-nums; font-weight:600; }
.floor-row:hover .track { outline:1px solid var(--line2); }
.floor-row .pc.na, .na-txt { color:var(--muted); font-weight:400; }
@media (prefers-reduced-motion: no-preference) { .floor-row .fill { transition:width .5s ease; } }

/* ── Emergencies panel ─────────────────────────────────────────────────── */
.em-stat { margin-bottom:16px; }
.em-line { display:flex; align-items:baseline; gap:10px; }
.em-line .big { font-size:26px; font-weight:650; letter-spacing:-.02em; }
.em-line .lbl { font-size:13px; color:var(--ink2); }
.em-bar { display:flex; height:14px; border-radius:4px; overflow:hidden; margin-top:7px; gap:2px; }
.em-bar .pass { background:var(--data); border-radius:4px 0 0 4px; }
.em-bar .fail { background:var(--fail); }
.em-bar .no-result { background:var(--line2); border-radius:0 4px 4px 0; }
.em-legend { display:flex; gap:16px; font-size:12.5px; color:var(--ink2); margin-top:7px; }
.em-legend i {
  display:inline-block; width:9px; height:9px; border-radius:2.5px;
  margin-right:6px;
}
.fail-types { margin-top:14px; border-top:1px solid var(--line); padding-top:12px; }
.fail-types .rw {
  display:flex; justify-content:space-between; gap:10px;
  font-size:12.5px; padding:3px 0; color:var(--ink2);
}
.fail-types .rw b { color:var(--ink); font-variant-numeric:tabular-nums; font-weight:600; }

/* ── Tables ────────────────────────────────────────────────────────────── */
.tbl-wrap { overflow-x:auto; }
table { border-collapse:collapse; width:100%; font-size:13px; }
th {
  text-align:left; font-size:11px; letter-spacing:.07em; text-transform:uppercase;
  color:var(--muted); font-weight:600; padding:8px 10px;
  border-bottom:1px solid var(--line2); white-space:nowrap;
  position:sticky; top:0; background:var(--card);
}
td { padding:8px 12px; border-bottom:1px solid var(--line);
     font-variant-numeric:tabular-nums; white-space:nowrap; }
tbody tr:last-child td { border-bottom:0; }
tr:hover td { background:var(--card2); }
td.num, th.num { text-align:right; }
.scroll-y { max-height:430px; overflow-y:auto; }

.chip {
  display:inline-flex; align-items:center; gap:5px; font-size:11.5px;
  font-weight:600; border-radius:999px; padding:2px 9px;
  letter-spacing:.02em; line-height:1.6; white-space:nowrap;
}
/* An optional dot, for the chips that carry a live state rather than a
   result. Chips without one are unaffected. */
.chip .dot { width:6px; height:6px; border-radius:50%; background:currentColor; flex:none; }
.chip.pass { background:var(--chip-pass-bg); color:var(--chip-pass-ink); }
.chip.fail { background:var(--chip-fail-bg); color:var(--chip-fail-ink); }
.chip.warn { background:var(--chip-warn-bg); color:var(--chip-warn-ink); }
.chip.info { background:var(--chip-info-bg); color:var(--chip-info-ink); }
.chip.na   { background:var(--chip-na-bg);   color:var(--chip-na-ink); font-weight:500; }

/* ── Toolbar ───────────────────────────────────────────────────────────── */
.toolbar { display:flex; gap:10px; flex-wrap:wrap; align-items:center; margin-bottom:14px; }
.toolbar input[type=search] {
  background:var(--card2); color:var(--ink); border:1px solid var(--line2);
  border-radius:8px; padding:7px 12px; font:inherit; font-size:13.5px; width:230px;
}
.toolbar input[type=search]:focus { outline:2px solid var(--accent); outline-offset:-1px; }
#dashboard-scope {
  background:var(--card2); color:var(--ink); border:1px solid var(--line2);
  border-radius:8px; padding:7px 10px; font:inherit; min-width:220px;
}
.seg { display:flex; border:1px solid var(--line2); border-radius:8px; overflow:hidden; }
.seg button {
  background:none; border:none; color:var(--ink2); font:inherit; font-size:13px;
  padding:7px 14px; cursor:pointer;
}
.seg button.on { background:var(--card2); color:var(--ink); font-weight:600; }
.seg button:focus-visible { outline:2px solid var(--accent); outline-offset:-2px; }
.count-note { font-size:12.5px; color:var(--muted); margin-left:auto; }

/* The module tracker follows the approved reference: search field with a
   visible search icon, counted filters, a short complete bar and coloured
   percentages. The exact percentage remains visible inside every colour. */
#modules .module-toolbar { gap:8px; }
#modules .filter-search { width:260px; }
#modules .seg { gap:2px; padding:2px; border:0; background:var(--card2); }
#modules .seg button {
  min-height:40px; gap:6px; padding:5px 11px; border-radius:6px;
}
#modules .seg button.on { background:var(--card); box-shadow:var(--shadow); }
#modules .seg button b {
  color:var(--muted); font-size:12px; font-weight:600;
  font-variant-numeric:tabular-nums;
}
#modules .seg button.on b { color:var(--ink2); }
/* The Module tracker scrolls with the page, not inside itself. A second
   vertical scrollbar inside a page that already has one means the wheel does
   different things depending on where the pointer is, and every row below the
   360px cut was reachable only by finding the inner bar.

   Removing the inner scroller costs the sticky column header: th is sticky to
   its nearest scrolling ancestor, so against the document it would stick under
   header.top and sit behind it. An offset would have to be a magic number -
   the toolbar is 56px, 58px on a phone, and the environment banner adds an
   unknown band above it on preview builds. So the header scrolls away with the
   table, which is what every other page-flow table here already does.
   Horizontal scrolling stays: #mod-table has an 860px minimum width and narrow
   screens still need to reach the last columns. */
#mod-table th { position:static; }
#mod-table { min-width:860px; }
#mod-table .module-complete-head { width:20%; min-width:180px; }
#mod-table .module-name {
  font-family:'IBM Plex Mono', ui-monospace, "Cascadia Mono", Consolas, monospace;
  font-weight:600; letter-spacing:-.01em;
}
#mod-table .module-floor {
  display:block; max-width:170px; overflow:hidden; text-overflow:ellipsis;
  color:var(--muted); font-size:12px;
}
:is(#mod-table, .rep-modules) .module-progress { display:flex; align-items:center; gap:9px; min-width:150px; }
:is(#mod-table, .rep-modules) .module-progress .track {
  flex:1; min-width:60px; height:6px; overflow:hidden;
  border-radius:4px; background:var(--data-track);
}
:is(#mod-table, .rep-modules) .module-progress .fill { height:100%; border-radius:4px; }
:is(#mod-table, .rep-modules) .module-complete-value {
  min-width:38px; font-size:12.5px; font-variant-numeric:tabular-nums;
  text-align:right;
}
:is(#mod-table, .rep-modules) .module-complete-value.band-low { color:var(--chip-fail-ink); }
:is(#mod-table, .rep-modules) .module-complete-value.band-mid { color:var(--chip-warn-ink); }
:is(#mod-table, .rep-modules) .module-complete-value.band-high { color:var(--chip-pass-ink); }
:is(#mod-table, .rep-modules) .module-score {
  display:inline-flex; min-width:48px; justify-content:center;
  padding:2px 8px; border-radius:999px; font-size:11.5px; font-weight:600;
  font-variant-numeric:tabular-nums; line-height:1.6;
}
:is(#mod-table, .rep-modules) .module-score.band-low { background:var(--chip-fail-bg); color:var(--chip-fail-ink); }
:is(#mod-table, .rep-modules) .module-score.band-mid { background:var(--chip-warn-bg); color:var(--chip-warn-ink); }
:is(#mod-table, .rep-modules) .module-score.band-high { background:var(--chip-pass-bg); color:var(--chip-pass-ink); }
:is(#mod-table, .rep-modules) .module-score.na { background:var(--chip-na-bg); color:var(--chip-na-ink); }

@media (max-width:700px) {
  #modules .filter-search { flex:1 1 100%; width:100%; }
  #modules .count-note { flex:1 1 100%; margin-left:0; }
}

/* The Floors table. Seven fixed columns, so it is read across floors as well
   as along one: a column that came and went with the project would change
   what the column beside it means.

   It scrolls sideways inside its own box on a narrow screen, exactly as the
   module tracker does, and never sideways on the page. No inner vertical
   scroller: the length of the list says how big the building is. */
#floors-table { min-width:820px; }
#floors-table th { position:static; }
#floors-table .floor-overall-head { width:20%; min-width:170px; }
#floors-table tbody th {
  font-weight:600; text-align:left; color:var(--ink); font-size:13px;
}
#floors-table .floor-name {
  display:block; max-width:280px; overflow:hidden; text-overflow:ellipsis;
  white-space:nowrap;
}
#floors-table .module-progress { display:flex; align-items:center; gap:9px; min-width:150px; }
#floors-table .module-progress .track {
  flex:1; min-width:60px; height:6px; overflow:hidden;
  border-radius:4px; background:var(--data-track);
}
#floors-table .module-progress .fill { height:100%; border-radius:4px; }
#floors-table .module-complete-value {
  min-width:38px; font-size:13px; font-weight:650;
  font-variant-numeric:tabular-nums; text-align:right;
}
#floors-table .module-complete-value.band-low { color:var(--chip-fail-ink); }
#floors-table .module-complete-value.band-mid { color:var(--chip-warn-ink); }
#floors-table .module-complete-value.band-high { color:var(--chip-pass-ink); }
/* position:relative is load-bearing. The dash carries its explanation in a
   .sr-only span, which is position:absolute !important - and an absolutely
   positioned box is clipped by an ancestor's overflow ONLY if that ancestor
   is in its containing-block chain. With nothing positioned between the two,
   the span's containing block was outside the scrolling wrapper, so it
   escaped the clip and pushed the whole document sideways on a narrow
   window. The chip becomes the containing block and the clip holds. */
#floors-table .module-score {
  position:relative;
  display:inline-flex; min-width:48px; justify-content:center;
  padding:2px 8px; border-radius:999px; font-size:11.5px; font-weight:600;
  font-variant-numeric:tabular-nums; line-height:1.6;
}
#floors-table .module-score.band-low { background:var(--chip-fail-bg); color:var(--chip-fail-ink); }
#floors-table .module-score.band-mid { background:var(--chip-warn-bg); color:var(--chip-warn-ink); }
#floors-table .module-score.band-high { background:var(--chip-pass-bg); color:var(--chip-pass-ink); }
#floors-table .module-score.na { background:var(--chip-na-bg); color:var(--chip-na-ink); }
#floors-table tbody tr.search-landed th { border-radius:6px 0 0 6px; }
#page-floors .tbl-wrap {
  overflow-x:auto; border:1px solid var(--line); border-radius:10px;
  background:var(--card);
}
#page-floors .tbl-wrap th { background:var(--card2); }
#page-floors .tbl-wrap tbody tr:last-child td { border-bottom:0; }

/* Report sections panel. Every available section stays visible. */
.sections { position:relative; }
.sections > summary {
  cursor:pointer; list-style:none; user-select:none;
  border:1px solid var(--line2); border-radius:8px; background:var(--card2);
  color:var(--ink2); font-size:13px; padding:8px 14px; min-height:44px;
  display:inline-flex; align-items:center; gap:7px; white-space:nowrap;
}
.sections > summary::-webkit-details-marker { display:none; }
.sections > summary::after { content:"\25BE"; font-size:11px; }
.sections[open] > summary { color:var(--ink); }
.sections[open] > summary::after { content:"\25B4"; }
.sections-list {
  position:absolute; z-index:30; margin-top:6px; min-width:230px;
  background:var(--card); border:1px solid var(--line2); border-radius:10px;
  box-shadow:var(--shadow); padding:10px 14px;
  display:flex; flex-direction:column; gap:2px;
}
.sections-list .check-label { padding:5px 0; }
.sections-list .count-note { margin-left:6px; }
.sections-list .seg { margin:2px 0 6px 24px; align-self:flex-start; }
.section-heading { display:flex; align-items:center; justify-content:space-between; gap:12px; }
.section-heading h2 { margin-bottom:0; }

/* Administration */
.admin-intro { margin-bottom:18px; }

/* One status line, outside every pane, so a confirmation is readable from
   whichever tab the reader is on. It was written inside the Projects tab,
   which meant saving a person announced itself where nobody was looking. */
.admin-status {
  margin:14px 0 0; padding:9px 13px; border-radius:8px;
  background:var(--chip-pass-bg); color:var(--chip-pass-ink);
  border:1px solid var(--chip-pass-bg); font-size:13px; font-weight:600;
}
.admin-status[data-state="failed"] {
  background:var(--chip-fail-bg); color:var(--chip-fail-ink);
  border-color:var(--chip-fail-bg);
}
.admin-filter {
  display:flex; align-items:center; gap:7px; font-size:12px; color:var(--ink2);
}
.admin-filter select {
  background:var(--card2); color:var(--ink); border:1px solid var(--line2);
  border-radius:8px; padding:7px 9px; font:inherit; min-height:38px;
}

/* A settings group is a seam. The form used to be one column of twenty
   controls, so the only way to find the Inspectly field was to read all of
   them. */
.admin-group { grid-column:1 / -1; }
.admin-group > legend {
  padding:0 6px; font-size:12px; font-weight:650; letter-spacing:.04em;
  text-transform:uppercase; color:var(--muted);
}
.admin-group-note {
  grid-column:1 / -1; margin:0 0 4px; color:var(--ink2); font-size:12.5px;
  line-height:1.5;
}
.admin-feature-head {
  grid-column:1 / -1; margin:10px 0 0; color:var(--muted);
}
.admin-feature-head:first-of-type { margin-top:0; }
/* A subordinate switch is indented under the one it depends on, and dimmed
   when that parent is off. Disabled rather than hidden: a control that
   vanishes reads as a setting that does not exist. */
.admin-feature-child { padding-inline-start:22px; position:relative; }
.admin-feature-child::before {
  content:""; position:absolute; inset-inline-start:7px; inset-block:6px auto;
  height:calc(100% - 12px); width:1px; background:var(--line2);
}
.admin-feature-child.is-unavailable { opacity:.5; }
.admin-feature-child.is-unavailable input { cursor:not-allowed; }
/* A switch, the reason it may be unavailable, and the setting that depends
   on it are one block across the whole fieldset. Left as separate grid
   items, the reason took the next free column and read as a note about
   whatever happened to be beside it. The text is inset by the width of a
   switch and its gap, so it starts under the words it explains, and the
   block stacks the same way at every width. */
.admin-feature-block { grid-column:1 / -1; display:grid; gap:5px; }
.admin-feature-block > .admin-emergency-evidence,
.admin-feature-block > .admin-feature-dependency {
  margin:0; padding-inline-start:24px;
}

.admin-form-actions {
  grid-column:1 / -1; display:flex; align-items:center; gap:12px;
}
.admin-form-actions .count-note { color:var(--chip-pass-ink); font-weight:600; }

/* The dialogs follow the person editor, which is the pattern this
   application already had: a real <dialog>, so focus is trapped and Escape
   is answered by the browser rather than by hand. */
.admin-dialog .person-fields { grid-template-columns:repeat(2, minmax(0, 1fr)); }
.admin-dialog .person-fields .invite-field-wide { grid-column:1 / -1; }
.admin-dialog .invite-no-project #invite-level-row { grid-column:1 / -1; }
.admin-dialog .person-dialog-body { min-width:min(520px, 86vw); }
.admin-dialog .person-fields input, .admin-dialog .person-fields select {
  width:100%; background:var(--card2); color:var(--ink);
  border:1px solid var(--line2); border-radius:8px; padding:8px 10px; font:inherit;
  font-size:var(--field-font);
}
@media (max-width:640px) {
  .admin-dialog .person-fields { grid-template-columns:1fr; }
  .admin-dialog .person-dialog-body { min-width:min(320px, 90vw); }
}
.admin-project-detail { margin-top:10px; }
.admin-project-detail-head { display:flex; align-items:center; gap:16px; margin-bottom:8px; }
.admin-project-detail-head .eyebrow { margin:0; }
.admin-project-detail-head h3 { margin:2px 0 0; font-size:19px; }
.admin-project-tabs { display:flex; gap:22px; border-bottom:1px solid var(--line2); margin-bottom:18px; }
.admin-project-tabs button {
  padding:9px 1px; border:0; border-bottom:2px solid transparent;
  background:transparent; color:var(--ink2); font:inherit; cursor:pointer;
}
.admin-project-tabs button.on { border-bottom-color:var(--accent); color:var(--ink); font-weight:700; }
.admin-project-tabs button:focus-visible { outline:2px solid var(--accent); outline-offset:2px; }
/* A grid item defaults to min-width:auto, so it refuses to shrink below its
   own content: on a phone the settings column stayed 411px wide inside a
   375px window and took the whole document sideways with it. The same rule
   the Overview panels already carry. */
.admin-project-detail > *, .admin-form > *, .admin-group > * { min-width:0; }
.admin-project-row { min-width:0; }
.admin-project-row > span:first-child { min-width:0; }
.admin-project-row b, .admin-project-row small {
  display:block; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.admin-project-list { display:grid; gap:7px; }
.admin-project-row {
  width:100%; display:flex; align-items:center; justify-content:space-between;
  gap:12px; text-align:left; background:var(--card2); color:var(--ink);
  border:1px solid var(--line); border-radius:8px; padding:10px 12px;
  font:inherit; cursor:pointer;
}
.admin-project-row.on {
  position:relative; background:var(--sel-bg); border-color:var(--line);
  color:var(--ink); font-weight:650;
}
.admin-project-row.on::before {
  content:""; position:absolute; inset-block:0; inset-inline-start:0;
  width:var(--sel-bar); background:var(--accent);
}
.admin-project-row small { display:block; color:var(--muted); }
.admin-form { display:grid; grid-template-columns:1fr 1fr; gap:12px; }
.admin-project-detail .admin-form { width:100%; }
.admin-form > label { display:flex; flex-direction:column; gap:4px; font-size:12px; color:var(--ink2); }
.admin-inspectly-picker {
  display:grid; grid-template-columns:minmax(120px, 1fr) auto; gap:6px 8px;
  align-items:end;
}
.admin-inspectly-picker label {
  display:flex; flex-direction:column; gap:4px; font-size:12px; color:var(--ink2);
}
.admin-inspectly-picker button { min-height:36px; }
.admin-inspectly-actions { display:flex; gap:6px; }
.admin-inspectly-picker select, .admin-inspectly-status { grid-column:1 / -1; }
.admin-inspectly-status { color:var(--muted); min-height:16px; font-size:12px; }
.admin-inspectly-status strong { display:block; color:var(--ink2); margin-bottom:5px; }
.admin-inspectly-summary {
  display:grid; gap:2px; margin:5px 0; padding:6px 8px;
  background:var(--card2); border:1px solid var(--line); border-radius:7px;
}
.admin-inspectly-summary > div { display:flex; justify-content:space-between; gap:12px; }
.admin-inspectly-summary b { color:var(--ink); font-variant-numeric:tabular-nums; }
.admin-form input:not([type=checkbox]), .admin-form select {
  width:100%; background:var(--card2); color:var(--ink); border:1px solid var(--line2);
  border-radius:8px; padding:8px 10px; font:inherit; font-size:var(--field-font);
}
.admin-form fieldset {
  grid-column:1 / -1; display:grid; grid-template-columns:repeat(2, minmax(0, 1fr));
  gap:7px 14px; border:1px solid var(--line); border-radius:8px; padding:12px;
}
.admin-driver-rules { grid-column:1 / -1; }
.admin-driver-rules > .note { grid-column:1 / -1; margin:0; }
.admin-driver-list { grid-column:1 / -1; display:grid; gap:6px; }
.admin-driver-list h3 { font-size:13px; margin:8px 0 2px; }
.admin-driver-list label { display:flex; align-items:flex-start; gap:8px; }
.admin-driver-list small { color:var(--ink2); }
.admin-form fieldset label {
  display:flex; align-items:center; gap:8px; min-height:20px;
  font-size:13px; color:var(--ink);
}
.admin-form fieldset input[type=checkbox] {
  width:16px; height:16px; flex:0 0 16px; margin:0;
}
.admin-form > button, .admin-form-actions > button {
  justify-self:start; background:var(--accent); color:var(--btn-ink); border:0;
  border-radius:8px; padding:8px 14px; font:inherit; font-weight:650; cursor:pointer;
}
#admin-access-table select { background:var(--card2); color:var(--ink); border:1px solid var(--line2); }
#admin-access-table button { padding:4px 9px; }
.admin-team-actions { display:flex; align-items:center; gap:8px; }
.admin-team-filters { display:grid; grid-template-columns:minmax(220px,1fr) minmax(160px,.5fr); gap:10px; }
.admin-team-filters > label:not(.filter-search) { display:flex; flex-direction:column; gap:4px; color:var(--ink2); font-size:12px; }
.admin-team-filters select { width:100%; }
.project-team-picker { border:1px solid var(--line); border-radius:8px; padding:6px; margin:12px 0; max-height:42vh; overflow:auto; }
.project-team-option { display:flex; align-items:flex-start; gap:10px; padding:9px; border-bottom:1px solid var(--line); }
.project-team-option:last-child { border-bottom:0; }
.project-team-option input { margin-top:3px; }
.project-team-option b,.project-team-option small { display:block; }
.project-team-option small { color:var(--muted); margin-top:2px; }
#project-member-handover { display:grid; gap:6px; }
#project-member-handover[hidden] { display:none; }
.admin-invite-form {
  display:grid; grid-template-columns:repeat(4, minmax(135px, 1fr));
  gap:10px; align-items:end; margin:18px 0; padding:14px;
  background:var(--card2); border:1px solid var(--line); border-radius:10px;
}
.admin-invite-form label { display:flex; flex-direction:column; gap:4px; font-size:12px; color:var(--ink2); }
.admin-invite-form input, .admin-invite-form select {
  min-width:0; background:var(--card); color:var(--ink); border:1px solid var(--line2);
  border-radius:8px; padding:7px 9px; font:inherit;
}
.admin-invite-form .check-label { flex-direction:row; align-items:center; padding-bottom:8px; }
.admin-invite-form button, #password-submit {
  background:var(--accent); color:var(--btn-ink); border:0; border-radius:8px;
  padding:8px 12px; font:inherit; font-weight:650; cursor:pointer;
}
#password-form { display:grid; gap:8px; min-width:min(340px, 80vw); }
#password-form input {
  background:var(--card2); color:var(--ink); border:1px solid var(--line2);
  border-radius:8px; padding:9px 11px; font:inherit; font-size:var(--field-font);
}
@media (max-width:800px) {
  .admin-form { grid-template-columns:1fr; }
  .admin-form fieldset { grid-template-columns:1fr; }
  .admin-filter { width:100%; }
  .admin-filter select { flex:1; }
  /* The Inspectly picker is a two-column grid with an auto track holding two
     buttons side by side. On a phone that track set the width of the whole
     settings column, and the document scrolled sideways behind it. */
  .admin-inspectly-picker { grid-template-columns:1fr; }
  .admin-inspectly-actions { flex-wrap:wrap; }
  .admin-inspectly-actions button { flex:1 1 auto; }
  .admin-inspectly-status { min-width:0; overflow-wrap:anywhere; }
  /* The project team table is wider than a phone and scrolls in its own box,
     which only works while the box itself is bounded. */
  #admin-access-card .tbl-wrap { max-width:100%; min-width:0; }
  #admin-access-table { min-width:640px; }
  .admin-invite-form { grid-template-columns:1fr 1fr; }
  .admin-team-filters { grid-template-columns:1fr; }
}
@media (max-width:520px) { .admin-invite-form { grid-template-columns:1fr; } }

/* ── Trend ─────────────────────────────────────────────────────────────── */
.deltas { display:flex; gap:10px; flex-wrap:wrap; margin-bottom:14px; }
.delta {
  border:1px solid var(--line); border-radius:8px; padding:7px 14px;
  background:var(--card2); font-size:12px; color:var(--ink2);
}
.delta b {
  display:block; font-size:17px; color:var(--ink);
  font-variant-numeric:tabular-nums; letter-spacing:-.01em;
}
.trend-wrap { overflow-x:auto; }
svg.trend { width:100%; height:auto; display:block; min-width:560px; }
svg.trend text { font:11px "Public Sans", "Segoe UI", system-ui, sans-serif; fill:var(--muted); }
svg.trend .endlab { font-size:12px; font-weight:600; fill:var(--ink); }
svg.trend .grid { stroke:var(--line); stroke-width:1; }
svg.trend { color:var(--data); }
svg.trend .area { stroke:none; }
svg.trend .lin { stroke:var(--data); stroke-width:2; fill:none; }
svg.trend .dot { fill:var(--card); stroke:var(--data); stroke-width:2; }
svg.trend .dot.hot { fill:var(--data); }
svg.trend .xh { stroke:var(--line2); stroke-width:1; stroke-dasharray:3 3; }

/* ── Parts ─────────────────────────────────────────────────────────────── */
.parts { display:grid; grid-template-columns:repeat(auto-fill,minmax(230px,1fr)); gap:14px; }
.part { border:1px solid var(--line); border-radius:10px; padding:14px 16px; background:var(--card2); }
.part img, .part .ph {
  width:100%; height:88px; object-fit:contain; border-radius:8px;
  background:var(--data-track); margin-bottom:10px;
}
.part .ph { display:grid; place-items:center; color:var(--muted); font-size:12px; }

/* Inspectly snag summary */
#snags-body > p { margin:0 0 8px; }
.snag-total { display:flex; align-items:baseline; gap:9px; color:var(--ink2); }
.snag-total b { color:var(--ink); font-size:30px; line-height:1; }
.snag-lifetime { margin:4px 0 0; color:var(--muted); font-size:12px; }
.snag-statuses { display:flex; flex-wrap:wrap; gap:8px; margin:13px 0 10px; }
.snag-statuses span { display:flex; gap:5px; align-items:baseline; color:var(--ink2); }
.snag-statuses small { color:var(--muted); font-size:10.5px; text-transform:uppercase; letter-spacing:.05em; }
.snag-statuses b { color:var(--ink); font-variant-numeric:tabular-nums; }
.snag-warning { color:var(--fail); }
.snag-breakdown {
  max-width:620px; margin:14px 0 10px; border-top:1px solid var(--line);
}
.snag-row {
  display:flex; align-items:center; justify-content:space-between; gap:16px;
  padding:7px 2px; border-bottom:1px solid var(--line); color:var(--ink2);
}
.snag-row span { display:flex; align-items:baseline; gap:9px; }
.snag-row small {
  min-width:68px; color:var(--muted); font-size:10.5px; font-weight:600;
  letter-spacing:.06em; text-transform:uppercase;
}
.snag-row b { color:var(--ink); font-variant-numeric:tabular-nums; }
.snag-scope, .snag-updated { margin:9px 0 0 !important; }
.snag-updated.stale { color:var(--fail); }
/* Snag records. The status tones come from the tokens already used elsewhere,
   so a colour means one thing across the product: amber is attention, blue is
   information (waiting to be looked at), green is passed, red is an issue.
   The chip pairs are the contrast-measured ones — see tests/test_theme_contrast.py. */
.snags-summary { margin:6px 0 12px; }
.snags-summary .snag-breakdown { margin-top:10px; }
#page-snags .snag-list { max-height:none; }

.snag-list-heading {
  display:flex; align-items:center; justify-content:space-between; gap:20px;
  margin:0 0 14px;
}
.snag-list-heading h2 { margin:0; }
.snag-page-actions { display:flex; align-items:center; justify-content:flex-end; gap:8px; flex:none; }
.snag-page-actions > button { min-height:40px; white-space:nowrap; }
.snag-filter-grid { display:grid; gap:12px; margin:0 0 10px; min-width:0; }
.snag-filter-row { display:grid; gap:10px 12px; align-items:end; min-width:0; }
.snag-filter-row-primary {
  grid-template-columns:minmax(110px,.7fr) minmax(130px,.9fr) minmax(320px,2fr) minmax(150px,1fr);
}
.snag-filter-row-secondary {
  grid-template-columns:minmax(440px,2.2fr) minmax(150px,1fr) minmax(150px,.9fr) auto;
}
.snag-filter-field { display:grid; gap:4px; min-width:0; color:var(--muted); font-size:11.5px; }
.snag-filter-field > label,
.snag-filter-group > legend { font-weight:650; color:var(--ink2); }
.snag-filter-field input,
.snag-filter-field select { width:100%; min-width:0; max-width:100%; min-height:40px; padding:4px 8px; }
.snag-filter-group { min-width:0; margin:0; padding:0; border:0; }
.snag-filter-group > legend { margin:0 0 4px; padding:0; font-size:11.5px; }
.snag-filter-group-fields { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:10px; min-width:0; }
.snag-raised-group .snag-filter-group-fields { grid-template-columns:minmax(150px,1.3fr) repeat(2,minmax(130px,1fr)); }
.snag-filter-search-field .filter-search { width:100%; box-sizing:border-box; }
.snag-clear-filters { min-height:40px; white-space:nowrap; }
.snag-clear-filters[hidden] { display:none; }
@container (max-width:900px) {
  .snag-filter-row-primary { grid-template-columns:repeat(2,minmax(0,1fr)); }
  .snag-responsibility-group { grid-column:1 / -1; }
  .snag-filter-row-secondary { grid-template-columns:repeat(2,minmax(0,1fr)); }
  .snag-raised-group { grid-column:1 / -1; }
  .snag-clear-filters { justify-self:start; }
}
@container (max-width:680px) {
  .snag-list-heading { align-items:stretch; flex-direction:column; gap:10px; }
  .snag-page-actions { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); }
  .snag-page-actions > button { width:100%; }
  .snag-page-actions > :last-child { grid-column:1 / -1; }
  .snag-filter-row-primary, .snag-filter-row-secondary { grid-template-columns:minmax(0,1fr); }
  .snag-responsibility-group, .snag-raised-group { grid-column:auto; }
  .snag-raised-group .snag-filter-group-fields { grid-template-columns:repeat(2,minmax(0,1fr)); }
  .snag-raised-by { grid-column:1 / -1; }
}
@container (max-width:420px) {
  .snag-page-actions, .snag-filter-group-fields,
  .snag-raised-group .snag-filter-group-fields { grid-template-columns:minmax(0,1fr); }
  .snag-page-actions > :last-child, .snag-raised-by { grid-column:auto; }
}
.snag-caption { margin:0 0 8px; color:var(--muted); font-size:12px; }
.snag-list {
  list-style:none; margin:0; padding:0; overflow:hidden;
  border:1px solid var(--line2); border-radius:10px; background:var(--card2);
}
.snag-item + .snag-item { border-top:1px solid var(--line2); }
.snag-item .snag-open {
  display:flex; align-items:center; gap:10px; width:100%; padding:12px 12px 12px 14px;
  background:transparent; border:0; border-radius:0;
  color:inherit; text-align:start; font:inherit; cursor:pointer;
}
.snag-item .snag-open:hover { background:color-mix(in srgb,var(--accent) 5%,transparent); }
.snag-item.withdrawn .snag-open { opacity:.62; }
.snag-item-main { display:flex; flex-direction:column; gap:2px; flex:1 1 auto; min-width:0; }
.snag-item-main b { color:var(--ink); }
.snag-item-main small { color:var(--ink2); font-size:11.5px; }
.snag-badge {
  flex:0 0 auto; min-width:38px; padding:3px 7px; border-radius:999px;
  font-variant-numeric:tabular-nums; font-weight:600; font-size:12px; text-align:center;
}
.snag-state { flex:0 0 auto; font-size:11.5px; font-weight:600; }
.snag-badge.tone-attention   { background:var(--chip-warn-bg); color:var(--chip-warn-ink); }
.snag-badge.tone-information { background:color-mix(in srgb,var(--info) 12%,var(--card)); color:var(--info); }
.snag-badge.tone-passed      { background:var(--chip-pass-bg); color:var(--chip-pass-ink); }
.snag-badge.tone-issue       { background:var(--chip-fail-bg); color:var(--chip-fail-ink); }
.snag-state.tone-attention   { color:var(--chip-warn-ink); }
.snag-state.tone-information { color:var(--info); }
.snag-state.tone-passed      { color:var(--chip-pass-ink); }
.snag-state.tone-issue       { color:var(--chip-fail-ink); }
@container (max-width:420px) {
  .snag-item .snag-open { display:grid; grid-template-columns:auto minmax(0,1fr); align-items:start; }
  .snag-state { grid-column:2; justify-self:start; }
}
.snag-legacy-note { margin:14px 0 0; color:var(--muted); font-size:12px; }
.snag-detail-meta { display:flex; flex-wrap:wrap; gap:10px; align-items:baseline; color:var(--muted); font-size:12px; }
.snag-field { margin:6px 0 0; color:var(--ink); }
.snag-field small {
  display:block; color:var(--muted); font-size:10.5px;
  text-transform:uppercase; letter-spacing:.05em;
}
.snag-history { margin:6px 0 14px; padding-inline-start:0; list-style:none; display:flex; flex-direction:column; gap:8px; }
.snag-history li { border-inline-start:3px solid var(--line2); padding-inline-start:9px; }
.snag-history b { color:var(--ink); }
.snag-history small { display:block; color:var(--muted); font-size:11px; }
.snag-history p { margin:3px 0 0; color:var(--ink2); }
.snag-form-error { color:var(--fail); margin:8px 0 0; }
/* One record panel is shared by the list and drawing. It uses the existing
   surface and colour tokens in every theme. */
.snag-workspace { display:grid; grid-template-columns:minmax(0,1fr); gap:20px; align-items:start; }
/* The list and the open record, side by side, split at the top of the section
   rather than below the filters. The panel column runs the full height, so the
   record starts level with the heading and uses the band that used to be
   empty. The page's own title row is above this section and is untouched. */
#snags-work {
  container-type:inline-size;
  display:grid; grid-template-columns:minmax(0,1fr); gap:20px; align-items:start;
}
#page-snags.has-snag-selection #snags-work {
  grid-template-columns:minmax(260px,1fr) minmax(320px,400px);
}
.snag-column { min-width:0; }
#snag-page-outbox { grid-column:1 / -1; min-width:0; }
#snag-page-outbox:empty { display:none; }
/* The split moved up to #snags-work, so this must NOT make a second column any
   more: the panel is no longer a child here. Left in place it reserved a
   320-400px empty track and squeezed the list into a third of its own column,
   which the measurements missed and the screenshot showed at once. */
#snag-panel-home:empty { display:none; }
.snag-detail-panel { min-width:0; background:var(--card); border:1px solid var(--line2); border-radius:14px; overflow:auto; }
.snag-detail-panel[hidden] { display:none; }
#snag-panel-home { position:sticky; top:16px; min-width:0; }
#snag-panel-home .snag-detail-panel { max-height:calc(100dvh - 110px); }
#snag-detail-body { padding:18px; }
.snag-panel-nav { display:flex; align-items:center; gap:6px; margin-bottom:16px; }
.snag-panel-nav #snag-position { flex:1; text-align:center; font-variant-numeric:tabular-nums; }
.snag-detail-panel button { min-height:44px; }
.snag-panel-nav button { padding:7px 10px; }
#snag-detail-title { margin:0; font-size:20px; line-height:1.35; overflow-wrap:anywhere; }
.snag-primary-actions, .snag-context-actions { display:flex; flex-wrap:wrap; gap:8px; margin:12px 0; }
.snag-primary-actions:empty { display:none; }
/* Each action wears the colour of the status it LEADS TO — Cleared blue,
   Completed green, Re-open red — so the colour is information rather than
   decoration. The earlier version coloured by POSITION, which put the
   Completed green on "Mark cleared", the one state that button does not
   reach.

   A soft tint, not a filled button: three saturated actions side by side shout
   at each other, and these are peers. Same tones the badge and the drawing
   mark use, so a status looks the same wherever it is seen. */
.snag-primary-actions button { flex:1; }
.snag-detail-panel .snag-primary-actions button { font-weight:650; }
.snag-primary-actions button.tone-issue {
  background:var(--chip-fail-bg); color:var(--chip-fail-ink);
  border-color:color-mix(in srgb, var(--chip-fail-ink) 38%, transparent);
}
.snag-primary-actions button.tone-passed {
  background:var(--chip-pass-bg); color:var(--chip-pass-ink);
  border-color:color-mix(in srgb, var(--chip-pass-ink) 38%, transparent);
}
.snag-primary-actions button.tone-information {
  background:color-mix(in srgb, var(--info) 12%, var(--card)); color:var(--info);
  border-color:color-mix(in srgb, var(--info) 38%, transparent);
}
.snag-primary-actions button:hover { filter:brightness(1.04); }

/* The edge of an Activity row says which state it reached, so the history can
   be read down the margin without reading a word of it. An entry that is not a
   status change keeps the neutral line it always had. */
.snag-history li.tone-issue { border-inline-start-color:var(--chip-fail-ink); }
.snag-history li.tone-passed { border-inline-start-color:var(--chip-pass-ink); }
.snag-history li.tone-information { border-inline-start-color:var(--info); }
.snag-context-actions button { flex:1; font-size:12px; }
.snag-panel-tabs { display:flex; gap:18px; border-bottom:1px solid var(--line2); margin:18px 0 14px; }
.snag-panel-tabs [role=tab] { padding:8px 0; border:0; border-bottom:2px solid transparent; border-radius:0; background:transparent; color:var(--muted); }
.snag-panel-tabs [aria-selected=true] { border-bottom-color:var(--accent); color:var(--ink); font-weight:700; }
.snag-detail-panel [role=tabpanel] { min-height:100px; }
.snag-detail-panel label { display:block; margin:14px 0 6px; color:var(--muted); font-size:12px; font-weight:600; text-transform:none; letter-spacing:normal; }
.snag-detail-panel textarea, .snag-detail-panel select { box-sizing:border-box; width:100%; }
.snag-detail-panel .snag-field { white-space:pre-wrap; overflow-wrap:anywhere; margin-bottom:12px; }
.snag-detail-panel .snag-history p { white-space:pre-wrap; overflow-wrap:anywhere; }
.snag-detail-panel .dlg-actions { flex-wrap:wrap; justify-content:flex-start; gap:8px; }
.snag-detail-panel .hint { line-height:1.5; }
/* ── Choosing files ──────────────────────────────────────────────────────────
   The browser's own file control reports what is IN the input. This
   application takes the files out of the input immediately, keeps them in its
   own draft list, and clears the input so the same file can be chosen twice.
   The native text then reads "No file chosen" directly above the files you
   just chose, which is the one thing it must never say.

   The input keeps the label, the keyboard and the focus ring — it is moved
   out of sight, never `display:none`, which would take it off the tab order.
   The button beside it is a visual proxy and is hidden from screen readers,
   because the input itself is already announced. */
.file-picker { display:flex; align-items:center; gap:10px; flex-wrap:wrap; margin-bottom:4px; }
/* Two class names on purpose, and they must both stay.
   `dialog input:not([type="checkbox"])` sets width:100% and a padding, and at
   (0,1,2) it beats a single class. Measured, not guessed: with one class the
   input still drew 428x20 of invisible layout inside the picker, pushing the
   button along and leaving a dead click target beside it. Two classes reach
   (0,2,0), which wins on class count without reaching for !important. */
.file-picker .file-picker-input {
  position:absolute; width:1px; height:1px; padding:0; margin:0; border:0;
  opacity:0; overflow:hidden; white-space:nowrap;
}
.file-picker-btn {
  background:none; border:1px solid var(--line2); border-radius:7px;
  color:var(--ink2); font:inherit; font-size:13.5px; padding:7px 13px; cursor:pointer;
}
.file-picker-btn:hover { color:var(--ink); background:var(--card2); border-color:var(--muted); }
.file-picker-input:focus-visible + .file-picker-btn { outline:2px solid var(--focus); outline-offset:2px; }
.file-picker-state { color:var(--muted); font-size:12.5px; }

/* A refused operation is not a failed one. It is quiet, not alarming: the
   person did nothing wrong, and the only move left is to discard it. */
.outbox-rejected { border-inline-start:3px solid var(--progress-mid); padding-inline-start:10px; }

/* The attachment mark sits on the text baseline it belongs to and takes the
   colour of the line it is in, which is what the emoji could not do. */
.attachment-count { display:inline-flex; align-items:center; gap:3px; color:var(--muted); }
.attachment-icon { width:14px; height:14px; flex:none; }

.snag-item .snag-open[aria-pressed=true] { background:color-mix(in srgb,var(--accent) 10%,var(--card)); box-shadow:inset 3px 0 var(--accent-ink); }
.snag-item .snag-open:focus-visible { outline:2px solid var(--accent-ink); outline-offset:-3px; }
.snag-selection-bar {
  display:flex; align-items:center; flex-wrap:wrap; gap:8px; margin:0 0 10px;
  padding:9px 10px; border:1px solid var(--line2); border-radius:9px; background:var(--card2);
}
.snag-selection-bar > .hint { flex:1 1 260px; margin:0; }
.snag-selection-steps { display:flex; flex:1 1 680px; flex-wrap:wrap; gap:8px 18px; margin:0; padding:0; list-style:none; }
.snag-selection-steps li { display:flex; flex-wrap:wrap; align-items:center; gap:8px; }
.snag-selection-step { display:grid; width:24px; height:24px; place-items:center; border-radius:50%; background:var(--accent); color:#13200a; font-weight:750; }
.snag-list.is-selecting .snag-item { display:grid; grid-template-columns:48px minmax(0,1fr); align-items:stretch; }
.snag-report-select { display:grid; place-items:center; margin:0; border-inline-end:1px solid var(--line); cursor:pointer; }
.snag-report-select input { width:20px; height:20px; accent-color:var(--accent-ink); }
/* ── The snag drawing ────────────────────────────────────────────────────────
   One dialog serves two viewers. A snag drawing is not a progress drawing with
   some pieces switched off — the Snapshot comparison, the change markers and
   the marked export are about what altered between syncs, which is a different
   question from where the faults are. Measured before this was written: the
   toolbar came to 1583px inside a 1440px window, so it did not merely look
   busy, it did not fit.

   Hiding is done here rather than in JavaScript on purpose. showDrawingMode()
   shows several of these unconditionally on every call, so a second writer
   toggling the same `hidden` property would be a race between two owners. CSS
   only ever ADDS hiding: with the class on, these are gone whatever `hidden`
   says; with it off, the existing logic is the only voice. Nothing here tries
   to reveal an element the browser has hidden, which cannot work anyway —
   `[hidden]` is display:none !important in the user-agent sheet. */
.drawing-viewer-dlg.snag-viewer #drawing-mode-toolbar,
.drawing-viewer-dlg.snag-viewer #drawing-newwork-control,
.drawing-viewer-dlg.snag-viewer #drawing-newwork-status,
.drawing-viewer-dlg.snag-viewer #drawing-markers-status,
.drawing-viewer-dlg.snag-viewer #drawing-current-control,
.drawing-viewer-dlg.snag-viewer #drawing-overlay-control,
.drawing-viewer-dlg.snag-viewer #drawing-overlay-strength-control,
.drawing-viewer-dlg.snag-viewer #drawing-overlay-status,
.drawing-viewer-dlg.snag-viewer #drawing-change-panel,
.drawing-viewer-dlg.snag-viewer #drawing-panel-collapse,
/* "Download PDF with markers" means the CHANGE markers. Plain Download PDF
   already composes the snag marks, so nothing is lost by removing it here. */
.drawing-viewer-dlg.snag-viewer #drawing-viewer-download-markers { display:none; }
/* ── The issue drawing ───────────────────────────────────────────────────────
   Opened from Issues. An engineering issue is a database mismatch, not a
   failure and not progress, so the comparison, new work, snags, the previous
   drawing and the Emergency work sheets are not part of it. Hidden here for
   the reason given above the snag drawing: CSS only adds hiding. */
.drawing-viewer-dlg:not(.issue-viewer) #drawing-mode-floor-issues,
.drawing-viewer-dlg.issue-viewer #drawing-mode-failures,
.drawing-viewer-dlg.issue-viewer #drawing-mode-changes,
.drawing-viewer-dlg.issue-viewer #drawing-comparison-label,
.drawing-viewer-dlg.issue-viewer #drawing-comparison,
.drawing-viewer-dlg.issue-viewer #drawing-marker-types,
.drawing-viewer-dlg.issue-viewer #drawing-newwork-control,
.drawing-viewer-dlg.issue-viewer #drawing-newwork-status,
.drawing-viewer-dlg.issue-viewer #drawing-snags-control,
.drawing-viewer-dlg.issue-viewer #drawing-snag-focus-control,
.drawing-viewer-dlg.issue-viewer #drawing-snag-scope-control,
.drawing-viewer-dlg.issue-viewer #drawing-snag-mark-edit,
.drawing-viewer-dlg.issue-viewer #drawing-snags-status,
.drawing-viewer-dlg.issue-viewer #drawing-offline-control,
.drawing-viewer-dlg.issue-viewer #drawing-offline-status,
.drawing-viewer-dlg.issue-viewer #drawing-current-control,
.drawing-viewer-dlg.issue-viewer #drawing-overlay-control,
.drawing-viewer-dlg.issue-viewer #drawing-overlay-strength-control,
.drawing-viewer-dlg.issue-viewer #drawing-overlay-status,
.drawing-viewer-dlg.issue-viewer #drawing-emergency-work-list { display:none; }
.drawing-issue-list { list-style:none; margin:0 0 12px; padding:0; display:grid; gap:4px; }
.drawing-issue-row {
  display:grid; grid-template-columns:minmax(0,1fr); justify-content:stretch; justify-items:start; gap:2px; width:100%; text-align:left; padding:8px 10px; border-radius:8px;
  border:1px solid var(--line2); background:transparent; color:var(--ink); font:inherit; cursor:pointer;
}
.drawing-issue-row b { font-size:13.5px; }
.drawing-issue-row span { font-size:12.5px; color:var(--muted); }
.drawing-issue-row:hover { border-color:var(--accent-ink); }
.drawing-issue-row.is-selected { border-color:var(--accent); background:var(--chip-pass-bg); }
.drawing-issue-row.is-selected span { color:var(--ink2); }

/* A tool in the toolbar: icon and words on one line, sitting on the same
   centre as the switches beside it. Move mark drew 5px higher than every
   neighbour and 91px wide among 139-183px controls, which is what "it did not
   look like it belonged" was. */
.drawing-target-toolbar .drawing-tool-btn {
  display:inline-flex; align-items:center; gap:6px; align-self:center;
  font-size:12px; white-space:nowrap;
}
.drawing-target-toolbar .drawing-tool-btn svg { width:16px; height:16px; flex:none; }
.drawing-viewer-dlg .drawing-target-toolbar > * { align-self:center; }
/* A label's ordinary block margin has no meaning in a row of controls, and it
   was doing real damage: measured on the real elements, each switch reported
   `margin:14px 0 4px` while the buttons reported 0. That made the switches an
   18px-taller box, stretched the toolbar to 62px, and centred every BUTTON
   five pixels above every SWITCH. It reads as one control not belonging with
   the others, which is exactly how it was reported. */
.drawing-target-toolbar .marker-visibility-control,
.drawing-mode-toolbar .marker-visibility-control { margin-block:0; }

/* The legend dialog carries both keys and shows one. */
.drawing-legend-dlg .drawing-snag-legend { display:none; }
.drawing-legend-dlg.snag-legend .drawing-marker-legend { display:none; }
.drawing-legend-dlg.snag-legend .drawing-snag-legend { display:block; }
.drawing-snag-legend dl { display:grid; gap:10px; margin:0; }
.drawing-snag-legend dt { display:flex; align-items:center; gap:9px; font-weight:650; }
.drawing-snag-legend dd { margin:3px 0 0 73px; color:var(--ink2); font-size:12.5px; }
.legend-snag {
  display:grid; place-items:center; width:64px; height:44px; flex:none;
  overflow:visible;
}
.legend-snag svg { display:block; overflow:visible; }
.legend-snag.tone-issue { color:var(--snag-ink-issue); }
.legend-snag.tone-information { color:var(--snag-ink-information); }
.legend-snag.tone-passed { color:var(--snag-ink-passed); }
.legend-snag-area {
  display:inline-block; width:42px; height:30px; margin-inline:11px; flex:none;
  border:2px solid var(--snag-ink-issue); background:transparent;
}

.drawing-viewer-dlg.has-snag-selection { grid-template-columns:minmax(0,1fr) minmax(320px,380px); }
.drawing-viewer-dlg.has-snag-selection > .drawing-viewer-head,
.drawing-viewer-dlg.has-snag-selection > .drawing-toolbars { grid-column:1 / -1; }
.drawing-viewer-dlg > .snag-detail-panel { grid-column:2; grid-row:3; height:100%; box-sizing:border-box; z-index:4; }
.drawing-viewer-dlg.has-snag-selection > .drawing-change-panel { display:none; }
.snag-detail-panel.is-marking .snag-panel-nav button:not(#snag-detail-close),
.snag-detail-panel.is-marking .snag-primary-actions,
.snag-detail-panel.is-marking .snag-context-actions,
.snag-detail-panel.is-marking .dlg-actions { visibility:hidden; }
#snag-report-dlg { box-sizing:border-box; width:min(1000px,96vw); height:92dvh; max-width:none; }
.snag-report-head { display:flex; align-items:center; flex-wrap:wrap; gap:8px; }
.snag-report-head h2 { flex:1; margin:0; }
#snag-report-frame { width:100%; height:calc(100% - 110px); border:1px solid var(--line2); background:white; }
@media (max-width:1000px) {
  .snag-workspace.has-selection { grid-template-columns:minmax(220px,1fr) minmax(300px,360px); }
  .has-selection .snag-open { flex-wrap:wrap; }
}
@container (max-width:680px) {
  .snag-workspace.has-selection { grid-template-columns:minmax(0,1fr); }
  /* Narrow: the record takes the whole width and the list steps aside, so the
     split above has to collapse with it. */
  #page-snags.has-snag-selection #snags-work { grid-template-columns:minmax(0,1fr); }
  .has-selection #snags-body { display:none; }
  .has-snag-selection .snag-list-heading,
  .has-snag-selection .snag-filter-grid,
  .has-snag-selection .snag-filter-chips,
  .has-snag-selection #snags-caption { display:none; }
  #snag-panel-home { position:static; }
  #snag-panel-home .snag-detail-panel { max-height:none; }
}
@media (max-width:760px) {
  .snag-workspace.has-selection { grid-template-columns:minmax(0,1fr); }
  #page-snags.has-snag-selection #snags-work { grid-template-columns:minmax(0,1fr); }
  #page-snags.has-snag-selection .workspace-heading,
  #page-snags.has-snag-selection #snags-heading,
  #page-snags.has-snag-selection .snag-list-heading,
  #page-snags.has-snag-selection .snag-filter-grid,
  #page-snags.has-snag-selection .snag-filter-chips,
  #page-snags.has-snag-selection #snags-caption,
  #page-snags.has-snag-selection #snags-body { display:none; }
  #snag-panel-home { position:static; }
  #snag-panel-home .snag-detail-panel { max-height:none; }
  .drawing-viewer-dlg.has-snag-selection { grid-template-columns:minmax(0,1fr); grid-template-rows:auto auto minmax(180px,1fr) minmax(220px,42dvh) auto; overflow:auto; }
  .drawing-viewer-dlg > .snag-detail-panel { grid-column:1; grid-row:4; width:100%; }
}
/* Mark colours are NOT theme colours.
   A drawing is white in every theme, and the chip inks are chosen to read as
   text against the app's own background — in dark mode --chip-fail-ink is
   #eb9a9a, a pale pink. Inheriting it painted the marks pink on white paper.
   These are fixed, and they are the same values the PDF composer uses, so a
   mark is the same colour on screen as it is on the sheet. */
:root, [data-theme] {
  --snag-ink-issue:#b42323;
  --snag-ink-information:#3b82f6;
  --snag-ink-passed:#567020;
}

/* Saved snags on the drawing. The badge keeps a fixed size on screen so its
   number stays readable at any zoom — the same deliberate choice the other
   markers make. In a PDF it is sized in page units instead. */
#drawing-snag-layer { position:absolute; inset:0; pointer-events:none; }
.drawing-snag-badge {
  position:absolute; transform:translate(-50%, -50%); line-height:0;
  color:var(--snag-ink-issue);
}
/* The open ring is the stored point. The opaque number sits above it, so the
   fault location stays visible. This is screen geometry only; PDF geometry
   remains in marker-shapes.js. */
/* A finger-sized target around a smaller badge.
   The badge is 34px and the target is 44px, so the badge MUST be centred in
   it: the whole element is positioned by translate(-50%,-50%) onto the stored
   point, and an off-centre child would move every mark about five pixels up
   and left of the fault it names. */
.drawing-viewer-dlg button.drawing-snag-badge {
  /* The size itself is set in app.js, so the balloon layout and the button
     cannot disagree about how much room a mark needs. */
  min-width:0; min-height:0; padding:0;
  display:grid; place-items:center;
  border:0; border-radius:0; background:transparent; pointer-events:auto;
  cursor:pointer; box-shadow:none; overflow:visible; z-index:1;
}
.drawing-snag-badge[aria-pressed=true] { z-index:2 !important; }
.drawing-snag-badge.is-subdued, .drawing-snag-area.is-subdued { opacity:.4; }
.drawing-snag-badge:hover, .drawing-snag-badge:focus-visible { opacity:1; z-index:3 !important; }
.drawing-target-page.marking .drawing-snag-badge { pointer-events:none; opacity:.3; }
.drawing-snag-badge.tone-attention   { color:var(--snag-ink-issue); }
.drawing-snag-badge.tone-information { color:var(--snag-ink-information); }
.drawing-snag-badge.tone-passed      { color:var(--snag-ink-passed); }
.drawing-snag-badge.tone-issue       { color:var(--snag-ink-issue); }
/* Placed from its recorded position after the drawing was re-issued. It is
   drawn, because the position is honest, but it says it is not the sheet the
   mark was made on. */
.drawing-snag-badge.reissued { opacity:.85; }
.drawing-snag-area { position:absolute; inset:0; }
.drawing-snag-area svg { position:absolute; inset:0; overflow:visible; }
.drawing-snag-area polygon {
  fill:color-mix(in srgb, var(--snag-ink-issue) 22%, transparent);
  stroke:var(--snag-ink-issue); stroke-linejoin:round;
}
/* The tail from the fault to its label, and the open ring on the fault.
   The ring is OPEN so the fitting shows through it — that is the whole reason
   the label was moved aside. The casing is drawn first and heavier, in paper
   colour, so both survive crossing drawing linework; the same pair the PDF
   draws. pointer-events:none, or the tail would swallow clicks meant for the
   drawing underneath it. */
.drawing-snag-lead { position:absolute; inset:0; pointer-events:none; }
.drawing-snag-lead svg { position:absolute; inset:0; overflow:visible; }
.drawing-snag-lead line, .drawing-snag-lead circle {
  fill:none; stroke:currentColor; stroke-linecap:round;
}
/* White, not a theme token: this is drawn ON the sheet, and the sheet is
   white paper in every theme. A token that followed the interface would turn
   the casing dark on a dark theme and the tail would vanish into the drawing. */
.drawing-snag-lead .casing { stroke:#fff; }
.drawing-snag-lead.tone-attention   { color:var(--snag-ink-issue); }
.drawing-snag-lead.tone-information { color:var(--snag-ink-information); }
.drawing-snag-lead.tone-passed      { color:var(--snag-ink-passed); }
.drawing-snag-lead.tone-issue       { color:var(--snag-ink-issue); }
.drawing-snag-lead.is-subdued { opacity:.4; }
.drawing-snags-status { color:var(--muted); font-size:12px; }

.admin-roles-head { margin-top:26px; }
.admin-roles-list { display:flex; flex-wrap:wrap; gap:12px; margin:10px 0 0; }
.admin-role {
  border:1px solid var(--line2); border-radius:10px; padding:10px 14px 12px;
  min-width:200px; flex:1 1 220px;
}
.admin-role legend { color:var(--muted); font-size:11.5px; font-weight:600; padding:0 4px; }
.admin-role-person { display:flex; align-items:center; gap:7px; margin:4px 0; }

.snag-assign { margin:12px 0 4px; }
.snag-assign select { width:100%; }
.snag-assign .hint { display:block; margin:5px 0 0; color:var(--muted); font-size:11.5px; }
.snag-evidence-list { margin-top:12px; }

.snag-preview { margin:14px 0 4px; }
.snag-preview h3 { margin:0 0 7px; color:var(--ink); font-size:12px; font-weight:600; }
.snag-preview-open {
  position:relative; display:block; width:100%; min-height:0 !important; padding:0;
  overflow:hidden; border:1px solid var(--line2); border-radius:9px;
  background:var(--card2); color:var(--ink); text-align:start;
}
.snag-preview-open:disabled { opacity:1; cursor:not-allowed; }
.snag-preview-stage { position:relative; display:block; width:100%; height:190px; background:#fff; }
.snag-preview-stage.is-empty {
  height:76px;
  background:repeating-linear-gradient(135deg,var(--card2),var(--card2) 12px,
    color-mix(in srgb,var(--line2) 35%,var(--card2)) 12px,
    color-mix(in srgb,var(--line2) 35%,var(--card2)) 24px);
}
#snag-preview-canvas { display:block; width:100%; height:100%; object-fit:cover; }
.snag-preview-action {
  position:absolute; right:8px; bottom:8px; padding:5px 8px; border-radius:6px;
  background:rgba(255,255,255,.94); color:#1c2421; font-size:11px; font-weight:700;
  box-shadow:0 1px 5px rgba(0,0,0,.18);
}
.snag-preview-open:disabled .snag-preview-action { display:none; }
.snag-preview-status { margin:6px 0 0; color:var(--muted); font-size:11.5px; line-height:1.45; }

/* Marking a snag on a drawing. The toolbar follows the drawing toolbars above
   it so the viewer keeps one look, and the crosshair says the next click will
   place something rather than pan. */
.snag-mark-toolbar {
  display:flex; flex-wrap:wrap; align-items:center; gap:10px;
  padding:8px 12px; border:1px solid var(--line2); border-radius:10px;
  background:var(--card2); margin:0 0 8px;
}
.snag-mark-what { font-weight:600; color:var(--ink); }
.snag-mark-status { color:var(--muted); font-size:12px; flex:1 1 180px; }
.snag-mark-kinds { display:flex; gap:6px; }
.drawing-target-page.marking { cursor:default; }
#snag-mark-layer {
  position:absolute; inset:0; pointer-events:none; overflow:visible;
}
/* A mark being placed has to be seen against dense drawing linework, at a zoom
   where a whole A0 is a few hundred pixels wide. A thin dark ring disappears
   into it, which is exactly what happened. So every stroke is drawn twice: a
   wide pale casing, then the coloured line on top of it — the same white-face
   idea the markers already use on paper.

   These sizes are SCREEN sizes and stay constant at any zoom, deliberately, so
   the mark you are placing is always the same size under your cursor. What
   reaches the PDF is sized separately, in page units, by the composer. */
.snag-mark-casing {
  fill:none; stroke:#ffffff;
  stroke-linejoin:round; stroke-linecap:round; opacity:.9;
}
.snag-mark-join {
  fill:none; stroke:var(--snag-ink-issue);
  stroke-linejoin:round; stroke-linecap:round;
}
.snag-mark-halo { fill:#ffffff; stroke:none; opacity:.9; }
.snag-mark-dot { fill:#ffffff; stroke:var(--snag-ink-issue); }
/* The one you just put down, so you can see where you are in a run of them. */
.snag-mark-dot.last { fill:var(--snag-ink-issue); stroke:#ffffff; }
/* The shape choice, one control for all three corner tools: snag marking, the
   area outline and the zone redline. A joined row of buttons with the chosen
   one filled, so it reads as "pick one" and not as three actions. */
.shape-choice {
  display:inline-flex; align-items:stretch; flex:none;
  border:1px solid var(--line2); border-radius:8px; overflow:hidden;
}
.shape-choice button {
  min-height:36px; padding:6px 14px; border:0; border-radius:0;
  background:var(--card); color:var(--ink2);
}
.shape-choice button + button { border-left:1px solid var(--line2); }
.shape-choice button:hover { background:var(--card2); color:var(--ink); }
.shape-choice button[aria-pressed="true"] { background:var(--accent); color:var(--btn-ink); font-weight:600; }
.zone-panel .shape-choice { justify-self:start; }
.zone-panel .shape-choice button { min-height:44px; }
.snag-link, .snag-link-missing { display:inline-block; margin-top:12px; }
.snag-link { color:var(--accent-ink); font-weight:600; }
.snag-link-missing { color:var(--muted); }
.part .nm { font-weight:600; font-size:13.5px; }
.part .code { font-size:12.5px; color:var(--ink2); font-variant-numeric:tabular-nums; }
.part-notes { color:var(--ink2); font-size:12px; margin-top:7px; white-space:pre-wrap; }
.part-actions { display:flex; flex-wrap:wrap; gap:6px; margin-top:12px; }
.part-actions .ghost-btn { font-size:12px; padding:4px 8px; }
.part-actions .ghost-btn:disabled { opacity:.45; cursor:not-allowed; }
.danger-btn { color:var(--fail); }

/* Portable snapshot workflow */
.snapshot-upload-form, .snapshot-inline-form {
  display:flex; align-items:end; gap:10px; flex-wrap:wrap; margin-top:16px;
}
.snapshot-installation-form {
  display:grid; grid-template-columns:minmax(180px,1fr) minmax(180px,1fr) auto auto;
  gap:10px; align-items:end; margin:14px 0;
}
.snapshot-installation-form input, .snapshot-installation-form select,
.snapshot-installation-row select {
  min-height:38px; border:1px solid var(--line); border-radius:7px;
  background:var(--card2); color:var(--ink); padding:7px 9px;
}
.snapshot-installation-form button { min-height:38px; }
.snapshot-installations { display:grid; gap:10px; margin-top:14px; }
.snapshot-installation-row {
  display:grid; grid-template-columns:minmax(180px,2fr) minmax(145px,1fr) minmax(160px,1fr) auto;
  gap:12px; align-items:center; padding:11px 12px;
  border:1px solid var(--line); border-radius:8px; background:var(--card2);
}
.snapshot-installation-row small { color:var(--muted); }
.snapshot-installation-secret {
  margin:12px 0; padding:12px; border:1px solid var(--accent);
  border-radius:8px; background:var(--data-track);
}
.snapshot-token-row { display:flex; gap:10px; align-items:center; margin-top:9px; }
.snapshot-token-row code { overflow-wrap:anywhere; flex:1; user-select:all; }
.snapshot-upload-form label {
  display:flex; flex:1 1 330px; flex-direction:column; gap:5px;
  color:var(--ink2); font-size:12px;
}
.snapshot-upload-form input, .snapshot-inline-form input,
.snapshot-map select, .snapshot-map input, .snapshot-source-row select,
.snapshot-package-row input {
  background:var(--card2); color:var(--ink); border:1px solid var(--line2);
  border-radius:8px; padding:8px 10px; font:inherit;
}
.snapshot-upload-form button, .snapshot-inline-form button,
.snapshot-actions button {
  background:var(--accent); color:var(--btn-ink); border:0; border-radius:8px;
  padding:9px 14px; font:inherit; font-weight:650; cursor:pointer;
}
.snapshot-actions .danger-btn { background:var(--fail); color:#fff; }
/* The buttons sat against the database row above them. */
#snapshot-preview-card .snapshot-actions { margin-top:16px; }
.snapshot-upload-form button:disabled, .snapshot-actions button:disabled {
  opacity:.55; cursor:not-allowed;
}
.snapshot-inline-form input { flex:1 1 260px; max-width:440px; }
.snapshot-structure, #snapshot-source-mappings { display:grid; gap:10px; margin-top:14px; }
.snapshot-package-row, .snapshot-map {
  border:1px solid var(--line); border-radius:9px; padding:12px;
  background:var(--card2);
}
.snapshot-package-head {
  display:flex; align-items:center; gap:8px; flex-wrap:wrap;
}
.snapshot-package-head input { flex:1 1 180px; font-weight:600; }
.snapshot-package-head button { padding:5px 9px; }
.snapshot-source-row {
  display:grid; grid-template-columns:minmax(160px,1fr) minmax(180px,1fr);
  gap:8px; align-items:center; margin:8px 0 0 18px; font-size:12.5px;
}
.snapshot-source-row small { color:var(--muted); }
.snapshot-map {
  display:grid; grid-template-columns:minmax(150px,1fr) minmax(220px,2fr);
  gap:8px 12px; align-items:center;
}
.snapshot-map strong { font-size:13.5px; }
.snapshot-map small { color:var(--muted); }
.snapshot-map input { grid-column:2; }
.snapshot-summary-grid {
  display:grid; grid-template-columns:repeat(auto-fit,minmax(135px,1fr));
  gap:10px; margin:16px 0;
}
.snapshot-summary-grid > div {
  border:1px solid var(--line); border-radius:8px; padding:10px 12px;
  background:var(--card2);
}
.snapshot-summary-grid b { display:block; font-size:21px; }
.snapshot-summary-grid span { color:var(--muted); font-size:12px; }
.snapshot-no-change {
  margin:12px 0; padding:10px 12px; border:1px solid var(--pass);
  border-radius:8px; background:color-mix(in srgb,var(--pass) 9%,var(--card2));
  color:var(--ink2); font-size:13px;
}
.snapshot-source-preview { margin-top:18px; }
.snapshot-source-preview h3 { margin:0 0 8px; font-size:14px; }
.snapshot-preview-table { min-width:690px; }
.snapshot-preview-table th, .snapshot-preview-table td { text-align:left; }
.snapshot-preview-table td { font-variant-numeric:tabular-nums; }
.snapshot-preview-table details { min-width:110px; }
.snapshot-preview-table summary { color:var(--accent); cursor:pointer; }
.snapshot-record-list { display:block; margin-top:6px; color:var(--muted); line-height:1.5; }
.snapshot-history-row, .snapshot-health-row {
  display:grid; grid-template-columns:minmax(180px,2fr) repeat(2,minmax(110px,1fr)) auto;
  gap:10px; align-items:center; padding:9px 0; border-bottom:1px solid var(--line);
  font-size:12.5px;
}
.snapshot-history-row small, .snapshot-health-row small { color:var(--muted); }
.snapshot-health-row { grid-template-columns:minmax(180px,2fr) 1fr 1fr; }
@media (max-width:700px) {
  .snapshot-map, .snapshot-source-row, .snapshot-history-row,
  .snapshot-health-row { grid-template-columns:1fr; }
  .snapshot-map input { grid-column:1; }
  .snapshot-source-row { margin-left:0; }
  .snapshot-installation-form, .snapshot-installation-row { grid-template-columns:1fr; }
  .snapshot-token-row { align-items:stretch; flex-direction:column; }
}

footer { text-align:center; color:var(--muted); font-size:12px; padding:10px 20px 30px; }
footer a { color:var(--ink2); text-decoration:none; border-bottom:1px solid var(--line2); }
footer a:hover { color:var(--ink); border-bottom-color:currentColor; }

/* ── Instant press feedback (respond on pointer-down, never on release) ── */
.ghost-btn, .seg button, nav.tabs button, .login-card button, #ra-submit {
  transition:transform 80ms ease-out;
}
.ghost-btn:active, .seg button:active, nav.tabs button:active,
.login-card button:active, #ra-submit:active { transform:scale(.96); }
@media (prefers-reduced-motion: reduce) {
  .ghost-btn, .seg button, nav.tabs button, .login-card button, #ra-submit,
  .ghost-btn:active, .seg button:active, nav.tabs button:active,
  .login-card button:active, #ra-submit:active { transition:none; transform:none; }
}

/* ── Tooltip — small translucent material ──────────────────────────────── */
#tip {
  position:fixed; pointer-events:none; z-index:10; display:none;
  background:color-mix(in srgb, var(--ink) 88%, transparent);
  -webkit-backdrop-filter:blur(10px);
  backdrop-filter:blur(10px);
  color:var(--page); border-radius:8px;
  padding:8px 12px; font-size:.8rem; line-height:1.55;
  box-shadow:0 4px 14px rgba(0,0,0,.25); max-width:260px;
}
@media (prefers-reduced-transparency: reduce) {
  #tip { background:var(--ink); -webkit-backdrop-filter:none; backdrop-filter:none; }
}
#tip b { font-weight:650; }

/* ── Loading splash ────────────────────────────────────────────────────── */
.loading { text-align:center; color:var(--muted); padding:80px 20px; font-size:14px; }

/* ── Header nav (engineers) ────────────────────────────────────────────── */
nav.tabs { display:flex; gap:4px; }
nav.tabs button {
  background:none; border:none; color:var(--ink2); font:inherit; font-size:13.5px;
  padding:6px 12px; border-radius:8px; cursor:pointer;
}
nav.tabs button.on { background:var(--card2); color:var(--ink); font-weight:600; }

/* ── Test devices screen ───────────────────────────────────────────────── */
.device-panel-head {
  display:flex; align-items:flex-start; justify-content:space-between; gap:18px;
  padding-bottom:13px; border-bottom:1px solid var(--line);
}
.device-panel-head h2 { margin:3px 0 0; font-size:17px; }
.device-panel-status { display:flex; align-items:center; justify-content:flex-end; gap:8px; flex-wrap:wrap; }
.device-completion-chip, #device-sync-state {
  display:inline-flex; align-items:center; min-height:28px; margin:0; padding:4px 10px;
  border-radius:999px; font-size:12px; font-weight:650; white-space:nowrap;
}
.device-completion-chip.band-low { background:var(--chip-fail-bg); color:var(--chip-fail-ink); }
.device-completion-chip.band-mid { background:var(--chip-warn-bg); color:var(--chip-warn-ink); }
.device-completion-chip.band-high { background:var(--chip-pass-bg); color:var(--chip-pass-ink); }
.device-completion-chip:not(.band-low):not(.band-mid):not(.band-high) {
  background:var(--chip-na-bg); color:var(--chip-na-ink);
}
#device-sync-state { gap:6px; background:var(--chip-pass-bg); color:var(--chip-pass-ink); }
#device-sync-state::before { content:""; width:7px; height:7px; border-radius:50%; background:currentColor; }
#device-sync-state[data-state="grace"], #device-sync-state[data-state="queued"],
#device-sync-state[data-state="syncing"] { background:var(--chip-warn-bg); color:var(--chip-warn-ink); }
#device-sync-state[data-state="failed"] { background:var(--chip-fail-bg); color:var(--chip-fail-ink); }
.device-workflow-bar:not(:has(button:not([hidden]))) { display:none; }
.device-workspace-layout {
  display:grid; grid-template-columns:250px minmax(0,1fr); gap:16px;
}
.device-scope-panel {
  align-self:start; min-width:0; padding:12px 9px; border:1px solid var(--line);
  border-radius:9px; background:var(--card2);
}
.device-scope-panel > .eyebrow { margin:2px 9px 8px; }
.device-scope-tree { display:grid; gap:2px; }
.device-scope-row {
  display:grid; grid-template-columns:16px minmax(0,1fr) auto; align-items:center; gap:8px;
  width:100%; min-height:40px; padding:7px 9px; border:0; border-radius:7px;
  background:transparent; color:var(--ink2); font-size:13px; text-align:left;
}
.device-scope-row:hover { border:0; background:var(--card); color:var(--ink); }
.device-scope-row.on {
  position:relative; background:var(--sel-bg); color:var(--ink); font-weight:650;
}
.device-scope-row.on::before {
  content:""; position:absolute; inset-block:2px; inset-inline-start:0;
  width:var(--sel-bar); border-radius:2px; background:var(--accent);
}
.device-scope-row.module { padding-left:25px; grid-template-columns:minmax(0,1fr) auto; }
.device-scope-row.module .device-scope-icon { display:none; }
.device-scope-icon { width:11px; height:11px; border:1.5px solid currentColor; border-radius:2px; opacity:.7; }
.device-scope-row b { font-weight:600; font-variant-numeric:tabular-nums; }
.device-scope-row b.band-low { color:var(--chip-fail-ink); }
.device-scope-row b.band-mid { color:var(--chip-warn-ink); }
.device-scope-row b.band-high { color:var(--data); }
.device-module-label {
  margin:12px 9px 4px; color:var(--muted); font-size:10px; font-weight:650;
  letter-spacing:.1em; text-transform:uppercase;
}
.device-results-panel { min-width:0; }
.device-results-panel > .device-panel-head { margin-bottom:12px; }
.device-mobile-scope { display:none; }
.device-filter-toolbar { align-items:center; gap:8px; margin-bottom:10px; }
.device-filter-toolbar .filter-search { flex:1 1 230px; min-width:180px; }
.device-filter-toolbar #device-sync-state { margin-left:auto; }
#page-test #device-list {
  overflow:hidden; border:1px solid var(--line); border-radius:10px;
  background:var(--card);
}
#page-test .dev-row { border-radius:0; }
#page-test .dev-row:last-child { border-bottom:0; }
#page-test .device-workflow-bar button,
#page-test .toolbar :is(input, select, button) {
  box-sizing:border-box; min-height:40px;
}
#page-test #device-tip { margin:14px 0; }
#page-test #device-tip > summary {
  min-height:40px; display:inline-flex; align-items:center; cursor:pointer;
}
@media (max-width:900px) {
  .device-workspace-layout { grid-template-columns:1fr; }
  .device-scope-panel { display:none; }
  .device-mobile-scope { display:block; margin-bottom:10px; border:1px solid var(--line); border-radius:8px; }
  .device-mobile-scope > summary { min-height:44px; padding:10px 12px; cursor:pointer; font-weight:650; }
  .device-mobile-scope-fields { display:grid; grid-template-columns:1fr 1fr; gap:8px; padding:0 10px 10px; }
  .device-mobile-scope select { width:100%; min-width:0; min-height:44px; }
}
@media (max-width:560px) {
  .device-panel-head { align-items:stretch; flex-direction:column; }
  .device-panel-status { justify-content:flex-start; }
  .device-mobile-scope-fields { grid-template-columns:1fr; }
}

/* ── Work action centre ────────────────────────────────────────────────── */
#page-action .action-heading { align-items:flex-start; }
#page-action .action-heading h1 { margin-bottom:6px; }
#page-action .action-heading p:last-child {
  max-width:68ch; margin:0; color:var(--ink2); font-size:13px; line-height:1.55;
}
.action-heading-actions {
  display:flex; flex-wrap:wrap; align-items:center; justify-content:flex-end; gap:8px;
}
.action-heading-actions button { min-height:38px; }
.action-workspace-panel { display:grid; gap:16px; min-width:0; }
.action-measures, .workspace-measures {
  display:grid; grid-template-columns:repeat(var(--measure-cols,4),minmax(0,1fr));
  overflow:hidden; border:1px solid var(--line); border-radius:10px;
  background:var(--card);
}
.action-measure, .workspace-measure {
  min-width:0; padding:15px 18px; border-inline-start:1px solid var(--line);
}
.action-measure:first-child, .workspace-measure:first-child { border-inline-start:0; }
.action-measure > p, .workspace-measure > p {
  margin:0; color:var(--muted); font-size:11px; font-weight:650;
  letter-spacing:.08em; text-transform:uppercase;
}
.action-measure > div, .workspace-measure > div {
  display:flex; align-items:baseline; gap:6px; margin-top:7px; line-height:1.1;
}
.action-measure b, .workspace-measure b {
  font-family:"Archivo",sans-serif; font-size:30px; font-weight:600;
  letter-spacing:-.03em; font-variant-numeric:tabular-nums;
}
.action-measure span, .workspace-measure span { color:var(--muted); font-size:14px; }
.action-measure small, .workspace-measure small {
  display:block; margin-top:8px; overflow:hidden; color:var(--ink2);
  font-size:12px; text-overflow:ellipsis; white-space:nowrap;
}
.action-measure.urgent b, .workspace-measure.urgent b { color:var(--fail); }
.action-measure.attention b, .workspace-measure.attention b { color:var(--progress-mid); }
.action-measure.routine b, .workspace-measure.routine b { color:var(--info); }
#page-action .action-toolbar { margin:0; }
#page-action .action-field {
  display:flex; align-items:center; gap:7px; min-height:40px; box-sizing:border-box;
  padding:6px 10px; border:1px solid var(--line2); border-radius:8px;
  background:var(--card2); color:var(--muted); font-size:13px;
}
#page-action .action-field select {
  min-height:26px; padding:0 18px 0 0; border:0; background:transparent;
  color:var(--ink); font:inherit; font-size:13.5px;
}
#page-action .action-field select option {
  background:var(--card); color:var(--ink);
}
:root[data-theme="dark"] #page-action .action-field select { color-scheme:dark; }
#page-action .action-field select:focus-visible { outline:2px solid var(--accent); outline-offset:2px; }
.action-open-count {
  margin-left:auto; color:var(--muted); font-size:12.5px; font-variant-numeric:tabular-nums;
}
#page-action #action-list { display:grid; gap:16px; min-width:0; }
#page-action .action-group-panel {
  min-width:0; overflow:hidden; border:1px solid var(--line);
  border-radius:10px; background:var(--card);
}
#page-action .action-group-head {
  display:flex; align-items:center; justify-content:space-between; gap:12px;
  padding:13px 16px; border-bottom:1px solid var(--line);
}
#page-action .action-group-head .eyebrow { margin:0 0 2px; }
#page-action .action-group-head h2 {
  margin:0; color:var(--ink); font-size:14.5px; font-weight:650;
  letter-spacing:-.01em; text-transform:none;
}
#page-action .action-group-head > .chip {
  background:var(--card2); color:var(--ink2); font-weight:500;
}
#page-action #action-list .action-row {
  display:flex; align-items:center; gap:12px; width:100%; min-height:58px;
  margin:0; padding:11px 16px 11px 13px; border:0;
  border-bottom:1px solid var(--line); border-inline-start:3px solid transparent;
  border-radius:0; background:var(--card); color:var(--ink); cursor:pointer;
}
#page-action #action-list .action-row:last-child { border-bottom:0; }
#page-action #action-list .action-row:hover { background:var(--card2); }
#page-action #action-list .action-row.urgent { border-inline-start-color:var(--fail); }
#page-action #action-list .action-row.attention { border-inline-start-color:var(--progress-mid); }
#page-action #action-list .action-row.routine { border-inline-start-color:var(--info); }
#page-action #action-list .action-row .txt { flex:1; min-width:0; }
#page-action #action-list .action-row .txt b {
  display:block; overflow:hidden; font-size:13.5px; font-weight:600;
  line-height:1.35; text-overflow:ellipsis; white-space:nowrap;
}
#page-action #action-list .action-row .txt small {
  display:block; overflow:hidden; margin-top:2px; color:var(--muted);
  font-size:12px; text-overflow:ellipsis; white-space:nowrap;
}
#page-action #action-list .action-row > .chip { flex:none; }
#page-action #action-list .action-row .chev { width:15px; height:15px; flex:none; color:var(--muted); }
#page-action #action-list > .empty-state {
  margin:0; border:1px solid var(--line); border-radius:10px; background:var(--card);
}

@media (max-width:700px) {
  .action-heading-actions { width:100%; justify-content:stretch; }
  .action-heading-actions button { flex:1; min-height:44px; }
  .action-measures, .workspace-measures { grid-template-columns:repeat(2,minmax(0,1fr))!important; }
  .action-measure, .workspace-measure { border-top:1px solid var(--line); margin-top:-1px; }
  .action-measure:nth-child(odd), .workspace-measure:nth-child(odd) { border-inline-start:0; }
  #page-action .action-field { flex:1 1 100%; min-height:44px; }
  #page-action .action-field select { flex:1; }
  .action-open-count { width:100%; margin-left:0; }
  #page-action #action-list .action-row { align-items:flex-start; flex-wrap:wrap; }
  #page-action #action-list .action-row .txt { flex-basis:calc(100% - 28px); }
  #page-action #action-list .action-row > .chip { margin-left:auto; }
  #page-action #action-list .action-row .chev { margin-top:3px; }
}

/* ── Engineering issues ────────────────────────────────────────────────── */
#page-engineering .engineering-heading {
  align-items:flex-start; flex-wrap:wrap; padding-bottom:0;
}
#page-engineering .engineering-heading h1 { margin-bottom:6px; }
#page-engineering .engineering-page-intro {
  max-width:72ch; margin:0; color:var(--ink2); font-size:13px; line-height:1.55;
}
.engineering-page-actions {
  display:flex; align-items:center; justify-content:flex-end; gap:8px; flex-wrap:wrap;
}
.engineering-page-actions > button { min-height:40px; }
.engineering-field {
  display:inline-flex; align-items:center; gap:7px; min-height:40px;
  box-sizing:border-box; padding:6px 10px; border:1px solid var(--line2);
  border-radius:8px; background:var(--card2); color:var(--muted); font-size:13px;
}
.engineering-field select {
  min-height:26px; padding:0 18px 0 0; border:0; background:transparent;
  color:var(--ink); font:inherit; font-size:13.5px;
}
.engineering-field select option { background:var(--card); color:var(--ink); }
:root[data-theme="dark"] .engineering-field select { color-scheme:dark; }
.engineering-state-tabs {
  display:flex; flex-basis:100%; gap:2px; overflow-x:auto; margin-top:4px;
}
.engineering-state-tabs button {
  min-height:42px; padding:8px 12px 10px; border:0;
  border-bottom:2px solid transparent; border-radius:0; background:transparent;
  color:var(--ink2); font:inherit; font-size:13px; cursor:pointer;
}
.engineering-state-tabs button.on {
  border-bottom-color:var(--accent); color:var(--ink); font-weight:650;
}
.engineering-state-tabs button b {
  margin-left:3px; color:var(--muted); font-size:12px; font-weight:600;
}
#page-engineering .engineering-coverage-panel { padding-bottom:0; }
#page-engineering .engineering-coverage {
  grid-template-columns:repeat(3,minmax(0,1fr)); gap:12px;
  margin:0; padding-bottom:14px;
}
#page-engineering .engineering-check-card {
  display:grid; grid-template-columns:minmax(0,1fr) auto;
  grid-template-rows:minmax(46px,auto) auto auto minmax(30px,auto);
  column-gap:10px; align-content:start; min-height:150px; margin:0; padding:14px;
  border:1px solid var(--line);
  border-radius:8px; background:var(--card2); box-shadow:none;
}
#page-engineering .engineering-check-card h3 {
  grid-column:1; grid-row:1; max-width:none; margin:0; font-size:13px;
  font-weight:650; line-height:1.45;
}
#page-engineering .engineering-check-card > .chip { grid-column:2; grid-row:1; align-self:start; }
#page-engineering .engineering-check-count {
  grid-column:1 / -1; grid-row:2;
  color:var(--ink); font-family:"Archivo",sans-serif; font-size:26px;
  font-weight:600; letter-spacing:-.03em;
}
#page-engineering .engineering-check-count.unavailable { color:var(--muted); }
#page-engineering .engineering-check-card > small:not(.engineering-coverage-summary) {
  grid-column:1 / -1; grid-row:3; font-size:11.5px;
}
#page-engineering .engineering-coverage-summary {
  grid-column:1 / -1; grid-row:4; align-self:end; margin-top:8px;
  padding-top:8px; border-top:1px solid var(--line); font-size:11.5px;
}
.engineering-help-open { min-width:44px; min-height:44px; }
.engineering-coverage-note {
  margin:0 -16px; padding:10px 16px; border-top:1px solid var(--line);
  color:var(--muted); font-size:12.5px;
}
#page-engineering .engineering-coverage-note > .count-note { margin:8px 0 0; }
.engineering-help-dialog { box-sizing:border-box; width:min(820px,92vw); max-height:84dvh; overflow:auto; }
.engineering-help-dialog form { display:grid; gap:22px; }
.engineering-help-head { display:flex; align-items:flex-start; justify-content:space-between; gap:16px; }
.engineering-help-head .eyebrow { margin:0 0 3px; }
.engineering-help-head h2 { margin:0; }
.engineering-help-dialog section > h3 { margin:0 0 10px; font-size:14px; }
.engineering-help-dialog .engineering-status-help {
  grid-template-columns:repeat(2,minmax(0,1fr)); gap:10px 20px; margin:0;
}
.engineering-help-checks { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:0 22px; }
.engineering-help-checks article { padding:10px 0; border-top:1px solid var(--line); }
.engineering-help-checks h4 { margin:0 0 4px; font-size:13px; }
.engineering-help-checks p { margin:0; color:var(--ink2); font-size:12px; line-height:1.45; }
#page-engineering .engineering-findings-head {
  display:flex; align-items:center; justify-content:space-between; gap:12px;
}
#page-engineering .engineering-findings-head h2 { margin:0; }
#page-engineering .engineering-findings-head .eyebrow { margin:0 0 2px; }
#page-engineering .engineering-filters { margin:0 0 14px; }
#page-engineering .engineering-filters .filter-search { min-height:40px; }
#page-engineering .engineering-findings {
  min-width:0; gap:0; overflow:hidden; margin:0 -16px -16px;
  border-top:1px solid var(--line); background:var(--card);
}
#page-engineering .issue-group-heading {
  margin:0; padding:10px 16px; border-bottom:1px solid var(--line);
  background:var(--card2); color:var(--muted); font-size:11px;
  font-weight:650; letter-spacing:.08em; text-transform:uppercase;
}
#page-engineering .engineering-finding {
  margin:0; padding:15px 16px; border:0; border-bottom:1px solid var(--line);
  border-radius:0; background:var(--card);
}
#page-engineering .engineering-finding:last-child { border-bottom:0; }
.engineering-finding-main { display:flex; align-items:flex-start; gap:14px; }
.engineering-finding-copy { flex:1; min-width:0; }
.engineering-finding-titleline {
  display:flex; align-items:center; gap:8px; flex-wrap:wrap;
}
.engineering-finding-titleline h3 {
  margin:0; font-size:14.5px; font-weight:650; letter-spacing:-.01em;
}
.engineering-finding-summary {
  max-width:82ch; margin:6px 0 0; color:var(--ink2); font-size:13px; line-height:1.45;
}
.engineering-finding-meta {
  display:flex; flex-wrap:wrap; gap:14px; margin-top:9px; color:var(--muted);
  font-size:12px;
}
.engineering-finding-row-actions {
  display:flex; align-items:center; justify-content:flex-end; gap:7px; flex:none;
}
.engineering-finding-row-actions button { min-height:36px; white-space:nowrap; }
.engineering-finding-details {
  margin-top:11px; padding-top:9px; border-top:1px solid var(--line);
  color:var(--ink2); font-size:12.5px;
}
.engineering-finding-details > summary {
  width:max-content; color:var(--ink2); font-weight:650; cursor:pointer;
}
.engineering-finding-details > p { margin:10px 0 0; }
.engineering-finding-identity .eyebrow { display:block; margin-bottom:3px; }
#page-engineering .engineering-placements { margin-top:10px; }
#page-engineering .engineering-placements li { padding:8px 0; }

@media (max-width:700px) {
  .engineering-page-actions { width:100%; justify-content:stretch; }
  .engineering-page-actions > * { flex:1 1 100%; width:100%; min-height:44px; }
  #page-engineering .engineering-findings-head { align-items:stretch; flex-direction:column; }
  #page-engineering .engineering-findings-head .engineering-field { width:100%; }
  #page-engineering .engineering-findings-head select { flex:1; }
  #page-engineering .engineering-filters > * { flex:1 1 100%; width:100%; min-height:44px; }
  #page-engineering .engineering-coverage { grid-template-columns:1fr 1fr; gap:8px; }
  #page-engineering .engineering-check-card { min-height:132px; padding:12px; }
  .engineering-finding-main { flex-direction:column; }
  .engineering-finding-row-actions { width:100%; justify-content:stretch; }
  .engineering-finding-row-actions button { flex:1; min-height:44px; }
}
@media (max-width:1000px) and (min-width:431px) {
  #page-engineering .engineering-coverage { grid-template-columns:repeat(2,minmax(0,1fr)); }
}
@media (max-width:430px) {
  #page-engineering .engineering-coverage { grid-template-columns:1fr; }
  .engineering-help-dialog .engineering-status-help,
  .engineering-help-checks { grid-template-columns:1fr; }
}

/* ── Project history ───────────────────────────────────────────────────── */
.intelligence-page-heading .intelligence-view-tabs { border-top:0; }
#page-project-intelligence .intelligence-head > .note:first-child { margin-top:0; }
#page-project-intelligence .workspace-heading > .chip,
#page-project-intelligence .intelligence-highlight > .chip { align-self:flex-start; }
#page-project-intelligence :is(.toolbar, .section-heading)
  :is(button, input:not([type=checkbox]), select) {
  box-sizing:border-box; min-height:40px;
}
/* Not the search box's own text: the shared search box draws the border, and
   this rule, weighted by the page's id, drew a second box inside it. */
#page-project-intelligence :is(.toolbar, .section-heading)
  :is(input:not([type=checkbox]):not(.filter-search input), select) {
  padding:7px 10px; background:var(--card2); color:var(--ink);
  border:1px solid var(--line2); border-radius:8px; font:inherit;
  font-size:var(--field-font);
}
#page-project-intelligence .journal-filters > label {
  display:inline-flex; align-items:center; min-height:40px;
}
#page-project-intelligence :is(.intelligence-highlights, .journal-list):not(:empty) {
  min-width:0; gap:0; overflow:hidden; border:1px solid var(--line);
  border-radius:10px; background:var(--card);
}
#page-project-intelligence .intelligence-highlight,
#page-project-intelligence .journal-entry {
  border:0; border-bottom:1px solid var(--line); border-radius:0;
  background:var(--card);
}
#page-project-intelligence :is(.intelligence-highlight, .journal-entry):last-child {
  border-bottom:0;
}
#page-project-intelligence .intelligence-highlight { border-inline-start:5px solid var(--data); }
#page-project-intelligence .intelligence-highlight.urgent { border-inline-start-color:var(--fail); }
#page-project-intelligence .intelligence-highlight.attention { border-inline-start-color:#9a681c; }
#page-project-intelligence .journal-entry.system { border-inline-start:5px solid var(--data); }

@media (max-width:700px) {
  #page-project-intelligence .intelligence-head .toolbar > *,
  #page-project-intelligence .journal-filters > * { flex:1 1 100%; width:100%; }
  #page-project-intelligence :is(.toolbar, .section-heading)
    :is(button, input:not([type=checkbox]), select),
  #page-project-intelligence .journal-filters > label { min-height:44px; }
}

/* ── Collector imports ─────────────────────────────────────────────────── */
#page-snapshot .imports-upload-panel > .note:first-child { margin-top:0; }
#page-snapshot :is(.snapshot-upload-form, .snapshot-installation-form,
  .snapshot-inline-form, .snapshot-actions)
  :is(input:not([type=checkbox]), select, button) {
  box-sizing:border-box; min-width:0; min-height:40px;
}
#page-snapshot .snapshot-installation-form > button {
  padding:9px 14px; background:var(--accent); color:var(--btn-ink);
  border:0; border-radius:8px; font:inherit; font-weight:650; cursor:pointer;
}
#page-snapshot :is(.snapshot-installations, #snapshot-history, #snapshot-health):not(:empty) {
  min-width:0; overflow:hidden; border:1px solid var(--line);
  border-radius:10px; background:var(--card);
}
#page-snapshot .snapshot-installations { gap:0; }
#page-snapshot :is(.snapshot-installation-row, .snapshot-history-row, .snapshot-health-row) {
  margin:0; padding:11px 12px; border:0; border-bottom:1px solid var(--line);
  border-radius:0; background:var(--card);
}
#page-snapshot :is(.snapshot-installation-row, .snapshot-history-row, .snapshot-health-row):last-child {
  border-bottom:0;
}

@media (max-width:700px) {
  #page-snapshot :is(.snapshot-upload-form, .snapshot-installation-form,
    .snapshot-inline-form, .snapshot-actions)
    :is(input:not([type=checkbox]), select, button) { min-height:44px; }
  #page-snapshot .snapshot-upload-form > *,
  #page-snapshot .snapshot-inline-form > *,
  #page-snapshot .snapshot-actions > * { flex:1 1 100%; width:100%; max-width:none; }
}

/* ── Administration workspace ──────────────────────────────────────────── */
#page-admin .admin-heading + .admin-tabs { margin-top:0; }
#page-admin > .admin-tabs {
  /* auto-fit rather than a counted three. There have been four tabs since
     Job roles was added, so the fourth was sharing a track with its
     neighbour. A band that counts its own columns cannot fall behind. */
  display:grid; grid-auto-flow:column; grid-auto-columns:minmax(0,1fr); gap:0;
  margin:0; padding:12px 0 0; border-bottom:1px solid var(--line2);
}
#page-admin > .admin-tabs button {
  min-width:0; min-height:44px; padding:8px 10px; background:transparent;
  color:var(--ink2); border:0; border-bottom:3px solid transparent;
  border-radius:0; font:inherit; font-size:13.5px; cursor:pointer;
}
#page-admin > .admin-tabs button.on {
  /* The accent is the underline, not the words. As text it is 1.7:1 against
     the light page - the selected tab was the hardest label to read on the
     screen, which is the opposite of what selected should mean. */
  background:transparent; color:var(--ink); border-color:var(--accent);
  font-weight:700;
}
#page-admin :is(.admin-invite-form, .admin-form, .toolbar,
  .people-table, #org-table, #admin-access-table)
  :is(input:not([type=checkbox]):not([type=hidden]), select, button) {
  box-sizing:border-box; min-height:40px;
}
#page-admin .tbl-wrap {
  min-width:0; overflow-x:auto; border:1px solid var(--line);
  border-radius:10px; background:var(--card);
}
#page-admin .tbl-wrap th { background:var(--card2); }
#page-admin .tbl-wrap tbody tr:last-child td { border-bottom:0; }
#page-admin .admin-project-list:not(:empty) {
  gap:0; overflow:hidden; border:1px solid var(--line);
  border-radius:10px; background:var(--card);
}
#page-admin .admin-project-list .admin-project-row {
  margin:0; border:0; border-bottom:1px solid var(--line);
  border-radius:0; background:var(--card);
}
#page-admin .admin-project-list .admin-project-row:last-child { border-bottom:0; }
#page-admin .admin-project-list .admin-project-row.on {
  outline:0; background:var(--sel-bg);
}

@media (max-width:700px) {
  #page-admin > .admin-tabs button { padding-inline:5px; font-size:12.5px; }
  #page-admin :is(.admin-invite-form, .admin-form, .toolbar,
    .people-table, #org-table, #admin-access-table)
    :is(input:not([type=checkbox]):not([type=hidden]), select, button) {
    min-height:44px;
  }
  #page-admin .toolbar input[type=search] { flex:1 1 100%; width:100%; }
}
#floor-picker, #module-picker {
  background:var(--card2); color:var(--ink); border:1px solid var(--line2);
  border-radius:8px; padding:7px 10px; font:inherit; font-size:.9rem;
  max-width:260px;
}
@media (max-width:640px) {
  #floor-picker, #module-picker { flex:1 1 45%; max-width:none; }
}

/* Swipe-to-record rows: a transformed surface over commit underlays.
   The surface tracks the finger 1:1 (fluid.js), rubber-bands past the
   reveal, and commits by momentum projection. touch-action:pan-y keeps
   vertical scrolling native while we own horizontal. */
/* Device names, short addresses and codes are data, not prose. In a
   monospaced face they line up in a column and the eye reads them as
   identifiers rather than as words. */
.dev-name, code {
  font-family:'IBM Plex Mono', ui-monospace, "Cascadia Mono", Consolas, monospace;
  letter-spacing:-.01em;
}
.dev-row {
  position:relative; overflow:hidden; border-bottom:1px solid var(--line);
  border-radius:8px;
}
.dev-under {
  position:absolute; inset:0; display:flex; align-items:center;
  font-size:.85rem; font-weight:700; letter-spacing:.04em;
  text-transform:uppercase; pointer-events:none;
}
.dev-under.commit-pass {
  justify-content:flex-start; padding-left:18px;
  background:var(--data); color:#fff;
}
.dev-under.commit-pending {
  justify-content:flex-end; padding-right:18px;
  background:var(--chip-na-bg); color:var(--ink2);
}
.dev-swipe {
  position:relative; display:flex; flex-wrap:wrap; align-items:center; gap:10px;
  padding:10px 8px; background:var(--card);
  touch-action:pan-y; will-change:transform;
}
.dev-main { flex:1 1 240px; min-width:200px; }
.dev-name { font-size:.9rem; font-weight:600; }
/* Result filter. Label above count so four thumb-sized targets fit a phone,
   and the active one borrows the colour its result already uses on the row
   buttons — so "I am looking at what's outstanding" is legible at a glance. */
.dev-filter { flex:1 1 100%; margin-top:2px; }
.dev-filter button {
  flex:1 1 0; display:flex; align-items:center;
  justify-content:center; gap:5px; padding:6px 10px; min-height:44px;
  line-height:1.2;
}
.dev-filter button b {
  font-size:12px; font-weight:600; color:var(--muted);
  font-variant-numeric:tabular-nums;
}
.dev-filter button.on b { color:inherit; opacity:.8; }
.dev-filter button.on[data-status=pass] {
  background:var(--chip-pass-bg); color:var(--chip-pass-ink);
}
.dev-filter button.on[data-status=pending] {
  background:var(--chip-warn-bg); color:var(--chip-warn-ink);
}
.dev-filter button.on[data-status=not_installed] {
  background:var(--chip-fail-bg); color:var(--chip-fail-ink);
}
@media (min-width:641px) { .dev-filter { max-width:440px; } }

.dev-meta { font-size:.8rem; color:var(--muted); }
.dev-meta .flag { color:var(--chip-fail-ink); font-weight:600; }
.dev-meta .queued { color:var(--accent-ink); font-weight:600; }
.tri {
  display:flex; border:1px solid var(--line2); border-radius:10px;
  overflow:hidden; background:var(--card2);
}
.tri button {
  background:none; border:none; border-radius:0; color:var(--ink2); font:inherit;
  font-size:.85rem; padding:10px 18px; min-height:44px; min-width:76px;
  white-space:nowrap; cursor:pointer;
  transition:transform 80ms ease-out, background 120ms ease-out;
}
.tri button:active { transform:scale(.94); }
.tri button + button { border-left:1px solid var(--line2); }
.tri button.on.pass { background:var(--chip-pass-bg); color:var(--chip-pass-ink); font-weight:650; }
.tri button.on.pending { background:var(--chip-warn-bg); color:var(--chip-warn-ink); font-weight:650; }
.tri button.on.not_installed { background:var(--chip-fail-bg); color:var(--chip-fail-ink); font-weight:650; }
/* This is NOT redundant with the site-wide button:disabled rule. `.tri button`
   sets cursor:pointer at the same specificity and later in the file, so it
   wins unless this says otherwise. Deleting it as a duplicate put the plain
   hand back on a device result that had already been recorded. */
.tri button:disabled { opacity:.55; cursor:not-allowed; }
.dev-actions { display:flex; align-items:center; gap:8px; }
.dev-actions .ghost-btn { min-height:44px; padding:7px 12px; }

/* Phones: the three results share the full row width equally — big,
   even, thumb-sized targets instead of squeezed desktop buttons. */
@media (max-width:640px) {
  .dev-actions { flex-basis:100%; }
  .tri { flex:1 1 auto; }
  .tri button {
    flex:1 1 0; min-width:0; padding:8px 4px; font-size:.82rem;
    white-space:normal; line-height:1.15;   /* "Not installed" wraps, never clips */
  }
}
.dev-error {
  flex-basis:100%; font-size:.8rem; color:var(--fail); padding:0 2px 6px;
}
@media (prefers-reduced-motion: reduce) {
  .tri button, .tri button:active { transition:none; transform:none; }
}

/* ── Network / outbox chip ─────────────────────────────────────────────── */
.net-chip {
  font-size:.78rem; font-weight:600; border-radius:999px; padding:4px 12px;
  letter-spacing:.02em; border:1px solid #4a4a4a; color:#cfcfcf;
}
.net-chip.offline { background:#3a2a1a; color:#f0b46a; border-color:#5a4020; }
.net-chip.queued  { background:#2c3618; color:#b9dd7d; border-color:#4a5a2a; }

/* ── Reassign dialog — a material that "materializes" (blur + scale in),
   over a blurred dimming scrim, per the modal-task pattern ─────────────── */
dialog {
  background:color-mix(in srgb, var(--card) 82%, transparent);
  -webkit-backdrop-filter:blur(24px) saturate(160%);
  backdrop-filter:blur(24px) saturate(160%);
  color:var(--ink); border:1px solid var(--line2);
  border-radius:14px; padding:26px 28px; width:min(430px, 92vw);
  box-shadow:0 18px 50px rgba(0,0,0,.35);
}
dialog::backdrop {
  background:rgba(0,0,0,.35);
  -webkit-backdrop-filter:blur(6px);
  backdrop-filter:blur(6px);
}
@media (prefers-reduced-motion: no-preference) {
  dialog[open] { animation:materialize 240ms cubic-bezier(.2,.9,.3,1); }
  @keyframes materialize {
    from { transform:scale(.94); opacity:0; filter:blur(6px); }
    to   { transform:scale(1);   opacity:1; filter:blur(0); }
  }
}
@media (prefers-reduced-motion: reduce) {
  dialog[open] { animation:fadein 160ms ease; }
  @keyframes fadein { from { opacity:0; } to { opacity:1; } }
}
@media (prefers-reduced-transparency: reduce) {
  dialog { background:var(--card); -webkit-backdrop-filter:none; backdrop-filter:none; }
  dialog::backdrop { -webkit-backdrop-filter:none; backdrop-filter:none; background:rgba(0,0,0,.55); }
}
@media (prefers-contrast: more) {
  dialog { background:var(--card); -webkit-backdrop-filter:none; backdrop-filter:none;
           border:2px solid var(--ink); }
}
dialog h2 { margin-top:0; }
dialog label {
  display:block; font-size:11px; font-weight:600; letter-spacing:.08em;
  text-transform:uppercase; color:var(--muted); margin:14px 0 4px;
}
dialog label .hint { text-transform:none; letter-spacing:0; font-weight:400; }
dialog input:not([type=checkbox]), dialog select, dialog textarea,
.snag-detail-panel select, .snag-detail-panel textarea {
  width:100%; background:var(--card2); color:var(--ink);
  border:1px solid var(--line2); border-radius:8px; padding:9px 12px; font:inherit;
  /* A field sits inside its label, which is 11 px capitals. The field's own
     text is the size of every other field, whatever its label looks like. */
  font-size:var(--field-font); font-weight:400; text-transform:none; letter-spacing:0;
}
dialog textarea, .snag-detail-panel textarea { resize:vertical; min-height:72px; }
.snag-detail-panel select { min-height:44px; }
.ra-manual-row {
  display:flex !important; align-items:center; gap:8px;
  text-transform:none !important; letter-spacing:0 !important;
  font-size:12.5px !important; font-weight:400 !important;
  color:var(--ink2) !important; margin:8px 0 4px !important;
}
.ra-preview {
  margin:14px 0 0; font-size:13px; background:var(--card2);
  border-radius:8px; padding:9px 12px;
}
/* Wrapping matters more than it looks. With nowrap, three buttons whose
   labels do not fit push the row LEFT out of the dialog: measured on the New
   snag form, the row had 357px and the buttons needed 418px, so Cancel began
   61px outside the dialog's own content box. It read as "Cancel is too close
   to the edge"; it was over it. Wrapping keeps every dialog inside itself at
   any width and any wording.
   One rule, carrying its own top margin: tests/test_webapp_icon_consistency.py
   requires exactly one `.dlg-actions {` block and that it is this one. */
.dlg-actions { display:flex; flex-wrap:wrap; justify-content:flex-end; gap:10px; margin-top:20px; }
/* Cancel is the way out, not one of the choices, so it takes the other end of
   the row. That also gives the two create actions room to sit together. */
#snag-form .dlg-actions #snag-cancel { margin-inline-end:auto; }
/* ── Snag drawings ───────────────────────────────────────────────────────────
   Floors as cards, each saying what is outstanding on it. Reached from Snags,
   opening the snag viewer — the same one a snag from the list opens. */
.snag-drawings-dlg { width:min(760px, 94vw); }
.snag-drawings-head { display:flex; align-items:flex-start; justify-content:space-between; gap:16px; }
.snag-drawings-head h2 { margin:0; }
/* Scrolls with the page, like the progress list. A pane of its own inside a
   page that also scrolls halves how many floors are on screen and gives the
   reader two scrollbars to choose between. */
.snag-drawings-list {
  display:grid; gap:10px; margin-top:16px;
  grid-template-columns:repeat(auto-fill, minmax(220px, 1fr));
}
.snag-drawing-card {
  position:relative; display:flex; flex-direction:column; align-items:stretch; gap:0;
  text-align:start; padding:0; min-height:44px; overflow:hidden;
  background:var(--card); border:1px solid var(--line2); border-radius:10px;
}
.snag-drawing-card:hover { border-color:var(--muted); background:var(--card2); }
.snag-drawing-card.selected { border-color:var(--accent); }
/* The whole card opens the floor; the tick box sits above it and is not part
   of that target, the same arrangement the progress cards use. */
.snag-drawing-open {
  position:absolute; inset:0; z-index:1; padding:0; border:0; border-radius:10px;
  background:none; cursor:pointer;
}
.snag-drawing-card .drawing-card-select { z-index:2; }
/* The preview is the same component the progress cards use, so a floor looks
   the same wherever it is listed. */
.snag-drawing-card .drawing-thumb { width:100%; }
.snag-drawing-body {
  display:flex; flex-direction:column; align-items:flex-start; gap:4px; padding:12px 14px;
}
.snag-drawing-floor { font-weight:700; color:var(--ink); }
.snag-drawing-name { color:var(--muted); font-size:11.5px; overflow-wrap:anywhere; }
.snag-drawing-counts { display:flex; flex-wrap:wrap; gap:5px; margin-top:4px; }
.snag-drawing-note { color:var(--muted); font-size:11px; }
/* The same three tones the badges and the marks use, so a count and a mark
   never disagree about what a status looks like. */
.snag-count-chip {
  border-radius:999px; padding:2px 8px; font-size:11px; font-weight:650;
  background:var(--chip-na-bg); color:var(--chip-na-ink);
}
.snag-count-chip.tone-issue { background:var(--chip-fail-bg); color:var(--chip-fail-ink); }
.snag-count-chip.tone-information { background:color-mix(in srgb,var(--info) 14%,var(--card)); color:var(--info); }
.snag-count-chip.tone-passed { background:var(--chip-pass-bg); color:var(--chip-pass-ink); }

/* New snag carries three buttons, one of them "Create and place on drawing".
   They come to 418px and the default dialog gives the row 357px. The names are
   the ones the workflow specifies, so the dialog makes room rather than the
   words getting shorter. */
#snag-dlg { width:min(520px, 92vw); }
#ra-submit, #part-submit {
  background:var(--accent); color:var(--btn-ink); border:none; border-radius:8px;
  padding:8px 18px; font:inherit; font-weight:650; cursor:pointer;
}
#part-submit:disabled { opacity:.6; cursor:not-allowed; }

/* ── Dashboard report ──────────────────────────────────────────────────────
   The screen follows the report builder in the workspace reference. The
   printable document keeps its existing rules and remains the only content
   that reaches paper. */
#page-report { gap:16px; }
.report-page-heading { align-items:flex-start; }
.report-heading-copy { max-width:650px; }
.report-heading-copy h1 { margin-bottom:6px; }
.report-heading-copy > p:last-child {
  margin:0; color:var(--ink2); font-size:13px; line-height:1.55;
}
.report-page-actions {
  display:flex; flex-wrap:wrap; align-items:center; justify-content:flex-end;
  gap:8px; max-width:58%;
}
.report-page-actions .chip { min-height:36px; display:inline-flex; align-items:center; }
.report-page-actions .ghost-btn, #report-print { min-height:38px; }
#report-print {
  background:var(--accent); color:var(--btn-ink); border:none; border-radius:8px;
  padding:8px 16px; font:inherit; font-weight:650; cursor:pointer;
}
.report-workspace {
  display:grid; grid-template-columns:minmax(230px,280px) minmax(0,1fr);
  gap:16px; align-items:start;
}
.report-toolbar {
  display:grid; gap:12px; margin:0; padding:0; max-width:none;
  align-self:start; background:transparent; border:0; border-radius:0; box-shadow:none;
}
.report-builder-panel {
  min-width:0; padding:14px 16px 16px; background:var(--card);
  border:1px solid var(--line); border-radius:10px;
}
.report-builder-panel > h2 {
  margin:0 -16px 12px; padding:0 16px 12px;
  border-bottom:1px solid var(--line); font-size:15px;
}
.report-builder-panel > .eyebrow { margin-bottom:3px; }
.report-preset-options { display:grid; gap:8px; }
.report-preset-option {
  display:flex; width:100%; min-height:38px; align-items:center;
  justify-content:flex-start; padding:8px 11px; background:transparent;
  border:1px solid var(--line); border-radius:8px; color:var(--ink2);
  font:inherit; font-size:13px; text-align:left; cursor:pointer;
}
.report-preset-option:hover { border-color:var(--line2); background:var(--card2); color:var(--ink); }
.report-preset-option.on {
  border-color:var(--accent); background:var(--chip-pass-bg);
  color:var(--accent-ink); font-weight:650;
}
#report-sections { margin:0; }
.report-toolbar .sections-list {
  position:static; min-width:0; margin:0; padding:0; display:grid; gap:0;
  background:transparent; border:0; border-radius:0; box-shadow:none;
}
.report-toolbar .check-label {
  display:grid; grid-template-columns:34px minmax(0,1fr) auto;
  align-items:center; gap:8px; min-height:42px; padding:7px 0;
  border-top:1px solid var(--line); color:var(--ink2); font-size:12.5px;
  cursor:pointer;
}
.report-toolbar .check-label input[type="checkbox"] {
  appearance:none; position:relative; width:30px; height:17px; margin:0;
  border:1px solid var(--line2); border-radius:999px; background:var(--card2);
  cursor:pointer; transition:background .15s ease,border-color .15s ease;
}
.report-toolbar .check-label input[type="checkbox"]::after {
  content:""; position:absolute; top:2px; left:2px; width:11px; height:11px;
  border-radius:50%; background:var(--muted); transition:transform .15s ease,background .15s ease;
}
.report-toolbar .check-label input[type="checkbox"]:checked {
  border-color:var(--accent); background:var(--chip-pass-bg);
}
.report-toolbar .check-label input[type="checkbox"]:checked::after {
  transform:translateX(13px); background:var(--accent);
}
.report-section-name { min-width:0; color:var(--ink); }
.report-section-status { color:var(--muted); font-size:10.5px; white-space:nowrap; }
.report-toolbar .sections-list .seg { margin:2px 0 8px 42px; }
.report-note-label {
  display:block; margin:14px 0 6px; color:var(--muted); font-size:11px;
  font-weight:600; letter-spacing:.06em; text-transform:uppercase;
}
.report-note-input {
  box-sizing:border-box; width:100%; min-width:0; background:var(--card2); color:var(--ink);
  border:1px solid var(--line2); border-radius:8px; padding:7px 11px; font:inherit;
  font-size:var(--field-font);
}
.report-hint { margin:10px 0 0; line-height:1.45; }
.report-back { width:100%; margin-top:12px; }
.report-preview-well {
  min-width:0; padding:26px; overflow-x:auto; background:var(--card2);
  border:1px solid var(--line); border-radius:10px;
}
.email-draft-dlg { width:min(720px, calc(100vw - 28px)); }
.email-draft-dlg form { display:grid; gap:10px; }
.email-draft-dlg fieldset { display:grid; gap:7px; border:1px solid var(--line); border-radius:8px; padding:10px 12px; }
.email-draft-dlg fieldset label { display:flex; align-items:center; gap:8px; }
.email-draft-dlg fieldset input { width:16px; height:16px; }
.email-draft-names { display:grid; grid-template-columns:auto 1fr; align-items:center; gap:8px 12px; }
#email-draft-preview { min-height:310px; font-family:inherit; line-height:1.45; }
@media (max-width:600px) { .email-draft-names { grid-template-columns:1fr; } }

.report {
  box-sizing:border-box; display:block; width:min(900px,100%); max-width:900px; margin:0 auto;
  background:var(--card); border:1px solid var(--line); border-radius:12px;
  box-shadow:var(--shadow); padding:34px 38px 28px;
}
#report-doc {
  --card:#ffffff; --card2:#f5f6f2; --ink:#1c1f19; --ink2:#454a3d;
  --muted:#6a705f; --line:#e2e5dc; --line2:#ccd1c5;
  --data:#7fb232; --data-track:#edf3df; --fail:#c94141;
  --progress-mid:#e3ad3d;
  --chip-pass-bg:#eef6dd; --chip-pass-ink:#56701f;
  --chip-fail-bg:#f9e7e5; --chip-fail-ink:#a92f2f;
  --chip-warn-bg:#fdf0d2; --chip-warn-ink:#8a5a12;
  --chip-info-bg:#e8f1fd; --chip-info-ink:#2c66a8;
  --chip-na-bg:#efefef; --chip-na-ink:#777d70;
  color:var(--ink); font-family:'Public Sans', "Segoe UI", system-ui, sans-serif;
}
@media (max-width:1050px) {
  .report-workspace { grid-template-columns:1fr; }
  .report-toolbar { grid-template-columns:repeat(2,minmax(0,1fr)); }
  .report-section-panel { min-width:0; }
}
@media (max-width:700px) {
  .report-page-actions { justify-content:flex-start; width:100%; max-width:none; }
  .report-page-actions > * { flex:1 1 auto; justify-content:center; }
  .report-toolbar { grid-template-columns:1fr; }
  .report-preview-well { padding:12px; }
}
/* Report header dividers: one thin line in a slightly muted Delmatic green
   (#9dc368, not #96D045), the weight of the grey dividers inside a report,
   so it accompanies the heading without competing with the wordmark. */
.rep-head { border-bottom:1px solid #9dc368; padding-bottom:18px; margin-bottom:22px; }
/* One heading scale for every printed report: a cover title 32px, a report
   or item title 21px, a section heading 15px. */
.rep-head h1 { font-size:21px; margin:10px 0 18px; letter-spacing:-.01em; }
.rep-meta { display:grid; grid-template-columns:repeat(auto-fit,minmax(190px,1fr)); gap:12px; }
.rep-meta span {
  display:block; font-size:10.5px; font-weight:600; letter-spacing:.09em;
  text-transform:uppercase; color:var(--muted); margin-bottom:2px;
}
.rep-meta b { font-size:13.5px; font-weight:600; }
.rep-user-note {
  margin:18px 0 0; font-size:13px; color:var(--ink2);
  background:var(--card2); border-radius:8px; padding:9px 13px;
}
.report-measures {
  display:grid; grid-template-columns:repeat(auto-fit,minmax(150px,1fr));
  gap:10px; margin-bottom:24px;
}
.report-measure {
  min-width:0; padding:14px 16px; border:1px solid var(--line);
  border-radius:8px; background:var(--card); break-inside:avoid;
}
.report-measure .v {
  font-size:28px; font-weight:650; letter-spacing:-.02em; line-height:1.15;
  font-variant-numeric:tabular-nums;
}
.report-measure .v small { font-size:14px; color:var(--ink2); font-weight:500; }
.report-measure .v small.unit { margin-left:3px; }
.report-measure .s { margin-top:3px; color:var(--ink2); font-size:11.5px; }
.report-progress-measure .v {
  display:inline-flex; align-items:baseline; padding:3px 10px;
  border-radius:999px;
}
.report-progress-measure.band-low .v { background:var(--chip-fail-bg); color:var(--chip-fail-ink); }
.report-progress-measure.band-mid .v { background:var(--chip-warn-bg); color:var(--chip-warn-ink); }
.report-progress-measure.band-high .v { background:var(--chip-pass-bg); color:var(--chip-pass-ink); }
.report-progress-measure .v small { color:inherit; }
.rep-sec { margin-bottom:26px; }
.rep-sec h2 { margin-bottom:12px; font-size:15px; }
.rep-note { font-size:11.5px; color:var(--muted); margin:10px 0 0; }
.rep-headline { font-size:14.5px; margin:0; color:var(--ink2); }
.rep-headline b { color:var(--ink); font-weight:650; }
.rep-subhead {
  font-size:11px; font-weight:600; letter-spacing:.09em; text-transform:uppercase;
  color:var(--muted); margin:18px 0 6px;
}
.rep-rows .rw {
  display:flex; justify-content:space-between; gap:14px; font-size:13px;
  padding:4px 0; color:var(--ink2); border-bottom:1px solid var(--line);
}
.rep-rows .rw b { color:var(--ink); font-variant-numeric:tabular-nums; font-weight:600; }
.rep-tbl th { position:static; }
.rep-tbl td, .rep-tbl th { padding:6px 8px; }
.rep-tbl tr:hover td { background:none; }
.rep-wrap { white-space:normal; min-width:200px; color:var(--ink2); }
.emergency-failure-table { margin-top:12px; width:100%; table-layout:fixed; }
.emergency-failure-table td { vertical-align:top; overflow-wrap:anywhere; white-space:normal; }
.emergency-failure-table th { white-space:normal; }
/* The locating facts and test dates sit under the value they describe. */
.emergency-failure-table td small { display:block; margin-top:2px; color:var(--muted); font-size:10px; line-height:1.35; }
.rep-floors .rep-floor-nm { white-space:normal; max-width:190px; }
.rep-bar-cell { width:44%; }
.rep-bar-cell .track {
  height:13px; background:var(--data-track); border-radius:4px; overflow:hidden;
}
.rep-bar-cell .fill { height:100%; border-radius:0 4px 4px 0; }
.rep-score { font-weight:650; }
.rep-score-chip {
  display:inline-flex; min-width:48px; justify-content:center; padding:2px 8px;
  border-radius:999px; font-size:11.5px; font-weight:650;
  font-variant-numeric:tabular-nums;
}
.rep-score-chip.band-low { background:var(--chip-fail-bg); color:var(--chip-fail-ink); }
.rep-score-chip.band-mid { background:var(--chip-warn-bg); color:var(--chip-warn-ink); }
.rep-score-chip.band-high { background:var(--chip-pass-bg); color:var(--chip-pass-ink); }
.rep-trend svg { width:100%; height:auto; display:block; color:var(--data); }
.rep-trend svg .area { stroke:none; }
.rep-modules td:first-child {
  font-family:'IBM Plex Mono', ui-monospace, "Cascadia Mono", Consolas, monospace;
  font-weight:600; letter-spacing:-.01em;
}
.rep-modules .rep-module-complete { width:24%; min-width:150px; }
.rep-modules .module-progress { min-width:120px; gap:6px; }
.rep-module-status {
  display:inline-flex; justify-content:center; min-width:68px; padding:2px 8px;
  border-radius:999px; font-size:10.5px; font-weight:650; white-space:nowrap;
}
.rep-module-status.complete { background:var(--chip-pass-bg); color:var(--chip-pass-ink); }
.rep-module-status.in-progress { background:var(--chip-warn-bg); color:var(--chip-warn-ink); }
/* ── Snapshot drawing evidence ─────────────────────────────────────────── */
.drawing-page-heading {
  align-items:flex-start; padding-bottom:10px; border-bottom:0;
}
.drawing-page-intro { max-width:610px; margin:6px 0 0; color:var(--ink2); font-size:13px; }
.drawing-page-actions {
  display:flex; flex-direction:column; align-items:flex-end; gap:9px; max-width:72%;
}
.drawing-snapshot-field {
  display:flex; align-items:center; gap:10px; min-height:38px; padding:0 10px;
  border:1px solid var(--line2); border-radius:8px; background:var(--card2);
  color:var(--muted); font-size:12.5px;
}
.drawing-snapshot-field:has(select[hidden]) { display:none; }
#drawing-request-picker {
  max-width:280px; padding:0 24px 0 0; border:0; background:transparent;
  color:var(--ink); font-weight:650;
}
.drawing-tabs {
  display:flex; gap:0; min-height:46px; margin-top:-1px; padding:0 10px;
  border-bottom:1px solid var(--line);
}
.drawing-tabs button {
  position:relative; min-height:46px; padding:0 14px; border:0; border-radius:0;
  background:transparent; color:var(--ink2); font:inherit; font-size:13px; cursor:pointer;
}
.drawing-tabs button.on { color:var(--ink); font-weight:650; }
.drawing-tabs button.on::after {
  content:""; position:absolute; right:0; bottom:-1px; left:0; height:2px;
  background:var(--accent);
}
.drawing-workspace { display:grid; gap:16px; }
.drawing-summary {
  display:grid; grid-template-columns:repeat(auto-fit,minmax(190px,1fr));
  overflow:hidden; border:1px solid var(--line); border-radius:10px; background:var(--card);
}
.drawing-measure {
  min-width:0; margin:-1px 0 0 -1px; padding:15px 18px;
  border-top:1px solid var(--line); border-left:1px solid var(--line);
}
.drawing-measure .eyebrow { margin:0; }
.drawing-measure-value {
  display:flex; align-items:baseline; gap:6px; margin-top:7px;
  color:var(--ink); font-size:30px; font-weight:650; letter-spacing:-.03em;
  font-variant-numeric:tabular-nums; line-height:1.1;
}
.drawing-measure-value small { color:var(--muted); font-size:13px; font-weight:500; letter-spacing:0; }
.drawing-measure-foot {
  min-height:22px; margin-top:8px; overflow:hidden; color:var(--ink2);
  font-size:12px; text-overflow:ellipsis; white-space:nowrap;
}
.report-family-options { display:grid; gap:7px; }
.report-family-options button {
  min-height:40px; text-align:left; background:var(--card2); color:var(--ink2);
  border:1px solid var(--line2); border-radius:8px;
}
.report-family-options button.on { border-color:var(--accent); box-shadow:inset 3px 0 var(--accent); color:var(--ink); font-weight:650; }
.snag-report-options { display:grid; gap:7px; }
.snag-report-options > label { color:var(--muted); font-size:11px; font-weight:650; }
.snag-report-options select, .snag-report-options input:not([type="checkbox"]), .snag-report-options textarea {
  box-sizing:border-box; width:100%; min-height:38px; padding:6px 8px;
  color:var(--ink); background:var(--card2); border:1px solid var(--line2); border-radius:7px;
}
.snag-report-options > .check-label { color:var(--ink2); font-size:12.5px; font-weight:500; }
.snag-report-inherited { margin:0 0 5px; padding:8px 10px; border-inline-start:3px solid var(--accent); background:var(--card2); color:var(--ink2); font-size:12px; }
.snag-report-date-fields { display:grid; grid-template-columns:1fr 1fr; gap:8px; }
.snag-report-date-fields label { display:grid; gap:4px; color:var(--muted); font-size:11px; }
.engineering-selection-bar {
  display:flex; flex-wrap:wrap; align-items:center; gap:8px; margin:12px 0;
  padding:10px 12px; border:1px solid var(--line); border-radius:9px; background:var(--card2);
}
.engineering-selection-bar[hidden] { display:none; }
.engineering-selection-bar b { margin-right:auto; }
.engineering-selection-bar p { flex-basis:100%; margin:0; color:var(--muted); font-size:12px; }
.engineering-select-control {
  display:flex; align-items:center; gap:7px; margin:0 0 9px; color:var(--ink2);
  font-size:12px; font-weight:650;
}
.engineering-select-control input { width:18px; height:18px; }
.engineering-finding.is-selecting { border-inline-start:3px solid var(--accent); }
.engineering-show-more { display:block; margin:14px auto 0; }
.admin-emergency-note { margin-top:2px; }

/* Derived Emergency evidence. It reads as a status line, not as a control,
   because nobody types it: it comes from the Collector Snapshot. */
.admin-emergency-evidence {
  margin:0 0 6px; color:var(--ink2); font-size:12px; font-weight:600;
  line-height:1.45; overflow-wrap:anywhere;
}

/* A Delmatic internal report says so on the screen and on the paper. On
   paper it is in the footer of every page (applyPrintFooter), not a line
   above the first page, where it pushed a full-page sheet onto page two. */
.report-internal-mark {
  margin:0 0 10px; padding:6px 12px; border-radius:8px;
  border:1px solid var(--warn-line, var(--line));
  background:var(--warn-bg, var(--panel2));
  color:var(--ink); font-size:12px; font-weight:700;
  letter-spacing:.04em; text-transform:uppercase;
}
@media print { .report-internal-mark { display:none!important; } }

/* Scope helper: ordinary smaller text on the form background. No icon, panel,
   border or tooltip colour: it is permanent explanation, not hidden help. */
.report-scope-helper { margin:0; color:var(--muted); font-size:12px; line-height:1.45; overflow-wrap:anywhere; }
.report-scope-count { margin:2px 0 4px; color:var(--ink2); font-size:12px; font-weight:600; line-height:1.45; overflow-wrap:anywhere; }
.engineering-report-options { display:grid; gap:7px; }
.engineering-report-options > label,
.engineering-report-check-types legend { color:var(--muted); font-size:11px; font-weight:650; }
.engineering-report-options select,
.engineering-report-options input:not([type="checkbox"]),
.engineering-report-options textarea {
  box-sizing:border-box; width:100%; min-height:38px; padding:6px 8px;
  color:var(--ink); background:var(--card2); border:1px solid var(--line2); border-radius:7px;
}
.engineering-report-options > .check-label { color:var(--ink2); font-size:12.5px; font-weight:500; }
.emergency-report-options { display:grid; gap:7px; }
.emergency-report-options > label,
.emergency-report-types legend { color:var(--muted); font-size:11px; font-weight:650; }
.emergency-report-options select,.emergency-report-options input:not([type="checkbox"]):not([type="radio"]),
.emergency-report-options textarea { box-sizing:border-box; width:100%; min-height:38px; padding:6px 8px;
  color:var(--ink); background:var(--card2); border:1px solid var(--line2); border-radius:7px; }
.emergency-report-types { display:grid; gap:7px; margin:0; padding:9px 0; border:0; }
.emergency-report-types label { display:flex; align-items:center; gap:8px; color:var(--ink2); }
.emergency-report-types input { width:17px; height:17px; }

.emergency-work-filters { display:grid; grid-template-columns:repeat(5,minmax(140px,1fr)); gap:10px; margin:12px 0; }
.emergency-work-filters label { display:grid; gap:5px; color:var(--muted); font-size:11px; font-weight:650; }
.emergency-work-filters select,.emergency-work-filters input { min-width:0; width:100%; box-sizing:border-box; }
.emergency-selection-bar { display:flex; flex-wrap:wrap; align-items:center; gap:8px; margin:12px 0; padding:10px 12px;
  border:1px solid var(--line); border-radius:9px; background:var(--card2); }
.emergency-selection-bar[hidden] { display:none; }
.emergency-selection-bar b { margin-right:auto; }
.emergency-selection-bar p { flex-basis:100%; margin:0; color:var(--muted); font-size:12px; }
.emergency-work-list { display:grid; gap:8px; }
.emergency-work-row { display:grid; grid-template-columns:minmax(220px,1.2fr) auto minmax(240px,1fr); gap:14px; align-items:center;
  padding:12px; border:1px solid var(--line); border-radius:9px; background:var(--card); }
.emergency-work-row.is-selecting { grid-template-columns:auto minmax(200px,1.2fr) auto minmax(220px,1fr); border-inline-start:3px solid var(--accent); }
.emergency-work-row h3,.emergency-work-row p { margin:0; }.emergency-work-row p { color:var(--muted); font-size:12px; }
.emergency-work-row dl { display:flex; justify-content:flex-end; gap:18px; margin:0; }
.emergency-work-row dl div { min-width:90px; }.emergency-work-row dt { color:var(--muted); font-size:10px; text-transform:uppercase; }
.emergency-work-row dd { margin:2px 0 0; }.emergency-select-control input { width:20px; height:20px; }
.emergency-work-state { font-size:12px; }.emergency-work-state.failure,.emergency-work-state.both { color:var(--fail); }
.emergency-work-state.required { color:#996000; }
@media(max-width:1050px){.emergency-work-filters{grid-template-columns:repeat(2,minmax(0,1fr));}.emergency-work-row,.emergency-work-row.is-selecting{grid-template-columns:auto minmax(0,1fr);}.emergency-work-row:not(.is-selecting)>div:first-child,.emergency-work-row:not(.is-selecting)>dl{grid-column:1/-1;}.emergency-work-row dl{justify-content:flex-start;}}
@media(max-width:600px){.emergency-work-filters{grid-template-columns:1fr}.emergency-selection-bar button{flex:1 1 140px}.emergency-work-row dl{display:grid;grid-template-columns:1fr 1fr;}}

.emergency-report-document { --sr-ink:#1b2119;--sr-muted:#66705f;--sr-line:#d9ded3;--sr-soft:#f3f5ef;
  color:var(--sr-ink);background:#fff;font:10.5px/1.4 'Public Sans','Segoe UI',system-ui,sans-serif; }
.emergency-work-sheet-head { display:flex; justify-content:space-between; align-items:baseline; gap:8mm; padding-bottom:2mm;
  margin-bottom:4mm; border-bottom:1px solid #9dc368; color:var(--sr-muted); font-size:8.5px; }
.emergency-work-sheet>h1 { margin:1mm 0 2mm; font-size:21px; line-height:1.15; }
.emergency-work-state-print { margin:0 0 3mm; padding:2.5mm 3mm; border-inline-start:4px solid #a76800; background:#fff5dd; font-size:15px; font-weight:750; }
.emergency-work-state-print.failure,.emergency-work-state-print.both { border-inline-start-color:#c22429; background:#fbe8e8; }
.emergency-work-facts { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:2mm 5mm; margin:0 0 4mm; padding:3mm; border:1px solid var(--sr-line); background:var(--sr-soft); }
.emergency-work-facts dt { color:var(--sr-muted); font-size:8px; font-weight:700; letter-spacing:.06em; text-transform:uppercase; }
.emergency-work-facts dd { margin:.5mm 0 0; overflow-wrap:anywhere; }
.emergency-work-drawings h2,.emergency-drawing-unavailable h2 { margin:0 0 2mm; font-size:15px; }
.emergency-work-drawings figure { margin:0 0 3mm; break-inside:avoid; }
.emergency-work-drawings img { display:block; box-sizing:border-box; width:100%; object-fit:contain; border:1px solid var(--sr-line); background:#fff; }
.emergency-locator img { height:47mm; }.emergency-detail img { height:102mm; }
/* A failure sheet carries how to fix it, so its drawings give up some height
   to keep the sheet on one A4 page. */
.emergency-work-sheet.has-fix .emergency-locator img { height:38mm; }
.emergency-work-sheet.has-fix .emergency-detail img { height:74mm; }
.emergency-work-fix { margin:0 0 4mm; padding:3mm 3.5mm; border:1px solid var(--sr-line); border-inline-start:4px solid #91c83e; break-inside:avoid; }
.emergency-work-fix h2 { display:flex; justify-content:space-between; align-items:baseline; gap:4mm; margin:0 0 1.5mm; font-size:15px; }
.emergency-work-fix h2 span { color:var(--sr-muted); font-size:9px; font-weight:700; letter-spacing:.05em; text-transform:uppercase; }
.emergency-work-fix-causes { margin:0 0 1.5mm; color:var(--sr-muted); font-size:9px; }
.emergency-work-fix-causes b { color:var(--sr-ink); }
.emergency-work-fix ol { margin:0; padding-left:5mm; columns:2; column-gap:6mm; font-size:9.5px; line-height:1.35; }
.emergency-work-fix li { break-inside:avoid; margin-bottom:1mm; }
.emergency-work-fix-after { margin:1.5mm 0 0; font-size:9px; font-weight:650; }
.emergency-work-signoff { display:grid; grid-template-columns:auto 1.2fr 1fr 2fr; gap:4mm; margin-top:2.5mm; font-size:8.5px; color:var(--sr-muted); }
.emergency-work-signoff span { display:flex; align-items:flex-end; gap:1.5mm; min-height:6mm; border-bottom:1px solid var(--sr-line); }
.emergency-work-signoff span:first-child { border-bottom:0; font-weight:700; color:var(--sr-ink); }
.emergency-work-signoff i { width:3.5mm; height:3.5mm; border:1px solid var(--sr-ink); }
.em-report-guide { margin-top:6mm; }
.em-report-cause { margin:0 0 4mm; break-inside:avoid; }
.em-report-cause h3 { margin:0 0 1mm; font-size:12px; }
.em-report-cause h3 code { color:#66705f; font:9px "IBM Plex Mono",monospace; }
.em-report-cause h3 span { color:#66705f; font-size:9px; font-weight:700; text-transform:uppercase; letter-spacing:.05em; }
.em-report-cause p { margin:0 0 1mm; color:#454a3d; font-size:10px; }
.em-report-cause ol { margin:0; padding-left:5mm; font-size:10px; line-height:1.4; }
.emergency-work-drawings figcaption { margin-top:1mm; color:var(--sr-muted); font-size:8.5px; }
.emergency-drawing-unavailable { margin-top:5mm; padding:4mm; border-inline-start:4px solid #a76800; background:#fff5dd; }
.emergency-multiple-note { padding:2mm 3mm; border-inline-start:3px solid #a76800; background:#fff5dd; }
.emergency-status-page .rep-sec { margin-bottom:7mm; }
.engineering-report-check-types { min-width:0; margin:4px 0; padding:7px 0 0; border:0; }
.engineering-report-check-types > div { display:grid; }
.engineering-report-check-types .check-label small { justify-self:end; color:var(--muted); }

.engineering-report-document { color:#1b2119; background:#fff; }
.engineering-report-body { box-sizing:border-box; min-height:270mm; }
.engineering-report-group { margin:0 0 8mm; }
.engineering-report-group:last-child { margin-bottom:0; }
.engineering-report-group h2 {
  display:flex; justify-content:space-between; gap:10px; margin:0 0 2mm;
  padding-bottom:2mm; border-bottom:1px solid #d9ded3; font-size:15px;
}
.engineering-report-group h2 small { color:#66705f; font-size:11px; }
.engineering-report-group table { width:100%; border-collapse:collapse; table-layout:fixed; }
.engineering-report-group th {
  padding:2mm; color:#66705f; font-size:9px; letter-spacing:.07em;
  text-align:left; text-transform:uppercase; border-bottom:1px solid #d9ded3;
}
.engineering-report-group td { padding:3mm 2mm; vertical-align:top; border-bottom:1px solid #e8ebe4; }
.engineering-report-group td:first-child { width:34%; }
.engineering-report-finding td > b,
.engineering-report-finding td > span { display:block; }
.engineering-report-finding td > span { margin-top:1mm; color:#454a3d; }
.engineering-report-finding dl { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:1.5mm 4mm; min-width:0; max-width:100%; margin:0; }
.engineering-report-finding dl div { min-width:0; }
.engineering-report-finding dt { color:#66705f; font-size:8.5px; letter-spacing:.06em; text-transform:uppercase; }
.engineering-report-finding dd { max-width:100%; margin:0; overflow-wrap:anywhere; word-break:break-word; white-space:normal; }
@media (max-width:600px) {
  .engineering-selection-bar > button { flex:1 1 140px; }
  .engineering-selection-bar b { flex-basis:100%; }
}

/* Shared paper model for the record, Work list and Status report. */
.snag-report-document {
  --sr-ink:#1b2119; --sr-muted:#66705f; --sr-line:#d9ded3; --sr-soft:#f3f5ef;
  box-sizing:border-box; color:var(--sr-ink); background:#fff;
  font:12px/1.45 'Public Sans','Segoe UI',system-ui,sans-serif;
}
.snag-report-page { box-sizing:border-box; padding:14mm; }
.snag-report-cover-head { display:flex; align-items:center; justify-content:space-between; gap:12px; color:var(--sr-muted); }
.snag-report-cover-rule { height:1px; margin:5mm 0 18mm; background:#9dc368; }
.snag-report-cover .snag-report-page-content > h1 { max-width:150mm; margin:2mm 0 1mm; font-size:32px; line-height:1.1; }
.snag-report-cover-client { margin:0 0 12mm; color:var(--sr-muted); font-size:16px; }
.snag-report-cover-meta { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:5mm 12mm; margin:0 0 10mm; }
.snag-report-cover-note, .snag-report-cover-summary, .snag-report-cover-list, .snag-report-cover-inclusions { margin:0 0 8mm; }
.snag-report-cover h2 { margin:0 0 2mm; font-size:14px; }
.snag-report-cover-note { padding:4mm; border-inline-start:3px solid #91c83e; background:var(--sr-soft); white-space:pre-wrap; }
.snag-report-cover-summary > div { display:flex; flex-wrap:wrap; gap:3mm 8mm; }
.snag-report-cover-summary span b { font-size:18px; }
.snag-report-cover-list ol { margin:0; padding-inline-start:6mm; }
.snag-report-cover-list li { margin-bottom:2mm; padding-inline-start:2mm; }
.snag-report-cover-list li span { display:block; color:var(--sr-muted); }
.snag-report-cover-inclusions { padding-top:4mm; border-top:1px solid var(--sr-line); }
.snag-report-cover-inclusions p { margin:1mm 0; }
.snag-report-page + .snag-report-page { border-top:8px solid #ecefe8; }
.snag-report-running { display:grid; grid-template-columns:auto auto minmax(0,1fr); align-items:baseline; gap:4mm; padding-bottom:2mm; margin-bottom:5mm; border-bottom:1px solid #9dc368; color:#4f574b; font-size:8.5px; }
.snag-report-running > span:last-child { text-align:right; overflow-wrap:anywhere; }
.snag-report-headline { border-bottom:1px solid #9dc368; padding-bottom:15px; margin-bottom:20px; }
.snag-report-headline > p { margin:12px 0 2px; color:var(--sr-muted); }
.snag-report-headline h1 { margin:0 0 14px; font-size:21px; letter-spacing:-.025em; }
.snag-report-headline dl, .snag-report-details { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:8px 18px; margin:0; }
.snag-report-headline dl div, .snag-report-details div { min-width:0; }
.snag-report-document dt { color:var(--sr-muted); font-size:9.5px; font-weight:700; text-transform:uppercase; letter-spacing:.07em; }
.snag-report-document dd { margin:2px 0 0; overflow-wrap:anywhere; }
.snag-report-measures { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:8px; margin-bottom:20px; }
.snag-report-status-measures { grid-template-columns:repeat(5,minmax(0,1fr)); }
.snag-report-measures > div { padding:10px 12px; border:1px solid var(--sr-line); background:var(--sr-soft); break-inside:avoid; }
.snag-report-measures b { display:block; font-size:24px; line-height:1.15; }
.snag-report-measures span { color:var(--sr-muted); }
.snag-report-warning, .snag-report-drawing-message { padding:9px 11px; border-inline-start:4px solid #c98a18; background:#fff6dc; }
.snag-report-group { margin:0 0 20px; }
.snag-report-group h2 {
  display:flex; justify-content:space-between; gap:10px; margin:0; padding:8px 10px;
  border-top:1px solid #a7b59b; border-bottom:1px solid var(--sr-line);
  border-inline-start:3px solid #7fb232; background:#f1f4ec; color:var(--sr-ink); font-size:13px;
}
.snag-report-group h2 small { color:var(--sr-muted); }
.snag-report-document table { width:100%; border-collapse:collapse; font-size:10.5px; }
.snag-report-document th { color:var(--sr-muted); text-align:left; font-weight:700; }
.snag-report-document td, .snag-report-document th { padding:7px 8px; border-bottom:1px solid var(--sr-line); vertical-align:top; }
.snag-report-document td small { display:block; color:var(--sr-muted); margin-top:2px; }
.snag-report-badge { display:inline-flex; align-items:center; min-width:42px; color:#b42323; }
.snag-report-badge.tone-information { color:#3479df; }
.snag-report-badge.tone-passed { color:#709929; }
.snag-report-badge svg { display:block; max-width:58px; }
.snag-report-state { font-weight:700; }
.snag-report-state.tone-issue { color:#9e2020; }.snag-report-state.tone-information { color:#2866b5; }.snag-report-state.tone-passed { color:#52741d; }
.snag-report-status-grid { display:grid; grid-template-columns:1fr 1fr .7fr; gap:14px; margin-bottom:22px; }
.snag-report-status-grid > div { padding:12px; border:1px solid var(--sr-line); break-inside:avoid; }
.snag-report-status-grid h2 { margin:0 0 8px; font-size:13px; }
.snag-report-status-grid dl { margin:0; }.snag-report-status-grid dl div { display:flex; justify-content:space-between; border-bottom:1px solid var(--sr-line); padding:6px 0; }
.snag-report-record-title { display:flex; align-items:center; gap:14px; margin-bottom:18px; }
.snag-report-record-title p { margin:0; color:var(--sr-muted); font-size:10px; font-weight:700; letter-spacing:.08em; }
.snag-report-record-title h2 { margin:2px 0 0; font-size:21px; }
.snag-report-record-identity { margin-bottom:3mm; }
.snag-report-record-identity h1 { margin:1mm 0 0; font-size:21px; line-height:1.15; }
.snag-report-prepared { margin:2mm 0 3mm; color:var(--sr-muted); font-size:9px; }
.snag-report-details { grid-template-columns:repeat(4,minmax(0,1fr)); padding:12px; border:1px solid var(--sr-line); background:var(--sr-soft); }
.snag-report-description { white-space:pre-wrap; }
.snag-report-description-section { margin:0; }
.snag-report-description-section h2 { margin-top:0; }
.snag-report-work-description { margin-top:4mm; }
.snag-report-work-description.is-continuation { margin-top:0; }
.snag-report-work-instruction { margin-bottom:4mm; }
.snag-report-work-instruction .snag-report-record-title { margin-bottom:3mm; }
.snag-report-work-instruction .snag-report-details { grid-template-columns:repeat(5,minmax(0,1fr)); padding:8px 10px; }
.snag-report-sheet img { display:block; width:100%; object-fit:contain; border:1px solid var(--sr-line); }
.snag-report-sheet figure { margin:5mm 0; break-inside:avoid; }
.snag-report-sheet h3 { margin:0 0 2mm; font-size:11px; text-transform:uppercase; letter-spacing:.06em; }
.snag-report-sheet figcaption { margin-top:1.5mm; color:var(--sr-muted); font-size:9.5px; }
.snag-report-locator img { height:54mm; }
.snag-report-detail img { height:105mm; }
.snag-report-document[data-snag-report-type="record"] .snag-report-sheet figure { margin:3mm 0; }
.snag-report-document[data-snag-report-type="record"] .snag-report-locator img { height:48mm; }
.snag-report-document[data-snag-report-type="record"] .snag-report-detail img { height:118mm; }
.snag-report-drawing-stack { break-inside:avoid; page-break-inside:avoid; }
.snag-report-work-evidence { margin-top:4mm; }
.snag-report-work-evidence figure { display:inline-block; width:48%; margin:2mm 1% 2mm 0; vertical-align:top; break-inside:avoid; }
.snag-report-work-evidence img, .snag-report-work-evidence svg { display:block; width:100%; height:42mm; object-fit:contain; }
.snag-report-continuation h2 { margin:0 0 4mm; }
.snag-report-history ol { list-style:none; padding:0; margin:8px 0; }
.snag-report-history li { padding:9px 0 9px 11px; border-inline-start:3px solid var(--sr-line); break-inside:avoid; }
.snag-report-history li.tone-issue { border-inline-start-color:#b42323; }
.snag-report-history li.tone-information { border-inline-start-color:#3479df; }
.snag-report-history li.tone-passed { border-inline-start-color:#709929; }
.snag-report-history li.has-evidence { break-inside:auto; page-break-inside:auto; }
.snag-report-event-line { display:flex; justify-content:space-between; gap:12px; }
.snag-report-event-line span { color:var(--sr-muted); font-size:10px; }
.snag-report-history li p { margin:4px 0 0; }
.snag-report-history li.has-evidence > figure { display:inline-block; width:48%; margin:3mm 1% 1mm 0; vertical-align:top; }
.snag-report-audit { margin-top:5mm; }
.snag-report-history figure { break-inside:avoid; }.snag-report-history img { max-width:100%; max-height:105mm; object-fit:contain; }
.snag-report-history li.has-evidence img,
.snag-report-history li.has-evidence svg { display:block; width:auto !important; max-width:100%; height:82mm; object-fit:contain; }
.snag-report-sheet h2 { margin-top:0; }
.snag-report-foot { margin-top:22px; padding-top:7px; border-top:1px solid var(--sr-line); color:var(--sr-muted); font-size:9px; }
.snag-report-empty { padding:22px; border:1px dashed var(--line2); color:var(--muted); text-align:center; }
.standalone-snag-report { margin:0; padding:14mm; background:#fff; }
.snag-report-option {
  box-sizing:border-box; min-height:40px; padding:0 10px;
  border:1px solid var(--line2); border-radius:8px; background:var(--card2);
  color:var(--ink); font-weight:600;
}
@media (max-width:700px) {
  .snag-report-headline dl, .snag-report-details, .snag-report-status-grid { grid-template-columns:1fr; }
  .snag-report-status-measures { grid-template-columns:repeat(2,minmax(0,1fr)); }
  .snag-report-document { overflow-x:auto; }
  .snag-report-document table { min-width:680px; }
  .snag-report-work-instruction .snag-report-details { grid-template-columns:1fr 1fr; }
  .snag-selection-bar > button { flex:1 1 auto; }
}
.drawing-measure.snag-status-measure {
  background:linear-gradient(180deg,
    color-mix(in srgb,var(--snag-status-colour) 11%,var(--card)),
    var(--card) 76%);
  box-shadow:inset 0 3px 0 var(--snag-status-colour);
}
.snag-status-measure.tone-issue { --snag-status-colour:var(--snag-ink-issue); }
.snag-status-measure.tone-information { --snag-status-colour:var(--snag-ink-information); }
.snag-status-measure.tone-passed { --snag-status-colour:var(--snag-ink-passed); }
.drawing-context-error {
  grid-column:1 / -1; margin:0; padding:10px 18px; border-top:1px solid var(--line);
  color:var(--chip-warn-ink); font-size:12.5px;
}
.drawing-kind-panel { min-width:0; }
.drawing-list {
  display:grid; grid-template-columns:repeat(auto-fill,minmax(240px,1fr)); gap:14px;
}
.drawing-tools { display:flex; justify-content:space-between; align-items:center; gap:12px;
  flex-wrap:wrap; margin:0 0 14px; color:var(--ink2); font-size:12.5px; }
.drawing-tools .seg { display:flex; gap:3px; }
/* The snag action line names several statuses at once, so it wraps rather
   than squeezing the filters. The drawing count is a separate, quieter line:
   a drawing total and a snag total are different things and must never read
   as one running sentence. */
.drawing-tools .drawing-totals { min-width:0; }
.drawing-totals-scope { display:block; color:var(--muted); font-size:11.5px; }
.drawing-tools .seg button { padding:5px 10px; }
.drawing-tool-controls { display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.drawing-select-all {
  display:inline-flex; align-items:center; gap:6px; min-height:36px; padding:0 6px;
  color:var(--ink2); cursor:pointer; white-space:nowrap;
}
.drawing-select-all input, .drawing-card-select input {
  width:18px; height:18px; margin:0; accent-color:var(--accent); cursor:pointer;
}
/* The sentence that tells a full pack from a selected one. It sits on the page
   rather than in a tooltip, which a touch screen cannot reach at all - but it
   belongs to the button, so it lines up under it and stops at its width rather
   than running off across the header. */
.drawing-zip-scope {
  /* flex:0 0 100% and not flex-basis alone: a max-width would let it share the
     line with the buttons and shove the main action leftwards. It keeps its
     own line and hangs off the right edge, under the button it describes. */
  flex:0 0 100%;
  color:var(--muted); font-size:11.5px; line-height:1.35; text-align:right;
}
.drawing-download-selected { min-height:36px; }
.drawing-download-selected:not(:disabled) {
  border-color:var(--accent); background:var(--accent); color:var(--btn-ink);
}
.drawing-download-selected:disabled { opacity:.45; cursor:not-allowed; }
.drawing-heading { align-items:center; gap:18px; }
.drawing-heading > div { min-width:0; }
.drawing-heading .eyebrow { margin:0 0 3px; }
.drawing-heading h2 { font-size:14.5px; }

/* Contextual help link beside the drawings panel heading. */
.help-link {
  display:inline-flex; align-items:center; gap:6px; margin-top:9px;
  font-size:12.5px; color:var(--ink2); text-decoration:none;
  border-bottom:1px solid var(--line2); padding-bottom:2px; min-height:24px;
}
.help-link svg { flex-shrink:0; }
fieldset .help-link { margin:2px 0 10px; }
.help-link:hover { color:var(--ink); border-bottom-color:currentColor; }
.drawing-key-link { flex:0 0 auto; margin:0; border-bottom:0; }
.drawing-row {
  position:relative; min-width:0; overflow:hidden; border:1px solid var(--line); border-radius:9px;
  background:var(--card); transition:border-color .16s, transform .16s, box-shadow .16s;
}
.drawing-row:hover { border-color:var(--line2); transform:translateY(-1px); box-shadow:var(--shadow); }
.drawing-row.selected {
  background:var(--sel-bg); border-color:var(--accent);
  box-shadow:0 0 0 1px var(--accent);
}
.drawing-card-open {
  position:absolute; z-index:2; inset:0; width:100%; min-height:0; padding:0;
  border:0; border-radius:9px; background:transparent; cursor:pointer;
}
.drawing-card-open:hover, .drawing-card-open:active, .drawing-card-open:focus {
  border:0; background:transparent;
}
.drawing-card-open:focus-visible { outline:2px solid var(--accent); outline-offset:-3px; }
/* The snag chip has to sit ABOVE the card's full-size open overlay, or the
   overlay swallows the click and the chip looks broken. Same reason the
   select checkbox carries z-index:3. */
.drawing-snag-chip {
  position:relative; z-index:3; min-height:0; padding:3px 9px;
  border:0; font: inherit; cursor:pointer;
}
.drawing-snag-chip:hover { filter:brightness(1.08); }
.drawing-card-select {
  position:absolute; z-index:3; top:9px; left:9px; display:grid; width:34px; height:34px;
  place-items:center; border:1px solid var(--line2); border-radius:7px;
  background:color-mix(in srgb,var(--card) 92%,transparent); box-shadow:var(--shadow);
}
.drawing-thumb {
  position:relative; display:grid; width:100%; aspect-ratio:4 / 3; min-height:0;
  place-items:center; overflow:hidden; padding:0; border:0; border-bottom:1px solid var(--line);
  border-radius:0; background:var(--card2); color:var(--muted);
}
.drawing-thumb-placeholder { display:grid; width:100%; height:100%; place-items:center; }
.drawing-thumb-placeholder svg { width:82%; height:82%; stroke:var(--line2); stroke-width:1.2; }
.drawing-thumb-placeholder svg circle { fill:var(--data); stroke:none; }
.drawing-thumbnail { width:100%; height:100%; object-fit:contain; background:#fff; }
.drawing-thumb-state {
  position:absolute; right:8px; bottom:8px; padding:3px 7px; border-radius:12px;
  background:color-mix(in srgb,var(--card) 88%,transparent); color:var(--ink2); font-size:10.5px;
}
.drawing-thumb-unavailable { cursor:default; opacity:.72; }
.drawing-card-body { display:grid; gap:9px; padding:11px 13px 12px; }
.drawing-card-title { display:flex; align-items:flex-start; justify-content:space-between; gap:8px; }
.drawing-row-name { min-width:0; }
.drawing-row-name b, .drawing-row-name small { display:block; overflow-wrap:anywhere; }
.drawing-row-name small { margin-top:2px; }
.drawing-row-name small, .drawing-meta { color:var(--muted); font-size:11.5px; }
.drawing-completion { display:grid; grid-template-columns:minmax(60px,1fr) auto; align-items:center; gap:8px; }
.drawing-completion .track { height:6px; overflow:hidden; border-radius:4px; background:var(--data-track); }
.drawing-completion .fill { display:block; height:100%; border-radius:4px; }
.drawing-completion b { font-size:12px; font-variant-numeric:tabular-nums; }
.drawing-card-chips { display:flex; align-items:center; gap:6px; min-height:22px; flex-wrap:wrap; }
.drawing-card-chips small { color:var(--muted); font-size:11.5px; }
.drawing-findings { min-height:34px; margin:0; color:var(--muted); font-size:11.5px; line-height:1.45; }
.drawing-failure { color:var(--fail); font-size:12px; overflow-wrap:anywhere; }
.drawing-row-actions { flex-wrap:nowrap; }
.drawing-row-actions .ghost-btn { min-height:34px; padding:5px 9px; font-size:12px; }
@media (prefers-reduced-motion:reduce) {
  .drawing-row { transition:none; }
}
.drawing-review { margin:10px 0 0; padding:9px 11px; border-left:3px solid var(--chip-warn-ink);
  background:var(--chip-warn-bg); color:var(--ink2); }
.floor-separator { color:var(--muted); }
.drawing-row-actions, .drawing-package-actions, .drawing-viewer-actions {
  display:flex; align-items:center; gap:8px; flex-wrap:wrap;
}
.drawing-package-actions { justify-content:flex-end; margin:0; }
.drawing-page-actions .drawing-package-actions > button {
  min-height:38px; padding:7px 13px; border:1px solid var(--line2); border-radius:8px;
  background:var(--card); color:var(--ink); font:inherit; font-size:12.5px; font-weight:650;
  cursor:pointer;
}
/* The tab's own pack is the main action, so it wears the accent and it sits at
   the right-hand end of the row, where the eye and the hand come back to. The
   row is right-aligned, so ordering the combined pack before it keeps that
   edge still whether or not the combined pack is on offer. */
.drawing-page-actions .drawing-package-actions > button { order:1; }
.drawing-page-actions .drawing-package-actions > #drawing-zip-both,
.drawing-page-actions .drawing-package-actions > #drawing-zip-cancel { order:0; }
/* The buttons keep the first line to themselves. The option and the two notes
   are full-width, so without an order of their own they take that line and
   push the buttons below it - and the main action then moved down the page
   every time a tab hid one of them. */
.drawing-package-actions > :is(.drawing-download-option, .count-note) { order:2; }
.drawing-page-actions .drawing-package-actions > :is(#drawing-zip, #emergency-zip, #snag-zip) {
  border-color:var(--accent); background:var(--accent); color:var(--btn-ink);
}
.drawing-download-option {
  display:flex; align-items:center; justify-content:flex-end; gap:9px;
  flex-basis:100%; min-height:44px; color:var(--ink2); cursor:pointer;
}
.drawing-download-option > span { display:grid; gap:1px; text-align:left; line-height:1.25; }
.drawing-download-option b { color:var(--ink); font-size:12.5px; font-weight:600; }
.drawing-download-option small { color:var(--muted); font-size:11.5px; }
.drawing-package-actions .marker-visibility-control,
.drawing-package-actions .count-note { flex-basis:100%; justify-content:flex-end; }
/* Filled green makes a file. An outline button takes you somewhere: the
   Work sheets shortcut and "Open in a new tab" sit together on the left, the
   downloads together on the right. */
.drawing-viewer-actions > button:not(.ghost-btn) {
  background:var(--accent); color:var(--btn-ink); border:none; border-radius:8px;
  padding:8px 16px; font:inherit; font-weight:650; cursor:pointer;
}
.drawing-viewer-actions > .ghost-btn { font-weight:600; }
.drawing-viewer-actions > #drawing-viewer-new { margin-right:auto; }
.drawing-package-actions button:disabled { opacity:.6; cursor:not-allowed; }
.drawing-viewer-dlg {
  box-sizing:border-box; width:100dvw; max-width:none; height:100dvh; max-height:none;
  margin:0; padding:max(14px,env(safe-area-inset-top)) max(28px,env(safe-area-inset-right))
    max(14px,env(safe-area-inset-bottom)) max(14px,env(safe-area-inset-left));
  border:0; border-radius:0; overflow:hidden;
  grid-template-columns:minmax(0,1fr);
  grid-template-rows:auto auto minmax(0,1fr) auto; gap:6px;
}
.drawing-viewer-dlg[open] { display:grid; }
.drawing-viewer-dlg > * { grid-column:1; }
.drawing-viewer-dlg button,
.drawing-viewer-dlg .drawing-viewer-actions a { box-sizing:border-box; min-width:44px; min-height:44px; }
/* "Open in a new tab" is a link, not a button. Without this its label sits on the
   text baseline while the 44px tap target grows below it, so it reads as
   off-centre beside the two download buttons. */
.drawing-viewer-dlg .drawing-viewer-actions a {
  display:inline-flex; align-items:center; justify-content:center; text-decoration:none;
}
/* A disabled download button must look disabled. Without this it keeps the full
   accent green, so a user clicks it and nothing happens. */
.drawing-viewer-actions > button:disabled {
  opacity:.45; cursor:not-allowed; filter:grayscale(.5);
}
.drawing-viewer-dlg .eyebrow,
.drawing-viewer-dlg .note { color:var(--ink2); }
/* Title, status and Close share one band. The status line used to have a row of
   its own, most of it empty, on every screen wider than a phone. */
.drawing-viewer-head { display:flex; justify-content:space-between; gap:16px; align-items:baseline; flex-wrap:wrap; }
.drawing-viewer-head > div:first-child, .drawing-viewer-title-group {
  flex:0 0 auto; display:flex; align-items:baseline; gap:10px;
}
/* "Progress drawing" and the floor name on one line, not stacked. */
.drawing-viewer-head .eyebrow { margin:0; white-space:nowrap; }
.drawing-viewer-head h2 { margin:0; white-space:nowrap; }
.drawing-viewer-head #drawing-viewer-message { flex:1 1 240px; margin:0; min-width:0; }
/* The two control bands sit side by side while there is width for them, and
   stack only when there is not. */
.drawing-toolbars {
  display:flex; flex-wrap:wrap; align-items:center; gap:6px 12px; padding:5px 7px;
  border:1px solid var(--line); border-radius:9px; background:var(--card2);
}
.drawing-toolbars > * { flex:0 0 auto; }
.drawing-viewer-head .eyebrow { margin:0 0 2px; }
.drawing-viewer-head h2 { margin:0; }
#drawing-viewer-frame {
  display:block; grid-row:3; width:100%; height:100%; min-height:0;
  border:1px solid var(--line2); border-radius:8px; background:#fff;
}
.drawing-mode-toolbar { display:flex; align-items:center; gap:4px; flex-wrap:nowrap; }
.drawing-mode-toolbar button { min-width:44px; min-height:44px; padding-inline:12px; }
.drawing-mode-toolbar button.on {
  background:var(--line); color:var(--ink); border-color:var(--line2);
}
.drawing-mode-toolbar button:disabled { opacity:.42; cursor:not-allowed; }
.drawing-mode-toolbar label { font-size:12px; color:var(--ink2); white-space:nowrap; }
.drawing-mode-toolbar select { min-height:44px; max-width:220px; }
.drawing-target-toolbar {
  display:flex; align-items:center; justify-content:flex-start; gap:7px;
  margin:0 0 0 auto;
}
.drawing-target-toolbar span { color:var(--ink2); font-size:12px; }
.drawing-target-label { display:inline-flex; align-items:center; gap:6px; flex:0 0 auto; }
.drawing-target-label:empty { display:none; }
.marker-visibility-control {
  display:inline-flex; align-items:center; gap:6px; min-height:44px; padding:0 4px;
  color:var(--ink2); font-size:12px; white-space:nowrap; cursor:pointer;
}
.marker-visibility-control input { width:18px; height:18px; accent-color:var(--accent); }
.marker-visibility-control:has(input:disabled) { opacity:.45; cursor:not-allowed; }
#drawing-markers-status { color:var(--ink); font-weight:650; white-space:nowrap; }
.drawing-target-toolbar button { min-width:44px; min-height:44px; padding:6px 10px; }
.drawing-help-btn {
  display:inline-flex; align-items:center; justify-content:center;
  width:36px; min-width:36px; height:36px; min-height:36px; padding:0!important;
  background:transparent; color:var(--muted); border:1px solid transparent;
  border-radius:8px; text-decoration:none; cursor:pointer;
  transition:background 120ms ease, border-color 120ms ease, color 120ms ease;
}
.drawing-help-btn:hover {
  background:var(--card2); color:var(--ink); border-color:var(--line2);
}
.drawing-help-btn:focus-visible {
  background:var(--card2); color:var(--ink); border-color:var(--accent);
  outline:2px solid color-mix(in srgb,var(--accent) 35%,transparent); outline-offset:2px;
}
.drawing-help-btn svg {
  width:20px; height:20px; fill:none; stroke:currentColor; stroke-width:1.6;
  stroke-linecap:round; stroke-linejoin:round;
}
.drawing-target-toolbar output {
  min-width:52px; color:var(--ink2); font-size:12px; text-align:center;
  font-variant-numeric:tabular-nums;
}
.drawing-target-stage {
  grid-row:3; width:100%; height:100%; min-height:0; overflow:auto;
  overflow-anchor:none;
  border:1px solid var(--line2); border-radius:8px; background:#e4e4e4;
  cursor:grab; user-select:none;
}
.drawing-target-stage.is-panning { cursor:grabbing; }
/* Position reads must see the new value at once, including under the global
   reduced-motion rule, which sets a short nonzero transition duration. */
.drawing-target-page, .drawing-target-page * { transition:none !important; }
.drawing-target-page { position:relative; width:max-content; height:max-content; margin:12px 0; }
/* The previous drawing's line work sits over the current drawing, tinted pink.
   The current drawing keeps its full colour: nothing is faded, because the fill
   that was hiding everything is discarded rather than seen through. The teal and
   marker layers come later in the document, so they still paint on top. */
.drawing-underlay-canvas { position:absolute; left:0; top:0; z-index:1; }
.drawing-underlay-canvas[hidden] { display:none; }
.drawing-target-page.previous-only #drawing-target-canvas,
.drawing-target-page.previous-only #drawing-teal-layer,
.drawing-target-page.previous-only #drawing-target-layer,
.drawing-target-page.previous-only #drawing-snag-layer,
.drawing-target-page.previous-only #snag-mark-layer { display:none; }
.drawing-overlay-strength {
  display:inline-flex; align-items:center; gap:8px; min-height:44px;
  color:var(--ink2); font-size:12px; white-space:nowrap;
}
.drawing-overlay-strength[hidden] { display:none; }
.drawing-overlay-strength input {
  --ratio:0; --thumb:18px;
  width:132px; height:18px; margin:0; padding:0; cursor:pointer;
  -webkit-appearance:none; appearance:none; background:none;
}
.drawing-overlay-strength input::-webkit-slider-runnable-track {
  height:6px; border-radius:3px;
  background:linear-gradient(to right, #d6006e 0 calc(var(--ratio) * 100%),
    var(--line2) calc(var(--ratio) * 100%) 100%);
}
.drawing-overlay-strength input::-moz-range-track {
  height:6px; border-radius:3px;
  background:linear-gradient(to right, #d6006e 0 calc(var(--ratio) * 100%),
    var(--line2) calc(var(--ratio) * 100%) 100%);
}
.drawing-overlay-strength input::-webkit-slider-thumb {
  -webkit-appearance:none; appearance:none;
  width:var(--thumb); height:var(--thumb); margin-top:-6px;
  border:2px solid #fff; border-radius:50%; background:#d6006e;
  box-shadow:0 1px 3px rgba(0,0,0,.35);
}
.drawing-overlay-strength input::-moz-range-thumb {
  width:var(--thumb); height:var(--thumb); box-sizing:border-box;
  border:2px solid #fff; border-radius:50%; background:#d6006e;
  box-shadow:0 1px 3px rgba(0,0,0,.35);
}
.drawing-overlay-strength input:focus-visible { outline-offset:6px; }
.drawing-overlay-strength output { min-width:38px; font-variant-numeric:tabular-nums; }

/* Zoom floats on the drawing, bottom left. */
.drawing-stage-wrap { position:relative; grid-row:3; min-height:0; }
.drawing-stage-wrap[hidden] { display:none; }
.drawing-stage-wrap > .drawing-target-stage { width:100%; height:100%; }
.drawing-zoom-bar {
  position:absolute; z-index:4; left:12px; bottom:12px;
  display:inline-flex; align-items:center; gap:2px; padding:4px;
  border:1px solid var(--line2); border-radius:10px;
  background:color-mix(in srgb,var(--card) 92%,transparent); box-shadow:var(--shadow);
}
.drawing-zoom-btn {
  display:inline-flex; align-items:center; justify-content:center; flex:0 0 auto;
  box-sizing:border-box; width:44px; height:44px; min-width:44px; min-height:44px;
  padding:0; cursor:pointer;
  border:0; border-radius:8px; background:none; color:var(--ink2);
}
.drawing-zoom-btn:hover:not(:disabled) { background:var(--line); color:var(--ink); }
.drawing-zoom-btn:disabled { opacity:.4; cursor:not-allowed; }
.drawing-zoom-btn svg { width:20px; height:20px; fill:none; stroke:currentColor;
  stroke-width:1.8; stroke-linecap:round; stroke-linejoin:round; }
.drawing-zoom-bar output {
  min-width:52px; text-align:center; color:var(--ink2); font-size:12px;
  font-variant-numeric:tabular-nums;
}
.drawing-zoom-divider { width:1px; height:24px; margin:0 3px; background:var(--line2); }
#drawing-target-canvas { display:block; background:#fff; box-shadow:0 2px 14px rgba(0,0,0,.22); }
#drawing-target-canvas[hidden] { display:none; }
#drawing-target-layer { position:absolute; inset:0; pointer-events:none; }
#drawing-target-layer[hidden] { display:none; }

/* Feature 007: teal new-work layer. Static, below the markers, above the page. */
#drawing-teal-layer { position:absolute; inset:0; pointer-events:none; }
#drawing-teal-layer[hidden] { display:none; }
.drawing-teal-highlight {
  position:absolute; box-sizing:border-box;
  background:rgba(0,167,157,.34); border:2px solid rgba(0,89,84,1);
  animation:none; transition:none;
}
.drawing-teal-highlight.luminaire { border-radius:50%; }
.drawing-teal-highlight.local-control { border-radius:6px; }
@media (forced-colors:active) {
  .drawing-teal-highlight { border-color:Highlight; background:transparent; }
}

/* Marker types are a drawing palette. The real marker shapes carry the first
   meaning; the short labels make the less familiar states unambiguous. */
.drawing-marker-types { position:relative; flex:0 1 auto; min-width:0; }
.drawing-marker-types > summary {
  cursor:pointer; min-height:44px; display:inline-flex; align-items:center; gap:7px;
  padding:0 12px; border:1px solid var(--line2); border-radius:8px;
  color:var(--ink); font-size:13px; font-weight:650; white-space:nowrap;
}
.drawing-marker-types > summary::-webkit-details-marker { display:none; }
.drawing-marker-types > summary::marker { content:""; }
.drawing-marker-types > summary > svg {
  width:18px; height:18px; fill:none; stroke:currentColor; stroke-width:1.6;
  stroke-linecap:round; stroke-linejoin:round;
}
.drawing-marker-types[open] > summary {
  background:var(--line); border-color:var(--line2);
}
.marker-selection-count {
  display:inline-flex; align-items:center; justify-content:center; min-width:20px; height:20px;
  padding:0 5px; border-radius:999px; background:var(--card); color:var(--ink2);
  font-size:11px; font-variant-numeric:tabular-nums;
}
.drawing-marker-types fieldset {
  position:absolute; z-index:12; top:calc(100% + 7px); left:0;
  box-sizing:border-box; width:420px; margin:0; padding:10px;
  border:1px solid var(--line2); border-radius:10px; background:var(--card,#fff);
  box-shadow:0 12px 32px rgba(0,0,0,.35);
  display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:6px;
}
.drawing-marker-types label {
  position:relative; display:flex; align-items:center; gap:9px; min-height:44px;
  padding:5px 30px 5px 8px; border:1px solid transparent; border-radius:8px;
  margin:0; font-size:12.5px; font-weight:600; letter-spacing:0; text-transform:none;
  color:var(--ink2); white-space:nowrap; cursor:pointer;
}
.drawing-marker-types label[hidden] { display:none; }
.drawing-marker-types label:hover { background:var(--card2); color:var(--ink); }
.drawing-marker-types label:has(input:checked) {
  background:color-mix(in srgb,var(--accent) 11%,var(--card2));
  border-color:color-mix(in srgb,var(--accent) 38%,var(--line2)); color:var(--ink);
}
.drawing-marker-types label::after {
  content:"✓"; position:absolute; right:10px; color:var(--accent); font-weight:800;
  opacity:0;
}
.drawing-marker-types label:has(input:checked)::after { opacity:1; }
.drawing-marker-types input {
  position:absolute; inset:0; width:100%; height:100%; margin:0; opacity:0;
  cursor:pointer;
}
.drawing-marker-types label:has(input:focus-visible) {
  outline:2px solid var(--accent); outline-offset:2px;
}
.marker-option-icon {
  display:grid; place-items:center; flex:0 0 26px; width:26px; height:26px;
  pointer-events:none;
}
.marker-option-icon.progress { color:#007f78; }
.marker-option-icon.fault { color:var(--fail); }
.marker-option-icon.resolved { color:#26843b; }
.marker-option-icon.retest { color:#246bb2; }
.marker-option-icon.structure { color:#7d5aa6; }
.marker-option-icon.readdressed { color:#8a6100; }
@media (max-width:700px) {
  #page-project-intelligence .intelligence-view-tabs { gap:16px; scrollbar-width:none; }
  #page-project-intelligence .intelligence-view-tabs::-webkit-scrollbar { display:none; }
  .drawing-marker-types { position:relative; }
  .drawing-marker-types fieldset {
    position:fixed; z-index:30; top:auto; left:8px; right:8px; bottom:72px;
    width:auto; max-height:55dvh; overflow:auto; grid-template-columns:1fr;
  }
}

/* The marker key, reachable from the toolbar instead of the foot of the list. */
.drawing-legend-dlg {
  box-sizing:border-box; width:min(520px,92vw); max-width:none; max-height:82vh;
  padding:16px 18px; border:1px solid var(--line2); border-radius:12px;
  background:var(--card,#fff); color:var(--ink); overflow:auto;
}
.drawing-legend-dlg::backdrop { background:rgba(0,0,0,.5); }
.drawing-legend-head { display:flex; align-items:center; justify-content:space-between; gap:16px; }
.drawing-legend-head h2 { margin:0; font-size:17px; }
.drawing-legend-dlg .drawing-marker-legend { margin-top:6px; border-top:0; padding-top:0; }
.legend-teal {
  display:inline-block; width:24px; height:24px; border-radius:50%; vertical-align:middle;
  background:rgba(0,167,157,.34); border:2px solid rgba(0,89,84,1);
}
.drawing-marker-legend .grouped dt, .drawing-marker-legend .teal dt { color:var(--ink); }

/* The change list uses a normal toolbar control. The old vertical edge tab was
   hard to discover and looked detached from the panel. */
.drawing-change-panel { position:relative; }
#drawing-change-body { flex:1 1 auto; min-height:0; overflow:auto; }
.drawing-panel-toggle {
  display:inline-flex; align-items:center; gap:7px; min-height:44px; padding:6px 10px;
  white-space:nowrap;
}
/* One icon at a time, chosen by the button's state. See setDrawingPanelCollapsed
   for why this is not done with the `hidden` attribute. */
.drawing-panel-toggle .drawing-panel-toggle-eye-off,
.drawing-panel-toggle.is-collapsed .drawing-panel-toggle-eye { display:none; }
.drawing-panel-toggle.is-collapsed .drawing-panel-toggle-eye-off { display:inline; }
.drawing-panel-toggle svg {
  width:18px; height:18px; fill:none;
  stroke:currentColor; stroke-width:1.5; stroke-linecap:round; stroke-linejoin:round;
}
.drawing-panel-toggle.on {
  background:var(--line); color:var(--ink); border-color:var(--line2);
}
@media (max-width:700px) {
  .drawing-panel-toggle-text { position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); }
}

/* Changes fold by type, so the summary lines answer "what kinds are here" before
   any scrolling. */
.drawing-change-group { border-bottom:1px solid var(--line2); }
.drawing-change-group:last-of-type { border-bottom:0; }
.drawing-change-group > summary {
  display:flex; align-items:center; gap:8px; min-height:44px;
  cursor:pointer; color:var(--ink); font-size:13px;
}
.drawing-change-group > summary .count-note { margin-left:auto; }
.drawing-change-group > summary .marker-symbol { flex:0 0 auto; }
.drawing-change-group[open] > summary { border-bottom:1px solid var(--line2); }
.drawing-change-group > .snapshot-change-row { margin-top:8px; }

/* The card matching the marker on the drawing, so the two are read together. */
.snapshot-change-row.is-selected {
  background:var(--sel-bg); border-color:var(--accent);
  box-shadow:0 0 0 1px var(--accent);
}

/* Feature 007: New work chip on affected floor rows. */
.drawing-new-work { display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.drawing-new-work small { color:var(--ink2); }
.chip.new-work { background:rgba(0,167,157,.16); color:#00655f; border:1px solid rgba(0,167,157,.55); }
/* The marker you asked for, picked out without changing what its colour means.
   Static, like every other marker. */
/* The halo and the picked-out ring are drawn inside the marker, following its
   own outline. A CSS shadow is always a rounded rectangle, so it would have put
   a square glow around a triangle. */
.drawing-target-ring.is-selected { z-index:2; }
.drawing-target-ring {
  position:absolute; box-sizing:border-box; min-width:28px; min-height:28px;
  pointer-events:auto;
}
.marker-glyph {
  display:inline-flex; align-items:center; justify-content:center;
  min-width:1em; line-height:1; font-family:Arial,'Segoe UI Symbol',sans-serif;
  transform:translateY(-.04em);
}
/* Group headings show the same marker chip the rows and the drawing use. Without
   this the summary showed a bare character with no ring. */
/* The ring is now only a box that carries the colour. The shape itself is an
   SVG from marker-shapes.js, which the downloaded PDF draws from too, so the
   paper and the screen cannot drift apart. The old border and border-radius
   made every marker a circle, which is exactly what this change undoes. */
:where(.drawing-target-ring,.snapshot-change-row .marker-symbol,.legend-marker,
       .drawing-change-group > summary .marker-symbol) {
  box-sizing:border-box; display:grid; place-items:center;
  border:0; background:none; line-height:0;
}
.marker-shape { display:block; width:100%; height:100%; overflow:visible; }
/* The chosen marker draws a target ring outside itself. The ring must grow from
   the centre, or the marker slides off the fitting it points at. */
.marker-shape-picked {
  position:absolute; top:50%; left:50%; translate:-50% -50%;
  width:156%; height:156%;
}
.drawing-target-ring { position:absolute; }
:where(.drawing-target-ring,.snapshot-change-row .marker-symbol,.legend-marker,
       .drawing-change-group > summary .marker-symbol).progress { color:#007f78; }
:where(.drawing-target-ring,.snapshot-change-row .marker-symbol,.legend-marker,
       .drawing-change-group > summary .marker-symbol).fault { color:var(--fail); }
:where(.drawing-target-ring,.snapshot-change-row .marker-symbol,.legend-marker,
       .drawing-change-group > summary .marker-symbol).resolved { color:#26843b; }
:where(.drawing-target-ring,.snapshot-change-row .marker-symbol,.legend-marker,
       .drawing-change-group > summary .marker-symbol).retest { color:#246bb2; }
:where(.drawing-target-ring,.snapshot-change-row .marker-symbol,.legend-marker,
       .drawing-change-group > summary .marker-symbol).structure { color:#7d5aa6; }
:where(.drawing-target-ring,.snapshot-change-row .marker-symbol,.legend-marker,
       .drawing-change-group > summary .marker-symbol).readdressed { color:#8a6100; }
.drawing-change-panel {
  grid-row:3; z-index:3; justify-self:end; align-self:stretch; width:min(360px,42vw);
  display:flex; flex-direction:column; overflow:hidden;
  margin:10px; padding:12px; border:1px solid var(--line2); border-radius:10px;
  background:color-mix(in srgb,var(--card) 94%,transparent); box-shadow:var(--shadow);
}
.drawing-change-panel-head { padding:0 0 10px; border-bottom:1px solid var(--line2); }
.drawing-change-panel-head .eyebrow { margin:0 0 3px; }
.drawing-change-panel-head h3 { margin:0; font-size:14px; }
.drawing-change-panel-head + .note { margin-top:10px; }
.drawing-issue-summary h3 { margin:4px 0 8px; }
.drawing-issue-summary p { margin:0 0 8px; }
.drawing-issue-summary details { margin-top:12px; border-top:1px solid var(--line2); padding-top:10px; }
.drawing-issue-summary summary { cursor:pointer; color:var(--ink2); font-weight:650; }
.drawing-issue-summary details p { margin:8px 0 0; color:var(--ink2); }
.drawing-marker-legend { margin-top:14px; border-top:1px solid var(--line2); padding-top:10px; }
.drawing-marker-legend summary { cursor:pointer; color:var(--ink2); font-weight:650; }
.drawing-marker-legend dl { display:grid; gap:10px; margin:12px 0 0; }
.drawing-marker-legend dl > div { display:grid; gap:2px; }
.drawing-marker-legend dt { display:flex; align-items:center; gap:8px; font-weight:700; }
.drawing-marker-legend dd { margin:0 0 0 34px; color:var(--ink2); font-size:13px; }
.legend-marker { width:26px; height:26px; }
.drawing-marker-legend .progress { color:#007f78; }
.drawing-marker-legend .fault { color:var(--fail); }
.drawing-marker-legend .resolved { color:#26843b; }
.drawing-marker-legend .retest { color:#246bb2; }
.drawing-marker-legend .readdressed { color:#8a6100; }
.drawing-marker-legend .structure { color:#7d5aa6; }
.drawing-marker-legend dd { color:var(--ink2); }
.drawing-viewer-actions { grid-row:6; justify-content:flex-end; margin-top:2px; }
.drawing-viewer-actions a { text-decoration:none; }
@media (max-width:760px) {
  .drawing-page-heading { display:flex; }
  .drawing-page-actions { align-items:stretch; width:100%; max-width:none; }
  .drawing-snapshot-field { justify-content:space-between; }
  #drawing-request-picker { width:auto; max-width:70%; }
  .drawing-package-actions { justify-content:flex-start; }
  .drawing-download-option { justify-content:flex-start; }
  .drawing-package-actions .marker-visibility-control,
  .drawing-package-actions .count-note { justify-content:flex-start; }
  .drawing-tabs { overflow-x:auto; overflow-y:hidden; padding-inline:0; scrollbar-width:none; }
  .drawing-tabs::-webkit-scrollbar { display:none; }
  .drawing-tabs button { white-space:nowrap; }
  .drawing-summary { grid-template-columns:repeat(2,minmax(0,1fr)); }
  .drawing-list { grid-template-columns:repeat(auto-fill,minmax(230px,1fr)); }
  .drawing-heading { align-items:flex-start; }
  .drawing-key-link { max-width:150px; text-align:right; }
  .drawing-viewer-dlg { padding:max(8px,env(safe-area-inset-top)) max(8px,env(safe-area-inset-right)) max(8px,env(safe-area-inset-bottom)) max(8px,env(safe-area-inset-left)); }
  .drawing-viewer-head > div:first-child, .drawing-viewer-title-group { flex-wrap:wrap; }
  .drawing-toolbars { display:grid; grid-template-columns:minmax(0,1fr); align-items:start; }
  .drawing-mode-toolbar, .drawing-target-toolbar {
    width:100%; min-width:0; margin:0; flex-wrap:wrap; justify-content:flex-start;
  }
  .drawing-mode-toolbar select { flex:1 1 190px; max-width:none; }
  .drawing-change-panel { z-index:5; width:calc(100% - 20px); max-height:45%; align-self:end; }
}
@media (max-width:520px) {
  .drawing-summary { grid-template-columns:1fr; }
  .drawing-list { grid-template-columns:1fr; }
  .drawing-row-actions { width:100%; }
  .drawing-row-actions .ghost-btn { flex:1; }
}
@media (max-width:640px) {
  .report { padding:22px 18px 20px; }
  .rep-bar-cell { width:30%; }
}

/* ── Administration: People / Organisations / Projects ─────────────────── */
.admin-tabs { display:flex; gap:6px; margin-bottom:16px; flex-wrap:wrap; }
.admin-tabs button {
  background:var(--card); border:1px solid var(--line); border-radius:9px;
  color:var(--ink2); font:inherit; font-size:13.5px; padding:7px 16px;
  cursor:pointer;
}
.admin-tabs button:hover { color:var(--ink); }
.admin-tabs button.on {
  background:var(--accent); border-color:var(--accent); color:var(--btn-ink);
  font-weight:650;
}
.people-group { margin-top:18px; }
.people-group .rep-subhead { margin:0 0 6px; text-transform:none;
  letter-spacing:.02em; font-size:12.5px; color:var(--ink2); }
.people-group .rep-subhead .chip { margin-left:6px; vertical-align:1px; }
.people-table td { white-space:nowrap; vertical-align:middle; }
.people-table select, .people-table input[type=text], .people-table .p-job {
  background:var(--card2); color:var(--ink); border:1px solid var(--line2);
  border-radius:7px; padding:5px 8px; font:inherit; font-size:12.5px;
  max-width:190px;
}
.people-table .p-job { width:170px; }
.people-projects { white-space:normal; max-width:230px; font-size:12px;
  color:var(--ink2); }
#org-table td { vertical-align:middle; }
@media (max-width:900px) {
  .people-table select, .people-table .p-job { max-width:130px; }
}

/* ── Print ─────────────────────────────────────────────────────────────────
   Only the report prints, and it prints as paper: a white sheet with black
   text, from Light, Dark or Delmatic alike.

   The light tokens below used to be declared on `:root` alone. That loses
   the cascade: `:root[data-theme="dark"]` is an attribute selector as well
   as a pseudo-class, so it is MORE specific than `:root`, and its dark
   values survived into print. A reader in Dark got a dark frame around a
   white report and was told to switch to Light first. Every screen-theme
   selector is therefore matched here, at equal specificity, and print
   comes last so it wins.

   The colour scheme needs !important, which nothing else in this file does.
   index.html sets `color-scheme` as an INLINE style on <html> before the
   stylesheet loads, so a dark reader never sees a white flash. An inline
   declaration beats every ordinary rule in a stylesheet, media query or
   not, so `color-scheme:light` here was simply ignored on paper. The page
   canvas is painted by the user agent from the colour scheme - the root's
   own white background box covers only its content, and everything outside
   it took the dark canvas. That is the dark frame: not a shell, not a
   border and not a token, but the sheet itself.

   It has to be beaten in the stylesheet rather than unset in the script,
   because a browser or a service worker may still be holding an older
   index.html with the old line in it.

   print-color-adjust keeps the bars and chips from dropping their fill. */
@media print {
  :root,
  :root[data-theme="light"],
  :root[data-theme="dark"],
  :root[data-theme="delmatic"] {
    color-scheme:light !important;
    --page:#ffffff; --card:#ffffff; --card2:#f4f4f4;
    --ink:#1f1f1f; --ink2:#454545; --muted:#6d6d6d;
    --line:#dcdcdc; --line2:#c4c4c4;
    --accent:#96d045; --accent-ink:#4e5d1d; --focus:#4e5d1d;
    --btn-ink:#263311;
    --data:#7fb232; --data-track:#e6eed6;
    --fail:#c23434;
    --progress-mid:#e3ad3d;
    --info:#2563c4;
    --chip-pass-bg:#eef6dd; --chip-pass-ink:#4a6118;
    --chip-fail-bg:#f9e7e5; --chip-fail-ink:#93292a;
    --chip-na-bg:#efefef; --chip-na-ink:#5d5d5d;
    --chip-warn-bg:#fdf0d2; --chip-warn-ink:#7a4f10;
    --chip-info-bg:#e6efff; --chip-info-ink:#1f4f9c;
    --shadow:none;
    /* The rail is not printed at all, but its tokens are inherited by
       anything that borrowed one, so they go light here too. */
    --rail-bg:#ffffff; --rail-ink:#1f1f1f; --rail-ink2:#5d5d5d;
    --rail-line:#dcdcdc; --rail-edge:#c4c4c4;
    --rail-hover-bg:#f4f4f4; --rail-hover-ink:#1f1f1f;
    --rail-sel-bg:#eef6dd; --rail-sel-ink:#243206; --rail-mark:#4e5d1d;
    --rail-count-bg:#efefef; --rail-count-ink:#454545;
    --rail-brand-ink:#1f1f1f; --rail-brand-sub:#5d5d5d; --rail-brand-iq:#4e5d1d;
  }
  * { -webkit-print-color-adjust:exact !important; print-color-adjust:exact !important; }
  /* The screen shell is a frame around the document. On paper there is no
     frame: the page itself is the white, and nothing between it and the
     report may contribute a ground, an edge, a corner, a shadow or a height
     that the sheet would then have to carry. */
  html, body {
    background:#fff !important; background-image:none !important;
    margin:0; padding:0; min-height:0; box-shadow:none;
  }
  #view-dash, .app-shell, .app-stage, main, .workspace-page,
  .report-workspace, .report-preview-well, .report {
    background:transparent !important; background-image:none !important;
    border:0 !important; border-radius:0 !important; box-shadow:none !important;
    outline:0 !important; min-height:0 !important;
  }
  header.top, nav.tabs, .app-rail, .environment-banner, .no-print, #tip, #foot,
  #page-dash, #page-test, #page-snapshot, #page-admin, #view-login { display:none !important; }
  /* The shell is a screen device. On paper it must not reserve the rail's
     column, or every printed page would carry a charcoal band down the
     left and a narrowed document beside it - print-color-adjust:exact
     above means that band would really be inked. */
  .app-shell { display:block !important; min-height:0; }
  .app-stage, #page-report { display:block !important; min-height:0; }
  body.printing-engineering #page-report { display:none !important; }
  body.printing-engineering #page-engineering { display:block !important; }
  body.printing-engineering #page-engineering > :not(#engineering-report-doc) { display:none !important; }
  body.printing-engineering #engineering-report-doc { display:block !important; }
  body.printing-completion #page-report { display:none !important; }
  body.printing-completion #page-closeout { display:block !important; }
  body.printing-completion #page-closeout > :not(.closeout-layout),
  body.printing-completion .closeout-layout > :not(.completion-preview-well) { display:none !important; }
  body.printing-completion .closeout-layout,.completion-preview-well { display:block!important;margin:0;padding:0;overflow:visible; }
  body.printing-completion .completion-document { width:auto;min-height:0;padding:0;border:0;box-shadow:none; }
  body.printing-completion .completion-certificate { min-height:270mm; }
  body.printing-completion .completion-module-report { break-before:page; }
  body.printing-completion .completion-module-report:first-child { break-before:auto; }
  body.printing-completion .completion-module-report .completion-report-section { break-inside:auto; }
  body.printing-completion .completion-module-report thead { display:table-header-group; }
  body.printing-completion .completion-module-report tr { break-inside:avoid; }
  body.printing-completion .completion-module-report .completion-report-foot { display:none; }
  main { max-width:none; margin:0; padding:0; }
  .report-workspace, .report-preview-well {
    display:block; margin:0; padding:0; overflow:visible;
  }
  .report { width:auto; max-width:none; padding:0; }
  /* Deliberately NOT .rep-sec: keeping a whole section together pushes a
     tall one (the floor table) onto a fresh page and leaves half a page of
     white under the figures. Sections flow and fill the page; only the small
     units that look broken when split are held together. */
  .rep-head, .report-measure, .em-stat, .rep-rows .rw, tr { break-inside:avoid; }
  /* The module appendix can run to several pages, so its head repeats and the
     numeric columns stay narrow enough for the name to keep its width. */
  .rep-modules thead { display:table-header-group; }
  .emergency-failure-table thead { display:table-header-group; }
  .rep-sec.report-appendix { break-before:page; page-break-before:always; }
  .report-appendix tr { break-inside:avoid; page-break-inside:avoid; }
  .rep-modules th.num, .rep-modules td.num { width:9%; }
  .rep-modules td, .rep-modules th { padding:3px 5px; font-size:10.5px; }
  .rep-modules .rep-module-complete { width:22%; min-width:100px; }
  .rep-modules .module-progress { min-width:90px; gap:5px; }
  .rep-modules .module-progress .track { min-width:44px; }
  .rep-modules .module-complete-value { min-width:30px; font-size:9.5px; }
  .rep-modules .module-score { min-width:34px; padding:1px 4px; font-size:9.5px; }
  .rep-module-status { min-width:54px; padding:1px 5px; font-size:9px; }
  .rep-sec h2, .rep-subhead, .rep-headline { break-after:avoid; }
  .rep-sec { break-before:auto; }
  thead { break-after:avoid; }
  .report-measures { grid-template-columns:repeat(4,1fr); gap:8px; }
  .report-measure { padding:10px 12px; border:1px solid var(--line); box-shadow:none; }
  .report-measure .v { font-size:22px; }
  .report-measure .v small { font-size:13px; }
  .report-measure .s { font-size:10.5px; }
  .card { box-shadow:none; }
  thead { display:table-header-group; }
  .scroll-y { max-height:none; overflow:visible; }
  a { text-decoration:none; color:var(--ink); }
  .engineering-report-body { min-height:0; }
  .engineering-report-group { break-inside:auto; page-break-inside:auto; }
  .engineering-report-group h2 { break-after:avoid; page-break-after:avoid; }
  .engineering-report-group thead { display:table-header-group; }
  .engineering-report-group tr { break-inside:avoid; page-break-inside:avoid; }
  .engineering-report-document .snag-report-cover { break-after:page; page-break-after:always; }
  @page { size:A4; margin:14mm; }
}
/* Workflow redesign: accessible navigation, progressive disclosure and safe areas. */
.sr-only{position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
.skip-link{position:fixed;z-index:1000;left:12px;top:8px;transform:translateY(-160%);background:var(--card,#fff);color:var(--text,#111);padding:12px 16px;border-radius:8px}
.skip-link:focus{transform:none}
:where(button,a,input,select,textarea,summary):focus-visible{outline:3px solid var(--focus)!important;outline-offset:3px}
.bottom-nav{display:none}
.more-groups{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:16px}.more-groups section{display:flex;flex-direction:column;align-items:stretch;gap:8px}.more-groups h2{font-size:13px;text-transform:uppercase;letter-spacing:.06em}.button-link{display:flex;align-items:center;justify-content:center;min-height:44px;border:1px solid currentColor;border-radius:8px;text-decoration:none}
.device-workflow-bar{display:flex;align-items:center;gap:10px;flex-wrap:wrap}.device-workflow-bar p{margin:0;margin-right:auto;font-size:13px}.device-workflow-bar [data-state="failed"],.status-warning{font-weight:700}.status-warning::first-letter{color:var(--fail,#b42318)}.status-ok{font-weight:600}.undo-action{min-height:44px}.summary-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:12px}.summary-grid p{display:flex;flex-direction:column;margin:0;padding:16px;border:1px solid var(--line,#777);border-radius:10px}.summary-grid b{font-size:1.5rem}.summary-grid span{font-size:13px}
.needs-attention .section-heading{display:flex;justify-content:space-between;align-items:start;gap:16px}.needs-attention-list,#needs-attention-list{display:grid;gap:8px}#needs-attention-list button,.action-row{display:flex;justify-content:space-between;align-items:center;text-align:left;min-height:52px;width:100%;gap:12px}.action-row span:first-child{display:flex;flex-direction:column}.action-row small{font-size:13px}.action-row.urgent{border-inline-start:5px solid var(--fail,#b42318)}.action-row.attention{border-inline-start:5px solid #b7791f}.action-row.routine{border-inline-start:5px solid #3b82f6}.empty-state{padding:24px;text-align:center}
.closeout-checks{list-style:none;padding:0;display:grid;gap:8px}.closeout-checks li{display:grid;grid-template-columns:28px 1fr auto;align-items:center;min-height:52px;padding:8px 12px;border:1px solid var(--line,#777);border-radius:8px}.closeout-checks small{font-size:13px;text-transform:capitalize}.closeout-checks .incomplete,.closeout-checks .unavailable{border-inline-start:5px solid #b7791f}
.admin-tabs [role="tab"]{min-height:44px}
.closeout-layout{display:grid;grid-template-columns:minmax(260px,340px) minmax(0,1fr);gap:16px;align-items:start}.closeout-builder{display:grid;gap:12px}.completion-issue-fields{display:grid;gap:7px}.completion-issue-fields label{color:var(--muted);font-size:11px;font-weight:600;letter-spacing:.05em;text-transform:uppercase}.completion-issue-fields input{box-sizing:border-box;width:100%;min-height:40px;padding:7px 10px;border:1px solid var(--line2);border-radius:8px;background:var(--card2);color:var(--ink);font:inherit}.completion-options .check-label{display:grid;grid-template-columns:34px minmax(0,1fr) auto;align-items:center;gap:8px;min-height:44px;padding:7px 0;border-top:1px solid var(--line);cursor:pointer}.completion-options .check-label input{appearance:none;position:relative;width:30px;height:17px;margin:0;border:1px solid var(--line2);border-radius:999px;background:var(--card2)}.completion-options .check-label input::after{content:"";position:absolute;top:2px;left:2px;width:11px;height:11px;border-radius:50%;background:var(--muted);transition:transform .15s ease}.completion-options .check-label input:checked{border-color:var(--accent);background:var(--chip-pass-bg)}.completion-options .check-label input:checked::after{transform:translateX(13px);background:var(--accent)}.completion-nested{margin-left:42px}.completion-options .seg{display:flex}.completion-options .seg button{min-height:44px}.completion-preview-well{min-height:720px}#completion-preview{width:min(210mm,100%);margin:0 auto}.completion-document{box-sizing:border-box;min-height:275mm;padding:17mm 18mm 15mm;background:#fff;color:#20251d;border:1px solid #dfe3d8;box-shadow:var(--shadow);font:11pt/1.5 'Public Sans','Segoe UI',sans-serif}.completion-doc-head{border-bottom:2px solid #7fb232;padding-bottom:8mm}.completion-wordmark{color:#76a82a;font-size:21pt;font-weight:800;letter-spacing:.12em}.completion-doc-head>p{margin:2mm 0 0;color:#5f6757;font-size:9pt;letter-spacing:.12em;text-transform:uppercase}.completion-doc-head h1{margin:10mm 0 0;font-size:24pt;line-height:1.15}.completion-control{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:5mm 8mm;margin:9mm 0}.completion-control div{min-width:0}.completion-control dt,.completion-signoff span{color:#697160;font-size:8pt;font-weight:700;letter-spacing:.08em;text-transform:uppercase}.completion-control dd{margin:1mm 0 0;font-weight:650;overflow-wrap:anywhere}.completion-statement{display:flex;min-height:92mm;align-items:center;padding:12mm 8mm;border-block:1px solid #dfe3d8;font-size:16pt;line-height:1.55;text-align:center}.completion-signoff{display:grid;grid-template-columns:1fr 1fr;gap:18mm;margin-top:20mm}.completion-signoff div{border-top:1px solid #697160;padding-top:3mm}.completion-signoff span,.completion-signoff strong{display:block}.completion-intro{margin:0 0 9mm;padding:4mm;background:#f3f6ed;border-left:3px solid #7fb232}.completion-report-section{margin:0 0 8mm;break-inside:avoid}.completion-report-section h2{margin:0 0 3mm;padding-bottom:2mm;border-bottom:1px solid #dfe3d8;font-size:15px}.completion-report-section table{width:100%;border-collapse:collapse}.completion-report-section th,.completion-report-section td{padding:2.5mm 2mm;border-bottom:1px solid #e5e8e0;text-align:left}.completion-report-section th{background:#f3f6ed;color:#3f463b}.completion-report-section th:last-child,.completion-report-section td:last-child{text-align:right}.completion-unavailable{color:#62695b;font-style:italic}.completion-report-foot{margin-top:12mm;padding-top:3mm;border-top:1px solid #9ba390;color:#62695b;font-size:8.5pt}@media(max-width:900px){.closeout-layout{grid-template-columns:1fr}}@media(max-width:500px){.completion-control{grid-template-columns:1fr 1fr}.completion-nested{margin-left:20px}}
.completion-snag-selection,.completion-module-selection{display:grid;max-height:240px;overflow:auto;border:1px solid var(--line);border-radius:8px}.completion-snag-selection label,.completion-module-selection label{display:grid;grid-template-columns:22px 1fr;gap:8px;align-items:center;min-height:44px;padding:6px 8px;border-bottom:1px solid var(--line);cursor:pointer}.completion-snag-selection label:last-child,.completion-module-selection label:last-child{border-bottom:0}.completion-snag-selection input,.completion-module-selection input{width:18px;height:18px}.completion-snag-selection span,.completion-snag-selection small,.completion-module-selection span,.completion-module-selection small{display:block;min-width:0}.completion-snag-selection small,.completion-module-selection small{color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.completion-snag-record{margin:6mm 0;padding:5mm;border:1px solid #dfe3d8;break-inside:avoid}.completion-snag-record header p{margin:0;color:#697160;font-size:8.5pt;font-weight:700;letter-spacing:.08em;text-transform:uppercase}.completion-snag-record h3{margin:1mm 0 3mm;font-size:13pt}.completion-snag-record dl{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:3mm}.completion-snag-record dt{color:#697160;font-size:8pt;font-weight:700;text-transform:uppercase}.completion-snag-record dd{margin:1mm 0 0}.completion-snag-description{white-space:pre-wrap}.completion-snag-crop{margin:4mm 0 0}.completion-snag-crop img{display:block;width:100%;max-height:115mm;object-fit:contain;border:1px solid #dfe3d8}.completion-snag-crop figcaption{margin-top:1.5mm;color:#62695b;font-size:8.5pt}.completion-module-facts{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:4mm}.completion-module-facts dt{color:#697160;font-size:8pt;font-weight:700;text-transform:uppercase}.completion-module-facts dd{margin:1mm 0 0;overflow-wrap:anywhere}.completion-module-report+.completion-module-report{margin-top:12px}
@media (max-width:700px){body{padding-bottom:calc(74px + env(safe-area-inset-bottom))}.desktop-nav{display:none!important}.app-rail{display:none}.app-shell,.app-shell.rail-collapsed{grid-template-columns:minmax(0,1fr)}header.top{min-height:58px;padding:0 12px}.mobile-brand{display:flex;font-size:16px;gap:8px}.mobile-brand .logo-mark{width:27px;height:27px}.rail-toggle{display:none}.project-context{margin-left:auto;max-width:calc(100vw - 145px)}.project-context-status{display:none}.top-right #report-btn,.top-right #signout{display:none}.bottom-nav{position:fixed;z-index:90;display:flex;inset:auto 0 0;justify-content:space-around;gap:2px;padding:6px 4px calc(6px + env(safe-area-inset-bottom));background:var(--card,#282828);border-top:1px solid var(--line,#777)}.bottom-nav button{display:flex;flex:1;min-width:44px;min-height:48px;padding:4px;flex-direction:column;align-items:center;justify-content:center;font-size:12px;border:0;background:none;border-radius:0}.bottom-nav button[hidden]{display:none}.bottom-nav button span{font-size:12px}.bottom-nav-ico{width:20px;height:20px}.bottom-nav button[aria-current="page"]{font-weight:800;text-decoration:underline;text-underline-offset:4px}.summary-grid{grid-template-columns:1fr}.needs-attention .section-heading{align-items:stretch;flex-direction:column}.admin-project-layout,.admin-invite-form{grid-template-columns:1fr!important}.admin-table-wrap table,.admin-table-wrap tbody,.admin-table-wrap tr,.admin-table-wrap td{display:block;width:100%}.admin-table-wrap th{position:absolute;clip:rect(0,0,0,0)}.admin-table-wrap tr{border:1px solid var(--line,#777);border-radius:8px;margin-block:8px;padding:8px}.admin-table-wrap td::before{content:attr(data-label);display:block;font-size:12px;font-weight:700}}
/* ── Workspace search on a narrow window ─────────────────────────────────
   The same element, a different shape. Closed it is a 40px target in the
   toolbar; open it takes the toolbar row and drops its results the full
   width beneath, because a 340px dropdown hung off a 40px button is
   unusable on a handset. Nothing is duplicated: one input, one listbox,
   one set of keyboard rules.

   980px, not 700px. Between those two widths the toolbar could not hold a
   field, the project name and the account controls at once, and it was the
   account controls — Reports and Sign out — that were pushed off the right
   edge of the window. A field nobody asked for must not take the controls
   everybody needs.

   The open panel is absolute against the toolbar, NOT a fixed full-screen
   sheet. header.top carries a backdrop-filter, and a filter makes an element
   the containing block for every fixed-position descendant — so a sheet
   asking for inset:0 was trapped inside a 57px toolbar and showed one line
   of results. Position fixed is not available under a filtered ancestor. */
@media (max-width:980px) {
  .workspace-search { flex:0 0 auto; min-width:0; margin-inline:0; }
  .workspace-search-open {
    display:grid; place-items:center; width:40px; min-width:40px; height:40px;
    padding:0; border:1px solid transparent; border-radius:8px;
    background:none; color:var(--ink2); cursor:pointer;
  }
  .workspace-search-open svg { width:19px; height:19px; }
  .workspace-search-open:hover { border-color:var(--line2); background:var(--card2); color:var(--ink); }
  .workspace-search .workspace-search-field { display:none; }

  .workspace-search[data-open="true"] { position:static; flex:1 1 auto; max-width:none; }
  .workspace-search[data-open="true"] .workspace-search-open { display:none; }
  .workspace-search[data-open="true"] .workspace-search-field {
    display:flex; min-height:44px; background:var(--card);
  }
  /* 16px, because anything smaller makes iOS zoom the page on focus. */
  .workspace-search[data-open="true"] input[type="search"] { height:42px; font-size:16px; }
  .workspace-search[data-open="true"] .workspace-search-close { width:34px; height:34px; }
  .workspace-search[data-open="true"] .workspace-search-panel {
    left:0; right:0; width:auto; max-width:none; max-height:min(70vh, 520px);
  }
  /* The project name gives up its room while a search is open, and takes it
     back the moment the panel closes. */
  header.top:has(.workspace-search[data-open="true"]) .mobile-brand,
  header.top:has(.workspace-search[data-open="true"]) .project-context { display:none; }
  .workspace-search-option { padding:11px 8px; min-height:52px; }
  .workspace-search-recent button { min-height:36px; }
}
/* The phone toolbar shows the brand as well, so the project name has to give
   the search trigger its room. */
@media (max-width:700px) {
  .project-context { max-width:calc(100vw - 190px); }
}
@media (prefers-reduced-motion:reduce){*,*::before,*::after{scroll-behavior:auto!important;animation-duration:.01ms!important;transition-duration:.01ms!important}}
@media (prefers-contrast:more){:where(button,input,select,textarea,.card){border-width:2px!important}.action-row{border-inline-start-width:7px}}

/* Applied Collector Snapshot changes. */
.snapshot-change-metrics { display:grid; grid-template-columns:repeat(auto-fit,minmax(125px,1fr)); gap:9px; margin:12px 0; }
.snapshot-change-metrics > div { display:flex; flex-direction:column; gap:3px; padding:12px; border:1px solid var(--line2); border-radius:9px; background:var(--card2); }
.snapshot-change-metrics b { font-size:1.45rem; font-variant-numeric:tabular-nums; }
.snapshot-change-metrics span { color:var(--ink2); font-size:12px; }
.snapshot-change-metrics .regression { border-inline-start:5px solid var(--fail); }
.snapshot-change-metrics .progress { border-inline-start:5px solid #007f78; }
.snapshot-change-locations { display:grid; gap:7px; margin:12px 0; }
.snapshot-change-location-list { display:flex; flex-wrap:wrap; gap:7px; }
.snapshot-change-location-list button { min-height:44px; }
.snapshot-change-list { display:grid; gap:7px; margin-top:10px; }
.snapshot-change-row { display:grid; grid-template-columns:auto minmax(0,1fr) auto; align-items:center; gap:10px; min-height:52px; padding:8px 10px; border:1px solid var(--line2); border-radius:8px; background:var(--card2); }
.snapshot-change-row .marker-symbol { width:28px; height:28px; }
.snapshot-change-row.regression { border-inline-start:5px solid var(--fail); }
.snapshot-change-row.progress { border-inline-start:5px solid #007f78; }
.snapshot-change-row.resolved { border-inline-start:5px solid #26843b; }
.snapshot-change-row.retest,.snapshot-change-row.unchanged_activity { border-inline-start:5px solid #246bb2; }
.snapshot-change-row small { display:block; color:var(--muted); margin-top:2px; }
#snapshot-comparison-label { display:grid; gap:4px; min-width:min(320px,100%); font-size:12px; color:var(--ink2); }
#snapshot-comparison { min-height:44px; }
.snapshot-change-filters { display:grid; grid-template-columns:repeat(auto-fit,minmax(150px,1fr)); gap:9px; margin:14px 0; padding:12px; border:1px solid var(--line2); border-radius:9px; }
.snapshot-change-filters label { display:grid; gap:4px; color:var(--ink2); font-size:12px; }
.snapshot-change-filters select { min-height:44px; min-width:0; }
.snapshot-filter-actions { display:flex; align-items:flex-end; gap:7px; }
.snapshot-filter-actions button { min-height:44px; }
.snapshot-change-paging { display:flex; justify-content:center; align-items:center; gap:10px; margin-top:12px; }
.snapshot-change-paging button { min-width:88px; min-height:44px; }
.snapshot-change-paging output { min-width:150px; text-align:center; color:var(--ink2); font-size:12px; }
@media(max-width:620px){.snapshot-change-row{grid-template-columns:auto minmax(0,1fr)}.snapshot-change-row button{grid-column:1/-1;width:100%}}

/* Project Intelligence uses the same cards and controls as the main tracker. */
#page-project-intelligence .section-heading,
#intelligence-overview .section-heading {
  display:flex; align-items:flex-start; justify-content:space-between; gap:16px;
}
#page-project-intelligence .eyebrow,
#page-project-intelligence .note { color:var(--ink2); }
.intelligence-metrics {
  display:grid; grid-template-columns:repeat(auto-fit,minmax(170px,1fr)); gap:12px;
}
.intelligence-metrics > div {
  display:flex; flex-direction:column; gap:4px; min-height:82px; padding:14px;
  border:1px solid var(--line2); border-radius:10px; background:var(--card2);
}
.intelligence-metrics span { color:var(--ink2); font-size:12px; }
.intelligence-metrics b { font-size:1.35rem; font-variant-numeric:tabular-nums; }
.intelligence-highlights, .journal-list { display:grid; gap:10px; margin-top:14px; }
.intelligence-highlight {
  display:flex; align-items:center; justify-content:space-between; gap:14px;
  border:1px solid var(--line2); border-inline-start:5px solid var(--data);
  border-radius:9px; padding:12px 14px;
}
.intelligence-highlight.urgent { border-inline-start-color:var(--fail); }
.intelligence-highlight.attention { border-inline-start-color:#9a681c; }
.intelligence-highlight p { margin:4px 0 0; overflow-wrap:anywhere; }
#intelligence-freshness[data-state="failed_latest"],
#intelligence-freshness[data-state="partial"],
#intelligence-freshness[data-state="stale"] { background:var(--chip-warn-bg); color:var(--chip-warn-ink); }
#intelligence-freshness[data-state="current"] { background:var(--chip-pass-bg); color:var(--chip-pass-ink); }
.evidence-identity { display:grid; grid-template-columns:max-content 1fr; gap:6px 14px; }
.evidence-identity dt { font-weight:700; }
.evidence-identity dd { margin:0; overflow-wrap:anywhere; }
.journal-filters input[type="search"] { flex:1; min-width:min(240px,100%); }
.journal-entry { border:1px solid var(--line2); border-radius:10px; padding:14px; overflow-wrap:anywhere; }
.journal-entry.system { border-inline-start:5px solid var(--data); background:var(--card2); }
.journal-entry > header { display:flex; justify-content:space-between; align-items:flex-start; gap:12px; }
.journal-entry h3 { margin:7px 0 0; }
.journal-entry time, .journal-entry small { color:var(--ink2); font-size:12px; }
.journal-entry footer, .journal-links { display:flex; flex-wrap:wrap; align-items:center; gap:12px; margin-top:12px; }
.journal-entry footer label { margin-right:auto; }
.journal-entry .danger { color:var(--fail); }
#journal-history-list { display:grid; gap:12px; max-height:55vh; overflow:auto; }
#journal-history-list article { border-bottom:1px solid var(--line); padding-bottom:10px; }
.project-update-print pre { white-space:pre-wrap; overflow-wrap:anywhere; font:11pt/1.45 system-ui,sans-serif; }

@media (max-width:700px) {
  #page-project-intelligence .section-heading,
  #intelligence-overview .section-heading,
  .journal-entry > header, .intelligence-highlight { flex-direction:column; align-items:stretch; }
  .journal-filters > * { width:100%; }
  .evidence-identity { grid-template-columns:1fr; }
  .evidence-identity dd { margin-bottom:8px; }
}

@media print {
  /* Strip everything back to the printable article, one level at a time.
     The workspace shell put two containers between #view-dash and the
     page, so a single child selector on #view-dash now hides the shell
     and the printout inside it. Each level is listed explicitly, which
     keeps the original intent: print this article and nothing else. */
  body.print-project-update #view-dash > :not(.app-shell),
  body.print-project-update .app-shell > :not(.app-stage),
  body.print-project-update .app-stage > :not(#page-project-intelligence),
  body.print-project-update #page-project-intelligence > :not(#project-update-print) { display:none!important; }
  body.print-project-update .app-shell,
  body.print-project-update .app-stage { display:block!important; }
  body.print-project-update #page-project-intelligence,
  body.print-project-update #project-update-print { display:block!important; }
  .journal-entry, .intelligence-highlight { break-inside:avoid; }
  .project-update-print { max-width:180mm; margin:0 auto; }
}

@media (prefers-contrast:more) {
  .intelligence-highlight, .journal-entry, .intelligence-metrics > div { border-width:2px; }
}

/* ── Remaining workspace pages: mockup alignment ───────────────────────── */
#page-project-intelligence .intelligence-head {
  display:flex; align-items:center; justify-content:space-between; gap:14px;
  padding-block:12px;
}
#page-project-intelligence .intelligence-head .toolbar { margin:0; flex:none; }
#page-project-intelligence #intelligence-content {
  display:grid; grid-template-columns:minmax(0,2fr) minmax(270px,1fr);
  gap:var(--workspace-gap);
}
#page-project-intelligence :is(.history-measures-panel, .history-change-detail-panel, .history-journal) {
  grid-column:1 / -1;
}
#page-project-intelligence .history-change-detail-panel > .section-heading { margin-bottom:14px; }
#page-project-intelligence .history-change-detail-panel .snapshot-change-filters { margin-top:0; }
#page-project-intelligence #intelligence-current {
  grid-template-columns:repeat(5,minmax(0,1fr)); gap:0;
  overflow:hidden; border:1px solid var(--line); border-radius:9px;
}
#page-project-intelligence #intelligence-current > div {
  min-height:110px; padding:14px 16px; border:0; border-radius:0;
  border-inline-start:1px solid var(--line); background:transparent;
}
#page-project-intelligence #intelligence-current > div:first-child { border-inline-start:0; }
#page-project-intelligence #intelligence-current > div.regression { box-shadow:inset 0 3px 0 var(--fail); }
#page-project-intelligence #intelligence-current > div.resolved { box-shadow:inset 0 3px 0 var(--pass); }
#page-project-intelligence #intelligence-current > div.progress { box-shadow:inset 0 3px 0 var(--accent); }
#page-project-intelligence #intelligence-current b {
  margin-top:4px; font:650 25px/1.15 'Archivo', sans-serif; letter-spacing:-.025em;
}
#page-project-intelligence #intelligence-current small {
  margin-top:auto; color:var(--muted); font-size:11.5px; line-height:1.35;
}
.history-view-hidden, .imports-view-hidden { display:none !important; }

#page-snapshot .snapshot-drop-zone {
  display:grid; grid-template-columns:minmax(0,1fr);
  gap:12px; justify-items:center; margin-top:0; padding:18px;
  border:1px dashed var(--line2); border-radius:9px; background:var(--card2);
  transition:border-color 120ms ease, background 120ms ease;
}
#page-snapshot .snapshot-drop-zone.drag-over {
  border-color:var(--accent); background:color-mix(in srgb,var(--accent) 9%,var(--card2));
}
#page-snapshot .snapshot-drop-copy {
  grid-column:1 / -1; padding:8px 8px 12px; text-align:center;
}
#page-snapshot .snapshot-drop-copy b { font:650 15px/1.3 'Archivo', sans-serif; }
#page-snapshot .snapshot-drop-copy p {
  max-width:68ch; margin:5px auto 0; color:var(--muted); font-size:12.5px;
}
/* The project the backup goes into, said before anything is chosen. */
#page-snapshot .snapshot-target {
  margin:0 0 12px; padding:10px 14px; border-inline-start:3px solid var(--accent);
  background:var(--card2); color:var(--ink2); font-size:13.5px;
}
#page-snapshot .snapshot-target b { color:var(--ink); font-size:15px; }
#page-snapshot .snapshot-target span { display:block; margin-top:2px; color:var(--muted); font-size:12.5px; }
#page-snapshot .snapshot-steps {
  display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:10px;
  margin:0 0 14px; padding:0; list-style:none; counter-reset:step;
}
#page-snapshot .snapshot-steps li {
  counter-increment:step; display:grid; grid-template-columns:auto 1fr; gap:2px 10px;
  color:var(--muted); font-size:12.5px; line-height:1.4;
}
#page-snapshot .snapshot-steps li::before {
  content:counter(step); grid-row:span 2; display:grid; place-items:center;
  width:24px; height:24px; border-radius:50%; background:var(--card2);
  border:1px solid var(--line2); color:var(--ink); font-weight:700; font-size:12px;
}
#page-snapshot .snapshot-steps b { color:var(--ink); }
#page-snapshot .snapshot-pick { display:flex; flex-wrap:wrap; justify-content:center; gap:10px; }
#page-snapshot .snapshot-pick .ghost-btn,
#page-snapshot .snapshot-drop-zone.has-package #snapshot-pick-zip {
  background:var(--card); color:var(--ink); border:1px solid var(--line2); font-weight:600;
}
#page-snapshot .snapshot-package { justify-self:stretch; }
#page-snapshot .snapshot-package > .note { margin:8px 0 0; text-align:center; }
#page-snapshot .snapshot-package-checks {
  display:grid; gap:0; margin:0; padding:0; list-style:none;
  border:1px solid var(--line); border-radius:9px; background:var(--card); overflow:hidden;
}
#page-snapshot .snapshot-package-checks li {
  display:grid; grid-template-columns:22px 150px minmax(0,1fr); gap:10px; align-items:baseline;
  padding:10px 14px; border-top:1px solid var(--line); font-size:13px;
}
#page-snapshot .snapshot-package-checks li:first-child { border-top:0; }
#page-snapshot .snapshot-package-checks li::before {
  content:"\2713"; color:var(--data); font-weight:800; text-align:center;
}
#page-snapshot .snapshot-package-checks li.warn::before { content:"!"; color:var(--progress-mid); }
#page-snapshot .snapshot-package-checks li span { color:var(--ink2); overflow-wrap:anywhere; }
#page-snapshot .snapshot-package-error {
  margin:0; padding:10px 14px; border-inline-start:3px solid var(--fail);
  background:var(--chip-fail-bg); color:var(--chip-fail-ink); font-size:13px;
}
#page-snapshot #snapshot-upload { justify-self:center; min-width:220px; }
@media (max-width:700px) {
  #page-snapshot .snapshot-steps { grid-template-columns:1fr; }
  #page-snapshot .snapshot-package-checks li { grid-template-columns:22px minmax(0,1fr); }
  #page-snapshot .snapshot-package-checks li span { grid-column:2; }
  #page-snapshot .snapshot-pick > * { flex:1 1 100%; }
}

#page-snapshot .snapshot-summary-grid {
  grid-template-columns:repeat(5,minmax(120px,1fr)); gap:0;
  overflow:hidden; border:1px solid var(--line); border-radius:9px;
}
#page-snapshot .snapshot-summary-grid > div {
  min-height:92px; border:0; border-inline-start:1px solid var(--line);
  border-radius:0; background:transparent;
}
#page-snapshot .snapshot-summary-grid > div:first-child { border-inline-start:0; }

#page-admin .admin-heading { align-items:flex-start; }
#page-admin > .admin-tabs {
  display:flex; gap:28px; padding-top:0; overflow-x:auto;
}
#page-admin > .admin-tabs button { flex:0 0 auto; padding-inline:1px; }
#page-admin .admin-pane > .note { max-width:84ch; }
#page-admin #people-groups { margin-top:14px; }
#page-admin #admin-invite-form #invite-cancel {
  background:transparent; border:1px solid var(--line2); color:var(--ink2); font-weight:500;
}

#page-admin .admin-section-head {
  display:flex; align-items:flex-start; justify-content:space-between; gap:16px;
}
#page-admin .admin-section-head .eyebrow { margin:0 0 3px; }
#page-admin .admin-section-head h2 { margin:0; }
#page-admin .admin-help-btn { flex:0 0 36px; }
#page-admin .admin-form fieldset { position:relative; padding-top:16px; }
#page-admin .admin-form fieldset > legend { padding-right:38px; }
#page-admin .admin-fieldset-help { position:absolute; top:5px; right:8px; }
.admin-help-dialog { box-sizing:border-box; width:min(560px,92vw); }
.admin-help-dialog form { display:grid; gap:18px; }
.admin-help-body { color:var(--ink2); font-size:13px; line-height:1.55; }
.admin-help-body p { margin:0 0 10px; }
.admin-help-body p:last-child { margin-bottom:0; }

/* A switch represents one stored on/off state. Long rule lists keep standard
   checkboxes because the user is selecting items from a set. */
input.ui-switch,
#page-admin .admin-form fieldset input.ui-switch {
  appearance:none; -webkit-appearance:none; box-sizing:border-box;
  width:32px; min-width:32px; height:18px; min-height:18px; flex:0 0 32px;
  margin:0; padding:2px; border:1px solid var(--line2); border-radius:999px;
  background:var(--line2); cursor:pointer; vertical-align:middle;
  transition:background 130ms ease, border-color 130ms ease;
}
input.ui-switch::before {
  content:""; display:block; width:12px; height:12px; border-radius:50%;
  background:var(--ink); box-shadow:0 1px 2px rgba(0,0,0,.3);
  transition:transform 130ms ease;
}
input.ui-switch:checked,
#page-admin .admin-form fieldset input.ui-switch:checked {
  background:var(--accent); border-color:var(--accent);
}
input.ui-switch:checked::before { transform:translateX(14px); background:var(--btn-ink); }
input.ui-switch:focus-visible { outline:2px solid var(--accent); outline-offset:3px; }
input.ui-switch:disabled { opacity:.45; cursor:not-allowed; }

#page-admin .people-table {
  width:100%; min-width:940px; table-layout:fixed;
}
#page-admin .people-table th:nth-child(1) { width:22%; }
#page-admin .people-table th:nth-child(2) { width:14%; }
#page-admin .people-table th:nth-child(3) { width:15%; }
#page-admin .people-table th:nth-child(4) { width:16%; }
#page-admin .people-table th:nth-child(5) { width:8%; }
#page-admin .people-table th:nth-child(6) { width:17%; }
#page-admin .people-table th:nth-child(7) { width:8%; }
#page-admin .people-table :is(th,td) { box-sizing:border-box; vertical-align:middle; }
#page-admin .people-table :is(.p-org,.p-job) { width:100%; max-width:none; }
#page-admin .people-table td:nth-child(5),
#page-admin #admin-access-table td:nth-child(3),
#page-admin #admin-access-table td:nth-child(4) { text-align:center; }
.people-identity { display:flex; align-items:center; gap:9px; min-width:0; }
.people-identity > span:last-child { min-width:0; }
.people-identity b, .people-identity small { display:block; overflow:hidden; text-overflow:ellipsis; }
.people-avatar {
  display:inline-flex; align-items:center; justify-content:center; flex:0 0 26px;
  width:26px; height:26px; border-radius:50%; background:var(--card2);
  color:var(--ink2); font-size:10px; font-weight:750; letter-spacing:.03em;
}

.people-table .p-level, .role-chip {
  box-sizing:border-box; display:inline-flex; align-items:center; width:auto; max-width:100%;
  border:1px solid transparent; border-radius:999px; font-size:11.5px; font-weight:700;
}
.role-chip { min-height:24px; padding:3px 9px; }
#page-admin .people-table select.p-level {
  width:auto; min-height:34px; padding:5px 28px 5px 10px; border-radius:999px;
}
.role-engineer { background:color-mix(in srgb,#6fb72f 18%,var(--card2))!important; color:color-mix(in srgb,#6fb72f 40%,var(--ink))!important; border-color:color-mix(in srgb,#6fb72f 34%,transparent)!important; }
.role-manager { background:color-mix(in srgb,#3b82f6 18%,var(--card2))!important; color:color-mix(in srgb,#3b82f6 40%,var(--ink))!important; border-color:color-mix(in srgb,#3b82f6 34%,transparent)!important; }
.role-admin { background:color-mix(in srgb,#a78bfa 18%,var(--card2))!important; color:color-mix(in srgb,#a78bfa 40%,var(--ink))!important; border-color:color-mix(in srgb,#a78bfa 34%,transparent)!important; }
.role-client { background:var(--card2)!important; color:var(--ink2)!important; border-color:var(--line)!important; }
.people-table .p-level[data-role="engineer"] { background:color-mix(in srgb,#6fb72f 18%,var(--card2))!important; color:color-mix(in srgb,#6fb72f 40%,var(--ink))!important; border-color:color-mix(in srgb,#6fb72f 34%,transparent)!important; }
.people-table .p-level[data-role="manager"] { background:color-mix(in srgb,#3b82f6 18%,var(--card2))!important; color:color-mix(in srgb,#3b82f6 40%,var(--ink))!important; border-color:color-mix(in srgb,#3b82f6 34%,transparent)!important; }
.people-table .p-level[data-role="admin"] { background:color-mix(in srgb,#a78bfa 18%,var(--card2))!important; color:color-mix(in srgb,#a78bfa 40%,var(--ink))!important; border-color:color-mix(in srgb,#a78bfa 34%,transparent)!important; }
.people-table .p-level[data-role="client"] { background:var(--card2)!important; color:var(--ink2)!important; border-color:var(--line)!important; }
.people-table .p-level:disabled { opacity:.75; cursor:not-allowed; }

#page-admin #admin-access-table { width:100%; min-width:820px; table-layout:fixed; }
#page-admin #admin-access-table th:nth-child(1) { width:28%; }
#page-admin #admin-access-table th:nth-child(2) { width:18%; }
#page-admin #admin-access-table th:nth-child(3),
#page-admin #admin-access-table th:nth-child(4) { width:15%; text-align:center; }
#page-admin #admin-access-table th:nth-child(5) { width:14%; }
#page-admin #admin-access-table th:nth-child(6) { width:10%; }

@media (max-width:1000px) {
  #page-project-intelligence #intelligence-current { grid-template-columns:repeat(2,minmax(0,1fr)); }
  #page-project-intelligence #intelligence-current > div:nth-child(odd) { border-inline-start:0; }
  #page-project-intelligence #intelligence-content { grid-template-columns:1fr; }
  #page-project-intelligence :is(.history-measures-panel, .history-change-detail-panel, .history-journal) { grid-column:auto; }
  #page-snapshot .snapshot-drop-zone { grid-template-columns:1fr 1fr; }
  #page-snapshot .snapshot-drop-copy { grid-column:1 / -1; }
  #page-snapshot .snapshot-summary-grid { grid-template-columns:repeat(2,minmax(0,1fr)); }
}

@media (max-width:700px) {
  #page-project-intelligence .intelligence-head { align-items:stretch; flex-direction:column; }
  #page-project-intelligence .intelligence-head .toolbar { width:100%; }
  #page-project-intelligence #intelligence-current { grid-template-columns:1fr; }
  #page-project-intelligence #intelligence-current > div { border-inline-start:0; border-top:1px solid var(--line); }
  #page-project-intelligence #intelligence-current > div:first-child { border-top:0; }
  #page-snapshot .snapshot-drop-zone,
  #page-snapshot .snapshot-summary-grid { grid-template-columns:1fr; }
  #page-snapshot .snapshot-drop-zone > * { grid-column:1; }
  #page-snapshot .snapshot-summary-grid > div { border-inline-start:0; border-top:1px solid var(--line); }
  #page-snapshot .snapshot-summary-grid > div:first-child { border-top:0; }
  #page-admin > .admin-tabs { gap:20px; }
}

/* History is one chronological project record. Evidence and export tools are
   secondary, so they stay closed until the reader asks for them. */
#page-project-intelligence .intelligence-page-heading { border-bottom:0; }
#page-project-intelligence .intelligence-view-tabs {
  margin-top:10px; border-top:0; border-bottom:1px solid var(--line2);
}
#page-project-intelligence .intelligence-head {
  padding:0; border:0; background:transparent;
}
#page-project-intelligence .intelligence-head > .note { flex:1 1 280px; }
#page-project-intelligence .history-primary-filters {
  display:flex; align-items:end; justify-content:flex-end; gap:8px; margin:0;
}
#page-project-intelligence .history-primary-filters .filter-search {
  width:min(300px,32vw); min-width:190px;
}
#page-project-intelligence .history-primary-filters label:not(.filter-search) {
  display:grid; gap:3px; color:var(--ink2); font-size:11px;
}
#history-help { font-size:0; }
#history-help::before {
  content:"?"; display:grid; place-items:center; width:16px; height:16px;
  border:1px solid currentColor; border-radius:50%; font-size:11px; line-height:1;
}
.history-export-menu { position:relative; }
.history-export-menu > summary {
  display:flex; align-items:center; min-height:38px; list-style:none; user-select:none;
}
.history-export-menu > summary::-webkit-details-marker { display:none; }
.history-export-menu > summary::after { content:"⌄"; margin-left:8px; color:var(--muted); }
.history-export-menu[open] > summary { color:var(--ink); background:var(--card2); }
.history-export-menu > div {
  position:absolute; z-index:20; top:calc(100% + 7px); right:0; display:grid; gap:5px;
  width:210px; padding:7px; border:1px solid var(--line2); border-radius:9px;
  background:var(--card); box-shadow:var(--shadow);
}
.history-export-menu > div button { width:100%; text-align:left; }

#page-project-intelligence #intelligence-content { display:grid; grid-template-columns:1fr; gap:var(--workspace-gap); }
#page-project-intelligence .history-journal { grid-column:1; padding-bottom:6px; }
#page-project-intelligence .history-journal > .section-heading { align-items:center; }
.history-timeline { position:relative; margin:0; padding:0 0 6px; }
.history-date-heading {
  position:relative; z-index:1; width:max-content; margin:18px 0 5px 42px;
  padding:0 8px; color:var(--ink2); background:var(--card);
  font:600 10.5px/1.5 'Public Sans',sans-serif; letter-spacing:.07em; text-transform:uppercase;
}
.history-date-heading:first-child { margin-top:2px; }
.history-event {
  position:relative; display:grid; grid-template-columns:34px minmax(0,1fr); gap:12px;
  min-width:0; padding:13px 0;
}
.history-event::before {
  content:""; position:absolute; left:16px; top:0; bottom:0; width:1px; background:var(--line2);
}
.history-event-marker {
  position:relative; z-index:1; display:grid; place-items:center; align-self:start;
  width:28px; height:28px; margin:1px 0 0 2px; border:1px solid var(--line2); border-radius:50%;
  background:var(--card); color:var(--muted); font:700 10px/1 'Archivo',sans-serif;
}
.history-event-testing .history-event-marker {
  border-color:color-mix(in srgb,var(--info) 58%,var(--line2)); color:var(--info);
  background:color-mix(in srgb,var(--info) 8%,var(--card));
}
.history-event-snapshot .history-event-marker {
  border-color:color-mix(in srgb,var(--accent) 62%,var(--line2)); color:var(--accent-ink);
  background:color-mix(in srgb,var(--accent) 10%,var(--card));
}
.history-event-issues .history-event-marker {
  border-color:color-mix(in srgb,var(--progress-mid) 64%,var(--line2)); color:var(--chip-warn-ink);
  background:var(--chip-warn-bg);
}
.history-event-content {
  min-width:0; padding:0 0 13px; border-bottom:1px solid var(--line);
}
.history-event:last-child .history-event-content { border-bottom:0; }
.history-event-content > header {
  display:flex; align-items:flex-start; justify-content:space-between; gap:16px;
}
.history-event-content h3 { margin:2px 0 0; font-size:14px; line-height:1.35; }
.history-event-content time { flex:none; color:var(--ink2); font-size:11.5px; font-variant-numeric:tabular-nums; }
.history-kind {
  color:var(--ink2); font-size:10px; font-weight:650; letter-spacing:.07em; text-transform:uppercase;
}
.history-event-content > p { max-width:95ch; margin:6px 0 0; color:var(--ink2); font-size:12.5px; line-height:1.5; }
.history-event-content > .history-event-meta { color:var(--ink2); font-size:11.5px; }
.history-event-detail { margin-top:5px; }
.history-event-detail > summary {
  display:inline-flex; align-items:center; min-height:34px; color:var(--ink2); cursor:pointer;
  font-size:12px; font-weight:600;
}
.history-event-detail > summary::after { content:"⌄"; margin-left:6px; color:var(--ink2); }
.history-event-detail[open] > summary::after { content:"⌃"; }
.history-event-detail > div {
  display:grid; gap:9px; max-width:900px; margin:2px 0 4px; padding:11px 13px;
  border:1px solid var(--line); border-radius:8px; background:var(--card2);
  color:var(--ink2); font-size:12px;
}
.history-event-detail dl { display:grid; grid-template-columns:max-content 1fr; gap:4px 12px; margin:0; }
.history-event-detail dt { font-weight:650; color:var(--ink); }
.history-event-detail dd { margin:0; }
.history-event-detail ul { margin:0; padding-left:18px; }
.history-event-actions { display:flex; flex-wrap:wrap; align-items:center; gap:10px; }
.history-event-actions label { margin-right:auto; }

.history-evidence-shell {
  overflow:hidden; border:1px solid var(--line); border-radius:10px; background:var(--card);
}
.history-evidence-shell > summary {
  display:flex; align-items:center; min-height:62px; padding:10px 16px; cursor:pointer;
}
.history-evidence-shell > summary span { display:grid; gap:3px; }
.history-evidence-shell > summary b { font:650 14px/1.3 'Archivo',sans-serif; }
.history-evidence-shell > summary small { color:var(--ink2); font-size:11.5px; }
.history-evidence-shell > summary::after { content:"⌄"; margin-left:auto; color:var(--ink2); }
.history-evidence-shell[open] > summary::after { content:"⌃"; }
.history-evidence-shell[open] > summary { border-bottom:1px solid var(--line); }
.history-evidence-grid {
  display:grid; grid-template-columns:minmax(0,2fr) minmax(270px,1fr); gap:var(--workspace-gap);
  padding:var(--workspace-gap);
}
#page-project-intelligence .history-evidence-grid .history-measures-panel,
#page-project-intelligence .history-evidence-grid .history-change-detail-panel { grid-column:1 / -1; }

@media (max-width:900px) {
  #page-project-intelligence .intelligence-head { align-items:stretch; flex-direction:column; }
  #page-project-intelligence .intelligence-head > .note { flex:0 1 auto; }
  #page-project-intelligence .history-primary-filters { justify-content:flex-start; flex-wrap:wrap; width:100%; }
  #page-project-intelligence .history-primary-filters .filter-search { flex:1 1 260px; width:auto; }
  .history-evidence-grid { grid-template-columns:1fr; }
  #page-project-intelligence .history-evidence-grid .history-measures-panel,
  #page-project-intelligence .history-evidence-grid .history-change-detail-panel { grid-column:1; }
}
@media (max-width:700px) {
  #page-project-intelligence .workspace-heading-actions #intelligence-freshness {
    flex:0 0 auto; align-self:flex-start; min-height:28px;
  }
  .history-export-menu { width:100%; }
  .history-export-menu > summary { justify-content:center; width:100%; box-sizing:border-box; }
  .history-export-menu > div { position:static; width:auto; margin-top:6px; }
  #page-project-intelligence .history-primary-filters > *,
  #page-project-intelligence .history-primary-filters .filter-search { flex:1 1 100%; width:100%; }
  #page-project-intelligence .history-primary-filters #history-help {
    flex:0 0 44px; width:44px; align-self:flex-end;
  }
  #page-project-intelligence .history-journal > .section-heading {
    align-items:center; flex-direction:row; text-align:left;
  }
  .history-event-content > header { flex-direction:column; gap:4px; }
  .history-event-content time { order:-1; }
  .history-event-detail > summary { min-height:44px; }
  .history-event-actions { align-items:stretch; flex-direction:column; }
  .history-event-actions > * { width:100%; box-sizing:border-box; }
  .history-evidence-grid { padding:12px; gap:12px; }
}

/* The line under a panel that says what the panel is for. Same weight and
   colour everywhere it appears. */
.panel-foot-note {
  margin:14px 0 0; padding-top:12px; border-top:1px solid var(--line);
  color:var(--muted); font-size:12px; line-height:1.5;
}

/* ── The person editor ───────────────────────────────────────────────────────
   A dialog, not an inline row of controls, so that changing somebody is a
   deliberate act with one Save at the end of it. */
.person-dialog {
  width:min(560px, calc(100vw - 32px)); max-height:min(88vh, 760px);
  padding:0; border:1px solid var(--line2); border-radius:14px;
  background:var(--card); color:var(--ink);
}
.person-dialog::backdrop { background:rgba(0,0,0,.55); }
.person-dialog form { display:flex; flex-direction:column; max-height:inherit; }
.person-dialog .engineering-help-head { padding:16px 20px 12px; border-bottom:1px solid var(--line); }
.person-dialog-body { overflow:auto; padding:16px 20px; display:grid; gap:16px; }
.person-dialog-who { padding-bottom:2px; }
.person-dialog-who .people-avatar { flex:0 0 34px; width:34px; height:34px; font-size:12px; }
.person-dialog-who b { font-size:15px; }
.person-dialog-who small { color:var(--muted); }
.person-fields { display:grid; grid-template-columns:1fr 1fr; gap:14px; }
.person-fields > label {
  display:flex; flex-direction:column; gap:6px;
  font-size:12px; color:var(--ink2);
}
/* A label here is a flex column, so every child of it takes a row. A bare
   "(optional)" beside the caption therefore became a row of its own and
   pushed that field's box a line below the box beside it - First name and
   Last name sit in the same pair and started at different heights. The
   caption and its note are one item, so they share one line and the two
   boxes start level. It wraps on a narrow window rather than overflowing. */
.person-fields > label > .field-caption {
  display:flex; align-items:baseline; flex-wrap:wrap; gap:6px;
}
.person-fields .person-switch-row {
  flex-direction:row; align-items:center; justify-content:space-between;
  gap:10px; min-height:40px; padding:0 12px;
  border:1px solid var(--line); border-radius:9px; background:var(--card2);
}
.person-fields select, .person-fields input[type=text], .person-fields .p-job {
  min-height:40px; padding:6px 10px; border:1px solid var(--line2);
  border-radius:8px; background:var(--card2); color:var(--ink); font:inherit;
  font-size:var(--field-font);
}
/* The access level keeps the pill and the colour it has in the People row,
   so the same fact looks the same wherever you meet it. */
.person-fields .p-level {
  min-height:40px; width:auto; align-self:start; max-width:100%;
  padding:5px 30px 5px 12px; border-radius:999px;
  border:1px solid transparent; font-size:12px; font-weight:700;
}
.person-fields .p-level[data-role="engineer"] { background:color-mix(in srgb,#6fb72f 18%,var(--card2))!important; color:color-mix(in srgb,#6fb72f 40%,var(--ink))!important; border-color:color-mix(in srgb,#6fb72f 34%,transparent)!important; }
.person-fields .p-level[data-role="manager"] { background:color-mix(in srgb,#3b82f6 18%,var(--card2))!important; color:color-mix(in srgb,#3b82f6 40%,var(--ink))!important; border-color:color-mix(in srgb,#3b82f6 34%,transparent)!important; }
.person-fields .p-level[data-role="admin"] { background:color-mix(in srgb,#a78bfa 18%,var(--card2))!important; color:color-mix(in srgb,#a78bfa 40%,var(--ink))!important; border-color:color-mix(in srgb,#a78bfa 34%,transparent)!important; }
.person-fields .p-level[data-role="client"] { background:var(--card2)!important; color:var(--ink2)!important; border-color:var(--line)!important; }
/* The control wears the colour of the level it is showing, and an option
   inherits its colour from the control it sits in - so opening the list gave
   four choices all in the same green, which reads as four Engineers rather
   than as four different levels. The list is plain; the closed control is the
   only place the colour means anything. */
.person-fields .p-level option, .people-table .p-level option {
  background:var(--card); color:var(--ink); font-weight:600;
}
.person-fields .p-level:disabled { opacity:.75; cursor:not-allowed; }
#person-level-note { margin:0; }

/* Project participation.
   A closed control that says how many, and a bounded panel that opens under
   it. The panel is anchored rather than floating: inside a dialog that already
   scrolls, a floating layer would be clipped or would escape the dialog, and
   neither of those is a thing a reader should have to fight. */
.project-picker { position:relative; }
.project-picker-toggle {
  display:flex; align-items:center; justify-content:space-between; gap:10px;
  width:100%; min-height:40px; padding:8px 12px; text-align:start;
  border:1px solid var(--line2); border-radius:9px;
  background:var(--card2); color:var(--ink); font:inherit; font-size:13px;
  text-transform:none; letter-spacing:0; font-weight:600; cursor:pointer;
}
.project-picker-toggle:hover { border-color:var(--line); }
.project-picker-chevron {
  width:16px; height:16px; flex:none; fill:none; stroke:currentColor;
  stroke-width:1.6; stroke-linecap:round; stroke-linejoin:round;
  transition:transform .15s ease;
}
.project-picker-toggle[aria-expanded="true"] .project-picker-chevron { transform:rotate(180deg); }
.project-picker-panel {
  margin-top:6px; padding:10px; border:1px solid var(--line2); border-radius:10px;
  background:var(--card); display:grid; gap:8px;
}
/* The shared filter control, sized for the dialog. One rule still says what
   it looks like; this only says how wide it is here. */
.project-picker-panel .filter-search { width:100%; max-width:none; }
.project-picker-bar {
  display:flex; align-items:center; justify-content:space-between;
  gap:10px; flex-wrap:wrap; font-size:11.5px;
}
.project-picker-bar .hint { text-transform:none; letter-spacing:0; }
.project-picker-bulk { display:flex; gap:12px; flex-wrap:wrap; }
.project-picker-bulk .text-btn { font-size:11.5px; }
/* Bounded, so a person on fifty projects does not get a fifty-row dialog. */
.project-picker-list {
  max-height:210px; overflow-y:auto; display:grid; gap:2px;
  border-top:1px solid var(--line2); padding-top:6px;
}
.project-picker-option {
  display:flex; align-items:center; gap:10px; min-height:40px;
  padding:4px 6px; border-radius:8px; cursor:pointer;
  text-transform:none; letter-spacing:0; font-weight:400; font-size:13px;
  color:var(--ink);
}
.project-picker-option:hover { background:var(--card2); }
.project-picker-option input { width:16px; height:16px; flex:none; margin:0; accent-color:var(--accent); }
.project-picker-option span { display:grid; min-width:0; }
.project-picker-option b { font-weight:600; }
.project-picker-option small { color:var(--muted); font-size:11.5px; }
.project-picker-option:focus-within { outline:2px solid var(--accent); outline-offset:1px; }
#person-project-empty { margin:0; }
@media (max-width:640px) {
  /* A phone gets a shorter list and bigger targets, and the two bulk actions
     move under the count rather than squeezing onto its line. */
  .project-picker-list { max-height:46vh; }
  .project-picker-option { min-height:44px; }
  .project-picker-bar { align-items:flex-start; flex-direction:column; gap:6px; }
}
.person-projects {
  margin:0; padding:12px 14px; border:1px solid var(--line); border-radius:10px;
}
.person-projects legend {
  padding:0 6px; font-size:11px; letter-spacing:.06em; text-transform:uppercase;
  color:var(--muted);
}
#person-project-list { display:grid; gap:0; }
/* A project row carries a name, not a caption, so it drops the dialog's
   uppercase label styling. */
.person-project-row {
  display:flex; align-items:center; gap:11px; min-height:44px;
  margin:0; padding:6px 2px; border-bottom:1px solid var(--line);
  cursor:pointer; text-transform:none; letter-spacing:normal;
  color:var(--ink); font-weight:400;
}
.person-project-row:last-child { border-bottom:0; }
.person-project-row b { display:block; font-size:13px; font-weight:600; }
.person-project-row small { display:block; color:var(--muted); font-size:11.5px; }
.person-project-row .ui-switch { flex:0 0 auto; }
#person-project-note { margin:8px 0 0; }
.person-dialog-actions {
  display:flex; justify-content:flex-end; gap:10px;
  padding:14px 20px; border-top:1px solid var(--line); background:var(--card2);
}
.person-dialog-actions button { min-height:40px; }
.people-row-action { text-align:right; }
@media (max-width:560px) {
  .person-fields { grid-template-columns:1fr; }
}

/* ── Emergency ───────────────────────────────────────────────────────────────
   The same parts as every other workspace page: one heading with view tabs, a
   measure band, and panels. Nothing here is styled specially; it uses the page
   treatment the rest of the workspace already has. */
#page-emergency { display:grid; gap:16px; min-width:0; align-content:start; }
/* The sub-line under a measure carries the part that explains the number —
   "31 failed both, 2 duration only", or the sensor that is oldest. Cutting it
   off with an ellipsis loses exactly the useful half, so it wraps instead. */
.workspace-measure small {
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical;
  overflow:hidden; white-space:normal; line-height:1.35;
}
/* Five narrow columns beside the rail cannot hold five numbers on a laptop.
   Below 1180px the band folds to three, then to two on a phone. */
@media (max-width:1180px) and (min-width:701px) {
  .workspace-measures { grid-template-columns:repeat(3,minmax(0,1fr))!important; }
  .workspace-measure:nth-child(3n+1) { border-inline-start:0; }
  .workspace-measure:nth-child(n+4) { border-top:1px solid var(--line); }
}
.emergency-view-hidden { display:none!important; }

/* The floor bars share the report's track and fill, so a bar means the same
   thing on the screen and on paper. */
/* ONE count bar, used in three places: the emergency floor bars, the
   emergency causes on Overview, and the module outstanding counts. Written
   once on purpose. A bar that answers "how much of this is left" has to be
   the same size and shape wherever it is read, and a second hand-drawn copy
   is a second drawing that drifts — the fault the icon sprite exists to stop.
   These bars are shares of the WORST row, not of a total, so the shape
   answers "where is the work" and the number beside it is the real count. */
.emergency-floor-bars, .overview-bars { display:grid; gap:2px; }
.emergency-floor-row, .overview-bar-row {
  display:grid; grid-template-columns:minmax(90px,150px) 1fr auto;
  align-items:center; gap:14px; min-height:36px;
  padding:5px 0; border-bottom:1px solid var(--line);
}
.emergency-floor-row:last-child, .overview-bar-row:last-child { border-bottom:0; }
.emergency-floor-nm, .overview-bar-name {
  overflow:hidden; color:var(--ink2); font-size:13px;
  text-overflow:ellipsis; white-space:nowrap;
}
/* A neutral track. The fill carries the meaning, so a green track would read
   as a pass share, which none of these are. */
.emergency-floor-row .track, .overview-bar-row .track {
  height:10px; border-radius:4px; overflow:hidden;
  background:color-mix(in srgb,var(--line2) 45%,transparent);
}
/* Amber by default: outstanding WORK, which is not the same claim as a
   failure. "Drivers not addressed" is a job nobody has done yet; red would
   say something is broken. --progress-mid is scoreBand's middle band, so the
   colour already means "in progress" everywhere else on the page. */
.emergency-floor-row .fill, .overview-bar-row .fill {
  display:block; height:100%; border-radius:4px; background:var(--progress-mid);
}
/* Every emergency floor row IS a failure count, and a cause bar is marked. */
.emergency-floor-row .fill, .overview-bar-row .fill.fail { background:var(--fail); }
/* Progress by work type is a percentage, so it takes the one red/amber/green
   scale the rest of the page uses. The amber default above belongs to the
   outstanding-work bars, which are counts; these rules are written here, and
   with the row in front of them, because that default would otherwise win on
   order alone. */
.overview-bar-row .fill.band-low  { background:var(--fail); }
.overview-bar-row .fill.band-mid  { background:var(--progress-mid); }
.overview-bar-row .fill.band-high { background:var(--data); }
/* Module completion counts how many incomplete modules each item affects.
   That is magnitude - not completion and not severity - and a module can be
   counted under more than one item, so red, amber and green would all be
   claims the figure does not make. A neutral information blue, from the
   theme, over the same neutral track. */
.count-bars .overview-bar-row .fill { background:var(--info); }
.emergency-floor-row b, .overview-bar-row b {
  min-width:26px; color:var(--ink); font-size:13px; font-weight:650;
  font-variant-numeric:tabular-nums; text-align:right;
}

#fail-table .emergency-sensor { font-family:"IBM Plex Mono",monospace; font-size:12.5px; }
#fail-table .emergency-module { color:var(--ink2); font-size:12.5px; }
#fail-table .emergency-since {
  color:var(--ink2); font-size:12.5px; white-space:nowrap;
  font-variant-numeric:tabular-nums;
}
#fail-table .emergency-since small { display:block; color:var(--muted); font-size:11px; }

/* ── Emergency failure follow-up ──────────────────────────────────────────
   A failing sensor opens in place: how to fix it on the left, where the
   follow-up stands on the right. The table no longer scrolls inside itself,
   because an open row would otherwise be read through a letterbox. */
.em-failure-tools { display:flex; flex-wrap:wrap; align-items:center; gap:10px 12px; margin:4px 0 12px; }
.em-failure-tools .seg button { display:inline-flex; align-items:center; gap:6px; min-height:36px; }
.em-failure-tools .seg button b { color:var(--muted); font-weight:600; font-variant-numeric:tabular-nums; }
.em-failure-tools .seg button.on b { color:var(--ink2); }
.em-failure-hint { margin:0 0 0 auto; color:var(--muted); font-size:12px; }
.em-failure-elsewhere { margin:0 0 12px; padding:8px 12px; border-inline-start:3px solid var(--line2);
  background:var(--card2); color:var(--ink2); font-size:13px; }
.em-failure-wrap { max-height:none; overflow-x:auto; }
#fail-table .em-failure-row { cursor:pointer; }
#fail-table .em-failure-row:hover > td { background:var(--card2); }
#fail-table .em-failure-row.is-open > td { background:var(--card2); border-bottom-color:transparent; }
.em-row-toggle { display:inline-flex; align-items:center; gap:6px; padding:4px 0; border:0; background:none;
  color:var(--ink); font:inherit; text-align:left; cursor:pointer; }
.em-row-toggle svg { width:14px; height:14px; flex:none; fill:none; stroke:var(--muted); stroke-width:2;
  stroke-linecap:round; stroke-linejoin:round; transition:transform .15s ease; }
.em-row-toggle[aria-expanded="true"] svg { transform:rotate(90deg); stroke:var(--accent-ink); }
.em-row-toggle:focus-visible { outline:2px solid var(--focus); outline-offset:2px; border-radius:4px; }
#fail-table .em-owner-cell { color:var(--ink2); font-size:12.5px; white-space:nowrap; }
.em-status-chip { white-space:nowrap; }
.em-failure-empty td { padding:18px 12px; color:var(--muted); text-align:center; }
.fail-types .rw .em-cause-owner { margin-left:8px; color:var(--muted); font-size:11px; }

#fail-table .em-failure-detail > td { padding:0 12px 16px; background:var(--card2); }
.em-fix { display:grid; grid-template-columns:minmax(0,1.35fr) minmax(260px,1fr); gap:16px; white-space:normal;
  padding:14px 16px 16px 26px; border-inline-start:3px solid var(--accent); background:var(--card);
  border-radius:0 8px 8px 0; cursor:auto; }
.em-fix h3 { display:flex; align-items:center; gap:8px; margin:0 0 10px; font-size:13px; font-weight:700;
  letter-spacing:.04em; text-transform:uppercase; color:var(--ink2); }
.em-fix-cause + .em-fix-cause { margin-top:14px; padding-top:12px; border-top:1px solid var(--line); }
.em-fix-cause header { display:flex; flex-wrap:wrap; align-items:baseline; gap:4px 10px; }
.em-fix-cause header b { font-size:14px; color:var(--ink); }
.em-fix-cause code { color:var(--muted); font:11px "IBM Plex Mono",monospace; }
.em-fix-cause p { margin:4px 0 8px; color:var(--ink2); font-size:13px; }
.em-fix-cause ol { margin:0; padding-left:22px; display:grid; gap:5px; font-size:13px; line-height:1.45; color:var(--ink); }
.em-fix-cause ol li::marker { color:var(--accent-ink); font-weight:700; }
.em-fix-after { margin:12px 0 0; color:var(--ink2); font-size:12.5px; }
.em-fix-after a { margin-left:6px; color:var(--accent-ink); font-weight:600; }
.em-owner-tag { display:inline-flex; align-items:center; padding:2px 8px; border-radius:999px; font-size:11px;
  font-weight:650; letter-spacing:0; text-transform:none; background:var(--chip-na-bg); color:var(--chip-na-ink); }
.em-owner-tag.contractor { background:var(--chip-warn-bg); color:var(--chip-warn-ink); }
.em-owner-tag.delmatic { background:var(--chip-pass-bg); color:var(--chip-pass-ink); }
.em-fix-progress { padding-left:16px; border-inline-start:1px solid var(--line); }
.em-fix-status { margin:0 0 10px; font-size:13.5px; font-weight:600; color:var(--ink); }
.em-fix-status.fixed { color:var(--chip-info-ink); }
.em-fix-status.retest { color:var(--fail); }
.em-fix-actions { display:grid; gap:8px; }
.em-fix-note { width:100%; box-sizing:border-box; min-height:58px; resize:vertical; font:inherit; font-size:13px; }
.em-fix-buttons { display:flex; flex-wrap:wrap; align-items:center; gap:8px; }
.em-fix-buttons button { min-height:40px; }
.em-handover { margin-left:auto; padding:6px 4px; border:0; background:none; color:var(--accent-ink);
  font:inherit; font-size:12.5px; font-weight:600; text-decoration:underline; text-underline-offset:3px; cursor:pointer; }
.em-handover:disabled { opacity:.5; cursor:not-allowed; }
.em-fix-message { min-height:1em; margin:0; color:var(--ink2); font-size:12.5px; }
.em-events { list-style:none; margin:14px 0 0; padding:12px 0 0; border-top:1px solid var(--line); display:grid; gap:10px; }
.em-event p { margin:0; color:var(--ink2); font-size:12px; }
.em-event p b { color:var(--ink); }
.em-event.fixed p b { color:var(--chip-info-ink); }
.em-event blockquote { margin:4px 0 0; padding:6px 10px; border-inline-start:2px solid var(--line2);
  background:var(--card2); color:var(--ink); font-size:13px; white-space:pre-wrap; overflow-wrap:anywhere; }
.em-event.is-earlier { opacity:.72; }
.em-event-earlier { font-style:italic; }
.emergency-work-state .em-status-chip { margin-left:8px; vertical-align:1px; }

@media (max-width:900px) {
  .em-fix { grid-template-columns:1fr; padding-left:16px; }
  .em-fix-progress { padding:14px 0 0; border-inline-start:0; border-top:1px solid var(--line); }
  .em-failure-hint { margin-left:0; flex-basis:100%; }
}
@media (max-width:700px) {
  .em-failure-tools .seg { flex:1 1 100%; }
  .em-failure-tools .seg button { flex:1; justify-content:center; min-height:44px; }
  .em-fix-buttons button { flex:1 1 140px; min-height:44px; }
  .em-handover { margin-left:0; }
}

@media (max-width:700px) {
  .emergency-page-actions { width:100%; justify-content:stretch; }
  .emergency-page-actions button { flex:1; min-height:44px; }
  .emergency-floor-row,
  .overview-bar-row { grid-template-columns:minmax(70px,110px) 1fr auto; gap:10px; }
}

/* ── Zoom to an area you draw ────────────────────────────────────────────────
   The band is drawn on the page, not on the window, so it stays where it was
   put while the sheet scrolls under it. */
.drawing-zoom-band {
  position:absolute; z-index:4; pointer-events:none;
  border:1.5px dashed #111111;
  outline:1.5px dashed #ffffff; outline-offset:-1.5px;
  background:rgba(255,255,255,.22);
}
.drawing-target-stage.is-area-zoom { cursor:crosshair; }
.drawing-target-stage.is-area-zoom.is-panning { cursor:grabbing; }
.drawing-zoom-btn.on {
  background:var(--accent); border-color:var(--accent); color:var(--btn-ink);
}

/* What has come back. Quiet by default — it is a summary, not an alarm — and
   absent entirely on a job where nothing has been reopened. */
.snag-recurrence { margin:0 0 10px; padding:8px 12px; border:1px solid var(--line);
  border-radius:8px; background:var(--card); }
.snag-recurrence > summary { cursor:pointer; font-weight:600; }
.snag-recurrence .note { margin:8px 0 4px; color:var(--muted); font-size:12px; }
.snag-recurrence-list { list-style:none; margin:0; padding:0; }
.snag-recurrence-list li { display:flex; flex-wrap:wrap; gap:4px 10px;
  align-items:baseline; padding:4px 0; border-top:1px solid var(--line); }
.snag-recurrence-list button { background:none; border:0; padding:0; cursor:pointer;
  color:inherit; font:inherit; text-align:left; text-decoration:underline; }
.snag-recurrence-list small { color:var(--muted); }

/* Snag Activity follows the existing theme tokens. */
.snag-status-row { border-bottom:1px solid var(--line2); padding:12px 0; }
.snag-status-row header { display:flex; flex-wrap:wrap; align-items:center; gap:8px; }
.snag-status-row small { display:block; color:var(--muted); }
.snag-status-row summary { cursor:pointer; color:var(--ink); padding:8px 0; }
.snag-status-row p { color:var(--ink); white-space:pre-wrap; overflow-wrap:anywhere; }
.snag-attachment-list { display:grid; grid-template-columns:repeat(auto-fit,minmax(100px,1fr));gap:8px; }
.snag-attachment-list > button {
  display:grid; min-width:0; width:100%; gap:2px; white-space:normal;
  text-align:start; justify-items:start; overflow-wrap:anywhere;
}
.snag-attachment-list > button span,
.snag-attachment-list > button small { display:block; min-width:0; overflow-wrap:anywhere; }
.snag-attachment-list img { width:100%; max-height:180px; object-fit:contain; }
.snag-file-draft { padding:8px 0;border-bottom:1px solid var(--line2);overflow-wrap:anywhere; }
.snag-file-draft input { width:100%; }
#snag-evidence-outbox article,
#snag-page-outbox article { border:1px solid var(--line2);padding:10px;margin-top:8px;overflow-wrap:anywhere; }
.person-project-row select { width:auto;max-width:55%; }

@media print {
  .skip-link { display:none !important; }
  .snag-report-document { font-size:10.5px; padding:0; }
  /* Use the printable A4 height and keep the footer inside that box. This
     prevents Chromium from moving only the footer to a blank extra sheet. */
  /* 297mm less the 8mm top and 13mm footer margins of the page rule below. */
  .snag-report-page { display:flex; flex-direction:column; box-sizing:border-box; height:276mm; min-height:0; overflow:hidden; padding:0; break-inside:avoid; page-break-inside:avoid; break-after:page; page-break-after:always; }
  .snag-report-page:last-child { break-after:auto; page-break-after:auto; }
  .snag-report-page + .snag-report-page { border-top:0; }
  .snag-report-page-content { flex:1 1 auto; min-height:0; }
  /* The page margin carries the footer in print, with the page number. The
     line inside the page is the on-screen preview's footer only. */
  .snag-report-foot { display:none; }
  .snag-report-headline, .snag-report-record-title, .snag-report-details,
  .snag-report-group h2, .snag-report-document thead { break-after:avoid; }
  .snag-report-document thead { display:table-header-group; }
  .snag-report-document tr, .snag-report-history li,
  .snag-report-drawing-stack { break-inside:avoid; page-break-inside:avoid; }
  .print-brand-lockup { -webkit-print-color-adjust:exact; print-color-adjust:exact; }
  .emergency-report-document { padding:0; }
  .emergency-work-sheet,.emergency-status-page { color:#1b2119; background:#fff; }
  .emergency-work-state-print,.emergency-drawing-unavailable,.emergency-multiple-note {
    -webkit-print-color-adjust:exact; print-color-adjust:exact;
  }
  .emergency-work-drawings,.emergency-work-drawings figure { break-inside:avoid; page-break-inside:avoid; }
  @media (monochrome) {
    .print-brand-product strong, .print-brand-attribution b { color:#111; }
    .print-brand-product strong { background:transparent; }
  }
  /* A group can contain more rows than one sheet. Keep its heading with the
     repeated table head, then allow rows to continue on the next sheet. */
  .snag-report-group { break-inside:auto; page-break-inside:auto; }
  .standalone-snag-report { padding:0; }
  /* One footer on every printed page of every report. The words on the left
     are added per report by applyPrintFooter (print-brand.js); the count is
     the browser's own, so it runs through the whole document. */
  @page {
    size:A4; margin:8mm 14mm 13mm;
    @bottom-left {
      content:"Delmatic"; width:150mm; vertical-align:top; padding-top:2.5mm;
      border-top:.25mm solid #cfd4ca; color:#5f6757;
      font:600 7.5pt 'Public Sans','Segoe UI',sans-serif;
    }
    @bottom-right {
      content:"Page " counter(page) " of " counter(pages);
      width:32mm; vertical-align:top; padding-top:2.5mm; text-align:right;
      border-top:.25mm solid #cfd4ca; color:#5f6757;
      font:600 7.5pt 'Public Sans','Segoe UI',sans-serif;
    }
  }
}

/* ══ Section surfaces ════════════════════════════════════════════
   An ordinary section shares the page canvas and is held apart by its
   outline alone. It is a region OF the page, not a card lying on it.

   This was compared against the older filled treatment behind a temporary
   switch and chosen; it is now simply what the application looks like. It
   is not a theme and not a preference - the rules below declare no colour
   of their own and read whatever Light, Dark or Delmatic has set.

   A surface that is not an ordinary section keeps its own fill, because it
   is a separate thing rather than a part of the page:
     * Needs attention - an independent action surface;
     * the report preview well, which holds a document;
     * bounded edit forms and their groups, where the boundary protects
       unsaved work.
   Dialogs, drawers, popovers, report documents, drawing tiles and drop
   targets are already their own material and are left alone here.
   ═════════════════════════════════════════════════════════════════════════ */
:root {
  /* The ordinary section ground IS the page ground. The outline, the radius,
     the padding and the internal rules all stay, so the region is still a
     region. */
  --section-bg:var(--page);
}
.workspace-page .workspace-section,
.workspace-page > .card.block,
.workspace-page > section.card.block,
.workspace-page > #intelligence-content > .card.block {
  background:var(--section-bg);
}
/* A table container, a list group and a chart well are part of their
   section, not separate things sitting inside it. */
.workspace-page .tbl-wrap,
.workspace-page .admin-table-wrap {
  background:var(--section-bg);
}
/* The exceptions named above, stated once. */
.workspace-page #needs-attention,
.workspace-page .needs-attention,
.report-preview-well,
.admin-form,
.admin-group {
  background:var(--card);
}

/* Delmatic green on white must meet the large-text print contrast threshold. */
.completion-wordmark { color:#5d861f; font-weight:850; letter-spacing:-.045em; }
.completion-wordmark { width:42mm; height:auto; color:initial; font-weight:initial; letter-spacing:initial; }
.completion-options .check-label[hidden] { display:none; }
.completion-module-report .completion-control { margin-block:6mm; gap:3mm 8mm; }
.completion-module-report .completion-report-section { margin-bottom:5mm; }
.completion-module-report .completion-report-foot { margin-top:6mm; }
/* A module report is an item in the pack: its title is an item title. */
.completion-module-report .completion-doc-head h1 { margin-top:6mm; font-size:21px; }
.completion-module-report { width:100%; max-width:none; }
.completion-module-head h1 { overflow-wrap:anywhere; }
.completion-module-head h1 strong { font-weight:800; }
.completion-module-details { display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:4mm 6mm; }
.completion-module-details div { min-width:0; }
.completion-module-details dt { color:#697160; font-size:8pt; font-weight:700; text-transform:uppercase; }
.completion-module-details dd { margin:1mm 0 0; overflow-wrap:anywhere; }
.completion-module-details .completion-module-detail-wide { grid-column:1/-1; padding-top:3mm; border-top:1px solid #e5e8e0; }
.completion-module-apb dd { overflow-wrap:normal; word-break:normal; }
@media(max-width:700px) { .completion-module-details { grid-template-columns:repeat(2,minmax(0,1fr)); } }

/* Recipient-report accents use the exact Delmatic brand green. */
.completion-doc-head { border-bottom:1px solid #9dc368; }
.completion-intro { border-left-color:#96D045; }

/* Completion controls keep one aligned rhythm at narrow builder widths. */
.completion-options .completion-nested:not([hidden]) { display:grid; gap:8px; }
.completion-options .seg,
#completion-preview-choice { width:100%; box-sizing:border-box; }
.completion-options .seg.completion-nested { width:auto; }
.completion-options .seg button,
#completion-preview-choice button {
  flex:1 1 0; min-width:0; padding-inline:10px; white-space:normal;
  line-height:1.25; text-align:center;
}
.completion-options .completion-nested > .note { margin:0; }
.completion-preview-controls #completion-preview-choice {
  display:grid; grid-template-columns:repeat(auto-fit,minmax(86px,1fr));
}
.completion-preview-controls #completion-print,
.completion-preview-controls #completion-download-drawings { width:100%; min-height:44px; margin-top:8px; }
.completion-preview-controls #completion-status { margin:0; padding-top:2px; }

/* ── Documents (feature 016) ─────────────────────────────────────────────────
   One list with a category filter. The filter is the Modules filter, so the
   two read as one family; it scrolls sideways on a phone rather than wrap. */
#page-documents .documents-toolbar { display:flex; flex-wrap:wrap; align-items:center; gap:8px; margin-bottom:6px; }
#page-documents .filter-search { width:260px; }
#page-documents .seg { gap:2px; padding:2px; border:0; background:var(--card2);
  overflow-x:auto; scrollbar-width:none; max-width:100%; }
#page-documents .seg::-webkit-scrollbar { display:none; }
#page-documents .seg button { min-height:40px; padding:5px 11px; border-radius:6px; white-space:nowrap; }
#page-documents .seg button.on { background:var(--card); box-shadow:var(--shadow); }
#page-documents .seg button b { color:var(--muted); font-size:12px; font-weight:600;
  font-variant-numeric:tabular-nums; margin-left:4px; }
#page-documents .seg button.on b { color:var(--ink2); }
.documents-list { list-style:none; margin:14px 0 0; padding:0; }
.document-row {
  display:grid; grid-template-columns:auto minmax(0,1fr) auto; gap:14px; align-items:start;
  padding:14px 4px; border-top:1px solid var(--line);
}
.document-row:first-child { border-top:0; }
.document-type {
  display:grid; place-items:center; width:42px; height:50px; border-radius:6px;
  background:var(--card2); border:1px solid var(--line2); color:var(--ink2);
  font-size:10.5px; font-weight:700; letter-spacing:.04em;
}
.document-type[data-kind="PDF"] { background:var(--chip-fail-bg); color:var(--chip-fail-ink); border-color:transparent; }
.document-type[data-kind="Image"] { background:var(--chip-pass-bg); color:var(--chip-pass-ink); border-color:transparent; }
.document-heading { margin:0; display:flex; flex-wrap:wrap; align-items:center; gap:6px 10px; }
.document-title {
  background:none; border:0; padding:0; font:inherit; font-size:15px; font-weight:650;
  color:var(--ink); text-align:left; cursor:pointer; overflow-wrap:anywhere;
}
.document-title:hover { text-decoration:underline; text-underline-offset:3px; }
.document-tag {
  font-size:11.5px; font-weight:600; padding:2px 8px; border-radius:999px;
  background:var(--chip-warn-bg); color:var(--chip-warn-ink);
}
.document-meta { margin:4px 0 0; font-size:12.5px; color:var(--muted); }
.document-description { margin:6px 0 0; font-size:13.5px; color:var(--ink2); max-width:70ch; }
.document-versions { margin-top:8px; font-size:12.5px; color:var(--ink2); }
.document-versions summary { cursor:pointer; color:var(--muted); }
.document-versions ul { list-style:none; margin:6px 0 0; padding:0; display:grid; gap:4px; }
.document-versions li span { color:var(--muted); margin-left:6px; }
.document-version {
  background:none; border:0; padding:0; font:inherit; color:var(--accent-ink);
  text-decoration:underline; text-underline-offset:2px; cursor:pointer;
}
.document-actions { display:flex; flex-wrap:wrap; justify-content:flex-end; gap:6px; }
.document-actions button { min-height:36px; }
.documents-empty { margin-top:14px; }
.document-dlg { width:min(480px, 92vw); }
.document-dlg .document-file-hint { margin:4px 0 0; font-size:12px; color:var(--muted); }
.document-choice { border:0; margin:14px 0 0; padding:0; }
.document-choice legend {
  font-size:11px; font-weight:600; letter-spacing:.08em; text-transform:uppercase;
  color:var(--muted); margin-bottom:4px; padding:0;
}
dialog .document-choice label {
  display:flex; align-items:center; gap:8px; margin:6px 0 0;
  font-size:14px; font-weight:400; letter-spacing:0; text-transform:none; color:var(--ink);
}
dialog .document-choice input[type=radio] { width:auto; margin:0; accent-color:var(--accent-ink); }
@media (max-width: 700px) {
  #page-documents .filter-search { width:100%; }
  .document-row { grid-template-columns:auto minmax(0,1fr); }
  .document-actions { grid-column:1 / -1; justify-content:flex-start; }
}

/* ── Documents, step two: module types and documents kept offline ─────────── */
.documents-for-type {
  display:flex; flex-wrap:wrap; align-items:center; gap:6px 10px; margin:10px 0 0;
  padding:9px 12px; border-radius:8px; background:var(--chip-pass-bg); color:var(--chip-pass-ink);
  font-size:13.5px;
}
.documents-for-type[hidden] { display:none; }
.documents-for-type button {
  background:none; border:0; padding:0; font:inherit; color:inherit; cursor:pointer;
  text-decoration:underline; text-underline-offset:2px; margin-left:auto;
}
.document-kept { background:var(--chip-pass-bg); color:var(--chip-pass-ink); }
.document-types-line { margin:6px 0 0; display:flex; flex-wrap:wrap; align-items:center; gap:4px 6px;
  font-size:12.5px; color:var(--muted); }
.document-type-chip {
  background:var(--card2); border:1px solid var(--line2); border-radius:999px; padding:1px 8px;
  font:inherit; font-size:12px; color:var(--ink2); cursor:pointer;
}
.document-type-chip:hover { border-color:var(--accent-ink); color:var(--ink); }
.document-keep.is-kept { border-color:var(--accent-ink); color:var(--accent-ink); }
.document-types { margin:14px 0 0; border:1px solid var(--line2); border-radius:8px; padding:8px 12px; }
.document-types summary {
  cursor:pointer; font-size:11px; font-weight:600; letter-spacing:.08em; text-transform:uppercase;
  color:var(--muted);
}
.document-types summary .hint { text-transform:none; letter-spacing:0; font-weight:400; }
.document-types > p.hint { margin:8px 0 0; font-size:12px; color:var(--muted); }
.document-types-list { display:grid; gap:2px; margin-top:8px; max-height:180px; overflow:auto; }
dialog .document-types-list label {
  display:flex; align-items:center; gap:8px; margin:0; padding:3px 0;
  font-size:13.5px; font-weight:400; letter-spacing:0; text-transform:none; color:var(--ink);
}
dialog .document-types-list input[type=checkbox] { margin:0; accent-color:var(--accent-ink); }
dialog .document-types-list .hint { color:var(--muted); font-size:12px; margin-left:auto; }
.module-guide {
  margin-left:8px; padding:1px 8px; border-radius:999px; border:1px solid var(--line2);
  background:var(--card); color:var(--accent-ink); font:inherit; font-size:12px; font-weight:600;
  cursor:pointer; vertical-align:1px;
}
.module-guide:hover { border-color:var(--accent-ink); }
.em-fix-documents { margin-top:12px; }
.em-fix-documents h4 { margin:0 0 6px; font-size:13px; }
.em-fix-documents ul { list-style:none; margin:0; padding:0; display:grid; gap:4px; }
.em-fix-documents li span { color:var(--muted); font-size:12px; margin-left:6px; }
.document-link {
  background:none; border:0; padding:0; font:inherit; color:var(--accent-ink); cursor:pointer;
  text-decoration:underline; text-underline-offset:2px; text-align:left;
}

/* ── Areas (feature 018) ─────────────────────────────────────────────────────
   Each state has one colour, used for its pill, its share of a bar and its
   outline on the drawing, where it is a strong border with a light wash of
   the same colour inside. The colour comes from areas.js through
   --area-colour, so the page, the drawing and the printed sheets agree. */
.areas-summary-head { display:flex; flex-wrap:wrap; align-items:baseline; justify-content:space-between; gap:4px 16px; }
.areas-summary-head h2 { margin:0; font-size:16px; }
.areas-summary-head .note { margin:0; }
.areas-summary { margin-top:12px; }
.areas-summary-figures { display:flex; flex-wrap:wrap; gap:6px 28px; margin-bottom:10px; }
.areas-headline { margin:0; color:var(--ink2); font-size:14px; }
.areas-headline b { color:var(--ink); font-size:26px; font-weight:700; margin-right:4px; font-variant-numeric:tabular-nums; }
.area-bar { display:flex; height:12px; border-radius:6px; overflow:hidden; background:var(--card2); gap:2px; }
.area-bar-part { background:var(--area-colour); min-width:4px; flex-basis:0; }
.area-bar-empty { flex:1; }
.area-legend { list-style:none; display:flex; flex-wrap:wrap; gap:6px; margin:10px 0 0; padding:0; }
.area-legend button {
  display:inline-flex; align-items:center; gap:6px; min-height:36px; padding:4px 10px;
  border:1px solid var(--line2); border-radius:999px; background:var(--card); color:var(--ink2); font:inherit; font-size:13px;
}
.area-legend button b { color:var(--ink); font-variant-numeric:tabular-nums; }
.area-legend button small { color:var(--muted); font-variant-numeric:tabular-nums; }
.area-legend button.on { border-color:var(--area-colour, var(--accent-ink)); box-shadow:inset 0 0 0 1px var(--ink2); }
.area-swatch {
  display:inline-block; width:12px; height:12px; flex:none; border-radius:3px;
  border:2px solid var(--area-colour); background:color-mix(in srgb, var(--area-colour) 22%, transparent);
}
.areas-floors { margin-top:18px; overflow-x:auto; }
.areas-floor-table, .areas-table { width:100%; border-collapse:collapse; font-size:13.5px; }
.areas-floor-table th, .areas-floor-table td, .areas-table th, .areas-table td {
  padding:8px 10px; border-top:1px solid var(--line); text-align:left; vertical-align:middle;
}
.areas-floor-table thead th, .areas-table thead th {
  border-top:0; color:var(--muted); font-size:12px; font-weight:600; white-space:nowrap;
}
.areas-floor-table tbody th { font-weight:650; white-space:nowrap; }
.areas-floor-bar { width:32%; min-width:140px; }
.areas-floor-table td:last-child { text-align:right; }
.areas-floor-table .ghost-btn { min-height:36px; white-space:nowrap; }
.areas-outside { color:var(--chip-warn-ink); }
.muted { color:var(--muted); }
#page-areas .areas-toolbar { display:flex; flex-wrap:wrap; align-items:center; gap:8px; margin-bottom:8px; }
#page-areas .filter-search { width:240px; }
#page-areas .seg { gap:2px; padding:2px; border:0; background:var(--card2);
  overflow-x:auto; scrollbar-width:none; max-width:100%; }
#page-areas .seg::-webkit-scrollbar { display:none; }
#page-areas .seg button { min-height:40px; padding:5px 11px; border-radius:6px; white-space:nowrap; }
#page-areas .seg button.on { background:var(--card); box-shadow:var(--shadow); }
#page-areas .seg button b { color:var(--muted); font-size:12px; font-weight:600;
  font-variant-numeric:tabular-nums; margin-left:4px; }
#page-areas .seg button.on b { color:var(--ink2); }
.areas-floor-select select { min-height:40px; }
.areas-bulk {
  display:flex; flex-wrap:wrap; align-items:center; gap:8px 12px; margin:6px 0 10px;
  padding:10px 12px; border:1px solid var(--line2); border-radius:10px; background:var(--card2);
}
.areas-bulk[hidden] { display:none; }
.areas-bulk input[type="text"] { flex:1 1 220px; min-height:38px; }
.areas-bulk select { min-height:38px; }
.areas-outbox { margin:14px 0; padding:12px; border:1px solid var(--line2); border-radius:10px; background:var(--card2); }
.areas-outbox h2 { margin:0 0 8px; font-size:14px; }
.area-outbox-list { display:grid; gap:10px; margin:0; padding:0; list-style:none; }
.area-outbox-list li { display:grid; gap:3px; padding:8px 0; border-top:1px solid var(--line2); }
.area-operation-status, .area-operation-note { color:var(--muted); font-size:12px; white-space:pre-wrap; }
.area-operation-actions { display:flex; flex-wrap:wrap; gap:10px; margin-top:3px; }
.area-sync-label { display:block; margin-top:3px; color:var(--muted); font-size:11px; }
.area-sync-label.is-conflict { color:var(--chip-warn-ink); font-weight:650; }
.areas-table-wrap { overflow-x:auto; }
.areas-select-col { width:36px; display:none; }
.areas-table.can-select .areas-select-col { display:table-cell; }
.areas-table tbody tr.is-selected { background:color-mix(in srgb, var(--accent) 10%, transparent); }
.areas-table td:nth-child(n+5) { font-variant-numeric:tabular-nums; white-space:nowrap; }
.area-open { font-weight:650; white-space:nowrap; }
.area-name { color:var(--ink2); font-size:13px; }
/* Number and name on one line; a long name wraps under itself, not under the number. */
.area-title-line { display:flex; align-items:baseline; gap:10px; }
.area-title-line .area-open { flex:0 0 auto; }
.area-title-line .area-name { min-width:0; }
.area-floor-links { display:flex; flex-direction:column; align-items:flex-start; gap:2px; }
.area-show-drawing {
  display:inline-flex; align-items:center; gap:6px; padding:3px 8px 3px 6px; margin:-3px 0 -3px -6px;
  border:0; border-radius:6px; background:none; color:var(--ink); font:inherit; text-align:left; cursor:pointer;
}
.area-show-drawing svg { width:14px; height:14px; flex:0 0 auto; fill:var(--muted); }
.area-show-drawing:hover, .area-show-drawing:focus-visible { background:var(--card2); color:var(--accent); }
.area-show-drawing:hover svg, .area-show-drawing:focus-visible svg { fill:var(--accent); }
.area-complete { color:var(--chip-pass-ink); font-weight:600; }
.area-snags { color:var(--chip-fail-ink); font-weight:650; }
.areas-empty { margin-top:14px; }
.area-state-pill {
  display:inline-flex; align-items:center; gap:6px; padding:2px 9px 2px 7px; border-radius:999px;
  font-size:12px; font-weight:650; white-space:nowrap; color:var(--ink);
  background:color-mix(in srgb, var(--area-colour) 16%, var(--card));
  border:1px solid color-mix(in srgb, var(--area-colour) 55%, transparent);
}
.area-state-pill::before { content:""; width:8px; height:8px; border-radius:50%; background:var(--area-colour); }

.area-dlg { width:min(640px, 94vw); padding:0; }
.area-dlg-head {
  display:flex; align-items:flex-start; justify-content:space-between; gap:12px;
  padding:18px 20px 12px; border-bottom:1px solid var(--line);
}
.area-dlg-head h2 { margin:2px 0 6px; font-size:20px; }
.area-dlg-head .eyebrow { margin:0; }
.area-dlg-body { padding:6px 20px 18px; max-height:calc(92dvh - 90px); overflow:auto; }
.area-dlg-section { padding:14px 0; border-bottom:1px solid var(--line); }
.area-dlg-section h3 { margin:0 0 10px; font-size:14px; }
.area-evidence { display:grid; grid-template-columns:repeat(auto-fill, minmax(150px, 1fr)); gap:8px; margin:0; }
.area-evidence div { padding:8px 10px; border:1px solid var(--line2); border-radius:8px; }
.area-evidence div.is-complete { border-color:color-mix(in srgb, var(--chip-pass-ink) 45%, transparent); background:var(--chip-pass-bg); }
.area-evidence dt { color:var(--muted); font-size:12px; }
.area-evidence dd { margin:2px 0 0; font-size:16px; font-weight:650; font-variant-numeric:tabular-nums; }
.area-state-choices { display:flex; flex-wrap:wrap; gap:6px; }
.area-state-choice {
  display:inline-flex; align-items:center; gap:7px; min-height:40px; padding:6px 12px;
  border:1px solid var(--line2); border-radius:8px; background:var(--card); color:var(--ink); font:inherit; font-size:13.5px;
}
.area-state-choice .area-swatch { border-color:var(--area-colour); }
.area-state-choice.on { border-color:var(--area-colour); box-shadow:inset 0 0 0 1px var(--area-colour);
  background:color-mix(in srgb, var(--area-colour) 12%, var(--card)); }
.area-state-choice.is-current { cursor:default; color:var(--muted); }
.area-state-choice small { color:var(--muted); font-size:11.5px; }
.area-field { display:grid; gap:4px; margin-top:10px; font-size:13px; font-weight:600; color:var(--ink2); }
.area-field input, .area-field textarea, .area-field select { font:inherit; font-weight:400; font-size:var(--field-font); }
.area-field-hint { font-weight:400; color:var(--muted); font-size:12px; }
.area-dlg-actions { display:flex; justify-content:flex-end; gap:8px; margin-top:10px; }
.area-dlg-foot { justify-content:flex-start; border-top:0; padding-top:6px; }
.area-outlines { list-style:none; margin:0; padding:0; display:grid; gap:6px; }
.area-outlines li { display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:6px 10px; }
.area-outlines li > span:first-child { font-weight:600; }
.area-outline-actions { display:flex; flex-wrap:wrap; gap:6px; }
.area-outline-actions button { min-height:34px; }
.area-draw-on { display:flex; flex-wrap:wrap; align-items:center; gap:8px; margin-top:10px; }
.area-draw-on[hidden] { display:none; }
/* The dialog rule gives every label a top margin and small capitals; here the
   label only wraps the floor list, so it must not push the row taller. */
.area-draw-on label { margin:0; }
.area-draw-on select { min-height:36px; font-size:13.5px; text-transform:none; letter-spacing:0; }
.area-history { list-style:none; margin:0; padding:0; display:grid; gap:8px; }
.area-history li { display:grid; gap:1px; padding-left:10px; border-left:2px solid var(--line2); }
.area-history-what { font-weight:600; font-size:13.5px; }
.area-history-when { color:var(--muted); font-size:12px; }
.area-history-note { color:var(--ink2); font-size:13px; white-space:pre-wrap; }
.area-add-dlg { width:min(440px, 92vw); }

/* On the drawing. The layer sits under the snags, so a snag balloon is never
   hidden by an area label. Labels take clicks only on the area drawing; in
   the snag and progress drawings a click belongs to the drawing. */
#drawing-area-layer { position:absolute; inset:0; pointer-events:none; }
#drawing-area-layer[hidden] { display:none; }
#drawing-area-layer svg { position:absolute; inset:0; overflow:visible; }
#drawing-area-layer polygon {
  fill:color-mix(in srgb, var(--area-colour) 16%, transparent);
  stroke:var(--area-colour); stroke-linejoin:round;
}
#drawing-area-layer polygon.is-selected { fill:color-mix(in srgb, var(--area-colour) 28%, transparent); }
#drawing-area-layer polygon.is-subdued { opacity:.45; }
.drawing-area-label {
  position:absolute; transform:translate(-50%, -50%); display:grid; justify-items:center; gap:0;
  min-width:30px; min-height:30px; max-width:160px; padding:3px 8px; border-radius:8px;
  border:2px solid var(--area-colour); background:#ffffff; color:#1f1f1f;
  font:600 12px/1.15 'Public Sans', "Segoe UI", system-ui, sans-serif; text-align:center;
  box-shadow:0 1px 3px rgba(0,0,0,.18); pointer-events:none;
}
.drawing-area-label b { font-size:14px; }
.drawing-area-label span { font-weight:500; font-size:11px; max-width:150px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.drawing-area-label.is-selected { box-shadow:0 0 0 3px color-mix(in srgb, var(--area-colour) 45%, transparent); }
.drawing-area-label.is-subdued { opacity:.5; }
#drawing-area-layer.is-interactive .drawing-area-label { pointer-events:auto; cursor:pointer; }
.drawing-viewer-dlg button.drawing-area-label { min-width:30px; min-height:30px; }
.drawing-target-page.marking .drawing-area-label, .drawing-target-page.filling .drawing-area-label { opacity:.35; }
.drawing-target-page.filling { cursor:crosshair; }
#area-draw-layer { position:absolute; inset:0; pointer-events:none; overflow:visible; }
.area-draw-fill { fill:color-mix(in srgb, #3b82f6 14%, transparent); stroke:none; }
#area-draw-layer .snag-mark-join { stroke:#1f5fbf; }
#area-draw-layer .snag-mark-dot { stroke:#1f5fbf; }
#area-draw-layer .snag-mark-dot.last { fill:#1f5fbf; }
#area-draw-layer .snag-mark-dot.snapped { fill:#6c972a; stroke:#ffffff; }
.area-barrier { stroke:#d03b3b; stroke-linecap:round; stroke-dasharray:6 5; }
.area-draw-toolbar .area-draw-name input { min-height:36px; width:min(260px, 60vw); }
.drawing-tool-btn.on { background:var(--card2); box-shadow:inset 0 0 0 1px var(--ink2); }

/* The area drawing: the progress comparison and the change list are not part
   of it. CSS only adds hiding, for the reason given above the snag drawing. */
.drawing-viewer-dlg.area-viewer #drawing-mode-toolbar,
.drawing-viewer-dlg.area-viewer #drawing-newwork-control,
.drawing-viewer-dlg.area-viewer #drawing-newwork-status,
.drawing-viewer-dlg.area-viewer #drawing-markers-status,
.drawing-viewer-dlg.area-viewer #drawing-current-control,
.drawing-viewer-dlg.area-viewer #drawing-overlay-control,
.drawing-viewer-dlg.area-viewer #drawing-overlay-strength-control,
.drawing-viewer-dlg.area-viewer #drawing-overlay-status,
.drawing-viewer-dlg.area-viewer #drawing-change-panel,
.drawing-viewer-dlg.area-viewer #drawing-panel-collapse,
.drawing-viewer-dlg.area-viewer #drawing-legend-open,
.drawing-viewer-dlg.area-viewer #drawing-snag-mark-edit,
.drawing-viewer-dlg.area-viewer #drawing-emergency-work-list,
.drawing-viewer-dlg.area-viewer #drawing-viewer-download-markers { display:none; }
.drawing-area-panel { grid-row:3; }
.drawing-area-panel[hidden] { display:none; }
.drawing-area-summary { padding:10px 0; border-bottom:1px solid var(--line2); }
.drawing-area-summary .note { margin:8px 0 0; }
.drawing-area-selected { padding:10px 0; border-bottom:1px solid var(--line2); }
.drawing-area-selected[hidden] { display:none; }
.drawing-area-selected-title { margin:0; display:flex; flex-wrap:wrap; align-items:center; gap:6px 10px; }
.drawing-area-selected .note { margin:6px 0 0; }
.drawing-area-selected-actions { display:flex; flex-wrap:wrap; gap:6px; margin:8px 0 0; }
.drawing-area-list { list-style:none; margin:8px 0 0; padding:0; overflow:auto; display:grid; gap:4px; }
.drawing-area-row {
  display:grid; grid-template-columns:auto auto minmax(0,1fr) auto; align-items:center; gap:8px;
  width:100%; padding:8px 10px; border:1px solid var(--line2); border-radius:8px;
  background:transparent; color:var(--ink); font:inherit; font-size:13px; text-align:left; cursor:pointer;
}
.drawing-area-row span:not(.area-swatch) { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:var(--ink2); }
.drawing-area-row small { color:var(--muted); font-size:11.5px; }
.drawing-area-row.is-selected { border-color:var(--accent); background:var(--chip-pass-bg); }
@media (max-width:760px) {
  #page-areas .filter-search { width:100%; }
  .areas-floor-bar { display:none; }
}
.areas-floor-table tbody th { text-transform:none; letter-spacing:0; color:var(--ink); font-size:13.5px; font-weight:650; }

/* ── Witnessing (feature 018, phase 3) ─────────────────────────────────────── */
#areas-visits-card .areas-summary-head { align-items:center; }
.witness-visits { list-style:none; margin:10px 0 0; padding:0; }
.witness-visit {
  display:grid; grid-template-columns:minmax(0,1fr) auto; gap:10px 16px; align-items:start;
  padding:12px 4px; border-top:1px solid var(--line);
}
.witness-visit:first-child { border-top:0; }
.witness-visit-title { margin:0; font-size:14px; }
.witness-visit-title b { margin-right:6px; }
.witness-visit .note { margin:3px 0 0; }
.witness-visit-areas { display:flex; flex-wrap:wrap; gap:4px; margin:6px 0 0; }
.witness-chip {
  display:inline-flex; align-items:center; gap:4px; padding:2px 8px; border-radius:999px;
  border:1px solid var(--line2); font-size:12px; font-weight:600; color:var(--ink2);
}
.witness-chip small { color:var(--muted); font-weight:500; }
.witness-chip.is-passed, .witness-chip.is-passed_with_snags { background:var(--chip-pass-bg); color:var(--chip-pass-ink); border-color:transparent; }
.witness-chip.is-failed { background:var(--chip-fail-bg); color:var(--chip-fail-ink); border-color:transparent; }
.witness-chip.is-not_witnessed { background:var(--chip-na-bg); color:var(--chip-na-ink); border-color:transparent; }
.witness-visit-actions { display:flex; flex-wrap:wrap; justify-content:flex-end; gap:6px; }
.witness-visit-actions button { min-height:36px; }
.witness-visit-dlg { width:min(720px, 94vw); }
.witness-visit-dlg h2 { margin:14px 0 6px; }
.witness-visit-fields { display:grid; grid-template-columns:repeat(auto-fit, minmax(200px, 1fr)); gap:0 12px; }
.witness-visit-picker { margin-top:14px; border-top:1px solid var(--line); padding-top:10px; }
.witness-visit-picker-head { display:flex; flex-wrap:wrap; align-items:center; gap:6px 12px; margin:0 0 8px; }
.witness-visit-picker-head .marker-visibility-control { margin-left:auto; }
.witness-visit-areas { max-height:40dvh; overflow:auto; }
.witness-area-group { border:0; margin:0 0 8px; padding:0; }
.witness-area-group legend { font-size:12px; font-weight:700; color:var(--muted); padding:0 0 4px; }
.witness-area-choice { display:flex; flex-wrap:wrap; align-items:center; gap:6px 8px; padding:6px 4px; border-top:1px solid var(--line); font-size:13.5px; }
.witness-area-choice span { color:var(--ink2); }
.witness-again { color:var(--chip-fail-ink); font-weight:700; }
.witness-record-dlg { width:min(760px, 94vw); padding:0; }
.witness-record-area { padding:14px 0; border-bottom:1px solid var(--line); }
.witness-record-area header { display:flex; flex-wrap:wrap; align-items:baseline; gap:4px 12px; }
.witness-record-area h3 { margin:0; font-size:15px; }
.witness-outcomes { display:flex; flex-wrap:wrap; gap:6px 16px; margin:10px 0 2px; font-size:13.5px; }
.witness-outcomes label { display:inline-flex; align-items:center; gap:6px; min-height:36px; }
.witness-failed-items { margin-top:10px; }
.witness-failed-head { margin:0 0 6px; font-weight:600; font-size:13px; }
.witness-failed-row { display:grid; grid-template-columns:minmax(0,1fr) minmax(120px,200px) auto; gap:6px; margin-bottom:6px; }
.witness-failed-row input, .witness-failed-row select { min-height:36px; }
.witness-scans { list-style:none; margin:0; padding:0; display:grid; gap:4px; }
.witness-scans li { display:flex; flex-wrap:wrap; gap:8px; align-items:baseline; }
.area-print-dlg { width:min(520px, 94vw); }
.area-print-kinds { border:0; margin:10px 0; padding:0; display:grid; gap:6px; }
.area-print-kinds .check-label { align-items:flex-start; padding:8px 10px; border:1px solid var(--line2); border-radius:8px; }
.area-print-kinds .check-label span { display:grid; gap:2px; }
.area-print-kinds small { color:var(--muted); font-size:12px; }
.area-print-choices { border:0; margin:10px 0; padding:0; }
.area-print-choices legend { font-size:12px; font-weight:700; color:var(--muted); padding:0 0 4px; }
.area-print-choices > div { display:flex; flex-wrap:wrap; gap:4px 16px; }
.area-report-dlg { box-sizing:border-box; width:min(1000px,96vw); height:92dvh; max-width:none; }
#area-report-frame, #precom-report-frame { width:100%; height:calc(100% - 70px); border:1px solid var(--line2); background:white; }

/* The printed documents. They sit inside .snag-report-document, so they take
   its type, colours and page frame, and the running head and footer. */
.area-print-kicker { margin:0; color:var(--sr-muted); font-size:9.5px; font-weight:700; letter-spacing:.08em; text-transform:uppercase; }
.area-print-head { display:flex; justify-content:space-between; align-items:flex-start; gap:10px; margin-bottom:4mm; }
.area-print-head h1 { margin:1mm 0 0; font-size:21px; line-height:1.15; }
.area-print-head h1 span { font-weight:500; color:#39412f; }
.area-print-state {
  display:inline-flex; align-items:center; gap:5px; padding:2px 8px 2px 6px; border-radius:999px; white-space:nowrap;
  font-size:10px; font-weight:700; border:1px solid var(--area-colour); color:#1b2119;
  background:color-mix(in srgb, var(--area-colour) 14%, #fff);
  -webkit-print-color-adjust:exact; print-color-adjust:exact;
}
.area-print-state::before { content:""; width:7px; height:7px; border-radius:50%; background:var(--area-colour); }
.area-print-drawings { display:grid; grid-template-columns:1fr; gap:2mm; margin-bottom:3mm; break-inside:avoid; }
.area-print-drawings figure { margin:0; }
.area-print-drawings img, .area-print-overview img { display:block; width:100%; object-fit:contain; border:1px solid var(--sr-line); }
.area-print-locator img { height:46mm; }
.area-print-detail img { height:78mm; }
.area-print-drawings figcaption { margin-top:1mm; color:var(--sr-muted); font-size:9px; }
.area-print-overview { margin:0 0 3mm; }
.area-print-overview img { max-height:120mm; }
.area-print-overview.is-full img { max-height:210mm; }
.area-print-block { margin:0 0 3.5mm; break-inside:avoid; }
.area-print-block h3 { margin:0 0 1.5mm; font-size:10.5px; text-transform:uppercase; letter-spacing:.06em; color:#39412f; }
.area-print-facts { display:grid; grid-template-columns:repeat(5,minmax(0,1fr)); gap:2mm; margin:0; }
.area-print-facts div { padding:2mm 2.5mm; border:1px solid var(--sr-line); background:var(--sr-soft); }
.area-print-facts div.is-complete { border-color:#9dc368; }
.area-print-facts dt { color:var(--sr-muted); font-size:8.5px; font-weight:700; text-transform:uppercase; letter-spacing:.05em; }
.area-print-facts dd { margin:1mm 0 0; font-size:13px; font-weight:700; }
.area-print-muted { color:var(--sr-muted); font-size:9.5px; margin:1mm 0; }
.area-print-history { margin:0; padding-inline-start:5mm; }
.area-print-history li span { display:block; color:var(--sr-muted); }
.area-print-signoff { padding:3mm; border:1px solid #9dc368; }
.area-print-ticks { display:flex; flex-wrap:wrap; gap:3mm 8mm; margin:0 0 3mm; font-size:11px; font-weight:600; }
.area-print-tick { display:inline-flex; align-items:center; gap:2mm; }
.area-print-box { display:inline-block; width:4.2mm; height:4.2mm; border:.4mm solid #1b2119; box-sizing:border-box; }
.area-print-comments { height:24mm; margin-bottom:3mm; border:1px solid var(--sr-line);
  background:repeating-linear-gradient(to bottom, transparent 0 7.6mm, #e3e7de 7.6mm 7.9mm); }
.area-print-comments span { display:block; padding:1mm 2mm; color:var(--sr-muted); font-size:8.5px; }
.area-print-sign { margin-top:2mm; }
.area-print-sign-role { margin:0 0 1mm; font-size:9px; font-weight:700; text-transform:uppercase; letter-spacing:.06em; color:#39412f; }
.area-print-sign-grid { display:grid; grid-template-columns:1.2fr 1.4fr .8fr; gap:3mm; }
.area-print-sign-grid div { border-bottom:.3mm solid #1b2119; min-height:9mm; display:flex; flex-direction:column; justify-content:space-between; }
.area-print-sign-grid span { color:var(--sr-muted); font-size:8px; }
.area-print-sign-grid b { font-size:10.5px; font-weight:600; }
.area-print-legend { list-style:none; display:flex; flex-wrap:wrap; gap:2mm 6mm; margin:0 0 3mm; padding:0; font-size:9.5px; }
.area-print-legend li { display:inline-flex; align-items:center; gap:1.5mm; }
.area-print-swatch { display:inline-block; width:4mm; height:3mm; border:.5mm solid var(--area-colour);
  background:color-mix(in srgb, var(--area-colour) 22%, #fff); -webkit-print-color-adjust:exact; print-color-adjust:exact; }
.area-print-worklist td small { display:block; color:var(--sr-muted); }
.area-print-done { width:12mm; text-align:center; }
.area-print-index td:first-child b { margin-right:2mm; }
.area-print-index-outcome { width:34mm; border-bottom:1px solid var(--sr-line); }
.area-print-worklist { table-layout:fixed; }
.area-print-worklist th { font-size:8.5px; letter-spacing:.03em; white-space:normal; }
.area-print-worklist th:nth-child(1) { width:26%; }
.area-print-worklist th:nth-child(2) { width:17%; }
.area-print-worklist th:nth-child(3), .area-print-worklist th:nth-child(4),
.area-print-worklist th:nth-child(5), .area-print-worklist th:nth-child(6) { width:8%; }
.area-print-worklist th:nth-child(7) { width:19%; }
.area-print-worklist th:nth-child(8) { width:6%; }
.area-print-worklist .area-print-state { white-space:normal; }

/* ── Names from drawings (feature 018, phase 4) ────────────────────────────── */
#drawing-name-layer { position:absolute; inset:0; pointer-events:none; }
#drawing-name-layer[hidden] { display:none; }
#drawing-name-layer svg { position:absolute; inset:0; overflow:visible; }
#drawing-name-layer polygon {
  fill:rgba(59,130,246,.06); stroke:#1f5fbf; stroke-width:2; stroke-dasharray:7 5;
  pointer-events:visiblePainted; cursor:pointer;
}
#drawing-name-layer polygon:hover { fill:rgba(59,130,246,.16); }
.drawing-name-marker {
  position:absolute; transform:translate(-50%, -50%); pointer-events:auto; cursor:pointer;
  max-width:180px; padding:2px 8px; border-radius:999px; border:1.5px dashed #1f5fbf;
  background:#ffffff; color:#1f3f7a; font:600 11px/1.3 'Public Sans', "Segoe UI", system-ui, sans-serif;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; box-shadow:0 1px 3px rgba(0,0,0,.15);
}
.drawing-viewer-dlg button.drawing-name-marker { min-width:0; min-height:24px; }
.drawing-name-marker:hover, .drawing-name-marker:focus-visible { background:#eaf1fd; }
#drawing-names-hint { font-size:12.5px; }
.area-names-dlg { width:min(640px, 94vw); }
.area-names-list { display:grid; gap:4px; max-height:55dvh; overflow:auto; margin:8px 0; }
.area-name-layer {
  display:grid; grid-template-columns:auto minmax(140px, 220px) minmax(0,1fr); gap:10px; align-items:start;
  padding:8px; border:1px solid var(--line2); border-radius:8px;
}
.area-name-layer-main { display:grid; gap:2px; }
.area-name-layer-main small { color:var(--muted); font-size:12px; }
.area-name-layer-examples { display:flex; flex-wrap:wrap; gap:4px; }
.area-name-layer-examples span { padding:1px 7px; border-radius:999px; background:var(--card2); font-size:12px; color:var(--ink2); }
/* The area drawing carries more tools than the others, so its toolbar wraps
   rather than pushing the heading off the left of the screen. Keeping a
   drawing for offline belongs to the site views, not to drawing areas. */
.drawing-viewer-dlg.area-viewer .drawing-target-toolbar { flex-wrap:wrap; justify-content:flex-end; min-width:0; }
.drawing-viewer-dlg.area-viewer #drawing-offline-control,
.drawing-viewer-dlg.area-viewer #drawing-offline-status { display:none; }
.drawing-viewer-dlg.area-viewer .drawing-toolbars > #drawing-target-toolbar { flex:1 1 100%; }
.drawing-viewer-dlg.area-viewer #drawing-snags-status { flex:1 1 220px; min-width:0; white-space:normal; text-align:right; }

/* Review, 28 September 2026. */
/* One scroll bar: the dialog holds still and only its body scrolls. */
.area-dlg[open] { display:flex; flex-direction:column; max-height:92dvh; overflow:hidden; }
.area-dlg > .area-dlg-body, .area-dlg > form.area-dlg-body { flex:1 1 auto; min-height:0; max-height:none; overflow:auto; }
.area-dlg-head { flex:0 0 auto; }
/* Choices read left to right: the control first, then its words. The
   dialog rule gives every input full width and upper-cases every label,
   which stood a radio button alone above its sentence. */
.area-print-dlg .check-label, .witness-visit-dlg .check-label {
  display:grid; grid-template-columns:auto minmax(0,1fr); align-items:start; gap:10px;
  margin:0; text-transform:none; letter-spacing:0; font-size:13.5px; font-weight:500; color:var(--ink);
}
.area-print-dlg input[type=radio], .area-print-dlg input[type=checkbox] { width:auto; margin:2px 0 0; }
.area-print-kinds .check-label b { font-weight:650; }
.area-print-kinds .check-label small { text-transform:none; letter-spacing:0; }
.area-print-choices > div:not(.area-floor-picker-list) { display:flex; flex-wrap:wrap; gap:6px 18px; }
.area-print-choices .check-label { display:inline-grid; }
.area-floor-picker { border:1px solid var(--line2); border-radius:8px; background:var(--card2); }
.area-floor-picker > summary { cursor:pointer; padding:9px 12px; font-size:13.5px; list-style:none; }
.area-floor-picker > summary::-webkit-details-marker { display:none; }
.area-floor-picker > summary::after { content:"▾"; float:right; color:var(--muted); }
.area-floor-picker-panel { padding:8px 10px 10px; border-top:1px solid var(--line2); }
.area-floor-picker-actions { display:flex; gap:14px; margin:6px 0; font-size:12.5px; }
.area-floor-picker-list { display:grid; gap:4px; max-height:32dvh; overflow:auto; }
.area-floor-picker-list .check-label[hidden] { display:none; }
/* The worksheet: every column has room, and the tick box has its own. */
.area-print-worklist th { letter-spacing:0; }
.area-print-worklist td { overflow-wrap:anywhere; }
.area-print-worklist th:nth-child(1) { width:20%; }
.area-print-worklist th:nth-child(2) { width:15%; }
.area-print-worklist th:nth-child(3) { width:10%; }
.area-print-worklist th:nth-child(4) { width:9%; }
.area-print-worklist th:nth-child(5) { width:10%; }
.area-print-worklist th:nth-child(6) { width:7%; }
.area-print-worklist th:nth-child(7) { width:21%; }
.area-print-worklist th:nth-child(8) { width:8%; }
.area-print-worklist td.area-print-done { text-align:center; padding-left:0; padding-right:0; }
.area-floor-picker .filter-search { width:100%; margin:0; text-transform:none; letter-spacing:0; }
.area-floor-picker .filter-search input { width:100%; }
.area-print-worklist td { white-space:normal; }
.area-print-worklist td:nth-child(7) { padding-right:3mm; }
.area-print-worklist .area-print-done { width:auto; }

/* Walls from drawings (feature 018, phase 5): the layer list beside a
   preview of what the fill will treat as walls. */
.area-walls-dlg { width:min(1100px, 96vw); }
.area-walls-body { display:grid; grid-template-columns:minmax(240px, 340px) minmax(0,1fr); gap:16px; align-items:start; }
.area-wall-layer { grid-template-columns:auto minmax(0,1fr); }
.area-walls-figure { margin:0; display:grid; gap:6px; }
.area-walls-figure canvas { width:100%; height:auto; border:1px solid var(--line2); border-radius:8px; background:#fff; }
@media (max-width: 720px) { .area-walls-body { grid-template-columns:minmax(0,1fr); } }
#drawing-walls-hint { font-size:12.5px; }
/* The dialog rule upper-cases every label; layer names and counts read as written. */
.area-walls-dlg .area-wall-layer, .area-walls-dlg .area-wall-layer small { text-transform:none; letter-spacing:0; }
.area-walls-dlg .area-wall-layer b { font-weight:650; color:var(--ink); }
.area-walls-dlg .area-wall-layer input { width:auto; margin:2px 0 0; }

/* ── Every list and text field starts from one look ─────────────────────────
   Before this, a drop-down or field that no rule styled fell back to the
   browser's own box: square, white, a 2 px border on dates. The controls sweep
   (tests/browser/controls.local.mjs) found them on Snags, Action Centre,
   Database checks and Drawings. :where() gives these rules no weight at all,
   so any control that already has its own style keeps it; only the unstyled
   ones change. */
:root { --field-font:14px; --field-height:38px; }
:where(select, textarea,
  input:not([type=checkbox], [type=radio], [type=range], [type=color], [type=file],
            [type=hidden], [type=submit], [type=button], [type=reset], [type=image])) {
  box-sizing:border-box; min-height:var(--field-height); padding:7px 10px;
  background:var(--card2); color:var(--ink); border:1px solid var(--line2); border-radius:8px;
  font:inherit; font-size:var(--field-font); font-weight:400; text-transform:none; letter-spacing:0;
}
:where(textarea) { min-height:72px; }
:where(select, textarea, input):where(:focus-visible) { outline:2px solid var(--accent); outline-offset:-1px; }

/* Drawings: the sort beside the filters, and the tag on a floor with no
   devices yet (feature 018, phase 6). */
.drawing-sort { display:inline-flex; align-items:center; gap:6px; color:var(--muted); font-size:12.5px; }
.drawing-sort select { min-height:34px; padding:5px 8px; }
.chip.neutral { background:var(--card2); color:var(--muted); border:1px solid var(--line2); }
.drawing-card:has(.drawing-blank-chip) .drawing-thumb { opacity:.55; }

/* Areas: the worked-out build stage, and the sort beside the filters
   (feature 018, phase 6). Quiet tones: the engineer's state is the loud one. */
.areas-sort-select { display:inline-flex; align-items:center; gap:6px; color:var(--muted); font-size:12.5px; }
.areas-sort-select select { min-height:40px; }
.areas-hide-done { white-space:nowrap; }
.area-build-pill { display:inline-block; padding:2px 9px; border-radius:999px; font-size:12px; white-space:nowrap;
  border:1px solid var(--line2); color:var(--ink2); background:var(--card2); }
.area-build-pill[data-build="dropped"] { border-color:color-mix(in srgb, #3b82f6 45%, var(--line2)); }
.area-build-pill[data-build="partly"] { border-color:color-mix(in srgb, #d18b00 55%, var(--line2)); }
.area-build-pill[data-build="addressed"] { border-color:color-mix(in srgb, #6c972a 60%, var(--line2)); color:var(--ink); }
.areas-floor-build { font-size:12.5px; color:var(--ink2); }
.area-build-count { white-space:nowrap; margin-right:8px; }
.area-build-count b { color:var(--ink); }
/* With the Build column the tables must still fit the page: headings wrap
   onto two lines, the floor bar gives up width first, and the build counts
   stack one under another. */
.areas-floor-table thead th, .areas-table thead th { white-space:normal; vertical-align:bottom; }
.areas-floor-table:has(.areas-floor-build) .areas-floor-bar { width:18%; min-width:90px; }
.areas-floor-build .area-build-count { display:block; margin:0; }

/* The room checklist (feature 018, phase 6, experimental). */
.room-checklist .section-heading { display:flex; justify-content:space-between; align-items:end; gap:12px; flex-wrap:wrap; }
.room-checklist-toolbar { display:flex; flex-wrap:wrap; align-items:center; gap:8px; margin:8px 0; }
.room-checklist-toolbar .filter-search { width:240px; }
.room-floor { margin-top:14px; }
.room-floor-head { display:flex; align-items:center; gap:12px; flex-wrap:wrap; padding:6px 0; border-bottom:1px solid var(--line); }
.room-floor-head h3 { margin:0; font-size:14px; }
.room-floor-head .ghost-btn { margin-left:auto; }
.room-list { list-style:none; margin:0; padding:0; }
.room-row { display:grid; grid-template-columns:22px minmax(0,1fr) auto auto; align-items:center; gap:10px;
  padding:3px 4px; border-bottom:1px solid var(--line); font-size:13.5px; }
.room-row[data-room-status="ignored"] .room-name, .room-row[data-room-status="not_ours"] .room-name { color:var(--muted); }
.room-row input[type=checkbox] { width:16px; height:16px; margin:0; }
.room-name { overflow-wrap:anywhere; }
.room-actions { display:flex; gap:6px; }
.room-actions .ghost-btn { min-height:28px; padding:3px 10px; font-size:12.5px; }
.room-chip { display:inline-block; padding:2px 9px; border-radius:999px; font-size:12px; white-space:nowrap;
  border:1px solid var(--line2); background:var(--card2); color:var(--ink2); }
button.room-chip { cursor:pointer; min-height:0; font:inherit; font-size:12px; }
.room-chip.is-mapped { border-color:color-mix(in srgb, #6c972a 60%, var(--line2)); color:var(--ink); }
.room-chip.is-open { border-color:color-mix(in srgb, #d18b00 55%, var(--line2)); }
.area-names-checklist { margin-top:12px; }
@media (max-width:640px) {
  .room-row { grid-template-columns:22px minmax(0,1fr) auto; }
  .room-actions { grid-column:2 / -1; }
}
/* A part of the floor that is not Delmatic's: grey hatching under the areas. */
#drawing-area-layer polygon.drawing-not-ours { fill:rgba(120,120,120,.18);
  stroke:rgba(120,120,120,.8); stroke-dasharray:6 4; }
/* Names from drawings: layer names, counts and examples read as written. The
   dialog rule upper-cases every label, which turned the drawing's own text
   into capitals it never had. */
.area-names-dlg .area-name-layer, .area-names-dlg .area-name-layer small,
.area-names-dlg .area-name-layer-examples span, .area-names-dlg .area-names-checklist,
.area-names-dlg .area-names-checklist small { text-transform:none; letter-spacing:0; }
.area-names-dlg .area-name-layer b { font-weight:650; color:var(--ink); font-size:13px; }
.area-names-dlg .area-name-layer input { width:auto; margin:2px 0 0; }
.area-names-dlg .area-names-checklist { display:grid; grid-template-columns:auto minmax(0,1fr); gap:10px; align-items:start;
  font-size:13.5px; font-weight:500; color:var(--ink); }
.area-names-dlg .area-names-checklist input { width:auto; margin:3px 0 0; }
.area-names-dlg .area-names-checklist small { color:var(--muted); font-size:12.5px; font-weight:400; }

/* Imports: the history reads as a table. Five places in every row; the file
   name wraps if anything does, and the action always sits at the right. */
#page-snapshot .snapshot-history-row {
  grid-template-columns:minmax(0,2fr) minmax(96px,.8fr) minmax(0,1.5fr) minmax(0,1.1fr) minmax(104px,auto);
}
.snapshot-history-file { min-width:0; overflow-wrap:anywhere; }
.snapshot-history-state, .snapshot-history-drawings { min-width:0; }
.snapshot-history-row .chip { white-space:normal; }
.snapshot-history-action { justify-self:end; display:flex; justify-content:flex-end; }
.snapshot-history-action .ghost-btn { min-width:96px; }
.snapshot-history-action .snapshot-open-above { max-width:240px; text-align:right; }
@media (max-width:700px) {
  #page-snapshot .snapshot-history-row { grid-template-columns:1fr; }
  .snapshot-history-action { justify-self:start; }
}
/* A database the project has never had: said plainly, confirmed by a tick. */
.snapshot-map-stranger { grid-column:1 / -1; padding:10px 12px; border-radius:8px;
  border:1px solid var(--chip-warn-ink, #d18b00); background:color-mix(in srgb, #d18b00 10%, var(--card2)); }
.snapshot-map-stranger p { margin:0 0 8px; font-size:13px; color:var(--ink); }
.snapshot-map-stranger .check-label { display:grid; grid-template-columns:auto minmax(0,1fr); gap:8px; align-items:start;
  font-size:13px; font-weight:600; text-transform:none; letter-spacing:0; color:var(--ink); }
.snapshot-map-stranger input { width:auto; margin:2px 0 0; }
.snapshot-map-stranger[hidden] { display:none; }
/* The mapping rows place every input in their second column; the tick box in
   the warning stays beside its own words. */
.snapshot-map .snapshot-map-stranger input.snapshot-map-confirm { grid-column:auto; width:auto; min-height:0; padding:0; }
/* The open list of a drop-down. A drop-down with a see-through background
   (the project picker) left the browser to draw its list on white, with the
   theme's pale text on it: unreadable in the dark and Delmatic themes. Every
   list now takes the theme's own card and ink. */
select option, select optgroup { background-color:var(--card); color:var(--ink); }
select option:disabled { color:var(--muted); }

/* The project menu: the app's own list in place of the native drop-down. */
.project-context { position:relative; }
.project-context select.proj-pill.has-menu {
  position:absolute; width:1px; height:1px; margin:0; opacity:0; pointer-events:none; overflow:hidden;
}
.project-menu-button {
  display:inline-flex; align-items:center; gap:6px; min-width:0; max-width:230px; min-height:0;
  padding:2px 4px; margin:-2px -4px; border:0; border-radius:6px; background:transparent;
  color:var(--ink); font:600 13.5px/1.25 'Public Sans', sans-serif; cursor:pointer;
}
.project-menu-button:hover { background:color-mix(in srgb, var(--ink) 8%, transparent); }
.project-menu-button:focus-visible { outline:2px solid var(--accent); outline-offset:2px; }
.project-menu-button:disabled { cursor:not-allowed; opacity:.6; }
.project-menu-button[hidden] { display:none; }
#project-menu-name { min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.project-menu-chevron { width:14px; height:14px; flex:none; color:var(--muted); transition:transform .15s ease; }
.project-menu-button[aria-expanded="true"] .project-menu-chevron { transform:rotate(180deg); }
.project-menu {
  position:absolute; z-index:120; top:calc(100% + 6px); left:0; min-width:260px; max-width:min(360px, 92vw);
  padding:6px; border:1px solid var(--line2); border-radius:10px; background:var(--card);
  box-shadow:0 10px 30px rgba(0,0,0,.28);
}
.project-menu[hidden] { display:none; }
.project-menu-search { margin-bottom:6px; }
.project-menu-search[hidden] { display:none; }
.project-menu-search .filter-search { width:100%; }
.project-menu-list { list-style:none; margin:0; padding:0; max-height:min(60vh, 420px); overflow:auto; }
.project-menu-item {
  display:flex; align-items:center; justify-content:space-between; gap:10px; width:100%;
  min-height:36px; padding:7px 10px; border:0; border-radius:7px; background:transparent;
  color:var(--ink); font:inherit; font-size:13.5px; text-align:left; cursor:pointer;
}
.project-menu-item:hover, .project-menu-item:focus-visible { background:var(--card2); outline:none; }
.project-menu-item.is-current { font-weight:650; }
.project-menu-item svg { width:15px; height:15px; flex:none; color:var(--accent); }
.project-menu-empty { padding:8px 10px; color:var(--muted); font-size:13px; }

/* ── Pre-commissioning checks (feature 019) ─────────────────────────────────
   A list of module cards, grouped by floor, that works on a phone: the
   contractor declares with two taps, so the choices are full-size buttons. */
.precom-legend .chip { pointer-events:none; }
.precom-toolbar { display:flex; flex-wrap:wrap; gap:8px 12px; align-items:center; }
.precom-list { display:grid; gap:18px; margin-top:12px; }
.precom-floor h3 { margin:0 0 8px; font-size:14px; color:var(--ink2); }
.precom-floor { display:grid; gap:8px; }
.precom-row {
  display:grid; gap:4px; padding:12px 14px; border:1px solid var(--line2); border-radius:10px;
  background:var(--card); border-left-width:4px;
}
.precom-row.precom-ready { border-left-color:var(--chip-pass-ink, var(--accent)); }
.precom-row.precom-waiting { border-left-color:var(--chip-warn-ink, var(--line2)); }
.precom-row.precom-not_ready { border-left-color:var(--chip-fail-ink, var(--fail)); }
.precom-row.precom-addressed { border-left-color:var(--chip-info-ink, var(--info)); }
.precom-row-head { display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:6px 12px; }
.precom-row-name {
  padding:0; border:0; background:none; color:var(--ink); font:inherit; font-size:15px; font-weight:700;
  text-align:left; cursor:pointer; min-height:0;
}
.precom-row-name:hover { text-decoration:underline; }
.precom-row p { margin:0; font-size:13px; color:var(--ink2); }
.precom-row-facts { display:flex; flex-wrap:wrap; align-items:center; gap:6px; }
.precom-row-decl { color:var(--ink) !important; }
.precom-row-pending, .precom-row-snags { font-weight:600; }
.precom-row-snags { color:var(--chip-fail-ink, var(--fail)) !important; }
.precom-row-actions { display:flex; flex-wrap:wrap; gap:8px; margin-top:6px; }
.precom-choice { flex:1 1 120px; min-height:44px; }
.precom-choice-not_ready { background:var(--card); color:var(--ink); border:1px solid var(--line2); }
.precom-statement {
  margin:10px 0 0; padding:10px 12px; border-left:3px solid var(--accent); background:var(--card2);
  border-radius:0 8px 8px 0; font-size:13.5px; color:var(--ink);
}
.precom-floor-note { margin-top:14px; }
.precom-add-file { display:flex; flex-wrap:wrap; align-items:center; gap:8px 16px; margin-top:10px; }
.precom-print-dates { display:grid; grid-template-columns:1fr 1fr; gap:10px; }
.precom-history, .precom-module-snags { list-style:none; margin:6px 0 14px; padding:0; display:grid; gap:10px; }
.precom-history li, .precom-module-snags li { padding:8px 0; border-top:1px solid var(--line); }
.precom-history li:first-child, .precom-module-snags li:first-child { border-top:0; }
.precom-history small, .precom-module-snags small { display:block; color:var(--muted); }
.precom-link { display:flex; flex-wrap:wrap; align-items:end; gap:8px; }
.snag-precom { margin-top:10px; display:grid; gap:6px; }
.precom-snag-module { display:grid; gap:4px; font-size:13px; font-weight:600; color:var(--ink2); }
.precom-snag-line { margin:0; padding:8px 10px; border-radius:8px; background:var(--card2); font-size:13px; color:var(--ink); }
.precom-snag-counted { background:var(--chip-fail-bg); color:var(--chip-fail-ink); }
.precom-snag-check { background:var(--chip-warn-bg); color:var(--chip-warn-ink); }
.precom-snag-exceptions { margin:0; font-size:13px; color:var(--ink2); }
.precom-snag-actions { display:flex; flex-wrap:wrap; gap:8px; }
.snapshot-precom-line { margin-top:10px; }
@media (max-width:600px) {
  .precom-row { padding:12px; }
  .precom-print-dates { grid-template-columns:1fr; }
}

/* The printed record. */
.precom-record { max-width:900px; margin:0 auto; padding:24px; color:#111; font-size:12.5px; }
.precom-record h1 { margin:2px 0 4px; font-size:22px; }
.precom-record h2 { margin:22px 0 8px; font-size:15px; }
.precom-record-figure { font-size:20px; font-weight:700; margin:12px 0 4px; }
.precom-record-table { width:100%; border-collapse:collapse; }
.precom-record-table th, .precom-record-table td { text-align:left; vertical-align:top; padding:6px 8px; border-bottom:1px solid #ccc; }
.precom-record-table hr { border:0; border-top:1px dashed #bbb; margin:6px 0; }
.precom-record-foot { margin-top:22px; color:#555; font-size:11px; }

/* One focus ring per field. A search box is a rounded frame with the text box
   inside it; the frame shows the ring. The site-wide focus rule also ringed
   the text box itself, which drew a second, square ring inside the first. */
.filter-search input:focus-visible,
.workspace-search-field input:focus-visible { outline:none !important; }
.workspace-search-field:focus-within { outline:2px solid var(--accent); outline-offset:-1px; }

/* Outstanding work: every row has the same columns, so the state and the
   Functional and Duration results line up down the list. Each row used to
   size its own middle column, and the results drifted with it. */
@media (min-width:1051px) {
  .emergency-work-row { grid-template-columns:minmax(0,1.3fr) 220px minmax(0,1fr); }
  .emergency-work-row.is-selecting { grid-template-columns:auto minmax(0,1.3fr) 220px minmax(0,1fr); }
  .emergency-work-row dl { display:grid; grid-template-columns:repeat(2, minmax(0,1fr)); justify-content:stretch; }
  .emergency-work-row dl div { min-width:0; }
}

/* A search field is always one line: icon, then the text box. Filter rows
   that lay their labels out as a stack (caption above the field) stacked the
   search field too, which put the icon on a line of its own. In such a row the
   search field sits on the same baseline as the drop-downs beside it. */
label.filter-search { display:flex; align-items:center; gap:7px; }
.emergency-work-filters .filter-search { align-self:end; min-height:var(--field-height, 38px); font-size:inherit; color:var(--muted); }
.emergency-work-filters .filter-search input[type="search"] { min-height:calc(var(--field-height, 38px) - 2px); }

/* Opening a page moves focus to its heading, so a screen reader announces
   the new page. The heading is not something to press, so it shows no focus
   box: the browser's default white box appeared until the next click. The
   same holds for a page or panel that takes focus for the same reason. */
:is(h1, h2, h3, main, section, aside, article)[tabindex="-1"]:focus { outline:none; }

/* The report audience switch fills its panel, so its two buttons share the
   width. They used to sit at the left and leave an empty strip inside the
   frame on the right. */
#report-audience button { flex:1 1 0; }

/* ── DALI zone drawings (feature 019, phase 2) ──────────────────────────────
   A viewer for a phone first: the whole screen, one finger to pan, two to
   pinch, and buttons big enough to tap. The sheet is drawn once at a fixed
   size and moved with a transform; names and marks ride on it and are scaled
   back so they stay readable at any zoom. */
.zone-list { display:grid; gap:8px; margin-top:12px; }
.zone-item {
  display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:8px 16px;
  padding:12px 14px; border:1px solid var(--line2); border-radius:10px; background:var(--card);
}
.zone-item small { display:block; color:var(--muted); margin-top:2px; }
.zone-item-actions { display:flex; gap:8px; }
.zone-upload-rows { display:grid; gap:4px; }
.zone-viewer-dlg {
  box-sizing:border-box; width:100vw; max-width:100vw; height:100dvh; max-height:100dvh; margin:0;
  padding:0; border:0; border-radius:0; display:flex; flex-direction:column; background:var(--page);
}
.zone-viewer-dlg:not([open]) { display:none; }
.zone-viewer-head {
  display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:8px 16px;
  padding:10px 16px; border-bottom:1px solid var(--line);
}
.zone-viewer-name h2 { margin:0; font-size:17px; }
.zone-viewer-name .eyebrow { margin:0; }
.zone-viewer-tools { display:flex; flex-wrap:wrap; gap:6px; }
.zone-viewer-tools button { min-height:40px; min-width:40px; }
.zone-viewer-tools [aria-pressed="true"] { background:var(--accent); color:var(--btn-ink, #10210a); border-color:var(--accent); }
.zone-viewer-status { margin:0; padding:0 16px; min-height:0; }
.zone-viewer-status:empty { display:none; }
.zone-stage {
  position:relative; flex:1 1 auto; overflow:hidden; touch-action:none; background:#e9e9e9;
  cursor:grab; user-select:none;
}
.zone-sheet { position:absolute; left:0; top:0; transform-origin:0 0; --zone-inverse:1; }
.zone-sheet canvas { display:block; width:100%; height:100%; background:#fff; }
.zone-overlay { position:absolute; inset:0; pointer-events:none; }
.zone-chip, .zone-mark {
  position:absolute; pointer-events:auto; transform:translate(-50%, -50%) scale(var(--zone-inverse));
  transform-origin:center; white-space:nowrap; cursor:pointer;
}
.zone-chip {
  padding:3px 8px; min-height:0; border-radius:999px; border:1.5px solid currentColor;
  font:600 12px/1.2 'Public Sans', sans-serif; background:#fff;
}
.zone-chip.tone-pass { color:#3d5a10; background:#eef6dd; }
.zone-chip.tone-warn { color:#7a4e0c; background:#fdf0d2; }
.zone-chip.tone-fail { color:#a92f2f; background:#f9e7e5; }
.zone-chip.tone-info { color:#1d4f91; background:#e4eefb; }
.zone-chip.tone-na { color:#666; background:#f1f1f1; border-style:dashed; }
.zone-mark {
  width:26px; height:26px; min-height:0; padding:0; border-radius:50%; border:2px solid #fff;
  font:700 16px/22px 'Public Sans', sans-serif; text-align:center; color:#fff; box-shadow:0 1px 4px rgba(0,0,0,.35);
}
.zone-mark-not_working { background:#c22429; }
.zone-mark-not_installed { background:#a76800; }
.zone-mark-pending { background:var(--accent); color:#10210a; pointer-events:none; }
.zone-panel {
  position:absolute; left:50%; bottom:16px; transform:translateX(-50%); width:min(520px, calc(100vw - 32px));
  box-sizing:border-box; padding:14px 16px; border:1px solid var(--line2); border-radius:12px;
  background:var(--card); box-shadow:0 12px 34px rgba(0,0,0,.3); display:grid; gap:8px;
}
.zone-panel[hidden] { display:none; }
.zone-panel p { margin:0; }
.zone-panel-title { display:flex; flex-wrap:wrap; align-items:center; gap:8px; font-size:15px; }
.zone-panel-actions { display:flex; flex-wrap:wrap; gap:8px; }
.zone-panel-actions button { flex:1 1 110px; min-height:44px; }
.zone-kind [aria-pressed="true"] { background:var(--accent); color:var(--btn-ink, #10210a); border-color:var(--accent); }
@media (max-width:600px) {
  .zone-viewer-head { padding:8px 12px; }
  .zone-viewer-tools { width:100%; }
  .zone-viewer-tools button { flex:1 1 auto; }
}
.zone-icon-btn svg { width:18px; height:18px; fill:none; stroke:currentColor; stroke-width:1.6; stroke-linecap:round; }

/* Redlines on a DALI zone drawing (feature 019, phase 3). The layer is the
   sheet's size and moves with it; the stroke keeps its width at any zoom. */
.zone-lines { position:absolute; inset:0; width:100%; height:100%; pointer-events:none; overflow:visible; }
/* The same 22 % shade as a snag area, so a redline stands out the same way;
   a rejected one is lighter, so old answers fall back. */
.zone-redline {
  fill:rgba(194,36,41,.22); stroke:#c22429; stroke-width:3; stroke-dasharray:10 6;
  vector-effect:non-scaling-stroke; pointer-events:visiblePainted; cursor:pointer;
}
.zone-redline-accepted { fill:rgba(61,90,16,.22); stroke:#3d5a10; stroke-dasharray:none; }
.zone-redline-rejected { fill:rgba(120,120,120,.10); stroke:#777; }
.zone-sketch { fill:rgba(194,36,41,.08); stroke:#c22429; stroke-width:3; vector-effect:non-scaling-stroke; }
.zone-sketch-corner { fill:#fff; stroke:#c22429; stroke-width:2; vector-effect:non-scaling-stroke; }
.zone-decide { display:grid; gap:6px; margin:0; padding:8px 10px; border:1px solid var(--line2); border-radius:8px; }
.zone-decide legend { font-size:12px; font-weight:650; color:var(--ink2); padding:0 4px; }
.zone-decide label { display:flex; align-items:center; gap:8px; font-size:13.5px; }
.zone-redline-status { font-weight:650; }
.zone-redline-status-open { color:var(--chip-warn-ink); }
.zone-redline-status-accepted { color:var(--chip-pass-ink); }
.zone-redline-status-rejected { color:var(--muted); }
.zone-waiting { color:var(--chip-warn-ink); }
/* The viewer's panel is a sheet of controls, not a form: its labels read as
   sentences, as on the module cards, not as the capitalised captions dialogs
   give their form fields. */
.zone-panel label, .zone-panel .area-field, .zone-panel .area-field-hint {
  text-transform:none; letter-spacing:normal; font-size:13.5px;
}
.zone-panel .area-field-hint, .zone-panel label small { color:var(--muted); font-weight:400; }
.zone-decide label { margin:0; }

/* The module map (feature 020): each luminaire a dot in its module's colour,
   ringed in white so it reads on the drawing's linework; an emergency driver
   has a white centre. Module names are white labels edged in the colour. */
.map-dot { stroke:#fff; stroke-width:1.5; vector-effect:non-scaling-stroke; pointer-events:none; }
.map-dot-em { fill:#fff; pointer-events:none; }
.zone-chip.map-label { color:#111; background:#fff; border:2px solid var(--map-colour); border-style:solid; }
.map-swatch { display:inline-block; width:14px; height:14px; border-radius:50%; background:var(--map-colour); flex:none; }

/* The DALI zone viewer's pointer: the hand to drag the sheet, the grabbing
   hand while dragging, and the ordinary arrow while a mark or a zone is being
   placed, as when a snag is placed on a progress drawing. */
.zone-stage.is-placing { cursor:default; }
.zone-stage.is-panning { cursor:grabbing; }

/* Pre-commissioning tabs: the Drawings tabs, with a count after each name. */
.precom-tabs { margin:4px 0 2px; padding:0; }
.precom-tabs button b { margin-left:4px; font-variant-numeric:tabular-nums; color:var(--ink2); }
.precom-tabs button b:empty { display:none; }
.precom-tabs button.on b { color:var(--accent-ink, var(--accent)); }
.precom-panel { display:grid; gap:var(--workspace-gap, 16px); }
.precom-panel[hidden] { display:none; }

/* A redline's balloon: its number and module in the middle of the zone, in
   the colour of its answer. A waiting one has a ring that pulses; with reduced
   motion the ring stays still. */
.zone-chip.redline-balloon {
  display:inline-flex; align-items:center; gap:6px; padding:3px 10px 3px 3px;
  border:2px solid #c22429; background:#fff; color:#111; font-weight:650;
  box-shadow:0 2px 8px rgba(0,0,0,.25);
}
.redline-ref {
  display:inline-grid; place-items:center; min-width:24px; height:22px; padding:0 4px; border-radius:999px;
  background:#c22429; color:#fff; font-size:11.5px; font-weight:750; letter-spacing:.02em;
}
.redline-balloon-accepted { border-color:#3d5a10; }
.redline-balloon-accepted .redline-ref { background:#3d5a10; }
.redline-balloon-rejected { border-color:#888; color:#555; }
.redline-balloon-rejected .redline-ref { background:#888; }
.redline-balloon-open::after {
  content:""; position:absolute; inset:-6px; border-radius:999px; border:3px solid rgba(194,36,41,.55);
  animation:redline-pulse 1.8s ease-out infinite; pointer-events:none;
}
@keyframes redline-pulse {
  0% { transform:scale(.92); opacity:.9; }
  70% { transform:scale(1.18); opacity:0; }
  100% { transform:scale(1.18); opacity:0; }
}
@media (prefers-reduced-motion: reduce) {
  .redline-balloon-open::after { animation:none; opacity:.8; transform:none; }
}
