/* Mulligan Dispatch - the operations console for Mulligan's fleet of mobile
   batteries, in Mulligan's own colours: a black ground, white ink, and one
   acid yellow (#E3FF42) kept for what you act on - the primary action, the
   selected thing, and island mode, the battery carrying the consumer alone.
   Status keeps its own small vocabulary of marks (green run, amber warn,
   red trip), never the brand yellow, so "selected" and "fine" cannot be
   confused at a glance.

   Type: Archivo Black for the wordmark, page titles and the mode a unit is
   in - the few things read from across a room - and Space Grotesk for
   everything else, data included, with tabular figures.

   Two themes, one system. Dark is the brand. Light is the same drawing on
   paper for a sunlit screen: yellow survives there only as a fill under
   black ink, so every line, focus ring and mark that is yellow in dark is
   drawn from --accent-ink, which is near-black in light. Everything a theme
   can change is a token below; nothing further down names a colour.
   theme.js sets data-theme on <html>. */

@font-face { font-family: "Space Grotesk"; font-style: normal; font-weight: 400; font-display: swap;
  src: url("/static/fonts/space-grotesk-latin-400-normal.woff2") format("woff2"); }
@font-face { font-family: "Space Grotesk"; font-style: normal; font-weight: 500; font-display: swap;
  src: url("/static/fonts/space-grotesk-latin-500-normal.woff2") format("woff2"); }
@font-face { font-family: "Space Grotesk"; font-style: normal; font-weight: 600; font-display: swap;
  src: url("/static/fonts/space-grotesk-latin-600-normal.woff2") format("woff2"); }
@font-face { font-family: "Space Grotesk"; font-style: normal; font-weight: 700; font-display: swap;
  src: url("/static/fonts/space-grotesk-latin-700-normal.woff2") format("woff2"); }
@font-face { font-family: "Archivo Black"; font-style: normal; font-weight: 400; font-display: swap;
  src: url("/static/fonts/archivo-black-latin-400-normal.woff2") format("woff2"); }

:root {
  /* -- brand ----------------------------------------------------------------- */
  --brand: #E3FF42;
  --accent: #E3FF42;            /* fills: the primary action, the selection */
  --on-accent: #000000;
  --accent-ink: #E3FF42;        /* lines and marks drawn in the accent */
  --accent-soft: rgba(227,255,66,.12);

  /* -- surfaces ---------------------------------------------------------- */
  --bg: #000000;
  --raise: #0D0D0D;
  --bg-2: #141414;
  --surface: #161616;
  --rule: rgba(255,255,255,.09);
  --rule-2: rgba(255,255,255,.18);
  --inset: rgba(255,255,255,.08);
  --panel-shadow: none;
  --topbar-bg: rgba(0,0,0,.86);
  --scrim: rgba(0,0,0,.74);

  /* -- ink --------------------------------------------------------------- */
  --text: #FFFFFF;
  --text-2: #C2C2C2;
  --text-3: #929292;
  --text-4: #5E5E5E;

  /* -- state: marks, never filled panels --------------------------------- */
  --run: #3DDC84;
  --warn: #FFA621;
  --trip: #FF4D42;
  --man: #6CB4FF;

  /* -- interactive fills -------------------------------------------------- */
  --track: rgba(255,255,255,.07);
  --track-hi: rgba(255,255,255,.12);
  --fill: rgba(255,255,255,.10);
  --fill-hi: rgba(255,255,255,.16);
  --on-fill: rgba(255,255,255,.16);
  --on-shadow: none;
  --row-hover: rgba(255,255,255,.045);
  --focus: rgba(227,255,66,.30);
  --notice-fill: rgba(255,255,255,.06);
  --danger-fill: #FF4D42;
  --danger-fill-hi: #FF6A61;
  --danger-ink: #000000;
  --danger-soft: rgba(255,77,66,.16);
  --tint-trip: rgba(255,77,66,.08);
  --tint-trip-2: rgba(255,77,66,.12);
  --tint-warn: rgba(255,166,33,.06);
  --tint-warn-2: rgba(255,166,33,.10);
  --dim-op: .3;

  /* -- things that float -------------------------------------------------- */
  --pop-bg: rgba(22,22,22,.97);
  --pop-shadow: 0 10px 28px rgba(0,0,0,.6);
  --modal-shadow: 0 28px 72px rgba(0,0,0,.7);
  --toast-shadow: 0 12px 32px rgba(0,0,0,.6);

  /* -- chart chrome: read by chart.js at draw time ------------------------ */
  --ch-label: #929292;
  --ch-grid: rgba(255,255,255,.06);
  --ch-base: rgba(255,255,255,.18);
  --ch-limit: rgba(255,255,255,.24);
  --ch-cursor: rgba(255,255,255,.4);
  --ch-band: rgba(255,255,255,.08);
  --ch-hover: rgba(255,255,255,.045);
  --ch-zoom: rgba(227,255,66,.14);
  --ch-soc-band: rgba(90,200,250,.16);

  /* -- series: the consumer is the customer's, so it carries the brand ---- */
  --s-out: #E3FF42;
  --s-grid: #FFFFFF;
  --s-grid-2: #8E8E8E;
  --s-bess: #5AC8FA;
  --s-bess-2: #2C8CC4;
  --s-base: #8E8E8E;
  --s-l2: #C2C2C2;
  --s-l3: #8E8E8E;
  --s-low: #FFA621;
  --s-island: #E3FF42;
  --s-auto: #2E7D52;
  --s-run-dim: #1F4D33;
  --s-idle: rgba(255,255,255,.22);
  --s-grid-idle: rgba(255,255,255,.12);
  --bess-1: #5AC8FA; --bess-2: #B48CFF; --bess-3: #2C8CC4; --bess-4: #8A6CD8;
  --bess-5: #7FE0FF; --bess-6: #D4BCFF; --bess-7: #1E6FA0; --bess-8: #6A4FB8;

  --display: "Archivo Black", "Arial Black", sans-serif;
  --sans: "Space Grotesk", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto,
          "Helvetica Neue", Arial, sans-serif;
  --mono: ui-monospace, "SF Mono", "Cascadia Mono", Consolas, monospace;
  --r-panel: 6px;
  --r-ctl: 3px;
  --gut: 28px;
  --pad: 24px;
  --ease: cubic-bezier(.22,1,.36,1);
  color-scheme: dark;
}

