/* ===== CSS Variables ===== */
:root {
  --bg-primary: #0f1923;
  --bg-secondary: #1a2632;
  --bg-tertiary: #243342;
  --bg-card: #1e2d3d;
  --text-primary: #e8edf2;
  --text-secondary: #8899aa;
  --text-muted: #5a6f82;
  --accent: #00c853;
  --accent-hover: #00e676;
  --accent-dim: rgba(0, 200, 83, 0.15);
  --danger: #ff5252;
  --warning: #ffab40;
  --info: #40c4ff;
  --spark-color: #ffe600;
  --vodafone-color: #e60000;
  --twodeg-color: #00aaff;
  --sidebar-width: 380px;
  --mobile-header-height: calc(56px + env(safe-area-inset-top, 0px)); /* fullscreen display: bar background reaches the true screen top; content pads below the camera cutout */
  --radius: 8px;
  --radius-sm: 4px;
  --shadow: 0 4px 24px rgba(0,0,0,0.4);
  --transition: 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}

/* ===== Reset ===== */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html, body { height: 100%; overflow: hidden; }
body {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  background: var(--bg-primary);
  color: var(--text-primary);
  -webkit-font-smoothing: antialiased;
}

/* ===== Login Screen ===== */
#login-screen {
  position: fixed; inset: 0;
  background: var(--bg-primary);
  display: flex; align-items: center; justify-content: center;
  z-index: 10001;
  transition: opacity 0.4s ease;
}
#login-screen.fade-out { opacity: 0; pointer-events: none; }
.login-card {
  display: flex; flex-direction: column; align-items: center;
  padding: 32px 28px;
  background: var(--bg-secondary);
  border-radius: 16px;
  border: 1px solid var(--border, rgba(255,255,255,0.06));
  width: min(360px, 90vw);
}
.login-input {
  width: 100%; padding: 10px 12px;
  border-radius: var(--radius-sm, 6px);
  border: 1px solid var(--border, rgba(255,255,255,0.1));
  background: var(--bg-tertiary); color: var(--text-primary);
  font-size: 0.88rem; font-family: inherit;
  margin-bottom: 8px; outline: none;
}
.login-input:focus { border-color: var(--accent); }
.login-error {
  font-size: 0.75rem; color: #ff5252;
  margin-bottom: 8px; display: none;
  text-align: center;
}
.login-btn {
  width: 100%; padding: 10px; font-size: 0.88rem;
  border-radius: var(--radius-sm, 6px);
  cursor: pointer; margin-bottom: 6px;
}
.login-google-btn {
  background: var(--bg-tertiary); color: var(--text-secondary);
  border: 1px solid var(--border, rgba(255,255,255,0.1));
}
.login-google-btn:hover { background: var(--bg-card); }

/* ===== Loading Screen ===== */
#loading-screen {
  position: fixed; inset: 0;
  background: var(--bg-primary);
  display: flex; align-items: center; justify-content: center;
  z-index: 10000;
  transition: opacity 0.5s ease;
}
#loading-screen.fade-out { opacity: 0; pointer-events: none; }
.loader-content { text-align: center; }
.loader-icon { font-size: 3rem; color: var(--accent); margin-bottom: 1rem; animation: pulse 1.5s infinite; }
.loader-content h2 { font-size: 1.5rem; font-weight: 700; margin-bottom: 0.5rem; }
.loader-content p { color: var(--text-secondary); margin-bottom: 1.5rem; }
.loader-bar { width: 200px; height: 3px; background: var(--bg-tertiary); border-radius: 3px; overflow: hidden; margin: 0 auto; }
.loader-progress { height: 100%; width: 30%; background: var(--accent); border-radius: 3px; animation: loading 1.5s ease-in-out infinite; }
@keyframes loading { 0% { transform: translateX(-100%); } 100% { transform: translateX(400%); } }
@keyframes pulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.1); } }

/* ===== Mobile Header ===== */
#mobile-header {
  display: none;
  position: fixed; top: 0; left: 0; right: 0;
  height: var(--mobile-header-height);
  background: var(--bg-secondary);
  border-bottom: 1px solid var(--bg-tertiary);
  align-items: center;
  justify-content: space-between;
  padding: env(safe-area-inset-top, 0px) 12px 0;
  z-index: 1001;
}
#mobile-header h1 { font-size: 1.1rem; font-weight: 700; }
#mobile-header button {
  background: none; border: none; color: var(--text-primary);
  font-size: 1.2rem; padding: 8px; cursor: pointer;
}

/* ===== Sidebar ===== */
.sidebar {
  position: fixed; top: 0; left: 0; bottom: 0;
  width: var(--sidebar-width);
  background: var(--bg-secondary);
  border-right: 1px solid var(--bg-tertiary);
  display: flex; flex-direction: column;
  z-index: 1000;
  transition: transform var(--transition);
  overflow: hidden;
}
.sidebar.collapsed { transform: translateX(-100%); }

/* Desktop sidebar collapse (onX-style). One body-level var override moves every
   --sidebar-width dependent (#map, #info-panel, #weather-timeline, 3D/basemap
   switches) at once. Desktop-only: mobile keeps the .open overlay pattern. */
@media (min-width: 769px) {
  body.sidebar-collapsed { --sidebar-width: 0px; }
  body.sidebar-collapsed .sidebar { transform: translateX(-100%); }
  /* Collapsed sidebar puts #info-panel at left:12px — the same corner the
     fixed #sidebar-expand (») button occupies — covering the site name.
     Shift the pane right to clear the 38px button + gaps. */
  body.sidebar-collapsed #info-panel { left: 62px; }
}
#sidebar-collapse {
  background: none; border: none; color: var(--text-secondary);
  font-size: 1rem; cursor: pointer; padding: 4px 8px;
}
#sidebar-collapse:hover { color: var(--text-primary); }
#sidebar-expand {
  position: fixed; top: 12px; left: 12px; z-index: 1001;
  width: 38px; height: 38px; border-radius: var(--radius-sm);
  background: var(--bg-secondary); border: 1px solid var(--bg-tertiary);
  color: var(--text-primary); font-size: 1rem; cursor: pointer;
  display: none; align-items: center; justify-content: center;
  box-shadow: 0 2px 10px rgba(0,0,0,0.4);
}
body.sidebar-collapsed #sidebar-expand { display: flex; }

.sidebar-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px 20px;
  border-bottom: 1px solid var(--bg-tertiary);
  flex-shrink: 0;
}
.brand { display: flex; align-items: center; gap: 10px; }
.brand i { font-size: 1.5rem; color: var(--accent); }
.brand h1 { font-size: 1.25rem; font-weight: 700; }
#sidebar-close {
  background: none; border: none; color: var(--text-secondary);
  font-size: 1.2rem; cursor: pointer; padding: 4px;
  display: none;
}

.sidebar-body {
  flex: 1; overflow-y: auto; overflow-x: hidden;
  padding: 0;
  scrollbar-width: thin;
  scrollbar-color: var(--bg-tertiary) transparent;
}
.sidebar-body::-webkit-scrollbar { width: 6px; }
.sidebar-body::-webkit-scrollbar-track { background: transparent; }
.sidebar-body::-webkit-scrollbar-thumb { background: var(--bg-tertiary); border-radius: 3px; }

.sidebar-footer {
  padding: 12px 20px;
  border-top: 1px solid var(--bg-tertiary);
  flex-shrink: 0;
}
.sidebar-footer p { font-size: 0.7rem; color: var(--text-muted); line-height: 1.5; }

/* ===== Tab Navigation ===== */
.tab-nav {
  display: flex;
  border-bottom: 1px solid var(--bg-tertiary);
  flex-shrink: 0;
}
.tab-btn {
  flex: 1;
  padding: 12px 8px;
  background: none; border: none;
  color: var(--text-secondary);
  font-size: 0.8rem; font-weight: 500;
  cursor: pointer;
  border-bottom: 2px solid transparent;
  transition: all var(--transition);
  display: flex; align-items: center; justify-content: center; gap: 6px;
}
.tab-btn:hover { color: var(--text-primary); background: var(--bg-tertiary); }
.tab-btn.active { color: var(--accent); border-bottom-color: var(--accent); }
.tab-btn i { font-size: 0.9rem; }

.tab-content { display: none; }
.tab-content.active { display: block; }

/* ===== Sidebar Sections ===== */
.sidebar-section {
  padding: 16px 20px;
  border-bottom: 1px solid rgba(255,255,255,0.04);
}
.sidebar-section h3 {
  font-size: 0.8rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--text-secondary);
  margin-bottom: 12px;
  display: flex; align-items: center; gap: 8px;
}
.sidebar-section h3 i { color: var(--accent); font-size: 0.85rem; }
.sidebar-section h4 {
  font-size: 0.78rem; font-weight: 600;
  color: var(--text-secondary);
  margin: 12px 0 8px;
}
.hint { font-size: 0.78rem; color: var(--text-muted); margin-bottom: 12px; line-height: 1.4; }

/* ===== Search ===== */
.search-box {
  display: flex; align-items: center;
  background: var(--bg-tertiary);
  border-radius: var(--radius);
  padding: 0 12px;
  border: 1px solid transparent;
  transition: border-color var(--transition);
}
.search-box:focus-within { border-color: var(--accent); }
.search-box i { color: var(--text-muted); font-size: 0.85rem; }
.search-box input {
  flex: 1; background: none; border: none; outline: none;
  color: var(--text-primary); padding: 10px 10px;
  font-size: 0.85rem; font-family: inherit;
}
.search-box input::placeholder { color: var(--text-muted); }
.search-box button { background: none; border: none; color: var(--text-muted); cursor: pointer; padding: 4px; }
.search-results {
  margin-top: 8px;
  background: var(--bg-tertiary);
  border-radius: var(--radius);
  max-height: 240px;
  overflow-y: auto;
}
.search-results.hidden { display: none; }
.search-result-item {
  padding: 10px 14px;
  cursor: pointer;
  font-size: 0.82rem;
  border-bottom: 1px solid rgba(255,255,255,0.04);
  transition: background var(--transition);
  display: flex; align-items: center; gap: 8px;
}
.search-result-item:hover { background: rgba(255,255,255,0.05); }
.search-result-item i { color: var(--accent); width: 16px; text-align: center; }
.search-result-item:last-child { border-bottom: none; }

/* ===== Layer Toggles ===== */
.layer-toggle {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 0;
  cursor: pointer;
  font-size: 0.85rem;
}
.layer-toggle input { display: none; }
.toggle-slider {
  width: 36px; height: 20px;
  background: var(--bg-tertiary);
  border-radius: 10px;
  position: relative;
  transition: background var(--transition);
  flex-shrink: 0;
}
.toggle-slider::after {
  content: '';
  position: absolute;
  width: 16px; height: 16px;
  background: var(--text-secondary);
  border-radius: 50%;
  top: 2px; left: 2px;
  transition: all var(--transition);
}
.layer-toggle input:checked + .toggle-slider { background: var(--accent-dim); }
.layer-toggle input:checked + .toggle-slider::after { transform: translateX(16px); background: var(--accent); }
.toggle-label { flex: 1; }

