/* CHOWBASE — Control Center design system.
   Restrained, operational. Solid surfaces, subtle borders, one accent.
   Three appearance modes — Dark / Light / System — driven entirely by
   semantic design tokens. Components never hard-code a theme colour. */

/* ── LIGHT is the base palette — soft, muted, warm-neutral stone ─────── */
:root {
  color-scheme: light;

  --bg:        #e7e9e6;   /* page — deliberately NOT near-white */
  --surface-1: #f0f1ee;   /* cards / sidebar / panels */
  --surface-2: #dde1dc;   /* secondary fill: inputs, table header, subtle hover */
  --surface-3: #d7dcd6;   /* track / pressed / inset well */
  --border:    #c7cdc6;
  --border-strong: #b4bbb4;

  --text:      #252a27;
  --text-dim:  #59625c;
  --text-mute: #7a837d;

  --accent:      #b58a52;
  --accent-hover:#9e7544;
  --accent-weak: #ece2d1;   /* soft warm wash behind active nav / selection */
  --accent-text: #86622f;   /* accent as text on a light surface (contrast) */
  --on-accent:   #ffffff;

  --ok:    #3e8060;  --ok-bg:    rgba(62, 128, 96, 0.14);
  --warn:  #a77932;  --warn-bg:  rgba(167, 121, 50, 0.15);
  --bad:   #b65353;  --bad-bg:   rgba(182, 83, 83, 0.14);
  --muted: #7a837d;  --muted-bg: rgba(122, 131, 125, 0.15);
  --info:  #4d718c;

  --shadow:   0 1px 2px rgba(37, 42, 39, 0.05), 0 8px 22px -14px rgba(37, 42, 39, 0.18);
  --backdrop: rgba(37, 42, 39, 0.30);
  --overlay:  rgba(37, 42, 39, 0.38);

  --chart-grid:  #d5dad4;
  --chart-track: #d9ded8;

  /* map — muted stone; clear separation page > ocean > land > border */
  --map-ocean:        #ced5cf;
  --map-land:         #e6eae4;
  --map-land-2:       #d3d9d3;   /* dimmed / out-of-focus land sinks toward the ocean */
  --map-border:       #a7b0a8;
  --map-border-strong:#93a094;
  --map-selected:     var(--accent);
  --map-label:        #39413b;
  --map-graticule:    #c4cbc5;
  --map-ok:  #3e8060;  --map-warn: #a77932;  --map-bad: #b65353;  --map-muted: #94a093;

  --mono: "SFMono-Regular", ui-monospace, Consolas, "Liberation Mono", Menlo, monospace;
  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --radius: 10px;
  --radius-sm: 7px;
  --nav-w: 244px;

  /* task-spec semantic aliases (follow the theme automatically) */
  --bg-page: var(--bg); --bg-surface: var(--surface-1); --bg-surface-secondary: var(--surface-2);
  --bg-elevated: var(--surface-3); --text-primary: var(--text); --text-secondary: var(--text-dim);
  --text-muted: var(--text-mute); --success: var(--ok); --warning: var(--warn); --danger: var(--bad);
  --map-marker: var(--accent);

  /* ── depth system (Command Center pass) ───────────────────────────────
     Additive tokens only — every existing --surface-N/--border/--shadow
     usage above is untouched. Used sparingly, only for hero-level surfaces
     (GeoMap panel, KPI row, active nav) — data tables and ordinary panels
     stay on the flat, opaque --surface-1 they already use (see ux-guideline
     "surface-readability": overly transparent surfaces blur hierarchy —
     glass is for the few things that should read as elevated, not everything). */
  --glass-bg: color-mix(in srgb, var(--surface-1) 72%, transparent);
  --glass-border: color-mix(in srgb, var(--border-strong) 130%, var(--text) 6%);
  --glass-highlight: color-mix(in srgb, #fff 55%, transparent);
  --elev-1: 0 1px 2px rgba(37,42,39,0.05), 0 6px 16px -12px rgba(37,42,39,0.16);
  --elev-2: 0 2px 4px rgba(37,42,39,0.06), 0 14px 28px -16px rgba(37,42,39,0.20);
  --elev-3: 0 4px 10px rgba(37,42,39,0.07), 0 26px 46px -20px rgba(37,42,39,0.24);
  --glow-accent: color-mix(in srgb, var(--accent) 38%, transparent);
  --radius-lg: 14px;
}

/* ── DARK — as a system preference, unless the user picked Light ─────── */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --bg: #0b0f17; --surface-1: #111725; --surface-2: #161d2e; --surface-3: #1c2539;
    --border: #263048; --border-strong: #33405e;
    --text: #e6ebf5; --text-dim: #93a1bd; --text-mute: #5f6d8a;
    --accent: #4f7dff; --accent-hover: #6b93ff; --accent-weak: #1e2a4a; --accent-text: #a9c0ff; --on-accent: #ffffff;
    --ok: #38c98a; --ok-bg: rgba(56,201,138,0.12); --warn: #e2ab48; --warn-bg: rgba(226,171,72,0.12);
    --bad: #e2596b; --bad-bg: rgba(226,89,107,0.12); --muted: #7b89a6; --muted-bg: rgba(123,137,166,0.12); --info: #5b9bd5;
    --shadow: 0 1px 2px rgba(0,0,0,0.3), 0 8px 24px -12px rgba(0,0,0,0.5);
    --backdrop: rgba(4,7,12,0.62); --overlay: rgba(0,0,0,0.55);
    --chart-grid: #1c2539; --chart-track: #1c2539;
    --map-ocean: #0b111d; --map-land: #1b2437; --map-land-2: #141b2b;
    --map-border: #2d3b5a; --map-border-strong: #45577d; --map-label: #a9b6d2; --map-graticule: #1d2740;
    --map-ok: #38c98a; --map-warn: #e2ab48; --map-bad: #e2596b; --map-muted: #7b89a6;
    --glass-bg: color-mix(in srgb, var(--surface-1) 66%, transparent);
    --glass-border: color-mix(in srgb, var(--border-strong) 100%, #fff 8%);
    --glass-highlight: color-mix(in srgb, #fff 8%, transparent);
    --elev-1: 0 1px 2px rgba(0,0,0,0.35), 0 8px 18px -12px rgba(0,0,0,0.55);
    --elev-2: 0 3px 6px rgba(0,0,0,0.4), 0 18px 34px -16px rgba(0,0,0,0.6);
    --elev-3: 0 6px 14px rgba(0,0,0,0.45), 0 34px 60px -22px rgba(0,0,0,0.7);
    --glow-accent: color-mix(in srgb, var(--accent) 46%, transparent);
  }
}
/* ── DARK — explicit user choice (wins over any system preference) ───── */
:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: #0b0f17; --surface-1: #111725; --surface-2: #161d2e; --surface-3: #1c2539;
  --border: #263048; --border-strong: #33405e;
  --text: #e6ebf5; --text-dim: #93a1bd; --text-mute: #5f6d8a;
  --accent: #4f7dff; --accent-hover: #6b93ff; --accent-weak: #1e2a4a; --accent-text: #a9c0ff; --on-accent: #ffffff;
  --ok: #38c98a; --ok-bg: rgba(56,201,138,0.12); --warn: #e2ab48; --warn-bg: rgba(226,171,72,0.12);
  --bad: #e2596b; --bad-bg: rgba(226,89,107,0.12); --muted: #7b89a6; --muted-bg: rgba(123,137,166,0.12); --info: #5b9bd5;
  --shadow: 0 1px 2px rgba(0,0,0,0.3), 0 8px 24px -12px rgba(0,0,0,0.5);
  --backdrop: rgba(4,7,12,0.62); --overlay: rgba(0,0,0,0.55);
  --chart-grid: #1c2539; --chart-track: #1c2539;
  --map-ocean: #0b111d; --map-land: #1b2437; --map-land-2: #141b2b;
  --map-border: #2d3b5a; --map-border-strong: #45577d; --map-label: #a9b6d2; --map-graticule: #1d2740;
  --map-ok: #38c98a; --map-warn: #e2ab48; --map-bad: #e2596b; --map-muted: #7b89a6;
  --glass-bg: color-mix(in srgb, var(--surface-1) 66%, transparent);
  --glass-border: color-mix(in srgb, var(--border-strong) 100%, #fff 8%);
  --glass-highlight: color-mix(in srgb, #fff 8%, transparent);
  --elev-1: 0 1px 2px rgba(0,0,0,0.35), 0 8px 18px -12px rgba(0,0,0,0.55);
  --elev-2: 0 3px 6px rgba(0,0,0,0.4), 0 18px 34px -16px rgba(0,0,0,0.6);
  --elev-3: 0 6px 14px rgba(0,0,0,0.45), 0 34px 60px -22px rgba(0,0,0,0.7);
  --glow-accent: color-mix(in srgb, var(--accent) 46%, transparent);
}
/* ── LIGHT — explicit user choice (re-assert so it wins under a dark OS) */
:root[data-theme="light"] { color-scheme: light; }

* { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 14px/1.55 var(--sans);
  -webkit-font-smoothing: antialiased;
}
a { color: var(--accent-text); text-decoration: none; }
a:hover { text-decoration: underline; }
button { font-family: inherit; }
[hidden] { display: none !important; }
::selection { background: var(--accent-weak); }

/* ── scrollbars ─────────────────────────────────────────────────────── */
* { scrollbar-width: thin; scrollbar-color: var(--border-strong) transparent; }
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 6px; border: 2px solid var(--bg); }

/* ── login ─────────────────────────────────────────────────────────── */
#login {
  min-height: 100dvh;
  display: grid;
  place-items: center;
  padding: 24px;
}
#login .box {
  width: 100%;
  max-width: 400px;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 30px 28px;
}
#login .brand { margin-bottom: 22px; }
.brand-lockup { display: flex; align-items: center; gap: 9px; }
/* CHOWBASE wordmark lockup — constrained height, automatic width (the
   source asset is a wide 1048x628 lockup, not a square icon), so it never
   consumes more vertical space than the old 30px C-mark did. Exactly one of
   the two theme variants is visible at a time, following this app's own
   existing three-state theme pattern (bare :root = light default; the
   prefers-color-scheme block = system-dark; the explicit [data-theme]
   attributes override either way) — see the :root rules below and
   lib/theme.js's own data-theme contract. */
