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

:root {
  --sidebar-width: 260px;
  --chat-width: 320px;
  --nav-height: 56px;
  /* The bottom nav's full on-screen height: its 56px of buttons plus the
     home-indicator inset it pads itself with. Anything reserving space for
     the nav must use this, not --nav-height. */
  --nav-total: calc(56px + env(safe-area-inset-bottom, 0px));
  --color-bg: #f4f5f7;
  --color-surface: #ffffff;
  --color-border: #e0e0e0;
  --color-primary: #1a73e8;
  --color-primary-dark: #1558b0;
  --color-text: #202124;
  --color-text-muted: #5f6368;
  --color-danger: #d93025;
  --shadow-sm: 0 1px 3px rgba(0,0,0,0.12);
  --shadow-md: 0 2px 8px rgba(0,0,0,0.15);
  --shadow-card: 0 1px 4px rgba(0,0,0,0.08), 0 0 0 1px rgba(0,0,0,0.04);
  --shadow-elevated: 0 4px 16px rgba(0,0,0,0.12), 0 1px 4px rgba(0,0,0,0.08);
  --radius: 8px;
  --radius-sm: 4px;
  /* Priority colours */
  --color-critical: #d32f2f;
  --color-high: #e65100;
  --color-medium: #1a73e8;
  --color-low: #616161;
  /* Status colours */
  --color-success: #2e7d32;
  --color-warning: #f57c00;
  --color-amber: #f59e0b;
  --color-purple: #7c3aed;
  --color-slate: #94a3b8;
}

html, body {
  height: 100%;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  font-size: 14px;
  color: var(--color-text);
  background: var(--color-bg);
}

/* ── Desktop/tablet layout (>768px) ── */

#app {
  display: flex;
  height: 100vh;
  overflow: hidden;
}

/* Left sidebar */
#sidebar {
  width: var(--sidebar-width);
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  background: var(--color-surface);
  border-right: 1px solid var(--color-border);
  overflow: hidden;
}

#sidebar-header {
  padding: 16px;
  border-bottom: 1px solid var(--color-border);
  display: flex;
  align-items: center;
  gap: 10px;
}

#sidebar-header h1 {
  font-size: 15px;
  font-weight: 600;
  color: var(--color-text);
}

#sidebar-nav {
  flex: 1;
  overflow-y: auto;
  padding: 8px 0;
}

#sidebar-nav ul {
  list-style: none;
}

#sidebar-nav li a {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 16px;
  color: var(--color-text);
  text-decoration: none;
  border-radius: 0;
  cursor: pointer;
  transition: background 0.15s;
}

#sidebar-nav li a:hover,
#sidebar-nav li a.active {
  background: #e8f0fe;
  color: var(--color-primary);
}

#sidebar-nav li a svg,
#bottom-nav a svg {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  stroke-width: 1.75;
}

#sidebar-header svg {
  width: 20px;
  height: 20px;
  color: var(--color-primary);
}

/* Main content panel */
#main-content {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  position: relative;
  background: var(--color-bg);
  position: relative;
}

/* Primary view container — starts below the 40px tab bar */
#view-container {
  position: absolute;
  top: 40px;
  left: 0;
  right: 0;
  bottom: 0;
  overflow-y: auto;
  padding: 16px;
}

/* Right chat panel */
#chat-panel {
  width: var(--chat-width);
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  background: var(--color-surface);
  border-left: 1px solid var(--color-border);
}

#chat-header {
  padding: 12px 16px;
  border-bottom: 1px solid var(--color-border);
  display: flex;
  align-items: center;
  gap: 8px;
}

#chat-header h3 {
  font-size: 14px;
  font-weight: 600;
  flex: 1;
}

#chat-context-label {
  font-size: 11px;
  padding: 2px 8px;
  border-radius: 12px;
  background: #e8f0fe;
  color: var(--color-primary);
  font-weight: 500;
}

#chat-messages {
  flex: 1;
  overflow-y: auto;
  padding: 12px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  /* a flex item's default min-width:auto lets wide content (long URLs, keys,
     stack traces) push the whole panel out and block collapsing */
  min-width: 0;
  overflow-x: hidden;
}

#chat-empty {
  color: var(--color-text-muted);
  font-size: 13px;
  text-align: center;
  margin-top: 32px;
}

#chat-input-area {
  padding: 10px 12px;
  border-top: 1px solid var(--color-border);
  display: flex;
  gap: 8px;
  align-items: flex-end;
}

#chat-input {
  flex: 1;
  resize: none;
  border: 1px solid var(--color-border);
  border-radius: 8px;
  padding: 8px 10px;
  font-family: inherit;
  font-size: 13px;
  line-height: 1.4;
  max-height: 120px;
  outline: none;
}

#chat-input:focus {
  border-color: var(--color-primary);
}

#chat-send-btn {
  flex-shrink: 0;
  background: var(--color-primary);
  color: #fff;
  border: none;
  border-radius: 8px;
  padding: 8px 14px;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  transition: background 0.15s;
}

#chat-send-btn:hover {
  background: var(--color-primary-dark);
}

/* ── Chat bubbles ── */

.chat-bubble {
  max-width: 88%;
  padding: 10px 14px;
  border-radius: 12px;
  font-size: 13px;
  line-height: 1.55;
  word-break: break-word;
}

.chat-bubble-user {
  align-self: flex-end;
  background: var(--color-primary);
  color: #fff;
  border-bottom-right-radius: 4px;
}

.chat-bubble-assistant {
  align-self: flex-start;
  background: var(--color-surface);
  color: var(--color-text);
  border: 1px solid var(--color-border);
  border-bottom-left-radius: 4px;
  box-shadow: var(--shadow-sm);
}

/* Markdown content inside assistant bubbles */
.chat-bubble-assistant p { margin: 0 0 8px; }
.chat-bubble-assistant p:last-child { margin-bottom: 0; }
.chat-bubble-assistant ol,
.chat-bubble-assistant ul { margin: 6px 0 8px 18px; padding: 0; }
.chat-bubble-assistant li { margin-bottom: 4px; }
.chat-bubble-assistant strong { font-weight: 600; }
.chat-bubble-assistant em { font-style: italic; }
.chat-bubble-assistant code {
  font-family: 'Courier New', monospace;
  font-size: 12px;
  background: var(--color-bg);
  padding: 1px 5px;
  border-radius: 3px;
  border: 1px solid var(--color-border);
}

.chat-system-msg {
  align-self: center;
  font-size: 11px;
  color: var(--color-text-muted);
  padding: 4px 10px;
  background: var(--color-bg);
  border-radius: 10px;
  border: 1px solid var(--color-border);
}

/* ── Thinking indicator ── */

.chat-thinking {
  align-self: flex-start;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 12px;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 10px;
  font-size: 12px;
  color: var(--color-text-muted);
  box-shadow: var(--shadow-sm);
}

.chat-thinking-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--color-primary);
  animation: chat-pulse 1.2s ease-in-out infinite;
  flex-shrink: 0;
}