/* ===== Route vehicle picker (js/vehicle.js + js/app.js) ===== */
.route-vehicle {
  padding-bottom: 10px;
  margin-bottom: 4px;
  border-bottom: 1px solid var(--bg-tertiary);
}
.route-vehicle-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: 8px;
  margin-bottom: 6px;
}
.route-vehicle-title {
  font-size: 0.72rem; font-weight: 600;
  color: var(--text-secondary);
  text-transform: uppercase; letter-spacing: 0.04em;
}
.route-vehicle-reset {
  background: none; border: 0; padding: 0;
  color: var(--accent); font-size: 0.66rem; cursor: pointer;
}
.route-vehicle-reset[hidden] { display: none; }
.route-vehicle-picker {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 5px;
}
.route-vehicle-btn {
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  padding: 7px 3px;
  border: 1px solid var(--bg-tertiary);
  border-radius: 6px;
  background: transparent;
  color: var(--text-secondary);
  font-size: 0.62rem;
  cursor: pointer;
  transition: all var(--transition);
  min-width: 0;
}
.route-vehicle-btn i { font-size: 0.92rem; }
.route-vehicle-btn span { overflow-wrap: anywhere; text-align: center; line-height: 1.2; }
.route-vehicle-btn:hover { border-color: var(--text-muted, #888); color: var(--text-primary); }
.route-vehicle-btn[aria-pressed="true"] {
  border-color: var(--accent);
  background: rgba(0, 200, 83, 0.12);
  color: var(--text-primary);
}
.route-vehicle-btn[aria-pressed="true"] i { color: var(--accent); }
.route-vehicle-tow {
  display: flex; align-items: center; gap: 7px;
  margin-top: 8px;
  font-size: 0.76rem;
  cursor: pointer;
}
.route-vehicle-tow[hidden] { display: none; }
.route-vehicle-note {
  font-size: 0.66rem;
  color: var(--text-muted, #888);
  margin-top: 7px;
  line-height: 1.45;
}
.route-vehicle-note:empty { display: none; }
.route-vehicle-note .warn { color: #ffab40; }

.badge {
  font-size: 0.65rem; font-weight: 600;
  padding: 2px 6px; border-radius: 3px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}
.badge-green { background: rgba(0,200,83,0.15); color: #00c853; }
.badge-blue { background: rgba(64,196,255,0.15); color: #40c4ff; }
.badge-orange { background: rgba(255,171,64,0.15); color: #ffab40; }
.badge-purple { background: rgba(176,128,255,0.15); color: #b080ff; }
.badge-teal { background: rgba(38,198,178,0.15); color: #26c6b2; }
.badge-yellow { background: rgba(255,230,0,0.15); color: #ffe600; }
.badge-red { background: rgba(230,0,0,0.15); color: #ff5252; }

/* ===== Base Map Selector ===== */
/* Warm up CARTO Voyager's pale palette so the base map reads richer, not washed out */
.basemap-selector { display: flex; gap: 6px; }
.basemap-btn {
  flex: 1; padding: 8px;
  background: var(--bg-tertiary);
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  color: var(--text-secondary);
  font-size: 0.75rem; font-weight: 500;
  cursor: pointer;
  transition: all var(--transition);
  display: flex; flex-direction: column; align-items: center; gap: 4px;
}
.basemap-btn i { font-size: 1rem; }
.basemap-btn:hover { color: var(--text-primary); background: rgba(255,255,255,0.08); }
.basemap-btn.active { border-color: var(--accent); color: var(--accent); background: var(--accent-dim); }

/* ===== Filter Chips ===== */
.filter-group { display: flex; flex-wrap: wrap; gap: 6px; }
.filter-chip {
  display: flex; align-items: center; gap: 4px;
  padding: 6px 10px;
  background: var(--bg-tertiary);
  border-radius: 20px;
  font-size: 0.75rem;
  cursor: pointer;
  transition: all var(--transition);
  border: 1px solid transparent;
  user-select: none;
}
.filter-chip:hover { background: rgba(255,255,255,0.08); }
.filter-chip input { display: none; }
.filter-chip:has(input:checked) { border-color: var(--accent); background: var(--accent-dim); color: var(--accent); }
.filter-chip i { font-size: 0.7rem; }

/* ===== Route Planning ===== */
.route-inputs { display: flex; flex-direction: column; gap: 4px; }
.route-point {
  display: flex; align-items: center; gap: 10px;
  background: var(--bg-tertiary);
  border-radius: var(--radius-sm);
  padding: 0 12px;
}
.route-point input {
  flex: 1; background: none; border: none; outline: none;
  color: var(--text-primary); padding: 10px 0;
  font-size: 0.85rem; font-family: inherit;
}
.route-point input::placeholder { color: var(--text-muted); }
/* Route search results dropdown */
.route-search-results {
  position: absolute;
  left: 0; right: 0;
  z-index: 9999;
  margin-top: 2px;
  max-height: 200px;
  overflow-y: auto;
  box-shadow: 0 6px 20px rgba(0,0,0,0.4);
  border: 1px solid rgba(255,255,255,0.08);
}
/* Suggestions are positioned in JS (see _positionResults in js/route.js):
   fixed to the viewport but anchored to the input's real position, flipping
   above it when the phone keyboard leaves no room below. The old mobile rule
   pinned them to top:52px of the SCREEN — detached from the box being typed
   in, floating over the header ("the destination box broke out"). */
.route-search-results {
  position: fixed;
  z-index: 10000;
}
.route-start-icon { color: var(--accent); font-size: 0.6rem; }
.route-locate-btn {
  flex-shrink: 0;
  padding: 6px 8px;
  border: none;
  color: var(--accent);
  background: none;
  font-size: 1rem;
  cursor: pointer;
  opacity: 0.7;
  transition: opacity 0.2s;
}
.route-locate-btn:hover { opacity: 1; }
.route-locate-btn.locating { animation: pulse-locate 1s infinite; }
@keyframes pulse-locate { 0%, 100% { opacity: 0.4; } 50% { opacity: 1; } }
.route-end-icon { color: var(--danger); font-size: 0.85rem; }
.route-waypoint-icon { color: var(--info); font-size: 0.6rem; }

.route-actions { display: flex; gap: 8px; margin-top: 8px; }
.route-dates { margin-top: 4px; }
.date-inputs { display: flex; gap: 8px; }
.date-field { flex: 1; }
.date-field label { display: block; font-size: 0.72rem; color: var(--text-muted); margin-bottom: 4px; }
.date-field input {
  width: 100%; padding: 8px 10px;
  background: var(--bg-tertiary);
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  color: var(--text-primary);
  font-size: 0.82rem; font-family: inherit;
  outline: none;
}
.date-field input:focus { border-color: var(--accent); }

/* ===== Buttons ===== */
.btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 14px;
  background: var(--bg-tertiary);
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: var(--radius-sm);
  color: var(--text-secondary);
  font-size: 0.8rem; font-weight: 500;
  cursor: pointer;
  transition: all var(--transition);
  font-family: inherit;
}
.btn:hover { background: rgba(255,255,255,0.08); color: var(--text-primary); }
.btn-sm { padding: 6px 10px; font-size: 0.75rem; }
.btn-primary { background: var(--accent); color: #000; border-color: var(--accent); font-weight: 600; }
.btn-primary:hover { background: var(--accent-hover); color: #000; }
.btn-danger { border-color: rgba(255,82,82,0.3); color: var(--danger); }
.btn-danger:hover { background: rgba(255,82,82,0.1); }
.btn-block { width: 100%; justify-content: center; margin-top: 12px; }

/* ===== Weather Controls ===== */
.time-slider-container { padding: 4px 0; }
.time-slider-container input[type="range"] {
  width: 100%; -webkit-appearance: none; appearance: none;
  height: 4px; background: var(--bg-tertiary);
  border-radius: 2px; outline: none;
}
.time-slider-container input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 16px; height: 16px;
  background: var(--accent); border-radius: 50%;
  cursor: pointer;
}
.time-labels { display: flex; justify-content: space-between; margin-top: 4px; font-size: 0.7rem; color: var(--text-muted); }

/* ===== Map ===== */
#map {
  position: fixed;
  top: 0; bottom: 0;
  left: var(--sidebar-width);
  right: 0;
  z-index: 1;
}

/* ===== Map Controls ===== */
#map-controls {
  position: fixed;
  top: 16px; right: 16px;
  display: flex; flex-direction: column; gap: 8px;
  z-index: 500;
}
.map-btn {
  width: auto; height: auto;
  padding: 8px 10px;
  background: var(--bg-secondary);
  border: 1px solid var(--bg-tertiary);
  border-radius: var(--radius);
  color: var(--text-primary);
  font-size: 1rem;
  cursor: pointer;
  display: flex; align-items: center; gap: 6px;
  transition: all var(--transition);
  box-shadow: var(--shadow);
}
.map-btn-label {
  font-size: 0.65rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--text-secondary);
}
.map-btn:hover { background: var(--bg-tertiary); color: var(--accent); }
.map-btn:hover .map-btn-label { color: var(--accent); }
.map-btn.active { background: var(--accent); color: #fff; border-color: var(--accent); }
.map-btn.active .map-btn-label { color: #fff; }

/* ===== Weather Tile Overlays ===== */
.weather-tile-temperature { filter: saturate(2.5) contrast(1.8) brightness(1.1); }
.weather-tile-precipitation { filter: saturate(2.0) contrast(1.5); }
.weather-tile-clouds { filter: contrast(1.4) brightness(0.95); }
.weather-tile-wind { filter: saturate(1.8) contrast(1.4); }

/* ===== Weather Timeline ===== */
/* ===== Info Panel =====
   Vertical side-loading pane (onX-style), 2026-07-27. Was a bottom-anchored
   horizontal strip eating 50vh; now a left card over the map. Mobile keeps the
   bottom-sheet geometry (overridden in the 768px block below). */
#info-panel {
  position: fixed;
  top: 12px; bottom: 12px;
  left: calc(var(--sidebar-width) + 12px);
  width: 380px;
  max-width: calc(100vw - var(--sidebar-width) - 24px);
  background: var(--bg-secondary);
  border: 1px solid var(--bg-tertiary);
  border-radius: var(--radius);
  z-index: 600;
  overflow-y: auto;
  box-shadow: 0 8px 30px rgba(0,0,0,0.45);
  transition: transform var(--transition), opacity var(--transition);
}
#info-panel.hidden {
  transform: translateX(calc(-100% - 420px));
  opacity: 0;
  pointer-events: none;
}
#info-close {
  position: sticky; top: 0; right: 0;
  float: right; margin: 12px 12px 0 0;
  background: var(--bg-tertiary); border: none;
  z-index: 10;
  color: var(--text-secondary); width: 32px; height: 32px;
  border-radius: 50%; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  font-size: 0.9rem;
}
#info-content { padding: 12px 16px 16px; }

/* Info Panel Content */
.info-header { margin-bottom: 8px; }
.info-header h2 { font-size: 1.15rem; font-weight: 700; margin-bottom: 4px; }
.info-header .info-type { font-size: 0.78rem; color: var(--accent); font-weight: 500; text-transform: uppercase; letter-spacing: 0.03em; }
.info-header .info-status { font-size: 0.75rem; padding: 2px 8px; border-radius: 3px; margin-left: 8px; }
.info-header .info-status.open { background: rgba(0,200,83,0.15); color: #00c853; }
.info-header .info-status.closed { background: rgba(255,82,82,0.15); color: #ff5252; }

.info-facilities {
  display: flex; flex-wrap: wrap; gap: 6px;
  margin-bottom: 10px;
}
.facility-badge {
  display: flex; align-items: center; gap: 4px;
  padding: 3px 8px;
  background: var(--bg-tertiary);
  border-radius: var(--radius-sm);
  font-size: 0.72rem;
  color: var(--text-secondary);
}
.facility-badge.available { color: var(--accent); background: var(--accent-dim); }
.facility-badge i { font-size: 0.8rem; }

.info-details { display: grid; grid-template-columns: 1fr 1fr; gap: 6px 12px; margin-bottom: 10px; }
.info-detail { }
.info-detail-label { font-size: 0.7rem; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.03em; margin-bottom: 2px; }
.info-detail-value { font-size: 0.85rem; color: var(--text-primary); }

.info-weather {
  background: var(--bg-tertiary);
  border-radius: var(--radius);
  padding: 14px;
  margin-bottom: 16px;
}
.info-weather h4 { font-size: 0.78rem; color: var(--text-secondary); margin-bottom: 8px; }
.weather-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(80px, 1fr)); gap: 8px;
}
.weather-item { text-align: center; }
.weather-item .wx-icon { font-size: 1.3rem; margin-bottom: 2px; }
.weather-item .wx-temp { font-size: 1rem; font-weight: 600; }
.weather-item .wx-desc { font-size: 0.68rem; color: var(--text-muted); }
.weather-item .wx-day { font-size: 0.68rem; color: var(--text-secondary); font-weight: 500; }

.info-cell-coverage { margin-bottom: 12px; max-width: 340px; }
.cell-bar-container { display: flex; align-items: center; gap: 8px; margin-bottom: 4px; }
.cell-carrier { font-size: 0.72rem; width: 64px; color: var(--text-secondary); }
.cell-bar { flex: 1; height: 6px; background: var(--bg-tertiary); border-radius: 3px; overflow: hidden; }
.cell-bar-fill { height: 100%; border-radius: 3px; transition: width 0.5s ease; }
.cell-bar-fill.spark { background: var(--spark-color); }
.cell-bar-fill.vodafone { background: var(--vodafone-color); }
.cell-bar-fill.twodeg { background: var(--twodeg-color); }
.cell-tech { font-size: 0.64rem; color: var(--text-muted); width: 52px; text-align: right; white-space: nowrap; }

.info-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.info-actions .btn i { font-size: 0.8rem; }

/* ===== Pane card components (onX card anatomy, shared by trail/land/hazard/
   waypoint cards and reusable by any info-panel content) ===== */
.pane-tiles { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-bottom: 14px; }
.pane-tile { background: var(--bg-tertiary); border-radius: var(--radius-sm); padding: 8px 10px; }
.pane-tile.wide { grid-column: 1 / -1; }
.pane-tile .pt-label { font-size: 0.68rem; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.03em; }
.pane-tile .pt-value { font-size: 0.95rem; font-weight: 700; margin-top: 2px; }
.pane-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px; }
.pane-chip { border: 1px solid var(--bg-tertiary); background: var(--bg-tertiary); border-radius: 999px; padding: 3px 10px; font-size: 0.72rem; color: var(--text-secondary); }
.pane-chip.ok { border-color: var(--accent); color: var(--accent); background: none; }
.pane-chip.warn { border-color: #f59e0b; color: #f59e0b; background: none; }
.pane-chip.bad { border-color: #ff5252; color: #ff5252; background: none; }
.pane-kv { border-top: 1px solid var(--bg-tertiary); padding: 8px 2px; display: flex; gap: 8px; font-size: 0.82rem; }
.pane-kv .k { color: var(--text-muted); min-width: 110px; flex-shrink: 0; }
.pane-kv .v { font-weight: 600; }
.pane-actions { display: flex; gap: 12px; justify-content: space-around; border-top: 1px solid var(--bg-tertiary); padding: 12px 4px 2px; margin-top: 12px; }
.pane-action { background: none; border: none; color: var(--text-secondary); cursor: pointer; display: flex; flex-direction: column; align-items: center; gap: 5px; font-size: 0.7rem; }
.pane-action .pa-ico { width: 42px; height: 42px; border-radius: 50%; display: flex; align-items: center; justify-content: center; background: var(--bg-tertiary); border: 1px solid var(--bg-tertiary); font-size: 1rem; color: var(--text-primary); }
.pane-action.primary .pa-ico { background: var(--accent); color: #00120a; }
.pane-action:hover .pa-ico { border-color: var(--accent); }
.diff-pill { display: inline-block; border-radius: 5px; padding: 2px 10px; font-weight: 700; font-size: 0.78rem; color: #08131c; }
.pane-note { color: var(--text-muted); font-size: 0.72rem; margin-top: 10px; line-height: 1.45; }

/* Waypoints */
.wp-icon-grid { display: grid; grid-template-columns: repeat(6, 1fr); gap: 6px; margin: 8px 0; }
.wp-icon-grid button { font-size: 1.05rem; padding: 8px 0; border-radius: var(--radius-sm); border: 2px solid var(--bg-tertiary); background: var(--bg-tertiary); cursor: pointer; }
.wp-icon-grid button.sel { border-color: var(--accent); }
.wp-color-row { display: flex; gap: 8px; margin: 8px 0; }
.wp-color-row button { width: 26px; height: 26px; border-radius: 50%; cursor: pointer; border: 2px solid transparent; }
.wp-color-row button.sel { border-color: #fff; }
.wp-marker { width: 30px; height: 30px; border-radius: 50% 50% 50% 0; transform: rotate(-45deg); display: flex; align-items: center; justify-content: center; border: 2px solid #fff; box-shadow: 0 2px 6px rgba(0,0,0,0.5); cursor: pointer; }
.wp-marker span { transform: rotate(45deg); font-size: 13px; }
.wp-list-item { display: flex; align-items: center; gap: 10px; padding: 8px 4px; border-bottom: 1px solid var(--bg-tertiary); cursor: pointer; border-radius: var(--radius-sm); }
.wp-list-item:hover { background: var(--bg-tertiary); }
.wp-list-dot { width: 28px; height: 28px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 0.85rem; flex-shrink: 0; }

/* Trail overlay legend lines (rendered inside the sidebar section) */
.trail-legend-line { display: flex; align-items: center; gap: 10px; padding: 3px 0; font-size: 0.75rem; color: var(--text-secondary); }
.trail-legend-swatch { width: 30px; height: 5px; border-radius: 3px; flex-shrink: 0; }

/* ===== Route Summary Styles ===== */
.route-overview {
  display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 8px;
  margin-bottom: 16px;
}
.route-stat {
  text-align: center;
  padding: 10px;
  background: var(--bg-tertiary);
  border-radius: var(--radius-sm);
}
.route-stat-value { font-size: 1.2rem; font-weight: 700; color: var(--accent); }
.route-stat-label { font-size: 0.68rem; color: var(--text-muted); margin-top: 2px; }

.route-segment {
  padding: 12px 0;
  border-bottom: 1px solid rgba(255,255,255,0.04);
}
.route-segment:last-child { border-bottom: none; }
.route-segment-header {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 6px;
}
.route-segment-header h4 { font-size: 0.85rem; font-weight: 600; }
.route-segment-header span { font-size: 0.75rem; color: var(--text-muted); }
.route-segment-weather {
  display: flex; gap: 12px;
  margin-bottom: 6px;
}
.route-segment-weather .wx-mini {
  display: flex; align-items: center; gap: 4px;
  font-size: 0.78rem; color: var(--text-secondary);
}
.route-segment-services { display: flex; flex-wrap: wrap; gap: 4px; }
.route-segment-services .service-tag {
  font-size: 0.68rem;
  padding: 2px 6px;
  background: var(--bg-tertiary);
  border-radius: 3px;
  color: var(--text-muted);
}
.route-segment-services .service-tag.available { color: var(--accent); background: var(--accent-dim); }

/* ===== Elevation Profile ===== */
.elevation-profile {
  margin-bottom: 14px;
  padding-bottom: 12px;
  border-bottom: 1px solid rgba(255,255,255,0.04);
}
.elevation-stats {
  display: flex; gap: 12px;
  margin-bottom: 8px;
  font-size: 0.75rem;
  color: var(--text-secondary);
}
.elevation-stats span {
  display: flex; align-items: center; gap: 4px;
}
.elevation-chart-wrap {
  position: relative;
  background: var(--bg-tertiary);
  border-radius: var(--radius-sm);
  padding: 4px;
  cursor: crosshair;
}
.elevation-chart-wrap canvas {
  display: block;
  width: 100%;
}
.elevation-tooltip {
  position: absolute;
  background: var(--bg-secondary);
  border: 1px solid var(--bg-tertiary);
  border-radius: var(--radius-sm);
  padding: 4px 8px;
  font-size: 0.72rem;
  color: var(--text-primary);
  pointer-events: none;
  white-space: nowrap;
  z-index: 10;
  box-shadow: var(--shadow);
  line-height: 1.3;
}
.elevation-map-tooltip {
  background: var(--bg-secondary) !important;
  border: 1px solid var(--accent) !important;
  color: var(--text-primary) !important;
  font-size: 0.75rem !important;
  font-weight: 600 !important;
  padding: 2px 6px !important;
  border-radius: 4px !important;
  box-shadow: var(--shadow) !important;
}
.elevation-map-tooltip::before {
  border-top-color: var(--accent) !important;
}

/* ===== Weather Overlay Legend ===== */
.weather-legend-bar {
  display: flex; height: 12px;
  border-radius: 6px; overflow: hidden;
  margin-bottom: 4px;
}
.weather-legend-labels { display: flex; justify-content: space-between; font-size: 0.68rem; color: var(--text-muted); }

/* ===== Leaflet Overrides ===== */
.leaflet-control-zoom { display: none !important; }
.leaflet-control-attribution { font-size: 0.6rem !important; background: rgba(15,25,35,0.8) !important; color: var(--text-muted) !important; }
.leaflet-control-attribution a { color: var(--text-secondary) !important; }
.leaflet-popup-content-wrapper {
  background: var(--bg-secondary) !important;
  color: var(--text-primary) !important;
  border-radius: var(--radius) !important;
  box-shadow: var(--shadow) !important;
  border: 1px solid var(--bg-tertiary) !important;
}
.leaflet-popup-tip { background: var(--bg-secondary) !important; border: 1px solid var(--bg-tertiary) !important; }
.leaflet-popup-close-button { color: var(--text-secondary) !important; font-size: 20px !important; }
/* Cluster icons: sized by count (24/30/36px via iconSize), colored per layer */
.marker-cluster {
  background: rgba(0,200,83,0.18) !important;
  border-radius: 50% !important;
}
.marker-cluster div {
  width: calc(100% - 6px) !important;
  height: calc(100% - 6px) !important;
  margin: 3px !important;
  border-radius: 50% !important;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  line-height: normal !important;
  background: rgba(0,200,83,0.75) !important;
  color: #fff !important;
  font-weight: 600 !important;
  font-family: 'Inter', sans-serif !important;
}
.marker-cluster.cluster-sm div { font-size: 10px !important; }
.marker-cluster.cluster-md div { font-size: 11px !important; }
.marker-cluster.cluster-lg div { font-size: 12px !important; }
/* Per-layer cluster colours matching their marker colours */
.marker-cluster-commercial { background: rgba(33,150,243,0.2) !important; }
.marker-cluster-commercial div { background: rgba(33,150,243,0.8) !important; }
.marker-cluster-freedom { background: rgba(156,39,176,0.2) !important; }
.marker-cluster-freedom div { background: rgba(156,39,176,0.8) !important; }
.marker-cluster-restarea { background: rgba(92,107,192,0.2) !important; }
.marker-cluster-restarea div { background: rgba(92,107,192,0.8) !important; }
.marker-cluster-selfcontained { background: rgba(0,137,123,0.2) !important; }
.marker-cluster-selfcontained div { background: rgba(0,137,123,0.8) !important; }
.marker-cluster-amenity { background: rgba(96,125,139,0.2) !important; }
.marker-cluster-amenity div { background: rgba(96,125,139,0.8) !important; }
.leaflet-routing-container { display: none !important; }

/* ===== MapLibre GL popups + controls — dark theme (GL defaults are white) ===== */
.maplibregl-ctrl-attrib { font-size: 0.6rem !important; background: rgba(15,25,35,0.8) !important; color: var(--text-muted) !important; }
.maplibregl-ctrl-attrib a { color: var(--text-secondary) !important; }
.maplibregl-popup-content {
  background: var(--bg-secondary) !important;
  color: var(--text-primary) !important;
  border-radius: var(--radius) !important;
  box-shadow: var(--shadow) !important;
  border: 1px solid var(--bg-tertiary) !important;
  padding: 12px 14px !important;
  font-family: 'Inter', sans-serif !important;
}
/* The popup tip is a CSS border triangle — theme every anchor direction */
.maplibregl-popup-anchor-bottom .maplibregl-popup-tip { border-top-color: var(--bg-secondary) !important; }
.maplibregl-popup-anchor-top .maplibregl-popup-tip { border-bottom-color: var(--bg-secondary) !important; }
.maplibregl-popup-anchor-left .maplibregl-popup-tip { border-right-color: var(--bg-secondary) !important; }
.maplibregl-popup-anchor-right .maplibregl-popup-tip { border-left-color: var(--bg-secondary) !important; }
.maplibregl-popup-close-button { color: var(--text-secondary) !important; font-size: 20px !important; right: 4px !important; top: 2px !important; }

/* Custom marker styles */
.custom-marker {
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%;
  /* Tight shadow: large blur radii multiply paint cost across hundreds of
     markers when a dense area re-renders after a zoom */
  box-shadow: 0 1px 3px rgba(0,0,0,0.5);
  font-size: 14px;
  transition: transform 0.2s ease;
}
.custom-marker:hover { transform: scale(1.2); }
/* (retired .marker-* divIcon classes removed — markers now draw on canvas via Utils.dotMarker; palette lives in Utils.markerStyles) */

/* ===== Responsive ===== */
@media (max-width: 768px) {
  #mobile-header { display: flex; }
  #sidebar-close { display: block; }

  .sidebar {
    width: 100%;
    transform: translateX(-100%);
    top: 0;
  }
  .sidebar.open { transform: translateX(0); }
  .sidebar-header { padding-top: calc(var(--mobile-header-height) + 8px); }

  #map {
    left: 0;
    top: var(--mobile-header-height);
  }

  #map-controls {
    top: calc(var(--mobile-header-height) + 12px);
    right: 12px;
  }

#info-panel {
    top: auto; bottom: 0; left: 0; right: 0;
    width: 100%; max-width: 100%;
    max-height: 60vh;
    border: none; border-top: 1px solid var(--bg-tertiary);
    border-radius: var(--radius) var(--radius) 0 0;
  }
  #info-panel.hidden { transform: translateY(100%); }
  #sidebar-collapse, #sidebar-expand { display: none !important; }

  .info-details { grid-template-columns: 1fr; }
  .route-overview { grid-template-columns: 1fr 1fr; }

  /* Inputs must be ≥16px to prevent iOS Safari from zooming on focus */
  .route-point input,
  .search-box input,
  .date-field input {
    font-size: 1rem;
  }
}

/* In landscape on mobile: compact the sidebar so content fits above the keyboard */
@media (max-width: 768px) and (orientation: landscape) {
  .sidebar-header { padding-top: calc(var(--mobile-header-height) + 4px); padding-bottom: 6px; }
  .sidebar-section { padding: 10px 16px; }
  .sidebar-section h3 { margin-bottom: 8px; }
  .tab-btn { padding: 8px 4px; }
}

@media (max-width: 480px) {
  .tab-btn { font-size: 0.72rem; padding: 10px 4px; }
  .basemap-selector { flex-direction: column; }
  .weather-grid { grid-template-columns: repeat(3, 1fr); }
}

/* ===== Context Menu ===== */
#context-menu {
  position: fixed;
  background: var(--bg-secondary);
  border: 1px solid var(--bg-tertiary);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  z-index: 2000;
  min-width: 200px;
  padding: 4px 0;
  overflow: hidden;
}
.ctx-item {
  padding: 10px 16px;
  font-size: 0.82rem;
  cursor: pointer;
  display: flex; align-items: center; gap: 10px;
  transition: background 0.15s;
  color: var(--text-primary);
}
.ctx-item:hover { background: rgba(255,255,255,0.06); }
.ctx-item i { color: var(--accent); width: 16px; text-align: center; font-size: 0.85rem; }
.ctx-divider { height: 1px; background: var(--bg-tertiary); margin: 4px 0; }

/* ===== Ride Dashboard ===== */

/* When dashboard is open, hide EVERYTHING else */
body.dashboard-active #map,
body.dashboard-active #sidebar,
body.dashboard-active #mobile-header,
body.dashboard-active #map-controls,
body.dashboard-active #info-panel,
body.dashboard-active #context-menu,
body.dashboard-active .leaflet-control-container {
  display: none !important;
  visibility: hidden !important;
}

body.dashboard-active {
  overflow: hidden;
  background: #0a0e14;
}

#dashboard-overlay {
  position: fixed;
  inset: 0;
  z-index: 99999;
  background: #0a0e14;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  overflow: hidden;
}

.dash-close-btn {
  position: absolute;
  top: 6px;
  right: 6px;
  z-index: 100002;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 1px solid var(--bg-tertiary);
  background: rgba(26,38,50,0.8);
  color: var(--text-primary);
  font-size: 1.1rem;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  touch-action: manipulation;
}
.dash-close-btn:hover { color: var(--danger); }

/* Dashboard layout — landscape-first: top bar, 3-col main, bottom bar */
.dash-layout {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
  overflow: hidden;
  position: relative;
}

/* ── Top instrument bar ── */
.dash-top-bar {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(16px, 4vw, 40px);
  padding: 10px 60px;
  background: rgba(10,14,20,0.9);
  border-bottom: 1px solid var(--bg-tertiary);
  min-width: 0;
  z-index: 2;
  overflow: visible;
}

.dash-alt-reading {
  display: flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
  min-width: 0;
  font-variant-numeric: tabular-nums;
}

.dash-alt-reading i {
  color: var(--accent);
  font-size: 1rem;
}

.dash-alt-value {
  font-size: clamp(1.3rem, 3vw, 1.8rem);
  font-weight: 700;
  color: var(--text-primary);
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.dash-alt-unit {
  font-size: 0.9rem;
  color: var(--text-secondary);
}

.dash-alt-reading #dash-heading-value {
  font-size: clamp(1.2rem, 3vw, 1.7rem);
  font-weight: 600;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}

.dash-info-unit {
  font-size: 0.8rem;
  color: var(--text-secondary);
  margin-left: 2px;
}

/* Pressure trend arrow */
.dash-pressure-arrow {
  transition: transform 0.3s ease;
  align-self: center;
  flex-shrink: 0;
  margin-left: 2px;
}

/* Wind direction arrow */
.dash-wind-arrow {
  transition: transform 0.5s ease-out;
  align-self: center;
  flex-shrink: 0;
  margin-left: 1px;
}

/* ── Main 3-column area ── */
.dash-main {
  flex: 1;
  display: flex;
  min-height: 0;
  overflow: hidden;
}

/* Left column: radar */
.dash-left-col {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 8px;
  gap: 4px;
}

.dash-radar-title {
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: 3px;
  color: var(--text-primary);
}

.dash-radar-wrap {
  position: relative;
  width: min(55vh, 220px);
  aspect-ratio: 1;
  border-radius: 12px;
  overflow: hidden;
  border: 1px solid rgba(255,255,255,0.08);
  background: rgba(20,28,38,0.6);
}

.dash-radar-canvas {
  width: 100%;
  height: 100%;
  border-radius: 12px;
}

.dash-radar-label {
  position: absolute;
  bottom: 4px;
  left: 50%;
  transform: translateX(-50%);
  font-size: 0.55rem;
  color: var(--text-muted);
  background: rgba(10,14,20,0.85);
  padding: 1px 5px;
  border-radius: 3px;
}

/* Centre column: speed + lean */
.dash-centre-col {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 0;
  position: relative;
}

.dash-speed-zone {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
}

.dash-speed-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  z-index: 1;
}

.dash-speed-num {
  font-size: min(28vw, 38vh);
  font-weight: 700;
  color: var(--text-primary);
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.dash-speed-unit {
  font-size: 1rem;
  color: var(--text-secondary);
  text-transform: uppercase;
  letter-spacing: 3px;
  margin-top: -2px;
}

.dash-speed-sub {
  display: flex;
  align-items: baseline;
  gap: 16px;
  margin-top: 4px;
}

.dash-speed-max {
  font-size: 1.2rem;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}

/* Lean angle arcs */
.dash-lean-arcs {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 0;
}

.dash-lean-readout {
  font-size: 1.3rem;
  font-weight: 600;
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
  min-width: 4ch;
}

/* Right column: compass OR nav mode */
.dash-right-col {
  flex: 0 0 auto;
  min-width: 0;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0;
  padding: 8px;
}

/* Nav mode container (minimap + next turn) */
.dash-nav-mode {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 6px;
  width: 100%;
  min-width: 0;
  height: 100%;
  /* Landscape (the usual dash orientation) has little vertical room: the square
     minimap + next-turn + home button can exceed the column height. Scroll
     instead of clipping so the buttons are never stranded off-window;
     overscroll-contain keeps the page behind from moving. */
  overflow-y: auto;
  overflow-x: hidden;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
}

/* Next turn indicator */
.dash-next-turn {
  display: flex;
  align-items: center;
  gap: 10px;
  background: rgba(255, 255, 255, 0.06);
  border-radius: 10px;
  padding: 8px 12px;
  width: 100%;
  max-width: 100%;
  min-width: 0;
  box-sizing: border-box;
  flex-shrink: 0;
  overflow: hidden;
}

.dash-turn-icon {
  flex-shrink: 0;
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  background: rgba(0, 200, 83, 0.15);
  color: #00c853;
  font-size: 1.3rem;
}

.dash-turn-info {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.dash-turn-dist {
  font-size: 1.2rem;
  font-weight: 700;
  color: var(--text-primary, #fff);
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}

.dash-turn-road {
  font-size: 0.68rem;
  color: var(--text-muted, #999);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  line-height: 1.2;
}

/* Minimap */
.dash-minimap-wrap {
  position: relative;
  flex: 0 0 auto;
  width: min(55vh, 220px);
  aspect-ratio: 1 / 1;
  border-radius: 10px;
  overflow: hidden;
  border: 1px solid rgba(255, 255, 255, 0.08);
}

.dash-minimap {
  position: absolute;
  top: -21%;
  left: -21%;
  width: 142%;
  height: 142%;
  background: #0a0e14;
  transition: transform 0.4s ease-out;
  transform-origin: center center;
}

/* Hide Leaflet chrome on minimap */
.dash-minimap .leaflet-control-container { display: none !important; }

/* Home button */
.dash-home-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  width: 100%;
  max-width: min(55vh, 220px);
  padding: 7px 12px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.06);
  color: var(--text-primary, #fff);
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.5px;
  cursor: pointer;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.dash-home-btn:active { background: rgba(255, 255, 255, 0.14); }
.dash-home-btn.home-set { border-color: rgba(0, 200, 83, 0.4); color: #00c853; }

/* Mode toggle button (compass ↔ map) */
.dash-mode-toggle {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 5px;
  padding: 5px 10px;
  border: 1px solid rgba(255,255,255,0.12);
  border-radius: 6px;
  background: rgba(255,255,255,0.06);
  color: var(--text-muted, #999);
  font-size: 0.68rem;
  cursor: pointer;
  transition: background 0.2s, color 0.2s;
}
.dash-mode-toggle:hover, .dash-mode-toggle:active {
  background: rgba(255,255,255,0.12);
  color: var(--text-primary, #fff);
}

/* Rider dot on minimap */
.dash-minimap-rider { background: none !important; border: none !important; }
.dash-rider-dot {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: #00c853;
  border: 2px solid #fff;
  box-shadow: 0 0 8px rgba(0, 200, 83, 0.7);
}

.dash-compass-zone {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  cursor: pointer;
  user-select: none;
}

.dash-compass-arrow-wrap {
  flex-shrink: 0;
  width: min(90px, 24vh);
  height: min(90px, 24vh);
  display: flex;
  align-items: center;
  justify-content: center;
  filter: drop-shadow(0 0 14px rgba(0,200,83,0.5));
}

.dash-compass-arrow {
  width: 100%;
  height: 100%;
  transition: transform 0.5s ease-out;
  transform-origin: 50% 50%;
}

.dash-compass-arrow.no-target {
  opacity: 0.25;
  filter: grayscale(1);
}

.dash-compass-info {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  min-width: 0;
}

.dash-compass-target {
  font-size: 0.75rem;
  color: var(--text-primary);
  font-weight: 600;
  max-width: 160px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  text-align: center;
}

/* Fixed camera warning — same shape as .dash-next-turn so they stack cleanly
   in the dash's right column, but red-edged and one step smaller: it must read
   as SUBORDINATE to the turn instruction directly above it. A "possible"
   camera is amber and visibly softer — it must never read as a confirmed one. */
.dash-camera {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  max-width: 100%;
  min-width: 0;
  box-sizing: border-box;
  flex-shrink: 0;
  overflow: hidden;
  padding: 6px 12px;
  margin-top: 4px;
  background: rgba(255, 82, 82, 0.12);
  border: 1px solid rgba(255, 82, 82, 0.6);
  border-radius: 10px;
}
.dash-camera-icon {
  flex-shrink: 0;
  width: 28px;
  text-align: center;
  font-size: 1.15rem;
  color: #ff5252;
}
.dash-camera-info { min-width: 0; }
.dash-camera-name {
  font-weight: 700;
  font-size: 0.85rem;
  color: #fff;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.dash-camera-detail { font-size: 0.72rem; color: var(--text-muted); }
.dash-camera.cam-possible {
  background: rgba(255, 171, 64, 0.12);
  border-color: rgba(255, 171, 64, 0.6);
}
.dash-camera.cam-possible .dash-camera-icon { color: #ffab40; }

/* Camera popup honesty lines (Layers.showCameraPopup) */
.cam-possible { color: #ffab40; font-size: 0.8em; margin: 4px 0; }
.cam-note { color: var(--text-muted, #999); font-size: 0.72em; margin-top: 6px; line-height: 1.35; }

.dash-recalc-banner {
  font-size: 0.72rem;
  font-weight: 600;
  color: #40c4ff;
  background: rgba(64, 196, 255, 0.1);
  border: 1px solid rgba(64, 196, 255, 0.3);
  border-radius: 10px;
  padding: 3px 9px;
  white-space: nowrap;
  margin-top: 2px;
}

.dash-compass-readout {
  display: flex;
  align-items: baseline;
  gap: 8px;
  flex-wrap: wrap;
  justify-content: center;
}

.dash-compass-num {
  font-size: 1.5rem;
  font-weight: 700;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
}

.dash-compass-brg {
  font-size: 0.65rem;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}

/* ── Bottom bar: elevation + stats ── */
.dash-bottom-bar {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  background: rgba(10,14,20,0.9);
  border-top: 1px solid var(--bg-tertiary);
  min-height: 36px;
  z-index: 2;
}

/* Elevation sparkline strip */
.dash-elevation-strip {
  flex: 0 0 auto;
  width: 40%;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border-right: 1px solid var(--bg-tertiary);
  height: 100%;
}

.dash-elevation-canvas {
  flex: 1;
  height: 32px;
  min-width: 0;
}

.dash-elevation-stats {
  display: flex;
  flex-direction: column;
  gap: 1px;
  font-size: 0.6rem;
  color: var(--text-muted);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.dash-elevation-stats .elev-gain { color: var(--accent); }
.dash-elevation-stats .elev-max { color: var(--text-secondary); }

/* Trip stats strip */
.dash-stats-strip {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-evenly;
  padding: 4px 12px;
  gap: 12px;
}

.dash-stat {
  display: flex;
  align-items: baseline;
  gap: 3px;
  font-variant-numeric: tabular-nums;
}

.dash-stat i {
  color: var(--text-muted);
  font-size: 0.6rem;
  align-self: center;
}

.dash-stat span:not(.dash-stat-unit) {
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--text-secondary);
  min-width: 2.5ch;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.dash-stat-unit {
  font-size: 0.6rem;
  color: var(--text-muted);
}

/* Address input popover */
.dash-compass-input {
  position: fixed;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: min(420px, 90vw);
  background: rgba(10,14,20,0.96);
  border: 1px solid var(--bg-tertiary);
  border-radius: 10px;
  padding: 12px;
  z-index: 100003;
  box-shadow: 0 8px 28px rgba(0,0,0,0.6);
}

/* In landscape the virtual keyboard takes the bottom half — anchor popup to top
   so it stays in the visible area above the keyboard. */
@media (orientation: landscape) {
  .dash-compass-input {
    top: max(env(safe-area-inset-top, 0px), 8px);
    transform: translateX(-50%);
    max-height: calc(100dvh - 24px);
    overflow-y: auto;
  }
}

.dash-compass-input input {
  width: 100%;
  padding: 10px 12px;
  background: var(--bg-secondary);
  color: var(--text-primary);
  border: 1px solid var(--bg-tertiary);
  border-radius: 6px;
  font-size: 1rem; /* must be ≥16px to suppress iOS auto-zoom */
  box-sizing: border-box;
}

.dash-compass-results {
  max-height: 180px;
  overflow-y: auto;
  margin-top: 8px;
}

@media (orientation: landscape) {
  .dash-compass-results {
    max-height: min(120px, 30vh);
  }
}

.dash-compass-results-item {
  padding: 8px 10px;
  color: var(--text-primary);
  font-size: 0.85rem;
  border-radius: 4px;
  cursor: pointer;
}

.dash-compass-results-item:hover,
.dash-compass-results-item:active {
  background: var(--bg-tertiary);
}

.dash-compass-input-row {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 8px;
}

.dash-compass-input-row button {
  padding: 8px 14px;
  background: var(--bg-secondary);
  color: var(--text-primary);
  border: 1px solid var(--bg-tertiary);
  border-radius: 6px;
  font-size: 0.85rem;
  cursor: pointer;
}

.dash-compass-input-row button:hover {
  background: var(--bg-tertiary);
}

/* ── Portrait fallback ── */
@media (orientation: portrait) {
  .dash-top-bar { padding: 6px 50px 6px 16px; gap: 10px; flex-wrap: wrap; }
  .dash-main { flex-direction: column; }
  .dash-left-col { flex: 0 0 auto; order: 3; padding: 4px; }
  .dash-left-col .dash-radar-wrap { width: min(30vw, 140px); }
  .dash-centre-col { flex: 1; }
  .dash-speed-num { font-size: min(42vw, 30vh); }
  .dash-right-col { flex: 0 0 auto; order: 2; padding: 4px; }
  .dash-right-col .dash-compass-zone { flex-direction: row; gap: 16px; }
  .dash-right-col .dash-compass-arrow-wrap { width: min(80px, 14vh); height: min(80px, 14vh); }
  .dash-right-col .dash-compass-info { align-items: flex-start; }
  .dash-nav-mode { flex-direction: row; height: auto; gap: 8px; }
  .dash-minimap-wrap { flex: 0 0 120px; height: 120px; }
  .dash-next-turn { padding: 6px 10px; }
  .dash-turn-icon { width: 32px; height: 32px; font-size: 1rem; }
  .dash-turn-dist { font-size: 1rem; }
  .dash-bottom-bar { flex-direction: column; }
  .dash-elevation-strip { width: 100%; border-right: none; border-bottom: 1px solid var(--bg-tertiary); }
  .dash-stats-strip { width: 100%; }
}

/* Desktop: cap the speed font size */
@media (min-width: 769px) and (orientation: landscape) {
  .dash-speed-num { font-size: min(28vw, 38vh); }
  .dash-right-col { flex: 0 0 auto; }
  .dash-radar-wrap { width: min(60vh, 240px); }
  .dash-compass-arrow-wrap { width: min(110px, 28vh); height: min(110px, 28vh); }
  .dash-minimap-wrap { width: min(60vh, 240px); }
}

/* ===== Hidden utility ===== */
.hidden { display: none !important; }

/* ===== Zoom hint =====
   Australia's default view is the whole continent, where no point data has
   loaded yet (see js/config.js — data is sharded per state and gated on zoom).
   Without this the empty map reads as a bug. */

/* Parks campground clusters. The NZ app registered a marker-cluster-doc class
   but never styled it, so its equivalent layer fell back to Leaflet's default
   blue. Renamed here and given the same treatment as its siblings. */
.marker-cluster-parks {
  background: rgba(0, 200, 83, 0.25);
}
.marker-cluster-parks div {
  background: rgba(0, 200, 83, 0.75);
  color: #00120a;
}

/* ===== 2D | 3D mode switch pill (GL migration) ===== */
#mode-3d-switch {
  position: fixed;
  bottom: 26px;
  left: calc(var(--sidebar-width) + 22px);
  z-index: 500;
  display: flex;
  gap: 4px;
  padding: 4px;
  background: var(--bg-secondary);
  border: 1px solid var(--bg-tertiary);
  border-radius: 999px;
  box-shadow: var(--shadow);
}
.mode-switch-btn {
  min-width: 76px;
  min-height: 46px;
  padding: 0 20px;
  border: none;
  border-radius: 999px;
  background: transparent;
  color: var(--text-secondary);
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: 1.5px;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center; gap: 8px;
  transition: all var(--transition);
}
.mode-switch-btn i { font-size: 0.95rem; }
.mode-switch-btn:hover { color: var(--text-primary); background: rgba(255,255,255,0.08); }
.mode-switch-btn.active { background: var(--accent); color: #fff; }
body.dashboard-active #mode-3d-switch,
body.nav-active #mode-3d-switch { display: none !important; }
@media (max-width: 768px) {
  #mode-3d-switch { left: 12px; bottom: 84px; }
}

/* Basemap switch (Topo | Sat) — pill stacked above the 2D/3D toggle. */
#basemap-switch {
  position: fixed;
  bottom: 88px;
  left: calc(var(--sidebar-width) + 22px);
  z-index: 500;
  display: flex;
  gap: 4px;
  padding: 4px;
  background: var(--bg-secondary);
  border: 1px solid var(--bg-tertiary);
  border-radius: 999px;
  box-shadow: var(--shadow);
}
body.dashboard-active #basemap-switch,
body.nav-active #basemap-switch { display: none !important; }
@media (max-width: 768px) {
  #basemap-switch { left: 12px; bottom: 146px; }
}

/* Voice picker row (Voice Guidance sidebar section) */
.voice-pick-row { display: flex; align-items: center; gap: 8px; margin: 8px 0 4px; }
.voice-pick-row .toggle-label { flex-shrink: 0; }
.voice-pick-row select {
  flex: 1; min-width: 0; padding: 5px 7px; font-size: 0.78rem;
  background: var(--bg-elevated, #1c1c22); color: var(--text-primary, #fff);
  border: 1px solid rgba(255,255,255,0.14); border-radius: var(--radius, 8px);
}
.voice-pick-row .btn-sm { padding: 5px 10px; font-size: 0.75rem; flex-shrink: 0; }
/* Name tag above the active (panel-open) site — pairs with Layers._highlightActive */
.active-site-tag {
  background: rgba(13, 21, 32, 0.95);
  border: 1px solid rgba(0, 200, 83, 0.6);
  color: #fff;
  font-weight: 600;
  font-size: 0.75rem;
  border-radius: 6px;
  padding: 3px 9px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.5);
  white-space: nowrap;
  max-width: 240px;
  overflow: hidden;
  text-overflow: ellipsis;
}
.active-site-tag::before { border-top-color: rgba(0, 200, 83, 0.6); }

/* ===== Full-screen Navigation Overlay (map + rain radar + speed) ===== */
/* Like the speedo dash, hide everything else behind it. */
body.nav-active #map,
body.nav-active #sidebar,
body.nav-active #mobile-header,
body.nav-active #map-controls,
body.nav-active #info-panel,
body.nav-active #context-menu,
body.nav-active .leaflet-control-container {
  display: none !important;
  visibility: hidden !important;
}
body.nav-active { overflow: hidden; background: #0a0e14; }

#nav-overlay {
  position: fixed;
  inset: 0;
  z-index: 99999;
  background: #0a0e14;
  overflow: hidden;
}

/* Clip the oversized, rotating map. */
#nav-map-wrap {
  position: absolute;
  inset: 0;
  overflow: hidden;
}
/* A square whose side (145vmax) exceeds any viewport's diagonal (≤ ~1.415·vmax),
   centred with negative margins so the `transform` property is free for the
   heading-up rotation JS applies. Being ≥ the diagonal, no corner gap ever
   shows however far it spins. */
#nav-map {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 145vmax;
  height: 145vmax;
  margin-left: -72.5vmax;
  margin-top: -72.5vmax;
  transform-origin: center center;
  /* No CSS transition: nav.js eases the rotation itself, frame by frame (see
     startHeadingLoop). A transition on top would restart every frame and lag. */
  background: #0a0e14;
  will-change: transform;
}
#nav-map .leaflet-control-container { display: none !important; }

/* Rider chevron — always points up (direction of travel) via JS counter-rotation. */
.nav-rider { background: none !important; border: none !important; }
.nav-rider-chevron {
  width: 34px; height: 34px;
  display: flex; align-items: center; justify-content: center;
  /* eased in JS per frame (see startHeadingLoop) — no CSS transition */
}
.nav-rider-chevron i {
  font-size: 26px;
  color: #2196f3;
  /* fa-location-arrow's art points NE (45°); correct it to point straight up. */
  transform: rotate(-45deg);
  text-shadow: 0 0 6px rgba(0,0,0,0.8), 0 0 2px #fff;
}

/* Current speed + speed-limit sign — bottom-left corner. */
#nav-speed {
  position: absolute;
  left: calc(14px + env(safe-area-inset-left, 0px));
  bottom: calc(18px + env(safe-area-inset-bottom, 0px));
  z-index: 10;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 14px;
  background: rgba(10,14,20,0.72);
  border: 1px solid rgba(255,255,255,0.1);
  border-radius: 14px;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.nav-speed-read { display: flex; align-items: baseline; gap: 4px; }
#nav-speed-value {
  font-size: 4.2rem;
  font-weight: 800;
  line-height: 1;
  color: #fff;
  font-variant-numeric: tabular-nums;
  letter-spacing: -1.5px;
}
#nav-speed-unit { font-size: 0.9rem; font-weight: 600; color: var(--text-secondary); text-transform: uppercase; }

/* Speed-limit sign — a circular white disc with a red ring (NZ/EU style). */
#nav-speed-limit {
  flex: 0 0 auto;
  display: flex; align-items: center; justify-content: center;
  width: 54px; height: 54px;
  border-radius: 50%;
  background: #fff;
  border: 5px solid #d32f2f;
  box-shadow: 0 1px 5px rgba(0,0,0,0.55);
}
#nav-speed-limit-value {
  color: #111;
  font-weight: 800;
  font-size: 1.3rem;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.5px;
}

/* Next-turn banner — top. */
#nav-turn {
  position: absolute;
  top: calc(12px + env(safe-area-inset-top, 0px));
  left: 50%;
  transform: translateX(-50%);
  z-index: 10;
  display: flex;
  align-items: center;
  gap: 12px;
  max-width: min(88vw, 460px);
  padding: 10px 16px 10px 10px;
  background: rgba(10,14,20,0.82);
  border: 1px solid rgba(255,255,255,0.1);
  border-radius: 16px;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  box-shadow: 0 6px 24px rgba(0,0,0,0.4);
}
.nav-turn-icon {
  flex: 0 0 auto;
  width: 46px; height: 46px;
  border-radius: 12px;
  display: flex; align-items: center; justify-content: center;
  font-size: 1.5rem;
}
.nav-turn-icon.prox-far  { background: rgba(0,200,83,0.15);  color: #00c853; }
.nav-turn-icon.prox-mid  { background: rgba(255,193,7,0.2);  color: #ffc107; }
.nav-turn-icon.prox-near { background: rgba(255,82,82,0.22); color: #ff5252; }
.nav-turn-info { min-width: 0; }
#nav-turn-dist { font-size: 1.5rem; font-weight: 800; color: #fff; line-height: 1.05; }
#nav-turn-road {
  font-size: 0.9rem; color: var(--text-secondary);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* Distance / ETA remaining — top-right. */
#nav-eta {
  position: absolute;
  top: calc(12px + env(safe-area-inset-top, 0px));
  right: calc(14px + env(safe-area-inset-right, 0px));
  z-index: 10;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 1px;
  padding: 7px 12px;
  background: rgba(10,14,20,0.72);
  border: 1px solid rgba(255,255,255,0.1);
  border-radius: 12px;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
#nav-eta-dist { font-size: 1.15rem; font-weight: 800; color: #fff; line-height: 1.1; }
#nav-eta-time { font-size: 0.8rem; font-weight: 600; color: var(--accent); }

/* Current time — the fullscreen display hides the OS status bar clock (2026-07-28). */
#nav-clock {
  position: absolute;
  top: calc(12px + env(safe-area-inset-top, 0px));
  right: calc(14px + env(safe-area-inset-right, 0px));
  z-index: 10;
  padding: 7px 12px;
  background: rgba(10,14,20,0.72);
  border: 1px solid rgba(255,255,255,0.1);
  border-radius: 12px;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  color: #fff;
  font-size: 0.95rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
/* Route active -> the ETA chip owns the corner; the clock tucks below it. */
#nav-eta:not(.hidden) ~ #nav-clock {
  top: calc(80px + env(safe-area-inset-top, 0px));
}

/* GPS elevation — bottom-right corner. */
#nav-elev {
  position: absolute;
  right: calc(14px + env(safe-area-inset-right, 0px));
  bottom: calc(18px + env(safe-area-inset-bottom, 0px));
  z-index: 10;
  display: flex;
  align-items: baseline;
  gap: 5px;
  padding: 7px 12px;
  background: rgba(10,14,20,0.72);
  border: 1px solid rgba(255,255,255,0.1);
  border-radius: 12px;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  color: #fff;
}
#nav-elev i { font-size: 0.85rem; color: var(--text-secondary); align-self: center; }
#nav-elev-value { font-size: 1.3rem; font-weight: 800; font-variant-numeric: tabular-nums; }
.nav-elev-unit { font-size: 0.8rem; font-weight: 600; color: var(--text-secondary); }

/* Close — top-left. */
#nav-close {
  position: absolute;
  top: calc(12px + env(safe-area-inset-top, 0px));
  left: calc(12px + env(safe-area-inset-left, 0px));
  z-index: 11;
  width: 42px; height: 42px;
  border-radius: 50%;
  border: 1px solid rgba(255,255,255,0.12);
  background: rgba(10,14,20,0.72);
  color: #fff;
  font-size: 1.1rem;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  touch-action: manipulation;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
#nav-close:hover { color: var(--danger); }

/* Small screens — trim the outsized readouts so nothing collides. */
@media (max-width: 480px) {
  #nav-speed-value { font-size: 3.4rem; }
  #nav-speed-limit { width: 48px; height: 48px; border-width: 4px; }
  #nav-speed-limit-value { font-size: 1.15rem; }
  #nav-turn { top: calc(66px + env(safe-area-inset-top, 0px)); }
}

/* Active-site ring (GL era — was an L.circleMarker before the migration) */
.active-site-ring {
  width: 32px; height: 32px; border-radius: 50%;
  border: 3px solid #00c853; opacity: 0.95;
  pointer-events: none; position: relative;
}
.active-site-ring .active-site-tag {
  position: absolute; left: 50%; bottom: 38px; transform: translateX(-50%);
  white-space: nowrap;
}

/* #nav-camera and friends — ported from NZ with the GL nav */
/* ===== CSS Variables ===== */
:root {
  --bg-primary: #0f1923;
  --bg-secondary: #1a2632;
  --bg-tertiary: #243342;
  --bg-card: #1e2d3d;
  --text-primary: #e8edf2;
  --text-secondary: #8899aa;
  --text-muted: #5a6f82;
  --accent: #00c853;
  --accent-hover: #00e676;
  --accent-dim: rgba(0, 200, 83, 0.15);
  --danger: #ff5252;
  --warning: #ffab40;
  --info: #40c4ff;
  --spark-color: #ffe600;
  --vodafone-color: #e60000;
  --twodeg-color: #00aaff;
  --sidebar-width: 380px;
  --mobile-header-height: calc(56px + env(safe-area-inset-top, 0px)); /* fullscreen display: bar background reaches the true screen top; content pads below the camera cutout */
  --radius: 8px;
  --radius-sm: 4px;
  --shadow: 0 4px 24px rgba(0,0,0,0.4);
  --transition: 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}

/* ===== Reset ===== */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html, body { height: 100%; overflow: hidden; }
body {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  background: var(--bg-primary);
  color: var(--text-primary);
  -webkit-font-smoothing: antialiased;
}

/* ===== Login Screen ===== */
#login-screen {
  position: fixed; inset: 0;
  background: var(--bg-primary);
  display: flex; align-items: center; justify-content: center;
  z-index: 10001;
  transition: opacity 0.4s ease;
}
#login-screen.fade-out { opacity: 0; pointer-events: none; }
.login-card {
  display: flex; flex-direction: column; align-items: center;
  padding: 32px 28px;
  background: var(--bg-secondary);
  border-radius: 16px;
  border: 1px solid var(--border, rgba(255,255,255,0.06));
  width: min(360px, 90vw);
}
.login-input {
  width: 100%; padding: 10px 12px;
  border-radius: var(--radius-sm, 6px);
  border: 1px solid var(--border, rgba(255,255,255,0.1));
  background: var(--bg-tertiary); color: var(--text-primary);
  font-size: 0.88rem; font-family: inherit;
  margin-bottom: 8px; outline: none;
}
.login-input:focus { border-color: var(--accent); }
.login-error {
  font-size: 0.75rem; color: #ff5252;
  margin-bottom: 8px; display: none;
  text-align: center;
}
.login-btn {
  width: 100%; padding: 10px; font-size: 0.88rem;
  border-radius: var(--radius-sm, 6px);
  cursor: pointer; margin-bottom: 6px;
}
.login-google-btn {
  background: var(--bg-tertiary); color: var(--text-secondary);
  border: 1px solid var(--border, rgba(255,255,255,0.1));
}
.login-google-btn:hover { background: var(--bg-card); }

/* ===== Loading Screen ===== */
#loading-screen {
  position: fixed; inset: 0;
  background: var(--bg-primary);
  display: flex; align-items: center; justify-content: center;
  z-index: 10000;
  transition: opacity 0.5s ease;
}
#loading-screen.fade-out { opacity: 0; pointer-events: none; }
.loader-content { text-align: center; }
.loader-icon { font-size: 3rem; color: var(--accent); margin-bottom: 1rem; animation: pulse 1.5s infinite; }
.loader-content h2 { font-size: 1.5rem; font-weight: 700; margin-bottom: 0.5rem; }
.loader-content p { color: var(--text-secondary); margin-bottom: 1.5rem; }
.loader-bar { width: 200px; height: 3px; background: var(--bg-tertiary); border-radius: 3px; overflow: hidden; margin: 0 auto; }
.loader-progress { height: 100%; width: 30%; background: var(--accent); border-radius: 3px; animation: loading 1.5s ease-in-out infinite; }
@keyframes loading { 0% { transform: translateX(-100%); } 100% { transform: translateX(400%); } }
@keyframes pulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.1); } }

/* ===== Mobile Header ===== */
#mobile-header {
  display: none;
  position: fixed; top: 0; left: 0; right: 0;
  height: var(--mobile-header-height);
  background: var(--bg-secondary);
  border-bottom: 1px solid var(--bg-tertiary);
  align-items: center;
  justify-content: space-between;
  padding: env(safe-area-inset-top, 0px) 12px 0;
  z-index: 1001;
}
#mobile-header h1 { font-size: 1.1rem; font-weight: 700; }
#mobile-header button {
  background: none; border: none; color: var(--text-primary);
  font-size: 1.2rem; padding: 8px; cursor: pointer;
}

/* ===== Sidebar ===== */
.sidebar {
  position: fixed; top: 0; left: 0; bottom: 0;
  width: var(--sidebar-width);
  background: var(--bg-secondary);
  border-right: 1px solid var(--bg-tertiary);
  display: flex; flex-direction: column;
  z-index: 1000;
  transition: transform var(--transition);
  overflow: hidden;
}
.sidebar.collapsed { transform: translateX(-100%); }

/* Desktop sidebar collapse (onX-style). One body-level var override moves every
   --sidebar-width dependent (#map, #info-panel, #weather-timeline, 3D/basemap
   switches) at once. Desktop-only: mobile keeps the .open overlay pattern. */
@media (min-width: 769px) {
  body.sidebar-collapsed { --sidebar-width: 0px; }
  body.sidebar-collapsed .sidebar { transform: translateX(-100%); }
  /* Collapsed sidebar puts #info-panel at left:12px — the same corner the
     fixed #sidebar-expand (») button occupies — covering the site name.
     Shift the pane right to clear the 38px button + gaps. */
  body.sidebar-collapsed #info-panel { left: 62px; }
}
#sidebar-collapse {
  background: none; border: none; color: var(--text-secondary);
  font-size: 1rem; cursor: pointer; padding: 4px 8px;
}
#sidebar-collapse:hover { color: var(--text-primary); }
#sidebar-expand {
  position: fixed; top: 12px; left: 12px; z-index: 1001;
  width: 38px; height: 38px; border-radius: var(--radius-sm);
  background: var(--bg-secondary); border: 1px solid var(--bg-tertiary);
  color: var(--text-primary); font-size: 1rem; cursor: pointer;
  display: none; align-items: center; justify-content: center;
  box-shadow: 0 2px 10px rgba(0,0,0,0.4);
}
body.sidebar-collapsed #sidebar-expand { display: flex; }

.sidebar-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px 20px;
  border-bottom: 1px solid var(--bg-tertiary);
  flex-shrink: 0;
}
.brand { display: flex; align-items: center; gap: 10px; }
.brand i { font-size: 1.5rem; color: var(--accent); }
.brand h1 { font-size: 1.25rem; font-weight: 700; }
#sidebar-close {
  background: none; border: none; color: var(--text-secondary);
  font-size: 1.2rem; cursor: pointer; padding: 4px;
  display: none;
}

.sidebar-body {
  flex: 1; overflow-y: auto; overflow-x: hidden;
  padding: 0;
  scrollbar-width: thin;
  scrollbar-color: var(--bg-tertiary) transparent;
}
.sidebar-body::-webkit-scrollbar { width: 6px; }
.sidebar-body::-webkit-scrollbar-track { background: transparent; }
.sidebar-body::-webkit-scrollbar-thumb { background: var(--bg-tertiary); border-radius: 3px; }

.sidebar-footer {
  padding: 12px 20px;
  border-top: 1px solid var(--bg-tertiary);
  flex-shrink: 0;
}
.sidebar-footer p { font-size: 0.7rem; color: var(--text-muted); line-height: 1.5; }

/* ===== Tab Navigation ===== */
.tab-nav {
  display: flex;
  border-bottom: 1px solid var(--bg-tertiary);
  flex-shrink: 0;
}
.tab-btn {
  flex: 1;
  padding: 12px 8px;
  background: none; border: none;
  color: var(--text-secondary);
  font-size: 0.8rem; font-weight: 500;
  cursor: pointer;
  border-bottom: 2px solid transparent;
  transition: all var(--transition);
  display: flex; align-items: center; justify-content: center; gap: 6px;
}
.tab-btn:hover { color: var(--text-primary); background: var(--bg-tertiary); }
.tab-btn.active { color: var(--accent); border-bottom-color: var(--accent); }
.tab-btn i { font-size: 0.9rem; }

.tab-content { display: none; }
.tab-content.active { display: block; }

/* ===== Sidebar Sections ===== */
.sidebar-section {
  padding: 16px 20px;
  border-bottom: 1px solid rgba(255,255,255,0.04);
}
.sidebar-section h3 {
  font-size: 0.8rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--text-secondary);
  margin-bottom: 12px;
  display: flex; align-items: center; gap: 8px;
}
.sidebar-section h3 i { color: var(--accent); font-size: 0.85rem; }
.sidebar-section h4 {
  font-size: 0.78rem; font-weight: 600;
  color: var(--text-secondary);
  margin: 12px 0 8px;
}
.hint { font-size: 0.78rem; color: var(--text-muted); margin-bottom: 12px; line-height: 1.4; }

/* ===== Search ===== */
.search-box {
  display: flex; align-items: center;
  background: var(--bg-tertiary);
  border-radius: var(--radius);
  padding: 0 12px;
  border: 1px solid transparent;
  transition: border-color var(--transition);
}
.search-box:focus-within { border-color: var(--accent); }
.search-box i { color: var(--text-muted); font-size: 0.85rem; }
.search-box input {
  flex: 1; background: none; border: none; outline: none;
  color: var(--text-primary); padding: 10px 10px;
  font-size: 0.85rem; font-family: inherit;
}
.search-box input::placeholder { color: var(--text-muted); }
.search-box button { background: none; border: none; color: var(--text-muted); cursor: pointer; padding: 4px; }
.search-results {
  margin-top: 8px;
  background: var(--bg-tertiary);
  border-radius: var(--radius);
  max-height: 240px;
  overflow-y: auto;
}
.search-results.hidden { display: none; }
.search-result-item {
  padding: 10px 14px;
  cursor: pointer;
  font-size: 0.82rem;
  border-bottom: 1px solid rgba(255,255,255,0.04);
  transition: background var(--transition);
  display: flex; align-items: center; gap: 8px;
}
.search-result-item:hover { background: rgba(255,255,255,0.05); }
.search-result-item i { color: var(--accent); width: 16px; text-align: center; }
.search-result-item:last-child { border-bottom: none; }

/* ===== Layer Toggles ===== */
.layer-toggle {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 0;
  cursor: pointer;
  font-size: 0.85rem;
}
.layer-toggle input { display: none; }
.toggle-slider {
  width: 36px; height: 20px;
  background: var(--bg-tertiary);
  border-radius: 10px;
  position: relative;
  transition: background var(--transition);
  flex-shrink: 0;
}
.toggle-slider::after {
  content: '';
  position: absolute;
  width: 16px; height: 16px;
  background: var(--text-secondary);
  border-radius: 50%;
  top: 2px; left: 2px;
  transition: all var(--transition);
}
.layer-toggle input:checked + .toggle-slider { background: var(--accent-dim); }
.layer-toggle input:checked + .toggle-slider::after { transform: translateX(16px); background: var(--accent); }
.toggle-label { flex: 1; }

/* ===== Route vehicle picker (js/vehicle.js) ===== */
/* Ported from Motocamp USA, minus the towing row — NZ ships no towing modifier
   (it would change nothing about the route here; see js/vehicle.js). */
.route-vehicle {
  padding-bottom: 10px;
  margin-bottom: 4px;
  border-bottom: 1px solid var(--bg-tertiary);
}
.route-vehicle-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 6px; margin-bottom: 7px;
}
.route-vehicle-title {
  font-size: 0.72rem; font-weight: 600;
  color: var(--text-secondary);
  text-transform: uppercase; letter-spacing: 0.04em;
}
.route-vehicle-reset {
  background: none; border: none; padding: 0;
  color: var(--text-muted, #888);
  font-size: 0.66rem; cursor: pointer; text-decoration: underline;
}
.route-vehicle-reset:hover { color: var(--accent); }
.route-vehicle-reset[hidden] { display: none; }
.route-vehicle-picker {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 5px;
}
.route-vehicle-btn {
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  padding: 7px 3px;
  border: 1px solid var(--bg-tertiary);
  border-radius: 6px;
  background: transparent;
  color: var(--text-secondary);
  font-size: 0.62rem;
  cursor: pointer;
  transition: all var(--transition);
  min-width: 0;
}
.route-vehicle-btn i { font-size: 0.92rem; }
.route-vehicle-btn span { overflow-wrap: anywhere; text-align: center; line-height: 1.2; }
.route-vehicle-btn:hover { border-color: var(--text-muted, #888); color: var(--text-primary); }
.route-vehicle-btn[aria-pressed="true"] {
  border-color: var(--accent);
  background: var(--accent-dim);
  color: var(--text-primary);
}
.route-vehicle-btn[aria-pressed="true"] i { color: var(--accent); }
.route-vehicle-note {
  font-size: 0.66rem;
  color: var(--text-muted, #888);
  margin-top: 7px;
  line-height: 1.45;
}
.route-vehicle-note:empty { display: none; }
.route-vehicle-note .warn { color: #ffab40; }

.badge {
  font-size: 0.65rem; font-weight: 600;
  padding: 2px 6px; border-radius: 3px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}
.badge-green { background: rgba(0,200,83,0.15); color: #00c853; }
.badge-blue { background: rgba(64,196,255,0.15); color: #40c4ff; }
.badge-orange { background: rgba(255,171,64,0.15); color: #ffab40; }
.badge-purple { background: rgba(176,128,255,0.15); color: #b080ff; }
.badge-teal { background: rgba(38,198,178,0.15); color: #26c6b2; }
.badge-yellow { background: rgba(255,230,0,0.15); color: #ffe600; }
.badge-red { background: rgba(230,0,0,0.15); color: #ff5252; }

/* ===== Base Map Selector ===== */
/* Warm up CARTO Voyager's pale palette so the base map reads richer, not washed out */
.basemap-selector { display: flex; gap: 6px; }
.basemap-btn {
  flex: 1; padding: 8px;
  background: var(--bg-tertiary);
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  color: var(--text-secondary);
  font-size: 0.75rem; font-weight: 500;
  cursor: pointer;
  transition: all var(--transition);
  display: flex; flex-direction: column; align-items: center; gap: 4px;
}
.basemap-btn i { font-size: 1rem; }
.basemap-btn:hover { color: var(--text-primary); background: rgba(255,255,255,0.08); }
.basemap-btn.active { border-color: var(--accent); color: var(--accent); background: var(--accent-dim); }

/* ===== Filter Chips ===== */
.filter-group { display: flex; flex-wrap: wrap; gap: 6px; }
.filter-chip {
  display: flex; align-items: center; gap: 4px;
  padding: 6px 10px;
  background: var(--bg-tertiary);
  border-radius: 20px;
  font-size: 0.75rem;
  cursor: pointer;
  transition: all var(--transition);
  border: 1px solid transparent;
  user-select: none;
}
.filter-chip:hover { background: rgba(255,255,255,0.08); }
.filter-chip input { display: none; }
.filter-chip:has(input:checked) { border-color: var(--accent); background: var(--accent-dim); color: var(--accent); }
.filter-chip i { font-size: 0.7rem; }

/* ===== Route Planning ===== */
.route-inputs { display: flex; flex-direction: column; gap: 4px; }
.route-point {
  display: flex; align-items: center; gap: 10px;
  background: var(--bg-tertiary);
  border-radius: var(--radius-sm);
  padding: 0 12px;
}
.route-point input {
  flex: 1; background: none; border: none; outline: none;
  color: var(--text-primary); padding: 10px 0;
  font-size: 0.85rem; font-family: inherit;
}
.route-point input::placeholder { color: var(--text-muted); }
/* Route search results dropdown */
.route-search-results {
  position: absolute;
  left: 0; right: 0;
  z-index: 9999;
  margin-top: 2px;
  max-height: 200px;
  overflow-y: auto;
  box-shadow: 0 6px 20px rgba(0,0,0,0.4);
  border: 1px solid rgba(255,255,255,0.08);
}
/* Suggestions are positioned in JS (see _positionResults in js/route.js):
   fixed to the viewport but anchored to the input's real position, flipping
   above it when the phone keyboard leaves no room below. The old mobile rule
   pinned them to top:52px of the SCREEN — detached from the box being typed
   in, floating over the header ("the destination box broke out"). */
.route-search-results {
  position: fixed;
  z-index: 10000;
}
.route-start-icon { color: var(--accent); font-size: 0.6rem; }
.route-locate-btn {
  flex-shrink: 0;
  padding: 6px 8px;
  border: none;
  color: var(--accent);
  background: none;
  font-size: 1rem;
  cursor: pointer;
  opacity: 0.7;
  transition: opacity 0.2s;
}
.route-locate-btn:hover { opacity: 1; }
.route-locate-btn.locating { animation: pulse-locate 1s infinite; }
@keyframes pulse-locate { 0%, 100% { opacity: 0.4; } 50% { opacity: 1; } }
.route-end-icon { color: var(--danger); font-size: 0.85rem; }
.route-waypoint-icon { color: var(--info); font-size: 0.6rem; }

.route-actions { display: flex; gap: 8px; margin-top: 8px; }
.route-dates { margin-top: 4px; }
.date-inputs { display: flex; gap: 8px; }
.date-field { flex: 1; }
.date-field label { display: block; font-size: 0.72rem; color: var(--text-muted); margin-bottom: 4px; }
.date-field input {
  width: 100%; padding: 8px 10px;
  background: var(--bg-tertiary);
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  color: var(--text-primary);
  font-size: 0.82rem; font-family: inherit;
  outline: none;
}
.date-field input:focus { border-color: var(--accent); }

/* ===== Buttons ===== */
.btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 14px;
  background: var(--bg-tertiary);
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: var(--radius-sm);
  color: var(--text-secondary);
  font-size: 0.8rem; font-weight: 500;
  cursor: pointer;
  transition: all var(--transition);
  font-family: inherit;
}
.btn:hover { background: rgba(255,255,255,0.08); color: var(--text-primary); }
.btn-sm { padding: 6px 10px; font-size: 0.75rem; }
.btn-primary { background: var(--accent); color: #000; border-color: var(--accent); font-weight: 600; }
.btn-primary:hover { background: var(--accent-hover); color: #000; }
.btn-danger { border-color: rgba(255,82,82,0.3); color: var(--danger); }
.btn-danger:hover { background: rgba(255,82,82,0.1); }
.btn-block { width: 100%; justify-content: center; margin-top: 12px; }

/* ===== Weather Controls ===== */
.time-slider-container { padding: 4px 0; }
.time-slider-container input[type="range"] {
  width: 100%; -webkit-appearance: none; appearance: none;
  height: 4px; background: var(--bg-tertiary);
  border-radius: 2px; outline: none;
}
.time-slider-container input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 16px; height: 16px;
  background: var(--accent); border-radius: 50%;
  cursor: pointer;
}
.time-labels { display: flex; justify-content: space-between; margin-top: 4px; font-size: 0.7rem; color: var(--text-muted); }

/* ===== Map ===== */
#map {
  position: fixed;
  top: 0; bottom: 0;
  left: var(--sidebar-width);
  right: 0;
  z-index: 1;
}

/* ===== Map Controls ===== */
#map-controls {
  position: fixed;
  top: 16px; right: 16px;
  display: flex; flex-direction: column; gap: 8px;
  z-index: 500;
}
.map-btn {
  width: auto; height: auto;
  padding: 8px 10px;
  background: var(--bg-secondary);
  border: 1px solid var(--bg-tertiary);
  border-radius: var(--radius);
  color: var(--text-primary);
  font-size: 1rem;
  cursor: pointer;
  display: flex; align-items: center; gap: 6px;
  transition: all var(--transition);
  box-shadow: var(--shadow);
}
.map-btn-label {
  font-size: 0.65rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--text-secondary);
}
.map-btn:hover { background: var(--bg-tertiary); color: var(--accent); }
.map-btn:hover .map-btn-label { color: var(--accent); }
.map-btn.active { background: var(--accent); color: #fff; border-color: var(--accent); }
.map-btn.active .map-btn-label { color: #fff; }

/* ===== Weather Tile Overlays ===== */
.weather-tile-temperature { filter: saturate(2.5) contrast(1.8) brightness(1.1); }
.weather-tile-precipitation { filter: saturate(2.0) contrast(1.5); }
.weather-tile-clouds { filter: contrast(1.4) brightness(0.95); }
.weather-tile-wind { filter: saturate(1.8) contrast(1.4); }

/* ===== Weather Timeline ===== */
/* ===== Info Panel =====
   Vertical side-loading pane (onX-style), 2026-07-27. Was a bottom-anchored
   horizontal strip eating 50vh; now a left card over the map. Mobile keeps the
   bottom-sheet geometry (overridden in the 768px block below). */
#info-panel {
  position: fixed;
  top: 12px; bottom: 12px;
  left: calc(var(--sidebar-width) + 12px);
  width: 380px;
  max-width: calc(100vw - var(--sidebar-width) - 24px);
  background: var(--bg-secondary);
  border: 1px solid var(--bg-tertiary);
  border-radius: var(--radius);
  z-index: 600;
  overflow-y: auto;
  box-shadow: 0 8px 30px rgba(0,0,0,0.45);
  transition: transform var(--transition), opacity var(--transition);
}
#info-panel.hidden {
  transform: translateX(calc(-100% - 420px));
  opacity: 0;
  pointer-events: none;
}
#info-close {
  position: sticky; top: 0; right: 0;
  float: right; margin: 12px 12px 0 0;
  background: var(--bg-tertiary); border: none;
  z-index: 10;
  color: var(--text-secondary); width: 32px; height: 32px;
  border-radius: 50%; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  font-size: 0.9rem;
}
#info-content { padding: 20px 24px 24px; }

/* Info Panel Content */
.info-header { margin-bottom: 16px; }
.info-header h2 { font-size: 1.15rem; font-weight: 700; margin-bottom: 4px; }
.info-header .info-type { font-size: 0.78rem; color: var(--accent); font-weight: 500; text-transform: uppercase; letter-spacing: 0.03em; }
.info-header .info-status { font-size: 0.75rem; padding: 2px 8px; border-radius: 3px; margin-left: 8px; }
.info-header .info-status.open { background: rgba(0,200,83,0.15); color: #00c853; }
.info-header .info-status.closed { background: rgba(255,82,82,0.15); color: #ff5252; }

.info-facilities {
  display: flex; flex-wrap: wrap; gap: 8px;
  margin-bottom: 16px;
}
.facility-badge {
  display: flex; align-items: center; gap: 5px;
  padding: 6px 10px;
  background: var(--bg-tertiary);
  border-radius: var(--radius-sm);
  font-size: 0.75rem;
  color: var(--text-secondary);
}
.facility-badge.available { color: var(--accent); background: var(--accent-dim); }
.facility-badge i { font-size: 0.8rem; }

.info-details { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 16px; }
.info-detail { }
.info-detail-label { font-size: 0.7rem; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.03em; margin-bottom: 2px; }
.info-detail-value { font-size: 0.85rem; color: var(--text-primary); }

.info-weather {
  background: var(--bg-tertiary);
  border-radius: var(--radius);
  padding: 14px;
  margin-bottom: 16px;
}
.info-weather h4 { font-size: 0.78rem; color: var(--text-secondary); margin-bottom: 8px; }
.weather-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(80px, 1fr)); gap: 8px;
}
.weather-item { text-align: center; }
.weather-item .wx-icon { font-size: 1.3rem; margin-bottom: 2px; }
.weather-item .wx-temp { font-size: 1rem; font-weight: 600; }
.weather-item .wx-desc { font-size: 0.68rem; color: var(--text-muted); }
.weather-item .wx-day { font-size: 0.68rem; color: var(--text-secondary); font-weight: 500; }

.info-cell-coverage { margin-bottom: 16px; }
.cell-bar-container { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
.cell-carrier { font-size: 0.78rem; width: 70px; color: var(--text-secondary); }
.cell-bar { flex: 1; height: 6px; background: var(--bg-tertiary); border-radius: 3px; overflow: hidden; }
.cell-bar-fill { height: 100%; border-radius: 3px; transition: width 0.5s ease; }
.cell-bar-fill.spark { background: var(--spark-color); }
.cell-bar-fill.vodafone { background: var(--vodafone-color); }
.cell-bar-fill.twodeg { background: var(--twodeg-color); }
.cell-tech { font-size: 0.68rem; color: var(--text-muted); width: 30px; }

.info-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.info-actions .btn i { font-size: 0.8rem; }

/* ===== Pane card components (onX card anatomy, shared by trail/land/hazard/
   waypoint cards and reusable by any info-panel content) ===== */
.pane-tiles { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-bottom: 14px; }
.pane-tile { background: var(--bg-tertiary); border-radius: var(--radius-sm); padding: 8px 10px; }
.pane-tile.wide { grid-column: 1 / -1; }
.pane-tile .pt-label { font-size: 0.68rem; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.03em; }
.pane-tile .pt-value { font-size: 0.95rem; font-weight: 700; margin-top: 2px; }
.pane-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px; }
.pane-chip { border: 1px solid var(--bg-tertiary); background: var(--bg-tertiary); border-radius: 999px; padding: 3px 10px; font-size: 0.72rem; color: var(--text-secondary); }
.pane-chip.ok { border-color: var(--accent); color: var(--accent); background: none; }
.pane-chip.warn { border-color: #f59e0b; color: #f59e0b; background: none; }
.pane-chip.bad { border-color: #ff5252; color: #ff5252; background: none; }
.pane-kv { border-top: 1px solid var(--bg-tertiary); padding: 8px 2px; display: flex; gap: 8px; font-size: 0.82rem; }
.pane-kv .k { color: var(--text-muted); min-width: 110px; flex-shrink: 0; }
.pane-kv .v { font-weight: 600; }
.pane-actions { display: flex; gap: 12px; justify-content: space-around; border-top: 1px solid var(--bg-tertiary); padding: 12px 4px 2px; margin-top: 12px; }
.pane-action { background: none; border: none; color: var(--text-secondary); cursor: pointer; display: flex; flex-direction: column; align-items: center; gap: 5px; font-size: 0.7rem; }
.pane-action .pa-ico { width: 42px; height: 42px; border-radius: 50%; display: flex; align-items: center; justify-content: center; background: var(--bg-tertiary); border: 1px solid var(--bg-tertiary); font-size: 1rem; color: var(--text-primary); }
.pane-action.primary .pa-ico { background: var(--accent); color: #00120a; }
.pane-action:hover .pa-ico { border-color: var(--accent); }
.diff-pill { display: inline-block; border-radius: 5px; padding: 2px 10px; font-weight: 700; font-size: 0.78rem; color: #08131c; }
.pane-note { color: var(--text-muted); font-size: 0.72rem; margin-top: 10px; line-height: 1.45; }

/* Waypoints */
.wp-icon-grid { display: grid; grid-template-columns: repeat(6, 1fr); gap: 6px; margin: 8px 0; }
.wp-icon-grid button { font-size: 1.05rem; padding: 8px 0; border-radius: var(--radius-sm); border: 2px solid var(--bg-tertiary); background: var(--bg-tertiary); cursor: pointer; }
.wp-icon-grid button.sel { border-color: var(--accent); }
.wp-color-row { display: flex; gap: 8px; margin: 8px 0; }
.wp-color-row button { width: 26px; height: 26px; border-radius: 50%; cursor: pointer; border: 2px solid transparent; }
.wp-color-row button.sel { border-color: #fff; }
.wp-marker { width: 30px; height: 30px; border-radius: 50% 50% 50% 0; transform: rotate(-45deg); display: flex; align-items: center; justify-content: center; border: 2px solid #fff; box-shadow: 0 2px 6px rgba(0,0,0,0.5); cursor: pointer; }
.wp-marker span { transform: rotate(45deg); font-size: 13px; }
.wp-list-item { display: flex; align-items: center; gap: 10px; padding: 8px 4px; border-bottom: 1px solid var(--bg-tertiary); cursor: pointer; border-radius: var(--radius-sm); }
.wp-list-item:hover { background: var(--bg-tertiary); }
.wp-list-dot { width: 28px; height: 28px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 0.85rem; flex-shrink: 0; }

/* Trail overlay legend lines (rendered inside the sidebar section) */
.trail-legend-line { display: flex; align-items: center; gap: 10px; padding: 3px 0; font-size: 0.75rem; color: var(--text-secondary); }
.trail-legend-swatch { width: 30px; height: 5px; border-radius: 3px; flex-shrink: 0; }

/* ===== Route Summary Styles ===== */
.route-overview {
  display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 8px;
  margin-bottom: 16px;
}
.route-stat {
  text-align: center;
  padding: 10px;
  background: var(--bg-tertiary);
  border-radius: var(--radius-sm);
}
.route-stat-value { font-size: 1.2rem; font-weight: 700; color: var(--accent); }
.route-stat-label { font-size: 0.68rem; color: var(--text-muted); margin-top: 2px; }

.route-segment {
  padding: 12px 0;
  border-bottom: 1px solid rgba(255,255,255,0.04);
}
.route-segment:last-child { border-bottom: none; }
.route-segment-header {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 6px;
}
.route-segment-header h4 { font-size: 0.85rem; font-weight: 600; }
.route-segment-header span { font-size: 0.75rem; color: var(--text-muted); }
.route-segment-weather {
  display: flex; gap: 12px;
  margin-bottom: 6px;
}
.route-segment-weather .wx-mini {
  display: flex; align-items: center; gap: 4px;
  font-size: 0.78rem; color: var(--text-secondary);
}
.route-segment-services { display: flex; flex-wrap: wrap; gap: 4px; }
.route-segment-services .service-tag {
  font-size: 0.68rem;
  padding: 2px 6px;
  background: var(--bg-tertiary);
  border-radius: 3px;
  color: var(--text-muted);
}
.route-segment-services .service-tag.available { color: var(--accent); background: var(--accent-dim); }

/* ===== Elevation Profile ===== */
.elevation-profile {
  margin-bottom: 14px;
  padding-bottom: 12px;
  border-bottom: 1px solid rgba(255,255,255,0.04);
}
.elevation-stats {
  display: flex; gap: 12px;
  margin-bottom: 8px;
  font-size: 0.75rem;
  color: var(--text-secondary);
}
.elevation-stats span {
  display: flex; align-items: center; gap: 4px;
}
.elevation-chart-wrap {
  position: relative;
  background: var(--bg-tertiary);
  border-radius: var(--radius-sm);
  padding: 4px;
  cursor: crosshair;
}
.elevation-chart-wrap canvas {
  display: block;
  width: 100%;
}
.elevation-tooltip {
  position: absolute;
  background: var(--bg-secondary);
  border: 1px solid var(--bg-tertiary);
  border-radius: var(--radius-sm);
  padding: 4px 8px;
  font-size: 0.72rem;
  color: var(--text-primary);
  pointer-events: none;
  white-space: nowrap;
  z-index: 10;
  box-shadow: var(--shadow);
  line-height: 1.3;
}
.elevation-map-tooltip {
  background: var(--bg-secondary) !important;
  border: 1px solid var(--accent) !important;
  color: var(--text-primary) !important;
  font-size: 0.75rem !important;
  font-weight: 600 !important;
  padding: 2px 6px !important;
  border-radius: 4px !important;
  box-shadow: var(--shadow) !important;
}
.elevation-map-tooltip::before {
  border-top-color: var(--accent) !important;
}

/* ===== Weather Overlay Legend ===== */
.weather-legend-bar {
  display: flex; height: 12px;
  border-radius: 6px; overflow: hidden;
  margin-bottom: 4px;
}
.weather-legend-labels { display: flex; justify-content: space-between; font-size: 0.68rem; color: var(--text-muted); }

/* ===== MapLibre GL Overrides ===== */
.maplibregl-ctrl-attrib { font-size: 0.6rem !important; background: rgba(15,25,35,0.8) !important; color: var(--text-muted) !important; }
.maplibregl-ctrl-attrib a { color: var(--text-secondary) !important; }
.maplibregl-popup-content {
  background: var(--bg-secondary) !important;
  color: var(--text-primary) !important;
  border-radius: var(--radius) !important;
  box-shadow: var(--shadow) !important;
  border: 1px solid var(--bg-tertiary) !important;
  padding: 12px 14px !important;
  font-family: 'Inter', sans-serif !important;
}
/* The popup tip is a CSS border triangle — theme every anchor direction */
.maplibregl-popup-anchor-bottom .maplibregl-popup-tip { border-top-color: var(--bg-secondary) !important; }
.maplibregl-popup-anchor-top .maplibregl-popup-tip { border-bottom-color: var(--bg-secondary) !important; }
.maplibregl-popup-anchor-left .maplibregl-popup-tip { border-right-color: var(--bg-secondary) !important; }
.maplibregl-popup-anchor-right .maplibregl-popup-tip { border-left-color: var(--bg-secondary) !important; }
.maplibregl-popup-close-button { color: var(--text-secondary) !important; font-size: 20px !important; right: 4px !important; top: 2px !important; }
/* Cluster count styling is data-driven GL symbol paint now (Utils.clusterColors) — no DOM cluster CSS. */

/* Custom marker styles */
.custom-marker {
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%;
  /* Tight shadow: large blur radii multiply paint cost across hundreds of
     markers when a dense area re-renders after a zoom */
  box-shadow: 0 1px 3px rgba(0,0,0,0.5);
  font-size: 14px;
  transition: transform 0.2s ease;
}
.custom-marker:hover { transform: scale(1.2); }

/* Home base pin — a green house badge on the main map at the saved home. */
.home-map-marker {
  display: flex; align-items: center; justify-content: center;
  width: 30px; height: 30px;
  border-radius: 50%;
  background: var(--accent);
  border: 2px solid #fff;
  box-shadow: 0 1px 4px rgba(0,0,0,0.5);
  color: #fff;
  font-size: 14px;
  transition: transform 0.15s ease;
}
.home-map-marker:hover { transform: scale(1.15); }
/* (retired .marker-* divIcon classes removed — markers now draw on canvas via Utils.dotMarker; palette lives in Utils.markerStyles) */

/* ===== Responsive ===== */
@media (max-width: 768px) {
  #mobile-header { display: flex; }
  #sidebar-close { display: block; }

  .sidebar {
    width: 100%;
    transform: translateX(-100%);
    top: 0;
  }
  .sidebar.open { transform: translateX(0); }
  .sidebar-header { padding-top: calc(var(--mobile-header-height) + 8px); }

  #map {
    left: 0;
    top: var(--mobile-header-height);
  }

  #map-controls {
    top: calc(var(--mobile-header-height) + 12px);
    right: 12px;
  }

#info-panel {
    top: auto; bottom: 0; left: 0; right: 0;
    width: 100%; max-width: 100%;
    max-height: 60vh;
    border: none; border-top: 1px solid var(--bg-tertiary);
    border-radius: var(--radius) var(--radius) 0 0;
  }
  #info-panel.hidden { transform: translateY(100%); }
  #sidebar-collapse, #sidebar-expand { display: none !important; }

  .info-details { grid-template-columns: 1fr; }
  .route-overview { grid-template-columns: 1fr 1fr; }

  /* Inputs must be ≥16px to prevent iOS Safari from zooming on focus */
  .route-point input,
  .search-box input,
  .date-field input {
    font-size: 1rem;
  }
}

/* In landscape on mobile: compact the sidebar so content fits above the keyboard */
@media (max-width: 768px) and (orientation: landscape) {
  .sidebar-header { padding-top: calc(var(--mobile-header-height) + 4px); padding-bottom: 6px; }
  .sidebar-section { padding: 10px 16px; }
  .sidebar-section h3 { margin-bottom: 8px; }
  .tab-btn { padding: 8px 4px; }
}

@media (max-width: 480px) {
  .tab-btn { font-size: 0.72rem; padding: 10px 4px; }
  .basemap-selector { flex-direction: column; }
  .weather-grid { grid-template-columns: repeat(3, 1fr); }
}

/* ===== Context Menu ===== */
#context-menu {
  position: fixed;
  background: var(--bg-secondary);
  border: 1px solid var(--bg-tertiary);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  z-index: 2000;
  min-width: 200px;
  padding: 4px 0;
  overflow: hidden;
}
.ctx-item {
  padding: 10px 16px;
  font-size: 0.82rem;
  cursor: pointer;
  display: flex; align-items: center; gap: 10px;
  transition: background 0.15s;
  color: var(--text-primary);
}
.ctx-item:hover { background: rgba(255,255,255,0.06); }
.ctx-item i { color: var(--accent); width: 16px; text-align: center; font-size: 0.85rem; }
.ctx-divider { height: 1px; background: var(--bg-tertiary); margin: 4px 0; }

/* ===== Ride Dashboard ===== */

/* When dashboard is open, hide EVERYTHING else */
body.dashboard-active #map,
body.dashboard-active #sidebar,
body.dashboard-active #mobile-header,
body.dashboard-active #map-controls,
body.dashboard-active #info-panel,
body.dashboard-active #context-menu,
body.dashboard-active .maplibregl-control-container {
  display: none !important;
  visibility: hidden !important;
}

body.dashboard-active {
  overflow: hidden;
  background: #0a0e14;
}

#dashboard-overlay {
  position: fixed;
  inset: 0;
  z-index: 99999;
  background: #0a0e14;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  overflow: hidden;
}

.dash-close-btn {
  position: absolute;
  top: 6px;
  right: 6px;
  z-index: 100002;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 1px solid var(--bg-tertiary);
  background: rgba(26,38,50,0.8);
  color: var(--text-primary);
  font-size: 1.1rem;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  touch-action: manipulation;
}
.dash-close-btn:hover { color: var(--danger); }

/* ===== Full-screen Navigation Overlay (map + rain radar + speed) ===== */
/* Like the speedo dash, hide everything else behind it. */
body.nav-active #map,
body.nav-active #sidebar,
body.nav-active #mobile-header,
body.nav-active #map-controls,
body.nav-active #info-panel,
body.nav-active #context-menu,
body.nav-active .maplibregl-control-container {
  display: none !important;
  visibility: hidden !important;
}
body.nav-active { overflow: hidden; background: #0a0e14; }

#nav-overlay {
  position: fixed;
  inset: 0;
  z-index: 99999;
  background: #0a0e14;
  overflow: hidden;
}

/* Clip the oversized, rotating map. */
#nav-map-wrap {
  position: absolute;
  inset: 0;
  overflow: hidden;
}
/* A square whose side (145vmax) exceeds any viewport's diagonal (≤ ~1.415·vmax),
   centred with negative margins so the `transform` property is free for the
   heading-up rotation JS applies. Being ≥ the diagonal, no corner gap ever
   shows however far it spins. */
#nav-map {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 145vmax;
  height: 145vmax;
  margin-left: -72.5vmax;
  margin-top: -72.5vmax;
  transform-origin: center center;
  /* No CSS transition: nav.js eases the rotation itself, frame by frame (see
     startHeadingLoop). A transition on top would restart every frame and lag. */
  background: #0a0e14;
  will-change: transform;
}
#nav-map .maplibregl-control-container { display: none !important; }

/* Rider chevron — always points up (direction of travel) via JS counter-rotation. */
.nav-rider { background: none !important; border: none !important; }
.nav-rider-chevron {
  width: 44px; height: 44px;
  display: flex; align-items: center; justify-content: center;
  /* eased in JS per frame (see startHeadingLoop) — no CSS transition */
}
.nav-rider-chevron i {
  font-size: 36px;
  color: #1a73e8;   /* Google-nav blue — a bold directional arrow, not a faint dot */
  /* fa-location-arrow's art points NE (45°); correct it to point straight up. */
  transform: rotate(-45deg);
  /* Heavy white outline OUTSIDE the blue so the arrow reads on the green line
     and any basemap (paint-order draws the stroke first, then the fill). */
  -webkit-text-stroke: 2.5px #fff;
  paint-order: stroke fill;
  filter: drop-shadow(0 1px 3px rgba(0,0,0,0.55));
}

/* Current speed + speed-limit sign — bottom-left corner. */
#nav-speed {
  position: absolute;
  left: calc(14px + env(safe-area-inset-left, 0px));
  bottom: calc(18px + env(safe-area-inset-bottom, 0px));
  z-index: 10;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 14px;
  background: rgba(10,14,20,0.72);
  border: 1px solid rgba(255,255,255,0.1);
  border-radius: 14px;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.nav-speed-read { display: flex; align-items: baseline; gap: 4px; }
#nav-speed-value {
  font-size: 4.2rem;
  font-weight: 800;
  line-height: 1;
  color: #fff;
  font-variant-numeric: tabular-nums;
  letter-spacing: -1.5px;
}
#nav-speed-unit { font-size: 0.9rem; font-weight: 600; color: var(--text-secondary); text-transform: uppercase; }

/* Speed-limit sign — a circular white disc with a red ring (NZ/EU style). */
#nav-speed-limit {
  flex: 0 0 auto;
  display: flex; align-items: center; justify-content: center;
  width: 54px; height: 54px;
  border-radius: 50%;
  background: #fff;
  border: 5px solid #d32f2f;
  box-shadow: 0 1px 5px rgba(0,0,0,0.55);
}
#nav-speed-limit-value {
  color: #111;
  font-weight: 800;
  font-size: 1.3rem;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.5px;
}

/* Next-turn banner — top. */
#nav-turn {
  position: absolute;
  top: calc(12px + env(safe-area-inset-top, 0px));
  left: 50%;
  transform: translateX(-50%);
  z-index: 10;
  display: flex;
  align-items: center;
  gap: 12px;
  max-width: min(88vw, 460px);
  padding: 10px 16px 10px 10px;
  background: rgba(10,14,20,0.82);
  border: 1px solid rgba(255,255,255,0.1);
  border-radius: 16px;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  box-shadow: 0 6px 24px rgba(0,0,0,0.4);
}
.nav-turn-icon {
  flex: 0 0 auto;
  width: 46px; height: 46px;
  border-radius: 12px;
  display: flex; align-items: center; justify-content: center;
  font-size: 1.5rem;
}
.nav-turn-icon.prox-far  { background: rgba(0,200,83,0.15);  color: #00c853; }
.nav-turn-icon.prox-mid  { background: rgba(255,193,7,0.2);  color: #ffc107; }
.nav-turn-icon.prox-near { background: rgba(255,82,82,0.22); color: #ff5252; }
.nav-turn-info { min-width: 0; }
#nav-turn-dist { font-size: 1.5rem; font-weight: 800; color: #fff; line-height: 1.05; }
#nav-turn-road {
  font-size: 0.9rem; color: var(--text-secondary);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* "Worth a Stop" heads-up — always SUBORDINATE to the turn banner: lower
   z-index and positioned below it, so an imminent turn instruction is never
   obscured or delayed by a POI alert. Tap target: the whole pill dismisses. */
#nav-poi {
  position: absolute;
  top: calc(92px + env(safe-area-inset-top, 0px)); /* clears #nav-turn (~78px at 46px icon) */
  left: 50%;
  transform: translateX(-50%);
  z-index: 9;
  display: flex;
  align-items: center;
  gap: 10px;
  max-width: min(84vw, 420px);
  padding: 10px 14px;
  background: rgba(22, 14, 34, 0.86);
  border: 1px solid rgba(126, 87, 194, 0.55);
  border-radius: 14px;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.4);
  cursor: pointer;
}
#nav-poi.hidden { display: none; }

/* Fixed camera warning — same geometry as #nav-poi so they stack cleanly, but
   red-edged and it owns the slot right under the turn banner. A "possible"
   camera is amber and visibly softer: it must never read as a confirmed one. */
#nav-camera {
  position: absolute;
  top: calc(92px + env(safe-area-inset-top, 0px)); /* the slot #nav-poi used */
  left: 50%;
  transform: translateX(-50%);
  z-index: 9;
  display: flex;
  align-items: center;
  gap: 10px;
  max-width: min(84vw, 420px);
  padding: 10px 14px;
  background: rgba(40, 12, 12, 0.9);
  border: 1px solid rgba(255, 82, 82, 0.75);
  border-radius: 14px;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.45);
}
#nav-camera.hidden { display: none; }
#nav-camera-icon { font-size: 1.5rem; color: #ff5252; flex-shrink: 0; width: 34px; text-align: center; }
#nav-camera-name {
  font-weight: 700; font-size: 0.95rem; color: #fff;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
#nav-camera-detail { font-size: 0.78rem; color: var(--text-secondary); }
#nav-camera.cam-possible {
  background: rgba(40, 30, 10, 0.88);
  border-color: rgba(255, 171, 64, 0.7);
}
#nav-camera.cam-possible #nav-camera-icon { color: #ffab40; }
#nav-camera { top: calc(146px + env(safe-area-inset-top, 0px)); }

/* #nav-poi and friends — ported from NZ with the GL nav */
/* ===== CSS Variables ===== */
:root {
  --bg-primary: #0f1923;
  --bg-secondary: #1a2632;
  --bg-tertiary: #243342;
  --bg-card: #1e2d3d;
  --text-primary: #e8edf2;
  --text-secondary: #8899aa;
  --text-muted: #5a6f82;
  --accent: #00c853;
  --accent-hover: #00e676;
  --accent-dim: rgba(0, 200, 83, 0.15);
  --danger: #ff5252;
  --warning: #ffab40;
  --info: #40c4ff;
  --spark-color: #ffe600;
  --vodafone-color: #e60000;
  --twodeg-color: #00aaff;
  --sidebar-width: 380px;
  --mobile-header-height: calc(56px + env(safe-area-inset-top, 0px)); /* fullscreen display: bar background reaches the true screen top; content pads below the camera cutout */
  --radius: 8px;
  --radius-sm: 4px;
  --shadow: 0 4px 24px rgba(0,0,0,0.4);
  --transition: 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}

/* ===== Reset ===== */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html, body { height: 100%; overflow: hidden; }
body {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  background: var(--bg-primary);
  color: var(--text-primary);
  -webkit-font-smoothing: antialiased;
}

/* ===== Login Screen ===== */
#login-screen {
  position: fixed; inset: 0;
  background: var(--bg-primary);
  display: flex; align-items: center; justify-content: center;
  z-index: 10001;
  transition: opacity 0.4s ease;
}
#login-screen.fade-out { opacity: 0; pointer-events: none; }
.login-card {
  display: flex; flex-direction: column; align-items: center;
  padding: 32px 28px;
  background: var(--bg-secondary);
  border-radius: 16px;
  border: 1px solid var(--border, rgba(255,255,255,0.06));
  width: min(360px, 90vw);
}
.login-input {
  width: 100%; padding: 10px 12px;
  border-radius: var(--radius-sm, 6px);
  border: 1px solid var(--border, rgba(255,255,255,0.1));
  background: var(--bg-tertiary); color: var(--text-primary);
  font-size: 0.88rem; font-family: inherit;
  margin-bottom: 8px; outline: none;
}
.login-input:focus { border-color: var(--accent); }
.login-error {
  font-size: 0.75rem; color: #ff5252;
  margin-bottom: 8px; display: none;
  text-align: center;
}
.login-btn {
  width: 100%; padding: 10px; font-size: 0.88rem;
  border-radius: var(--radius-sm, 6px);
  cursor: pointer; margin-bottom: 6px;
}
.login-google-btn {
  background: var(--bg-tertiary); color: var(--text-secondary);
  border: 1px solid var(--border, rgba(255,255,255,0.1));
}
.login-google-btn:hover { background: var(--bg-card); }

