*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

:root {
  --bg:      #0f1117;
  --surface: #1a1d27;
  --surface2:#20232f;
  --border:  #2a2d3e;
  --accent:  #74C906;
  --green:   #14b8a6;
  --amber:   #e0a84f;
  --danger:  #e05454;
  --text:    #e8eaf6;
  --muted:   #7b7f9a;
  --r:       8px;
}

html, body { height: 100%; }
body {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  background: var(--bg);
  color: var(--text);
  display: flex;
  flex-direction: column;
  height: 100vh;
  overflow: hidden;
}

a { color: inherit; text-decoration: none; }

/* ── Top bar (header + nav, shared by every page) ── */
#topbar {
  position: relative;
  display: flex; align-items: center; gap: 24px;
  padding: 0 20px; height: 52px; flex-shrink: 0;
  background: var(--surface); border-bottom: 1px solid var(--border);
}
#topbar .brand { display: flex; align-items: center; white-space: nowrap; }
#topbar .brand img { height: 26px; display: block; }
#topbar nav { display: flex; gap: 4px; flex: 1; }
#topbar nav a {
  font-size: 13px; color: var(--muted); padding: 7px 14px;
  border-radius: 20px; transition: all .12s; white-space: nowrap;
}
#topbar nav a:hover     { color: var(--text); background: rgba(255,255,255,.05); }
#topbar nav a.active    { color: #fff; background: var(--accent); }
#topbar .actions { display: flex; gap: 8px; align-items: center; }

/* ── "Management" nav dropdown (injected by common.js' renderTopbar) ── */
#topbar nav .nav-dropdown { position: relative; }
#topbar nav .nav-dropdown-trigger {
  font: inherit; font-size: 13px; color: var(--muted); background: none; border: none;
  padding: 7px 14px; border-radius: 20px; transition: all .12s; cursor: pointer; white-space: nowrap;
}
#topbar nav .nav-dropdown-trigger .caret { font-size: 10px; }
#topbar nav .nav-dropdown-trigger:hover { color: var(--text); background: rgba(255,255,255,.05); }
#topbar nav .nav-dropdown.open .nav-dropdown-trigger,
#topbar nav .nav-dropdown-trigger.active { color: #fff; background: var(--accent); }
#topbar nav .nav-dropdown-menu {
  display: none; flex-direction: column; gap: 2px;
  position: absolute; top: calc(100% + 6px); left: 0; min-width: 190px; z-index: 60;
  background: var(--surface); border: 1px solid var(--border); border-radius: 10px;
  box-shadow: 0 8px 20px rgba(0,0,0,.35); padding: 6px;
}
#topbar nav .nav-dropdown.open .nav-dropdown-menu { display: flex; }
#topbar nav .nav-dropdown-menu a { padding: 8px 12px; border-radius: 8px; }
#nav-user-info { display: flex; gap: 12px; align-items: center; white-space: nowrap; font-size: 12px; }
#nav-user-info .nav-user-badge { color: var(--muted); }
#nav-user-info a { color: var(--muted); }
#nav-user-info a:hover { color: var(--text); }

/* ── Mobile nav toggle (button injected by common.js; hidden on desktop) ── */
#nav-toggle {
  display: none; margin-left: auto; background: none; border: none;
  color: var(--text); font-size: 20px; line-height: 1; cursor: pointer; padding: 6px 8px;
}

/* ── Collapsible sidebar chevron (injected by common.js; hidden on desktop) ── */
.collapse-chevron { display: none; margin-left: 8px; color: var(--muted); transition: transform .15s; }

/* ── Horizontal scroller for wide tables on narrow screens ── */
.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }

/* ── Generic layout ── */
#layout { flex: 1; display: flex; overflow: hidden; }