@keyframes chat-pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%       { opacity: 0.4; transform: scale(0.7); }
}

/* Waiting longer than expected — amber, so a stalled model reads as stalled */
.chat-thinking-slow {
  border-color: #f59e0b;
  color: #b45309;
}
.chat-thinking-slow .chat-thinking-dot {
  background: #f59e0b;
  animation-duration: 0.7s;
}

/* Terminal failure — replaces the spinner so nothing spins forever */
.chat-thinking-failed {
  align-items: flex-start;
  border-color: var(--color-danger);
  color: var(--color-danger);
  max-width: 85%;
  min-width: 0;
  line-height: 1.45;
  overflow-wrap: anywhere;   /* long URLs/keys must not widen the panel */
}
.chat-thinking-failed .chat-thinking-detail {
  color: var(--color-text-muted);
  font-size: 11px;
}

/* ── Suggestion chips ── */

.chat-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 8px 12px;
  border-top: 1px solid var(--color-border);
}

.chat-chip {
  padding: 4px 10px;
  border: 1px solid var(--color-border);
  border-radius: 12px;
  background: var(--color-surface);
  color: var(--color-text);
  font-size: 12px;
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.12s, border-color 0.12s;
}

.chat-chip:hover {
  background: #e8f0fe;
  border-color: var(--color-primary);
  color: var(--color-primary);
}

/* ── Chat action buttons ── */

.chat-action-btn {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  margin: 4px 12px 0 12px;
  border: 1px solid var(--color-primary);
  border-radius: var(--radius-sm);
  background: #e8f0fe;
  color: var(--color-primary);
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  width: fit-content;
  transition: background 0.12s;
}
.chat-action-btn:hover {
  background: var(--color-primary);
  color: #fff;
}
.chat-action-btn svg {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
}