/* ---- light: the same drawing on paper ------------------------------------
   The brand's paper grey and black ink. Every value restruck by hand: state
   colours taken down until each clears 5:1 on white, series darkened until
   they read as lines, and the yellow kept only where black sits on it. */
:root[data-theme="light"] {
  --accent: #E3FF42;
  --on-accent: #000000;
  --accent-ink: #111111;
  --accent-soft: rgba(110,128,0,.10);

  --bg: #F5F5F5;
  --raise: #FFFFFF;
  --bg-2: #F7F7F7;
  --surface: #FFFFFF;
  --rule: rgba(0,0,0,.10);
  --rule-2: rgba(0,0,0,.22);
  --inset: rgba(0,0,0,.09);
  --panel-shadow: 0 1px 2px rgba(0,0,0,.05);
  --topbar-bg: rgba(245,245,245,.88);
  --scrim: rgba(0,0,0,.36);

  --text: #000000;
  --text-2: #3D3D3D;
  --text-3: #626262;
  --text-4: #9C9C9C;

  --run: #157A3E;
  --warn: #9A5200;
  --trip: #C4130A;
  --man: #0B5CB5;

  --track: rgba(0,0,0,.055);
  --track-hi: rgba(0,0,0,.12);
  --fill: rgba(0,0,0,.075);
  --fill-hi: rgba(0,0,0,.13);
  --on-fill: #FFFFFF;
  --on-shadow: 0 1px 2px rgba(0,0,0,.14), 0 0 0 .5px rgba(0,0,0,.05);
  --row-hover: rgba(0,0,0,.035);
  --focus: rgba(0,0,0,.18);
  --notice-fill: rgba(0,0,0,.045);
  --danger-fill: #C4130A;
  --danger-fill-hi: #A50F07;
  --danger-ink: #FFFFFF;
  --danger-soft: rgba(196,19,10,.09);
  --tint-trip: rgba(196,19,10,.06);
  --tint-trip-2: rgba(196,19,10,.08);
  --tint-warn: rgba(154,82,0,.06);
  --tint-warn-2: rgba(154,82,0,.09);
  --dim-op: .34;

  --pop-bg: rgba(255,255,255,.97);
  --pop-shadow: 0 10px 28px rgba(0,0,0,.14);
  --modal-shadow: 0 28px 72px rgba(0,0,0,.22);
  --toast-shadow: 0 12px 32px rgba(0,0,0,.18);

  --ch-label: #626262;
  --ch-grid: rgba(0,0,0,.07);
  --ch-base: rgba(0,0,0,.26);
  --ch-limit: rgba(0,0,0,.30);
  --ch-cursor: rgba(0,0,0,.45);
  --ch-band: rgba(0,0,0,.08);
  --ch-hover: rgba(0,0,0,.045);
  --ch-zoom: rgba(110,128,0,.14);
  --ch-soc-band: rgba(11,92,181,.12);

  --s-out: #6E8000;
  --s-grid: #111111;
  --s-grid-2: #8A8A8A;
  --s-bess: #0B6FC9;
  --s-bess-2: #0A4F8F;
  --s-base: #8A8A8A;
  --s-l2: #555555;
  --s-l3: #9C9C9C;
  --s-low: #9A5200;
  --s-island: #B8D400;
  --s-auto: #9ED9B5;
  --s-run-dim: #C2E8CF;
  --s-idle: rgba(0,0,0,.22);
  --s-grid-idle: rgba(0,0,0,.12);
  --bess-1: #0B6FC9; --bess-2: #6B3FC4; --bess-3: #0A4F8F; --bess-4: #8A5CD6;
  --bess-5: #1E8FBF; --bess-6: #5130A0; --bess-7: #08436F; --bess-8: #9A7AE0;

  color-scheme: light;
}

* { box-sizing: border-box; }
html, body { margin: 0; background: var(--bg); color: var(--text); }
body {
  font: 400 13.5px/1.45 var(--sans);
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
  min-height: 100vh;
}
::selection { background: var(--accent); color: var(--on-accent); }
* { scrollbar-color: var(--track-hi) transparent; }
a { color: inherit; text-decoration: none; }
button, input, select { font: inherit; color: inherit; }
[hidden] { display: none !important; }
:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: 2px; border-radius: var(--r-ctl); }

/* ---- top bar ------------------------------------------------------------ */
.topbar {
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; gap: 24px;
  padding: 12px var(--gut);
  background: var(--topbar-bg);
  backdrop-filter: saturate(180%) blur(20px);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  border-bottom: 1px solid var(--rule);
}
/* The wordmark: Mulligan's own logo (static/brand, yellow on transparent),
   inked black on the light theme, with the product name set small beside it. */
.wordmark { display: inline-flex; align-items: center; gap: 10px; white-space: nowrap; line-height: 1; }
.wm-logo { display: block; height: 22px; width: auto; }
:root[data-theme="light"] .wm-logo { filter: brightness(0); }
.wm-product { font-weight: 600; font-size: 10.5px; letter-spacing: .24em; color: var(--text-3); }
.nav { display: flex; gap: 2px; }
.nav a {
  position: relative; padding: 6px 12px; color: var(--text-2); font-weight: 600;
  font-size: 12px; letter-spacing: .06em; text-transform: uppercase;
}
.nav a:hover { color: var(--text); }
.nav a.on { color: var(--text); }
.nav a.on::after {
  content: ""; position: absolute; left: 12px; right: 12px; bottom: -13px; height: 3px;
  background: var(--accent-ink);
}
.topbar .spacer { flex: 1; }
.who { color: var(--text-3); display: flex; align-items: center; gap: 12px; }
.who .email:hover { color: var(--text); }

/* ---- appearance: auto, light, dark -----------------------------------------
   Signs rather than words: the bar already carries five text labels, and the
   sun, the moon and the half-disc are read without being read. */
.theme-pick { display: inline-flex; gap: 2px; padding: 3px; border-radius: var(--r-ctl); background: var(--track); }
.theme-pick button {
  border: 0; background: transparent; cursor: pointer; color: var(--text-3);
  width: 30px; height: 22px; border-radius: 2px; display: grid; place-items: center;
  transition: color .15s var(--ease), background .15s var(--ease);
}
.theme-pick button:hover { color: var(--text); }
.theme-pick button[aria-pressed="true"] { background: var(--on-fill); box-shadow: var(--on-shadow); color: var(--text); }
.theme-pick svg { display: block; width: 15px; height: 15px; }