/* ===== Loading Screen ===== */
#loading-screen {
  position: fixed; inset: 0;
  background: var(--bg-primary);
  display: flex; align-items: center; justify-content: center;
  z-index: 10000;
  transition: opacity 0.5s ease;
}
#loading-screen.fade-out { opacity: 0; pointer-events: none; }
.loader-content { text-align: center; }
.loader-icon { font-size: 3rem; color: var(--accent); margin-bottom: 1rem; animation: pulse 1.5s infinite; }
.loader-content h2 { font-size: 1.5rem; font-weight: 700; margin-bottom: 0.5rem; }
.loader-content p { color: var(--text-secondary); margin-bottom: 1.5rem; }
.loader-bar { width: 200px; height: 3px; background: var(--bg-tertiary); border-radius: 3px; overflow: hidden; margin: 0 auto; }
.loader-progress { height: 100%; width: 30%; background: var(--accent); border-radius: 3px; animation: loading 1.5s ease-in-out infinite; }
@keyframes loading { 0% { transform: translateX(-100%); } 100% { transform: translateX(400%); } }
@keyframes pulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.1); } }

/* ===== Mobile Header ===== */
#mobile-header {
  display: none;
  position: fixed; top: 0; left: 0; right: 0;
  height: var(--mobile-header-height);
  background: var(--bg-secondary);
  border-bottom: 1px solid var(--bg-tertiary);
  align-items: center;
  justify-content: space-between;
  padding: env(safe-area-inset-top, 0px) 12px 0;
  z-index: 1001;
}
#mobile-header h1 { font-size: 1.1rem; font-weight: 700; }
#mobile-header button {
  background: none; border: none; color: var(--text-primary);
  font-size: 1.2rem; padding: 8px; cursor: pointer;
}