/* ── In-page tab bar (Dashboard: Overview/Map/Control Room) ── */
.tab-bar {
  display: flex; gap: 4px; padding: 8px 14px; flex-shrink: 0;
  border-bottom: 1px solid var(--border); background: var(--surface);
}
.tab-bar .tab-btn {
  font: inherit; font-size: 13px; color: var(--muted); background: none; border: none;
  padding: 7px 14px; border-radius: 20px; transition: all .12s; cursor: pointer; white-space: nowrap;
}
.tab-bar .tab-btn:hover { color: var(--text); background: rgba(255,255,255,.05); }
.tab-bar .tab-btn.active { color: #fff; background: var(--accent); }
.tab-pane { flex: 1; display: flex; flex-direction: column; overflow: hidden; min-height: 0; }
.tab-pane.hidden { display: none; }

/* ── Buttons ── */
.btn {
  background: var(--surface2); border: 1px solid var(--border); color: var(--text);
  font-size: 12px; font-weight: 500; padding: 6px 14px;
  border-radius: 20px; cursor: pointer; transition: all .12s; white-space: nowrap;
}
.btn:hover { border-color: var(--accent); color: var(--accent); }
.btn:disabled { opacity: .5; cursor: default; }
.btn-primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.btn-primary:hover { background: #3a7ae0; color: #fff; }
.btn-danger  { border-color: var(--danger); color: var(--danger); }
.btn-danger:hover { background: var(--danger); color: #fff; }
.btn-green   { border-color: var(--green); color: var(--green); }
.btn-green:hover { background: var(--green); color: #fff; }
.btn-sm { padding: 3px 10px; font-size: 11px; }

/* ── Device list: static desktop sidebar / mobile popup drawer (shared: dashboard /
   vehicle monitor / map monitor / history / control room / alarms) ── */
/* Wrap is what actually positions+slides; injected by common.js around the existing
   .col-list so the drawer works without changing markup on every page. On desktop it's
   a normal in-flow flex column — always visible, not collapsible. Only inside the mobile
   media query below does it become an absolute overlay that can be minimised via the tab. */
.col-list-wrap {
  position: relative; width: 270px; max-width: calc(100vw - 40px);
  flex-shrink: 0;
}

/* The collapse tab/handle is a mobile-only affordance — hidden on desktop, where the
   sidebar stays static and ignores the .minimized class entirely (see @media 760px below). */
.col-list-tab { display: none; }

.col-list {
  width: 100%; height: 100%;
  background: var(--surface); border-right: 1px solid var(--border);
  box-shadow: 6px 0 20px rgba(0,0,0,.35);
  display: flex; flex-direction: column; overflow: hidden;
}
.col-list .list-head {
  padding: 10px 14px; border-bottom: 1px solid var(--border);
  font-size: 11px; color: var(--muted); text-transform: uppercase; letter-spacing: .5px;
  display: flex; justify-content: space-between; align-items: center;
}
#device-list, .device-list { flex: 1; overflow-y: auto; padding: 6px 0; }

.device-row {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 14px; cursor: pointer;
  border-left: 3px solid transparent;
  transition: background .12s, border-color .12s;
}
.device-row:hover  { background: rgba(255,255,255,.04); }
.device-row.active { background: rgba(116,201,6,.1); border-left-color: var(--accent); }

.dot { width: 8px; height: 8px; border-radius: 50%; background: var(--muted); flex-shrink: 0; }
.dot.online { background: var(--green); box-shadow: 0 0 6px var(--green); }

.device-row .device-info { flex: 1; min-width: 0; }
.device-row .device-name { font-size: 13px; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.device-row .device-meta { font-size: 11px; color: var(--muted); margin-top: 2px; }
.badge-warn  { color: var(--amber); font-size: 10px; margin-left: 4px; }
.badge-err   { color: var(--danger); font-size: 10px; margin-left: 4px; }
/* Alarm severity from the camera (repair plan A4) and the routine-event marker (A2) */
.sev    { display: inline-block; font-size: 10px; font-weight: 600; line-height: 1; padding: 2px 5px; border-radius: 4px; margin-right: 4px; vertical-align: 1px; }
.sev-2  { background: var(--danger); color: #fff; }
.sev-1  { background: var(--amber); color: #111; }
.sev-ev { background: rgba(255,255,255,.12); color: var(--muted); }
.text-warn   { color: var(--amber); }
.text-err    { color: var(--danger); }

.list-empty { padding: 20px 16px; font-size: 12px; color: var(--muted); line-height: 1.6; }

.select-all-label {
  display: flex; align-items: center; gap: 6px;
  font-size: 11px; color: var(--muted); text-transform: none; letter-spacing: normal;
  cursor: pointer;
}
.select-all-label:hover { color: var(--text); }

.section-label {
  padding: 8px 14px 4px; font-size: 10px; color: var(--muted);
  text-transform: uppercase; letter-spacing: .5px;
}

.company-row { background: var(--surface2); }
.company-row .device-name { font-size: 12px; font-weight: 600; }
.company-row:hover { background: rgba(255,255,255,.08); }

/* ── Alarms side column (shared) ── */
.col-alarms {
  width: 260px; min-width: 210px; flex-shrink: 0;
  background: var(--surface); border-left: 1px solid var(--border);
  display: flex; flex-direction: column; overflow: hidden;
}
.col-alarms .list-head {
  padding: 10px 14px; border-bottom: 1px solid var(--border);
  font-size: 11px; color: var(--muted); text-transform: uppercase; letter-spacing: .5px;
  display: flex; justify-content: space-between; align-items: center;
}
.col-alarms .list-head .btn-sm { text-transform: none; letter-spacing: normal; }
#alarm-list, .alarm-list { flex: 1; overflow-y: auto; padding: 6px 0; }
.alarm-row {
  padding: 8px 14px; border-bottom: 1px solid var(--border);
  font-size: 12px; line-height: 1.5;
  display: flex; align-items: center; gap: 8px;
}
.alarm-row .alarm-body { flex: 1; min-width: 0; }
.alarm-row .alarm-dev  { font-weight: 600; }
.alarm-row .alarm-what { color: var(--danger); }
.alarm-row .alarm-detail { font-size: 11px; color: var(--muted); }
.alarm-row .alarm-time { font-size: 10px; color: var(--muted); }
.alarm-row.acked { opacity: .5; }
.alarm-row.acked .alarm-what { color: var(--text); }
.alarm-row .alarm-actions { display: flex; flex-direction: column; gap: 4px; flex-shrink: 0; }
.list-head .btn-sm { margin-left: 8px; }

/* ── Alarms page: clip cards ── */
.clip-card {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r);
  padding: 12px 16px; margin-bottom: 12px;
}
.clip-card-head { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; margin-bottom: 10px; }
.clip-what { color: var(--danger); font-weight: 600; font-size: 13px; }
.clip-time { font-size: 11px; color: var(--muted); flex-shrink: 0; }
.clip-channels { display: flex; gap: 12px; flex-wrap: wrap; }
.clip-slot {
  flex: 1; min-width: 220px; background: var(--surface2); border: 1px solid var(--border);
  border-radius: var(--r); padding: 8px; font-size: 12px;
}
.clip-ch-label { font-weight: 600; margin-bottom: 6px; }
.clip-slot video { width: 100%; display: block; border-radius: 4px; background: #000; }
.clip-status { color: var(--muted); margin-left: 6px; }
.clip-slot-failed .clip-status { color: var(--danger); }
.clip-slot-failed { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 6px; }
.clip-slot-none { color: var(--muted); display: flex; align-items: center; justify-content: space-between; }

.dsm-snapshot-link { display: block; margin-bottom: 10px; }
.dsm-snapshot {
  display: block; max-width: 320px; width: 100%; border-radius: var(--r);
  border: 1px solid var(--border); background: #000;
}
.dsm-snapshots { display: flex; gap: 12px; flex-wrap: wrap; margin-bottom: 10px; }
.dsm-snapshot-slot {
  flex: 1; min-width: 220px; max-width: 320px; background: var(--surface2); border: 1px solid var(--border);
  border-radius: var(--r); padding: 8px; font-size: 12px; display: block; text-decoration: none; color: inherit;
}
.dsm-snapshot-label { font-weight: 600; margin-bottom: 6px; }
.dsm-snapshot-slot .dsm-snapshot { margin: 0; max-width: none; border: none; }
.dsm-snapshot-pending { color: var(--muted); display: flex; align-items: center; justify-content: space-between; }

/* ── Toast notifications (clip request completed) ── */
#toast-host {
  position: fixed; bottom: 20px; right: 20px; z-index: 1000;
  display: flex; flex-direction: column; gap: 8px; max-width: 340px;
}
.toast {
  background: var(--surface2); border: 1px solid var(--border); border-left: 3px solid var(--accent);
  border-radius: var(--r); padding: 10px 14px; font-size: 12px; color: var(--text);
  box-shadow: 0 4px 16px rgba(0,0,0,.3);
  animation: toast-in .15s ease-out;
}
@keyframes toast-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }

/* ── Main content column ── */
.col-main { flex: 1; display: flex; flex-direction: column; overflow: hidden; min-width: 0; }
.col-main-scroll { flex: 1; overflow-y: auto; padding: 16px; }

.empty-state {
  flex: 1; display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  color: var(--muted); gap: 12px; text-align: center; padding: 32px;
}
.empty-state h2 { font-size: 18px; font-weight: 500; }
.empty-state p  { font-size: 13px; line-height: 1.6; max-width: 340px; }

/* ── Stat tiles (dashboard) ── */
/* No side padding here — always lives inside .col-main-scroll, which already gutters it;
   adding more here would just double up empty space at the edges for no reason. */
.stat-row { display: flex; gap: 12px; margin-bottom: 16px; flex-wrap: wrap; }
.stat-tile {
  flex: 1; min-width: 130px; background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r); padding: 16px 18px;
}
.stat-tile .stat-value { font-size: 28px; font-weight: 700; }
.stat-tile .stat-label { font-size: 11px; color: var(--muted); text-transform: uppercase; letter-spacing: .5px; margin-top: 4px; }
.stat-tile.online .stat-value  { color: var(--green); }
.stat-tile.error  .stat-value  { color: var(--danger); }
.stat-tile.alarm  .stat-value  { color: var(--amber); }

/* ── Simple tables/panels ── */
/* No side margin here — always lives inside .col-main-scroll, which already gutters it. */
.panel { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r); margin: 0 0 16px; overflow: hidden; }
.panel .panel-head { padding: 10px 16px; border-bottom: 1px solid var(--border); font-size: 12px; font-weight: 600; color: var(--muted); text-transform: uppercase; letter-spacing: .5px; }
table.simple { width: 100%; border-collapse: collapse; }
table.simple th, table.simple td { text-align: left; padding: 8px 16px; font-size: 13px; border-bottom: 1px solid var(--border); }
table.simple th { color: var(--muted); font-weight: 500; font-size: 11px; text-transform: uppercase; }
table.simple tr:last-child td { border-bottom: none; }
.table-empty { padding: 16px; font-size: 12px; color: var(--muted); }

/* ── Channel tabs & stream toggle (device monitor) ── */
#channel-bar { display: flex; gap: 6px; padding: 8px 20px; border-bottom: 1px solid var(--border); background: var(--surface); overflow-x: auto; align-items: center; }
.ch-btn {
  background: var(--bg); border: 1px solid var(--border); color: var(--muted);
  font-size: 12px; padding: 4px 12px; border-radius: 20px; cursor: pointer;
  white-space: nowrap; transition: all .12s;
}
.ch-btn:hover  { border-color: var(--accent); color: var(--accent); }
.ch-btn.active { background: var(--accent); border-color: var(--accent); color: #fff; }
.ch-live { color: var(--green); font-size: 9px; }

#stream-toggle {
  margin-left: auto; background: var(--bg); border: 1px solid var(--border);
  color: var(--text); font-size: 12px; padding: 4px 14px; border-radius: 20px; cursor: pointer; white-space: nowrap;
}
#stream-toggle.live     { border-color: var(--danger); color: var(--danger); }
#stream-toggle.live:hover    { background: var(--danger); color: #fff; }
#stream-toggle.stopped  { border-color: var(--green); color: var(--green); }
#stream-toggle.stopped:hover { background: var(--green); color: #fff; }
#stream-toggle:disabled { opacity: .5; cursor: default; }

/* ── Video ── */
.video-wrap { position: relative; background: #000; border-radius: var(--r); overflow: hidden; }
.video-wrap video { width: 100%; height: 100%; display: block; }
.stream-status {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  font-size: 12px; color: var(--muted); background: rgba(0,0,0,.65); text-align: center; padding: 10px;
}
.stream-status.hidden { display: none; }
.hidden { display: none; }

/* ── Info grid (device monitor) ── */
.info-grid { margin-top: 16px; display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px; }
.info-card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r); padding: 12px 14px; }
.info-card .label { font-size: 10px; color: var(--muted); text-transform: uppercase; letter-spacing: .5px; margin-bottom: 4px; }
.info-card .value { font-size: 13px; font-weight: 500; word-break: break-all; }
.info-card .value.online  { color: var(--green); }
.info-card .value.offline { color: var(--muted); }
.info-card .value.mono    { font-family: monospace; font-size: 12px; }

/* ── Status timeline (30-day online/offline history) ── */
.status-timeline-row + .status-timeline-row { margin-top: 16px; }
.status-timeline-head {
  display: flex; justify-content: space-between; align-items: baseline;
  font-size: 12px; margin-bottom: 5px;
}
.status-timeline-head .label { font-weight: 600; }
.status-timeline-bar {
  position: relative; height: 24px; border-radius: 4px;
  background: var(--surface2); border: 1px solid var(--border); overflow: hidden;
}
.status-seg { position: absolute; top: 0; bottom: 0; }
.status-seg-online  { background: var(--green); }
.status-seg-offline { background: var(--muted); opacity: .5; }
.status-timeline-axis {
  display: flex; justify-content: space-between;
  font-size: 10px; color: var(--muted); margin-top: 3px;
}

/* ── Map ── */
/* isolation: isolate pins Leaflet's own z-index scale (panes 200-700, zoom/layer controls
   1000) inside this box — without it those values have no containing stacking context to
   stop at and compare directly against the page's own chrome (the vehicle drawer, menus,
   modals), painting the map on top of things that should sit above it. Every Leaflet
   container on the site needs this same containment — see also .widget-box (index.html)
   and #hist-map (history.html). */
.map-box { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r); overflow: hidden; isolation: isolate; }
.leaflet-container { background: #1a1d27; }

/* ── Leaflet base-layer picker (dark theme to match the rest of the app) ── */
.leaflet-control-layers {
  background: var(--surface); color: var(--text); border: 1px solid var(--border);
  border-radius: var(--r); box-shadow: none;
}
.leaflet-control-layers-toggle { filter: invert(1); }
.leaflet-control-layers-list label { font-size: 12px; margin: 4px 0; }
.leaflet-control-layers-separator { border-top: 1px solid var(--border); }

/* ── Control room grid ── */
.crgrid { display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr)); }
.crtile { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r); overflow: hidden; }
.crtile .crtile-head { padding: 6px 10px; font-size: 12px; display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid var(--border); }
.crtile .crtile-head .name { font-weight: 600; }
.crtile video { width: 100%; aspect-ratio: 16/9; background: #000; display: block; }
.crtile .crtile-audio { padding: 6px 10px; display: flex; gap: 6px; border-top: 1px solid var(--border); }
.crtile .crtile-audio .btn { flex: 1; }

/* Groups a vehicle's channel tiles together with a shared boundary so the whole vehicle can be
   flagged at a glance — border is transparent (not just absent) by default so it doesn't shift
   layout when an alarm comes in or gets acknowledged. */
.cr-vehicle-group { border: 3px solid transparent; border-radius: calc(var(--r) + 4px); padding: 4px; transition: border-color .2s; }
.cr-vehicle-group.has-alarm { border-color: var(--danger); }
.cr-vehicle-group-head { font-size: 12px; font-weight: 600; color: var(--muted); padding: 2px 6px 8px; }
.cr-vehicle-group-tiles { display: flex; flex-wrap: wrap; gap: 10px; }
.cr-vehicle-group-tiles .crtile { flex: 1 1 300px; min-width: 260px; }

/* Auto-focus panel (top of Control Room) — same tile look as the grid below, just roughly
   double the minimum width (640px vs the grid's 320px), so the vehicle with the most recent
   alarm gets a visibly larger feed than the manually-selected tiles underneath it. */
.cr-focus-area { display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(min(640px, 100%), 1fr)); margin-bottom: 16px; }
.cr-focus-area .crtile .crtile-head { font-size: 14px; }

