/* ============================================================
   CALDWELL COUNTY ELECTIONS MANAGEMENT — county navy & gold
   design system. Cool paper neutrals · county-navy accent
   (#16294D) · gold highlights. Adapted from the projects-app
   foundation; every token + utility class name is unchanged.
   ============================================================ */

:root {
  color-scheme: light;
  /* ground + surfaces */
  --bg: #f4f5f7;
  --surface: #ffffff;
  --surface-2: #eceef2;      /* inset wells, kanban columns */
  --surface-3: #f2f4f7;      /* hover wash */
  --sidebar: #eef0f4;
  /* ink */
  --ink: #1a2233;
  /* --ink-2/--ink-3 carry real (normal-size) text — counts, captions, stat
     labels, meta rows — mostly at 10.5-12px. They are held well ABOVE the WCAG
     AA 4.5:1 floor on purpose: AA is a minimum for body copy, and at this size
     a bare-minimum ratio reads visibly washed out. Ratios below are measured on
     the DARKEST surface either lands on, --surface-2 (#eceef2), not just white.
     Keep --ink > --ink-2 > --ink-3 in darkness so hierarchy still reads.
     (Was #4d5a70 / #5d6880 — 6.00:1 and 4.81:1, too pale in practice.) */
  --ink-2: #414d61;   /* 7.35:1 on --surface-2, 8.54:1 on white */
  --ink-3: #4b5669;   /* 6.38:1 on --surface-2, 7.41:1 on white */
  /* hairlines */
  --line: #e2e6ec;
  --line-2: #c9d0dc;
  /* county-navy accent */
  --accent: #16294D;
  --accent-hover: #0E1B33;
  --accent-ink: #ffffff;
  --accent-wash: #e8edf6;
  --accent-wash-line: #c6d2e6;
  --accent-soft: #1e3b6d;    /* accent-toned text on wash */
  --focus-ring: #35578f;
  /* county gold — stars & highlights only; gold TEXT on light surfaces uses --gold-deep */
  --gold: #D4AA28;
  /* Gold ink was #816614 — 4.47:1 on --gold-tint, i.e. under AA on the very
     chip it exists for. Darkened to clear it with room to spare. */
  --gold-deep: #6b540f;  /* 5.93:1 on --gold-tint, 7.24:1 on white */
  /* --gold-ink: alias of --gold-deep. Several view stylesheets reference
     var(--gold-ink, #6b540f); leaving it undefined pinned them to the LIGHT gold in
     dark mode (3.09:1). Defined in EVERY theme block so the themes cannot drift. */
  --gold-ink: #6b540f;
  --gold-tint: #F4E8C4;
  /* Semantic ink — each fg measured on its OWN wash (the badge/tile background
     it is made for), which is always the tightest pairing, and likewise held
     above the bare AA floor because these render at 11.5px on badges.
     (Was #167a37 / #8a6410 / #bf3535 / #5a49c0 — all 4.6-4.8:1 on their wash.) */
  --good: #12692f;      --good-wash: #e3f2e6;   --good-wash-line: #bfe0c6;   /* 5.87:1 on wash */
  --warn: #7a570b;      --warn-wash: #faf0d2;   --warn-wash-line: #ecd99c;   /* 5.78:1 on wash */
  --danger: #b02b2b;    --danger-wash: #fbe5e3; --danger-wash-line: #f0c1bc; /* 5.40:1 on wash */
  --violet: #4c3bb0;    --violet-wash: #ecebfb; --violet-wash-line: #d3cff2; /* 6.97:1 on wash */
  /* chart chrome (dataviz) */
  --chart-grid: #e6e9ef;
  --chart-axis: #ccd3de;
  /* ── Navigation chrome: SLATE in light mode ───────────────────────────────
     The side menu and the top bar are one continuous slate plane in light mode,
     and graphite in dark (see the dark blocks). Slate rather than the county
     navy #16294D on purpose: a saturated navy slab next to a near-white content
     area reads as a heavy blue wall, which is why the navy ground was dropped
     in the first place. Slate is the same idea desaturated — it recedes, and it
     lets the gold carry the county identity.
     Every ink below was measured against the LIGHTEST gradient stop (#323d4a),
     not against the darkest, because the top of the sidebar is where the brand
     cap and the search field sit: nav items 7.8:1, brand cap 6.0:1, muted
     5.3:1, gold 5.0:1. Held well above the 4.5 floor deliberately — at 11px a
     bare-minimum ratio reads washed out. */
  --nav-1: #323d4a; --nav-2: #2b3543; --nav-3: #232c38;
  --nav-ink: #D2DAE6;      /* nav items, primary label */
  --nav-ink-2: #B4C0D4;    /* brand cap, search field */
  --nav-ink-3: #AAB4C4;    /* muted: role, group headings, icon buttons */
  --nav-line: rgba(255, 255, 255, 0.09);
  --nav-hover: rgba(255, 255, 255, 0.07);
  --topbar-bg: #323d4a;
  --topbar-ink: #F2F5FA;
  --topbar-ink-2: #B7C2D2;
  --topbar-line: rgba(255, 255, 255, 0.10);
  --topbar-hover: rgba(255, 255, 255, 0.09);
  --ramp-1: #9db4dc; --ramp-2: #6f8fc5; --ramp-3: #4569a8; --ramp-4: #2c4a82; --ramp-5: #16294D;
  /* ── Data-visualisation palette (web/charts.js) ────────────────────────────
     Eight categorical slots, assigned in FIXED ORDER and never cycled: a ninth
     series folds into "Other" or becomes small multiples. The order itself is
     the colour-blindness safety mechanism — adjacent pairs are what a stacked
     bar and a legend put side by side — and it was validated against THIS
     product's surfaces (#ffffff light, #1b1c1f dark), not a reference one.
     Both modes clear the lightness band, the chroma floor, adjacent CVD
     separation (worst dE 9.1 light / 8.4 dark) and the normal-vision floor
     (19.6 / 19.3).
     On the LIGHT surface slots 3, 4 and 5 measure below 3:1 (2.82 / 2.17 /
     2.69). That is a measured, accepted trade: they are legible as MARKS, and
     every chart ships a legend plus a data table, which is the documented
     relief. It is also why nothing in this product ever colours TEXT with a
     series hue. */
  --series-1: #2a78d6;  /* blue    */
  --series-2: #eb6834;  /* orange  */
  --series-3: #1baf7a;  /* aqua    */
  --series-4: #eda100;  /* yellow  */
  --series-5: #e87ba4;  /* magenta */
  --series-6: #008300;  /* green   */
  --series-7: #4a3aa7;  /* violet  */
  --series-8: #e34948;  /* red     */
  /* Sequential — ONE hue, light to dark, for continuous magnitude (heat maps).
     Never a rainbow: a hue sequence encodes an order the eye cannot read back. */
  --seq-100: #cde2fb; --seq-200: #9ec5f4; --seq-300: #6da7ec;
  --seq-450: #2a78d6; --seq-550: #1c5cab; --seq-650: #104281;
  /* Diverging — two poles and a NEUTRAL grey midpoint, for values that can run
     either side of zero (over/under allocation, budget variance). */
  --div-neg-1: #f6d3d1; --div-neg-2: #eba09c; --div-neg-3: #d9605c; --div-neg-4: #b02b2b;
  --div-mid: #f0efec;
  --div-pos-1: #cde2fb; --div-pos-2: #9ec5f4; --div-pos-3: #5598e7; --div-pos-4: #256abf;
  --stat-good: #0ca30c; --stat-warn: #fab219; --stat-serious: #ec835a; --stat-crit: #d03b3b;
  /* elevation */
  --shadow-pop: 0 6px 24px rgba(18, 28, 52, 0.14), 0 1px 3px rgba(18, 28, 52, 0.10);
  --shadow-modal: 0 24px 64px rgba(18, 28, 52, 0.22), 0 4px 12px rgba(18, 28, 52, 0.10);
  --shadow-card-drag: 0 12px 28px rgba(18, 28, 52, 0.18);
  /* type */
  --font-display: "Avenir Next", "Segoe UI Variable Display", -apple-system, system-ui, sans-serif;
  --font-body: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  --font-mono: ui-monospace, "SF Mono", "Cascadia Code", Menlo, Consolas, monospace;
  /* radii — flat civic planes: modest rounding */
  --r-s: 4px; --r-m: 6px; --r-l: 10px;
}