.brand-logo { height: 26px; width: auto; display: block; }
.brand-logo-dark { display: none; }
.brand-logo-light { display: block; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .brand-logo-dark { display: block; }
  :root:not([data-theme="light"]) .brand-logo-light { display: none; }
}
:root[data-theme="dark"] .brand-logo-dark { display: block; }
:root[data-theme="dark"] .brand-logo-light { display: none; }
:root[data-theme="light"] .brand-logo-dark { display: none; }
:root[data-theme="light"] .brand-logo-light { display: block; }
.brand-mark {
  width: 30px; height: 30px; border-radius: 8px;
  background: var(--accent); color: var(--on-accent);
  display: grid; place-items: center;
  font-weight: 800; font-size: 15px; letter-spacing: -0.5px;
}
.brand-name { font-weight: 700; font-size: 15px; letter-spacing: 0.2px; }
.brand-sub { font-size: 12px; color: var(--text-dim); margin-top: 1px; }
#login h1 { font-size: 16px; margin: 0 0 4px; }
#login p.hint { color: var(--text-dim); font-size: 12.5px; margin: 0 0 20px; }
.field { margin-bottom: 14px; }
.field label { display: block; font-size: 11.5px; color: var(--text-dim); margin-bottom: 6px; letter-spacing: 0.2px; }
.field input, .field select {
  width: 100%; padding: 9px 11px;
  background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  font-size: 13px; font-family: var(--mono);
}
.field input:focus, .field select:focus { outline: none; border-color: var(--accent); }
#login button[type=submit] {
  width: 100%; margin-top: 6px; padding: 10px;
  background: var(--accent); color: var(--on-accent); border: none; border-radius: var(--radius-sm);
  font-weight: 600; font-size: 13.5px; cursor: pointer;
}
#login button[type=submit]:hover { filter: brightness(1.07); }
#login button[type=submit]:disabled { opacity: 0.5; cursor: progress; }
#login .err { color: var(--bad); font-size: 12.5px; min-height: 16px; margin-top: 10px; }
#login .note {
  margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--border);
  font-size: 11.5px; color: var(--text-mute); line-height: 1.5;
}
#login code { font-family: var(--mono); background: var(--bg); padding: 1px 5px; border-radius: 4px; }