/* ===== Sidebar ===== */
.sidebar {
  position: fixed; top: 0; left: 0; bottom: 0;
  width: var(--sidebar-width);
  background: var(--bg-secondary);
  border-right: 1px solid var(--bg-tertiary);
  display: flex; flex-direction: column;
  z-index: 1000;
  transition: transform var(--transition);
  overflow: hidden;
}
.sidebar.collapsed { transform: translateX(-100%); }

/* Desktop sidebar collapse (onX-style). One body-level var override moves every
   --sidebar-width dependent (#map, #info-panel, #weather-timeline, 3D/basemap
   switches) at once. Desktop-only: mobile keeps the .open overlay pattern. */
@media (min-width: 769px) {
  body.sidebar-collapsed { --sidebar-width: 0px; }
  body.sidebar-collapsed .sidebar { transform: translateX(-100%); }
  /* Collapsed sidebar puts #info-panel at left:12px — the same corner the
     fixed #sidebar-expand (») button occupies — covering the site name.
     Shift the pane right to clear the 38px button + gaps. */
  body.sidebar-collapsed #info-panel { left: 62px; }
}
#sidebar-collapse {
  background: none; border: none; color: var(--text-secondary);
  font-size: 1rem; cursor: pointer; padding: 4px 8px;
}
#sidebar-collapse:hover { color: var(--text-primary); }
#sidebar-expand {
  position: fixed; top: 12px; left: 12px; z-index: 1001;
  width: 38px; height: 38px; border-radius: var(--radius-sm);
  background: var(--bg-secondary); border: 1px solid var(--bg-tertiary);
  color: var(--text-primary); font-size: 1rem; cursor: pointer;
  display: none; align-items: center; justify-content: center;
  box-shadow: 0 2px 10px rgba(0,0,0,0.4);
}
body.sidebar-collapsed #sidebar-expand { display: flex; }

.sidebar-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px 20px;
  border-bottom: 1px solid var(--bg-tertiary);
  flex-shrink: 0;
}
.brand { display: flex; align-items: center; gap: 10px; }
.brand i { font-size: 1.5rem; color: var(--accent); }
.brand h1 { font-size: 1.25rem; font-weight: 700; }
#sidebar-close {
  background: none; border: none; color: var(--text-secondary);
  font-size: 1.2rem; cursor: pointer; padding: 4px;
  display: none;
}

.sidebar-body {
  flex: 1; overflow-y: auto; overflow-x: hidden;
  padding: 0;
  scrollbar-width: thin;
  scrollbar-color: var(--bg-tertiary) transparent;
}
.sidebar-body::-webkit-scrollbar { width: 6px; }
.sidebar-body::-webkit-scrollbar-track { background: transparent; }
.sidebar-body::-webkit-scrollbar-thumb { background: var(--bg-tertiary); border-radius: 3px; }

.sidebar-footer {
  padding: 12px 20px;
  border-top: 1px solid var(--bg-tertiary);
  flex-shrink: 0;
}
.sidebar-footer p { font-size: 0.7rem; color: var(--text-muted); line-height: 1.5; }

/* ===== Tab Navigation ===== */
.tab-nav {
  display: flex;
  border-bottom: 1px solid var(--bg-tertiary);
  flex-shrink: 0;
}
.tab-btn {
  flex: 1;
  padding: 12px 8px;
  background: none; border: none;
  color: var(--text-secondary);
  font-size: 0.8rem; font-weight: 500;
  cursor: pointer;
  border-bottom: 2px solid transparent;
  transition: all var(--transition);
  display: flex; align-items: center; justify-content: center; gap: 6px;
}
.tab-btn:hover { color: var(--text-primary); background: var(--bg-tertiary); }
.tab-btn.active { color: var(--accent); border-bottom-color: var(--accent); }
.tab-btn i { font-size: 0.9rem; }

.tab-content { display: none; }
.tab-content.active { display: block; }

/* ===== Sidebar Sections ===== */
.sidebar-section {
  padding: 16px 20px;
  border-bottom: 1px solid rgba(255,255,255,0.04);
}
.sidebar-section h3 {
  font-size: 0.8rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--text-secondary);
  margin-bottom: 12px;
  display: flex; align-items: center; gap: 8px;
}
.sidebar-section h3 i { color: var(--accent); font-size: 0.85rem; }
.sidebar-section h4 {
  font-size: 0.78rem; font-weight: 600;
  color: var(--text-secondary);
  margin: 12px 0 8px;
}
.hint { font-size: 0.78rem; color: var(--text-muted); margin-bottom: 12px; line-height: 1.4; }

/* ===== Search ===== */
.search-box {
  display: flex; align-items: center;
  background: var(--bg-tertiary);
  border-radius: var(--radius);
  padding: 0 12px;
  border: 1px solid transparent;
  transition: border-color var(--transition);
}
.search-box:focus-within { border-color: var(--accent); }
.search-box i { color: var(--text-muted); font-size: 0.85rem; }
.search-box input {
  flex: 1; background: none; border: none; outline: none;
  color: var(--text-primary); padding: 10px 10px;
  font-size: 0.85rem; font-family: inherit;
}
.search-box input::placeholder { color: var(--text-muted); }
.search-box button { background: none; border: none; color: var(--text-muted); cursor: pointer; padding: 4px; }
.search-results {
  margin-top: 8px;
  background: var(--bg-tertiary);
  border-radius: var(--radius);
  max-height: 240px;
  overflow-y: auto;
}
.search-results.hidden { display: none; }
.search-result-item {
  padding: 10px 14px;
  cursor: pointer;
  font-size: 0.82rem;
  border-bottom: 1px solid rgba(255,255,255,0.04);
  transition: background var(--transition);
  display: flex; align-items: center; gap: 8px;
}
.search-result-item:hover { background: rgba(255,255,255,0.05); }
.search-result-item i { color: var(--accent); width: 16px; text-align: center; }
.search-result-item:last-child { border-bottom: none; }

/* ===== Layer Toggles ===== */
.layer-toggle {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 0;
  cursor: pointer;
  font-size: 0.85rem;
}
.layer-toggle input { display: none; }
.toggle-slider {
  width: 36px; height: 20px;
  background: var(--bg-tertiary);
  border-radius: 10px;
  position: relative;
  transition: background var(--transition);
  flex-shrink: 0;
}
.toggle-slider::after {
  content: '';
  position: absolute;
  width: 16px; height: 16px;
  background: var(--text-secondary);
  border-radius: 50%;
  top: 2px; left: 2px;
  transition: all var(--transition);
}
.layer-toggle input:checked + .toggle-slider { background: var(--accent-dim); }
.layer-toggle input:checked + .toggle-slider::after { transform: translateX(16px); background: var(--accent); }
.toggle-label { flex: 1; }

/* ===== Route vehicle picker (js/vehicle.js) ===== */
/* Ported from Motocamp USA, minus the towing row — NZ ships no towing modifier
   (it would change nothing about the route here; see js/vehicle.js). */
.route-vehicle {
  padding-bottom: 10px;
  margin-bottom: 4px;
  border-bottom: 1px solid var(--bg-tertiary);
}
.route-vehicle-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 6px; margin-bottom: 7px;
}
.route-vehicle-title {
  font-size: 0.72rem; font-weight: 600;
  color: var(--text-secondary);
  text-transform: uppercase; letter-spacing: 0.04em;
}
.route-vehicle-reset {
  background: none; border: none; padding: 0;
  color: var(--text-muted, #888);
  font-size: 0.66rem; cursor: pointer; text-decoration: underline;
}
.route-vehicle-reset:hover { color: var(--accent); }
.route-vehicle-reset[hidden] { display: none; }
.route-vehicle-picker {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 5px;
}
.route-vehicle-btn {
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  padding: 7px 3px;
  border: 1px solid var(--bg-tertiary);
  border-radius: 6px;
  background: transparent;
  color: var(--text-secondary);
  font-size: 0.62rem;
  cursor: pointer;
  transition: all var(--transition);
  min-width: 0;
}
.route-vehicle-btn i { font-size: 0.92rem; }
.route-vehicle-btn span { overflow-wrap: anywhere; text-align: center; line-height: 1.2; }
.route-vehicle-btn:hover { border-color: var(--text-muted, #888); color: var(--text-primary); }
.route-vehicle-btn[aria-pressed="true"] {
  border-color: var(--accent);
  background: var(--accent-dim);
  color: var(--text-primary);
}
.route-vehicle-btn[aria-pressed="true"] i { color: var(--accent); }
.route-vehicle-note {
  font-size: 0.66rem;
  color: var(--text-muted, #888);
  margin-top: 7px;
  line-height: 1.45;
}
.route-vehicle-note:empty { display: none; }
.route-vehicle-note .warn { color: #ffab40; }

.badge {
  font-size: 0.65rem; font-weight: 600;
  padding: 2px 6px; border-radius: 3px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}
.badge-green { background: rgba(0,200,83,0.15); color: #00c853; }
.badge-blue { background: rgba(64,196,255,0.15); color: #40c4ff; }
.badge-orange { background: rgba(255,171,64,0.15); color: #ffab40; }
.badge-purple { background: rgba(176,128,255,0.15); color: #b080ff; }
.badge-teal { background: rgba(38,198,178,0.15); color: #26c6b2; }
.badge-yellow { background: rgba(255,230,0,0.15); color: #ffe600; }
.badge-red { background: rgba(230,0,0,0.15); color: #ff5252; }

/* ===== Base Map Selector ===== */
/* Warm up CARTO Voyager's pale palette so the base map reads richer, not washed out */
.basemap-selector { display: flex; gap: 6px; }
.basemap-btn {
  flex: 1; padding: 8px;
  background: var(--bg-tertiary);
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  color: var(--text-secondary);
  font-size: 0.75rem; font-weight: 500;
  cursor: pointer;
  transition: all var(--transition);
  display: flex; flex-direction: column; align-items: center; gap: 4px;
}
.basemap-btn i { font-size: 1rem; }
.basemap-btn:hover { color: var(--text-primary); background: rgba(255,255,255,0.08); }
.basemap-btn.active { border-color: var(--accent); color: var(--accent); background: var(--accent-dim); }

/* ===== Filter Chips ===== */
.filter-group { display: flex; flex-wrap: wrap; gap: 6px; }
.filter-chip {
  display: flex; align-items: center; gap: 4px;
  padding: 6px 10px;
  background: var(--bg-tertiary);
  border-radius: 20px;
  font-size: 0.75rem;
  cursor: pointer;
  transition: all var(--transition);
  border: 1px solid transparent;
  user-select: none;
}
.filter-chip:hover { background: rgba(255,255,255,0.08); }
.filter-chip input { display: none; }
.filter-chip:has(input:checked) { border-color: var(--accent); background: var(--accent-dim); color: var(--accent); }
.filter-chip i { font-size: 0.7rem; }

/* ===== Route Planning ===== */
.route-inputs { display: flex; flex-direction: column; gap: 4px; }
.route-point {
  display: flex; align-items: center; gap: 10px;
  background: var(--bg-tertiary);
  border-radius: var(--radius-sm);
  padding: 0 12px;
}
.route-point input {
  flex: 1; background: none; border: none; outline: none;
  color: var(--text-primary); padding: 10px 0;
  font-size: 0.85rem; font-family: inherit;
}
.route-point input::placeholder { color: var(--text-muted); }
/* Route search results dropdown */
.route-search-results {
  position: absolute;
  left: 0; right: 0;
  z-index: 9999;
  margin-top: 2px;
  max-height: 200px;
  overflow-y: auto;
  box-shadow: 0 6px 20px rgba(0,0,0,0.4);
  border: 1px solid rgba(255,255,255,0.08);
}
/* Suggestions are positioned in JS (see _positionResults in js/route.js):
   fixed to the viewport but anchored to the input's real position, flipping
   above it when the phone keyboard leaves no room below. The old mobile rule
   pinned them to top:52px of the SCREEN — detached from the box being typed
   in, floating over the header ("the destination box broke out"). */
.route-search-results {
  position: fixed;
  z-index: 10000;
}
.route-start-icon { color: var(--accent); font-size: 0.6rem; }
.route-locate-btn {
  flex-shrink: 0;
  padding: 6px 8px;
  border: none;
  color: var(--accent);
  background: none;
  font-size: 1rem;
  cursor: pointer;
  opacity: 0.7;
  transition: opacity 0.2s;
}
.route-locate-btn:hover { opacity: 1; }
.route-locate-btn.locating { animation: pulse-locate 1s infinite; }
@keyframes pulse-locate { 0%, 100% { opacity: 0.4; } 50% { opacity: 1; } }
.route-end-icon { color: var(--danger); font-size: 0.85rem; }
.route-waypoint-icon { color: var(--info); font-size: 0.6rem; }

.route-actions { display: flex; gap: 8px; margin-top: 8px; }
.route-dates { margin-top: 4px; }
.date-inputs { display: flex; gap: 8px; }
.date-field { flex: 1; }
.date-field label { display: block; font-size: 0.72rem; color: var(--text-muted); margin-bottom: 4px; }
.date-field input {
  width: 100%; padding: 8px 10px;
  background: var(--bg-tertiary);
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  color: var(--text-primary);
  font-size: 0.82rem; font-family: inherit;
  outline: none;
}
.date-field input:focus { border-color: var(--accent); }

/* ===== Buttons ===== */
.btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 14px;
  background: var(--bg-tertiary);
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: var(--radius-sm);
  color: var(--text-secondary);
  font-size: 0.8rem; font-weight: 500;
  cursor: pointer;
  transition: all var(--transition);
  font-family: inherit;
}
.btn:hover { background: rgba(255,255,255,0.08); color: var(--text-primary); }
.btn-sm { padding: 6px 10px; font-size: 0.75rem; }
.btn-primary { background: var(--accent); color: #000; border-color: var(--accent); font-weight: 600; }
.btn-primary:hover { background: var(--accent-hover); color: #000; }
.btn-danger { border-color: rgba(255,82,82,0.3); color: var(--danger); }
.btn-danger:hover { background: rgba(255,82,82,0.1); }
.btn-block { width: 100%; justify-content: center; margin-top: 12px; }

/* ===== Weather Controls ===== */
.time-slider-container { padding: 4px 0; }
.time-slider-container input[type="range"] {
  width: 100%; -webkit-appearance: none; appearance: none;
  height: 4px; background: var(--bg-tertiary);
  border-radius: 2px; outline: none;
}
.time-slider-container input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 16px; height: 16px;
  background: var(--accent); border-radius: 50%;
  cursor: pointer;
}
.time-labels { display: flex; justify-content: space-between; margin-top: 4px; font-size: 0.7rem; color: var(--text-muted); }

/* ===== Map ===== */
#map {
  position: fixed;
  top: 0; bottom: 0;
  left: var(--sidebar-width);
  right: 0;
  z-index: 1;
}

/* ===== Map Controls ===== */
#map-controls {
  position: fixed;
  top: 16px; right: 16px;
  display: flex; flex-direction: column; gap: 8px;
  z-index: 500;
}
.map-btn {
  width: auto; height: auto;
  padding: 8px 10px;
  background: var(--bg-secondary);
  border: 1px solid var(--bg-tertiary);
  border-radius: var(--radius);
  color: var(--text-primary);
  font-size: 1rem;
  cursor: pointer;
  display: flex; align-items: center; gap: 6px;
  transition: all var(--transition);
  box-shadow: var(--shadow);
}
.map-btn-label {
  font-size: 0.65rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--text-secondary);
}
.map-btn:hover { background: var(--bg-tertiary); color: var(--accent); }
.map-btn:hover .map-btn-label { color: var(--accent); }
.map-btn.active { background: var(--accent); color: #fff; border-color: var(--accent); }
.map-btn.active .map-btn-label { color: #fff; }

/* ===== Weather Tile Overlays ===== */
.weather-tile-temperature { filter: saturate(2.5) contrast(1.8) brightness(1.1); }
.weather-tile-precipitation { filter: saturate(2.0) contrast(1.5); }
.weather-tile-clouds { filter: contrast(1.4) brightness(0.95); }
.weather-tile-wind { filter: saturate(1.8) contrast(1.4); }

/* ===== Weather Timeline ===== */
/* ===== Info Panel =====
   Vertical side-loading pane (onX-style), 2026-07-27. Was a bottom-anchored
   horizontal strip eating 50vh; now a left card over the map. Mobile keeps the
   bottom-sheet geometry (overridden in the 768px block below). */
#info-panel {
  position: fixed;
  top: 12px; bottom: 12px;
  left: calc(var(--sidebar-width) + 12px);
  width: 380px;
  max-width: calc(100vw - var(--sidebar-width) - 24px);
  background: var(--bg-secondary);
  border: 1px solid var(--bg-tertiary);
  border-radius: var(--radius);
  z-index: 600;
  overflow-y: auto;
  box-shadow: 0 8px 30px rgba(0,0,0,0.45);
  transition: transform var(--transition), opacity var(--transition);
}
#info-panel.hidden {
  transform: translateX(calc(-100% - 420px));
  opacity: 0;
  pointer-events: none;
}
#info-close {
  position: sticky; top: 0; right: 0;
  float: right; margin: 12px 12px 0 0;
  background: var(--bg-tertiary); border: none;
  z-index: 10;
  color: var(--text-secondary); width: 32px; height: 32px;
  border-radius: 50%; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  font-size: 0.9rem;
}
#info-content { padding: 20px 24px 24px; }

/* Info Panel Content */
.info-header { margin-bottom: 16px; }
.info-header h2 { font-size: 1.15rem; font-weight: 700; margin-bottom: 4px; }
.info-header .info-type { font-size: 0.78rem; color: var(--accent); font-weight: 500; text-transform: uppercase; letter-spacing: 0.03em; }
.info-header .info-status { font-size: 0.75rem; padding: 2px 8px; border-radius: 3px; margin-left: 8px; }
.info-header .info-status.open { background: rgba(0,200,83,0.15); color: #00c853; }
.info-header .info-status.closed { background: rgba(255,82,82,0.15); color: #ff5252; }

.info-facilities {
  display: flex; flex-wrap: wrap; gap: 8px;
  margin-bottom: 16px;
}
.facility-badge {
  display: flex; align-items: center; gap: 5px;
  padding: 6px 10px;
  background: var(--bg-tertiary);
  border-radius: var(--radius-sm);
  font-size: 0.75rem;
  color: var(--text-secondary);
}
.facility-badge.available { color: var(--accent); background: var(--accent-dim); }
.facility-badge i { font-size: 0.8rem; }

.info-details { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 16px; }
.info-detail { }
.info-detail-label { font-size: 0.7rem; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.03em; margin-bottom: 2px; }
.info-detail-value { font-size: 0.85rem; color: var(--text-primary); }

.info-weather {
  background: var(--bg-tertiary);
  border-radius: var(--radius);
  padding: 14px;
  margin-bottom: 16px;
}
.info-weather h4 { font-size: 0.78rem; color: var(--text-secondary); margin-bottom: 8px; }
.weather-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(80px, 1fr)); gap: 8px;
}
.weather-item { text-align: center; }
.weather-item .wx-icon { font-size: 1.3rem; margin-bottom: 2px; }
.weather-item .wx-temp { font-size: 1rem; font-weight: 600; }
.weather-item .wx-desc { font-size: 0.68rem; color: var(--text-muted); }
.weather-item .wx-day { font-size: 0.68rem; color: var(--text-secondary); font-weight: 500; }

.info-cell-coverage { margin-bottom: 16px; }
.cell-bar-container { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
.cell-carrier { font-size: 0.78rem; width: 70px; color: var(--text-secondary); }
.cell-bar { flex: 1; height: 6px; background: var(--bg-tertiary); border-radius: 3px; overflow: hidden; }
.cell-bar-fill { height: 100%; border-radius: 3px; transition: width 0.5s ease; }
.cell-bar-fill.spark { background: var(--spark-color); }
.cell-bar-fill.vodafone { background: var(--vodafone-color); }
.cell-bar-fill.twodeg { background: var(--twodeg-color); }
.cell-tech { font-size: 0.68rem; color: var(--text-muted); width: 30px; }

.info-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.info-actions .btn i { font-size: 0.8rem; }

/* ===== Pane card components (onX card anatomy, shared by trail/land/hazard/
   waypoint cards and reusable by any info-panel content) ===== */
.pane-tiles { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-bottom: 14px; }
.pane-tile { background: var(--bg-tertiary); border-radius: var(--radius-sm); padding: 8px 10px; }
.pane-tile.wide { grid-column: 1 / -1; }
.pane-tile .pt-label { font-size: 0.68rem; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.03em; }
.pane-tile .pt-value { font-size: 0.95rem; font-weight: 700; margin-top: 2px; }
.pane-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px; }
.pane-chip { border: 1px solid var(--bg-tertiary); background: var(--bg-tertiary); border-radius: 999px; padding: 3px 10px; font-size: 0.72rem; color: var(--text-secondary); }
.pane-chip.ok { border-color: var(--accent); color: var(--accent); background: none; }
.pane-chip.warn { border-color: #f59e0b; color: #f59e0b; background: none; }
.pane-chip.bad { border-color: #ff5252; color: #ff5252; background: none; }
.pane-kv { border-top: 1px solid var(--bg-tertiary); padding: 8px 2px; display: flex; gap: 8px; font-size: 0.82rem; }
.pane-kv .k { color: var(--text-muted); min-width: 110px; flex-shrink: 0; }
.pane-kv .v { font-weight: 600; }
.pane-actions { display: flex; gap: 12px; justify-content: space-around; border-top: 1px solid var(--bg-tertiary); padding: 12px 4px 2px; margin-top: 12px; }
.pane-action { background: none; border: none; color: var(--text-secondary); cursor: pointer; display: flex; flex-direction: column; align-items: center; gap: 5px; font-size: 0.7rem; }
.pane-action .pa-ico { width: 42px; height: 42px; border-radius: 50%; display: flex; align-items: center; justify-content: center; background: var(--bg-tertiary); border: 1px solid var(--bg-tertiary); font-size: 1rem; color: var(--text-primary); }
.pane-action.primary .pa-ico { background: var(--accent); color: #00120a; }
.pane-action:hover .pa-ico { border-color: var(--accent); }
.diff-pill { display: inline-block; border-radius: 5px; padding: 2px 10px; font-weight: 700; font-size: 0.78rem; color: #08131c; }
.pane-note { color: var(--text-muted); font-size: 0.72rem; margin-top: 10px; line-height: 1.45; }

/* Waypoints */
.wp-icon-grid { display: grid; grid-template-columns: repeat(6, 1fr); gap: 6px; margin: 8px 0; }
.wp-icon-grid button { font-size: 1.05rem; padding: 8px 0; border-radius: var(--radius-sm); border: 2px solid var(--bg-tertiary); background: var(--bg-tertiary); cursor: pointer; }
.wp-icon-grid button.sel { border-color: var(--accent); }
.wp-color-row { display: flex; gap: 8px; margin: 8px 0; }
.wp-color-row button { width: 26px; height: 26px; border-radius: 50%; cursor: pointer; border: 2px solid transparent; }
.wp-color-row button.sel { border-color: #fff; }
.wp-marker { width: 30px; height: 30px; border-radius: 50% 50% 50% 0; transform: rotate(-45deg); display: flex; align-items: center; justify-content: center; border: 2px solid #fff; box-shadow: 0 2px 6px rgba(0,0,0,0.5); cursor: pointer; }
.wp-marker span { transform: rotate(45deg); font-size: 13px; }
.wp-list-item { display: flex; align-items: center; gap: 10px; padding: 8px 4px; border-bottom: 1px solid var(--bg-tertiary); cursor: pointer; border-radius: var(--radius-sm); }
.wp-list-item:hover { background: var(--bg-tertiary); }
.wp-list-dot { width: 28px; height: 28px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 0.85rem; flex-shrink: 0; }

/* Trail overlay legend lines (rendered inside the sidebar section) */
.trail-legend-line { display: flex; align-items: center; gap: 10px; padding: 3px 0; font-size: 0.75rem; color: var(--text-secondary); }
.trail-legend-swatch { width: 30px; height: 5px; border-radius: 3px; flex-shrink: 0; }

/* ===== Route Summary Styles ===== */
.route-overview {
  display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 8px;
  margin-bottom: 16px;
}
.route-stat {
  text-align: center;
  padding: 10px;
  background: var(--bg-tertiary);
  border-radius: var(--radius-sm);
}
.route-stat-value { font-size: 1.2rem; font-weight: 700; color: var(--accent); }
.route-stat-label { font-size: 0.68rem; color: var(--text-muted); margin-top: 2px; }

.route-segment {
  padding: 12px 0;
  border-bottom: 1px solid rgba(255,255,255,0.04);
}
.route-segment:last-child { border-bottom: none; }
.route-segment-header {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 6px;
}
.route-segment-header h4 { font-size: 0.85rem; font-weight: 600; }
.route-segment-header span { font-size: 0.75rem; color: var(--text-muted); }
.route-segment-weather {
  display: flex; gap: 12px;
  margin-bottom: 6px;
}
.route-segment-weather .wx-mini {
  display: flex; align-items: center; gap: 4px;
  font-size: 0.78rem; color: var(--text-secondary);
}
.route-segment-services { display: flex; flex-wrap: wrap; gap: 4px; }
.route-segment-services .service-tag {
  font-size: 0.68rem;
  padding: 2px 6px;
  background: var(--bg-tertiary);
  border-radius: 3px;
  color: var(--text-muted);
}
.route-segment-services .service-tag.available { color: var(--accent); background: var(--accent-dim); }

/* ===== Elevation Profile ===== */
.elevation-profile {
  margin-bottom: 14px;
  padding-bottom: 12px;
  border-bottom: 1px solid rgba(255,255,255,0.04);
}
.elevation-stats {
  display: flex; gap: 12px;
  margin-bottom: 8px;
  font-size: 0.75rem;
  color: var(--text-secondary);
}
.elevation-stats span {
  display: flex; align-items: center; gap: 4px;
}
.elevation-chart-wrap {
  position: relative;
  background: var(--bg-tertiary);
  border-radius: var(--radius-sm);
  padding: 4px;
  cursor: crosshair;
}
.elevation-chart-wrap canvas {
  display: block;
  width: 100%;
}
.elevation-tooltip {
  position: absolute;
  background: var(--bg-secondary);
  border: 1px solid var(--bg-tertiary);
  border-radius: var(--radius-sm);
  padding: 4px 8px;
  font-size: 0.72rem;
  color: var(--text-primary);
  pointer-events: none;
  white-space: nowrap;
  z-index: 10;
  box-shadow: var(--shadow);
  line-height: 1.3;
}
.elevation-map-tooltip {
  background: var(--bg-secondary) !important;
  border: 1px solid var(--accent) !important;
  color: var(--text-primary) !important;
  font-size: 0.75rem !important;
  font-weight: 600 !important;
  padding: 2px 6px !important;
  border-radius: 4px !important;
  box-shadow: var(--shadow) !important;
}
.elevation-map-tooltip::before {
  border-top-color: var(--accent) !important;
}

/* ===== Weather Overlay Legend ===== */
.weather-legend-bar {
  display: flex; height: 12px;
  border-radius: 6px; overflow: hidden;
  margin-bottom: 4px;
}
.weather-legend-labels { display: flex; justify-content: space-between; font-size: 0.68rem; color: var(--text-muted); }

/* ===== MapLibre GL Overrides ===== */
.maplibregl-ctrl-attrib { font-size: 0.6rem !important; background: rgba(15,25,35,0.8) !important; color: var(--text-muted) !important; }
.maplibregl-ctrl-attrib a { color: var(--text-secondary) !important; }
.maplibregl-popup-content {
  background: var(--bg-secondary) !important;
  color: var(--text-primary) !important;
  border-radius: var(--radius) !important;
  box-shadow: var(--shadow) !important;
  border: 1px solid var(--bg-tertiary) !important;
  padding: 12px 14px !important;
  font-family: 'Inter', sans-serif !important;
}
/* The popup tip is a CSS border triangle — theme every anchor direction */
.maplibregl-popup-anchor-bottom .maplibregl-popup-tip { border-top-color: var(--bg-secondary) !important; }
.maplibregl-popup-anchor-top .maplibregl-popup-tip { border-bottom-color: var(--bg-secondary) !important; }
.maplibregl-popup-anchor-left .maplibregl-popup-tip { border-right-color: var(--bg-secondary) !important; }
.maplibregl-popup-anchor-right .maplibregl-popup-tip { border-left-color: var(--bg-secondary) !important; }
.maplibregl-popup-close-button { color: var(--text-secondary) !important; font-size: 20px !important; right: 4px !important; top: 2px !important; }
/* Cluster count styling is data-driven GL symbol paint now (Utils.clusterColors) — no DOM cluster CSS. */

/* Custom marker styles */
.custom-marker {
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%;
  /* Tight shadow: large blur radii multiply paint cost across hundreds of
     markers when a dense area re-renders after a zoom */
  box-shadow: 0 1px 3px rgba(0,0,0,0.5);
  font-size: 14px;
  transition: transform 0.2s ease;
}
.custom-marker:hover { transform: scale(1.2); }

/* Home base pin — a green house badge on the main map at the saved home. */
.home-map-marker {
  display: flex; align-items: center; justify-content: center;
  width: 30px; height: 30px;
  border-radius: 50%;
  background: var(--accent);
  border: 2px solid #fff;
  box-shadow: 0 1px 4px rgba(0,0,0,0.5);
  color: #fff;
  font-size: 14px;
  transition: transform 0.15s ease;
}
.home-map-marker:hover { transform: scale(1.15); }
/* (retired .marker-* divIcon classes removed — markers now draw on canvas via Utils.dotMarker; palette lives in Utils.markerStyles) */

/* ===== Responsive ===== */
@media (max-width: 768px) {
  #mobile-header { display: flex; }
  #sidebar-close { display: block; }

  .sidebar {
    width: 100%;
    transform: translateX(-100%);
    top: 0;
  }
  .sidebar.open { transform: translateX(0); }
  .sidebar-header { padding-top: calc(var(--mobile-header-height) + 8px); }

  #map {
    left: 0;
    top: var(--mobile-header-height);
  }

  #map-controls {
    top: calc(var(--mobile-header-height) + 12px);
    right: 12px;
  }

#info-panel {
    top: auto; bottom: 0; left: 0; right: 0;
    width: 100%; max-width: 100%;
    max-height: 60vh;
    border: none; border-top: 1px solid var(--bg-tertiary);
    border-radius: var(--radius) var(--radius) 0 0;
  }
  #info-panel.hidden { transform: translateY(100%); }
  #sidebar-collapse, #sidebar-expand { display: none !important; }

  .info-details { grid-template-columns: 1fr; }
  .route-overview { grid-template-columns: 1fr 1fr; }

  /* Inputs must be ≥16px to prevent iOS Safari from zooming on focus */
  .route-point input,
  .search-box input,
  .date-field input {
    font-size: 1rem;
  }
}

/* In landscape on mobile: compact the sidebar so content fits above the keyboard */
@media (max-width: 768px) and (orientation: landscape) {
  .sidebar-header { padding-top: calc(var(--mobile-header-height) + 4px); padding-bottom: 6px; }
  .sidebar-section { padding: 10px 16px; }
  .sidebar-section h3 { margin-bottom: 8px; }
  .tab-btn { padding: 8px 4px; }
}

@media (max-width: 480px) {
  .tab-btn { font-size: 0.72rem; padding: 10px 4px; }
  .basemap-selector { flex-direction: column; }
  .weather-grid { grid-template-columns: repeat(3, 1fr); }
}

/* ===== Context Menu ===== */
#context-menu {
  position: fixed;
  background: var(--bg-secondary);
  border: 1px solid var(--bg-tertiary);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  z-index: 2000;
  min-width: 200px;
  padding: 4px 0;
  overflow: hidden;
}
.ctx-item {
  padding: 10px 16px;
  font-size: 0.82rem;
  cursor: pointer;
  display: flex; align-items: center; gap: 10px;
  transition: background 0.15s;
  color: var(--text-primary);
}
.ctx-item:hover { background: rgba(255,255,255,0.06); }
.ctx-item i { color: var(--accent); width: 16px; text-align: center; font-size: 0.85rem; }
.ctx-divider { height: 1px; background: var(--bg-tertiary); margin: 4px 0; }

/* ===== Ride Dashboard ===== */

/* When dashboard is open, hide EVERYTHING else */
body.dashboard-active #map,
body.dashboard-active #sidebar,
body.dashboard-active #mobile-header,
body.dashboard-active #map-controls,
body.dashboard-active #info-panel,
body.dashboard-active #context-menu,
body.dashboard-active .maplibregl-control-container {
  display: none !important;
  visibility: hidden !important;
}

body.dashboard-active {
  overflow: hidden;
  background: #0a0e14;
}

#dashboard-overlay {
  position: fixed;
  inset: 0;
  z-index: 99999;
  background: #0a0e14;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  overflow: hidden;
}

.dash-close-btn {
  position: absolute;
  top: 6px;
  right: 6px;
  z-index: 100002;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 1px solid var(--bg-tertiary);
  background: rgba(26,38,50,0.8);
  color: var(--text-primary);
  font-size: 1.1rem;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  touch-action: manipulation;
}
.dash-close-btn:hover { color: var(--danger); }

/* ===== Full-screen Navigation Overlay (map + rain radar + speed) ===== */
/* Like the speedo dash, hide everything else behind it. */
body.nav-active #map,
body.nav-active #sidebar,
body.nav-active #mobile-header,
body.nav-active #map-controls,
body.nav-active #info-panel,
body.nav-active #context-menu,
body.nav-active .maplibregl-control-container {
  display: none !important;
  visibility: hidden !important;
}
body.nav-active { overflow: hidden; background: #0a0e14; }

#nav-overlay {
  position: fixed;
  inset: 0;
  z-index: 99999;
  background: #0a0e14;
  overflow: hidden;
}

/* Clip the oversized, rotating map. */
#nav-map-wrap {
  position: absolute;
  inset: 0;
  overflow: hidden;
}
/* A square whose side (145vmax) exceeds any viewport's diagonal (≤ ~1.415·vmax),
   centred with negative margins so the `transform` property is free for the
   heading-up rotation JS applies. Being ≥ the diagonal, no corner gap ever
   shows however far it spins. */
#nav-map {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 145vmax;
  height: 145vmax;
  margin-left: -72.5vmax;
  margin-top: -72.5vmax;
  transform-origin: center center;
  /* No CSS transition: nav.js eases the rotation itself, frame by frame (see
     startHeadingLoop). A transition on top would restart every frame and lag. */
  background: #0a0e14;
  will-change: transform;
}
#nav-map .maplibregl-control-container { display: none !important; }

/* Rider chevron — always points up (direction of travel) via JS counter-rotation. */
.nav-rider { background: none !important; border: none !important; }
.nav-rider-chevron {
  width: 44px; height: 44px;
  display: flex; align-items: center; justify-content: center;
  /* eased in JS per frame (see startHeadingLoop) — no CSS transition */
}
.nav-rider-chevron i {
  font-size: 36px;
  color: #1a73e8;   /* Google-nav blue — a bold directional arrow, not a faint dot */
  /* fa-location-arrow's art points NE (45°); correct it to point straight up. */
  transform: rotate(-45deg);
  /* Heavy white outline OUTSIDE the blue so the arrow reads on the green line
     and any basemap (paint-order draws the stroke first, then the fill). */
  -webkit-text-stroke: 2.5px #fff;
  paint-order: stroke fill;
  filter: drop-shadow(0 1px 3px rgba(0,0,0,0.55));
}

/* Current speed + speed-limit sign — bottom-left corner. */
#nav-speed {
  position: absolute;
  left: calc(14px + env(safe-area-inset-left, 0px));
  bottom: calc(18px + env(safe-area-inset-bottom, 0px));
  z-index: 10;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 14px;
  background: rgba(10,14,20,0.72);
  border: 1px solid rgba(255,255,255,0.1);
  border-radius: 14px;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.nav-speed-read { display: flex; align-items: baseline; gap: 4px; }
#nav-speed-value {
  font-size: 4.2rem;
  font-weight: 800;
  line-height: 1;
  color: #fff;
  font-variant-numeric: tabular-nums;
  letter-spacing: -1.5px;
}
#nav-speed-unit { font-size: 0.9rem; font-weight: 600; color: var(--text-secondary); text-transform: uppercase; }

/* Speed-limit sign — a circular white disc with a red ring (NZ/EU style). */
#nav-speed-limit {
  flex: 0 0 auto;
  display: flex; align-items: center; justify-content: center;
  width: 54px; height: 54px;
  border-radius: 50%;
  background: #fff;
  border: 5px solid #d32f2f;
  box-shadow: 0 1px 5px rgba(0,0,0,0.55);
}
#nav-speed-limit-value {
  color: #111;
  font-weight: 800;
  font-size: 1.3rem;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.5px;
}

/* Next-turn banner — top. */
#nav-turn {
  position: absolute;
  top: calc(12px + env(safe-area-inset-top, 0px));
  left: 50%;
  transform: translateX(-50%);
  z-index: 10;
  display: flex;
  align-items: center;
  gap: 12px;
  max-width: min(88vw, 460px);
  padding: 10px 16px 10px 10px;
  background: rgba(10,14,20,0.82);
  border: 1px solid rgba(255,255,255,0.1);
  border-radius: 16px;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  box-shadow: 0 6px 24px rgba(0,0,0,0.4);
}
.nav-turn-icon {
  flex: 0 0 auto;
  width: 46px; height: 46px;
  border-radius: 12px;
  display: flex; align-items: center; justify-content: center;
  font-size: 1.5rem;
}
.nav-turn-icon.prox-far  { background: rgba(0,200,83,0.15);  color: #00c853; }
.nav-turn-icon.prox-mid  { background: rgba(255,193,7,0.2);  color: #ffc107; }
.nav-turn-icon.prox-near { background: rgba(255,82,82,0.22); color: #ff5252; }
.nav-turn-info { min-width: 0; }
#nav-turn-dist { font-size: 1.5rem; font-weight: 800; color: #fff; line-height: 1.05; }
#nav-turn-road {
  font-size: 0.9rem; color: var(--text-secondary);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* "Worth a Stop" heads-up — always SUBORDINATE to the turn banner: lower
   z-index and positioned below it, so an imminent turn instruction is never
   obscured or delayed by a POI alert. Tap target: the whole pill dismisses. */
#nav-poi {
  position: absolute;
  top: calc(92px + env(safe-area-inset-top, 0px)); /* clears #nav-turn (~78px at 46px icon) */
  left: 50%;
  transform: translateX(-50%);
  z-index: 9;
  display: flex;
  align-items: center;
  gap: 10px;
  max-width: min(84vw, 420px);
  padding: 10px 14px;
  background: rgba(22, 14, 34, 0.86);
  border: 1px solid rgba(126, 87, 194, 0.55);
  border-radius: 14px;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.4);
  cursor: pointer;
}
#nav-poi.hidden { display: none; }
/* Fixed camera warning — same geometry as #nav-poi so they stack cleanly, but
   red-edged and it owns the slot right under the turn banner. A "possible"
   camera is amber and visibly softer: it must never read as a confirmed one. */
#nav-camera {
  position: absolute;
  top: calc(92px + env(safe-area-inset-top, 0px)); /* the slot #nav-poi used */
  left: 50%;
  transform: translateX(-50%);
  z-index: 9;
  display: flex;
  align-items: center;
  gap: 10px;
  max-width: min(84vw, 420px);
  padding: 10px 14px;
  background: rgba(40, 12, 12, 0.9);
  border: 1px solid rgba(255, 82, 82, 0.75);
  border-radius: 14px;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.45);
}
#nav-camera.hidden { display: none; }
#nav-camera-icon { font-size: 1.5rem; color: #ff5252; flex-shrink: 0; width: 34px; text-align: center; }
#nav-camera-name {
  font-weight: 700; font-size: 0.95rem; color: #fff;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
#nav-camera-detail { font-size: 0.78rem; color: var(--text-secondary); }
#nav-camera.cam-possible {
  background: rgba(40, 30, 10, 0.88);
  border-color: rgba(255, 171, 64, 0.7);
}
#nav-camera.cam-possible #nav-camera-icon { color: #ffab40; }
/* Scenery yields to the camera warning rather than overlapping it. */
#nav-overlay.cam-visible #nav-poi { top: calc(166px + env(safe-area-inset-top, 0px)); }
/* Camera popup honesty lines (Layers.showCameraPopup) */
.cam-possible { color: #ffab40; font-size: 0.8rem; margin: 4px 0; }
.cam-note { color: var(--text-muted, #999); font-size: 0.72rem; margin-top: 6px; line-height: 1.35; }
#nav-poi-icon { font-size: 1.5rem; color: #b39ddb; flex-shrink: 0; width: 34px; text-align: center; }
.nav-poi-info { min-width: 0; }
#nav-poi-name {
  font-weight: 700; font-size: 0.95rem; color: #fff;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
#nav-poi-detail { font-size: 0.78rem; color: var(--text-secondary); }

/* Distance / ETA remaining — top-right. */
#nav-eta {
  position: absolute;
  top: calc(12px + env(safe-area-inset-top, 0px));
  right: calc(14px + env(safe-area-inset-right, 0px));
  z-index: 10;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 1px;
  padding: 7px 12px;
  background: rgba(10,14,20,0.72);
  border: 1px solid rgba(255,255,255,0.1);
  border-radius: 12px;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
#nav-eta-dist { font-size: 1.15rem; font-weight: 800; color: #fff; line-height: 1.1; }
#nav-eta-time { font-size: 0.8rem; font-weight: 600; color: var(--accent); }

/* Current time — the fullscreen display hides the OS status bar clock (2026-07-28). */
#nav-clock {
  position: absolute;
  top: calc(12px + env(safe-area-inset-top, 0px));
  right: calc(14px + env(safe-area-inset-right, 0px));
  z-index: 10;
  padding: 7px 12px;
  background: rgba(10,14,20,0.72);
  border: 1px solid rgba(255,255,255,0.1);
  border-radius: 12px;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  color: #fff;
  font-size: 0.95rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
/* Route active -> the ETA chip owns the corner; the clock tucks below it. */
#nav-eta:not(.hidden) ~ #nav-clock {
  top: calc(80px + env(safe-area-inset-top, 0px));
}

/* GPS elevation — bottom-right corner. */
#nav-elev {
  position: absolute;
  right: calc(14px + env(safe-area-inset-right, 0px));
  bottom: calc(18px + env(safe-area-inset-bottom, 0px));
  z-index: 10;
  display: flex;
  align-items: baseline;
  gap: 5px;
  padding: 7px 12px;
  background: rgba(10,14,20,0.72);
  border: 1px solid rgba(255,255,255,0.1);
  border-radius: 12px;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  color: #fff;
}
#nav-elev i { font-size: 0.85rem; color: var(--text-secondary); align-self: center; }
#nav-elev-value { font-size: 1.3rem; font-weight: 800; font-variant-numeric: tabular-nums; }
.nav-elev-unit { font-size: 0.8rem; font-weight: 600; color: var(--text-secondary); }

/* Compact in-nav 2D|3D pill — bottom-center. */
#nav-mode-switch {
  position: absolute;
  bottom: calc(18px + env(safe-area-inset-bottom, 0px));
  left: 50%;
  transform: translateX(-50%);
  z-index: 12;
  display: flex; gap: 3px; padding: 3px;
  background: rgba(10,14,20,0.72);
  border: 1px solid rgba(255,255,255,0.12);
  border-radius: 999px;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
#nav-mode-switch .mode-switch-btn {
  min-width: 52px;
  min-height: 40px;
  padding: 0 14px;
  font-size: 0.85rem;
  letter-spacing: 1px;
}

/* Nav basemap pill (Topo | Sat) — stacked just above the 2D|3D pill. */
#nav-base-switch {
  position: absolute;
  bottom: calc(70px + env(safe-area-inset-bottom, 0px));
  left: 50%;
  transform: translateX(-50%);
  z-index: 12;
  display: flex; gap: 3px; padding: 3px;
  background: rgba(10,14,20,0.72);
  border: 1px solid rgba(255,255,255,0.12);
  border-radius: 999px;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
#nav-base-switch .mode-switch-btn {
  min-width: 52px;
  min-height: 40px;
  padding: 0 14px;
  font-size: 0.85rem;
  letter-spacing: 1px;
}

