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

:root {
  --bg:      #0f1117;
  --surface: #1a1d27;
  --surface2:#20232f;
  --border:  #2a2d3e;
  --accent:  #4f8ef7;
  --green:   #34c77b;
  --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; }
#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; }

/* ── 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: 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. Taken out of
   flex flow (absolute) so .col-main/.col-alarms reclaim the width when it's minimised —
   that's the "reduce empty space" win: the list no longer permanently eats 270px. */
.col-list-wrap {
  position: absolute; top: 0; left: 0; bottom: 0; z-index: 45;
  width: 270px; max-width: calc(100vw - 40px);
  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 {
  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);
  display: flex; 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; }

.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(79,142,247,.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; }
.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; }

/* ── 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 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 { 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; }

  .col-list-wrap { width: min(85vw, 300px); }

  /* 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; }
}