/* ── app shell ─────────────────────────────────────────────────────── */
#app { display: grid; grid-template-columns: var(--nav-w) 1fr; min-height: 100dvh; }

nav#sidebar {
  /* a faint vertical wash (not a hard gradient) gives the sidebar a hair
     of depth against the flat page background without competing with the
     content it holds — same surface color at both ends, just barely lit
     from the top. */
  background: linear-gradient(180deg, color-mix(in srgb, var(--surface-1) 100%, var(--text) 1.5%) 0%, var(--surface-1) 220px, var(--surface-1) 100%);
  border-right: 1px solid var(--border);
  display: flex; flex-direction: column;
  position: sticky; top: 0; height: 100dvh;
  overflow-y: auto;
}
#sidebar .head { padding: 18px 18px 14px; border-bottom: 1px solid var(--border); }
#sidebar .nav-scroll { flex: 1; padding: 10px 10px 16px; }
.nav-group { margin-top: 14px; }
.nav-group:first-child { margin-top: 4px; }
.nav-group > .lbl {
  font-size: 10.5px; font-weight: 600; letter-spacing: 0.9px;
  color: var(--text-mute); text-transform: uppercase;
  padding: 6px 10px 4px;
}
.nav-item {
  position: relative;
  display: flex; align-items: center; gap: 10px;
  padding: 7px 10px; margin: 1px 0;
  border-radius: var(--radius-sm);
  color: var(--text-dim); font-size: 13px; font-weight: 500;
  cursor: pointer; user-select: none;
  border: 1px solid transparent;
  transition: background .12s ease, color .12s ease;
}
.nav-item:hover { background: var(--surface-2); color: var(--text); }
.nav-item.active {
  background: var(--accent-weak); color: var(--text); border-color: var(--border-strong); font-weight: 600;
  /* a faint accent-toned glow behind the active item, plus a hairline top
     highlight — the same "lit from above" cue as the elevated panels, kept
     to a single low-opacity token so it reads as intentional, not neon. */
  box-shadow: 0 0 0 1px transparent, 0 2px 10px -4px var(--glow-accent), inset 0 1px 0 var(--glass-highlight);
}
.nav-item.active::before {
  content: ""; position: absolute; left: -1px; top: 7px; bottom: 7px; width: 2.5px;
  border-radius: 99px; background: var(--accent);
  box-shadow: 0 0 6px var(--glow-accent);
}
.nav-item .ico { width: 15px; height: 15px; flex: none; opacity: 0.8; }
.nav-item.active .ico { opacity: 1; color: var(--accent-text); }
.nav-item .badge {
  margin-left: auto; font-size: 10.5px; font-weight: 700;
  background: var(--surface-3); color: var(--text-dim);
  border-radius: 99px; padding: 1px 7px; min-width: 18px; text-align: center;
}
.nav-item.active .badge { background: var(--accent); color: var(--on-accent); }

#sidebar .foot {
  padding: 12px 16px; border-top: 1px solid var(--border);
  font-size: 11.5px; color: var(--text-mute);
}
#sidebar .foot .conn { display: flex; align-items: center; gap: 7px; color: var(--text-dim); }
#sidebar .foot .conn .dot { width: 7px; height: 7px; border-radius: 99px; background: var(--ok); box-shadow: 0 0 0 3px var(--ok-bg); }
#sidebar .foot .conn.down .dot { background: var(--bad); box-shadow: 0 0 0 3px var(--bad-bg); }
#sidebar .foot .ver { margin-top: 5px; font-family: var(--mono); font-size: 10.5px; }

.theme-toggle {
  display: inline-flex; margin-bottom: 12px; padding: 2px;
  background: var(--surface-2); border: 1px solid var(--border); border-radius: 8px;
}
.theme-toggle button {
  appearance: none; border: 0; background: transparent; cursor: pointer;
  width: 30px; height: 24px; border-radius: 6px; color: var(--text-mute);
  font-size: 13px; line-height: 1; display: grid; place-items: center;
  transition: background .12s ease, color .12s ease;
}
.theme-toggle button:hover { color: var(--text-dim); }
.theme-toggle button.on { background: var(--surface-1); color: var(--accent-text); box-shadow: var(--shadow); }
.theme-toggle button:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

.seg-radio { display: flex; gap: 8px; flex-wrap: wrap; }
.seg-opt {
  flex: 1; min-width: 120px; text-align: left; cursor: pointer;
  background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-sm);
  padding: 10px 12px; color: var(--text-dim); transition: border-color .12s ease, background .12s ease;
}
.seg-opt:hover { border-color: var(--border-strong); }
.seg-opt.on { background: var(--accent-weak); border-color: var(--accent); color: var(--text); }
.seg-opt:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.seg-opt .so-label { display: block; font-weight: 600; font-size: 12.5px; }
.seg-opt .so-desc { display: block; font-size: 11px; color: var(--text-mute); margin-top: 2px; }