/* ── Chat sessions panel ── */
#chat-sessions-panel {
  display: none;
  flex-direction: column;
  border-bottom: 1px solid var(--color-border);
  max-height: 280px;
  overflow: hidden;
}
#chat-sessions-panel.open {
  display: flex;
}
.chat-sessions-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 12px;
  border-bottom: 1px solid var(--color-border);
  gap: 8px;
  flex-shrink: 0;
}
#chat-sessions-list {
  list-style: none;
  overflow-y: auto;
  flex: 1;
}
.chat-session-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 14px;
  cursor: pointer;
  font-size: 13px;
  border-bottom: 1px solid var(--color-border);
  transition: background 0.12s;
}
.chat-session-item:hover { background: #e8f0fe; }
.chat-session-item.active { background: #e8f0fe; color: var(--color-primary); }
.chat-session-title {
  flex: 1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.chat-session-date {
  font-size: 11px;
  color: var(--color-text-muted);
  flex-shrink: 0;
  white-space: nowrap;
}
.chat-session-asset-badge {
  font-size: 11px;
  padding: 2px 7px;
  border-radius: 10px;
  background: #e8f0fe;
  color: var(--color-primary);
  font-weight: 500;
  white-space: nowrap;
  flex-shrink: 0;
}
.chat-session-empty {
  padding: 16px 14px;
  color: var(--color-text-muted);
  font-size: 13px;
}

/* Notification bell wrapper */
.chat-notif-btn {
  position: relative;
}

/* ── Generic shared components ── */

.btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 14px;
  border-radius: 6px;
  border: 1px solid transparent;
  font-family: inherit;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s;
}

.btn-primary {
  background: var(--color-primary);
  color: #fff;
}

.btn-primary:hover {
  background: var(--color-primary-dark);
}

.btn-secondary {
  background: var(--color-surface);
  color: var(--color-text);
  border-color: var(--color-border);
}

.btn-secondary:hover {
  background: var(--color-bg);
}

.btn-danger {
  background: var(--color-danger);
  color: #fff;
}

.card {
  background: var(--color-surface);
  border-radius: 8px;
  border: 1px solid var(--color-border);
  padding: 16px;
  box-shadow: var(--shadow-sm);
}

/* ── Phone layout (≤768px) ── */

@media (max-width: 900px) {
  /* Full viewport flex column — app fills space above the fixed bottom nav */
  html, body {
    height: 100%;
    overflow: hidden;
  }

  #app {
    flex-direction: column;
    /* The top inset keeps content clear of the status bar and Dynamic Island;
       without it the first row of every view sits underneath the clock. Needs
       viewport-fit=cover on the viewport meta or the inset reads 0.

       border-box matters: with the default content-box the padding would be
       added on top of the height below, making #app taller than the space
       available and pushing its last rows underneath the bottom nav. */
    box-sizing: border-box;
    /* The inset is NOT padded here: that left a bare strip of page background
       under the status bar. #tab-bar carries it instead, so the bar's own
       surface runs right up under the clock and there is no band. */
    /* --nav-total is the bar's real on-screen height, inset included, and is
       the single definition #bottom-nav and #app both work from. Subtracting
       the inset separately here double-counted it and pulled content up so
       it straddled the nav's border line. */
    height: calc(100vh - var(--nav-total));
    height: calc(100svh - var(--nav-total)); /* svh = small viewport height (browser chrome always visible) */
    overflow: hidden;
  }

  #sidebar {
    display: none;
  }

  #main-content {
    flex: 1;
    overflow: hidden;
    min-height: 0;
  }

  /* The desktop rule reserves 40px for the tab bar; on a phone that bar is
     34px, and the leftover 6px reads as a grey band under the status bar.
     #app already accounts for the nav and the safe-area insets, so the
     container simply fills what is left. */
  #view-container {
    /* Sits below the tab bar, which is 34px plus the status-bar inset it now
       paints. */
    top: calc(34px + env(safe-area-inset-top, 0px));
    bottom: 0;
    /* This is the scroller for every data-view (Prestart, My Truck, Profile…)
       and it runs to bottom:0, i.e. UNDER the fixed bottom nav. Without the
       nav's height reserved here the tail of a long form — the Prestart
       submit button — sits behind the nav with no way to scroll it clear.
       Matches the .tab-pane rule below. */
    padding: 12px 12px
             calc(12px + var(--nav-total)) 12px;
  }

  /* Chat is hidden by default on mobile; JS removes hidden-phone to show it */
  #chat-panel {
    display: none;
    width: 100%;
    border-left: none;
    border-top: 1px solid var(--color-border);
    flex-shrink: 0;
  }

  /* No tab BUTTONS on a phone — the bottom nav is the navigation, and tabs.js
     creates none here. The bar itself stays as a slim status strip, because
     the PTT channel chip and the notifications chip mount into it and the
     channel a driver is on has to stay visible on every view. Hiding it
     outright is what made the channel indicator disappear. */
  #tab-bar {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 6px;
    height: 34px;
    min-height: 34px;
    padding: 0 8px;
    position: relative;
    /* Owns the status-bar strip so it is painted, not left as a band. */
    padding-top: env(safe-area-inset-top, 0px);
    height: calc(34px + env(safe-area-inset-top, 0px));
    min-height: calc(34px + env(safe-area-inset-top, 0px));
    background: var(--color-surface);
  }

  /* Content starts below that strip. Must match the header's real height —
     the bar is 34px PLUS the status-bar inset it paints, so a bare 34px here
     slides content up under the notch. */
  #tab-content {
    top: calc(34px + env(safe-area-inset-top, 0px));
  }

  /* Tighter padding inside panes — extra bottom padding clears fixed bottom
     nav, which is --nav-height plus its own home-indicator inset. */
  .tab-pane {
    padding: 12px 12px
             calc(12px + var(--nav-total)) 12px;
  }

  /* Bottom nav — fixed to viewport bottom so it's always visible */
  #bottom-nav {
    display: flex;
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    background: var(--color-surface);
    border-top: 1px solid var(--color-border);
    /* box-sizing is border-box globally, so padding comes OUT of height. With
       a plain height:56px the home-indicator inset ate ~34px of that and left
       the icons about 22px tall, crushed against the top edge. The bar has to
       be 56px of buttons PLUS the inset. */
    height: var(--nav-total);
    /* Above the phone tab overlay (z-index 200) — the nav is permanent chrome
       and must never be covered by a view the driver drilled into. */
    z-index: 210;
    /* Safe area inset for devices with home indicator */
    padding-bottom: env(safe-area-inset-bottom, 0px);
  }

  #bottom-nav a {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    color: var(--color-text-muted);
    text-decoration: none;
    font-size: 10px;
    font-weight: 500;
    cursor: pointer;
    transition: color 0.15s;
    -webkit-tap-highlight-color: transparent;
  }

  #bottom-nav a svg {
    width: 22px;
    height: 22px;
  }

  #bottom-nav a.active {
    color: var(--color-primary);
  }

  /* Workstream F: driver Prestart entry (tagged by app.js for sub-supervisor
     roles) only shows while signed on to a truck — VehicleSignOn toggles the
     'vehicle-signed-on' body class. */
  #bottom-nav a.phone-signed-on-only {
    display: none;
  }

  body.vehicle-signed-on #bottom-nav a.phone-signed-on-only {
    display: flex;
  }

  /* Phone: only one panel visible at a time */
  #main-content.hidden-phone,
  #chat-panel.hidden-phone {
    display: none;
  }

  /* When JS shows the chat panel it removes hidden-phone; restore flex layout */
  #chat-panel:not(.hidden-phone) {
    display: flex;
    flex-direction: column;
    flex: 1;
    overflow: hidden;
  }

  #chat-back-btn {
    display: flex;
  }

  /* Phone: asset context card at top of chat */
  #asset-context-card {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 14px;
    background: var(--color-surface);
    border-bottom: 1px solid var(--color-border);
    font-size: 13px;
  }

  #asset-context-card.collapsed {
    padding: 6px 14px;
  }

  #asset-context-card .asset-name {
    font-weight: 600;
  }

  #asset-context-card .asset-meta {
    color: var(--color-text-muted);
    font-size: 12px;
  }

  /* Asset list: card layout instead of table on mobile */
  .data-table-wrapper .data-table {
    display: none;
  }

  .data-table-wrapper::before {
    content: '';
    display: block;
  }

  /* Card grid replaces the table — injected by JS via .dt-mobile-cards */
  .dt-mobile-cards {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 4px 0 8px;
  }

  .dt-mobile-search {
    display: flex;
    gap: 8px;
    margin-bottom: 10px;
  }

  .dt-mobile-search input {
    flex: 1;
    padding: 10px 12px;
    border: 1px solid var(--color-border);
    border-radius: 8px;
    font-size: 14px;
    background: var(--color-surface);
    color: var(--color-text);
    outline: none;
  }

  .dt-mobile-search input:focus {
    border-color: var(--color-primary);
  }

  .dt-mobile-card {
    background: var(--color-surface);
    border-radius: 10px;
    padding: 14px;
    box-shadow: var(--shadow-card);
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 12px;
    -webkit-tap-highlight-color: transparent;
  }

  .dt-mobile-card:active {
    background: #f0f4ff;
  }

  .dt-mobile-card.asset-row-nearby {
    border-left: 3px solid #22c55e;
    background: #f0fdf4;
  }

  .dt-mobile-card-body {
    flex: 1;
    min-width: 0;
  }

  .dt-mobile-card-title {
    font-size: 14px;
    font-weight: 600;
    color: var(--color-text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    margin-bottom: 3px;
  }

  .dt-mobile-card-sub {
    font-size: 12px;
    color: var(--color-text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .dt-mobile-card-right {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 4px;
    flex-shrink: 0;
  }

  .dt-mobile-card-chevron {
    color: var(--color-text-muted);
    opacity: 0.4;
    flex-shrink: 0;
  }

  /* Hide desktop pagination on mobile card view */
  .dt-mobile-cards ~ .dt-pagination,
  .data-table-wrapper:has(.dt-mobile-cards) .dt-pagination {
    display: none;
  }

  /* Overlay already stops above the bottom nav via its `bottom` offset —
     padding here would double-count and leave a dead gap. */

  .chat-session-item { min-height: 48px; }
}

/* ── iPhone safe-area buffer ──────────────────────────────────────────────
   The buffer goes in the CONTENT. The nav and the header are not touched.

   Only the view scrollers get the extra padding, so the first and last rows
   of a view clear the status bar and the home indicator.

   iOS only, keyed off the platform class NativeBridge puts on <html>.
   Android and desktop report zero insets, so these rules would be no-ops
   there, but scoping them keeps the phone layout above untouched. */
@media (max-width: 900px) {

  html.platform-ios #view-container,
  html.platform-ios .tab-pane {
    padding-top: calc(12px + env(safe-area-inset-top, 0px));
    padding-bottom: calc(12px + var(--nav-total) + env(safe-area-inset-bottom, 0px));
  }
}

/* ── Android header buffer ────────────────────────────────────────────────
   Nothing here any more, deliberately.

   This block used to add a hardcoded 18px to #tab-bar because
   env(safe-area-inset-top) reads 0 on Android and the header was rendering
   under the status bar. That was treating the symptom: the real cause was
   targetSdk 35's forced edge-to-edge, which handed the page the whole screen
   and let the OS paint the clock and battery over the top of it. The battery
   pill sat directly on the PTT channel chip.

   MainActivity now consumes the system-bar insets, so the WebView is laid out
   BELOW the status bar and y=0 in the page is genuinely the first free pixel.
   Padding here as well would be double: the header would sit a status bar's
   height plus 18px down the screen, with a white gap above it.

   The rule is kept as a comment rather than deleted so the next person who
   sees a cramped Android header knows this was tried and why it was wrong. */

/* ── Map view ── */

#map-container {
  width: 100%;
  height: 100%;
  min-height: 400px;
}

.map-control-panel {
  position: absolute;
  top: 12px;
  right: 12px;
  z-index: 10;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 8px;
  padding: 10px 12px;
  box-shadow: var(--shadow-md);
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 180px;
  font-size: 13px;
}

.map-status-line {
  color: var(--color-text-muted);
  font-size: 12px;
}

.asset-marker {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  border: 2px solid #fff;
  box-shadow: var(--shadow-sm);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}

.asset-marker svg {
  width: 14px;
  height: 14px;
  color: #fff;
  stroke-width: 2;
}

/* Desktop: hide phone-only elements */
@media (min-width: 901px) {
  #bottom-nav {
    display: none;
  }

  #asset-context-card {
    display: none;
  }

  #chat-back-btn {
    display: none;
  }
}