/* ── Checkbox (multi-select lists) ── */
.chk { width: 15px; height: 15px; accent-color: var(--accent); flex-shrink: 0; }

/* ── Modal (register device) ── */
.modal-backdrop {
  position: fixed; inset: 0; background: rgba(0,0,0,.55);
  display: flex; align-items: center; justify-content: center; z-index: 100;
}
.modal-backdrop.hidden { display: none; }
.modal {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r);
  width: 340px; padding: 20px;
}
.modal h3 { font-size: 15px; margin-bottom: 14px; }
.modal label { font-size: 11px; color: var(--muted); text-transform: uppercase; letter-spacing: .5px; display: block; margin: 12px 0 5px; }
.modal input, .modal select {
  width: 100%; background: var(--bg); border: 1px solid var(--border); color: var(--text);
  font-size: 13px; padding: 7px 10px; border-radius: var(--r); outline: none;
}
.modal input:focus, .modal select:focus { border-color: var(--accent); }
select.inline-select {
  background: var(--bg); border: 1px solid var(--border); color: var(--text);
  font-size: 12px; padding: 4px 8px; border-radius: var(--r); outline: none;
}
.modal .modal-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 18px; }
.modal .modal-error { color: var(--danger); font-size: 12px; margin-top: 8px; min-height: 16px; }