/* ── main / content ────────────────────────────────────────────────── */
main#content { min-width: 0; display: flex; flex-direction: column; }
.topbar {
  position: sticky; top: 0; z-index: 8;
  display: flex; align-items: center; gap: 14px;
  padding: 12px 24px;
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--border);
  /* a soft cast shadow (not another border) is what actually separates a
     "floating" sticky bar from the content scrolling beneath it */
  box-shadow: 0 8px 20px -16px rgba(0,0,0,0.35);
}
.topbar .crumbs { font-size: 12.5px; color: var(--text-dim); display: flex; gap: 6px; align-items: center; }
.topbar .crumbs b { color: var(--text); font-weight: 600; }
.search-box { margin-left: auto; position: relative; width: 320px; max-width: 40vw; }
.search-box input {
  width: 100%; padding: 7px 11px 7px 32px;
  background: var(--surface-1); color: var(--text);
  border: 1px solid var(--border); border-radius: 99px; font-size: 12.5px;
}
.search-box input:focus { outline: none; border-color: var(--accent); }
.search-box .ico { position: absolute; left: 11px; top: 50%; transform: translateY(-50%); width: 13px; height: 13px; color: var(--text-mute); }
.search-results {
  position: absolute; top: calc(100% + 6px); left: 0; right: 0; z-index: 20;
  background: var(--surface-2); border: 1px solid var(--border-strong);
  border-radius: var(--radius); box-shadow: var(--shadow); overflow: hidden;
  max-height: 66vh; overflow-y: auto;
}
.search-results .cat { font-size: 10.5px; font-weight: 700; letter-spacing: 0.7px; color: var(--text-mute); text-transform: uppercase; padding: 9px 12px 4px; }
.search-results .r { padding: 8px 12px; cursor: pointer; border-top: 1px solid var(--border); }
.search-results .r:hover { background: var(--surface-3); }
.search-results .r .t { font-size: 13px; }
.search-results .r .s { font-size: 11.5px; color: var(--text-dim); }
.search-results .none { padding: 14px 12px; color: var(--text-dim); font-size: 12.5px; }

.page { padding: 22px 24px 40px; flex: 1; }
.page-head { display: flex; align-items: flex-start; gap: 16px; margin-bottom: 18px; }
.page-head h1 { font-size: 19px; font-weight: 650; margin: 0; letter-spacing: 0.1px; }
.page-head .sub { font-size: 12.5px; color: var(--text-dim); margin-top: 3px; }
.page-head .actions { margin-left: auto; display: flex; gap: 8px; flex-wrap: wrap; }