/* Close — top-left. */
#nav-close {
  position: absolute;
  top: calc(12px + env(safe-area-inset-top, 0px));
  left: calc(12px + env(safe-area-inset-left, 0px));
  z-index: 11;
  width: 42px; height: 42px;
  border-radius: 50%;
  border: 1px solid rgba(255,255,255,0.12);
  background: rgba(10,14,20,0.72);
  color: #fff;
  font-size: 1.1rem;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  touch-action: manipulation;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
#nav-close:hover { color: var(--danger); }

/* NOTE: this block sits mid-file rather than at EOF for a historical
   reason worth keeping: an @media (max-width: 480px) below used to be
   unclosed, so anything appended at the end of this file only applied
   under 480px. That brace is closed now (see the note on it), so EOF is
   safe again — but leaving these here costs nothing and the position is
   still correct. */
/* ===== Granted-access expiry banner (js/auth.js _maybeGrantEndingNotice) =====
   Appended at EOF DELIBERATELY: this stylesheet is five concatenated copies of
   itself, so a rule placed anywhere earlier can be overridden by a later copy.
   Same trap as the nav pill fix above — see tasks/lessons.md.

   Sits above the bottom pills rather than centred on them, and slightly higher
   than #renewal-toast so the two can never stack on the same pixels. */
#grant-ending-note {
  position: fixed; bottom: 132px; left: 50%; transform: translateX(-50%);
  z-index: 2001; display: none; align-items: center; gap: 8px;
  background: #243342; color: #e8edf2; border: 1px solid rgba(255,255,255,0.12);
  border-radius: 8px; padding: 10px 14px; font-size: 0.8rem;
  max-width: min(440px, 92vw); box-shadow: 0 8px 30px rgba(0,0,0,0.5);
}
#grant-ending-note i { color: var(--accent, #00c853); flex: none; }
#grant-ending-note span { flex: 1 1 auto; }
#grant-ending-note a {
  color: var(--accent, #00c853); font-weight: 700; text-decoration: none; flex: none;
}
#grant-ending-note button {
  background: none; border: none; cursor: pointer; flex: none;
  color: var(--text-muted, #999); font-size: 1rem; padding: 0 2px; line-height: 1;
}
/* Last 48 hours only — an amber edge, not a red alarm. Nothing is broken and
   nobody is being charged; they are about to lose something they were given. */
#grant-ending-note.urgent {
  border-color: rgba(255, 167, 38, 0.55);
  background: #33291d;
}
#grant-ending-note.urgent i { color: #ffa726; }


/* Small screens — trim the outsized readouts so nothing collides. */
@media (max-width: 480px) {
  #nav-speed-value { font-size: 3.4rem; }
  #nav-speed-limit { width: 48px; height: 48px; border-width: 4px; }
  #nav-speed-limit-value { font-size: 1.15rem; }
  #nav-turn { top: calc(66px + env(safe-area-inset-top, 0px)); }
  /* keep the Worth a Stop pill below the relocated turn banner */
  #nav-poi { top: calc(146px + env(safe-area-inset-top, 0px)); }
#nav-overlay.cam-visible #nav-poi { top: calc(220px + env(safe-area-inset-top, 0px)); }
}
/* ^ THIS BRACE. Added 2026-08-02. Without it the @media (max-width: 480px)
   above ran to end-of-file, swallowing the last ~41% of this stylesheet (113KB)
   into a small-screen query. The effect was invisible on a phone and total on
   anything wider: the social login buttons, the AI route planner, the arrival
   cards, the location puck, the recording indicator and the cancel-intercept
   modal all rendered UNSTYLED above 480px.
   Checked before changing it — closing this alters ZERO existing declarations
   (the five concatenated copies of this file diverge by ADDING rules, not by
   conflicting); it only lets 95 already-written selectors start working. */

/* #nav-mode-switch and friends — ported from NZ with the GL nav */
/* ===== CSS Variables ===== */
:root {
  --bg-primary: #0f1923;
  --bg-secondary: #1a2632;
  --bg-tertiary: #243342;
  --bg-card: #1e2d3d;
  --text-primary: #e8edf2;
  --text-secondary: #8899aa;
  --text-muted: #5a6f82;
  --accent: #00c853;
  --accent-hover: #00e676;
  --accent-dim: rgba(0, 200, 83, 0.15);
  --danger: #ff5252;
  --warning: #ffab40;
  --info: #40c4ff;
  --spark-color: #ffe600;
  --vodafone-color: #e60000;
  --twodeg-color: #00aaff;
  --sidebar-width: 380px;
  --mobile-header-height: calc(56px + env(safe-area-inset-top, 0px)); /* fullscreen display: bar background reaches the true screen top; content pads below the camera cutout */
  --radius: 8px;
  --radius-sm: 4px;
  --shadow: 0 4px 24px rgba(0,0,0,0.4);
  --transition: 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}

/* ===== Reset ===== */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html, body { height: 100%; overflow: hidden; }
body {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  background: var(--bg-primary);
  color: var(--text-primary);
  -webkit-font-smoothing: antialiased;
}

/* ===== Login Screen ===== */
#login-screen {
  position: fixed; inset: 0;
  background: var(--bg-primary);
  display: flex; align-items: center; justify-content: center;
  z-index: 10001;
  transition: opacity 0.4s ease;
}
#login-screen.fade-out { opacity: 0; pointer-events: none; }
.login-card {
  display: flex; flex-direction: column; align-items: center;
  padding: 32px 28px;
  background: var(--bg-secondary);
  border-radius: 16px;
  border: 1px solid var(--border, rgba(255,255,255,0.06));
  width: min(360px, 90vw);
}
.login-input {
  width: 100%; padding: 10px 12px;
  border-radius: var(--radius-sm, 6px);
  border: 1px solid var(--border, rgba(255,255,255,0.1));
  background: var(--bg-tertiary); color: var(--text-primary);
  font-size: 0.88rem; font-family: inherit;
  margin-bottom: 8px; outline: none;
}
.login-input:focus { border-color: var(--accent); }
.login-error {
  font-size: 0.75rem; color: #ff5252;
  margin-bottom: 8px; display: none;
  text-align: center;
}
.login-btn {
  width: 100%; padding: 10px; font-size: 0.88rem;
  border-radius: var(--radius-sm, 6px);
  cursor: pointer; margin-bottom: 6px;
}
.login-google-btn {
  background: var(--bg-tertiary); color: var(--text-secondary);
  border: 1px solid var(--border, rgba(255,255,255,0.1));
}
.login-google-btn:hover { background: var(--bg-card); }

/* ===== Loading Screen ===== */
#loading-screen {
  position: fixed; inset: 0;
  background: var(--bg-primary);
  display: flex; align-items: center; justify-content: center;
  z-index: 10000;
  transition: opacity 0.5s ease;
}
#loading-screen.fade-out { opacity: 0; pointer-events: none; }
.loader-content { text-align: center; }
.loader-icon { font-size: 3rem; color: var(--accent); margin-bottom: 1rem; animation: pulse 1.5s infinite; }
.loader-content h2 { font-size: 1.5rem; font-weight: 700; margin-bottom: 0.5rem; }
.loader-content p { color: var(--text-secondary); margin-bottom: 1.5rem; }
.loader-bar { width: 200px; height: 3px; background: var(--bg-tertiary); border-radius: 3px; overflow: hidden; margin: 0 auto; }
.loader-progress { height: 100%; width: 30%; background: var(--accent); border-radius: 3px; animation: loading 1.5s ease-in-out infinite; }
@keyframes loading { 0% { transform: translateX(-100%); } 100% { transform: translateX(400%); } }
@keyframes pulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.1); } }

/* ===== Mobile Header ===== */
#mobile-header {
  display: none;
  position: fixed; top: 0; left: 0; right: 0;
  height: var(--mobile-header-height);
  background: var(--bg-secondary);
  border-bottom: 1px solid var(--bg-tertiary);
  align-items: center;
  justify-content: space-between;
  padding: env(safe-area-inset-top, 0px) 12px 0;
  z-index: 1001;
}
#mobile-header h1 { font-size: 1.1rem; font-weight: 700; }
#mobile-header button {
  background: none; border: none; color: var(--text-primary);
  font-size: 1.2rem; padding: 8px; cursor: pointer;
}

/* ===== Sidebar ===== */
.sidebar {
  position: fixed; top: 0; left: 0; bottom: 0;
  width: var(--sidebar-width);
  background: var(--bg-secondary);
  border-right: 1px solid var(--bg-tertiary);
  display: flex; flex-direction: column;
  z-index: 1000;
  transition: transform var(--transition);
  overflow: hidden;
}
.sidebar.collapsed { transform: translateX(-100%); }

/* Desktop sidebar collapse (onX-style). One body-level var override moves every
   --sidebar-width dependent (#map, #info-panel, #weather-timeline, 3D/basemap
   switches) at once. Desktop-only: mobile keeps the .open overlay pattern. */
@media (min-width: 769px) {
  body.sidebar-collapsed { --sidebar-width: 0px; }
  body.sidebar-collapsed .sidebar { transform: translateX(-100%); }
  /* Collapsed sidebar puts #info-panel at left:12px — the same corner the
     fixed #sidebar-expand (») button occupies — covering the site name.
     Shift the pane right to clear the 38px button + gaps. */
  body.sidebar-collapsed #info-panel { left: 62px; }
}
#sidebar-collapse {
  background: none; border: none; color: var(--text-secondary);
  font-size: 1rem; cursor: pointer; padding: 4px 8px;
}
#sidebar-collapse:hover { color: var(--text-primary); }
#sidebar-expand {
  position: fixed; top: 12px; left: 12px; z-index: 1001;
  width: 38px; height: 38px; border-radius: var(--radius-sm);
  background: var(--bg-secondary); border: 1px solid var(--bg-tertiary);
  color: var(--text-primary); font-size: 1rem; cursor: pointer;
  display: none; align-items: center; justify-content: center;
  box-shadow: 0 2px 10px rgba(0,0,0,0.4);
}
body.sidebar-collapsed #sidebar-expand { display: flex; }

.sidebar-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px 20px;
  border-bottom: 1px solid var(--bg-tertiary);
  flex-shrink: 0;
}
.brand { display: flex; align-items: center; gap: 10px; }
.brand i { font-size: 1.5rem; color: var(--accent); }
.brand h1 { font-size: 1.25rem; font-weight: 700; }
#sidebar-close {
  background: none; border: none; color: var(--text-secondary);
  font-size: 1.2rem; cursor: pointer; padding: 4px;
  display: none;
}

.sidebar-body {
  flex: 1; overflow-y: auto; overflow-x: hidden;
  padding: 0;
  scrollbar-width: thin;
  scrollbar-color: var(--bg-tertiary) transparent;
}
.sidebar-body::-webkit-scrollbar { width: 6px; }
.sidebar-body::-webkit-scrollbar-track { background: transparent; }
.sidebar-body::-webkit-scrollbar-thumb { background: var(--bg-tertiary); border-radius: 3px; }

.sidebar-footer {
  padding: 12px 20px;
  border-top: 1px solid var(--bg-tertiary);
  flex-shrink: 0;
}
.sidebar-footer p { font-size: 0.7rem; color: var(--text-muted); line-height: 1.5; }

/* ===== Tab Navigation ===== */
.tab-nav {
  display: flex;
  border-bottom: 1px solid var(--bg-tertiary);
  flex-shrink: 0;
}
.tab-btn {
  flex: 1;
  padding: 12px 8px;
  background: none; border: none;
  color: var(--text-secondary);
  font-size: 0.8rem; font-weight: 500;
  cursor: pointer;
  border-bottom: 2px solid transparent;
  transition: all var(--transition);
  display: flex; align-items: center; justify-content: center; gap: 6px;
}
.tab-btn:hover { color: var(--text-primary); background: var(--bg-tertiary); }
.tab-btn.active { color: var(--accent); border-bottom-color: var(--accent); }
.tab-btn i { font-size: 0.9rem; }

.tab-content { display: none; }
.tab-content.active { display: block; }

/* ===== Sidebar Sections ===== */
.sidebar-section {
  padding: 16px 20px;
  border-bottom: 1px solid rgba(255,255,255,0.04);
}
.sidebar-section h3 {
  font-size: 0.8rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--text-secondary);
  margin-bottom: 12px;
  display: flex; align-items: center; gap: 8px;
}
.sidebar-section h3 i { color: var(--accent); font-size: 0.85rem; }
.sidebar-section h4 {
  font-size: 0.78rem; font-weight: 600;
  color: var(--text-secondary);
  margin: 12px 0 8px;
}
.hint { font-size: 0.78rem; color: var(--text-muted); margin-bottom: 12px; line-height: 1.4; }

/* ===== Search ===== */
.search-box {
  display: flex; align-items: center;
  background: var(--bg-tertiary);
  border-radius: var(--radius);
  padding: 0 12px;
  border: 1px solid transparent;
  transition: border-color var(--transition);
}
.search-box:focus-within { border-color: var(--accent); }
.search-box i { color: var(--text-muted); font-size: 0.85rem; }
.search-box input {
  flex: 1; background: none; border: none; outline: none;
  color: var(--text-primary); padding: 10px 10px;
  font-size: 0.85rem; font-family: inherit;
}
.search-box input::placeholder { color: var(--text-muted); }
.search-box button { background: none; border: none; color: var(--text-muted); cursor: pointer; padding: 4px; }
.search-results {
  margin-top: 8px;
  background: var(--bg-tertiary);
  border-radius: var(--radius);
  max-height: 240px;
  overflow-y: auto;
}
.search-results.hidden { display: none; }
.search-result-item {
  padding: 10px 14px;
  cursor: pointer;
  font-size: 0.82rem;
  border-bottom: 1px solid rgba(255,255,255,0.04);
  transition: background var(--transition);
  display: flex; align-items: center; gap: 8px;
}
.search-result-item:hover { background: rgba(255,255,255,0.05); }
.search-result-item i { color: var(--accent); width: 16px; text-align: center; }
.search-result-item:last-child { border-bottom: none; }

/* ===== Layer Toggles ===== */
.layer-toggle {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 0;
  cursor: pointer;
  font-size: 0.85rem;
}
.layer-toggle input { display: none; }
.toggle-slider {
  width: 36px; height: 20px;
  background: var(--bg-tertiary);
  border-radius: 10px;
  position: relative;
  transition: background var(--transition);
  flex-shrink: 0;
}
.toggle-slider::after {
  content: '';
  position: absolute;
  width: 16px; height: 16px;
  background: var(--text-secondary);
  border-radius: 50%;
  top: 2px; left: 2px;
  transition: all var(--transition);
}
.layer-toggle input:checked + .toggle-slider { background: var(--accent-dim); }
.layer-toggle input:checked + .toggle-slider::after { transform: translateX(16px); background: var(--accent); }
.toggle-label { flex: 1; }

/* ===== Route vehicle picker (js/vehicle.js) ===== */
/* Ported from Motocamp USA, minus the towing row — NZ ships no towing modifier
   (it would change nothing about the route here; see js/vehicle.js). */