.modal.modal-raw { width: min(640px, calc(100vw - 32px)); }
.raw-json {
  background: var(--bg); border: 1px solid var(--border); border-radius: var(--r);
  padding: 12px; font-size: 12px; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  white-space: pre-wrap; word-break: break-all; max-height: 60vh; overflow-y: auto;
}

.muted-note { font-size: 11px; color: var(--muted); }

/* ── Vehicle icon & colour pickers (vehicle modal) ── */
.icon-picker { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; }
.icon-swatch {
  display: flex; align-items: center; justify-content: center; padding: 8px 4px;
  background: var(--bg); border: 1px solid var(--border); border-radius: var(--r);
  color: var(--muted); cursor: pointer;
}
.icon-swatch:hover { border-color: var(--accent); color: var(--text); }
.icon-swatch.selected { border-color: var(--accent); color: var(--accent); background: var(--surface2); }
.icon-swatch svg { display: block; }

.color-picker { display: grid; grid-template-columns: repeat(5, 1fr); gap: 8px; }
.color-swatch {
  width: 100%; aspect-ratio: 1; border-radius: 50%; padding: 0; cursor: pointer;
  border: 2px solid var(--border);
}
.color-swatch.selected { border-color: var(--text); box-shadow: 0 0 0 2px var(--surface), 0 0 0 3px var(--text); }