/* ---- layout ------------------------------------------------------------- */
main { max-width: 1680px; margin: 0 auto; padding: 22px var(--gut) 64px; }
.panel {
  background: var(--raise); border-radius: var(--r-panel);
  box-shadow: inset 0 0 0 1px var(--inset), var(--panel-shadow);
  padding: var(--pad); margin-bottom: 16px;
}
.panel > h2, .panel-head h2 {
  font-size: 15px; font-weight: 700; letter-spacing: -.005em; margin: 0;
}
.panel-head { display: flex; align-items: center; gap: 16px; margin-bottom: 16px; flex-wrap: wrap; }
.panel-head .spacer { flex: 1; }
.panel > h2 { margin-bottom: 16px; }
.cols { display: grid; gap: 16px; grid-template-columns: repeat(auto-fit, minmax(340px, 1fr)); }
.cols > .panel { margin-bottom: 0; }
.stack > * + * { margin-top: 16px; }

/* ---- type voices -------------------------------------------------------- */
.cap {
  font-size: 10.5px; font-weight: 600; letter-spacing: .12em; text-transform: uppercase;
  color: var(--text-3);
}
.reg, .mono { font-family: var(--mono); font-size: 11px; color: var(--text-3); }
.muted { color: var(--text-3); }
.dim { color: var(--text-2); }
.hero { display: flex; flex-wrap: wrap; gap: 12px 44px; align-items: flex-end; }
.hero .n { font-size: 60px; font-weight: 500; letter-spacing: -.04em; line-height: 1; }
.hero .u { font-size: 18px; font-weight: 500; color: var(--text-2); margin-left: 6px; }
.metric .v { font-size: 25px; font-weight: 500; letter-spacing: -.025em; line-height: 1.1; }
.metric .v small { font-size: 13px; color: var(--text-2); font-weight: 400; margin-left: 4px; letter-spacing: 0; }
.metric .s { color: var(--text-3); margin-top: 2px; font-size: 12px; }

.tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
.tiles > .metric { padding: 4px 20px 4px 0; }
.tiles > .metric + .metric { border-left: 1px solid var(--rule); padding-left: 20px; }

/* ---- marks: state never depends on colour alone ------------------------- */
.mark { display: inline-flex; align-items: center; gap: 7px; white-space: nowrap; }
.mark::before { content: ""; flex: none; width: 8px; height: 8px; background: currentColor; }
.m-ok::before, .m-dot::before { border-radius: 50%; }
.m-bad::before { border-radius: 1px; }
.m-warn::before { transform: rotate(45deg) scale(.86); border-radius: 1px; }
.m-dash::before { height: 2px; width: 9px; }
.m-ring::before { border-radius: 50%; background: transparent; box-shadow: inset 0 0 0 1.5px currentColor; }
.c-run { color: var(--run); } .c-warn { color: var(--warn); } .c-trip { color: var(--trip); }
.c-man { color: var(--man); } .c-dim { color: var(--text-3); } .c-text { color: var(--text); }
.mark > span { color: var(--text); }
.mark.quiet > span { color: var(--text-2); }
.m-dot.breathe::before { animation: breathe 2.4s var(--ease) infinite; }
@keyframes breathe { 50% { opacity: .35; } }

/* ---- controls ----------------------------------------------------------- */
.key {
  border: 0; border-radius: var(--r-ctl); padding: 7px 14px; cursor: pointer;
  background: var(--fill); color: var(--text); font-weight: 600; font-size: 12px;
  letter-spacing: .05em; text-transform: uppercase; line-height: 1.25;
  transition: background .15s var(--ease), transform .15s var(--ease), color .15s var(--ease);
}
.key:hover { background: var(--fill-hi); }
.key:active { transform: scale(.97); }
.key.armed { background: var(--accent); color: var(--on-accent); }
.key.armed:hover { background: var(--brand); filter: brightness(1.06); }
.key.ghost { background: transparent; color: var(--text-2); }
.key.ghost:hover { color: var(--text); background: var(--track); }
.key[disabled] { opacity: .38; cursor: not-allowed; transform: none; filter: none; }
.seg { display: inline-flex; padding: 3px; gap: 2px; border-radius: var(--r-ctl); background: var(--track); flex-wrap: wrap; }
.seg button { border: 0; background: transparent; padding: 4px 11px; border-radius: 2px; cursor: pointer; color: var(--text-2); font-weight: 500; }
.seg button:hover { color: var(--text); }
.seg button.on { background: var(--on-fill); box-shadow: var(--on-shadow); color: var(--text); }
input[type=text], input[type=email], input[type=password], input[type=search], input[type=date],
input[type=tel], input[type=month], select, textarea {
  background: var(--bg-2); border: 1px solid var(--rule-2); border-radius: var(--r-ctl);
  padding: 7px 10px; outline: none; min-width: 0;
}
textarea { font: inherit; resize: vertical; width: 100%; line-height: 1.5; }
input:focus, select:focus, textarea:focus { border-color: var(--accent-ink); box-shadow: 0 0 0 3px var(--focus); }
.key.danger { background: var(--danger-fill); color: var(--danger-ink); }
.key.danger:hover { background: var(--danger-fill-hi); }
.err { color: var(--trip); margin-top: 10px; }
.err:empty { display: none; }

/* ---- tables --------------------------------------------------------------- */
.scroll { overflow-x: auto; margin: 0 calc(var(--pad) * -1); padding: 0 var(--pad); }
table { width: 100%; border-collapse: collapse; }
th {
  text-align: left; font-size: 10.5px; font-weight: 600; letter-spacing: .1em;
  text-transform: uppercase; color: var(--text-3); padding: 0 12px 10px 0; white-space: nowrap;
}
td { padding: 11px 12px 11px 0; border-top: 1px solid var(--rule); vertical-align: middle; }
td.num, th.num { text-align: right; white-space: nowrap; }
tr.link { cursor: pointer; }
tbody tr.link:hover td { background: var(--row-hover); }
tr.hot td { background: var(--tint-trip); }
tr.warmish td { background: var(--tint-warn); }
tr.stale td { color: var(--text-3); }
td .sub { display: block; color: var(--text-3); font-size: 12px; margin-top: 1px; }
.kv { display: grid; grid-template-columns: minmax(140px, max-content) 1fr; gap: 8px 20px; margin: 0; }
.kv dt { color: var(--text-3); }
.kv dd { margin: 0; }