@media (prefers-color-scheme: dark) {
  :root:where(:not([data-theme="light"])) {
    color-scheme: dark;
    /* graphite ground — neutral charcoal (was county-navy dark); each token keeps
       its original lightness so the tuned contrast ratios below still hold. */
    --bg: #121316;
    --surface: #1b1c1f;
    --surface-2: #161719;
    --surface-3: #232428;
    --sidebar: #151619;
    --ink: #e8ecf4;
    --ink-2: #a3aec4;
    /* The lightest dark background is NOT --surface-3 (#232428) — it is the
       toned washes (--good-wash #16301c, --warn-wash #33290f), where the old
       #838fa9 fell to 4.39:1 and missed AA on the gauge hints that sit on them.
       #919cb4 clears every dark background (5.17:1 worst case, on --good-wash)
       and stays clearly lighter-than-ink-2 so the hierarchy still reads. */
    --ink-3: #919cb4;
    --line: #2c2d32;
    --line-2: #40424a;
    --accent: #6d9ae8;
    --accent-hover: #86acf0;
    --accent-ink: #0a1526;
    --accent-wash: #282c34;
    --accent-wash-line: #3a3f4a;
    --accent-soft: #8fb4f2;
    --focus-ring: #6d9ae8;
    --gold: #E7C55E;
    --gold-deep: #E7C55E;
    --gold-ink: #E7C55E;   /* must track --gold-deep in every theme block */
    --gold-tint: #38300f;
    --good: #55c46c;      --good-wash: #16301c;   --good-wash-line: #285534;
    --warn: #e3ad42;      --warn-wash: #33290f;   --warn-wash-line: #5c4a1e;
    --danger: #e87b71;    --danger-wash: #3a1d1c; --danger-wash-line: #63332f;
    --violet: #ab9ff2;    --violet-wash: #272144; --violet-wash-line: #423a6e;
    --chart-grid: #232c3d;
    --chart-axis: #38445a;
  /* Navigation chrome: GRAPHITE in dark mode, unchanged. The top bar keeps the
     surface colour here rather than taking a distinct plane — on a dark ground
     the sidebar and the content area are already close enough that a third
     shade would read as banding rather than as structure. */
  --nav-1: #1e1f23; --nav-2: #191a1d; --nav-3: #141518;
  --nav-ink: #CBD3E1;
  --nav-ink-2: #9FACC6;
  --nav-ink-3: #9aa0ac;
  --nav-line: rgba(255, 255, 255, 0.08);
  --nav-hover: rgba(255, 255, 255, 0.06);
  --topbar-bg: #1b1c1f;
  --topbar-ink: #e8ecf4;
  --topbar-ink-2: #a3aec4;
  --topbar-line: #2c2d32;
  --topbar-hover: #232428;
    --ramp-1: #cfdcf3; --ramp-2: #9db4dc; --ramp-3: #6f8fc5; --ramp-4: #40639f; --ramp-5: #2a4a80;
  /* The same eight hues, stepped for the dark surface — a selected dark
     palette, not an automatic flip. All eight clear 3:1 on #1b1c1f. */
  --series-1: #3987e5;
  --series-2: #d95926;
  --series-3: #199e70;
  --series-4: #c98500;
  --series-5: #d55181;
  --series-6: #008300;
  --series-7: #9085e9;
  --series-8: #e66767;
  --seq-100: #17304f; --seq-200: #1c4576; --seq-300: #256abf;
  --seq-450: #3987e5; --seq-550: #6da7ec; --seq-650: #9ec5f4;
  --div-neg-1: #3a1d1c; --div-neg-2: #6b2f2c; --div-neg-3: #b8524c; --div-neg-4: #e87b71;
  --div-mid: #383835;
  --div-pos-1: #17304f; --div-pos-2: #1c4576; --div-pos-3: #3987e5; --div-pos-4: #86b6ef;
    --shadow-pop: 0 6px 24px rgba(0, 0, 0, 0.5), 0 1px 3px rgba(0, 0, 0, 0.4);
    --shadow-modal: 0 24px 64px rgba(0, 0, 0, 0.6), 0 4px 12px rgba(0, 0, 0, 0.4);
    --shadow-card-drag: 0 12px 28px rgba(0, 0, 0, 0.55);
  }
}
:root[data-theme="dark"] {
  color-scheme: dark;
  /* graphite ground — neutral charcoal (was county-navy dark); lightness preserved. */
  --bg: #121316;
  --surface: #1b1c1f;
  --surface-2: #161719;
  --surface-3: #232428;
  --sidebar: #151619;
  --ink: #e8ecf4;
  --ink-2: #a3aec4;
  --ink-3: #919cb4;   /* 5.17:1 worst case, on --good-wash (#16301c) */
  --line: #2c2d32;
  --line-2: #40424a;
  --accent: #6d9ae8;
  --accent-hover: #86acf0;
  --accent-ink: #0a1526;
  --accent-wash: #282c34;
  --accent-wash-line: #3a3f4a;
  --accent-soft: #8fb4f2;
  --focus-ring: #6d9ae8;
  --gold: #E7C55E;
  --gold-deep: #E7C55E;
  --gold-ink: #E7C55E;   /* must track --gold-deep in every theme block */
  --gold-tint: #38300f;
  --good: #55c46c;      --good-wash: #16301c;   --good-wash-line: #285534;
  --warn: #e3ad42;      --warn-wash: #33290f;   --warn-wash-line: #5c4a1e;
  --danger: #e87b71;    --danger-wash: #3a1d1c; --danger-wash-line: #63332f;
  --violet: #ab9ff2;    --violet-wash: #272144; --violet-wash-line: #423a6e;
  --chart-grid: #232c3d;
  --chart-axis: #38445a;
  /* Navigation chrome: GRAPHITE in dark mode, unchanged. The top bar keeps the
     surface colour here rather than taking a distinct plane — on a dark ground
     the sidebar and the content area are already close enough that a third
     shade would read as banding rather than as structure. */
  --nav-1: #1e1f23; --nav-2: #191a1d; --nav-3: #141518;
  --nav-ink: #CBD3E1;
  --nav-ink-2: #9FACC6;
  --nav-ink-3: #9aa0ac;
  --nav-line: rgba(255, 255, 255, 0.08);
  --nav-hover: rgba(255, 255, 255, 0.06);
  --topbar-bg: #1b1c1f;
  --topbar-ink: #e8ecf4;
  --topbar-ink-2: #a3aec4;
  --topbar-line: #2c2d32;
  --topbar-hover: #232428;
  --ramp-1: #cfdcf3; --ramp-2: #9db4dc; --ramp-3: #6f8fc5; --ramp-4: #40639f; --ramp-5: #2a4a80;
  /* The same eight hues, stepped for the dark surface — a selected dark
     palette, not an automatic flip. All eight clear 3:1 on #1b1c1f. */
  --series-1: #3987e5;
  --series-2: #d95926;
  --series-3: #199e70;
  --series-4: #c98500;
  --series-5: #d55181;
  --series-6: #008300;
  --series-7: #9085e9;
  --series-8: #e66767;
  --seq-100: #17304f; --seq-200: #1c4576; --seq-300: #256abf;
  --seq-450: #3987e5; --seq-550: #6da7ec; --seq-650: #9ec5f4;
  --div-neg-1: #3a1d1c; --div-neg-2: #6b2f2c; --div-neg-3: #b8524c; --div-neg-4: #e87b71;
  --div-mid: #383835;
  --div-pos-1: #17304f; --div-pos-2: #1c4576; --div-pos-3: #3987e5; --div-pos-4: #86b6ef;
  --shadow-pop: 0 6px 24px rgba(0, 0, 0, 0.5), 0 1px 3px rgba(0, 0, 0, 0.4);
  --shadow-modal: 0 24px 64px rgba(0, 0, 0, 0.6), 0 4px 12px rgba(0, 0, 0, 0.4);
  --shadow-card-drag: 0 12px 28px rgba(0, 0, 0, 0.55);
}
:root[data-theme="light"] {
  color-scheme: light;
  --bg: #f4f5f7;
  --surface: #ffffff;
  --surface-2: #eceef2;
  --surface-3: #f2f4f7;
  --sidebar: #eef0f4;
  --ink: #1a2233;
  /* Secondary/tertiary ink is deliberately well ABOVE the 4.5:1 AA floor. Most
     text wearing these tokens is 10.5-12px (stat labels, captions, hints, meta
     rows) and at that size a bare-minimum ratio reads washed out on a white
     surface — AA is a floor for body copy, not a target for small type. Values
     below are measured on --surface-2 (#eceef2), the darkest surface either
     lands on; on white they are higher still. Keep --ink darker than --ink-2
     darker than --ink-3 so the hierarchy survives. */
  --ink-2: #414d61;   /* 7.35:1 on --surface-2, 8.54:1 on white */
  --ink-3: #4b5669;   /* 6.38:1 on --surface-2, 7.41:1 on white */
  --line: #e2e6ec;
  --line-2: #c9d0dc;
  --accent: #16294D;
  --accent-hover: #0E1B33;
  --accent-ink: #ffffff;
  --accent-wash: #e8edf6;
  --accent-wash-line: #c6d2e6;
  --accent-soft: #1e3b6d;
  --focus-ring: #35578f;
  --gold: #D4AA28;
  /* Gold ink was 4.47:1 on --gold-tint — under AA on the very chip it is made
     for. Darkened to clear it with room to spare. */
  --gold-deep: #6b540f;  /* 5.93:1 on --gold-tint, 7.24:1 on white */
  --gold-ink: #6b540f;   /* must track --gold-deep in every theme block */
  --gold-tint: #F4E8C4;
  /* Semantic inks: each measured on its OWN wash (the badge/tile background it
     is made for), which is always the tightest pairing. */
  --good: #12692f;      --good-wash: #e3f2e6;   --good-wash-line: #bfe0c6;   /* 5.87:1 on wash */
  --warn: #7a570b;      --warn-wash: #faf0d2;   --warn-wash-line: #ecd99c;   /* 5.78:1 on wash */
  --danger: #b02b2b;    --danger-wash: #fbe5e3; --danger-wash-line: #f0c1bc; /* 5.40:1 on wash */
  --violet: #4c3bb0;    --violet-wash: #ecebfb; --violet-wash-line: #d3cff2; /* 6.97:1 on wash */
  --chart-grid: #e6e9ef;
  --chart-axis: #ccd3de;
  /* ── Navigation chrome: SLATE in light mode ───────────────────────────────
     The side menu and the top bar are one continuous slate plane in light mode,
     and graphite in dark (see the dark blocks). Slate rather than the county
     navy #16294D on purpose: a saturated navy slab next to a near-white content
     area reads as a heavy blue wall, which is why the navy ground was dropped
     in the first place. Slate is the same idea desaturated — it recedes, and it
     lets the gold carry the county identity.
     Every ink below was measured against the LIGHTEST gradient stop (#323d4a),
     not against the darkest, because the top of the sidebar is where the brand
     cap and the search field sit: nav items 7.8:1, brand cap 6.0:1, muted
     5.3:1, gold 5.0:1. Held well above the 4.5 floor deliberately — at 11px a
     bare-minimum ratio reads washed out. */
  --nav-1: #323d4a; --nav-2: #2b3543; --nav-3: #232c38;
  --nav-ink: #D2DAE6;      /* nav items, primary label */
  --nav-ink-2: #B4C0D4;    /* brand cap, search field */
  --nav-ink-3: #AAB4C4;    /* muted: role, group headings, icon buttons */
  --nav-line: rgba(255, 255, 255, 0.09);
  --nav-hover: rgba(255, 255, 255, 0.07);
  --topbar-bg: #323d4a;
  --topbar-ink: #F2F5FA;
  --topbar-ink-2: #B7C2D2;
  --topbar-line: rgba(255, 255, 255, 0.10);
  --topbar-hover: rgba(255, 255, 255, 0.09);
  --ramp-1: #9db4dc; --ramp-2: #6f8fc5; --ramp-3: #4569a8; --ramp-4: #2c4a82; --ramp-5: #16294D;
  /* ── Data-visualisation palette (web/charts.js) ────────────────────────────
     Eight categorical slots, assigned in FIXED ORDER and never cycled: a ninth
     series folds into "Other" or becomes small multiples. The order itself is
     the colour-blindness safety mechanism — adjacent pairs are what a stacked
     bar and a legend put side by side — and it was validated against THIS
     product's surfaces (#ffffff light, #1b1c1f dark), not a reference one.
     Both modes clear the lightness band, the chroma floor, adjacent CVD
     separation (worst dE 9.1 light / 8.4 dark) and the normal-vision floor
     (19.6 / 19.3).
     On the LIGHT surface slots 3, 4 and 5 measure below 3:1 (2.82 / 2.17 /
     2.69). That is a measured, accepted trade: they are legible as MARKS, and
     every chart ships a legend plus a data table, which is the documented
     relief. It is also why nothing in this product ever colours TEXT with a
     series hue. */
  --series-1: #2a78d6;  /* blue    */
  --series-2: #eb6834;  /* orange  */
  --series-3: #1baf7a;  /* aqua    */
  --series-4: #eda100;  /* yellow  */
  --series-5: #e87ba4;  /* magenta */
  --series-6: #008300;  /* green   */
  --series-7: #4a3aa7;  /* violet  */
  --series-8: #e34948;  /* red     */
  /* Sequential — ONE hue, light to dark, for continuous magnitude (heat maps).
     Never a rainbow: a hue sequence encodes an order the eye cannot read back. */
  --seq-100: #cde2fb; --seq-200: #9ec5f4; --seq-300: #6da7ec;
  --seq-450: #2a78d6; --seq-550: #1c5cab; --seq-650: #104281;
  /* Diverging — two poles and a NEUTRAL grey midpoint, for values that can run
     either side of zero (over/under allocation, budget variance). */
  --div-neg-1: #f6d3d1; --div-neg-2: #eba09c; --div-neg-3: #d9605c; --div-neg-4: #b02b2b;
  --div-mid: #f0efec;
  --div-pos-1: #cde2fb; --div-pos-2: #9ec5f4; --div-pos-3: #5598e7; --div-pos-4: #256abf;
  --shadow-pop: 0 6px 24px rgba(18, 28, 52, 0.14), 0 1px 3px rgba(18, 28, 52, 0.10);
  --shadow-modal: 0 24px 64px rgba(18, 28, 52, 0.22), 0 4px 12px rgba(18, 28, 52, 0.10);
  --shadow-card-drag: 0 12px 28px rgba(18, 28, 52, 0.18);
}