/* ── Settings / Config ── */

.cfg-wrap {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 16px;
  max-width: 720px;
}

.cfg-group {
  padding: 0;
  overflow: hidden;
}

.cfg-group-header {
  padding: 14px 16px 12px;
  border-bottom: 1px solid var(--color-border);
}

.cfg-group-title {
  font-size: 14px;
  font-weight: 600;
  color: var(--color-text);
  margin: 0;
}

.cfg-group-desc {
  font-size: 12px;
  color: var(--color-text-muted);
  margin-top: 2px;
}

.cfg-rows {
  display: flex;
  flex-direction: column;
}

.cfg-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--color-border);
}

.cfg-row:last-child {
  border-bottom: none;
}

.cfg-row-meta {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.cfg-row-label {
  font-size: 13px;
  font-weight: 500;
  color: var(--color-text);
}

.cfg-row-key {
  font-size: 11px;
  color: var(--color-text-muted);
  font-family: monospace;
}

.cfg-row-value {
  font-size: 13px;
  min-width: 120px;
  max-width: 240px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.cfg-unset {
  color: var(--color-text-muted);
  font-style: italic;
}

.cfg-masked {
  color: var(--color-text-muted);
  letter-spacing: 2px;
}

.cfg-set {
  color: var(--color-text);
  font-family: monospace;
  font-size: 12px;
}

.cfg-row-actions {
  display: flex;
  gap: 6px;
  flex-shrink: 0;
}

@media (max-width: 600px) {
  .cfg-row {
    flex-wrap: wrap;
  }

  .cfg-row-value {
    min-width: unset;
    max-width: unset;
    width: 100%;
  }

  .cfg-row-actions {
    width: 100%;
    justify-content: flex-end;
  }
}

/* ── Profile Sheet ── */

#profile-overlay {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.4);
  z-index: 300;
  align-items: flex-end;
  justify-content: center;
}

#profile-overlay.open {
  display: flex;
}

#profile-sheet {
  background: var(--color-surface);
  border-radius: 16px 16px 0 0;
  width: 100%;
  max-width: 480px;
  padding-bottom: env(safe-area-inset-bottom, 0);
  max-height: 90vh;
  overflow-y: auto;
}

.profile-sheet-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 16px 12px;
  border-bottom: 1px solid var(--color-border);
}

.profile-sheet-title {
  font-size: 15px;
  font-weight: 600;
  color: var(--color-text);
}

.profile-sheet-close {
  background: none;
  border: none;
  cursor: pointer;
  color: var(--color-text-muted);
  padding: 4px;
  display: flex;
  align-items: center;
}

.profile-picker-row {
  padding: 14px 16px 0;
  display: flex;
  flex-direction: column;
}

.profile-card-inner {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 16px;
}

.profile-avatar-wrap {
  position: relative;
  flex-shrink: 0;
}

.profile-avatar {
  width: 72px;
  height: 72px;
  border-radius: 50%;
  object-fit: cover;
  display: block;
}

.profile-avatar-initials {
  width: 72px;
  height: 72px;
  border-radius: 50%;
  background: var(--color-primary);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 22px;
  font-weight: 700;
}

.profile-photo-btn {
  position: absolute;
  bottom: 0;
  right: 0;
  width: 26px;
  height: 26px;
  background: var(--color-primary);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  color: #fff;
  border: 2px solid var(--color-surface);
}

.profile-card-name {
  font-size: 16px;
  font-weight: 600;
  color: var(--color-text);
}

.profile-card-role {
  font-size: 13px;
  color: var(--color-text-muted);
  margin-top: 2px;
}

.profile-card-detail {
  font-size: 12px;
  color: var(--color-text-muted);
  margin-top: 2px;
}

.profile-card-info {
  flex: 1;
  min-width: 0;
}

@media (min-width: 901px) {
  #profile-overlay.open {
    align-items: center;
  }
  #profile-sheet {
    border-radius: 12px;
    max-height: 80vh;
  }
}

/* ── Contact Cards ── */

.contact-cards {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  padding: 4px 0;
}

.contact-card {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 8px;
  padding: 12px 14px;
  min-width: 220px;
  flex: 1 1 220px;
  max-width: 340px;
  box-shadow: var(--shadow-sm);
}

.contact-avatar {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  object-fit: cover;
  flex-shrink: 0;
}

.contact-avatar-initials {
  background: var(--color-primary);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.02em;
}