/* ---- conditions strip ----------------------------------------------------- */
.conds { display: flex; flex-wrap: wrap; gap: 8px 22px; }
.conds .mark > span { font-weight: 600; }

/* ---- notices ---------------------------------------------------------------- */
.notice {
  display: flex; gap: 10px; align-items: flex-start; border-radius: var(--r-panel);
  padding: 12px 16px; margin-bottom: 16px; background: var(--notice-fill); color: var(--text-2);
}
.notice::before { content: ""; width: 8px; height: 8px; border-radius: 50%; margin-top: 5px; flex: none; background: var(--text-3); }
.notice.warn { background: var(--tint-warn-2); } .notice.warn::before { background: var(--warn); }
.notice.bad { background: var(--tint-trip-2); } .notice.bad::before { background: var(--trip); border-radius: 1px; }
.notice b { color: var(--text); font-weight: 600; }

/* ---- stale data is suppressed, not styled ---------------------------------- */
.stale .dimmable { opacity: var(--dim-op); filter: saturate(0); transition: opacity .3s var(--ease); }

/* ---- bars --------------------------------------------------------------------- */
.meter-bar { position: relative; height: 3px; background: var(--track-hi); width: 72px; margin-top: 6px; overflow: hidden; }
.meter-bar i { position: absolute; inset: 0; background: var(--s-bess); transform-origin: left; transition: transform .3s var(--ease); }

/* ---- charts --------------------------------------------------------------------- */
.chart { position: relative; width: 100%; user-select: none; }
.chart canvas { display: block; touch-action: pan-y; }
.chart-tip {
  position: absolute; pointer-events: none; z-index: 5;
  background: var(--pop-bg); border-radius: var(--r-panel); padding: 8px 10px;
  box-shadow: var(--pop-shadow), inset 0 0 0 1px var(--rule-2); min-width: 150px;
}
.chart-tip-t { color: var(--text-3); font-size: 11px; margin-bottom: 4px; }
.chart-tip-r { display: grid; grid-template-columns: 10px 1fr auto; gap: 8px; align-items: center; font-size: 12px; }
.chart-tip-r i { width: 8px; height: 2px; }
.chart-tip-r b { font-weight: 500; }
.legend { display: flex; flex-wrap: wrap; gap: 4px 16px; }
.legend button { border: 0; background: none; padding: 2px 0; cursor: pointer; color: var(--text-2); display: inline-flex; align-items: center; gap: 7px; }
.legend button i { width: 14px; height: 2px; display: inline-block; }
.legend button.off { color: var(--text-4); }
.legend button.off i { opacity: .3; }
.chart-block + .chart-block { margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--rule); }
.chart-block .panel-head { margin-bottom: 8px; }

/* ---- site header ------------------------------------------------------------------ */
.site-head { display: flex; flex-wrap: wrap; gap: 14px 28px; align-items: flex-end; margin: 4px 0 18px; }
.site-head h1 {
  font-family: var(--display); font-weight: 400; font-size: 30px; line-height: 1.05;
  letter-spacing: -.01em; text-transform: uppercase; margin: 6px 0 4px; text-wrap: balance;
}
.site-head .spacer { flex: 1; }
.crumb { color: var(--text-3); }
.crumb:hover { color: var(--text); }

/* ---- login -------------------------------------------------------------------------- */
.login { min-height: 100vh; display: grid; place-items: center; padding: 24px; }
.login form { width: min(380px, 100%); }
.login .panel { padding: 32px; }
.login label { display: block; margin: 14px 0 6px; }
.login input { width: 100%; }
.login .err { color: var(--trip); min-height: 20px; margin-top: 12px; }
.login .err:empty { display: block; }
.login .head { display: flex; align-items: flex-start; gap: 16px; margin-bottom: 22px; }
.login .head .wordmark { flex: 1; }
.login .wm-logo { height: 38px; }
.login-lede { color: var(--text-2); margin: 0 0 8px; max-width: 32ch; }

.empty { color: var(--text-3); padding: 28px 0; text-align: center; }
.events td:first-child { width: 1%; }
.events .when { white-space: nowrap; color: var(--text-3); }
.pill { display: inline-block; font-size: 10.5px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--text-3); border: 1px solid var(--rule-2); border-radius: 2px; padding: 1px 6px; }
.loadmore { text-align: center; padding-top: 14px; }

/* ---- forms: one column of captioned controls, two when there is room ------- */
.form { display: grid; gap: 14px 20px; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }
.field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.field > .cap { cursor: inherit; }
.field input, .field select { width: 100%; }
.field .hint { color: var(--text-3); font-size: 12px; }
.field.wide { grid-column: 1 / -1; }
.stackfield { display: flex; flex-direction: column; gap: 8px; }
.actions { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 18px; }
.actions.end { justify-content: flex-end; margin-top: 0; }
.danger-row { margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--rule); }

.check { display: flex; gap: 10px; align-items: flex-start; cursor: pointer; padding: 6px 0; }
.check input { flex: none; margin: 2px 0 0; width: 15px; height: 15px; accent-color: var(--accent-ink); }
.check .sub { display: block; color: var(--text-3); font-size: 12px; margin-top: 1px; }

/* ---- the site picker: long enough to scroll, short enough to keep Save in view */
.picklist {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 2px 20px; max-height: 340px; overflow-y: auto;
  padding: 4px 10px; margin: 0 -10px;
  border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule);
}
.picklist .check:hover { background: var(--row-hover); border-radius: 8px; }

/* ---- modals ---------------------------------------------------------------- */
.modal {
  border: 0; padding: 0; color: var(--text); background: var(--surface);
  border-radius: var(--r-panel); box-shadow: var(--modal-shadow), inset 0 0 0 1px var(--rule-2);
  width: min(560px, calc(100vw - 32px)); max-height: calc(100vh - 48px);
  display: flex; flex-direction: column; overflow: hidden;
}
.modal::backdrop { background: var(--scrim); backdrop-filter: blur(3px); }
.modal-head {
  display: flex; align-items: center; gap: 16px;
  padding: 18px var(--pad) 12px; border-bottom: 1px solid var(--rule);
}
.modal-head h2 { font-size: 16px; font-weight: 700; letter-spacing: -.005em; margin: 0; flex: 1; }
.modal-head .x { padding: 4px 10px; }
.modal-body { padding: 18px var(--pad); overflow-y: auto; }
.modal-body p { margin: 0 0 14px; color: var(--text-2); }
.modal-body p.muted { margin-bottom: 0; }
.modal-foot {
  display: flex; justify-content: flex-end; gap: 10px;
  padding: 14px var(--pad); border-top: 1px solid var(--rule); background: var(--bg-2);
}