/* ---------- base ---------- */
* { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0;
  font-family: var(--font-body);
  font-size: 14px;
  line-height: 1.45;
  color: var(--ink);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  overflow: hidden;
}
h1, h2, h3, h4 { font-family: var(--font-display); margin: 0; text-wrap: balance; }
p { margin: 0; }
a { color: var(--accent-soft); text-decoration: none; }
a:hover { text-decoration: underline; }
button { font: inherit; color: inherit; }
::selection { background: var(--accent-wash-line); }

*:focus { outline: none; }
*:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 1px; border-radius: var(--r-s); }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}

/* scrollbars */
* { scrollbar-width: thin; scrollbar-color: var(--line-2) transparent; }
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-thumb { background: var(--line-2); border-radius: 6px; border: 3px solid transparent; background-clip: content-box; }
*::-webkit-scrollbar-track { background: transparent; }

/* ---------- app frame ---------- */
#app { display: flex; height: 100vh; }

#sidebar {
  width: 248px; flex: 0 0 248px;
  background: var(--sidebar);
  border-right: 1px solid var(--line);
  display: flex; flex-direction: column;
  transition: margin-left 0.22s ease;
}
#sidebar.collapsed { margin-left: -249px; }

.brand {
  display: flex; align-items: center; gap: 10px;
  padding: 14px 14px 12px;
}
.brand-mark { flex: 0 0 24px; width: 24px; height: 24px; }
.brand-name {
  font-family: var(--font-display); font-size: 17px; font-weight: 700; letter-spacing: 0.01em;
}
.brand-org { font-size: 10.5px; color: var(--ink-3); letter-spacing: 0.06em; text-transform: uppercase; margin-top: -2px; }