.route-vehicle {
  padding-bottom: 10px;
  margin-bottom: 4px;
  border-bottom: 1px solid var(--bg-tertiary);
}
.route-vehicle-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 6px; margin-bottom: 7px;
}
.route-vehicle-title {
  font-size: 0.72rem; font-weight: 600;
  color: var(--text-secondary);
  text-transform: uppercase; letter-spacing: 0.04em;
}
.route-vehicle-reset {
  background: none; border: none; padding: 0;
  color: var(--text-muted, #888);
  font-size: 0.66rem; cursor: pointer; text-decoration: underline;
}
.route-vehicle-reset:hover { color: var(--accent); }
.route-vehicle-reset[hidden] { display: none; }
.route-vehicle-picker {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 5px;
}
.route-vehicle-btn {
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  padding: 7px 3px;
  border: 1px solid var(--bg-tertiary);
  border-radius: 6px;
  background: transparent;
  color: var(--text-secondary);
  font-size: 0.62rem;
  cursor: pointer;
  transition: all var(--transition);
  min-width: 0;
}
.route-vehicle-btn i { font-size: 0.92rem; }
.route-vehicle-btn span { overflow-wrap: anywhere; text-align: center; line-height: 1.2; }
.route-vehicle-btn:hover { border-color: var(--text-muted, #888); color: var(--text-primary); }
.route-vehicle-btn[aria-pressed="true"] {
  border-color: var(--accent);
  background: var(--accent-dim);
  color: var(--text-primary);
}
.route-vehicle-btn[aria-pressed="true"] i { color: var(--accent); }
.route-vehicle-note {
  font-size: 0.66rem;
  color: var(--text-muted, #888);
  margin-top: 7px;
  line-height: 1.45;
}
.route-vehicle-note:empty { display: none; }
.route-vehicle-note .warn { color: #ffab40; }

.badge {
  font-size: 0.65rem; font-weight: 600;
  padding: 2px 6px; border-radius: 3px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}
.badge-green { background: rgba(0,200,83,0.15); color: #00c853; }
.badge-blue { background: rgba(64,196,255,0.15); color: #40c4ff; }
.badge-orange { background: rgba(255,171,64,0.15); color: #ffab40; }
.badge-purple { background: rgba(176,128,255,0.15); color: #b080ff; }
.badge-teal { background: rgba(38,198,178,0.15); color: #26c6b2; }
.badge-yellow { background: rgba(255,230,0,0.15); color: #ffe600; }
.badge-red { background: rgba(230,0,0,0.15); color: #ff5252; }

/* ===== Base Map Selector ===== */
/* Warm up CARTO Voyager's pale palette so the base map reads richer, not washed out */
.basemap-selector { display: flex; gap: 6px; }
.basemap-btn {
  flex: 1; padding: 8px;
  background: var(--bg-tertiary);
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  color: var(--text-secondary);
  font-size: 0.75rem; font-weight: 500;
  cursor: pointer;
  transition: all var(--transition);
  display: flex; flex-direction: column; align-items: center; gap: 4px;
}
.basemap-btn i { font-size: 1rem; }
.basemap-btn:hover { color: var(--text-primary); background: rgba(255,255,255,0.08); }
.basemap-btn.active { border-color: var(--accent); color: var(--accent); background: var(--accent-dim); }

/* ===== Filter Chips ===== */
.filter-group { display: flex; flex-wrap: wrap; gap: 6px; }
.filter-chip {
  display: flex; align-items: center; gap: 4px;
  padding: 6px 10px;
  background: var(--bg-tertiary);
  border-radius: 20px;
  font-size: 0.75rem;
  cursor: pointer;
  transition: all var(--transition);
  border: 1px solid transparent;
  user-select: none;
}
.filter-chip:hover { background: rgba(255,255,255,0.08); }
.filter-chip input { display: none; }
.filter-chip:has(input:checked) { border-color: var(--accent); background: var(--accent-dim); color: var(--accent); }
.filter-chip i { font-size: 0.7rem; }

/* ===== Route Planning ===== */
.route-inputs { display: flex; flex-direction: column; gap: 4px; }
.route-point {
  display: flex; align-items: center; gap: 10px;
  background: var(--bg-tertiary);
  border-radius: var(--radius-sm);
  padding: 0 12px;
}
.route-point input {
  flex: 1; background: none; border: none; outline: none;
  color: var(--text-primary); padding: 10px 0;
  font-size: 0.85rem; font-family: inherit;
}
.route-point input::placeholder { color: var(--text-muted); }
/* Route search results dropdown */
.route-search-results {
  position: absolute;
  left: 0; right: 0;
  z-index: 9999;
  margin-top: 2px;
  max-height: 200px;
  overflow-y: auto;
  box-shadow: 0 6px 20px rgba(0,0,0,0.4);
  border: 1px solid rgba(255,255,255,0.08);
}
/* Suggestions are positioned in JS (see _positionResults in js/route.js):
   fixed to the viewport but anchored to the input's real position, flipping
   above it when the phone keyboard leaves no room below. The old mobile rule
   pinned them to top:52px of the SCREEN — detached from the box being typed
   in, floating over the header ("the destination box broke out"). */
.route-search-results {
  position: fixed;
  z-index: 10000;
}
.route-start-icon { color: var(--accent); font-size: 0.6rem; }
.route-locate-btn {
  flex-shrink: 0;
  padding: 6px 8px;
  border: none;
  color: var(--accent);
  background: none;
  font-size: 1rem;
  cursor: pointer;
  opacity: 0.7;
  transition: opacity 0.2s;
}
.route-locate-btn:hover { opacity: 1; }
.route-locate-btn.locating { animation: pulse-locate 1s infinite; }
@keyframes pulse-locate { 0%, 100% { opacity: 0.4; } 50% { opacity: 1; } }
.route-end-icon { color: var(--danger); font-size: 0.85rem; }
.route-waypoint-icon { color: var(--info); font-size: 0.6rem; }

.route-actions { display: flex; gap: 8px; margin-top: 8px; }
.route-dates { margin-top: 4px; }
.date-inputs { display: flex; gap: 8px; }
.date-field { flex: 1; }
.date-field label { display: block; font-size: 0.72rem; color: var(--text-muted); margin-bottom: 4px; }
.date-field input {
  width: 100%; padding: 8px 10px;
  background: var(--bg-tertiary);
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  color: var(--text-primary);
  font-size: 0.82rem; font-family: inherit;
  outline: none;
}
.date-field input:focus { border-color: var(--accent); }

/* ===== Buttons ===== */
.btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 14px;
  background: var(--bg-tertiary);
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: var(--radius-sm);
  color: var(--text-secondary);
  font-size: 0.8rem; font-weight: 500;
  cursor: pointer;
  transition: all var(--transition);
  font-family: inherit;
}
.btn:hover { background: rgba(255,255,255,0.08); color: var(--text-primary); }
.btn-sm { padding: 6px 10px; font-size: 0.75rem; }
.btn-primary { background: var(--accent); color: #000; border-color: var(--accent); font-weight: 600; }
.btn-primary:hover { background: var(--accent-hover); color: #000; }
.btn-danger { border-color: rgba(255,82,82,0.3); color: var(--danger); }
.btn-danger:hover { background: rgba(255,82,82,0.1); }
.btn-block { width: 100%; justify-content: center; margin-top: 12px; }

/* ===== Weather Controls ===== */
.time-slider-container { padding: 4px 0; }
.time-slider-container input[type="range"] {
  width: 100%; -webkit-appearance: none; appearance: none;
  height: 4px; background: var(--bg-tertiary);
  border-radius: 2px; outline: none;
}
.time-slider-container input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 16px; height: 16px;
  background: var(--accent); border-radius: 50%;
  cursor: pointer;
}
.time-labels { display: flex; justify-content: space-between; margin-top: 4px; font-size: 0.7rem; color: var(--text-muted); }

/* ===== Map ===== */
#map {
  position: fixed;
  top: 0; bottom: 0;
  left: var(--sidebar-width);
  right: 0;
  z-index: 1;
}

/* ===== Map Controls ===== */
#map-controls {
  position: fixed;
  top: 16px; right: 16px;
  display: flex; flex-direction: column; gap: 8px;
  z-index: 500;
}
.map-btn {
  width: auto; height: auto;
  padding: 8px 10px;
  background: var(--bg-secondary);
  border: 1px solid var(--bg-tertiary);
  border-radius: var(--radius);
  color: var(--text-primary);
  font-size: 1rem;
  cursor: pointer;
  display: flex; align-items: center; gap: 6px;
  transition: all var(--transition);
  box-shadow: var(--shadow);
}
.map-btn-label {
  font-size: 0.65rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--text-secondary);
}
.map-btn:hover { background: var(--bg-tertiary); color: var(--accent); }
.map-btn:hover .map-btn-label { color: var(--accent); }
.map-btn.active { background: var(--accent); color: #fff; border-color: var(--accent); }
.map-btn.active .map-btn-label { color: #fff; }

/* ===== Weather Tile Overlays ===== */
.weather-tile-temperature { filter: saturate(2.5) contrast(1.8) brightness(1.1); }
.weather-tile-precipitation { filter: saturate(2.0) contrast(1.5); }
.weather-tile-clouds { filter: contrast(1.4) brightness(0.95); }
.weather-tile-wind { filter: saturate(1.8) contrast(1.4); }

/* ===== Weather Timeline ===== */
/* ===== Info Panel =====
   Vertical side-loading pane (onX-style), 2026-07-27. Was a bottom-anchored
   horizontal strip eating 50vh; now a left card over the map. Mobile keeps the
   bottom-sheet geometry (overridden in the 768px block below). */
#info-panel {
  position: fixed;
  top: 12px; bottom: 12px;
  left: calc(var(--sidebar-width) + 12px);
  width: 380px;
  max-width: calc(100vw - var(--sidebar-width) - 24px);
  background: var(--bg-secondary);
  border: 1px solid var(--bg-tertiary);
  border-radius: var(--radius);
  z-index: 600;
  overflow-y: auto;
  box-shadow: 0 8px 30px rgba(0,0,0,0.45);
  transition: transform var(--transition), opacity var(--transition);
}
#info-panel.hidden {
  transform: translateX(calc(-100% - 420px));
  opacity: 0;
  pointer-events: none;
}
#info-close {
  position: sticky; top: 0; right: 0;
  float: right; margin: 12px 12px 0 0;
  background: var(--bg-tertiary); border: none;
  z-index: 10;
  color: var(--text-secondary); width: 32px; height: 32px;
  border-radius: 50%; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  font-size: 0.9rem;
}
#info-content { padding: 20px 24px 24px; }

/* Info Panel Content */
.info-header { margin-bottom: 16px; }
.info-header h2 { font-size: 1.15rem; font-weight: 700; margin-bottom: 4px; }
.info-header .info-type { font-size: 0.78rem; color: var(--accent); font-weight: 500; text-transform: uppercase; letter-spacing: 0.03em; }
.info-header .info-status { font-size: 0.75rem; padding: 2px 8px; border-radius: 3px; margin-left: 8px; }
.info-header .info-status.open { background: rgba(0,200,83,0.15); color: #00c853; }
.info-header .info-status.closed { background: rgba(255,82,82,0.15); color: #ff5252; }

.info-facilities {
  display: flex; flex-wrap: wrap; gap: 8px;
  margin-bottom: 16px;
}
.facility-badge {
  display: flex; align-items: center; gap: 5px;
  padding: 6px 10px;
  background: var(--bg-tertiary);
  border-radius: var(--radius-sm);
  font-size: 0.75rem;
  color: var(--text-secondary);
}
.facility-badge.available { color: var(--accent); background: var(--accent-dim); }
.facility-badge i { font-size: 0.8rem; }

.info-details { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 16px; }
.info-detail { }
.info-detail-label { font-size: 0.7rem; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.03em; margin-bottom: 2px; }
.info-detail-value { font-size: 0.85rem; color: var(--text-primary); }

.info-weather {
  background: var(--bg-tertiary);
  border-radius: var(--radius);
  padding: 14px;
  margin-bottom: 16px;
}
.info-weather h4 { font-size: 0.78rem; color: var(--text-secondary); margin-bottom: 8px; }
.weather-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(80px, 1fr)); gap: 8px;
}
.weather-item { text-align: center; }
.weather-item .wx-icon { font-size: 1.3rem; margin-bottom: 2px; }
.weather-item .wx-temp { font-size: 1rem; font-weight: 600; }
.weather-item .wx-desc { font-size: 0.68rem; color: var(--text-muted); }
.weather-item .wx-day { font-size: 0.68rem; color: var(--text-secondary); font-weight: 500; }

.info-cell-coverage { margin-bottom: 16px; }
.cell-bar-container { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
.cell-carrier { font-size: 0.78rem; width: 70px; color: var(--text-secondary); }
.cell-bar { flex: 1; height: 6px; background: var(--bg-tertiary); border-radius: 3px; overflow: hidden; }
.cell-bar-fill { height: 100%; border-radius: 3px; transition: width 0.5s ease; }
.cell-bar-fill.spark { background: var(--spark-color); }
.cell-bar-fill.vodafone { background: var(--vodafone-color); }
.cell-bar-fill.twodeg { background: var(--twodeg-color); }
.cell-tech { font-size: 0.68rem; color: var(--text-muted); width: 30px; }

.info-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.info-actions .btn i { font-size: 0.8rem; }

/* ===== Pane card components (onX card anatomy, shared by trail/land/hazard/
   waypoint cards and reusable by any info-panel content) ===== */
.pane-tiles { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-bottom: 14px; }
.pane-tile { background: var(--bg-tertiary); border-radius: var(--radius-sm); padding: 8px 10px; }
.pane-tile.wide { grid-column: 1 / -1; }
.pane-tile .pt-label { font-size: 0.68rem; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.03em; }
.pane-tile .pt-value { font-size: 0.95rem; font-weight: 700; margin-top: 2px; }
.pane-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px; }
.pane-chip { border: 1px solid var(--bg-tertiary); background: var(--bg-tertiary); border-radius: 999px; padding: 3px 10px; font-size: 0.72rem; color: var(--text-secondary); }
.pane-chip.ok { border-color: var(--accent); color: var(--accent); background: none; }
.pane-chip.warn { border-color: #f59e0b; color: #f59e0b; background: none; }
.pane-chip.bad { border-color: #ff5252; color: #ff5252; background: none; }
.pane-kv { border-top: 1px solid var(--bg-tertiary); padding: 8px 2px; display: flex; gap: 8px; font-size: 0.82rem; }
.pane-kv .k { color: var(--text-muted); min-width: 110px; flex-shrink: 0; }
.pane-kv .v { font-weight: 600; }
.pane-actions { display: flex; gap: 12px; justify-content: space-around; border-top: 1px solid var(--bg-tertiary); padding: 12px 4px 2px; margin-top: 12px; }
.pane-action { background: none; border: none; color: var(--text-secondary); cursor: pointer; display: flex; flex-direction: column; align-items: center; gap: 5px; font-size: 0.7rem; }
.pane-action .pa-ico { width: 42px; height: 42px; border-radius: 50%; display: flex; align-items: center; justify-content: center; background: var(--bg-tertiary); border: 1px solid var(--bg-tertiary); font-size: 1rem; color: var(--text-primary); }
.pane-action.primary .pa-ico { background: var(--accent); color: #00120a; }
.pane-action:hover .pa-ico { border-color: var(--accent); }
.diff-pill { display: inline-block; border-radius: 5px; padding: 2px 10px; font-weight: 700; font-size: 0.78rem; color: #08131c; }
.pane-note { color: var(--text-muted); font-size: 0.72rem; margin-top: 10px; line-height: 1.45; }

/* Waypoints */
.wp-icon-grid { display: grid; grid-template-columns: repeat(6, 1fr); gap: 6px; margin: 8px 0; }
.wp-icon-grid button { font-size: 1.05rem; padding: 8px 0; border-radius: var(--radius-sm); border: 2px solid var(--bg-tertiary); background: var(--bg-tertiary); cursor: pointer; }
.wp-icon-grid button.sel { border-color: var(--accent); }
.wp-color-row { display: flex; gap: 8px; margin: 8px 0; }
.wp-color-row button { width: 26px; height: 26px; border-radius: 50%; cursor: pointer; border: 2px solid transparent; }
.wp-color-row button.sel { border-color: #fff; }
.wp-marker { width: 30px; height: 30px; border-radius: 50% 50% 50% 0; transform: rotate(-45deg); display: flex; align-items: center; justify-content: center; border: 2px solid #fff; box-shadow: 0 2px 6px rgba(0,0,0,0.5); cursor: pointer; }
.wp-marker span { transform: rotate(45deg); font-size: 13px; }
.wp-list-item { display: flex; align-items: center; gap: 10px; padding: 8px 4px; border-bottom: 1px solid var(--bg-tertiary); cursor: pointer; border-radius: var(--radius-sm); }
.wp-list-item:hover { background: var(--bg-tertiary); }
.wp-list-dot { width: 28px; height: 28px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 0.85rem; flex-shrink: 0; }

/* Trail overlay legend lines (rendered inside the sidebar section) */
.trail-legend-line { display: flex; align-items: center; gap: 10px; padding: 3px 0; font-size: 0.75rem; color: var(--text-secondary); }
.trail-legend-swatch { width: 30px; height: 5px; border-radius: 3px; flex-shrink: 0; }

/* ===== Route Summary Styles ===== */
.route-overview {
  display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 8px;
  margin-bottom: 16px;
}
.route-stat {
  text-align: center;
  padding: 10px;
  background: var(--bg-tertiary);
  border-radius: var(--radius-sm);
}
.route-stat-value { font-size: 1.2rem; font-weight: 700; color: var(--accent); }
.route-stat-label { font-size: 0.68rem; color: var(--text-muted); margin-top: 2px; }

.route-segment {
  padding: 12px 0;
  border-bottom: 1px solid rgba(255,255,255,0.04);
}
.route-segment:last-child { border-bottom: none; }
.route-segment-header {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 6px;
}
.route-segment-header h4 { font-size: 0.85rem; font-weight: 600; }
.route-segment-header span { font-size: 0.75rem; color: var(--text-muted); }
.route-segment-weather {
  display: flex; gap: 12px;
  margin-bottom: 6px;
}
.route-segment-weather .wx-mini {
  display: flex; align-items: center; gap: 4px;
  font-size: 0.78rem; color: var(--text-secondary);
}
.route-segment-services { display: flex; flex-wrap: wrap; gap: 4px; }
.route-segment-services .service-tag {
  font-size: 0.68rem;
  padding: 2px 6px;
  background: var(--bg-tertiary);
  border-radius: 3px;
  color: var(--text-muted);
}
.route-segment-services .service-tag.available { color: var(--accent); background: var(--accent-dim); }

/* ===== Elevation Profile ===== */
.elevation-profile {
  margin-bottom: 14px;
  padding-bottom: 12px;
  border-bottom: 1px solid rgba(255,255,255,0.04);
}
.elevation-stats {
  display: flex; gap: 12px;
  margin-bottom: 8px;
  font-size: 0.75rem;
  color: var(--text-secondary);
}
.elevation-stats span {
  display: flex; align-items: center; gap: 4px;
}
.elevation-chart-wrap {
  position: relative;
  background: var(--bg-tertiary);
  border-radius: var(--radius-sm);
  padding: 4px;
  cursor: crosshair;
}
.elevation-chart-wrap canvas {
  display: block;
  width: 100%;
}
.elevation-tooltip {
  position: absolute;
  background: var(--bg-secondary);
  border: 1px solid var(--bg-tertiary);
  border-radius: var(--radius-sm);
  padding: 4px 8px;
  font-size: 0.72rem;
  color: var(--text-primary);
  pointer-events: none;
  white-space: nowrap;
  z-index: 10;
  box-shadow: var(--shadow);
  line-height: 1.3;
}
.elevation-map-tooltip {
  background: var(--bg-secondary) !important;
  border: 1px solid var(--accent) !important;
  color: var(--text-primary) !important;
  font-size: 0.75rem !important;
  font-weight: 600 !important;
  padding: 2px 6px !important;
  border-radius: 4px !important;
  box-shadow: var(--shadow) !important;
}
.elevation-map-tooltip::before {
  border-top-color: var(--accent) !important;
}

/* ===== Weather Overlay Legend ===== */
.weather-legend-bar {
  display: flex; height: 12px;
  border-radius: 6px; overflow: hidden;
  margin-bottom: 4px;
}
.weather-legend-labels { display: flex; justify-content: space-between; font-size: 0.68rem; color: var(--text-muted); }

/* ===== MapLibre GL Overrides ===== */
.maplibregl-ctrl-attrib { font-size: 0.6rem !important; background: rgba(15,25,35,0.8) !important; color: var(--text-muted) !important; }
.maplibregl-ctrl-attrib a { color: var(--text-secondary) !important; }
.maplibregl-popup-content {
  background: var(--bg-secondary) !important;
  color: var(--text-primary) !important;
  border-radius: var(--radius) !important;
  box-shadow: var(--shadow) !important;
  border: 1px solid var(--bg-tertiary) !important;
  padding: 12px 14px !important;
  font-family: 'Inter', sans-serif !important;
}
/* The popup tip is a CSS border triangle — theme every anchor direction */
.maplibregl-popup-anchor-bottom .maplibregl-popup-tip { border-top-color: var(--bg-secondary) !important; }
.maplibregl-popup-anchor-top .maplibregl-popup-tip { border-bottom-color: var(--bg-secondary) !important; }
.maplibregl-popup-anchor-left .maplibregl-popup-tip { border-right-color: var(--bg-secondary) !important; }
.maplibregl-popup-anchor-right .maplibregl-popup-tip { border-left-color: var(--bg-secondary) !important; }
.maplibregl-popup-close-button { color: var(--text-secondary) !important; font-size: 20px !important; right: 4px !important; top: 2px !important; }
/* Cluster count styling is data-driven GL symbol paint now (Utils.clusterColors) — no DOM cluster CSS. */

/* Custom marker styles */
.custom-marker {
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%;
  /* Tight shadow: large blur radii multiply paint cost across hundreds of
     markers when a dense area re-renders after a zoom */
  box-shadow: 0 1px 3px rgba(0,0,0,0.5);
  font-size: 14px;
  transition: transform 0.2s ease;
}
.custom-marker:hover { transform: scale(1.2); }

/* Home base pin — a green house badge on the main map at the saved home. */
.home-map-marker {
  display: flex; align-items: center; justify-content: center;
  width: 30px; height: 30px;
  border-radius: 50%;
  background: var(--accent);
  border: 2px solid #fff;
  box-shadow: 0 1px 4px rgba(0,0,0,0.5);
  color: #fff;
  font-size: 14px;
  transition: transform 0.15s ease;
}
.home-map-marker:hover { transform: scale(1.15); }
/* (retired .marker-* divIcon classes removed — markers now draw on canvas via Utils.dotMarker; palette lives in Utils.markerStyles) */

/* ===== Responsive ===== */
@media (max-width: 768px) {
  #mobile-header { display: flex; }
  #sidebar-close { display: block; }

  .sidebar {
    width: 100%;
    transform: translateX(-100%);
    top: 0;
  }
  .sidebar.open { transform: translateX(0); }
  .sidebar-header { padding-top: calc(var(--mobile-header-height) + 8px); }

  #map {
    left: 0;
    top: var(--mobile-header-height);
  }

  #map-controls {
    top: calc(var(--mobile-header-height) + 12px);
    right: 12px;
  }

#info-panel {
    top: auto; bottom: 0; left: 0; right: 0;
    width: 100%; max-width: 100%;
    max-height: 60vh;
    border: none; border-top: 1px solid var(--bg-tertiary);
    border-radius: var(--radius) var(--radius) 0 0;
  }
  #info-panel.hidden { transform: translateY(100%); }
  #sidebar-collapse, #sidebar-expand { display: none !important; }

  .info-details { grid-template-columns: 1fr; }
  .route-overview { grid-template-columns: 1fr 1fr; }

  /* Inputs must be ≥16px to prevent iOS Safari from zooming on focus */
  .route-point input,
  .search-box input,
  .date-field input {
    font-size: 1rem;
  }
}

/* In landscape on mobile: compact the sidebar so content fits above the keyboard */
@media (max-width: 768px) and (orientation: landscape) {
  .sidebar-header { padding-top: calc(var(--mobile-header-height) + 4px); padding-bottom: 6px; }
  .sidebar-section { padding: 10px 16px; }
  .sidebar-section h3 { margin-bottom: 8px; }
  .tab-btn { padding: 8px 4px; }
}

@media (max-width: 480px) {
  .tab-btn { font-size: 0.72rem; padding: 10px 4px; }
  .basemap-selector { flex-direction: column; }
  .weather-grid { grid-template-columns: repeat(3, 1fr); }
}

/* ===== Context Menu ===== */
#context-menu {
  position: fixed;
  background: var(--bg-secondary);
  border: 1px solid var(--bg-tertiary);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  z-index: 2000;
  min-width: 200px;
  padding: 4px 0;
  overflow: hidden;
}
.ctx-item {
  padding: 10px 16px;
  font-size: 0.82rem;
  cursor: pointer;
  display: flex; align-items: center; gap: 10px;
  transition: background 0.15s;
  color: var(--text-primary);
}
.ctx-item:hover { background: rgba(255,255,255,0.06); }
.ctx-item i { color: var(--accent); width: 16px; text-align: center; font-size: 0.85rem; }
.ctx-divider { height: 1px; background: var(--bg-tertiary); margin: 4px 0; }

/* ===== Ride Dashboard ===== */

/* When dashboard is open, hide EVERYTHING else */
body.dashboard-active #map,
body.dashboard-active #sidebar,
body.dashboard-active #mobile-header,
body.dashboard-active #map-controls,
body.dashboard-active #info-panel,
body.dashboard-active #context-menu,
body.dashboard-active .maplibregl-control-container {
  display: none !important;
  visibility: hidden !important;
}

body.dashboard-active {
  overflow: hidden;
  background: #0a0e14;
}

#dashboard-overlay {
  position: fixed;
  inset: 0;
  z-index: 99999;
  background: #0a0e14;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  overflow: hidden;
}

.dash-close-btn {
  position: absolute;
  top: 6px;
  right: 6px;
  z-index: 100002;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 1px solid var(--bg-tertiary);
  background: rgba(26,38,50,0.8);
  color: var(--text-primary);
  font-size: 1.1rem;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  touch-action: manipulation;
}
.dash-close-btn:hover { color: var(--danger); }

/* ===== Full-screen Navigation Overlay (map + rain radar + speed) ===== */
/* Like the speedo dash, hide everything else behind it. */
body.nav-active #map,
body.nav-active #sidebar,
body.nav-active #mobile-header,
body.nav-active #map-controls,
body.nav-active #info-panel,
body.nav-active #context-menu,
body.nav-active .maplibregl-control-container {
  display: none !important;
  visibility: hidden !important;
}
body.nav-active { overflow: hidden; background: #0a0e14; }

#nav-overlay {
  position: fixed;
  inset: 0;
  z-index: 99999;
  background: #0a0e14;
  overflow: hidden;
}

/* Clip the oversized, rotating map. */
#nav-map-wrap {
  position: absolute;
  inset: 0;
  overflow: hidden;
}
/* A square whose side (145vmax) exceeds any viewport's diagonal (≤ ~1.415·vmax),
   centred with negative margins so the `transform` property is free for the
   heading-up rotation JS applies. Being ≥ the diagonal, no corner gap ever
   shows however far it spins. */
#nav-map {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 145vmax;
  height: 145vmax;
  margin-left: -72.5vmax;
  margin-top: -72.5vmax;
  transform-origin: center center;
  /* No CSS transition: nav.js eases the rotation itself, frame by frame (see
     startHeadingLoop). A transition on top would restart every frame and lag. */
  background: #0a0e14;
  will-change: transform;
}
#nav-map .maplibregl-control-container { display: none !important; }

/* Rider chevron — always points up (direction of travel) via JS counter-rotation. */
.nav-rider { background: none !important; border: none !important; }
.nav-rider-chevron {
  width: 44px; height: 44px;
  display: flex; align-items: center; justify-content: center;
  /* eased in JS per frame (see startHeadingLoop) — no CSS transition */
}
.nav-rider-chevron i {
  font-size: 36px;
  color: #1a73e8;   /* Google-nav blue — a bold directional arrow, not a faint dot */
  /* fa-location-arrow's art points NE (45°); correct it to point straight up. */
  transform: rotate(-45deg);
  /* Heavy white outline OUTSIDE the blue so the arrow reads on the green line
     and any basemap (paint-order draws the stroke first, then the fill). */
  -webkit-text-stroke: 2.5px #fff;
  paint-order: stroke fill;
  filter: drop-shadow(0 1px 3px rgba(0,0,0,0.55));
}

/* Current speed + speed-limit sign — bottom-left corner. */
#nav-speed {
  position: absolute;
  left: calc(14px + env(safe-area-inset-left, 0px));
  bottom: calc(18px + env(safe-area-inset-bottom, 0px));
  z-index: 10;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 14px;
  background: rgba(10,14,20,0.72);
  border: 1px solid rgba(255,255,255,0.1);
  border-radius: 14px;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.nav-speed-read { display: flex; align-items: baseline; gap: 4px; }
#nav-speed-value {
  font-size: 4.2rem;
  font-weight: 800;
  line-height: 1;
  color: #fff;
  font-variant-numeric: tabular-nums;
  letter-spacing: -1.5px;
}
#nav-speed-unit { font-size: 0.9rem; font-weight: 600; color: var(--text-secondary); text-transform: uppercase; }

/* Speed-limit sign — a circular white disc with a red ring (NZ/EU style). */
#nav-speed-limit {
  flex: 0 0 auto;
  display: flex; align-items: center; justify-content: center;
  width: 54px; height: 54px;
  border-radius: 50%;
  background: #fff;
  border: 5px solid #d32f2f;
  box-shadow: 0 1px 5px rgba(0,0,0,0.55);
}
#nav-speed-limit-value {
  color: #111;
  font-weight: 800;
  font-size: 1.3rem;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.5px;
}

/* Next-turn banner — top. */
#nav-turn {
  position: absolute;
  top: calc(12px + env(safe-area-inset-top, 0px));
  left: 50%;
  transform: translateX(-50%);
  z-index: 10;
  display: flex;
  align-items: center;
  gap: 12px;
  max-width: min(88vw, 460px);
  padding: 10px 16px 10px 10px;
  background: rgba(10,14,20,0.82);
  border: 1px solid rgba(255,255,255,0.1);
  border-radius: 16px;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  box-shadow: 0 6px 24px rgba(0,0,0,0.4);
}
.nav-turn-icon {
  flex: 0 0 auto;
  width: 46px; height: 46px;
  border-radius: 12px;
  display: flex; align-items: center; justify-content: center;
  font-size: 1.5rem;
}
.nav-turn-icon.prox-far  { background: rgba(0,200,83,0.15);  color: #00c853; }
.nav-turn-icon.prox-mid  { background: rgba(255,193,7,0.2);  color: #ffc107; }
.nav-turn-icon.prox-near { background: rgba(255,82,82,0.22); color: #ff5252; }
.nav-turn-info { min-width: 0; }
#nav-turn-dist { font-size: 1.5rem; font-weight: 800; color: #fff; line-height: 1.05; }
#nav-turn-road {
  font-size: 0.9rem; color: var(--text-secondary);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* "Worth a Stop" heads-up — always SUBORDINATE to the turn banner: lower
   z-index and positioned below it, so an imminent turn instruction is never
   obscured or delayed by a POI alert. Tap target: the whole pill dismisses. */
#nav-poi {
  position: absolute;
  top: calc(92px + env(safe-area-inset-top, 0px)); /* clears #nav-turn (~78px at 46px icon) */
  left: 50%;
  transform: translateX(-50%);
  z-index: 9;
  display: flex;
  align-items: center;
  gap: 10px;
  max-width: min(84vw, 420px);
  padding: 10px 14px;
  background: rgba(22, 14, 34, 0.86);
  border: 1px solid rgba(126, 87, 194, 0.55);
  border-radius: 14px;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.4);
  cursor: pointer;
}
#nav-poi.hidden { display: none; }

/* Fixed camera warning — same geometry as #nav-poi so they stack cleanly, but
   red-edged and it owns the slot right under the turn banner. A "possible"
   camera is amber and visibly softer: it must never read as a confirmed one. */
#nav-camera {
  position: absolute;
  top: calc(92px + env(safe-area-inset-top, 0px)); /* the slot #nav-poi used */
  left: 50%;
  transform: translateX(-50%);
  z-index: 9;
  display: flex;
  align-items: center;
  gap: 10px;
  max-width: min(84vw, 420px);
  padding: 10px 14px;
  background: rgba(40, 12, 12, 0.9);
  border: 1px solid rgba(255, 82, 82, 0.75);
  border-radius: 14px;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.45);
}
#nav-camera.hidden { display: none; }
#nav-camera-icon { font-size: 1.5rem; color: #ff5252; flex-shrink: 0; width: 34px; text-align: center; }
#nav-camera-name {
  font-weight: 700; font-size: 0.95rem; color: #fff;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
#nav-camera-detail { font-size: 0.78rem; color: var(--text-secondary); }
#nav-camera.cam-possible {
  background: rgba(40, 30, 10, 0.88);
  border-color: rgba(255, 171, 64, 0.7);
}
#nav-camera.cam-possible #nav-camera-icon { color: #ffab40; }
/* Scenery yields to the camera warning rather than overlapping it. */
#nav-overlay.cam-visible #nav-poi { top: calc(166px + env(safe-area-inset-top, 0px)); }

/* Camera popup honesty lines (Layers.showCameraPopup) */
.cam-possible { color: #ffab40; font-size: 0.8rem; margin: 4px 0; }
.cam-note { color: var(--text-muted, #999); font-size: 0.72rem; margin-top: 6px; line-height: 1.35; }
#nav-poi-icon { font-size: 1.5rem; color: #b39ddb; flex-shrink: 0; width: 34px; text-align: center; }
.nav-poi-info { min-width: 0; }
#nav-poi-name {
  font-weight: 700; font-size: 0.95rem; color: #fff;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
#nav-poi-detail { font-size: 0.78rem; color: var(--text-secondary); }

/* Distance / ETA remaining — top-right. */
#nav-eta {
  position: absolute;
  top: calc(12px + env(safe-area-inset-top, 0px));
  right: calc(14px + env(safe-area-inset-right, 0px));
  z-index: 10;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 1px;
  padding: 7px 12px;
  background: rgba(10,14,20,0.72);
  border: 1px solid rgba(255,255,255,0.1);
  border-radius: 12px;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
#nav-eta-dist { font-size: 1.15rem; font-weight: 800; color: #fff; line-height: 1.1; }
#nav-eta-time { font-size: 0.8rem; font-weight: 600; color: var(--accent); }

/* Current time — the fullscreen display hides the OS status bar clock (2026-07-28). */
#nav-clock {
  position: absolute;
  top: calc(12px + env(safe-area-inset-top, 0px));
  right: calc(14px + env(safe-area-inset-right, 0px));
  z-index: 10;
  padding: 7px 12px;
  background: rgba(10,14,20,0.72);
  border: 1px solid rgba(255,255,255,0.1);
  border-radius: 12px;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  color: #fff;
  font-size: 0.95rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
/* Route active -> the ETA chip owns the corner; the clock tucks below it. */
#nav-eta:not(.hidden) ~ #nav-clock {
  top: calc(80px + env(safe-area-inset-top, 0px));
}

/* GPS elevation — bottom-right corner. */
#nav-elev {
  position: absolute;
  right: calc(14px + env(safe-area-inset-right, 0px));
  bottom: calc(18px + env(safe-area-inset-bottom, 0px));
  z-index: 10;
  display: flex;
  align-items: baseline;
  gap: 5px;
  padding: 7px 12px;
  background: rgba(10,14,20,0.72);
  border: 1px solid rgba(255,255,255,0.1);
  border-radius: 12px;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  color: #fff;
}
#nav-elev i { font-size: 0.85rem; color: var(--text-secondary); align-self: center; }
#nav-elev-value { font-size: 1.3rem; font-weight: 800; font-variant-numeric: tabular-nums; }
.nav-elev-unit { font-size: 0.8rem; font-weight: 600; color: var(--text-secondary); }

/* Compact in-nav 2D|3D pill — bottom-center. */
#nav-mode-switch {
  position: absolute;
  bottom: calc(18px + env(safe-area-inset-bottom, 0px));
  left: 50%;
  transform: translateX(-50%);
  z-index: 12;
  display: flex; gap: 3px; padding: 3px;
  background: rgba(10,14,20,0.72);
  border: 1px solid rgba(255,255,255,0.12);
  border-radius: 999px;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
#nav-mode-switch .mode-switch-btn {
  min-width: 52px;
  min-height: 40px;
  padding: 0 14px;
  font-size: 0.85rem;
  letter-spacing: 1px;
}

/* #nav-base-switch and friends — ported from NZ with the GL nav */
/* ===== CSS Variables ===== */
:root {
  --bg-primary: #0f1923;
  --bg-secondary: #1a2632;
  --bg-tertiary: #243342;
  --bg-card: #1e2d3d;
  --text-primary: #e8edf2;
  --text-secondary: #8899aa;
  --text-muted: #5a6f82;
  --accent: #00c853;
  --accent-hover: #00e676;
  --accent-dim: rgba(0, 200, 83, 0.15);
  --danger: #ff5252;
  --warning: #ffab40;
  --info: #40c4ff;
  --spark-color: #ffe600;
  --vodafone-color: #e60000;
  --twodeg-color: #00aaff;
  --sidebar-width: 380px;
  --mobile-header-height: calc(56px + env(safe-area-inset-top, 0px)); /* fullscreen display: bar background reaches the true screen top; content pads below the camera cutout */
  --radius: 8px;
  --radius-sm: 4px;
  --shadow: 0 4px 24px rgba(0,0,0,0.4);
  --transition: 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}

/* ===== Reset ===== */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html, body { height: 100%; overflow: hidden; }
body {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  background: var(--bg-primary);
  color: var(--text-primary);
  -webkit-font-smoothing: antialiased;
}

/* ===== Login Screen ===== */
#login-screen {
  position: fixed; inset: 0;
  background: var(--bg-primary);
  display: flex; align-items: center; justify-content: center;
  z-index: 10001;
  transition: opacity 0.4s ease;
}
#login-screen.fade-out { opacity: 0; pointer-events: none; }
.login-card {
  display: flex; flex-direction: column; align-items: center;
  padding: 32px 28px;
  background: var(--bg-secondary);
  border-radius: 16px;
  border: 1px solid var(--border, rgba(255,255,255,0.06));
  width: min(360px, 90vw);
}
.login-input {
  width: 100%; padding: 10px 12px;
  border-radius: var(--radius-sm, 6px);
  border: 1px solid var(--border, rgba(255,255,255,0.1));
  background: var(--bg-tertiary); color: var(--text-primary);
  font-size: 0.88rem; font-family: inherit;
  margin-bottom: 8px; outline: none;
}
.login-input:focus { border-color: var(--accent); }
.login-error {
  font-size: 0.75rem; color: #ff5252;
  margin-bottom: 8px; display: none;
  text-align: center;
}
.login-btn {
  width: 100%; padding: 10px; font-size: 0.88rem;
  border-radius: var(--radius-sm, 6px);
  cursor: pointer; margin-bottom: 6px;
}
.login-google-btn {
  background: var(--bg-tertiary); color: var(--text-secondary);
  border: 1px solid var(--border, rgba(255,255,255,0.1));
}
.login-google-btn:hover { background: var(--bg-card); }

/* ===== Loading Screen ===== */
#loading-screen {
  position: fixed; inset: 0;
  background: var(--bg-primary);
  display: flex; align-items: center; justify-content: center;
  z-index: 10000;
  transition: opacity 0.5s ease;
}
#loading-screen.fade-out { opacity: 0; pointer-events: none; }
.loader-content { text-align: center; }
.loader-icon { font-size: 3rem; color: var(--accent); margin-bottom: 1rem; animation: pulse 1.5s infinite; }
.loader-content h2 { font-size: 1.5rem; font-weight: 700; margin-bottom: 0.5rem; }
.loader-content p { color: var(--text-secondary); margin-bottom: 1.5rem; }
.loader-bar { width: 200px; height: 3px; background: var(--bg-tertiary); border-radius: 3px; overflow: hidden; margin: 0 auto; }
.loader-progress { height: 100%; width: 30%; background: var(--accent); border-radius: 3px; animation: loading 1.5s ease-in-out infinite; }
@keyframes loading { 0% { transform: translateX(-100%); } 100% { transform: translateX(400%); } }
@keyframes pulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.1); } }

/* ===== Mobile Header ===== */
#mobile-header {
  display: none;
  position: fixed; top: 0; left: 0; right: 0;
  height: var(--mobile-header-height);
  background: var(--bg-secondary);
  border-bottom: 1px solid var(--bg-tertiary);
  align-items: center;
  justify-content: space-between;
  padding: env(safe-area-inset-top, 0px) 12px 0;
  z-index: 1001;
}
#mobile-header h1 { font-size: 1.1rem; font-weight: 700; }
#mobile-header button {
  background: none; border: none; color: var(--text-primary);
  font-size: 1.2rem; padding: 8px; cursor: pointer;
}

/* ===== Sidebar ===== */
.sidebar {
  position: fixed; top: 0; left: 0; bottom: 0;
  width: var(--sidebar-width);
  background: var(--bg-secondary);
  border-right: 1px solid var(--bg-tertiary);
  display: flex; flex-direction: column;
  z-index: 1000;
  transition: transform var(--transition);
  overflow: hidden;
}
.sidebar.collapsed { transform: translateX(-100%); }

/* Desktop sidebar collapse (onX-style). One body-level var override moves every
   --sidebar-width dependent (#map, #info-panel, #weather-timeline, 3D/basemap
   switches) at once. Desktop-only: mobile keeps the .open overlay pattern. */
@media (min-width: 769px) {
  body.sidebar-collapsed { --sidebar-width: 0px; }
  body.sidebar-collapsed .sidebar { transform: translateX(-100%); }
  /* Collapsed sidebar puts #info-panel at left:12px — the same corner the
     fixed #sidebar-expand (») button occupies — covering the site name.
     Shift the pane right to clear the 38px button + gaps. */
  body.sidebar-collapsed #info-panel { left: 62px; }
}
#sidebar-collapse {
  background: none; border: none; color: var(--text-secondary);
  font-size: 1rem; cursor: pointer; padding: 4px 8px;
}
#sidebar-collapse:hover { color: var(--text-primary); }
#sidebar-expand {
  position: fixed; top: 12px; left: 12px; z-index: 1001;
  width: 38px; height: 38px; border-radius: var(--radius-sm);
  background: var(--bg-secondary); border: 1px solid var(--bg-tertiary);
  color: var(--text-primary); font-size: 1rem; cursor: pointer;
  display: none; align-items: center; justify-content: center;
  box-shadow: 0 2px 10px rgba(0,0,0,0.4);
}
body.sidebar-collapsed #sidebar-expand { display: flex; }

.sidebar-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px 20px;
  border-bottom: 1px solid var(--bg-tertiary);
  flex-shrink: 0;
}
.brand { display: flex; align-items: center; gap: 10px; }
.brand i { font-size: 1.5rem; color: var(--accent); }
.brand h1 { font-size: 1.25rem; font-weight: 700; }
#sidebar-close {
  background: none; border: none; color: var(--text-secondary);
  font-size: 1.2rem; cursor: pointer; padding: 4px;
  display: none;
}