/* ── stat cards ────────────────────────────────────────────────────── */
.stat-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(168px, 1fr)); gap: 12px; margin-bottom: 22px; }
.stat {
  position: relative; overflow: hidden;
  background: var(--surface-1); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 12px 14px;
  display: block; color: inherit; text-decoration: none;
  /* one hairline top highlight = a lit edge, the cheapest legible "raised
     surface" cue there is — kept to a single inset line, no drop shadow at
     rest, so the KPI row stays calm until something needs attention */
  box-shadow: inset 0 1px 0 var(--glass-highlight);
}
a.stat:hover, .stat.interactive:hover { border-color: var(--border-strong); box-shadow: var(--elev-1), inset 0 1px 0 var(--glass-highlight); }
.stat.ok::after, .stat.warn::after, .stat.bad::after, .stat.accent::after {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 2px;
}
.stat.ok::after { background: var(--ok); } .stat.warn::after { background: var(--warn); }
.stat.bad::after { background: var(--bad); } .stat.accent::after { background: var(--accent); }
.stat .k { font-size: 10px; font-weight: 600; letter-spacing: 0.7px; color: var(--text-mute); text-transform: uppercase; }
.stat .v { font-size: 24px; font-weight: 700; margin-top: 4px; letter-spacing: -0.4px; line-height: 1.1; font-variant-numeric: tabular-nums; }
.stat .v small { font-size: 13px; font-weight: 500; color: var(--text-dim); }
.stat .d { font-size: 11px; color: var(--text-dim); margin-top: 3px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.stat.accent .v { color: var(--accent-text); }
.stat.ok .v { color: var(--ok); }
.stat.warn .v { color: var(--warn); }
.stat.bad .v { color: var(--bad); }

/* ── panels ────────────────────────────────────────────────────────── */
.panel {
  background: var(--surface-1); border: 1px solid var(--border);
  border-radius: var(--radius); overflow: hidden; margin-bottom: 18px;
}
.panel > .p-head {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 15px; border-bottom: 1px solid var(--border);
}
.panel > .p-head h2 { font-size: 13px; font-weight: 600; margin: 0; }
.panel > .p-head .p-sub { font-size: 11.5px; color: var(--text-dim); }
.panel > .p-head .p-actions { margin-left: auto; display: flex; gap: 6px; }
.panel > .p-body { padding: 14px 15px; }
.panel > .p-body.flush { padding: 0; }
.panel.grid-2 { display: block; }

/* the ONE elevated centerpiece per page (dashboard's Fleet geography) —
   deliberately not applied broadly: a glass surface everywhere would flatten
   the hierarchy this is meant to create. Radius up a step, border a touch
   brighter, a real cast shadow instead of none, and a top highlight line —
   the same "lit surface" language as the KPI cards and active nav, just
   turned up because this is the page's hero element. */
.panel.hero {
  border-radius: var(--radius-lg);
  border-color: var(--glass-border);
  box-shadow: var(--elev-2), inset 0 1px 0 var(--glass-highlight);
}
.panel.hero > .p-head {
  background: linear-gradient(180deg, color-mix(in srgb, var(--surface-1) 100%, var(--text) 2%), var(--surface-1));
}
.cols-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
@media (max-width: 1100px) { .cols-2 { grid-template-columns: 1fr; } }

/* ── filter bar ────────────────────────────────────────────────────── */
.filters { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-bottom: 14px; }
.filters .fx { display: flex; flex-direction: column; gap: 3px; }
.filters .fx > span { font-size: 10px; color: var(--text-mute); letter-spacing: 0.4px; text-transform: uppercase; padding-left: 2px; }
.filters input, .filters select {
  background: var(--surface-1); color: var(--text);
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  padding: 6px 9px; font-size: 12.5px; min-width: 120px;
}
.filters input:focus, .filters select:focus { outline: none; border-color: var(--accent); }

/* ── buttons ───────────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--surface-2); color: var(--text);
  border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
  padding: 6px 12px; font-size: 12.5px; font-weight: 500; cursor: pointer;
}
.btn:hover { border-color: var(--accent); background: var(--surface-3); }
.btn:disabled { opacity: 0.45; cursor: not-allowed; }
.btn.primary {
  background: linear-gradient(180deg, color-mix(in srgb, var(--accent) 100%, #fff 8%), var(--accent));
  border-color: var(--accent); color: var(--on-accent);
  box-shadow: 0 1px 2px rgba(0,0,0,.15), inset 0 1px 0 rgba(255,255,255,.16);
}
.btn.primary:hover { filter: brightness(1.07); }
.btn.danger { background: var(--bad-bg); border-color: rgba(226,89,107,0.4); color: var(--bad); }
.btn.ghost { background: transparent; border-color: transparent; color: var(--text-dim); }
.btn.ghost:hover { background: var(--surface-2); color: var(--text); }
.btn.sm { padding: 4px 9px; font-size: 11.5px; }

/* ── tables ────────────────────────────────────────────────────────── */
/* ── data grid ─────────────────────────────────────────────────────────
   Fixed layout + a shared <colgroup>: header and body cells always align,
   and no value can shift a column. Wide tables scroll inside .table-wrap
   with the grid staying perfectly aligned. */
.table-wrap { overflow-x: auto; overflow-y: hidden; overscroll-behavior-x: contain; }
.table-wrap::-webkit-scrollbar { height: 8px; }
table.data { width: 100%; border-collapse: collapse; table-layout: fixed; font-size: 12.5px; }
table.data th, table.data td {
  padding: 0 14px; border-bottom: 1px solid var(--border);
  vertical-align: middle;
}
table.data td { height: 44px; color: var(--text); }
table.data.dense td { height: 38px; }
table.data thead { background: var(--surface-2); }
table.data th {
  height: 34px; background: var(--surface-2); border-bottom-color: var(--border-strong);
  color: var(--text-mute); font-weight: 600; font-size: 10px; letter-spacing: 0.6px; text-transform: uppercase;
}
table.data th .th-in { display: inline-flex; align-items: center; gap: 4px; }
table.data th.ta-r .th-in { flex-direction: row-reverse; }
table.data th.sortable { cursor: pointer; user-select: none; }
table.data th.sortable:hover { color: var(--text-dim); }
table.data th.sorted { color: var(--text); }
table.data th .arrow { opacity: .45; font-size: 9px; }
table.data th.sorted .arrow { opacity: .9; color: var(--accent-text); }

table.data td.ta-l, table.data th.ta-l { text-align: left; }
table.data td.ta-r, table.data th.ta-r { text-align: right; }
table.data td.ta-c, table.data th.ta-c { text-align: center; }
table.data td.ta-r { font-variant-numeric: tabular-nums; }
table.data td.clip { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
table.data td.wrap { white-space: normal; }
table.data td.mono, table.data td.mono * { font-family: var(--mono); font-size: 11px; }

table.data tbody tr:last-child td { border-bottom: none; }
table.data tr.row { cursor: pointer; }
table.data tr.row:hover td { background: var(--surface-2); }
table.data tr.row:active td { background: var(--surface-3); }

/* the shared "primary + secondary line" cell — identical height everywhere */
.cell-stack { display: flex; flex-direction: column; justify-content: center; gap: 2px; min-width: 0; width: 100%; }
.cell-stack .cs-1, .cell-stack .cs-2 { min-width: 0; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cell-stack .cs-1 { line-height: 1.25; }
.cell-stack .cs-2 { line-height: 1.2; font-size: 10.5px; color: var(--text-mute); font-family: var(--mono); }
td.ta-r .cell-stack { align-items: flex-end; }

.mono { font-family: var(--mono); font-size: 11.5px; }
.dim { color: var(--text-dim); }
.mute { color: var(--text-mute); }
.trunc { max-width: 240px; overflow: hidden; text-overflow: ellipsis; }

/* pagination */
.pager { display: flex; align-items: center; gap: 10px; padding: 11px 14px; border-top: 1px solid var(--border); font-size: 12px; color: var(--text-dim); }
.pager .spacer { flex: 1; }

/* ── pills / status ────────────────────────────────────────────────── */
.pill {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 9px; border-radius: 99px;
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.4px;
}
.pill .dot { width: 6px; height: 6px; border-radius: 99px; background: currentColor; }
.pill.ok    { background: var(--ok-bg);    color: var(--ok); }
.pill.warn  { background: var(--warn-bg);  color: var(--warn); }
.pill.bad   { background: var(--bad-bg);   color: var(--bad); }
.pill.muted { background: var(--muted-bg); color: var(--muted); }
.pill.accent{ background: var(--accent-weak); color: var(--accent-text); }

/* compact numeric count pills (health rollups in table cells) */
.count-pills { display: inline-flex; gap: 4px; align-items: center; }
.count-pill {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 20px; height: 18px; padding: 0 5px; border-radius: 5px;
  font-size: 11px; font-weight: 700; font-variant-numeric: tabular-nums;
}
.count-pill.ok    { background: var(--ok-bg);    color: var(--ok); }
.count-pill.warn  { background: var(--warn-bg);  color: var(--warn); }
.count-pill.bad   { background: var(--bad-bg);   color: var(--bad); }
.count-pill.muted { background: var(--muted-bg); color: var(--muted); }
.count-pill.accent{ background: var(--accent-weak); color: var(--accent-text); }

/* ── key/value ─────────────────────────────────────────────────────── */
.kv { display: grid; grid-template-columns: 170px 1fr; gap: 8px 16px; font-size: 12.5px; }
.kv .k { color: var(--text-dim); }
.kv .v { color: var(--text); word-break: break-word; }

/* ── data states ──────────────────────────────────────────────────── */
.state { display: grid; place-items: center; padding: 46px 20px; text-align: center; }
.state .ico { width: 30px; height: 30px; color: var(--text-mute); margin-bottom: 12px; }
.state .t { font-size: 13.5px; color: var(--text-dim); }
.state .s { font-size: 12px; color: var(--text-mute); margin-top: 4px; max-width: 380px; }
.state .btn { margin-top: 14px; }
.state.error .ico { color: var(--bad); }

.skeleton { background: linear-gradient(90deg, var(--surface-2) 25%, var(--surface-3) 37%, var(--surface-2) 63%); background-size: 400% 100%; animation: sk 1.4s ease infinite; border-radius: 6px; }
@keyframes sk { 0% { background-position: 100% 0; } 100% { background-position: -100% 0; } }
.sk-row { height: 34px; margin: 6px 0; }
.sk-stat { height: 84px; }

/* ── bars (adoption / distribution) ───────────────────────────────── */
.bar-list { display: flex; flex-direction: column; gap: 9px; }
.bar-row { display: grid; grid-template-columns: 140px 1fr 74px; gap: 12px; align-items: center; font-size: 12px; }
.bar-row .lbl { color: var(--text-dim); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bar-track { height: 8px; background: var(--surface-3); border-radius: 99px; overflow: hidden; }
.bar-fill { height: 100%; background: var(--accent); border-radius: 99px; }
.bar-fill.ok { background: var(--ok); }
.bar-fill.warn { background: var(--warn); }
.bar-fill.bad { background: var(--bad); }
.bar-row .amt { text-align: right; font-variant-numeric: tabular-nums; color: var(--text); }

/* inline mini-bar for a table cell (adoption %, etc.) */
.bar-inline { display: inline-flex; align-items: center; gap: 7px; justify-content: flex-end; font-variant-numeric: tabular-nums; }
.bar-inline .bi-track { width: 42px; height: 5px; border-radius: 99px; background: var(--surface-3); overflow: hidden; }
.bar-inline .bi-fill { display: block; height: 100%; border-radius: 99px; background: var(--accent); }

/* ── donut ─────────────────────────────────────────────────────────── */
.donut-wrap { display: flex; align-items: center; gap: 20px; flex-wrap: wrap; }
.donut { width: 132px; height: 132px; flex: none; }
.donut-legend { display: flex; flex-direction: column; gap: 7px; font-size: 12px; }
.donut-legend .li { display: flex; align-items: center; gap: 8px; }
.donut-legend .sw { width: 9px; height: 9px; border-radius: 3px; flex: none; }
.donut-legend .n { color: var(--text-dim); }
.donut-legend .c { margin-left: auto; font-variant-numeric: tabular-nums; }

/* ── dialog ────────────────────────────────────────────────────────── */
dialog {
  border: 1px solid var(--border-strong); border-radius: var(--radius);
  background: var(--surface-1); color: var(--text);
  padding: 0; max-width: 480px; width: calc(100vw - 40px);
  box-shadow: var(--shadow);
}
dialog::backdrop { background: var(--backdrop); backdrop-filter: blur(2px); }
dialog .d-head { padding: 16px 18px 12px; border-bottom: 1px solid var(--border); }
dialog .d-head h3 { margin: 0; font-size: 14.5px; }
dialog .d-head p { margin: 4px 0 0; font-size: 12px; color: var(--text-dim); }
dialog .d-body { padding: 16px 18px; }
dialog .d-foot { padding: 12px 18px; border-top: 1px solid var(--border); display: flex; justify-content: flex-end; gap: 8px; }
dialog .d-body .err, .p-body .err { color: var(--bad); font-size: 12px; min-height: 15px; margin-top: 8px; }
.hint { font-size: 11.5px; color: var(--text-mute); margin-top: 6px; }
.cols-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; }
@media (max-width: 1100px) { .cols-3 { grid-template-columns: 1fr; } }

.credential-reveal {
  background: var(--bg); border: 1px solid var(--warn);
  border-radius: var(--radius-sm); padding: 14px; margin: 4px 0;
}
.credential-reveal .cap { font-size: 11px; color: var(--warn); font-weight: 700; letter-spacing: 0.4px; text-transform: uppercase; margin-bottom: 8px; }
.credential-reveal code { display: block; font-family: var(--mono); font-size: 12px; word-break: break-all; color: var(--text); background: var(--surface-2); padding: 10px; border-radius: 6px; }
.credential-reveal .warn-line { font-size: 11.5px; color: var(--text-dim); margin-top: 9px; }
/* Device approvals: dim row actions while the list refreshes */
[aria-busy="true"] [data-dev-action] { opacity: .5; pointer-events: none; }
/* Device approvals: consequence notes inside confirmation dialogs */
.dev-warn { margin-top: 10px; padding: 9px 11px; border-radius: var(--radius-sm); background: var(--warn-bg); border: 1px solid var(--warn); font-size: 12px; color: var(--text); line-height: 1.45; }
/* Installation detail: reconcile result tone */
.dev-warn[data-reconcile-result="ok"] { background: var(--ok-bg); border-color: var(--ok); }
.dev-warn[data-reconcile-result="bad"] { background: var(--bad-bg); border-color: var(--bad); }

/* ── misc ──────────────────────────────────────────────────────────── */
.toast-host { position: fixed; right: 18px; bottom: 18px; z-index: 40; display: flex; flex-direction: column; gap: 8px; }
.toast {
  background: var(--surface-3); border: 1px solid var(--border-strong);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius-sm); padding: 10px 14px; font-size: 12.5px;
  box-shadow: var(--shadow); max-width: 340px;
}
.toast.ok { border-left-color: var(--ok); }
.toast.bad { border-left-color: var(--bad); }

.inline-copy { cursor: pointer; color: var(--text-dim); }
.inline-copy:hover { color: var(--accent-text); }

.chips { display: flex; flex-wrap: wrap; gap: 5px; }
.chip { font-size: 10.5px; padding: 2px 7px; border-radius: 5px; background: var(--surface-3); color: var(--text-dim); }
.chip.on { background: var(--accent-weak); color: var(--accent-text); }

.rel-time { cursor: default; }

/* ── motion ───────────────────────────────────────────────────────────
   Restrained: short, eased, geometry + opacity only (no colour tricks),
   and only on a route change — polled re-renders don't re-animate. */
.stat { transition: border-color .14s ease, transform .14s ease; }
a.stat:hover, .stat.interactive:hover { transform: translateY(-1px); }
.bar-fill { transform-origin: left center; transition: width .5s cubic-bezier(.4,0,.2,1); }
#page.route-enter .bar-fill { animation: cc-bar .55s cubic-bezier(.4,0,.2,1) both; }
@keyframes cc-bar { from { transform: scaleX(0); } to { transform: scaleX(1); } }
.bar-row { transition: opacity .12s ease; }
.bar-list:hover .bar-row { opacity: .55; }
.bar-list .bar-row:hover { opacity: 1; }
.bar-row[data-row-id] { cursor: pointer; }
.donut-legend .li { transition: opacity .12s ease; }
.donut-wrap:hover .donut-legend .li { opacity: .5; }
.donut-wrap .donut-legend .li:hover { opacity: 1; }

#page.route-enter > * { animation: cc-rise .3s ease both; }
#page.route-enter > *:nth-child(2) { animation-delay: .04s; }
#page.route-enter > *:nth-child(3) { animation-delay: .08s; }
#page.route-enter > *:nth-child(n+4) { animation-delay: .1s; }
#page.route-enter .stat { animation: cc-rise .34s ease both; }
#page.route-enter .stat:nth-child(2) { animation-delay: .03s; }
#page.route-enter .stat:nth-child(3) { animation-delay: .06s; }
#page.route-enter .stat:nth-child(4) { animation-delay: .09s; }
#page.route-enter .stat:nth-child(n+5) { animation-delay: .12s; }
#page.route-enter .donut { animation: cc-pop .42s cubic-bezier(.2,.7,.2,1) both; }

@keyframes cc-rise { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
@keyframes cc-pop  { from { opacity: 0; transform: scale(.94); } to { opacity: 1; transform: none; } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important; animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
}

/* ── fleet geography ─────────────────────────────────────────────────── */
.geo-wrap { display: grid; grid-template-columns: 1fr 288px; gap: 18px; align-items: start; }
@media (max-width: 1180px) { .geo-wrap { grid-template-columns: 1fr; } }
.geo-map {
  position: relative;
  /* atmospheric light source: a soft radial wash centred slightly above
     middle, darkening toward the corners — the "ocean" SVG rect below is
     made partially transparent (see .geo-ocean) so this shows through it.
     This is the map's own depth cue and needs nothing from the SVG/JS side. */
  background: radial-gradient(120% 90% at 50% 38%, color-mix(in srgb, var(--map-ocean) 78%, var(--text) 6%) 0%, var(--map-ocean) 62%, color-mix(in srgb, var(--map-ocean) 88%, #000 14%) 100%);
  border: 1px solid var(--glass-border); border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--elev-3);
}
.geo-svg { display: block; width: 100%; height: auto; max-height: 440px; }
.geo-ocean { fill: color-mix(in srgb, var(--map-ocean) 45%, transparent); }
.geo-map::after {
  /* vignette + a faint top highlight, layered on the same pseudo-element —
     the "glass dome over a lit tabletop map" read this whole treatment is
     going for, at rest, no hover/JS required */
  content: ""; position: absolute; inset: 0; pointer-events: none; border-radius: inherit;
  box-shadow: inset 0 0 90px -30px var(--map-border-strong), inset 0 1px 0 var(--glass-highlight);
}

/* breadcrumb (World / Africa / Nigeria) + back */
.geo-crumbs {
  position: absolute; top: 8px; left: 8px; right: 8px; z-index: 2;
  display: flex; align-items: center; gap: 5px; flex-wrap: wrap;
  background: color-mix(in srgb, var(--surface-1) 84%, transparent);
  backdrop-filter: blur(6px); padding: 4px 7px; border-radius: 8px; border: 1px solid var(--border);
  font-size: 11.5px; box-shadow: var(--shadow);
}
.geo-back {
  font: inherit; line-height: 1; color: var(--text-dim); background: var(--surface-2);
  border: 1px solid var(--border); border-radius: 5px; padding: 2px 7px; margin-right: 3px; cursor: pointer;
}
.geo-back:hover { color: var(--text); border-color: var(--border-strong); }
.geo-cr { font: inherit; color: var(--text-dim); background: transparent; border: 0; padding: 2px 4px; cursor: pointer; border-radius: 4px; }
.geo-cr:hover { color: var(--accent-text); background: var(--surface-2); }
.geo-cr.cur { color: var(--text); font-weight: 600; cursor: default; }
.geo-cr.cur:hover { background: transparent; }
.geo-sep { color: var(--text-mute); }

/* the zoomable scene — one CSS-eased transform per geographic level */
.geo-scene { transform-box: view-box; transform-origin: 0 0; transition: transform .6s cubic-bezier(.3,.7,.25,1); }
.geo-markers circle, .geo-markers text, .geo-labels text {
  transition: r .6s cubic-bezier(.3,.7,.25,1), font-size .6s cubic-bezier(.3,.7,.25,1);
}

/* real country geometry — subtle, precise, theme-aware */
.geo-cp {
  fill: var(--map-land-2); stroke: var(--map-border); stroke-width: 0.5;
  stroke-linejoin: round; vector-effect: non-scaling-stroke;
  transition: fill .3s ease, opacity .3s ease;
}
/* "fleet" territory (has installations) reads as gently raised terrain — a
   gentle drop-shadow per path is the cheapest pseudo-extrusion CSS/SVG can
   do without a rendering engine, and it's applied by class (not per-frame),
   so the cost is one paint on drill-down, not an animation tax. */
.geo-cp.fleet { fill: var(--map-land); filter: drop-shadow(0 1px 1.5px rgba(0,0,0,.28)); }
.geo-cp.focus { fill: var(--map-land); stroke: var(--map-border-strong); filter: drop-shadow(0 1px 2px rgba(0,0,0,.32)); }
.geo-cp.dim   { fill: var(--map-land-2); opacity: .45; }
.geo-cp.sel   {
  fill: color-mix(in srgb, var(--accent) 12%, var(--map-land)); stroke: var(--map-selected); stroke-width: 1.1;
  filter: drop-shadow(0 2px 4px rgba(0,0,0,.38)) drop-shadow(0 0 5px var(--glow-accent));
}
.geo-wrap[data-geo-level="continent"] .geo-cp:not(.dim),
.geo-wrap[data-geo-level="world"] .geo-cp.fleet { cursor: pointer; }
.geo-cp:not(.dim):hover { fill: color-mix(in srgb, var(--accent) 10%, var(--map-land)); }

/* country subdivisions (admin-1) — visible, slightly stronger than borders */
.geo-rp {
  fill: color-mix(in srgb, var(--accent) 7%, var(--map-land));
  stroke: var(--map-border-strong); stroke-width: 0.8;
  stroke-linejoin: round; vector-effect: non-scaling-stroke;
  filter: drop-shadow(0 1px 1.5px rgba(0,0,0,.22));
}
.geo-rp.sel {
  fill: color-mix(in srgb, var(--accent) 20%, var(--map-land)); stroke: var(--map-selected);
  filter: drop-shadow(0 2px 4px rgba(0,0,0,.35)) drop-shadow(0 0 4px var(--glow-accent));
}

.geo-marker { cursor: pointer; outline: none; transform-box: fill-box; transform-origin: center; }
.geo-shadow { fill: rgba(0,0,0,.32); pointer-events: none; }
.geo-marker.t-muted .geo-shadow { fill: rgba(0,0,0,.18); }
.geo-marker .geo-dot {
  fill: var(--map-marker); stroke: var(--surface-1); stroke-width: 1; vector-effect: non-scaling-stroke;
  filter: drop-shadow(0 1.5px 2px rgba(0,0,0,.4));
}
.geo-marker.t-ok    .geo-dot, .geo-marker.t-ok    .geo-glow { fill: var(--map-ok); }
.geo-marker.t-warn  .geo-dot, .geo-marker.t-warn  .geo-glow { fill: var(--map-warn); }
.geo-marker.t-bad   .geo-dot, .geo-marker.t-bad   .geo-glow { fill: var(--map-bad); }
.geo-marker.t-muted .geo-dot, .geo-marker.t-muted .geo-glow { fill: var(--map-muted); }
.geo-marker .geo-count {
  fill: var(--on-accent); font-weight: 700; text-anchor: middle; pointer-events: none;
  paint-order: stroke; stroke: color-mix(in srgb, #000 22%, transparent); stroke-width: .4px;
}
/* filter is not additive across rules — repeat the resting drop-shadow here
   too, or hover/focus would silently replace it with brightness() alone
   and the dot would go flat exactly when it's being interacted with */
.geo-marker:hover .geo-dot, .geo-marker:focus-visible .geo-dot { filter: brightness(1.12) drop-shadow(0 1.5px 2px rgba(0,0,0,.4)); }
.geo-marker:focus-visible .geo-dot { outline: 2px solid var(--accent); outline-offset: 2px; }

.geo-labels .geo-label.off { display: none; }
.geo-labels text {
  /* centered directly above its marker — see geomap.js's labelAnchor(),
     which derives this position from the marker's own (x, y) coordinate */
  fill: var(--map-label); font-weight: 600; text-anchor: middle; pointer-events: none;
  paint-order: stroke; stroke: var(--map-ocean); stroke-width: 3px; stroke-linejoin: round;
}

/* breathing glow — slow, subtle, health-toned; CSS-only; halo behind the dot */
.geo-glow {
  transform-box: fill-box; transform-origin: center; opacity: 0;
  animation: geo-breathe 4.6s ease-in-out infinite; animation-delay: var(--gd, 0s);
}
.geo-marker.t-bad .geo-glow { animation-duration: 3.8s; }
.geo-marker.t-muted .geo-glow { animation: none; }
@keyframes geo-breathe {
  0%, 100% { transform: scale(.8);  opacity: .05; }
  50%      { transform: scale(1.5); opacity: .16; }
}
#page.route-enter .geo-marker { animation: cc-pop .5s cubic-bezier(.2,.7,.2,1) both; }

@media (prefers-reduced-motion: reduce) {
  .geo-scene, .geo-markers circle, .geo-markers text, .geo-labels text, .geo-cp, .geo-rp { transition: none; }
  .geo-glow { animation: none; opacity: .07; transform: scale(1.15); }
}

.geo-aside { min-width: 0; }
.geo-legend { display: flex; gap: 14px; font-size: 11px; color: var(--text-dim); margin-bottom: 8px; }
.geo-legend i { display: inline-block; width: 8px; height: 8px; border-radius: 2px; margin-right: 5px; vertical-align: middle; }
.geo-legend i.ok { background: var(--ok); } .geo-legend i.warn { background: var(--warn); } .geo-legend i.bad { background: var(--bad); }
.geo-unavail { font-size: 11.5px; color: var(--text-dim); margin: 4px 0 10px; }
.geo-unavail .geo-cr { display: block; margin-top: 4px; color: var(--accent-text); padding: 0; }
.geo-list { list-style: none; margin: 0; padding: 0; max-height: 300px; overflow-y: auto; }
.geo-row {
  display: grid; grid-template-columns: 1fr 66px 34px; align-items: center; gap: 8px;
  padding: 6px 5px; border-radius: 6px; cursor: pointer; font-size: 12px; outline: none;
}
.geo-row:hover, .geo-row:focus-visible { background: var(--surface-2); }
.geo-row .gl-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.geo-row .gl-bar { display: flex; height: 6px; border-radius: 99px; overflow: hidden; background: var(--surface-3); }
.geo-row .gl-seg.ok { background: var(--ok); } .geo-row .gl-seg.warn { background: var(--warn); }
.geo-row .gl-seg.bad { background: var(--bad); } .geo-row .gl-seg.muted { background: var(--muted); }
.geo-row .gl-n { text-align: right; font-variant-numeric: tabular-nums; color: var(--text-dim); }

/* ── dev preview banner ───────────────────────────────────────────── */
#devBanner {
  position: fixed; left: 50%; bottom: 14px; transform: translateX(-50%);
  z-index: 50; display: flex; align-items: center; gap: 8px;
  background: var(--surface-3); border: 1px solid var(--warn);
  color: var(--text-dim); font-size: 11.5px; padding: 6px 12px; border-radius: 99px;
  box-shadow: var(--shadow); pointer-events: none;
}
#devBanner::before { content: ""; width: 6px; height: 6px; border-radius: 99px; background: var(--warn); }

/* ── responsive ───────────────────────────────────────────────────── */
@media (max-width: 940px) {
  :root { --nav-w: 0px; }
  #app { grid-template-columns: 1fr; }
  nav#sidebar {
    position: fixed; left: 0; top: 0; z-index: 30; width: 244px;
    transform: translateX(-100%); transition: transform 0.18s ease;
  }
  #app.nav-open nav#sidebar { transform: translateX(0); }
  #app.nav-open::after { content: ""; position: fixed; inset: 0; background: var(--overlay); z-index: 25; }
  .topbar .menu-btn { display: inline-flex; }
  .search-box { max-width: none; width: auto; flex: 1; }
}
.topbar .menu-btn { display: none; }