.side-search {
  margin: 2px 12px 10px; padding: 7px 10px;
  display: flex; align-items: center; gap: 8px;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-m);
  color: var(--ink-3); font-size: 13px; cursor: pointer; width: calc(100% - 24px);
  text-align: left;
}
.side-search:hover { border-color: var(--line-2); color: var(--ink-2); }
.side-search kbd {
  margin-left: auto; font-family: var(--font-body); font-size: 10.5px;
  border: 1px solid var(--line-2); border-radius: 4px; padding: 1px 5px; color: var(--ink-3);
  background: var(--surface-3);
}

#side-nav { flex: 1; overflow-y: auto; padding: 0 8px 12px; }
.nav-item {
  display: flex; align-items: center; gap: 9px;
  padding: 6px 8px; margin: 1px 0;
  border-radius: var(--r-m); cursor: pointer; color: var(--ink-2);
  border: none; background: none; width: 100%; text-align: left; font-size: 13.5px;
}
.nav-item:hover { background: var(--surface-3); color: var(--ink); }
.nav-item.active { background: var(--accent-wash); color: var(--accent-soft); font-weight: 600; }
.nav-item .nav-badge {
  margin-left: auto; background: var(--accent); color: var(--accent-ink);
  font-size: 10.5px; font-weight: 700; border-radius: 99px; padding: 1px 6.5px; line-height: 1.5;
}
a.nav-item:hover { text-decoration: none; }
.nav-section {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 8px 4px; font-size: 10.5px; font-weight: 700; letter-spacing: 0.09em;
  text-transform: uppercase; color: var(--ink-3);
}
.nav-section button { opacity: 0; }
.nav-section:hover button { opacity: 1; }
.nav-proj-dot { width: 9px; height: 9px; border-radius: 3px; flex: 0 0 9px; }

.side-back {
  display: flex; align-items: center; gap: 8px;
  margin: 0 8px 8px; padding: 6px 8px;
  border-radius: var(--r-m); color: var(--ink-2); font-size: 13px; font-weight: 600;
}
.side-back:hover { background: var(--surface-3); color: var(--ink); text-decoration: none; }

.side-pin { padding: 6px 8px; border-top: 1px solid var(--line); }

.side-footer { border-top: 1px solid var(--line); padding: 10px 12px; }
.user-card { display: flex; align-items: center; gap: 9px; cursor: pointer; border-radius: var(--r-m); padding: 5px 6px; border: none; background: none; width: 100%; text-align: left; }
.user-card:hover { background: var(--surface-3); }
.user-card .u-name { font-size: 13px; font-weight: 600; }
.user-card .u-role { font-size: 11px; color: var(--ink-3); text-transform: capitalize; }

#main { flex: 1; min-width: 0; display: flex; flex-direction: column; }

#topbar {
  height: 52px; flex: 0 0 52px;
  display: flex; align-items: center; gap: 10px;
  padding: 0 16px 0 10px;
  border-bottom: 1px solid var(--line);
  background: var(--surface);
}
.top-title { font-family: var(--font-display); font-size: 15.5px; font-weight: 700; display: flex; align-items: center; gap: 8px; min-width: 0; }
.top-title .crumb { color: var(--ink-3); font-weight: 500; }
.proj-tabs { display: flex; gap: 2px; margin-left: 10px; align-self: stretch; align-items: stretch; }
.proj-tab {
  display: flex; align-items: center; gap: 6px; padding: 0 11px;
  border: none; background: none; cursor: pointer; font-size: 13px; color: var(--ink-2);
  border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.proj-tab:hover { color: var(--ink); }
.proj-tab.active { color: var(--accent-soft); border-bottom-color: var(--accent); font-weight: 600; }
.top-actions { margin-left: auto; display: flex; align-items: center; gap: 8px; }

#view-root { flex: 1; overflow: auto; position: relative; }
.view-wrap { padding: 20px 24px 40px; max-width: 1400px; margin: 0 auto; }
.view-wrap.full { max-width: none; }

.view-head { display: flex; align-items: flex-start; gap: 14px; margin-bottom: 16px; flex-wrap: wrap; }
.view-title { font-size: 22px; font-weight: 700; letter-spacing: -0.01em; }
.view-sub { color: var(--ink-2); font-size: 13px; margin-top: 3px; }
.view-head .spacer { flex: 1; }
.toolbar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

/* ---------- buttons ---------- */
.btn {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 6.5px 12px; border-radius: var(--r-m);
  border: 1px solid var(--line-2); background: var(--surface);
  font-size: 13px; font-weight: 600; color: var(--ink-2); cursor: pointer;
  transition: background 0.12s ease, border-color 0.12s ease;
  white-space: nowrap;
}
.btn:hover { background: var(--surface-3); color: var(--ink); }
.btn-primary { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.btn-primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); color: var(--accent-ink); }
.btn-ghost { border-color: transparent; background: none; }
.btn-ghost:hover { background: var(--surface-3); }
.btn-danger { color: var(--danger); }
.btn-danger:hover { background: var(--danger-wash); border-color: var(--danger-wash-line); color: var(--danger); }
.btn-sm { padding: 4px 9px; font-size: 12.5px; }
.btn-icon { padding: 6px; border-color: transparent; background: none; color: var(--ink-2); border-radius: var(--r-m); position: relative; }
.btn-icon:hover { background: var(--surface-3); color: var(--ink); }
.btn-icon .dot-badge {
  position: absolute; top: 4px; right: 4px; width: 8px; height: 8px; border-radius: 50%;
  background: var(--danger); border: 2px solid var(--surface);
}

/* ---------- inputs ---------- */
.input, .textarea, select.input {
  padding: 7px 10px;
  border: 1px solid var(--line-2); border-radius: var(--r-m);
  background: var(--surface); color: var(--ink); font: inherit; font-size: 13.5px;
  /* Form controls carry an intrinsic min-width (~20 chars). Without this they
     refuse to shrink inside a flex row and push the whole page sideways. */
  min-width: 0;
}
/* Default width lives in :where() so it has ZERO specificity. `select.input`
   is specificity 0-1-1 and would otherwise beat every single-class width
   utility (.mnt-tpl-type, .flt-sel, …), which is what stretched the checklist
   editor's type select to 754px and pushed the page off-screen. */
:where(.input, .textarea, select.input) { width: 100%; }
.input:focus, .textarea:focus, select.input:focus { border-color: var(--accent); outline: none; box-shadow: 0 0 0 3px var(--accent-wash); }
.input::placeholder, .textarea::placeholder { color: var(--ink-3); }
.textarea { resize: vertical; min-height: 70px; line-height: 1.5; }
.field { margin-bottom: 14px; }
.field-label {
  display: block; font-size: 11px; font-weight: 700; letter-spacing: 0.07em;
  text-transform: uppercase; color: var(--ink-3); margin-bottom: 5px;
}