/* ---- a secret, shown once --------------------------------------------------- */
.secret-row { display: flex; gap: 10px; align-items: center; }
input.secret {
  flex: 1; font-family: var(--mono); font-size: 14px; letter-spacing: .02em;
  background: var(--bg); border-color: var(--rule-2);
}

/* ---- the line that says it worked -------------------------------------------- */
.toast {
  position: fixed; left: 50%; bottom: 28px; transform: translate(-50%, 12px); z-index: 60;
  padding: 10px 18px; border-radius: var(--r-panel); background: var(--surface); color: var(--text);
  box-shadow: var(--toast-shadow), inset 0 0 0 1px var(--rule-2);
  opacity: 0; pointer-events: none; transition: opacity .2s var(--ease), transform .2s var(--ease);
}
.toast.on { opacity: 1; transform: translate(-50%, 0); }

@media (max-width: 1100px) { :root { --gut: 20px; } }
@media (max-width: 820px) {
  :root { --pad: 18px; }
  .hero .n { font-size: 48px; }
  .topbar { gap: 12px; flex-wrap: wrap; }
  /* Shortened rather than hidden: it is the way to your own account page. */
  .who .email { max-width: 130px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
}
@media (max-width: 560px) {
  :root { --gut: 16px; }
  .nav { max-width: 100%; overflow-x: auto; scrollbar-width: none; }
  .nav a { white-space: nowrap; }
  .kv, .kv.tight { grid-template-columns: minmax(0, 1fr); gap: 2px 0; }
  .kv dd { margin-bottom: 8px; }
  .annun { gap: 8px; padding: 4px 10px; }
  .form { grid-template-columns: 1fr; }
  .picklist { grid-template-columns: 1fr; }
  .hero .n { font-size: 40px; }
  .tiles > .metric + .metric { border-left: 0; padding-left: 0; }
  .tiles { grid-template-columns: 1fr 1fr; gap: 12px; }
  .theme-pick button { width: 34px; height: 24px; }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before { animation-duration: .001ms !important; transition-duration: .001ms !important; }
}

/* ==========================================================================
   v3: operations
   ========================================================================== */

/* ---- the site diagram ----------------------------------------------------
   Monochrome drawing, series colour only where power moves. The dots are a
   dashed stroke whose offset runs; stopped, they are still dots, so a still
   frame (a print, a reduced-motion setting) still says which way it flows,
   and the arrow at mid-line says it again for anyone who cannot tell hues. */
.dg { display: grid; grid-template-columns: minmax(0, 1fr) 300px; gap: 20px; align-items: start; }
.dg-canvas { overflow-x: auto; padding-bottom: 4px; min-width: 0; }
.dg-svg { display: block; margin: 0 auto; width: 100%; height: auto; font-family: var(--sans); }
.dg-inspector { border-left: 1px solid var(--rule); padding-left: 20px; min-height: 100%; }
.dg-inspector h3 { font-size: 17px; font-weight: 700; letter-spacing: -.01em; margin: 4px 0 2px; }
.dg-alarms { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.dg-alarms .sub { display: block; color: var(--text-3); font-size: 12px; margin-left: 15px; }
.dg-foot { margin-top: 14px; display: grid; gap: 8px; }
.dg-foot p { margin: 0; }
.dg-foot .mark { white-space: normal; align-items: flex-start; }
.dg-foot .mark::before { margin-top: 4px; }
.kv.tight { gap: 5px 14px; font-size: 12.5px; grid-template-columns: minmax(110px, max-content) 1fr; }

.dg-bus { stroke: var(--text-3); stroke-width: 5; stroke-linecap: round; }
.dg-tap { fill: var(--text-3); }
.dg-line { fill: none; stroke: var(--rule-2); stroke-width: 2; }
.dg-flow {
  fill: none; stroke-width: 3.2; stroke-linecap: round; stroke-dasharray: .1 11.9;
  opacity: 0; transition: opacity .3s var(--ease);
  animation: dg-flow 1.2s linear infinite;
}
.dg-flow.on { opacity: 1; }
@keyframes dg-flow { to { stroke-dashoffset: -12; } }
.dg-arrow { fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.dg-arrow { stroke: currentColor; }
.dg-arrow-g { opacity: 0; transition: opacity .3s var(--ease); }
.dg-arrow-g.on { opacity: 1; }
.fl-grid { stroke: var(--s-grid); color: var(--s-grid); }
.fl-bess { stroke: var(--s-bess); color: var(--s-bess); }
.fl-out { stroke: var(--s-out); color: var(--s-out); }

.dg-node { cursor: pointer; outline: none; }
.dg-card { fill: var(--bg-2); stroke: var(--rule-2); stroke-width: 1; transition: stroke .15s var(--ease); }
.dg-node:hover .dg-card { stroke: var(--text-3); }
.dg-node.on .dg-card { stroke: var(--accent-ink); stroke-width: 1.6; }
.dg-node:focus-visible .dg-card { stroke: var(--accent-ink); stroke-width: 2.4; }
.dg-card.alarm { fill: var(--tint-trip); }
.dg-icon path { fill: none; stroke: var(--text-2); stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.dg-label { fill: var(--text); font-size: 13px; font-weight: 700; letter-spacing: -.005em; }
.dg-value { fill: var(--text); font-size: 20px; font-weight: 500; letter-spacing: -.025em; font-variant-numeric: tabular-nums; }
.dg-sub { fill: var(--text-3); font-size: 11.5px; }
.dg-small { fill: var(--text-3); font-size: 10.5px; font-family: var(--mono); }
.dg-cap { fill: var(--text-4); font-size: 9.5px; font-weight: 600; letter-spacing: .13em; }
.dg-meter circle { fill: var(--raise); stroke: var(--text-3); stroke-width: 1.5; }
.dg-meter text { fill: var(--text-2); font-size: 10px; font-weight: 700; }
.dg-socbar { fill: var(--track-hi); }
.dg-socfill { fill: var(--s-bess); }
.dg-ph.ph-ok { fill: var(--run); } .dg-ph.ph-warn { fill: var(--warn); }
.dg-ph.ph-lost { fill: var(--trip); } .dg-ph.ph-none { fill: var(--text-4); }
.dg-sev { fill: currentColor; }
.dg-sev .ring { fill: none; stroke: currentColor; stroke-width: 1.6; }
.frozen .dg-flow, .frozen .dg-arrow-g { opacity: 0 !important; }
.frozen .dg-node, .frozen .dg-bus { opacity: .5; }
@media (prefers-reduced-motion: reduce) { .dg-flow { animation: none !important; } }
@media (max-width: 1000px) {
  .dg { grid-template-columns: 1fr; }
  .dg-inspector { border-left: 0; padding-left: 0; border-top: 1px solid var(--rule); padding-top: 16px; }
}

/* ---- the annunciator and the bell ------------------------------------------ */
.annun-wrap { display: flex; align-items: center; gap: 8px; }
.annun { display: inline-flex; align-items: center; gap: 12px; padding: 4px 12px; border-radius: var(--r-ctl); background: var(--track); }
.annun:hover { background: var(--track-hi); }
.annun .chip .mark > span { font-weight: 600; }
.annun .chip.unacked .mark::before { animation: breathe 1.6s var(--ease) infinite; }
.bell { position: relative; border: 0; background: transparent; cursor: pointer; color: var(--text-2);
  width: 34px; height: 28px; border-radius: var(--r-ctl); display: grid; place-items: center; }
.bell:hover { color: var(--text); background: var(--track); }
.bell svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linejoin: round; stroke-linecap: round; }
.bell .badge { position: absolute; top: -1px; right: -3px; min-width: 17px; height: 17px; padding: 0 4px; border-radius: 9px;
  background: var(--trip); color: #fff; font-size: 10px; font-weight: 700; line-height: 17px; text-align: center; }
.notif-pop {
  position: fixed; z-index: 50; width: min(400px, calc(100vw - 16px)); max-height: min(70vh, 640px); overflow-y: auto;
  background: var(--surface); border-radius: var(--r-panel); box-shadow: var(--pop-shadow), inset 0 0 0 1px var(--rule-2);
}
.notif-head { display: flex; align-items: center; gap: 6px; padding: 10px 10px 10px 16px; border-bottom: 1px solid var(--rule);
  position: sticky; top: 0; background: var(--surface); }
.notif-head .spacer { flex: 1; }
.notif { display: block; padding: 10px 16px; border-top: 1px solid var(--rule); }
.notif:first-child { border-top: 0; }
.notif:hover { background: var(--row-hover); }
.notif.unread { box-shadow: inset 3px 0 0 var(--accent-ink); }
.notif-t .mark > span { font-weight: 500; white-space: normal; }
.notif-t .mark { white-space: normal; align-items: flex-start; }
.notif-t .mark::before { margin-top: 5px; }
.notif-s { color: var(--text-3); font-size: 11.5px; margin: 2px 0 0 15px; }
.notif-b { color: var(--text-2); font-size: 12px; margin: 3px 0 0 15px; }
.notif-list .empty { padding: 20px; }

/* ---- alarm, work and plan lists --------------------------------------------- */
td.pick, th.pick { width: 1%; padding-right: 6px; }
td.pick input, th.pick input { width: 15px; height: 15px; accent-color: var(--accent-ink); }
.wide-cell { min-width: 240px; }
.t { font-weight: 500; }
.sub.clamp { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; max-width: 560px; }
.bulk { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; padding: 10px 14px; margin-bottom: 14px;
  border-radius: var(--r-panel); background: var(--notice-fill); }
.metric.sev-hot .v { color: var(--trip); }
a.metric.link-metric:hover .cap { color: var(--text); }
.meter-bar.wide { width: 140px; }
.meter-bar i.over { background: var(--trip); }
.modal-foot { flex-wrap: wrap; }
.modal-foot .key { white-space: nowrap; }
.modal-foot .spacer { flex: 1; }
.pre { white-space: pre-wrap; }
.form.one { grid-template-columns: 1fr; }

/* ---- a work order ----------------------------------------------------------- */
.wo-cols { display: grid; grid-template-columns: minmax(0, 2fr) minmax(280px, 1fr); gap: 16px; align-items: start; }
.timeline { list-style: none; margin: 0; padding: 0; }
.timeline li { padding: 12px 0; border-top: 1px solid var(--rule); }
.timeline li:first-child { border-top: 0; padding-top: 0; }
.timeline li.internal { box-shadow: inset 2px 0 0 var(--warn); padding-left: 12px; }
.tl-h { font-size: 12.5px; color: var(--text-2); display: flex; flex-wrap: wrap; gap: 4px 8px; align-items: baseline; }
.tl-h b { color: var(--text); font-weight: 600; }
.tl-b { margin-top: 4px; }
.note-form { margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--rule); }
.note-form .actions { margin-top: 10px; }
@media (max-width: 1000px) { .wo-cols { grid-template-columns: 1fr; } }

/* ---- the service contract ------------------------------------------------------- */
.contract-tier { display: flex; align-items: baseline; gap: 14px; }
.tier-name { font-size: 24px; font-weight: 500; letter-spacing: -.02em; }
.resp { display: inline-flex; margin: 0 16px 4px 0; }

/* ---- the SLA report prints as a document ---------------------------------------- */
@media print {
  .topbar, .noprint, .site-head .seg, .toast { display: none !important; }
  html, body { background: #fff; color: #000; }
  main { padding: 0; max-width: none; }
  .panel { box-shadow: none; border: 1px solid #ccc; break-inside: avoid; }
}

/* A unit: the SoC hero, and its strings compared side by side. */
.jb-soc { min-width: 220px; }
.jb-soc .meter-bar.wide { width: 100%; max-width: 260px; height: 3px; margin: 10px 0 8px; }
.metric .v.small { font-size: 15px; font-weight: 400; letter-spacing: 0; padding: 7px 0 4px; }
.jb-compare { width: auto; min-width: min(100%, 640px); }
.jb-compare th.num, .jb-compare td.num { min-width: 190px; }
.jb-compare td.num .meter-bar { display: inline-block; vertical-align: middle; margin: 0 0 0 10px; }
.jb-compare tbody td:first-child { white-space: nowrap; }

/* ==========================================================================
   Control: the one place the portal changes what a unit does
   ========================================================================== */
.c-island { color: var(--accent-ink); }

.ctl-grid { display: grid; grid-template-columns: minmax(240px, .8fr) minmax(0, 2fr); gap: 20px 32px; align-items: start; }
/* The mode the unit reports, readable from across the room. */
.ctl-mode {
  font-family: var(--display); font-size: 46px; line-height: .95; letter-spacing: -.015em;
  text-transform: uppercase; margin: 8px 0 6px; overflow-wrap: anywhere;
}
.ctl-mode.m3 { color: var(--accent-ink); }
.ctl-mode.m1, .ctl-mode.mx, .ctl-mode.m0 { color: var(--text-2); }

.ctl-keys { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; }
.ctl-key {
  display: flex; flex-direction: column; gap: 6px; text-align: left; min-height: 112px;
  padding: 14px 14px 12px; border-radius: var(--r-ctl); cursor: pointer;
  background: var(--bg-2); border: 1px solid var(--rule-2); color: var(--text);
  transition: border-color .15s var(--ease), background .15s var(--ease), transform .15s var(--ease);
}
.ctl-key:hover:not([disabled]) { border-color: var(--text-3); background: var(--fill); }
.ctl-key:active:not([disabled]) { transform: translateY(1px); }
.ctl-key-l { font-weight: 700; font-size: 14px; letter-spacing: .07em; text-transform: uppercase; }
.ctl-key-s { color: var(--text-3); font-size: 12px; line-height: 1.38; }
.ctl-key.island .ctl-key-l { color: var(--accent-ink); }
.ctl-key.island:hover:not([disabled]) { border-color: var(--accent-ink); }
.ctl-key.stop .ctl-key-l { color: var(--trip); }
.ctl-key.stop:hover:not([disabled]) { border-color: var(--trip); background: var(--danger-soft); }
.ctl-key[disabled] { cursor: not-allowed; opacity: .42; }
/* The mode the unit is in now is not an action, it is a fact: shown, not faded. */
.ctl-key.current[disabled] { opacity: 1; cursor: default; background: var(--accent-soft); border-color: var(--accent-ink); }
.ctl-key.current .ctl-key-s { color: var(--text-2); }

.ctl-why { margin: 16px 0 0; color: var(--text-2); }
.ctl-result {
  display: flex; flex-wrap: wrap; align-items: center; gap: 4px 6px;
  margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--rule);
}
.ctl-result-t { color: var(--text); font-weight: 700; margin-right: 6px; }

/* A command on its way: five steps, the current one alive. */
.ctl-flight { margin-top: 18px; }
.ctl-flight-t { color: var(--text-2); }
.ctl-flight-t b { color: var(--text); font-weight: 700; }
.ctl-steps { list-style: none; display: grid; grid-template-columns: repeat(5, 1fr); gap: 4px; margin: 10px 0 0; padding: 0; }
.ctl-steps li {
  padding-top: 7px; border-top: 3px solid var(--track-hi); color: var(--text-4);
  font-size: 10.5px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase;
}
.ctl-steps li.done { border-color: var(--text-3); color: var(--text-3); }
.ctl-steps li.now { border-color: var(--accent-ink); color: var(--text); animation: ctl-now 1.6s var(--ease) infinite; }
@keyframes ctl-now { 50% { border-top-color: var(--track-hi); } }

/* Confirming: the consequence first, in the words of the unit's situation. */
.ctl-confirm { padding: 12px 14px; border-radius: var(--r-panel); background: var(--notice-fill); margin-bottom: 16px; }
.ctl-confirm p { margin: 0; color: var(--text); font-size: 14px; line-height: 1.45; }
.ctl-confirm p + p { margin-top: 6px; color: var(--text-2); }
.ctl-confirm.island { background: var(--accent-soft); }
.ctl-confirm.stop { background: var(--danger-soft); }
.ctl-ctx { margin-bottom: 14px; }
.ctl-confirm.raise { background: var(--accent-soft); }
/* The grid input limit: a setting, not a mode - one quiet line under the keys. */
.ctl-limit {
  display: flex; align-items: center; gap: 12px 24px; flex-wrap: wrap;
  margin-top: 20px; padding-top: 16px; border-top: 1px solid var(--rule);
}
.ctl-limit > div { flex: 1 1 260px; min-width: 0; }
.ctl-limit-v { font-weight: 600; font-size: 24px; letter-spacing: -.01em; line-height: 1.15; margin-top: 2px; font-variant-numeric: tabular-nums; }
.ctl-limit-s { margin-top: 2px; }
.ctl-amps { font-size: 20px; font-weight: 600; font-variant-numeric: tabular-nums; }
/* Fuse sizes to tap: the rating on the fuse is what people on site know. */
.ctl-fuses { display: flex; flex-wrap: wrap; gap: 6px; margin: 10px 0 8px; }
.ctl-fuses button {
  min-height: 32px; padding: 4px 10px; border: 1px solid var(--rule); border-radius: var(--r-ctl);
  background: transparent; color: var(--text-2); font: inherit; font-size: 12.5px; font-weight: 600;
  font-variant-numeric: tabular-nums; cursor: pointer;
}
.ctl-fuses button:hover { border-color: var(--text-3); color: var(--text); }
.ctl-fuses button.on { border-color: var(--accent-ink); background: var(--accent-soft); color: var(--text); }

@media (max-width: 1100px) { .ctl-keys { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 820px) {
  .ctl-grid { grid-template-columns: 1fr; }
  .ctl-mode { font-size: 38px; }
  .ctl-key { min-height: 0; }
  .nav a.on::after { bottom: -4px; }
}
@media (max-width: 560px) {
  /* Wrapped onto three rows, a sticky bar would hide a fifth of a phone screen. */
  .topbar { position: static; }
  .ctl-keys { grid-template-columns: 1fr; gap: 6px; }
  .ctl-key { padding: 12px; }
  .ctl-steps li { font-size: 9.5px; letter-spacing: .04em; }
}

/* ==========================================================================
   Schedules
   ========================================================================== */
/* Mode swatches, shared by the timeline, the entry list and the fleet view. */
.wk-sw { display: inline-block; width: 10px; height: 10px; border-radius: 1px; margin-right: 8px; vertical-align: -1px; }
.wk-sw.island { background: var(--s-island); }
.wk-sw.auto { background: var(--run); }
.wk-sw.stop, .wk-sw.standby { background: var(--text-3); }
.wk-sw.after, .wk-sw.previous { background: transparent; box-shadow: inset 0 0 0 1.5px var(--text-3); }

.wk { display: grid; gap: 6px; }
.wk-axis, .wk-row { display: grid; grid-template-columns: 64px 1fr; align-items: center; gap: 12px; }
.wk-axis { color: var(--text-4); font-size: 10.5px; }
.wk-axis { grid-template-columns: 64px repeat(4, 1fr) 0; }
.wk-axis span:last-child { justify-self: end; transform: translateX(50%); }
.wk-day { color: var(--text-2); font-size: 12px; font-weight: 600; white-space: nowrap; }
.wk-track {
  position: relative; height: 26px; border-radius: 2px; background: var(--track);
  background-image: linear-gradient(to right, var(--rule) 1px, transparent 1px);
  background-size: 25% 100%;
}
.wk-bar {
  position: absolute; top: 3px; bottom: 3px; border-radius: 2px; overflow: hidden;
  font-style: normal; font-size: 10.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  line-height: 20px; padding: 0 6px; white-space: nowrap; color: var(--on-accent);
}
.wk-bar.island { background: var(--s-island); }
.wk-bar.auto { background: var(--run); color: #000; }
.wk-bar.stop { background: var(--text-3); color: var(--bg); }
.wk-now { position: absolute; top: -3px; bottom: -3px; width: 2px; background: var(--trip); }
.wk-key { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; margin-top: 10px; color: var(--text-2); font-size: 12px; }
.wk-key .wk-sw { margin: 0 2px 0 10px; }
.wk-key .wk-sw:first-child { margin-left: 0; }

.entry-form { margin-top: 16px; padding: 16px; border-radius: var(--r-panel); background: var(--bg-2); box-shadow: inset 0 0 0 1px var(--rule-2); }
.daypick { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 10px; }
.daypick button {
  border: 1px solid var(--rule-2); background: transparent; color: var(--text-2); cursor: pointer;
  border-radius: var(--r-ctl); padding: 5px 9px; font-weight: 600; font-size: 12px;
}
.daypick button.on { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
input[type=time] {
  background: var(--bg-2); border: 1px solid var(--rule-2); border-radius: var(--r-ctl);
  padding: 7px 10px; outline: none; color: inherit; font: inherit;
}
.sched-save { align-items: flex-start; }
tr.sel td { background: var(--accent-soft); }
.ctl-sched { margin-top: 14px; display: grid; gap: 6px; justify-items: start; }
.day-group + .day-group { margin-top: 18px; }
.day-cap { margin-bottom: 6px; }
@media (max-width: 560px) {
  .wk-axis, .wk-row { grid-template-columns: 46px 1fr; gap: 8px; }
  .wk-axis { grid-template-columns: 46px repeat(4, 1fr) 0; }
}

/* ---- map: units where their GPS put them ---------------------------------
   Leaflet's own stylesheet loads after this one, so every rule here is
   scoped under .map to outrank it. Tiles are drawn for paper; in the dark
   theme they are turned to night rather than shining through the console. */
.map { height: 440px; border-radius: var(--r-ctl); background: var(--bg-2); font: inherit;
  box-shadow: inset 0 0 0 1px var(--rule); z-index: 0; }
.map-unit { height: 260px; margin-top: 16px; }
@media (max-width: 820px) { .map { height: 340px; } .map-unit { height: 220px; } }
:root:not([data-theme="light"]) .map .leaflet-tile-pane {
  filter: invert(1) hue-rotate(180deg) brightness(.82) contrast(.9) saturate(.5); }
.map.leaflet-container { background: var(--bg-2); font-family: var(--sans); color: var(--text); }
.map.leaflet-container .leaflet-bar { border: 0; box-shadow: inset 0 0 0 1px var(--rule-2), var(--pop-shadow); border-radius: var(--r-ctl); }
.map .leaflet-bar a { background: var(--pop-bg); color: var(--text); border-bottom-color: var(--rule-2); }
.map .leaflet-bar a:hover { background: var(--surface); }
.map.leaflet-container .leaflet-control-attribution { background: var(--pop-bg); color: var(--text-3); font-size: 10.5px; }
.map .leaflet-control-attribution a { color: var(--text-2); }
.map .leaflet-popup-content-wrapper, .map .leaflet-popup-tip {
  background: var(--pop-bg); color: var(--text); box-shadow: var(--pop-shadow); }
.map .leaflet-popup-content-wrapper { border-radius: var(--r-panel); box-shadow: inset 0 0 0 1px var(--rule-2), var(--pop-shadow); }
.map .leaflet-popup-content { margin: 14px 16px; font-size: 13px; line-height: 1.45; }
.map .leaflet-container a.leaflet-popup-close-button, .map a.leaflet-popup-close-button { color: var(--text-3); }
.map .leaflet-tooltip { background: var(--pop-bg); color: var(--text); border: 0;
  box-shadow: inset 0 0 0 1px var(--rule-2), var(--pop-shadow); font-weight: 600; font-size: 12px; }
.map .leaflet-tooltip-right::before { border-right-color: var(--pop-bg); }
.map-pop { display: grid; gap: 4px; }
.map-pop .name { font-weight: 700; font-size: 14px; color: var(--text); }
.map-pop .conds { display: flex; flex-wrap: wrap; gap: 4px 14px; margin: 4px 0 2px; }
/* A pin is a status mark, larger, on a ring of ground so it reads on any
   tile. Hollow and dashed: the registered location, not a GPS fix. */
.map-pin { display: block; width: 18px; height: 18px; cursor: pointer; }
.map-pin::before { content: ""; display: block; box-sizing: border-box; width: 12px; height: 12px; margin: 3px;
  background: currentColor; box-shadow: 0 0 0 2px var(--bg), 0 1px 6px rgba(0,0,0,.45); }
.map-pin.m-ok::before { border-radius: 50%; }
.map-pin.m-bad::before { border-radius: 1px; }
.map-pin.m-warn::before { transform: rotate(45deg) scale(.9); border-radius: 1px; }
.map-pin.m-ring::before { border-radius: 50%; background: var(--bg);
  box-shadow: inset 0 0 0 3px currentColor, 0 0 0 2px var(--bg), 0 1px 6px rgba(0,0,0,.45); }
.map-pin.approx::before { width: 14px; height: 14px; margin: 2px; border-radius: 50%; background: var(--bg);
  border: 2.5px dashed currentColor; box-shadow: 0 0 0 2px var(--bg), 0 1px 6px rgba(0,0,0,.45); }
/* Grey on a map is lost among the roads: an offline pin is drawn darker. */
.map-pin.c-dim { color: var(--text-2); }