.sidebar-body {
  flex: 1; overflow-y: auto; overflow-x: hidden;
  padding: 0;
  scrollbar-width: thin;
  scrollbar-color: var(--bg-tertiary) transparent;
}
.sidebar-body::-webkit-scrollbar { width: 6px; }
.sidebar-body::-webkit-scrollbar-track { background: transparent; }
.sidebar-body::-webkit-scrollbar-thumb { background: var(--bg-tertiary); border-radius: 3px; }

.sidebar-footer {
  padding: 12px 20px;
  border-top: 1px solid var(--bg-tertiary);
  flex-shrink: 0;
}
.sidebar-footer p { font-size: 0.7rem; color: var(--text-muted); line-height: 1.5; }

/* ===== Tab Navigation ===== */
.tab-nav {
  display: flex;
  border-bottom: 1px solid var(--bg-tertiary);
  flex-shrink: 0;
}
.tab-btn {
  flex: 1;
  padding: 12px 8px;
  background: none; border: none;
  color: var(--text-secondary);
  font-size: 0.8rem; font-weight: 500;
  cursor: pointer;
  border-bottom: 2px solid transparent;
  transition: all var(--transition);
  display: flex; align-items: center; justify-content: center; gap: 6px;
}
.tab-btn:hover { color: var(--text-primary); background: var(--bg-tertiary); }
.tab-btn.active { color: var(--accent); border-bottom-color: var(--accent); }
.tab-btn i { font-size: 0.9rem; }

.tab-content { display: none; }
.tab-content.active { display: block; }

/* ===== Sidebar Sections ===== */
.sidebar-section {
  padding: 16px 20px;
  border-bottom: 1px solid rgba(255,255,255,0.04);
}
.sidebar-section h3 {
  font-size: 0.8rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--text-secondary);
  margin-bottom: 12px;
  display: flex; align-items: center; gap: 8px;
}
.sidebar-section h3 i { color: var(--accent); font-size: 0.85rem; }
.sidebar-section h4 {
  font-size: 0.78rem; font-weight: 600;
  color: var(--text-secondary);
  margin: 12px 0 8px;
}
.hint { font-size: 0.78rem; color: var(--text-muted); margin-bottom: 12px; line-height: 1.4; }

/* ===== Search ===== */
.search-box {
  display: flex; align-items: center;
  background: var(--bg-tertiary);
  border-radius: var(--radius);
  padding: 0 12px;
  border: 1px solid transparent;
  transition: border-color var(--transition);
}
.search-box:focus-within { border-color: var(--accent); }
.search-box i { color: var(--text-muted); font-size: 0.85rem; }
.search-box input {
  flex: 1; background: none; border: none; outline: none;
  color: var(--text-primary); padding: 10px 10px;
  font-size: 0.85rem; font-family: inherit;
}
.search-box input::placeholder { color: var(--text-muted); }
.search-box button { background: none; border: none; color: var(--text-muted); cursor: pointer; padding: 4px; }
.search-results {
  margin-top: 8px;
  background: var(--bg-tertiary);
  border-radius: var(--radius);
  max-height: 240px;
  overflow-y: auto;
}
.search-results.hidden { display: none; }
.search-result-item {
  padding: 10px 14px;
  cursor: pointer;
  font-size: 0.82rem;
  border-bottom: 1px solid rgba(255,255,255,0.04);
  transition: background var(--transition);
  display: flex; align-items: center; gap: 8px;
}
.search-result-item:hover { background: rgba(255,255,255,0.05); }
.search-result-item i { color: var(--accent); width: 16px; text-align: center; }
.search-result-item:last-child { border-bottom: none; }

/* ===== Layer Toggles ===== */
.layer-toggle {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 0;
  cursor: pointer;
  font-size: 0.85rem;
}
.layer-toggle input { display: none; }
.toggle-slider {
  width: 36px; height: 20px;
  background: var(--bg-tertiary);
  border-radius: 10px;
  position: relative;
  transition: background var(--transition);
  flex-shrink: 0;
}
.toggle-slider::after {
  content: '';
  position: absolute;
  width: 16px; height: 16px;
  background: var(--text-secondary);
  border-radius: 50%;
  top: 2px; left: 2px;
  transition: all var(--transition);
}
.layer-toggle input:checked + .toggle-slider { background: var(--accent-dim); }
.layer-toggle input:checked + .toggle-slider::after { transform: translateX(16px); background: var(--accent); }
.toggle-label { flex: 1; }

/* ===== Route vehicle picker (js/vehicle.js) ===== */
/* Ported from Motocamp USA, minus the towing row — NZ ships no towing modifier
   (it would change nothing about the route here; see js/vehicle.js). */
.route-vehicle {
  padding-bottom: 10px;
  margin-bottom: 4px;
  border-bottom: 1px solid var(--bg-tertiary);
}
.route-vehicle-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 6px; margin-bottom: 7px;
}
.route-vehicle-title {
  font-size: 0.72rem; font-weight: 600;
  color: var(--text-secondary);
  text-transform: uppercase; letter-spacing: 0.04em;
}
.route-vehicle-reset {
  background: none; border: none; padding: 0;
  color: var(--text-muted, #888);
  font-size: 0.66rem; cursor: pointer; text-decoration: underline;
}
.route-vehicle-reset:hover { color: var(--accent); }
.route-vehicle-reset[hidden] { display: none; }
.route-vehicle-picker {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 5px;
}
.route-vehicle-btn {
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  padding: 7px 3px;
  border: 1px solid var(--bg-tertiary);
  border-radius: 6px;
  background: transparent;
  color: var(--text-secondary);
  font-size: 0.62rem;
  cursor: pointer;
  transition: all var(--transition);
  min-width: 0;
}
.route-vehicle-btn i { font-size: 0.92rem; }
.route-vehicle-btn span { overflow-wrap: anywhere; text-align: center; line-height: 1.2; }
.route-vehicle-btn:hover { border-color: var(--text-muted, #888); color: var(--text-primary); }
.route-vehicle-btn[aria-pressed="true"] {
  border-color: var(--accent);
  background: var(--accent-dim);
  color: var(--text-primary);
}
.route-vehicle-btn[aria-pressed="true"] i { color: var(--accent); }
.route-vehicle-note {
  font-size: 0.66rem;
  color: var(--text-muted, #888);
  margin-top: 7px;
  line-height: 1.45;
}
.route-vehicle-note:empty { display: none; }
.route-vehicle-note .warn { color: #ffab40; }

.badge {
  font-size: 0.65rem; font-weight: 600;
  padding: 2px 6px; border-radius: 3px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}
.badge-green { background: rgba(0,200,83,0.15); color: #00c853; }
.badge-blue { background: rgba(64,196,255,0.15); color: #40c4ff; }
.badge-orange { background: rgba(255,171,64,0.15); color: #ffab40; }
.badge-purple { background: rgba(176,128,255,0.15); color: #b080ff; }
.badge-teal { background: rgba(38,198,178,0.15); color: #26c6b2; }
.badge-yellow { background: rgba(255,230,0,0.15); color: #ffe600; }
.badge-red { background: rgba(230,0,0,0.15); color: #ff5252; }

/* ===== Base Map Selector ===== */
/* Warm up CARTO Voyager's pale palette so the base map reads richer, not washed out */
.basemap-selector { display: flex; gap: 6px; }
.basemap-btn {
  flex: 1; padding: 8px;
  background: var(--bg-tertiary);
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  color: var(--text-secondary);
  font-size: 0.75rem; font-weight: 500;
  cursor: pointer;
  transition: all var(--transition);
  display: flex; flex-direction: column; align-items: center; gap: 4px;
}
.basemap-btn i { font-size: 1rem; }
.basemap-btn:hover { color: var(--text-primary); background: rgba(255,255,255,0.08); }
.basemap-btn.active { border-color: var(--accent); color: var(--accent); background: var(--accent-dim); }

/* ===== Filter Chips ===== */
.filter-group { display: flex; flex-wrap: wrap; gap: 6px; }
.filter-chip {
  display: flex; align-items: center; gap: 4px;
  padding: 6px 10px;
  background: var(--bg-tertiary);
  border-radius: 20px;
  font-size: 0.75rem;
  cursor: pointer;
  transition: all var(--transition);
  border: 1px solid transparent;
  user-select: none;
}
.filter-chip:hover { background: rgba(255,255,255,0.08); }
.filter-chip input { display: none; }
.filter-chip:has(input:checked) { border-color: var(--accent); background: var(--accent-dim); color: var(--accent); }
.filter-chip i { font-size: 0.7rem; }

/* ===== Route Planning ===== */
.route-inputs { display: flex; flex-direction: column; gap: 4px; }
.route-point {
  display: flex; align-items: center; gap: 10px;
  background: var(--bg-tertiary);
  border-radius: var(--radius-sm);
  padding: 0 12px;
}
.route-point input {
  flex: 1; background: none; border: none; outline: none;
  color: var(--text-primary); padding: 10px 0;
  font-size: 0.85rem; font-family: inherit;
}
.route-point input::placeholder { color: var(--text-muted); }
/* Route search results dropdown */
.route-search-results {
  position: absolute;
  left: 0; right: 0;
  z-index: 9999;
  margin-top: 2px;
  max-height: 200px;
  overflow-y: auto;
  box-shadow: 0 6px 20px rgba(0,0,0,0.4);
  border: 1px solid rgba(255,255,255,0.08);
}
/* Suggestions are positioned in JS (see _positionResults in js/route.js):
   fixed to the viewport but anchored to the input's real position, flipping
   above it when the phone keyboard leaves no room below. The old mobile rule
   pinned them to top:52px of the SCREEN — detached from the box being typed
   in, floating over the header ("the destination box broke out"). */
.route-search-results {
  position: fixed;
  z-index: 10000;
}
.route-start-icon { color: var(--accent); font-size: 0.6rem; }
.route-locate-btn {
  flex-shrink: 0;
  padding: 6px 8px;
  border: none;
  color: var(--accent);
  background: none;
  font-size: 1rem;
  cursor: pointer;
  opacity: 0.7;
  transition: opacity 0.2s;
}
.route-locate-btn:hover { opacity: 1; }
.route-locate-btn.locating { animation: pulse-locate 1s infinite; }
@keyframes pulse-locate { 0%, 100% { opacity: 0.4; } 50% { opacity: 1; } }
.route-end-icon { color: var(--danger); font-size: 0.85rem; }
.route-waypoint-icon { color: var(--info); font-size: 0.6rem; }

.route-actions { display: flex; gap: 8px; margin-top: 8px; }
.route-dates { margin-top: 4px; }
.date-inputs { display: flex; gap: 8px; }
.date-field { flex: 1; }
.date-field label { display: block; font-size: 0.72rem; color: var(--text-muted); margin-bottom: 4px; }
.date-field input {
  width: 100%; padding: 8px 10px;
  background: var(--bg-tertiary);
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  color: var(--text-primary);
  font-size: 0.82rem; font-family: inherit;
  outline: none;
}
.date-field input:focus { border-color: var(--accent); }

/* ===== Buttons ===== */
.btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 14px;
  background: var(--bg-tertiary);
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: var(--radius-sm);
  color: var(--text-secondary);
  font-size: 0.8rem; font-weight: 500;
  cursor: pointer;
  transition: all var(--transition);
  font-family: inherit;
}
.btn:hover { background: rgba(255,255,255,0.08); color: var(--text-primary); }
.btn-sm { padding: 6px 10px; font-size: 0.75rem; }
.btn-primary { background: var(--accent); color: #000; border-color: var(--accent); font-weight: 600; }
.btn-primary:hover { background: var(--accent-hover); color: #000; }
.btn-danger { border-color: rgba(255,82,82,0.3); color: var(--danger); }
.btn-danger:hover { background: rgba(255,82,82,0.1); }
.btn-block { width: 100%; justify-content: center; margin-top: 12px; }

/* ===== Weather Controls ===== */
.time-slider-container { padding: 4px 0; }
.time-slider-container input[type="range"] {
  width: 100%; -webkit-appearance: none; appearance: none;
  height: 4px; background: var(--bg-tertiary);
  border-radius: 2px; outline: none;
}
.time-slider-container input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 16px; height: 16px;
  background: var(--accent); border-radius: 50%;
  cursor: pointer;
}
.time-labels { display: flex; justify-content: space-between; margin-top: 4px; font-size: 0.7rem; color: var(--text-muted); }

/* ===== Map ===== */
#map {
  position: fixed;
  top: 0; bottom: 0;
  left: var(--sidebar-width);
  right: 0;
  z-index: 1;
}

/* ===== Map Controls ===== */
#map-controls {
  position: fixed;
  top: 16px; right: 16px;
  display: flex; flex-direction: column; gap: 8px;
  z-index: 500;
}
.map-btn {
  width: auto; height: auto;
  padding: 8px 10px;
  background: var(--bg-secondary);
  border: 1px solid var(--bg-tertiary);
  border-radius: var(--radius);
  color: var(--text-primary);
  font-size: 1rem;
  cursor: pointer;
  display: flex; align-items: center; gap: 6px;
  transition: all var(--transition);
  box-shadow: var(--shadow);
}
.map-btn-label {
  font-size: 0.65rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--text-secondary);
}
.map-btn:hover { background: var(--bg-tertiary); color: var(--accent); }
.map-btn:hover .map-btn-label { color: var(--accent); }
.map-btn.active { background: var(--accent); color: #fff; border-color: var(--accent); }
.map-btn.active .map-btn-label { color: #fff; }

/* ===== Weather Tile Overlays ===== */
.weather-tile-temperature { filter: saturate(2.5) contrast(1.8) brightness(1.1); }
.weather-tile-precipitation { filter: saturate(2.0) contrast(1.5); }
.weather-tile-clouds { filter: contrast(1.4) brightness(0.95); }
.weather-tile-wind { filter: saturate(1.8) contrast(1.4); }

/* ===== Weather Timeline ===== */
/* ===== Info Panel =====
   Vertical side-loading pane (onX-style), 2026-07-27. Was a bottom-anchored
   horizontal strip eating 50vh; now a left card over the map. Mobile keeps the
   bottom-sheet geometry (overridden in the 768px block below). */
#info-panel {
  position: fixed;
  top: 12px; bottom: 12px;
  left: calc(var(--sidebar-width) + 12px);
  width: 380px;
  max-width: calc(100vw - var(--sidebar-width) - 24px);
  background: var(--bg-secondary);
  border: 1px solid var(--bg-tertiary);
  border-radius: var(--radius);
  z-index: 600;
  overflow-y: auto;
  box-shadow: 0 8px 30px rgba(0,0,0,0.45);
  transition: transform var(--transition), opacity var(--transition);
}
#info-panel.hidden {
  transform: translateX(calc(-100% - 420px));
  opacity: 0;
  pointer-events: none;
}
#info-close {
  position: sticky; top: 0; right: 0;
  float: right; margin: 12px 12px 0 0;
  background: var(--bg-tertiary); border: none;
  z-index: 10;
  color: var(--text-secondary); width: 32px; height: 32px;
  border-radius: 50%; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  font-size: 0.9rem;
}
#info-content { padding: 20px 24px 24px; }

/* Info Panel Content */
.info-header { margin-bottom: 16px; }
.info-header h2 { font-size: 1.15rem; font-weight: 700; margin-bottom: 4px; }
.info-header .info-type { font-size: 0.78rem; color: var(--accent); font-weight: 500; text-transform: uppercase; letter-spacing: 0.03em; }
.info-header .info-status { font-size: 0.75rem; padding: 2px 8px; border-radius: 3px; margin-left: 8px; }
.info-header .info-status.open { background: rgba(0,200,83,0.15); color: #00c853; }
.info-header .info-status.closed { background: rgba(255,82,82,0.15); color: #ff5252; }

.info-facilities {
  display: flex; flex-wrap: wrap; gap: 8px;
  margin-bottom: 16px;
}
.facility-badge {
  display: flex; align-items: center; gap: 5px;
  padding: 6px 10px;
  background: var(--bg-tertiary);
  border-radius: var(--radius-sm);
  font-size: 0.75rem;
  color: var(--text-secondary);
}
.facility-badge.available { color: var(--accent); background: var(--accent-dim); }
.facility-badge i { font-size: 0.8rem; }

.info-details { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 16px; }
.info-detail { }
.info-detail-label { font-size: 0.7rem; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.03em; margin-bottom: 2px; }
.info-detail-value { font-size: 0.85rem; color: var(--text-primary); }

.info-weather {
  background: var(--bg-tertiary);
  border-radius: var(--radius);
  padding: 14px;
  margin-bottom: 16px;
}
.info-weather h4 { font-size: 0.78rem; color: var(--text-secondary); margin-bottom: 8px; }
.weather-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(80px, 1fr)); gap: 8px;
}
.weather-item { text-align: center; }
.weather-item .wx-icon { font-size: 1.3rem; margin-bottom: 2px; }
.weather-item .wx-temp { font-size: 1rem; font-weight: 600; }
.weather-item .wx-desc { font-size: 0.68rem; color: var(--text-muted); }
.weather-item .wx-day { font-size: 0.68rem; color: var(--text-secondary); font-weight: 500; }

.info-cell-coverage { margin-bottom: 16px; }
.cell-bar-container { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
.cell-carrier { font-size: 0.78rem; width: 70px; color: var(--text-secondary); }
.cell-bar { flex: 1; height: 6px; background: var(--bg-tertiary); border-radius: 3px; overflow: hidden; }
.cell-bar-fill { height: 100%; border-radius: 3px; transition: width 0.5s ease; }
.cell-bar-fill.spark { background: var(--spark-color); }
.cell-bar-fill.vodafone { background: var(--vodafone-color); }
.cell-bar-fill.twodeg { background: var(--twodeg-color); }
.cell-tech { font-size: 0.68rem; color: var(--text-muted); width: 30px; }

.info-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.info-actions .btn i { font-size: 0.8rem; }

/* ===== Pane card components (onX card anatomy, shared by trail/land/hazard/
   waypoint cards and reusable by any info-panel content) ===== */
.pane-tiles { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-bottom: 14px; }
.pane-tile { background: var(--bg-tertiary); border-radius: var(--radius-sm); padding: 8px 10px; }
.pane-tile.wide { grid-column: 1 / -1; }
.pane-tile .pt-label { font-size: 0.68rem; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.03em; }
.pane-tile .pt-value { font-size: 0.95rem; font-weight: 700; margin-top: 2px; }
.pane-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px; }
.pane-chip { border: 1px solid var(--bg-tertiary); background: var(--bg-tertiary); border-radius: 999px; padding: 3px 10px; font-size: 0.72rem; color: var(--text-secondary); }
.pane-chip.ok { border-color: var(--accent); color: var(--accent); background: none; }
.pane-chip.warn { border-color: #f59e0b; color: #f59e0b; background: none; }
.pane-chip.bad { border-color: #ff5252; color: #ff5252; background: none; }
.pane-kv { border-top: 1px solid var(--bg-tertiary); padding: 8px 2px; display: flex; gap: 8px; font-size: 0.82rem; }
.pane-kv .k { color: var(--text-muted); min-width: 110px; flex-shrink: 0; }
.pane-kv .v { font-weight: 600; }
.pane-actions { display: flex; gap: 12px; justify-content: space-around; border-top: 1px solid var(--bg-tertiary); padding: 12px 4px 2px; margin-top: 12px; }
.pane-action { background: none; border: none; color: var(--text-secondary); cursor: pointer; display: flex; flex-direction: column; align-items: center; gap: 5px; font-size: 0.7rem; }
.pane-action .pa-ico { width: 42px; height: 42px; border-radius: 50%; display: flex; align-items: center; justify-content: center; background: var(--bg-tertiary); border: 1px solid var(--bg-tertiary); font-size: 1rem; color: var(--text-primary); }
.pane-action.primary .pa-ico { background: var(--accent); color: #00120a; }
.pane-action:hover .pa-ico { border-color: var(--accent); }
.diff-pill { display: inline-block; border-radius: 5px; padding: 2px 10px; font-weight: 700; font-size: 0.78rem; color: #08131c; }
.pane-note { color: var(--text-muted); font-size: 0.72rem; margin-top: 10px; line-height: 1.45; }

/* Waypoints */
.wp-icon-grid { display: grid; grid-template-columns: repeat(6, 1fr); gap: 6px; margin: 8px 0; }
.wp-icon-grid button { font-size: 1.05rem; padding: 8px 0; border-radius: var(--radius-sm); border: 2px solid var(--bg-tertiary); background: var(--bg-tertiary); cursor: pointer; }
.wp-icon-grid button.sel { border-color: var(--accent); }
.wp-color-row { display: flex; gap: 8px; margin: 8px 0; }
.wp-color-row button { width: 26px; height: 26px; border-radius: 50%; cursor: pointer; border: 2px solid transparent; }
.wp-color-row button.sel { border-color: #fff; }
.wp-marker { width: 30px; height: 30px; border-radius: 50% 50% 50% 0; transform: rotate(-45deg); display: flex; align-items: center; justify-content: center; border: 2px solid #fff; box-shadow: 0 2px 6px rgba(0,0,0,0.5); cursor: pointer; }
.wp-marker span { transform: rotate(45deg); font-size: 13px; }
.wp-list-item { display: flex; align-items: center; gap: 10px; padding: 8px 4px; border-bottom: 1px solid var(--bg-tertiary); cursor: pointer; border-radius: var(--radius-sm); }
.wp-list-item:hover { background: var(--bg-tertiary); }
.wp-list-dot { width: 28px; height: 28px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 0.85rem; flex-shrink: 0; }

/* Trail overlay legend lines (rendered inside the sidebar section) */
.trail-legend-line { display: flex; align-items: center; gap: 10px; padding: 3px 0; font-size: 0.75rem; color: var(--text-secondary); }
.trail-legend-swatch { width: 30px; height: 5px; border-radius: 3px; flex-shrink: 0; }

/* ===== Route Summary Styles ===== */
.route-overview {
  display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 8px;
  margin-bottom: 16px;
}
.route-stat {
  text-align: center;
  padding: 10px;
  background: var(--bg-tertiary);
  border-radius: var(--radius-sm);
}
.route-stat-value { font-size: 1.2rem; font-weight: 700; color: var(--accent); }
.route-stat-label { font-size: 0.68rem; color: var(--text-muted); margin-top: 2px; }

.route-segment {
  padding: 12px 0;
  border-bottom: 1px solid rgba(255,255,255,0.04);
}
.route-segment:last-child { border-bottom: none; }
.route-segment-header {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 6px;
}
.route-segment-header h4 { font-size: 0.85rem; font-weight: 600; }
.route-segment-header span { font-size: 0.75rem; color: var(--text-muted); }
.route-segment-weather {
  display: flex; gap: 12px;
  margin-bottom: 6px;
}
.route-segment-weather .wx-mini {
  display: flex; align-items: center; gap: 4px;
  font-size: 0.78rem; color: var(--text-secondary);
}
.route-segment-services { display: flex; flex-wrap: wrap; gap: 4px; }
.route-segment-services .service-tag {
  font-size: 0.68rem;
  padding: 2px 6px;
  background: var(--bg-tertiary);
  border-radius: 3px;
  color: var(--text-muted);
}
.route-segment-services .service-tag.available { color: var(--accent); background: var(--accent-dim); }

/* ===== Elevation Profile ===== */
.elevation-profile {
  margin-bottom: 14px;
  padding-bottom: 12px;
  border-bottom: 1px solid rgba(255,255,255,0.04);
}
.elevation-stats {
  display: flex; gap: 12px;
  margin-bottom: 8px;
  font-size: 0.75rem;
  color: var(--text-secondary);
}
.elevation-stats span {
  display: flex; align-items: center; gap: 4px;
}
.elevation-chart-wrap {
  position: relative;
  background: var(--bg-tertiary);
  border-radius: var(--radius-sm);
  padding: 4px;
  cursor: crosshair;
}
.elevation-chart-wrap canvas {
  display: block;
  width: 100%;
}
.elevation-tooltip {
  position: absolute;
  background: var(--bg-secondary);
  border: 1px solid var(--bg-tertiary);
  border-radius: var(--radius-sm);
  padding: 4px 8px;
  font-size: 0.72rem;
  color: var(--text-primary);
  pointer-events: none;
  white-space: nowrap;
  z-index: 10;
  box-shadow: var(--shadow);
  line-height: 1.3;
}
.elevation-map-tooltip {
  background: var(--bg-secondary) !important;
  border: 1px solid var(--accent) !important;
  color: var(--text-primary) !important;
  font-size: 0.75rem !important;
  font-weight: 600 !important;
  padding: 2px 6px !important;
  border-radius: 4px !important;
  box-shadow: var(--shadow) !important;
}
.elevation-map-tooltip::before {
  border-top-color: var(--accent) !important;
}

/* ===== Weather Overlay Legend ===== */
.weather-legend-bar {
  display: flex; height: 12px;
  border-radius: 6px; overflow: hidden;
  margin-bottom: 4px;
}
.weather-legend-labels { display: flex; justify-content: space-between; font-size: 0.68rem; color: var(--text-muted); }

/* ===== MapLibre GL Overrides ===== */
.maplibregl-ctrl-attrib { font-size: 0.6rem !important; background: rgba(15,25,35,0.8) !important; color: var(--text-muted) !important; }
.maplibregl-ctrl-attrib a { color: var(--text-secondary) !important; }
.maplibregl-popup-content {
  background: var(--bg-secondary) !important;
  color: var(--text-primary) !important;
  border-radius: var(--radius) !important;
  box-shadow: var(--shadow) !important;
  border: 1px solid var(--bg-tertiary) !important;
  padding: 12px 14px !important;
  font-family: 'Inter', sans-serif !important;
}
/* The popup tip is a CSS border triangle — theme every anchor direction */
.maplibregl-popup-anchor-bottom .maplibregl-popup-tip { border-top-color: var(--bg-secondary) !important; }
.maplibregl-popup-anchor-top .maplibregl-popup-tip { border-bottom-color: var(--bg-secondary) !important; }
.maplibregl-popup-anchor-left .maplibregl-popup-tip { border-right-color: var(--bg-secondary) !important; }
.maplibregl-popup-anchor-right .maplibregl-popup-tip { border-left-color: var(--bg-secondary) !important; }
.maplibregl-popup-close-button { color: var(--text-secondary) !important; font-size: 20px !important; right: 4px !important; top: 2px !important; }
/* Cluster count styling is data-driven GL symbol paint now (Utils.clusterColors) — no DOM cluster CSS. */

/* Custom marker styles */
.custom-marker {
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%;
  /* Tight shadow: large blur radii multiply paint cost across hundreds of
     markers when a dense area re-renders after a zoom */
  box-shadow: 0 1px 3px rgba(0,0,0,0.5);
  font-size: 14px;
  transition: transform 0.2s ease;
}
.custom-marker:hover { transform: scale(1.2); }

/* Home base pin — a green house badge on the main map at the saved home. */
.home-map-marker {
  display: flex; align-items: center; justify-content: center;
  width: 30px; height: 30px;
  border-radius: 50%;
  background: var(--accent);
  border: 2px solid #fff;
  box-shadow: 0 1px 4px rgba(0,0,0,0.5);
  color: #fff;
  font-size: 14px;
  transition: transform 0.15s ease;
}
.home-map-marker:hover { transform: scale(1.15); }
/* (retired .marker-* divIcon classes removed — markers now draw on canvas via Utils.dotMarker; palette lives in Utils.markerStyles) */

/* ===== Responsive ===== */
@media (max-width: 768px) {
  #mobile-header { display: flex; }
  #sidebar-close { display: block; }

  .sidebar {
    width: 100%;
    transform: translateX(-100%);
    top: 0;
  }
  .sidebar.open { transform: translateX(0); }
  .sidebar-header { padding-top: calc(var(--mobile-header-height) + 8px); }

  #map {
    left: 0;
    top: var(--mobile-header-height);
  }

  #map-controls {
    top: calc(var(--mobile-header-height) + 12px);
    right: 12px;
  }

#info-panel {
    top: auto; bottom: 0; left: 0; right: 0;
    width: 100%; max-width: 100%;
    max-height: 60vh;
    border: none; border-top: 1px solid var(--bg-tertiary);
    border-radius: var(--radius) var(--radius) 0 0;
  }
  #info-panel.hidden { transform: translateY(100%); }
  #sidebar-collapse, #sidebar-expand { display: none !important; }

  .info-details { grid-template-columns: 1fr; }
  .route-overview { grid-template-columns: 1fr 1fr; }

  /* Inputs must be ≥16px to prevent iOS Safari from zooming on focus */
  .route-point input,
  .search-box input,
  .date-field input {
    font-size: 1rem;
  }
}

/* In landscape on mobile: compact the sidebar so content fits above the keyboard */
@media (max-width: 768px) and (orientation: landscape) {
  .sidebar-header { padding-top: calc(var(--mobile-header-height) + 4px); padding-bottom: 6px; }
  .sidebar-section { padding: 10px 16px; }
  .sidebar-section h3 { margin-bottom: 8px; }
  .tab-btn { padding: 8px 4px; }
}

@media (max-width: 480px) {
  .tab-btn { font-size: 0.72rem; padding: 10px 4px; }
  .basemap-selector { flex-direction: column; }
  .weather-grid { grid-template-columns: repeat(3, 1fr); }
}

/* ===== Context Menu ===== */
#context-menu {
  position: fixed;
  background: var(--bg-secondary);
  border: 1px solid var(--bg-tertiary);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  z-index: 2000;
  min-width: 200px;
  padding: 4px 0;
  overflow: hidden;
}
.ctx-item {
  padding: 10px 16px;
  font-size: 0.82rem;
  cursor: pointer;
  display: flex; align-items: center; gap: 10px;
  transition: background 0.15s;
  color: var(--text-primary);
}
.ctx-item:hover { background: rgba(255,255,255,0.06); }
.ctx-item i { color: var(--accent); width: 16px; text-align: center; font-size: 0.85rem; }
.ctx-divider { height: 1px; background: var(--bg-tertiary); margin: 4px 0; }

/* ===== Ride Dashboard ===== */

/* When dashboard is open, hide EVERYTHING else */
body.dashboard-active #map,
body.dashboard-active #sidebar,
body.dashboard-active #mobile-header,
body.dashboard-active #map-controls,
body.dashboard-active #info-panel,
body.dashboard-active #context-menu,
body.dashboard-active .maplibregl-control-container {
  display: none !important;
  visibility: hidden !important;
}

body.dashboard-active {
  overflow: hidden;
  background: #0a0e14;
}

#dashboard-overlay {
  position: fixed;
  inset: 0;
  z-index: 99999;
  background: #0a0e14;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  overflow: hidden;
}

.dash-close-btn {
  position: absolute;
  top: 6px;
  right: 6px;
  z-index: 100002;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 1px solid var(--bg-tertiary);
  background: rgba(26,38,50,0.8);
  color: var(--text-primary);
  font-size: 1.1rem;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  touch-action: manipulation;
}
.dash-close-btn:hover { color: var(--danger); }

/* ===== Full-screen Navigation Overlay (map + rain radar + speed) ===== */
/* Like the speedo dash, hide everything else behind it. */
body.nav-active #map,
body.nav-active #sidebar,
body.nav-active #mobile-header,
body.nav-active #map-controls,
body.nav-active #info-panel,
body.nav-active #context-menu,
body.nav-active .maplibregl-control-container {
  display: none !important;
  visibility: hidden !important;
}
body.nav-active { overflow: hidden; background: #0a0e14; }

#nav-overlay {
  position: fixed;
  inset: 0;
  z-index: 99999;
  background: #0a0e14;
  overflow: hidden;
}

/* Clip the oversized, rotating map. */
#nav-map-wrap {
  position: absolute;
  inset: 0;
  overflow: hidden;
}
/* A square whose side (145vmax) exceeds any viewport's diagonal (≤ ~1.415·vmax),
   centred with negative margins so the `transform` property is free for the
   heading-up rotation JS applies. Being ≥ the diagonal, no corner gap ever
   shows however far it spins. */
#nav-map {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 145vmax;
  height: 145vmax;
  margin-left: -72.5vmax;
  margin-top: -72.5vmax;
  transform-origin: center center;
  /* No CSS transition: nav.js eases the rotation itself, frame by frame (see
     startHeadingLoop). A transition on top would restart every frame and lag. */
  background: #0a0e14;
  will-change: transform;
}
/* 3D nav only. There the GL camera bearing does heading-up, so the square above
   is never rotated — and every pixel of it outside the viewport is rendered and
   then clipped away (4.4x the screen's pixels on an S23). js/nav.js adds this
   class and narrows the field of view to match, so the picture is unchanged. */
#nav-map.nav-fit {
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  will-change: auto;
}
#nav-map .maplibregl-control-container { display: none !important; }

/* Rider chevron — always points up (direction of travel) via JS counter-rotation. */
.nav-rider { background: none !important; border: none !important; }
.nav-rider-chevron {
  width: 44px; height: 44px;
  display: flex; align-items: center; justify-content: center;
  /* eased in JS per frame (see startHeadingLoop) — no CSS transition */
}
.nav-rider-chevron i {
  font-size: 36px;
  color: #1a73e8;   /* Google-nav blue — a bold directional arrow, not a faint dot */
  /* fa-location-arrow's art points NE (45°); correct it to point straight up. */
  transform: rotate(-45deg);
  /* Heavy white outline OUTSIDE the blue so the arrow reads on the green line
     and any basemap (paint-order draws the stroke first, then the fill). */
  -webkit-text-stroke: 2.5px #fff;
  paint-order: stroke fill;
  filter: drop-shadow(0 1px 3px rgba(0,0,0,0.55));
}

/* Current speed + speed-limit sign — bottom-left corner. */
#nav-speed {
  position: absolute;
  left: calc(14px + env(safe-area-inset-left, 0px));
  bottom: calc(18px + env(safe-area-inset-bottom, 0px));
  z-index: 10;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 14px;
  background: rgba(10,14,20,0.72);
  border: 1px solid rgba(255,255,255,0.1);
  border-radius: 14px;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.nav-speed-read { display: flex; align-items: baseline; gap: 4px; }
#nav-speed-value {
  font-size: 4.2rem;
  font-weight: 800;
  line-height: 1;
  color: #fff;
  font-variant-numeric: tabular-nums;
  letter-spacing: -1.5px;
}
#nav-speed-unit { font-size: 0.9rem; font-weight: 600; color: var(--text-secondary); text-transform: uppercase; }

/* Speed-limit sign — a circular white disc with a red ring (NZ/EU style). */
#nav-speed-limit {
  flex: 0 0 auto;
  display: flex; align-items: center; justify-content: center;
  width: 54px; height: 54px;
  border-radius: 50%;
  background: #fff;
  border: 5px solid #d32f2f;
  box-shadow: 0 1px 5px rgba(0,0,0,0.55);
}
#nav-speed-limit-value {
  color: #111;
  font-weight: 800;
  font-size: 1.3rem;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.5px;
}

/* Next-turn banner — top. */
#nav-turn {
  position: absolute;
  top: calc(12px + env(safe-area-inset-top, 0px));
  left: 50%;
  transform: translateX(-50%);
  z-index: 10;
  display: flex;
  align-items: center;
  gap: 12px;
  max-width: min(88vw, 460px);
  padding: 10px 16px 10px 10px;
  background: rgba(10,14,20,0.82);
  border: 1px solid rgba(255,255,255,0.1);
  border-radius: 16px;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  box-shadow: 0 6px 24px rgba(0,0,0,0.4);
}
.nav-turn-icon {
  flex: 0 0 auto;
  width: 46px; height: 46px;
  border-radius: 12px;
  display: flex; align-items: center; justify-content: center;
  font-size: 1.5rem;
}
.nav-turn-icon.prox-far  { background: rgba(0,200,83,0.15);  color: #00c853; }
.nav-turn-icon.prox-mid  { background: rgba(255,193,7,0.2);  color: #ffc107; }
.nav-turn-icon.prox-near { background: rgba(255,82,82,0.22); color: #ff5252; }
.nav-turn-info { min-width: 0; }
#nav-turn-dist { font-size: 1.5rem; font-weight: 800; color: #fff; line-height: 1.05; }
#nav-turn-road {
  font-size: 0.9rem; color: var(--text-secondary);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* "Worth a Stop" heads-up — always SUBORDINATE to the turn banner: lower
   z-index and positioned below it, so an imminent turn instruction is never
   obscured or delayed by a POI alert. Tap target: the whole pill dismisses. */
#nav-poi {
  position: absolute;
  top: calc(92px + env(safe-area-inset-top, 0px)); /* clears #nav-turn (~78px at 46px icon) */
  left: 50%;
  transform: translateX(-50%);
  z-index: 9;
  display: flex;
  align-items: center;
  gap: 10px;
  max-width: min(84vw, 420px);
  padding: 10px 14px;
  background: rgba(22, 14, 34, 0.86);
  border: 1px solid rgba(126, 87, 194, 0.55);
  border-radius: 14px;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.4);
  cursor: pointer;
}
#nav-poi.hidden { display: none; }

/* Fixed camera warning — same geometry as #nav-poi so they stack cleanly, but
   red-edged and it owns the slot right under the turn banner. A "possible"
   camera is amber and visibly softer: it must never read as a confirmed one. */
#nav-camera {
  position: absolute;
  top: calc(92px + env(safe-area-inset-top, 0px)); /* the slot #nav-poi used */
  left: 50%;
  transform: translateX(-50%);
  z-index: 9;
  display: flex;
  align-items: center;
  gap: 10px;
  max-width: min(84vw, 420px);
  padding: 10px 14px;
  background: rgba(40, 12, 12, 0.9);
  border: 1px solid rgba(255, 82, 82, 0.75);
  border-radius: 14px;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.45);
}
#nav-camera.hidden { display: none; }
#nav-camera-icon { font-size: 1.5rem; color: #ff5252; flex-shrink: 0; width: 34px; text-align: center; }
#nav-camera-name {
  font-weight: 700; font-size: 0.95rem; color: #fff;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
#nav-camera-detail { font-size: 0.78rem; color: var(--text-secondary); }
#nav-camera.cam-possible {
  background: rgba(40, 30, 10, 0.88);
  border-color: rgba(255, 171, 64, 0.7);
}
#nav-camera.cam-possible #nav-camera-icon { color: #ffab40; }
/* Scenery yields to the camera warning rather than overlapping it. */
#nav-overlay.cam-visible #nav-poi { top: calc(166px + env(safe-area-inset-top, 0px)); }