/* ---------- chips ---------- */
.chip {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 11.5px; font-weight: 600; line-height: 1;
  padding: 4px 8px; border-radius: 99px; white-space: nowrap;
  border: 1px solid transparent;
}
.chip-interactive { cursor: pointer; }
.chip-interactive:hover { filter: brightness(0.97); box-shadow: 0 0 0 3px var(--surface-3); }
.st-backlog    { background: var(--surface-2); color: var(--ink-2); border-color: var(--line-2); }
.st-todo       { background: var(--accent-wash); color: var(--accent-soft); border-color: var(--accent-wash-line); }
.st-inprogress { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
.st-review     { background: var(--violet-wash); color: var(--violet); border-color: var(--violet-wash-line); }
.st-done       { background: var(--good-wash); color: var(--good); border-color: var(--good-wash-line); }
.health-ontrack  { background: var(--good-wash); color: var(--good); border-color: var(--good-wash-line); }
.health-atrisk   { background: var(--warn-wash); color: var(--warn); border-color: var(--warn-wash-line); }
.health-offtrack { background: var(--danger-wash); color: var(--danger); border-color: var(--danger-wash-line); }
.pr-flag { display: inline-flex; align-items: center; gap: 4px; font-size: 11.5px; font-weight: 600; }
.pr-urgent { color: var(--danger); }
.pr-high   { color: var(--warn); }
.pr-medium { color: var(--accent-soft); }
.pr-low    { color: var(--ink-3); }
.due-chip { display: inline-flex; align-items: center; gap: 4px; font-size: 11.5px; font-weight: 600; color: var(--ink-3); }
.due-chip.overdue { color: var(--danger); }
.due-chip.today   { color: var(--warn); }
.due-chip.soon    { color: var(--ink-2); }
.due-chip.done-date { color: var(--good); }
.label-chip {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 10.5px; font-weight: 700; padding: 2.5px 7px; border-radius: 4px; line-height: 1.4;
}

/* label palette — pale wash + readable ink, both themes via tokens */
.lb-azure  { background: var(--accent-wash); color: var(--accent-soft); }
.lb-green  { background: var(--good-wash);   color: var(--good); }
.lb-amber  { background: var(--warn-wash);   color: var(--warn); }
.lb-red    { background: var(--danger-wash); color: var(--danger); }
.lb-violet { background: var(--violet-wash); color: var(--violet); }
.lb-sand   { background: var(--surface-2);   color: var(--ink-2); }

/* ---------- avatars ---------- */
.avatar {
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%; font-weight: 700; color: #fff;
  flex: none; user-select: none; letter-spacing: 0.02em;
}
.avatar-stack { display: inline-flex; align-items: center; }
.avatar-stack .avatar { margin-left: -6px; box-shadow: 0 0 0 2px var(--surface); }
.avatar-stack .avatar:first-child { margin-left: 0; }
.avatar-more {
  margin-left: -6px; background: var(--surface-2); color: var(--ink-2);
  box-shadow: 0 0 0 2px var(--surface);
}

/* ---------- cards & panels ---------- */
.card {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-l);
  padding: 16px;
}
.card-title { font-size: 13px; font-weight: 700; margin-bottom: 4px; font-family: var(--font-display); }
.card-sub { font-size: 12px; color: var(--ink-3); }

/* ---------- progress ---------- */
.progress { height: 6px; border-radius: 99px; background: var(--surface-2); overflow: hidden; flex: 1; min-width: 40px; }
.progress > i { display: block; height: 100%; border-radius: 99px; background: var(--accent); transition: width 0.3s ease; }
.progress.good > i { background: var(--good); }

/* ---------- menus / popovers ---------- */
.menu-pop {
  position: fixed; z-index: 300; min-width: 190px; max-width: 300px;
  background: var(--surface); border: 1px solid var(--line-2); border-radius: var(--r-m);
  box-shadow: var(--shadow-pop); padding: 5px; max-height: 320px; overflow-y: auto;
}
.menu-item {
  display: flex; align-items: center; gap: 9px; width: 100%;
  padding: 6.5px 9px; border: none; background: none; border-radius: var(--r-s);
  font-size: 13px; color: var(--ink); cursor: pointer; text-align: left;
}
.menu-item:hover { background: var(--surface-3); }
.menu-item.danger { color: var(--danger); }
.menu-item.danger:hover { background: var(--danger-wash); }
.menu-item .mi-check { margin-left: auto; color: var(--accent); }
.menu-head { font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: var(--ink-3); padding: 7px 9px 3px; }
.menu-sep { height: 1px; background: var(--line); margin: 5px 4px; }

/* ---------- modals ---------- */
.modal-overlay {
  position: fixed; inset: 0; z-index: 200;
  background: rgba(13, 20, 35, 0.45);
  display: flex; align-items: flex-start; justify-content: center;
  padding: 48px 20px; overflow-y: auto;
  animation: fadeIn 0.15s ease;
}
@keyframes fadeIn { from { opacity: 0; } }
.modal {
  background: var(--surface); border: 1px solid var(--line); border-radius: 12px;
  box-shadow: var(--shadow-modal); width: 100%; max-width: 560px;
  animation: modalUp 0.18s ease;
}
@keyframes modalUp { from { opacity: 0; transform: translateY(10px); } }
.modal.modal-task { max-width: 860px; }
.modal-head { display: flex; align-items: center; gap: 10px; padding: 14px 18px 0; }
.modal-body { padding: 16px 18px 18px; }
.modal-title { font-size: 16px; font-weight: 700; }

/* ---------- tooltips ---------- */
#tip-layer {
  position: fixed; z-index: 500; pointer-events: none;
  background: var(--ink); color: var(--bg); font-size: 11.5px; font-weight: 600;
  border-radius: var(--r-s); padding: 4px 8px; max-width: 260px;
  opacity: 0; transition: opacity 0.1s ease;
}
#tip-layer.show { opacity: 1; }

/* ---------- toasts ---------- */
#toast-root { position: fixed; bottom: 20px; left: 50%; transform: translateX(-50%); z-index: 600; display: flex; flex-direction: column; align-items: center; gap: 8px; }
.toast {
  display: flex; align-items: center; gap: 8px;
  background: var(--ink); color: var(--bg); font-size: 13px; font-weight: 600;
  padding: 9px 16px; border-radius: 8px; box-shadow: var(--shadow-pop);
  animation: toastUp 0.2s ease;
}
@keyframes toastUp { from { opacity: 0; transform: translateY(8px); } }
.toast .t-ico { color: var(--ramp-1); display: flex; }

/* ---------- tables ---------- */
.data-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.data-table th {
  text-align: left; font-size: 10.5px; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.07em; color: var(--ink-3); padding: 8px 10px;
  border-bottom: 1px solid var(--line-2); white-space: nowrap; user-select: none;
}
.data-table td { padding: 8px 10px; border-bottom: 1px solid var(--line); vertical-align: middle; }
.data-table tbody tr { cursor: pointer; }
.data-table tbody tr:hover { background: var(--surface-3); }
.data-table .num { font-variant-numeric: tabular-nums; }

/* ---------- empty states ---------- */
.empty-state {
  text-align: center; padding: 48px 20px; color: var(--ink-3);
}
.empty-state .es-ico { display: inline-flex; padding: 14px; border-radius: 50%; background: var(--surface-2); color: var(--ink-3); margin-bottom: 12px; }
.empty-state .es-title { font-weight: 700; color: var(--ink-2); font-size: 14px; margin-bottom: 4px; }
.empty-state .es-sub { font-size: 12.5px; max-width: 320px; margin: 0 auto; }

/* ---------- utilities ---------- */
.row { display: flex; align-items: center; gap: 8px; min-width: 0; }
.col { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.grow { flex: 1; min-width: 0; }
.muted { color: var(--ink-3); }
.small { font-size: 12px; }
.mono { font-family: var(--font-mono); font-size: 0.92em; }
.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wrap { flex-wrap: wrap; }
.num, .tnum { font-variant-numeric: tabular-nums; }
.divider { height: 1px; background: var(--line); margin: 12px 0; border: none; }
.eyebrow { font-size: 10.5px; font-weight: 700; letter-spacing: 0.09em; text-transform: uppercase; color: var(--ink-3); }
.gold { color: var(--gold); }

/* segmented control */
.seg { display: inline-flex; background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--r-m); padding: 2px; gap: 2px; }
.seg button {
  border: none; background: none; padding: 4px 10px; font-size: 12.5px; font-weight: 600;
  color: var(--ink-2); border-radius: 4px; cursor: pointer;
}
.seg button.active { background: var(--surface); color: var(--ink); box-shadow: 0 1px 2px rgba(0,0,0,0.08); }

/* command palette */
#palette-overlay {
  position: fixed; inset: 0; z-index: 400; background: rgba(13, 20, 35, 0.38);
  display: flex; justify-content: center; align-items: flex-start; padding-top: 12vh;
  animation: fadeIn 0.12s ease;
}
#palette {
  width: 100%; max-width: 580px; background: var(--surface);
  border: 1px solid var(--line-2); border-radius: 12px; box-shadow: var(--shadow-modal);
  overflow: hidden; animation: modalUp 0.15s ease;
}
#palette .pal-input-row { display: flex; align-items: center; gap: 10px; padding: 13px 16px; border-bottom: 1px solid var(--line); color: var(--ink-3); }
#palette input { border: none; background: none; font-size: 15px; flex: 1; color: var(--ink); outline: none; }
#palette .pal-results { max-height: 380px; overflow-y: auto; padding: 6px; }
.pal-group { font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: var(--ink-3); padding: 8px 10px 3px; }
.pal-item {
  display: flex; align-items: center; gap: 10px; padding: 8px 10px;
  border-radius: var(--r-m); cursor: pointer; font-size: 13.5px;
  border: none; background: none; width: 100%; text-align: left; color: var(--ink);
}
.pal-item.sel { background: var(--accent-wash); }
.pal-item .pal-meta { margin-left: auto; font-size: 11.5px; color: var(--ink-3); flex: none; }