.vehicle-mini-icon {
  display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
  width: 20px; height: 20px; border-radius: 50%; margin-right: 6px; vertical-align: -5px;
}

/* ── Vehicle/device map markers (Leaflet divIcon) ── */
.vehicle-marker-wrap { background: transparent !important; border: none !important; }
.vehicle-marker {
  width: 30px; height: 30px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
  border: 2px solid #fff; box-shadow: 0 1px 4px rgba(0,0,0,.5);
}

/* ══ Mobile layout (phones / narrow tablets) ══════════════════════════════ */
@media (max-width: 760px) {
  /* Collapsible dropdown nav instead of the inline link row */
  #nav-toggle { display: block; }
  #topbar { flex-wrap: wrap; gap: 12px; }
  #topbar nav {
    display: none; width: 100%; flex-direction: column; gap: 4px;
    position: absolute; top: 52px; left: 0; right: 0; z-index: 50;
    background: var(--surface); border-bottom: 1px solid var(--border);
    padding: 8px; box-shadow: 0 8px 16px rgba(0,0,0,.35);
    max-height: calc(100vh - 52px); overflow-y: auto;
    padding-bottom: max(8px, env(safe-area-inset-bottom));
  }
  #topbar.nav-open nav { display: flex; }
  /* Taller tap targets (~44px) so links are easy to hit without mis-taps */
  #topbar nav a { padding: 13px 14px; }

  /* The whole nav is already a dropdown on mobile (opened via the hamburger), so the
     Management submenu just renders inline/indented instead of as its own popup. */
  #topbar nav .nav-dropdown-trigger { width: 100%; text-align: left; padding: 13px 14px; }
  #topbar nav .nav-dropdown-menu {
    display: flex; position: static; box-shadow: none; border: none; background: none;
    padding: 0 0 0 14px; margin: 0;
  }
  #topbar nav .nav-dropdown-menu a { padding: 11px 14px; }

  /* The alarms sidebar still stacks full-width above/below the main column; the vehicle
     list drawer (.col-list-wrap) stays an overlay on mobile too, just narrower. */
  #layout, #dm-body, #hist-body, #dm-content { flex-direction: column; }
  .col-alarms {
    width: 100%; min-width: 0; max-height: 40vh;
    border-right: none; border-left: none; border-bottom: 1px solid var(--border);
  }
  .col-main { min-height: 45vh; }

  /* Vehicle Monitor's info sidebar (#info-sidebar, style.css counterpart in index.html)
     stacks full-width below the grid instead of squeezing beside it. */
  #info-sidebar { width: 100%; max-width: none; max-height: 40vh; border-left: none; border-top: 1px solid var(--border); }

  /* Collapsible vehicle-list drawer — mobile only. Taken out of flex flow (absolute) so
     .col-main/.col-alarms reclaim the width when it's minimised. */
  .col-list-wrap {
    position: absolute; top: 0; left: 0; bottom: 0; z-index: 45;
    width: min(85vw, 300px);
    transition: transform .18s ease;
  }
  .col-list-wrap.minimized { transform: translateX(-100%); }

  /* A small handle stays attached to the drawer's right edge and slides with it via the
     parent's transform — always ending up right at the screen edge whichever state it's
     in, no separate positioning logic needed. */
  .col-list-tab {
    display: flex; position: absolute; top: 50%; right: -26px; transform: translateY(-50%);
    width: 26px; height: 56px; padding: 0;
    background: var(--surface); border: 1px solid var(--border); border-left: none;
    border-radius: 0 8px 8px 0; box-shadow: 4px 0 10px rgba(0,0,0,.25);
    align-items: center; justify-content: center;
    color: var(--muted); cursor: pointer; font-size: 14px; line-height: 1;
  }
  .col-list-tab:hover { color: var(--text); border-color: var(--accent); }

  /* Reserve just enough space for the handle so it doesn't sit on top of main content
     when the drawer is minimised. Targets whatever sibling(s) follow the drawer — every
     page's main-content area — but not a right-hand .col-alarms column, which the handle
     never overlaps. */
  .col-list-wrap ~ *:not(.col-alarms) { padding-left: 30px; }

  /* Extra top/bottom padding on the scrollable list itself: keeps the first/last
     row clear of the sidebar's own edges and the phone's home-indicator area, so
     a scroll gesture started near either edge doesn't clip or fight page chrome. */
  #device-list, .device-list, #alarm-list, .alarm-list {
    padding: 10px 0 max(10px, env(safe-area-inset-bottom));
  }

  /* Tap the alarms sidebar's header to collapse it down to just the header row */
  .col-alarms .list-head { cursor: pointer; }
  .collapse-chevron { display: inline-block; }
  .col-alarms.collapsed { max-height: none; }
  .col-alarms.collapsed .collapse-chevron { transform: rotate(-90deg); }
  .col-alarms.collapsed #alarm-list, .col-alarms.collapsed .alarm-list { display: none; }

  .stat-row { margin-bottom: 12px; gap: 10px; }
  .panel { margin: 0 0 12px; }
  .col-main-scroll { padding: 12px; padding-bottom: max(12px, env(safe-area-inset-bottom)); }

  .modal { width: calc(100vw - 32px) !important; max-height: 85vh; overflow-y: auto; }
  .modal [style*="display:flex"] { flex-wrap: wrap; }
  /* Cap nested scrollers inside a modal so the modal's own scrollbar and the
     inner list's scrollbar aren't fighting for the same swipe gesture. */
  #device-alarms-list { max-height: 40vh !important; }

  #channel-bar { padding: 8px 12px; }

  /* History's table isn't inside a padded container (#hist-main has none), so it needs
     its own side margin for edge-swipe-gesture safety. Users/Changelog's tables are
     already inside #users-body/#changelog-body's own padding below — that's enough
     clearance on its own, so no extra margin here (would just double up the gutter). */
  #hist-points-wrap {
    margin: 0 12px 12px; border-radius: var(--r); border: 1px solid var(--border);
  }
  #users-body .table-scroll, #changelog-body .table-scroll {
    border-radius: var(--r); border: 1px solid var(--border); margin-bottom: 12px;
  }

  #users-body, #changelog-body {
    padding: 12px; padding-bottom: max(12px, env(safe-area-inset-bottom));
  }
  #users-toolbar, #changelog-toolbar, #enforcement-banner { margin-left: 0; margin-right: 0; }
  table.users-table, table.changelog-table { max-width: none; }
}