/* Camera popup honesty lines (Layers.showCameraPopup) */
.cam-possible { color: #ffab40; font-size: 0.8rem; margin: 4px 0; }
.cam-note { color: var(--text-muted, #999); font-size: 0.72rem; margin-top: 6px; line-height: 1.35; }
#nav-poi-icon { font-size: 1.5rem; color: #b39ddb; flex-shrink: 0; width: 34px; text-align: center; }
.nav-poi-info { min-width: 0; }
#nav-poi-name {
  font-weight: 700; font-size: 0.95rem; color: #fff;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
#nav-poi-detail { font-size: 0.78rem; color: var(--text-secondary); }

/* Distance / ETA remaining — top-right. */
#nav-eta {
  position: absolute;
  top: calc(12px + env(safe-area-inset-top, 0px));
  right: calc(14px + env(safe-area-inset-right, 0px));
  z-index: 10;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 1px;
  padding: 7px 12px;
  background: rgba(10,14,20,0.72);
  border: 1px solid rgba(255,255,255,0.1);
  border-radius: 12px;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
#nav-eta-dist { font-size: 1.15rem; font-weight: 800; color: #fff; line-height: 1.1; }
#nav-eta-time { font-size: 0.8rem; font-weight: 600; color: var(--accent); }

/* Current time — the fullscreen display hides the OS status bar clock (2026-07-28). */
#nav-clock {
  position: absolute;
  top: calc(12px + env(safe-area-inset-top, 0px));
  right: calc(14px + env(safe-area-inset-right, 0px));
  z-index: 10;
  padding: 7px 12px;
  background: rgba(10,14,20,0.72);
  border: 1px solid rgba(255,255,255,0.1);
  border-radius: 12px;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  color: #fff;
  font-size: 0.95rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
/* Route active -> the ETA chip owns the corner; the clock tucks below it. */
#nav-eta:not(.hidden) ~ #nav-clock {
  top: calc(80px + env(safe-area-inset-top, 0px));
}

/* GPS elevation — bottom-right corner. */
#nav-elev {
  position: absolute;
  right: calc(14px + env(safe-area-inset-right, 0px));
  bottom: calc(18px + env(safe-area-inset-bottom, 0px));
  z-index: 10;
  display: flex;
  align-items: baseline;
  gap: 5px;
  padding: 7px 12px;
  background: rgba(10,14,20,0.72);
  border: 1px solid rgba(255,255,255,0.1);
  border-radius: 12px;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  color: #fff;
}
#nav-elev i { font-size: 0.85rem; color: var(--text-secondary); align-self: center; }
#nav-elev-value { font-size: 1.3rem; font-weight: 800; font-variant-numeric: tabular-nums; }
.nav-elev-unit { font-size: 0.8rem; font-weight: 600; color: var(--text-secondary); }

/* Compact in-nav 2D|3D pill — bottom-center. */
#nav-mode-switch {
  position: absolute;
  bottom: calc(18px + env(safe-area-inset-bottom, 0px));
  left: 50%;
  transform: translateX(-50%);
  z-index: 12;
  display: flex; gap: 3px; padding: 3px;
  background: rgba(10,14,20,0.72);
  border: 1px solid rgba(255,255,255,0.12);
  border-radius: 999px;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
#nav-mode-switch .mode-switch-btn {
  min-width: 52px;
  min-height: 40px;
  padding: 0 14px;
  font-size: 0.85rem;
  letter-spacing: 1px;
}

/* Nav basemap pill (Topo | Sat) — stacked just above the 2D|3D pill. */
#nav-base-switch {
  position: absolute;
  bottom: calc(70px + env(safe-area-inset-bottom, 0px));
  left: 50%;
  transform: translateX(-50%);
  z-index: 12;
  display: flex; gap: 3px; padding: 3px;
  background: rgba(10,14,20,0.72);
  border: 1px solid rgba(255,255,255,0.12);
  border-radius: 999px;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
#nav-base-switch .mode-switch-btn {
  min-width: 52px;
  min-height: 40px;
  padding: 0 14px;
  font-size: 0.85rem;
  letter-spacing: 1px;
}

/* Rain-radar offline notice — small transient pill, top-centre */
.radar-note {
  position: fixed;
  top: 14px; left: 50%; transform: translateX(-50%);
  z-index: 1200;
  display: flex; align-items: center; gap: 7px;
  max-width: 90vw;
  padding: 8px 14px;
  background: var(--bg-secondary); color: var(--text-primary);
  border: 1px solid var(--bg-tertiary); border-left: 3px solid #ffab40;
  border-radius: 999px; box-shadow: var(--shadow);
  font-size: 0.8rem; font-weight: 600; white-space: nowrap;
  pointer-events: none;
}
.radar-note i { color: #ffab40; }
.radar-note.hidden { display: none; }
#nav-radar-note { top: 70px; z-index: 40; }  /* clear the turn banner in nav */
@media (max-width: 768px) {
  #radar-offline-note { top: 58px; }          /* clear the mobile header */
  .radar-note { font-size: 0.74rem; white-space: normal; text-align: center; }
}

/* ===== Social sign-in buttons (js/auth.js _renderSocialButtons) ===== */
/* Ported from NZ (which ported from Trailhead). Rendered only for enabled
   AUTH_PROVIDERS, so these styles are inert until a provider is flipped on at
   go-live. */
.login-divider {
  display: flex; align-items: center; gap: 10px;
  width: 100%; margin: 12px 0;
  font-size: 0.68rem; color: var(--text-muted, #999);
  text-transform: uppercase; letter-spacing: 0.06em; white-space: nowrap;
}
.login-divider::before, .login-divider::after {
  content: ''; flex: 1; height: 1px; background: rgba(255, 255, 255, 0.12);
}
.social-btn {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  width: 100%; padding: 10px; margin-bottom: 8px;
  border-radius: var(--radius-sm, 6px); border: 1px solid transparent;
  font-size: 0.85rem; font-weight: 600; font-family: inherit;
  cursor: pointer; transition: filter 0.15s ease;
}
.social-btn:hover { filter: brightness(1.08); }
.social-btn i { font-size: 1rem; }
.social-btn-google   { background: #fff;    color: #1f1f1f; border-color: #dadce0; }
.social-btn-google i { color: #4285f4; }
.social-btn-facebook { background: #1877f2; color: #fff; }
.social-btn-apple    { background: #000;    color: #fff; border-color: rgba(255,255,255,0.25); }

/* ===== AI route planner (js/ai-route.js) ===== */
.ai-route-log { display: flex; flex-direction: column; gap: 6px; max-height: 260px; overflow-y: auto; margin-bottom: 8px; }
.ai-route-log:empty { display: none; }
.ai-route-msg { padding: 7px 10px; border-radius: 10px; font-size: 0.82rem; line-height: 1.4; max-width: 90%; white-space: pre-wrap; word-break: break-word; }
.ai-route-user { align-self: flex-end; background: var(--accent-dim); color: var(--text-primary); }
.ai-route-assistant { align-self: flex-start; background: var(--bg-tertiary); color: var(--text-secondary); }
.ai-route-cards { display: flex; flex-direction: column; gap: 6px; margin-top: 4px; }
.ai-route-card { display: grid; grid-template-columns: 1fr auto; gap: 2px 8px; text-align: left; padding: 8px 10px; border: 1px solid var(--bg-tertiary); border-radius: var(--radius); background: var(--bg-card); color: var(--text-primary); cursor: pointer; }
.ai-route-card:hover { border-color: var(--accent); }
.ai-route-card:disabled { opacity: 0.5; cursor: default; }
.ai-card-title { font-weight: 600; font-size: 0.85rem; }
.ai-card-dist { font-size: 0.78rem; color: var(--accent); }
.ai-card-sum { grid-column: 1 / -1; font-size: 0.78rem; color: var(--text-muted); }
.ai-route-form { display: flex; gap: 6px; }
.ai-route-form input { flex: 1; background: var(--bg-tertiary); border: 1px solid transparent; border-radius: var(--radius); padding: 8px 10px; color: var(--text-primary); font-size: 0.85rem; font-family: inherit; outline: none; }
.ai-route-form input:focus { border-color: var(--accent); }
/* AI route — accommodation suggestions */
.ai-stay-town { font-weight: 600; font-size: 0.8rem; margin: 6px 0 2px; color: var(--text-primary); }
.ai-stay { display: flex; align-items: center; gap: 6px; font-size: 0.8rem; padding: 2px 0; }
.ai-stay-tier { font-size: 0.6rem; font-weight: 700; padding: 1px 5px; border-radius: 4px; text-transform: uppercase; letter-spacing: 0.03em; }
.ai-stay-lo { background: rgba(0,200,83,0.18); color: var(--accent); }
.ai-stay-hi { background: rgba(64,196,255,0.18); color: var(--info, #40c4ff); }
.ai-stay-name { flex: 1; color: var(--text-secondary); overflow-wrap: anywhere; }
.ai-stay-book { color: var(--accent); text-decoration: none; font-weight: 600; white-space: nowrap; }
.ai-stay-book:hover { text-decoration: underline; }
.ai-stay-est { font-size: 0.72rem; color: var(--text-muted); white-space: nowrap; }

/* ===== Trip recording (js/ride-recorder.js) ===== */
.map-btn.recording {
  background: #d32f2f;
  border-color: #d32f2f;
  color: #fff;
}
.map-btn.recording .map-btn-label { color: #fff; }
.map-btn.recording i { animation: rec-pulse 1.6s ease-in-out infinite; }
@keyframes rec-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.35; }
}

/* Current-location puck (shown while recording a trip).
   A green dot + heading arrow marking where you ARE now — the breadcrumb line
   shows where you've BEEN. The arrow points up in the element and the marker is
   rotation-aligned to the map, then rotated to the GPS heading, so it points
   your direction of travel; .no-heading hides it when stationary rather than
   leaving it frozen pointing somewhere you are not going. */
.loc-puck { width: 30px; height: 30px; position: relative; pointer-events: none; }
.loc-puck .puck-pulse {
  position: absolute; inset: 0; margin: auto; width: 20px; height: 20px;
  border-radius: 50%; background: #00e676; opacity: 0.4;
  animation: puckPulse 2s ease-out infinite;
}
.loc-puck .puck-dot {
  position: absolute; inset: 0; margin: auto; width: 18px; height: 18px;
  border-radius: 50%; background: #00e676; border: 3px solid #fff;
  box-shadow: 0 0 3px rgba(0,0,0,0.5);
}
.loc-puck .puck-arrow {
  position: absolute; top: -3px; left: 50%; transform: translateX(-50%);
  width: 0; height: 0; border-left: 6px solid transparent;
  border-right: 6px solid transparent; border-bottom: 9px solid #00e676;
  filter: drop-shadow(0 -1px 0 #fff);
}
.loc-puck.no-heading .puck-arrow { display: none; }
@keyframes puckPulse {
  0% { transform: scale(1); opacity: 0.45; }
  100% { transform: scale(2.6); opacity: 0; }
}

/* ===== Cancel intercept + renewal toast (retention, js/auth.js) ===== */
#cancel-intercept {
  position: fixed; inset: 0; z-index: 10002;
  background: rgba(0,0,0,0.6);
  align-items: center; justify-content: center; padding: 16px;
  /* display toggled 'none'/'flex' by Auth._openCancelIntercept */
}
#cancel-intercept .cancel-card { position: relative; width: min(400px, 92vw); text-align: center; }
#cancel-intercept h2 { margin: 0 0 14px; font-size: 1.05rem; color: var(--text-primary, #fff); }
#cancel-intercept-close {
  position: absolute; top: 8px; right: 12px;
  background: none; border: none; cursor: pointer;
  color: var(--text-muted, #999); font-size: 1.2rem; line-height: 1; padding: 4px;
}
#cancel-intercept-options { width: 100%; }
.cancel-option { width: 100%; margin-bottom: 8px; padding: 10px; font-size: 0.85rem; }
#cancel-intercept-slot { width: 100%; }
#cancel-intercept-slot p {
  margin: 0 0 14px; font-size: 0.82rem; line-height: 1.55;
  color: var(--text-muted, #bbb); text-align: left;
}
#renewal-toast {
  position: fixed; bottom: 80px; left: 50%; transform: translateX(-50%);
  z-index: 2000; display: none; align-items: center; gap: 8px;
  background: #243342; color: #e8edf2; border: 1px solid rgba(255,255,255,0.1);
  border-radius: 8px; padding: 10px 14px; font-size: 0.8rem;
  max-width: min(420px, 90vw); box-shadow: 0 8px 30px rgba(0,0,0,0.5);
}
#renewal-toast a { color: var(--accent, #00c853); }
#renewal-toast button {
  background: none; border: none; cursor: pointer;
  color: var(--text-muted, #999); font-size: 1rem; padding: 0 2px;
}

/* Narrow (phone-portrait) nav: the bottom-CENTERED pills collide with the
   bottom-left speed cluster — on an S23 the 2D|3D pill sat ON the speed-limit
   roundel (2026-07-28, found on NZ; AUS stylesheet is 5 concatenated copies, so this lives at EOF to win the cascade). Nothing may cover
   anything: right-align both pills in a column above the elevation chip. */
@media (max-width: 640px) {
  #nav-mode-switch, #nav-base-switch {
    left: auto;
    right: calc(14px + env(safe-area-inset-right, 0px));
    transform: none;
  }
  #nav-mode-switch { bottom: calc(66px + env(safe-area-inset-bottom, 0px)); }
  #nav-base-switch { bottom: calc(116px + env(safe-area-inset-bottom, 0px)); }
}



/* ===== Arrival card (js/trip.js) — shown in BOTH ride views when a trip
   completes. Appended at the end of the sheet deliberately: AUS's style.css is
   five concatenated copies, so a rule inserted mid-file can be overridden by a
   later copy. ===== */

/* Full-screen nav: same pill language as #nav-turn, which it replaces, but
   with full-width buttons — this is the one thing in nav a rider taps wearing
   gloves, so both targets are 44 px+ tall. */
#nav-arrived {
  position: absolute;
  /* A THIRD of the way down, not at the top: up there it covered the close
     button, the ETA chip and the clock — the trip is over, but the rider still
     wants to read the screen (Josh, 2026-07-31). */
  top: 30%;
  left: 50%;
  transform: translateX(-50%);
  z-index: 12;                  /* above the banner it replaces and the POI/camera pills */
  width: min(88vw, 460px);
  padding: 12px 14px;
  background: rgba(10,14,20,0.9);
  border: 1px solid rgba(0,200,83,0.35);
  border-radius: 16px;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  box-shadow: 0 6px 24px rgba(0,0,0,0.45);
}
.nav-arrived-head { display: flex; align-items: center; gap: 12px; }
#nav-arrived-icon {
  flex: 0 0 auto;
  width: 56px; height: 56px;
  border-radius: 14px;
  display: flex; align-items: center; justify-content: center;
  font-size: 1.9rem;
  background: rgba(0,200,83,0.16); color: var(--accent, #00c853);
}
.nav-arrived-info { min-width: 0; }
.nav-arrived-title { font-size: 1.5rem; font-weight: 800; color: #fff; line-height: 1.1; }
#nav-arrived-name {
  font-size: 0.95rem; color: var(--text-secondary);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Elevation profile of the route just ridden. */
.nav-arrived-elev { margin-top: 12px; }
.nav-arrived-elev canvas {
  display: block;
  width: 100%; height: 56px;
}
.nav-arrived-elev-cap {
  margin-top: 2px;
  font-size: 0.7rem; color: var(--text-secondary);
  letter-spacing: 0.02em;
}

/* Distance travelled · time moving · average over that moving time. */
.nav-arrived-stats {
  display: flex;
  gap: 8px;
  margin-top: 12px;
  padding-top: 10px;
  border-top: 1px solid rgba(255,255,255,0.08);
}
.nav-arrived-stat { flex: 1; min-width: 0; text-align: center; }
.nav-arrived-stat b {
  display: block;
  font-size: 1.15rem; font-weight: 800; color: #fff; line-height: 1.15;
  white-space: nowrap;
}
.nav-arrived-stat span {
  display: block;
  font-size: 0.7rem; color: var(--text-secondary);
  text-transform: uppercase; letter-spacing: 0.04em;
}
#nav-arrived-note {
  margin-top: 10px;
  font-size: 0.82rem; color: var(--text-secondary);
}
#nav-arrived-note i { color: #ff5252; margin-right: 5px; }
.nav-arrived-actions { display: flex; gap: 8px; margin-top: 12px; }
.nav-arrived-btn {
  flex: 1;
  padding: 12px 10px;
  font-size: 1rem; font-weight: 700;
  color: #fff;
  background: rgba(255,255,255,0.1);
  border: 1px solid rgba(255,255,255,0.14);
  border-radius: 12px;
  cursor: pointer;
}
.nav-arrived-btn.primary { background: var(--accent, #00c853); border-color: var(--accent, #00c853); color: #06210f; }

/* Speedo dash: the same card in the next-turn slot. */
.dash-arrived {
  width: 100%;
  max-width: 100%;
  min-width: 0;
  box-sizing: border-box;
  flex-shrink: 0;
  background: rgba(0, 200, 83, 0.1);
  border: 1px solid rgba(0, 200, 83, 0.3);
  border-radius: 10px;
  padding: 8px 12px;
}
.dash-arrived-head { display: flex; align-items: center; gap: 10px; }
.dash-arrived-icon {
  flex-shrink: 0;
  width: 40px; height: 40px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 8px;
  background: rgba(0, 200, 83, 0.15);
  color: #00c853;
  font-size: 1.3rem;
}
.dash-arrived-info { flex: 1; min-width: 0; }
.dash-arrived-title { font-size: 1.2rem; font-weight: 700; color: var(--text-primary, #fff); }
.dash-arrived-name {
  font-size: 0.8rem; color: var(--text-secondary);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.dash-arrived-elev { margin-top: 8px; }
.dash-arrived-elev canvas { display: block; width: 100%; height: 38px; }
.dash-arrived-elev-cap { margin-top: 1px; font-size: 0.62rem; color: var(--text-secondary); }

.dash-arrived-stats {
  display: flex;
  gap: 6px;
  margin-top: 8px;
  padding-top: 6px;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}
.dash-arrived-stat { flex: 1; min-width: 0; text-align: center; }
.dash-arrived-stat b {
  display: block;
  font-size: 0.95rem; font-weight: 800; color: var(--text-primary, #fff);
  line-height: 1.15; white-space: nowrap;
}
.dash-arrived-stat span {
  display: block;
  font-size: 0.62rem; color: var(--text-secondary);
  text-transform: uppercase; letter-spacing: 0.04em;
}
.dash-arrived-note { margin-top: 8px; font-size: 0.75rem; color: var(--text-secondary); }
.dash-arrived-note i { color: #ff5252; margin-right: 5px; }
.dash-arrived-actions { display: flex; gap: 8px; margin-top: 8px; }
.dash-arrived-btn {
  flex: 1;
  padding: 10px 8px;
  font-size: 0.9rem; font-weight: 700;
  color: #fff;
  background: rgba(255, 255, 255, 0.1);
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: 8px;
  cursor: pointer;
}
.dash-arrived-btn.primary { background: #00c853; border-color: #00c853; color: #06210f; }

/* Off-route-with-no-network notice in nav. Appended at the END on purpose: this
   stylesheet carries duplicated .radar-note blocks, so a rule placed inline
   beside one copy could be overridden by a later one. */
#nav-offline-note { top: 112px; z-index: 40; }

/* ===== Start button (js/route-start.js) ===== */
/* Centred on the MAP, not the viewport — on desktop the sidebar owns the left
   380px, so a plain 50% would sit visibly off to the left of the map area.
   --sidebar-width is 0 on mobile and when the sidebar is collapsed, so the one
   expression covers every case. */
#route-start-btn {
  position: fixed;
  /* ABOVE the whole bottom furniture, not beside it. The bottom strip is fully
     spoken for: pills bottom-left (2D/3D at 26px, basemap at 90px, 56px tall
     each, so the stack tops out at 146px) and the imagery credits bottom-right.
     A centred button at 26px was measured colliding with the credits at EVERY
     width from 769px to 1440px — it only cleared at 1600+, which is the one
     size it happened to be developed at. Esri's terms require their credit to
     stay visible, so the button moves, not the credits. 154px clears the pill
     stack with 8px of air and is far above the attribution. */
  bottom: 154px;
  left: calc(50% + var(--sidebar-width) / 2);
  transform: translateX(-50%);
  z-index: 600;          /* above the 2D/3D and basemap pills (500) */
  min-height: 56px;
  padding: 0 38px;
  border: none;
  border-radius: 999px;
  background: var(--accent);
  color: #fff;
  font-size: 1.15rem;
  font-weight: 800;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  cursor: pointer;
  display: flex; align-items: center; gap: 12px;
  /* Deliberately louder than any other map control: a green glow on top of the
     standard shadow, so it reads as THE next action rather than one more pill. */
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.5), 0 0 0 4px rgba(0, 200, 83, 0.18);
  transition: background var(--transition), box-shadow var(--transition), transform var(--transition);
}
#route-start-btn:hover {
  background: var(--accent-hover);
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.55), 0 0 0 7px rgba(0, 200, 83, 0.22);
}
#route-start-btn:active { transform: translateX(-50%) scale(0.97); }

/* Clear is CENTRED by default, because Start is phone-only: the rule further
   down hides #route-start-btn at >=769px, so on a desktop Clear is the only
   button on that baseline and an offset one would sit lopsided beside nothing.
   On a phone Start reappears and Clear steps to its right, so the pair reads as
   one control group. Same 154px bottom as Start, tuned to clear the 2D/3D +
   basemap pill stack and the imagery credits at every width. */
#route-clear-btn {
  position: fixed;
  bottom: 154px;
  left: calc(50% + var(--sidebar-width) / 2);
  transform: translateX(-50%);
  z-index: 600;
  min-height: 56px;
  padding: 0 26px;
  border: 2px solid #ff5252;
  border-radius: 999px;
  background: rgba(20, 16, 16, 0.92);
  color: #ff8a80;
  font-size: 1rem;
  font-weight: 800;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  cursor: pointer;
  display: flex; align-items: center; gap: 10px;
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.5);
  transition: background var(--transition), box-shadow var(--transition), transform var(--transition);
}
#route-clear-btn:hover {
  background: #ff5252;
  color: #fff;
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.55), 0 0 0 6px rgba(255, 82, 82, 0.22);
}
#route-clear-btn:active { transform: translateX(-50%) scale(0.97); }
#route-clear-btn i { font-size: 0.95rem; }
#route-clear-btn.hidden { display: none; }
body.dashboard-active #route-clear-btn,
body.nav-active #route-clear-btn { display: none !important; }
/* Phone: Start is visible here, so Clear steps to its right. */
@media (max-width: 768px) {
  #route-clear-btn { transform: translateX(calc(-50% + 112px)); padding: 0 18px; font-size: 0.9rem; }
  #route-clear-btn:active { transform: translateX(calc(-50% + 112px)) scale(0.97); }
}
#route-start-btn i { font-size: 1.05rem; }
#route-start-btn.hidden { display: none; }
/* Full-screen overlays own the whole screen — the button goes with them.
   (Nav in particular: it IS nav, so offering to start it again is nonsense.) */
body.dashboard-active #route-start-btn,
body.nav-active #route-start-btn { display: none !important; }

/* The panel twin in Route Summary. Same job, so the same loud green.
   Taller than the .btn default: measured 33px on an S23, under the 44px tap
   target the rest of the map UI holds itself to, and this is the primary action
   on the panel. (The Google / GPX buttons below it are the same 33px — that is
   pre-existing and deliberately left alone.) */
.route-start-inline {
  min-height: 48px;
  font-weight: 800;
  letter-spacing: 1px;
  text-transform: uppercase;
  display: flex; align-items: center; justify-content: center; gap: 9px;
}
.route-start-inline.hidden { display: none; }

@media (max-width: 768px) {
  /* Bottom-RIGHT on a phone, not centred. The left column is already full to
     ~176px (2D/3D pill at 56, basemap pill at 120, both 56 tall), and a centred
     button overlaps the basemap pill on anything narrower than ~460px. Right is
     also the thumb corner. 56px clears the imagery credits, which wrap to the
     full width at this breakpoint and must stay readable — Esri's terms require
     their credit to be visible (see the #mode-3d-switch note above). */
  #route-start-btn {
    left: auto;
    right: 12px;
    bottom: 56px;
    transform: none;
    min-height: 54px;
    padding: 0 26px;
    font-size: 1.05rem;
  }
  #route-start-btn:active { transform: scale(0.97); }
}

/* Narrow phones: share the bottom row with the 2D/3D pill and you eventually
   collide. Measured on an S23 (384 CSS px): the button spans 232-372 and the
   pill ends at 202 — a 30px gap. The button is 140px wide and sits 12px off the
   right edge, so the gap closes at 384 - 152 = 202, i.e. any viewport under
   ~354px OVERLAPS. That is an iPhone SE (320) and the compact Androids. Lift it
   clear of the whole pill stack there instead: the basemap pill tops out 176px
   off the bottom, so 184px clears it with 8px of air. */
@media (max-width: 380px) {
  #route-start-btn { bottom: 184px; }
}

/* Phones only (Josh, 2026-08-04). Start hands a planned route to turn-by-turn
   nav — something you do on the phone clipped to the bars, never at a desk. The
   gate is VIEWPORT WIDTH, not native-vs-web: the web app on a phone is exactly
   where this belongs, and 768/769 is already the phone breakpoint everywhere
   else in this file. Both go: the floating map button and its Route Summary
   twin are one feature with one label, so leaving one behind would just be the
   same button in a quieter place. Planning a route on a desktop is untouched —
   only the hand-off to nav disappears. */
@media (min-width: 769px) {
  #route-start-btn,
  .route-start-inline { display: none !important; }
}

/* ===== Arrival clock (Utils.arrivalTime) ===== */
/* Quieter than the distance and dimmer than the remaining-time green: it is
   reference information, not what a rider glances down for at speed. Hidden
   when empty so the chip does not grow a blank line before the first ETA. */
#nav-eta-arrive { font-size: 0.72rem; font-weight: 600; color: rgba(255,255,255,0.6); }
#nav-eta-arrive:empty { display: none; }
@media (max-width: 768px) {
  /* Three short stats fit a phone fine; two columns would orphan Arrive onto
     a row of its own. Appended at EOF so it wins in AUS, whose style.css is
     five concatenated copies. */
  .route-overview { grid-template-columns: repeat(3, 1fr); gap: 6px; }
  .route-stat { padding: 8px 4px; }
}


/* ===== Guided search chips + elevation profile (onX port, 2026-08-03) ======
   APPENDED AT THE END ON PURPOSE. The AUS stylesheet is five concatenated
   copies of itself (tasks/lessons.md), so a rule written anywhere else can be
   silently overridden by a later duplicate. Last-in wins at equal specificity,
   and the end of the file is the only position that is last in all regions. */
.guided-chips { display: flex; flex-wrap: wrap; gap: 6px; padding: 8px 0 2px; align-items: center; }
.guided-chip {
  padding: 5px 11px; border-radius: 999px; cursor: pointer;
  border: 1px solid var(--border, rgba(255,255,255,.16));
  background: var(--surface-2, rgba(255,255,255,.06));
  color: var(--text, #e6edf3); font-size: .78rem; font-weight: 600;
  font-family: inherit; line-height: 1.2; white-space: nowrap;
}
.guided-chip:hover { border-color: var(--accent, #4fbeda); }
.guided-chip.on { background: var(--accent, #4fbeda); border-color: var(--accent, #4fbeda); color: #08222b; }
.guided-status { font-size: .72rem; opacity: .75; margin-left: 2px; flex-basis: 100%; }
#elev-canvas { background: #111a22; margin: 6px 0 10px; }

/* Road Closures is zoom-gated (Layers.ROAD_EVENT_MINZOOM) and ships ON, so the
   toggle can be lit while the map is empty. This says which. */
.layer-toggle .zoom-hint {
  margin-left: auto; font-size: .64rem; font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase;
  color: var(--text-muted, #9aa8a1); opacity: .8; white-space: nowrap;
}

/* Mute for the spoken directions. Third row of the nav control column (2D/3D
   sits at 18px, Topo|Sat at 70px), in the same pill language: bottom-centre is
   the only band of this screen with nothing else in it at any width, and the
   turn banner, speed readout and elevation chip all keep their space. */
#nav-voice {
  position: absolute;
  bottom: calc(122px + env(safe-area-inset-bottom, 0px));
  left: 50%;
  transform: translateX(-50%);
  z-index: 12;
  display: flex; align-items: center; gap: 7px;
  /* 44px, not the 40px of its neighbours: this one gets pressed in gloves at a
     set of lights, and Apple's 44pt floor is the number that matters there. */
  min-height: 44px;
  padding: 0 16px;
  background: rgba(10,14,20,0.72);
  border: 1px solid rgba(255,255,255,0.12);
  border-radius: 999px;
  color: #fff;
  font-size: 0.8rem; font-weight: 700; letter-spacing: 1px;
  cursor: pointer;
  touch-action: manipulation;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
#nav-voice i { font-size: 0.95rem; }
/* Muted is a state a rider has to read at a glance from a moving bike, so it
   changes colour as well as the icon and the word. */
#nav-voice.muted { color: #ffab40; border-color: rgba(255,171,64,0.5); }

/* ===== Pan / tilt / zoom pad (js/app.js) =====
   Bottom-right, because the button column owns the top-right and the basemap
   and 2D/3D pills own the bottom-left. Lifted clear of MapLibre's attribution:
   Esri's terms require their credit to stay readable, so nothing may sit on it. */
#map-ptz {
  position: fixed;
  right: 16px;
  bottom: 44px;
  z-index: 500;
  display: flex; flex-direction: column; gap: 6px;
  padding: 6px;
  background: var(--bg-secondary);
  border: 1px solid var(--bg-tertiary);
  border-radius: var(--radius);
  box-shadow: 0 4px 16px rgba(0,0,0,0.35);
}
#map-ptz .ptz-pad {
  display: grid;
  grid-template-columns: repeat(3, 38px);
  gap: 4px;
}
/* Column-first, so each pair (in/out, tilt/flatten, left/right) is one column.
   Laid out across instead, the pairs split apart as soon as a phone drops the
   grid to two columns. */
#map-ptz .ptz-row {
  display: grid;
  grid-template-rows: repeat(2, 38px);
  grid-auto-flow: column;
  gap: 4px;
}
#map-ptz button {
  width: 38px; height: 38px;
  display: flex; align-items: center; justify-content: center;
  background: var(--bg-tertiary);
  border: 1px solid transparent;
  border-radius: 8px;
  color: var(--text-primary);
  font-size: 0.95rem;
  cursor: pointer;
  touch-action: manipulation;
}
#map-ptz button:hover { border-color: var(--accent); color: var(--accent); }
#map-ptz button:active { transform: scale(0.94); }
#map-ptz .ptz-home { color: var(--accent); }

/* Hidden wherever a full-screen view has taken the map away, exactly like the
   other on-map furniture. */
body.dashboard-active #map-ptz,
body.nav-active #map-ptz { display: none; }

@media (max-width: 768px) {
  /* A phone gets the camera controls that gestures make hardest: tilt, turn and
     zoom. Panning by dragging a map is the one thing everybody already does, and
     a 3x3 pad costs a third of the screen width to duplicate it. */
  #map-ptz { bottom: 56px; right: 12px; padding: 5px; }
  #map-ptz .ptz-pad { display: none; }
  /* Row-first here: two columns, one pair per row. */
  #map-ptz .ptz-row {
    grid-template-rows: none;
    grid-template-columns: repeat(2, 40px);
    grid-auto-flow: row;
  }
  #map-ptz button { width: 40px; height: 40px; }
}


/* ===== Small on/off map buttons (Sat, 3D) =====
   Replaces the two-option pills. Lit = on; off is topo and flat, which is how
   the app opens, so an unlit pair is the default state rather than a missing
   choice. Sized to match the PTZ pad's cells so the map's furniture is one
   family. */
.map-toggle {
  display: inline-flex; align-items: center; gap: 6px;
  min-height: 38px;
  padding: 0 12px;
  background: var(--bg-secondary);
  border: 1px solid var(--bg-tertiary);
  border-radius: 8px;
  color: var(--text-secondary);
  font-size: 0.82rem; font-weight: 700; letter-spacing: 0.5px;
  cursor: pointer;
  touch-action: manipulation;
  box-shadow: 0 4px 16px rgba(0,0,0,0.35);
}
.map-toggle:hover { color: var(--text-primary); border-color: var(--accent); }
.map-toggle[aria-pressed="true"] {
  background: var(--accent);
  border-color: var(--accent);
  color: #00120a;
}
/* The pills used to carry their own backgrounds and padding; the containers are
   now just anchors for one button each. */
#basemap-switch, #mode-3d-switch {
  background: none;
  border: none;
  box-shadow: none;
  padding: 0;
  display: flex;
}
/* Re-derived from the new size: one 38px button and no container padding, where
   the old pills were 56px tall. 20 + 38 + 8 of air = 66. */
#mode-3d-switch { bottom: 20px; }
#basemap-switch { bottom: 66px; }

/* Terrain height slider — sits directly above the basemap button, same left
   edge, and only while 3D is on. */
#terrain-exag {
  position: fixed;
  bottom: 112px;
  left: calc(var(--sidebar-width) + 22px);
  z-index: 500;
  display: flex; align-items: center; gap: 8px;
  padding: 0 12px; min-height: 38px;
  background: var(--bg-secondary);
  border: 1px solid var(--bg-tertiary);
  border-radius: 8px;
  box-shadow: 0 4px 16px rgba(0,0,0,0.35);
  font-size: 0.72rem; font-weight: 700; letter-spacing: 0.5px;
  color: var(--text-secondary);
}
#terrain-exag.hidden { display: none; }
#terrain-exag input[type="range"] { width: 96px; accent-color: var(--accent); cursor: pointer; }
#terrain-exag-value { min-width: 34px; color: var(--accent); }
@media (max-width: 768px) {
  #terrain-exag { left: 12px; bottom: 148px; }
  #terrain-exag input[type="range"] { width: 84px; }
}