/* notifications popover */
#notif-pop {
  position: fixed; z-index: 300; width: 380px; max-width: calc(100vw - 24px);
  background: var(--surface); border: 1px solid var(--line-2); border-radius: var(--r-l);
  box-shadow: var(--shadow-pop); overflow: hidden;
}
#notif-pop .np-head { display: flex; align-items: center; justify-content: space-between; padding: 12px 14px; border-bottom: 1px solid var(--line); }
#notif-pop .np-list { max-height: 420px; overflow-y: auto; }
.notif-row { display: flex; gap: 10px; padding: 11px 14px; cursor: pointer; align-items: flex-start; width: 100%; text-align: left; font: inherit; color: inherit; background: none; border: none; border-bottom: 1px solid var(--line); }
.notif-row:last-child { border-bottom: none; }
.notif-row:hover { background: var(--surface-3); }
.notif-row.unread { background: var(--accent-wash); }
.notif-row.unread:hover { filter: brightness(0.98); }
.notif-row .n-text { font-size: 12.5px; line-height: 1.45; }
.notif-row .n-time { font-size: 11px; color: var(--ink-3); margin-top: 2px; }

/* ============================================================
   EMS ADDITIONS — navy sidebar, KPI tiles, status badges,
   login screen, skeletons, mobile nav (svcdesk idioms)
   ============================================================ */

/* ---------- navigation chrome: SLATE in light, GRAPHITE in dark ----------
   The ground is a token now (--nav-1/2/3, set per theme at the top of this
   file), so the two modes can differ without this block knowing which one is
   in force. Light mode is slate and dark mode is graphite; the county identity
   is carried by the gold in both — gold wordmark, gold active rail, gold seal —
   which is why the ground was free to change at all.
   Both grounds are DARK, so the inks below are light in both modes and there is
   no light-on-light case to defend against.
   Selector is #sidebar.side-navy, not a bare .side-navy: the base #sidebar rule
   is an ID selector, so a class alone loses on specificity and the sidebar would
   fall back to var(--sidebar) — near-white in light mode, which made every one
   of these inks unreadable. */