.contact-card-body {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.contact-card-name {
  font-size: 14px;
  font-weight: 600;
  color: var(--color-text);
}

.contact-card-role {
  font-size: 12px;
  color: var(--color-text-muted);
}

.contact-card-detail {
  font-size: 12px;
  color: var(--color-primary);
  text-decoration: none;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.contact-card-detail:hover {
  text-decoration: underline;
}

.contact-card-notifs {
  display: flex;
  gap: 4px;
  margin-top: 4px;
  flex-wrap: wrap;
}

/* ── Reports view ──────────────────────────────────────────────────────────── */

.reports-wrap {
  display: flex;
  flex-direction: column;
  gap: 0;
  height: 100%;
}

.report-panel {
  padding: 16px;
  overflow-y: auto;
}

.report-filters {
  display: flex;
  align-items: flex-end;
  gap: 12px;
  flex-wrap: wrap;
  padding: 12px 16px;
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
  margin: -16px -16px 16px -16px;
}

.report-filter-group {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  flex: 1;
}

.report-filter-label {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 12px;
  color: var(--color-text-muted);
  font-weight: 500;
}

.report-filter-label .form-input {
  min-width: 140px;
  font-size: 13px;
}

.report-filter-actions {
  display: flex;
  gap: 8px;
  align-items: flex-end;
}

.report-section-title {
  font-size: 14px;
  font-weight: 600;
  color: var(--color-text);
  margin-bottom: 10px;
}

.report-table-wrap {
  overflow-x: auto;
}

.report-loading,
.report-error {
  padding: 24px;
  text-align: center;
  color: var(--color-text-muted);
  font-size: 14px;
}

.report-error {
  color: var(--color-danger);
}

/* KPI Strip */

.kpi-strip {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
  margin-bottom: 20px;
}

.kpi-card {
  background: var(--color-surface);
  border-radius: var(--radius);
  box-shadow: var(--shadow-card);
  padding: 14px 16px;
  border-left: 4px solid var(--color-primary);
}

.kpi-value {
  font-size: 28px;
  font-weight: 700;
  line-height: 1.1;
  color: var(--color-text);
}

.kpi-label {
  font-size: 12px;
  color: var(--color-text-muted);
  margin-top: 4px;
}

@media (max-width: 900px) {
  .kpi-strip {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 600px) {
  .kpi-strip {
    grid-template-columns: 1fr;
  }
  .report-filter-group {
    flex-direction: column;
  }
}

/* ── Login overlay ── */

.login-overlay {
  position: fixed;
  inset: 0;
  z-index: 9999;
  background: linear-gradient(135deg, #1a56db 0%, #1e429f 100%);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
}

.login-overlay.hidden {
  display: none;
}

.login-card {
  background: var(--color-surface);
  border-radius: 12px;
  box-shadow: 0 20px 60px rgba(0,0,0,0.25);
  padding: 36px 32px 32px;
  width: 100%;
  max-width: 360px;
}

.login-logo {
  text-align: center;
  margin-bottom: 28px;
}

.login-icon-wrap {
  width: 52px;
  height: 52px;
  border-radius: 14px;
  background: var(--color-primary);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 14px;
  box-shadow: 0 4px 12px rgba(26,86,219,0.35);
}

/* Dark plate behind the Pastin logo. The artwork is white text with an orange
   road mark and has a transparent background, so on the light login card it
   would be invisible without a backing. Replaces the old wrench tile. */
.login-brand-plate {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 14px 20px;
  border-radius: 14px;
  background: #1f2430;
  margin-bottom: 14px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.28);
}

.login-brand-logo {
  display: block;
  width: 190px;
  max-width: 60vw;
  height: auto;
}

.login-title {
  font-size: 1.25rem;
  font-weight: 700;
  color: var(--color-text);
  margin: 0 0 4px;
}

.login-brand-by {
  font-size: 0.8rem;
  color: var(--color-text-muted);
  margin: 0 0 6px;
}

.login-subtitle {
  font-size: 0.85rem;
  color: var(--color-text-muted);
  margin: 0;
}

.login-submit {
  width: 100%;
  margin-top: 8px;
  padding: 11px;
  font-size: 14px;
  font-weight: 600;
}

.login-error {
  margin-top: 10px;
  padding: 8px 12px;
  background: #fce8e6;
  color: var(--color-danger);
  border-radius: var(--radius-sm);
  font-size: 0.85rem;
}

/* Sidebar user/logout row */
#sidebar-user {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 6px;
}

#sidebar-user-name {
  font-size: 0.75rem;
  color: var(--color-text-muted);
  max-width: 100px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.btn-icon {
  background: none;
  border: none;
  cursor: pointer;
  padding: 4px;
  border-radius: var(--radius-sm);
  color: var(--color-text-muted);
  display: flex;
  align-items: center;
  justify-content: center;
}

.btn-icon:hover {
  background: var(--color-bg);
  color: var(--color-danger);
}

.btn-icon svg {
  width: 16px;
  height: 16px;
}

@media (max-width: 480px) {
  .login-card {
    padding: 28px 20px 24px;
  }
}

/* ── IT Asset Panel ─────────────────────────────────────────────────────── */

.it-asset-panel {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.it-status-strip {
  display: flex;
  align-items: center;
  gap: 24px;
  padding: 12px 16px;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 8px;
  flex-wrap: wrap;
}

.it-status-strip.it-status-unknown {
  color: var(--color-text-muted);
  font-size: 13px;
  gap: 8px;
}

.it-status-metric {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 100px;
}

.it-status-label {
  font-size: 11px;
  font-weight: 600;
  color: var(--color-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.it-status-value {
  font-size: 20px;
  font-weight: 700;
  color: var(--color-text);
}

.it-status-meta {
  font-size: 11px;
  color: var(--color-text-muted);
  margin-left: auto;
}

.it-percent-bar-wrap {
  height: 4px;
  background: var(--color-border);
  border-radius: 2px;
  overflow: hidden;
}

.it-percent-bar {
  height: 100%;
  border-radius: 2px;
  transition: width 0.3s ease;
}

.it-bar-ok       { background: var(--color-low, #27ae60); }
.it-bar-warn     { background: var(--color-warning, #f39c12); }
.it-bar-critical { background: var(--color-critical, #c0392b); }

.it-subtab-bar {
  border-bottom: 1px solid var(--color-border);
  margin-bottom: 4px;
}

.it-tab-empty {
  color: var(--color-text-muted);
  margin-left: 2px;
  font-size: 10px;
}

.it-snapshot-ts {
  font-size: 11px;
  color: var(--color-text-muted);
  margin-bottom: 8px;
}

.it-kv-table td.it-key {
  font-weight: 600;
  color: var(--color-text-muted);
  white-space: nowrap;
  width: 30%;
}

.it-raw-json {
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: 6px;
  padding: 12px 16px;
  font-size: 12px;
  overflow-x: auto;
  white-space: pre-wrap;
  word-break: break-all;
  max-height: 400px;
  overflow-y: auto;
}

.it-updates-badge {
  display: inline-block;
  background: var(--color-warning, #f39c12);
  color: #fff;
  font-size: 12px;
  font-weight: 600;
  padding: 2px 10px;
  border-radius: 12px;
  margin-bottom: 8px;
}

.it-ok-msg {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--color-low, #27ae60);
}

.muted-label {
  font-size: 12px;
  color: var(--color-text-muted);
}

/* ── Login overlay ── */

.login-overlay {
  position: fixed;
  inset: 0;
  z-index: 9999;
  background: var(--color-bg);
  display: flex;
  justify-content: center;
  /* On a phone the software keyboard shrinks the visual viewport below the
     card's height. Centred-and-fixed then leaves the Sign In button behind the
     keyboard with no way to reach it, so the overlay scrolls instead.
     auto margins on the child (not align-items:center) because a centred flex
     child that overflows gets clipped at the top and cannot be scrolled to. */
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: max(16px, env(safe-area-inset-top)) 16px
           max(16px, env(safe-area-inset-bottom));
}

.login-overlay > * {
  margin: auto;
}

.login-overlay.hidden {
  display: none;
}

.login-card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-elevated);
  padding: 32px;
  width: 100%;
  max-width: 380px;
}

.login-logo {
  text-align: center;
  padding-bottom: 8px;
}

.login-icon-wrap {
  width: 52px;
  height: 52px;
  background: var(--color-primary);
  border-radius: 14px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 14px;
}

.login-title {
  font-size: 1.4rem;
  font-weight: 600;
  margin: 0 0 4px;
  color: var(--color-text);
}

.login-subtitle {
  color: var(--color-text-muted);
  font-size: 0.85rem;
  margin: 0 0 24px;
}

.login-error {
  margin-top: 10px;
  padding: 8px 12px;
  background: #fce8e6;
  color: var(--color-danger);
  border-radius: var(--radius-sm);
  font-size: 0.85rem;
}

.login-submit {
  width: 100%;
  margin-top: 20px;
  padding: 12px;
}

/* Sidebar user/logout row */
#sidebar-user {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 6px;
}

#sidebar-user-name {
  font-size: 0.75rem;
  color: var(--color-text-muted);
  max-width: 100px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.btn-icon {
  background: none;
  border: none;
  cursor: pointer;
  padding: 4px;
  border-radius: var(--radius-sm);
  color: var(--color-text-muted);
  display: flex;
  align-items: center;
  justify-content: center;
}

.btn-icon:hover {
  background: var(--color-bg);
  color: var(--color-danger);
}

.btn-icon svg {
  width: 16px;
  height: 16px;
}

@media (max-width: 900px) {
  .login-card {
    max-width: 340px;
    padding: 24px;
  }
}

/* ── Sidebar collapse ──────────────────────────────────────────────────── */

#sidebar { transition: width 0.2s ease; }

#sidebar.sidebar-collapsed { width: 56px; }

#sidebar.sidebar-collapsed #sidebar-header h1,
#sidebar.sidebar-collapsed .tab-label-nav,
#sidebar.sidebar-collapsed #sidebar-user { display: none; }

#sidebar.sidebar-collapsed #sidebar-nav li a { justify-content: center; padding: 10px; }

#sidebar.sidebar-collapsed #sidebar-header {
  justify-content: center;
  padding: 8px 0;
  gap: 0;
}

/* Hide the wrench brand icon when collapsed — only the toggle button stays */
#sidebar.sidebar-collapsed #sidebar-header > i[data-lucide] { display: none; }

/* Ensure the collapse button is always visible and centred */
#sidebar.sidebar-collapsed #sidebar-collapse-btn {
  display: flex;
  margin: 0 auto;
}

#sidebar-collapse-btn {
  cursor: pointer;
  background: none;
  border: none;
  color: var(--color-text-muted);
  padding: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

#sidebar-collapse-btn:hover { color: var(--color-text); }

@media (max-width: 900px) {
  #sidebar-collapse-btn,
  #chat-collapse-btn { display: none; }
}

/* ── Chat panel collapse ───────────────────────────────────────────────── */

#chat-panel { transition: width 0.2s ease; overflow: hidden; }

/* min/max-width pinned too: width alone loses to a wide flex child (a long
   unbreakable error string could keep the panel expanded after collapsing). */
#chat-panel.chat-collapsed { width: 40px; min-width: 40px; max-width: 40px; flex: 0 0 40px; }

#chat-panel.chat-collapsed > *:not(#chat-header) { display: none; }

#chat-panel.chat-collapsed #chat-header {
  flex-direction: column;
  padding: 8px 0;
  align-items: center;
  justify-content: flex-start;
  gap: 12px;
  border: none;
}

#chat-panel.chat-collapsed #chat-header > *:not(#chat-collapse-btn) { display: none; }

#chat-collapse-btn {
  cursor: pointer;
  background: none;
  border: none;
  color: var(--color-text-muted);
  padding: 4px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

#chat-collapse-btn:hover { color: var(--color-text); }

/* ── Tab bar ───────────────────────────────────────────────────────────── */

/* Tab bar — always visible, part of the normal flex flow */
#tab-bar {
  display: flex;
  align-items: center;
  gap: 2px;
  padding: 0 8px;
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
  box-shadow: var(--shadow-sm);
  overflow: visible;
  height: 40px;
  flex-shrink: 0;
  position: relative;
  z-index: 20;
}


.tab-btn {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 0 10px;
  height: 32px;
  border: none;
  border-radius: var(--radius-sm);
  background: none;
  color: var(--color-text-muted);
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  white-space: nowrap;
  flex-shrink: 0;
  position: relative;
  transition: background 0.12s, color 0.12s;
}

.tab-btn:hover { background: var(--color-bg); color: var(--color-text); }
.tab-btn.active { background: #e8f0fe; color: var(--color-primary); }
.tab-btn svg { width: 14px; height: 14px; flex-shrink: 0; }

.tab-close-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  border: none;
  border-radius: 50%;
  background: none;
  color: var(--color-text-muted);
  cursor: pointer;
  padding: 0;
  margin-left: 2px;
  flex-shrink: 0;
}

.tab-close-btn:hover { background: var(--color-border); color: var(--color-text); }
.tab-close-btn svg { width: 10px; height: 10px; }

.tab-more-btn {
  height: 32px;
  padding: 0 12px;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  cursor: pointer;
  font-size: 13px;
  white-space: nowrap;
  flex-shrink: 0;
  position: relative;
  margin-left: auto;
}

.tab-more-btn:hover { background: var(--color-surface-2); }

.tab-overflow-menu {
  position: absolute;
  top: 100%;
  right: 0;
  z-index: 200;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  box-shadow: 0 4px 12px rgba(0,0,0,0.15);
  list-style: none;
  margin: 4px 0 0;
  padding: 4px 0;
  min-width: 180px;
}

.tab-overflow-menu li {
  padding: 8px 16px;
  cursor: pointer;
  font-size: 13px;
  white-space: nowrap;
}

.tab-overflow-menu li:hover { background: var(--color-surface-2); }
.tab-overflow-menu li.active { font-weight: 600; color: var(--color-primary); }

/* ── Tab content ───────────────────────────────────────────────────────── */

/* Tab content — absolutely positioned, starts BELOW the tab bar (40px) */
#tab-content {
  position: absolute;
  top: 40px;
  left: 0;
  right: 0;
  bottom: 0;
  pointer-events: none;
  z-index: 10;
}

.tab-pane {
  position: absolute;
  inset: 0;
  overflow: auto;
  padding: 16px;
  background: var(--color-bg);
  pointer-events: auto;
  box-sizing: border-box;
}

/* Map pane needs no padding — the map fills edge to edge */
.tab-pane:has(#map-container) {
  padding: 0;
}

/* ── Asset detail mobile tab bar ──────────────────────────────────────── */

@media (max-width: 900px) {
  .asset-detail-tab-bar {
    display: flex;
    flex-wrap: nowrap;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    gap: 4px;
    padding-bottom: 2px;
  }
  .asset-detail-tab-bar::-webkit-scrollbar { display: none; }
  .asset-detail-tab-bar .tab-btn {
    flex-shrink: 0;
    white-space: nowrap;
    font-size: 13px;
    padding: 6px 12px;
  }
}

/* ── Asset detail record cards ─────────────────────────────────────────── */

.ad-card-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.ad-record-card {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  background: var(--color-surface);
  border-radius: 10px;
  border: 1px solid var(--color-border);
  cursor: pointer;
  user-select: none;
}

.ad-record-card:active { background: var(--color-bg); }

.ad-record-card-main { flex: 1; min-width: 0; }

.ad-record-card-title {
  font-size: 14px;
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ad-record-card-sub {
  font-size: 12px;
  color: var(--color-text-muted);
  margin-top: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ad-record-card-by {
  font-size: 12px;
  color: var(--color-text-muted);
  white-space: nowrap;
}

.ad-record-card-chev {
  width: 16px;
  height: 16px;
  color: var(--color-text-muted);
  opacity: 0.4;
  flex-shrink: 0;
}

.ad-record-badge {
  font-size: 11px;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--color-surface-raised, #f0f4ff);
  color: var(--color-text-muted);
  white-space: nowrap;
  flex-shrink: 0;
}

.ad-record-badge--pass { background: #e6f4ea; color: #1e7e34; }
.ad-record-badge--fail { background: #fce8e6; color: #c5221f; }
.ad-record-badge--warn { background: #fef7e0; color: #b06000; }

/* ── Phone overlay for instance tabs ──────────────────────────────────── */

/* Stops at the top of the bottom nav — never inset:0. The bottom bar is the
   phone's navigation and carries the round PTT talk button; an overlay that
   covers it strands the driver in whatever they drilled into. */
#phone-tab-overlay {
  display: none;
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: var(--nav-total);
  background: var(--color-bg);
  z-index: 200;
  flex-direction: column;
}

#phone-tab-overlay.visible { display: flex; }

#phone-tab-overlay-header {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px 16px;
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
  flex-shrink: 0;
}

#phone-tab-overlay-content { flex: 1; overflow-y: auto; padding: 16px; }

/* ── BLE Scanner view ───────────────────────────────────────────────────── */

.ble-scanner-wrap {
  max-width: 560px;
  margin: 0 auto;
  padding: 20px 16px 32px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.ble-scanner-header {
  display: flex;
  align-items: center;
  gap: 12px;
  padding-bottom: 4px;
}

.ble-no-support-notice {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  background: #fffbeb;
  border: 1px solid #fcd34d;
  border-radius: 8px;
  padding: 12px 14px;
  font-size: 13px;
  color: #92400e;
  line-height: 1.5;
}

.ble-scan-row {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
}

.ble-scan-main-btn {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 20px;
  font-size: 14px;
}

.ble-status {
  font-size: 13px;
  color: var(--color-text-muted);
  flex: 1;
  min-width: 0;
}

.ble-manual-section {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 10px;
  padding: 14px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.ble-manual-label {
  font-size: 12px;
  font-weight: 600;
  color: var(--color-text-muted);
  letter-spacing: .04em;
}

.ble-manual-row {
  display: flex;
  gap: 8px;
  align-items: center;
}

.ble-results-section {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.ble-results-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.ble-result-card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 10px;
  overflow: hidden;
}

.ble-card-header {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 14px;
  border-bottom: 1px solid var(--color-border);
}

.ble-card-matched     { background: #eff6ff; }
.ble-card-unregistered { background: var(--color-surface-alt, #f8fafc); }

.ble-card-device-name {
  flex: 1;
  font-family: monospace;
  font-size: 13px;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ble-card-time {
  font-size: 11px;
  color: var(--color-text-muted);
  white-space: nowrap;
  flex-shrink: 0;
}

.ble-card-body {
  padding: 12px 14px;
}

.ble-asset-name {
  font-size: 15px;
  font-weight: 600;
  margin-bottom: 4px;
}

.ble-asset-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  font-size: 12px;
  color: var(--color-text-muted);
  margin-bottom: 4px;
}

.ble-asset-meta span + span::before {
  content: '·';
  margin-right: 6px;
}

.ble-asset-desc {
  font-size: 12px;
  color: var(--color-text-muted);
  margin-top: 4px;
  line-height: 1.4;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* ── Geofence notification overlay ─────────────────────────────────────── */

@keyframes geofence-notif-in {
  from { opacity: 0; transform: translateY(16px) scale(0.97); }
  to   { opacity: 1; transform: translateY(0)    scale(1); }
}

@keyframes geofence-notif-out {
  from { opacity: 1; transform: translateY(0)    scale(1);    max-height: 200px; }
  to   { opacity: 0; transform: translateY(8px)  scale(0.97); max-height: 0; }
}

#geofence-notif-container {
  position: fixed;
  bottom: 80px;
  right: 16px;
  z-index: 500;
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-width: 340px;
  pointer-events: none;
}

.geofence-notif-card {
  background: #fff;
  border: 1px solid #d1d5db;
  border-radius: 12px;
  box-shadow: 0 4px 20px rgba(0,0,0,.14);
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  pointer-events: all;
  animation: geofence-notif-in 0.25s ease both;
  overflow: hidden;
}

.geofence-notif-card.removing {
  animation: geofence-notif-out 0.25s ease forwards;
}

.geofence-notif-header {
  display: flex;
  align-items: center;
  gap: 8px;
}

.geofence-notif-icon {
  flex-shrink: 0;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: #eff6ff;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #2563eb;
}

.geofence-notif-icon svg { width: 16px; height: 16px; stroke: currentColor; }

.geofence-notif-title {
  font-size: 13px;
  font-weight: 700;
  color: #111827;
  flex: 1;
}

.geofence-notif-msg {
  font-size: 13px;
  color: #374151;
  line-height: 1.45;
}

.geofence-notif-actions {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
}

.geofence-notif-actions .btn-sm {
  font-size: 12px;
  padding: 5px 12px;
}


/* ── Asset document list ───────────────────────────────────────────────── */

.doc-list {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.doc-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  font-size: 13px;
  overflow: hidden;
}

.doc-item a {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--color-primary);
  text-decoration: none;
}

.doc-item a:hover { text-decoration: underline; }

.doc-type {
  font-size: 11px;
  font-weight: 600;
  padding: 2px 6px;
  border-radius: 4px;
  background: var(--color-bg);
  color: var(--color-text-muted);
  flex-shrink: 0;
}

/* ── Chat sessions manager ─────────────────────────────────────────────── */

.chat-sessions-filter {
  display: flex;
  gap: 0;
  border-bottom: 1px solid var(--color-border);
  flex-shrink: 0;
}

.chat-sessions-filter-btn {
  flex: 1;
  padding: 7px 0;
  border: none;
  background: none;
  font-size: 12px;
  font-weight: 500;
  color: var(--color-text-muted);
  cursor: pointer;
  border-bottom: 2px solid transparent;
  transition: color 0.12s, border-color 0.12s;
}

.chat-sessions-filter-btn.active {
  color: var(--color-primary);
  border-bottom-color: var(--color-primary);
}

.chat-session-actions {
  display: none;
  align-items: center;
  gap: 2px;
  flex-shrink: 0;
  margin-left: auto;
}

.chat-session-item:hover .chat-session-actions { display: flex; }

.chat-session-action-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border: none;
  border-radius: var(--radius-sm);
  background: none;
  cursor: pointer;
  color: var(--color-text-muted);
  transition: background 0.12s, color 0.12s;
}

.chat-session-action-btn:hover { background: var(--color-bg); color: var(--color-text); }
.chat-session-action-del:hover { color: var(--color-danger); }

.chat-session-title-input {
  flex: 1;
  border: 1px solid var(--color-primary);
  border-radius: var(--radius-sm);
  padding: 2px 6px;
  font-size: 13px;
  font-family: inherit;
  outline: none;
  min-width: 0;
}

@media (max-width: 768px) {
  .chat-session-actions { display: flex; }
}

/* ── Phone sign-in ──────────────────────────────────────────────────────────
   A screen built for a driver at a truck, not the desktop card with pieces
   hidden. Only ~350pt of height survives once the keyboard is up, so this
   spends it on two fields and one button and nothing else.
   Rendered by Login._renderLoginPhone (js/login.js). */

.phone-login {
  width: 100%;
  max-width: 420px;
  display: flex;
  flex-direction: column;
  gap: 18px;
  padding: 4px 20px;
}

.phone-login-brand {
  text-align: center;
}

/* The artwork is white with an orange road mark, so it needs the dark plate
   behind it to read on a light background. */
.phone-login-brand img {
  width: 100%;
  max-width: 220px;
  background: #1f2430;
  border-radius: 12px;
  padding: 10px 14px;
}

.phone-login-brand h1 {
  font-size: 1.25rem;
  font-weight: 600;
  color: var(--color-text);
  margin-top: 10px;
}

.phone-login-form {
  display: flex;
  flex-direction: column;
}

.phone-login-label {
  font-size: 13px;
  font-weight: 600;
  color: var(--color-text-secondary, var(--color-text-muted));
  margin-bottom: 6px;
}

.phone-login-label-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-top: 16px;
}

.phone-login-link {
  font-size: 13px;
  color: var(--color-primary);
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
}

/* 16px minimum: iOS zooms the page in when a focused input is smaller, which
   is what makes the whole layout lurch sideways on tap. 52px tall so it is a
   reliable target with work gloves on. */
.phone-login-input {
  width: 100%;
  font-size: 16px;
  min-height: 52px;
  padding: 14px;
  border: 1px solid var(--color-border);
  border-radius: 10px;
  background: var(--color-surface);
  color: var(--color-text);
}

.phone-login-input:focus {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px rgba(26,115,232,0.15);
}

.phone-login-save {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 16px;
  font-size: 15px;
  color: var(--color-text-secondary, var(--color-text-muted));
  cursor: pointer;
  user-select: none;
}

.phone-login-save input {
  width: 22px;
  height: 22px;
  accent-color: var(--color-primary);
}

.phone-login-submit {
  width: 100%;
  min-height: 54px;
  margin-top: 20px;
  border: none;
  border-radius: 10px;
  background: var(--color-primary);
  color: #fff;
  font-size: 17px;
  font-weight: 600;
  cursor: pointer;
}

.phone-login-submit:active {
  background: var(--color-primary-dark);
}

/* ── Privacy consent gate ────────────────────────────────────────────────────
   The tracking disclosure shown once (per policy version) before the app
   records any position. Full-screen and above everything including the modal
   overlay's own layer, because it is a gate: nothing behind it should be
   reachable until the driver has answered. See js/privacy-consent.js.

   Scrolls internally rather than clipping — the points list plus the two
   buttons do not fit a small phone in landscape, and a driver must always be
   able to reach the Accept button. */
.privacy-gate {
  position: fixed;
  inset: 0;
  z-index: 9000;
  background: var(--color-bg);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: max(24px, env(safe-area-inset-top)) 18px
           max(24px, env(safe-area-inset-bottom));
}

.privacy-gate.hidden { display: none; }

.privacy-gate-card {
  width: 100%;
  max-width: 460px;
  margin: auto;
}

.privacy-gate-head {
  text-align: center;
  margin-bottom: 22px;
}

.privacy-gate-icon {
  width: 52px;
  height: 52px;
  border-radius: 50%;
  background: var(--color-primary);
  color: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 12px;
}

.privacy-gate-icon svg { width: 26px; height: 26px; }

.privacy-gate-head h1 {
  font-size: 1.4rem;
  font-weight: 650;
  color: var(--color-text);
  margin: 0 0 6px;
}

.privacy-gate-sub {
  font-size: 14px;
  line-height: 1.5;
  color: var(--color-text-muted);
  margin: 0;
}

.privacy-gate-points {
  list-style: none;
  margin: 0 0 18px;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.privacy-gate-points li {
  display: flex;
  gap: 13px;
  align-items: flex-start;
  padding: 13px 14px;
  background: var(--color-surface);
  border: 1px solid var(--color-border, #e0e3e7);
  border-radius: 10px;
  margin-bottom: 8px;
}

.privacy-gate-points li svg {
  width: 19px;
  height: 19px;
  flex: none;
  margin-top: 1px;
  color: var(--color-primary);
}

.privacy-gate-points strong {
  display: block;
  font-size: 14.5px;
  font-weight: 620;
  color: var(--color-text);
  line-height: 1.35;
  margin-bottom: 3px;
}

.privacy-gate-points span {
  display: block;
  font-size: 13.5px;
  line-height: 1.45;
  color: var(--color-text-muted);
}

.privacy-gate-fineprint {
  font-size: 13px;
  line-height: 1.5;
  color: var(--color-text-muted);
  margin: 0 0 20px;
  padding: 0 2px;
}

.privacy-gate-fineprint a {
  color: var(--color-primary);
  font-weight: 600;
}

.privacy-gate-actions {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* Deliberately big: this is tapped once, wearing gloves, in a truck cab. */
.privacy-gate-accept {
  width: 100%;
  padding: 15px;
  font-size: 16px;
  font-weight: 620;
  color: #fff;
  background: var(--color-primary);
  border: none;
  border-radius: 10px;
  cursor: pointer;
}

.privacy-gate-accept:active { background: var(--color-primary-dark); }

.privacy-gate-decline {
  width: 100%;
  padding: 12px;
  font-size: 14px;
  font-weight: 500;
  color: var(--color-text-muted);
  background: none;
  border: none;
  cursor: pointer;
}

/* TEMPORARY — delete with _PIN_HINT in js/login.js once the legacy PIN
   accounts have migrated. Sits directly under the password field on both the
   phone and desktop sign-in forms. Muted and small: it is guidance for a
   shrinking minority, not a call to action for everyone. */
.login-pin-hint {
  font-size: 12px;
  line-height: 1.45;
  color: var(--color-text-muted);
  margin: 6px 0 0;
}

/* Privacy link under the sign-in button. Present on both the phone and desktop
   login screens — see js/login.js for why it must be reachable pre-auth. */
.phone-login-legal {
  font-size: 12.5px;
  line-height: 1.5;
  text-align: center;
  color: var(--color-text-muted);
  margin: 16px 0 0;
  padding: 0 8px;
}

.phone-login-legal a {
  color: var(--color-primary);
  font-weight: 600;
  white-space: nowrap;
}