#sidebar.side-navy, .side-navy {
  background: linear-gradient(180deg, var(--nav-1) 0%, var(--nav-2) 55%, var(--nav-3) 100%);
  border-right: 1px solid var(--nav-line);
  color: var(--nav-ink);
}
.side-navy .nav-section,
.side-navy .user-card .u-role,
.side-navy .btn-icon { color: var(--nav-ink-3); }
.side-navy *::-webkit-scrollbar-thumb { background: rgba(255,255,255,.14); border: 3px solid transparent; background-clip: content-box; }
.side-navy :focus-visible { outline-color: #D4AA28; }
.side-navy .brand-text { line-height: 1.15; min-width: 0; }
.side-navy .brand-cap { font-size: 10px; letter-spacing: 0.14em; color: var(--nav-ink-2); text-transform: uppercase; }
.side-navy .brand-word { font-family: var(--font-display); font-size: 14.5px; color: #fff; font-weight: 600; line-height: 1.2; }
.side-navy .brand-word .gold, .side-navy .gold { color: #D4AA28; }
.side-navy .brand-mark { flex: 0 0 34px; width: 34px; height: 34px; }
.side-navy .side-search { background: rgba(255,255,255,.07); border-color: rgba(255,255,255,.16); color: var(--nav-ink-2); }
.side-navy .side-search:hover { border-color: rgba(255,255,255,.30); color: #E5E9F0; }
.side-navy .side-search kbd { background: rgba(255,255,255,.08); border-color: rgba(255,255,255,.20); color: var(--nav-ink-2); }
.side-navy .nav-item { color: var(--nav-ink); position: relative; }
.side-navy .nav-item:hover { background: var(--nav-hover); color: #fff; }
.side-navy .nav-item.active { background: rgba(231,197,94,.13); color: #fff; font-weight: 600; }
.side-navy .nav-item.active::before {
  content: ''; position: absolute; left: -8px; top: 6px; bottom: 6px; width: 3px;
  border-radius: 2px; background: #D4AA28;
}
.side-navy .nav-item.active svg { color: #E7C55E; }
.side-navy .nav-item .nav-badge, .side-navy .nav-item .count {
  margin-left: auto; background: #D4AA28; color: #0E1B33;
  font-size: 10.5px; font-weight: 700; border-radius: 999px; padding: 1px 7px; line-height: 1.5;
}
.side-navy .nav-group-head { color: var(--nav-ink-3); }
.side-navy .nav-group-head:hover { color: var(--nav-ink); }
.side-navy .nav-section { color: var(--nav-ink-3); }
.side-navy .side-pin { border-top-color: var(--nav-line); }
.side-navy .side-back { color: var(--nav-ink); }
.side-navy .side-back:hover { background: var(--nav-hover); color: #fff; }
.side-navy .side-footer { border-top-color: var(--nav-line); }
.side-navy .user-card:hover { background: var(--nav-hover); }
.side-navy .user-card .u-name { color: #fff; }
.side-navy .user-card .u-role { color: var(--nav-ink-3); }
.side-navy .btn-icon { color: var(--nav-ink-3); }
.side-navy .btn-icon:hover { background: rgba(255,255,255,.10); color: #fff; }

/* ---------- top bar ----------
   In LIGHT mode the top bar is the same slate as the sidebar, so the two form
   one continuous plane of chrome around the content rather than an L-shaped
   dark strip with a white lid. In DARK mode --topbar-bg is the surface colour
   and this block is a no-op change from what it was.

   The primary action button is the thing that breaks when the bar goes dark:
   .btn-primary is navy on white, and navy on slate is a dark blob with an
   invisible edge. On a dark bar it becomes GOLD with navy ink (6.6:1), which is
   also the county's established convention for a primary call to action. */
#topbar {
  background: var(--topbar-bg);
  border-bottom-color: var(--topbar-line);
  color: var(--topbar-ink);
}
#topbar .top-title { color: var(--topbar-ink); }
#topbar .top-title .crumb,
#topbar .top-title .muted,
#topbar .small { color: var(--topbar-ink-2); }
#topbar .btn-icon { color: var(--topbar-ink-2); }
#topbar .btn-icon:hover { background: var(--topbar-hover); color: var(--topbar-ink); }
#topbar .btn-icon.has-dot::after { border-color: var(--topbar-bg); }
#topbar :focus-visible { outline-color: #D4AA28; }
#topbar .proj-tab { color: var(--topbar-ink-2); }
#topbar .proj-tab:hover { color: var(--topbar-ink); }
#topbar .proj-tab.active { color: #fff; border-bottom-color: #D4AA28; }

/* Light mode only — in dark mode the bar is the surface colour and the ordinary
   navy-on-surface button is correct. `:root:not([data-theme="dark"])` covers
   the default and an explicit light stamp; the media query covers OS dark with
   no stamp, and must lose to an explicit light one, hence the :where(). */
:root:not([data-theme="dark"]) #topbar .btn-primary {
  background: #D4AA28; border-color: #D4AA28; color: #16294D; font-weight: 650;
}
:root:not([data-theme="dark"]) #topbar .btn-primary:hover {
  background: #E7C55E; border-color: #E7C55E; color: #16294D;
}
:root:not([data-theme="dark"]) #topbar .btn:not(.btn-primary):not(.btn-icon) {
  background: rgba(255,255,255,.10); border-color: rgba(255,255,255,.20); color: var(--topbar-ink);
}
:root:not([data-theme="dark"]) #topbar .btn:not(.btn-primary):not(.btn-icon):hover {
  background: rgba(255,255,255,.16); border-color: rgba(255,255,255,.32);
}
@media (prefers-color-scheme: dark) {
  :root:where(:not([data-theme="light"])):not([data-theme="dark"]) #topbar .btn-primary {
    background: var(--accent); border-color: var(--accent); color: var(--accent-ink); font-weight: 600;
  }
  :root:where(:not([data-theme="light"])):not([data-theme="dark"]) #topbar .btn:not(.btn-primary):not(.btn-icon) {
    background: var(--surface); border-color: var(--line-2); color: var(--ink-2);
  }
}

/* The sidebar and top bar read their ground and their inks from --nav-* and
   --topbar-* tokens, so the light/dark difference lives in the theme blocks at
   the top of this file and nowhere else. There are no per-theme overrides down
   here to drift out of step. */

/* ---------- KPI tiles (gold left border, big display number) ---------- */
.kpi-strip { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; margin-bottom: 16px; }
.kpi {
  background: var(--surface); border: 1px solid var(--line); border-left: 3px solid var(--gold);
  border-radius: var(--r-l); padding: 12px 14px; min-width: 0;
}
.kpi .k { font-size: 10.5px; letter-spacing: 0.07em; text-transform: uppercase; color: var(--ink-3); font-weight: 700; }
.kpi b, .kpi .n { display: block; font-family: var(--font-display); font-size: 26px; font-weight: 700; margin-top: 2px; font-variant-numeric: tabular-nums; color: var(--ink); }
.kpi .sub { font-size: 12px; color: var(--ink-3); }
.kpi.warn { border-left-color: var(--warn); }
.kpi.danger { border-left-color: var(--danger); }
.kpi.ok { border-left-color: var(--good); }
.kpi.info { border-left-color: var(--accent); }

/* ---------- status badges (pill + currentColor dot) ---------- */
.badge {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 11.5px; font-weight: 650; border-radius: 999px; padding: 3px 10px;
  white-space: nowrap; background: var(--surface-2); color: var(--ink-2);
  border: 1px solid var(--line); line-height: 1.4;
}
.badge::before { content: ''; width: 7px; height: 7px; border-radius: 50%; background: currentColor; flex: none; }
.badge.plain::before { display: none; }
.badge.b-ok     { background: var(--good-wash);   color: var(--good);        border-color: transparent; }
.badge.b-warn   { background: var(--warn-wash);   color: var(--warn);        border-color: transparent; }
.badge.b-danger { background: var(--danger-wash); color: var(--danger);      border-color: transparent; }
.badge.b-info   { background: var(--accent-wash); color: var(--accent-soft); border-color: transparent; }
.badge.b-gold   { background: var(--gold-tint);   color: var(--gold-deep);   border-color: transparent; }
.badge.b-muted  { background: var(--surface-2);   color: var(--ink-3);       border-color: transparent; }

/* ---------- login screen (fixed navy in both themes, gold dot-grid) ---------- */
.login {
  /* align-items:center would make a card taller than the viewport overflow in BOTH
     directions, putting its top above the scroll origin (unreachable). flex-start +
     auto margins on the card centers when there is room and scrolls when there isn't. */
  position: fixed; inset: 0; z-index: 50; overflow: auto;
  display: flex; align-items: flex-start; justify-content: center; padding: 20px;
  background-color: #0E1B33;
  background-image: radial-gradient(rgba(231, 197, 94, 0.075) 1px, transparent 1.4px);
  background-size: 26px 26px;
}
.login :focus-visible { outline-color: #D4AA28; }
.login-card {
  background: linear-gradient(180deg, #14264A 0%, #16294D 58%);
  border: 1px solid rgba(255,255,255,.09); border-radius: 16px;
  box-shadow: 0 24px 64px rgba(0,0,0,.5), 0 4px 12px rgba(0,0,0,.35);
  padding: 34px 34px 28px; width: 100%; max-width: 400px; color: #E5E9F0;
  margin: auto; /* centers when it fits; collapses to 0 (scrollable) when it doesn't */
}
.login-card .mark { display: flex; justify-content: center; margin-bottom: 14px; }
.login-card .mark img { width: 56px; height: 56px; }
.login-word { text-align: center; font-family: var(--font-display); font-size: 22px; font-weight: 700; color: #fff; margin-bottom: 2px; }
.login-word .gold { color: #D4AA28; }
.login-sub { text-align: center; font-size: 12.5px; color: #AAB6CC; margin-bottom: 22px; }
.login .field-label { color: #C4CEDF; }
.login .input { background: rgba(255,255,255,.06); border-color: rgba(255,255,255,.16); color: #fff; }
.login .input:focus { border-color: #D4AA28; box-shadow: 0 0 0 3px rgba(212,170,40,.22); }
.login .input::placeholder { color: #7f8db0; }
.login-sso {
  width: 100%; justify-content: center; text-decoration: none;
  background: #D4AA28; border-color: #D4AA28; color: #0E1B33; font-weight: 700;
}
.login-sso:hover { background: #C29A1F; border-color: #C29A1F; color: #0E1B33; text-decoration: none; }
.login-local {
  width: 100%; justify-content: center;
  background: rgba(255,255,255,.07); border-color: rgba(255,255,255,.18); color: #E5E9F0;
}
.login-local:hover { background: rgba(255,255,255,.12); border-color: rgba(255,255,255,.3); color: #fff; }
.login-div { display: flex; align-items: center; gap: 10px; margin: 16px 0 14px; color: #8E9DBC; font-size: 11px; text-transform: uppercase; letter-spacing: 0.08em; }
.login-div::before, .login-div::after { content: ''; flex: 1; height: 1px; background: rgba(255,255,255,.12); }
.login-err { color: #F2A9A2; font-size: 12.5px; margin-top: 10px; min-height: 17px; text-align: center; }

/* ---------- loading skeletons ---------- */
.skeleton {
  background: linear-gradient(90deg, var(--surface-2) 25%, var(--surface-3) 50%, var(--surface-2) 75%);
  background-size: 200% 100%; animation: shimmer 1.4s infinite;
  border-radius: var(--r-m); min-height: 14px;
}
@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }

/* ---------- responsive / mobile nav ---------- */
#side-backdrop { display: none; }
#side-toggle { display: inline-flex; }
@media (max-width: 900px) {
  .view-wrap { padding: 14px 14px 32px; }
  #sidebar {
    position: fixed; left: 0; top: 0; bottom: 0; height: 100%;
    width: 264px; flex-basis: 264px; z-index: 120;
    margin-left: 0 !important;
    transform: translateX(-100%);
    transition: transform 0.22s ease;
  }
  #sidebar.mobile-open { transform: translateX(0); box-shadow: var(--shadow-modal); }
  #side-backdrop { position: fixed; inset: 0; z-index: 110; background: rgba(10, 16, 30, 0.45); }
  body:not(.nav-open) #side-backdrop { display: none; }
  body.nav-open #side-backdrop { display: block; }
}

/* ============================================================
   PLANNING / NAVIGATION ADDITIONS (PLANNING-SPEC §2–3)
   Grouped collapsible nav · notification bell · shared task
   modal · @mention popup · attachments. Tokens only — the
   contrast floors above are unchanged.
   ============================================================ */

/* ---------- grouped, collapsible sidebar nav ---------- */
.nav-group { margin-top: 8px; }
.nav-group:first-child { margin-top: 0; }
.nav-group-head {
  display: flex; align-items: center; gap: 6px; width: 100%;
  padding: 6px 8px; margin: 1px 0;
  border: none; background: none; cursor: pointer; text-align: left;
  border-radius: var(--r-m);
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.09em; text-transform: uppercase;
  color: var(--ink-3);
}
.nav-group-head:hover { background: var(--surface-3); color: var(--ink-2); }
.nav-group-head .ngh-chev {
  display: flex; flex: none; transition: transform 0.16s ease;
}
.nav-group.collapsed .nav-group-head .ngh-chev { transform: rotate(-90deg); }
.nav-group-items { display: block; }
.nav-group-items[hidden] { display: none; }
/* items indent under their group header; the active rail stays at the sidebar edge */
.nav-item.nav-sub { padding-left: 26px; }
#side-nav .nav-group + .nav-item { margin-top: 8px; }

/* Tokenised, like the rest of the sidebar. This rule used to hardcode the dark
   theme's #9aa0ac, and because it sits AFTER the sidebar block it won on source
   order — so the group headings alone stayed graphite-grey when the light theme
   went slate, at 3.9:1 against it. */
.side-navy .nav-group-head { color: var(--nav-ink-3); }
.side-navy .nav-group-head:hover { background: var(--nav-hover); color: #fff; }

/* ---------- notification bell + popover ---------- */
.btn-icon.bell { position: relative; }
.bell-pill {
  position: absolute; top: 1px; right: 0;
  min-width: 16px; height: 16px; padding: 0 4px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 999px; background: var(--gold); color: #0E1B33;
  font-size: 10px; font-weight: 700; line-height: 1;
  font-variant-numeric: tabular-nums;
  border: 2px solid var(--surface); box-sizing: content-box;
}
.bell-pop {
  position: fixed; z-index: 300; width: 380px; max-width: calc(100vw - 24px);
  background: var(--surface); border: 1px solid var(--line-2); border-radius: var(--r-l);
  box-shadow: var(--shadow-pop); overflow: hidden;
}
.bell-pop .np-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 11px 14px; border-bottom: 1px solid var(--line);
}
.bell-pop .np-list { max-height: 440px; overflow-y: auto; }
.bell-pop .n-day {
  padding: 7px 14px 4px; background: var(--surface-2);
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--ink-3); border-bottom: 1px solid var(--line);
  position: sticky; top: 0; z-index: 1;
}
.bell-pop .notif-row .n-kind { display: flex; flex: none; color: var(--ink-3); padding-top: 1px; }
.bell-pop .notif-row.unread .n-kind { color: var(--accent-soft); }
/* --ink-3 on the unread wash falls to 4.42:1 in dark mode — n-time uses --ink-2 (6.4:1) */
.notif-row .n-time { color: var(--ink-2); }
.n-dot {
  flex: none; width: 8px; height: 8px; border-radius: 50%;
  background: var(--gold); margin-top: 5px;
}

/* ---------- shared task modal ---------- */
.modal.modal-task { max-width: 940px; }
.tm-wrap { display: flex; gap: 22px; flex-wrap: wrap; align-items: flex-start; }
.tm-left { flex: 1.7 1 340px; min-width: 300px; }
.tm-side { flex: 1 1 250px; min-width: 240px; gap: 14px; }
.tm-proj {
  display: inline-flex; align-items: center; gap: 6px; min-width: 0; max-width: 240px;
  font-size: 12.5px; font-weight: 600; color: var(--ink-2);
}
.tm-title {
  width: 100%; font-family: var(--font-display); font-size: 18px; font-weight: 700;
  border: 1px solid transparent; background: none; color: var(--ink);
  padding: 5px 7px; margin-left: -7px; border-radius: var(--r-m); line-height: 1.3;
}
.tm-title:hover { border-color: var(--line); }
.tm-title:focus { border-color: var(--accent); background: var(--surface); box-shadow: 0 0 0 3px var(--accent-wash); outline: none; }
.tm-title-ro { border-color: transparent; }
.tm-desc {
  font-size: 13px; line-height: 1.55; white-space: pre-wrap; word-break: break-word;
  padding: 7px 9px; border: 1px solid transparent; border-radius: var(--r-m);
  min-height: 34px;
}
.tm-desc.editable { cursor: text; }
.tm-desc.editable:hover { background: var(--surface-3); border-color: var(--line); }
.tm-cl-item .tm-cl-x { opacity: 0; }
.tm-cl-item:hover .tm-cl-x, .tm-cl-item .tm-cl-x:focus-visible { opacity: 1; }
.tm-cl-item input[type="checkbox"] { accent-color: var(--accent); width: 15px; height: 15px; flex: none; }
.tm-comment-body { font-size: 13px; margin-top: 2px; white-space: pre-wrap; word-break: break-word; }
.tm-activity { padding-bottom: 4px; }
.tm-person {
  display: inline-flex; align-items: center; gap: 6px; max-width: 100%;
  background: var(--surface-2); border: 1px solid var(--line);
  border-radius: 999px; padding: 2px 8px 2px 3px; font-size: 12px; color: var(--ink);
}
.tm-person .truncate { max-width: 130px; }
.tm-x {
  display: inline-flex; align-items: center; justify-content: center;
  border: none; background: none; color: var(--ink-3); cursor: pointer;
  padding: 1px; border-radius: 50%; flex: none;
}
.tm-x:hover { background: var(--danger-wash); color: var(--danger); }
.tm-foot { font-size: 11px; margin-top: auto; padding-top: 10px; border-top: 1px solid var(--line); }

/* @mention — escaped text, highlighted inline */
.mention {
  background: var(--accent-wash); color: var(--accent-soft);
  border-radius: 4px; padding: 0 3px; font-weight: 600;
}
.mention-pop {
  position: fixed; z-index: 320; width: 260px; max-width: calc(100vw - 24px);
  background: var(--surface); border: 1px solid var(--line-2); border-radius: var(--r-m);
  box-shadow: var(--shadow-pop); padding: 4px; max-height: 240px; overflow-y: auto;
}
.mention-item {
  display: flex; align-items: center; gap: 8px; width: 100%;
  padding: 6px 8px; border: none; background: none; border-radius: var(--r-s);
  font-size: 13px; color: var(--ink); cursor: pointer; text-align: left;
}
.mention-item.sel, .mention-item:hover { background: var(--accent-wash); }
/* --ink-3 on the accent wash is 4.42:1 in dark mode — the row's meta text uses --ink-2 (6.4:1) */
.mention-item .muted { color: var(--ink-2); }

/* ---------- attachments ---------- */
.attach-grid { display: flex; flex-direction: column; gap: 6px; }
.attach-item {
  display: flex; align-items: center; gap: 9px;
  border: 1px solid var(--line); border-radius: var(--r-m);
  padding: 6px 8px; background: var(--surface);
}
.attach-item:hover { background: var(--surface-3); }
.attach-thumb {
  flex: none; width: 38px; height: 38px; border-radius: var(--r-s);
  background: var(--surface-2); color: var(--ink-3);
  display: flex; align-items: center; justify-content: center; overflow: hidden;
}
.attach-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.attach-name { font-size: 12.5px; font-weight: 600; }
.attach-x { opacity: 0; flex: none; }
.attach-item:hover .attach-x, .attach-x:focus-visible { opacity: 1; }
.attach-x:hover { background: var(--danger-wash); color: var(--danger); }

@media (max-width: 900px) {
  .modal.modal-task { max-width: 100%; }
  .tm-wrap { gap: 16px; }
  .tm-left, .tm-side { flex: 1 1 100%; min-width: 0; }
  .bell-pop { width: calc(100vw - 20px); }
}

/* ---------- minimum control size ----------
   WCAG 2.5.8 asks for a 24px minimum target. Dense table controls (column
   sort headers, filter chips, segment buttons) were landing at 22-23px, so
   raise the floor globally rather than patching each view. min-height only
   ever grows a control, so no existing layout shrinks. */
button, .btn, .btn-sm, .chip, .seg button { min-height: 24px; }
/* Native checkboxes stay at their compact size on purpose — 24px boxes make
   the device/seal tables unusably tall. Their row label is the large target. */
input[type="checkbox"], input[type="radio"] { width: 15px; height: 15px; }

/* ---------- scrollable column stacks ----------
   A column flex container with a height cap crushes its children:
   flex-shrink defaults to 1, so N rows of real content get squeezed to a
   fraction of their height and paint ON TOP of each other instead of the
   container scrolling. That is exactly what made the election staffing
   list unreadable. Children of every such container keep their natural
   height here, in one place. :where() keeps specificity at 0 so a view can
   still opt out. The audit's content-exceeds-box check guards new ones. */
:where(.dev-pick-list,
       .dsh-act-list,
       .dsh-pl-list,
       .elc-incs,
       .elc-kvs,
       .elc-sites,
       .elc-unsealed,
       .grp-pick-list,
       .lbl-tpls,
       .log-add-results,
       .log-col-body,
       .log-scan-log,
       .mnt-cl-list,
       .mnt-pl-assets,
       .pp-shiftlist,
       .pp-ta,
       .pr-col-body,
       .rcv-log,
       .rpt-assetresults,
       .seal-pick-list,
       .site-eq,
       .site-feed,
       .sw-col-body,
       .sw-comments) > * { flex-shrink: 0; }

/* --gold-on-tint used to live here: a darker gold for text on --gold-tint,
   because --gold-deep was 4.47:1 on that wash. It had no call sites, and
   --gold-deep is now #6b540f (5.93:1 on the tint), so it was both dead and
   lighter than the token it existed to darken. Removed rather than left to
   contradict itself — .badge.b-gold uses var(--gold-deep) directly. */
