/* ===== 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;
  /* Wild-camping legality — must match Region.WILD_STATUS[*].colour in
     js/region-config.js. Used by the country choropleth, the sidebar legend
     and the "can I sleep here?" line in campsite popups. */
  --wild-allowed: #00c853;
  --wild-tolerated: #9ccc65;
  --wild-restricted: #ffab40;
  --wild-prohibited: #ff5252;
  --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 ===== */
/* auto-fit rather than a hardcoded column count: EU ships four classes where the
   US build ships six (see js/vehicle.js), and the labels are long enough
   ("Campervan", "Motorhome") that a fixed 4-across is cramped on a phone. This
   lays out 4 across on a wide sidebar and 2x2 on a narrow one, and survives the
   class list changing. */
.route-vehicle {
  padding: 4px 0 10px;
  border-bottom: 1px solid var(--bg-tertiary);
  margin-bottom: 4px;
}
.route-vehicle-head {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  margin-bottom: 7px;
}
.route-vehicle-title {
  font-size: 0.68rem; font-weight: 600;
  letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--text-muted, #888);
}
.route-vehicle-reset {
  background: none; border: none; padding: 0; cursor: pointer;
  font-size: 0.66rem; color: var(--accent);
  text-decoration: underline; text-underline-offset: 2px;
}
.route-vehicle-reset[hidden] { display: none; }
.route-vehicle-picker {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(72px, 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; }

/* ===== Wild-Camping Legend ===== */
/* Sits under the wild-camping toggle. The four swatches are the same four
   colours the country choropleth paints with, so the map reads without a key. */
.wild-legend { list-style: none; margin: 8px 0 10px; }
.wild-legend li {
  display: flex; align-items: center; gap: 8px;
  font-size: 0.74rem; line-height: 1.5;
  color: var(--text-secondary);
  padding: 2px 0;
}
.wild-swatch {
  flex: 0 0 auto;
  width: 12px; height: 12px;
  border-radius: 3px;
  border: 1px solid rgba(255,255,255,0.12);
}
.wild-swatch.wild-allowed { background: var(--wild-allowed); }
.wild-swatch.wild-tolerated { background: var(--wild-tolerated); }
.wild-swatch.wild-restricted { background: var(--wild-restricted); }
.wild-swatch.wild-prohibited { background: var(--wild-prohibited); }

/* ===== Units Selector ===== */
.units-select {
  width: 100%;
  padding: 8px 10px;
  background: var(--bg-tertiary);
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  color: var(--text-primary);
  font-family: inherit;
  font-size: 0.8rem;
  cursor: pointer;
}
.units-select:focus { outline: none; border-color: var(--accent); }

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

/* Wild-camping status line in a place popup — coloured left rule + the
   one-sentence summary from Region.WILD_STATUS. */
.info-wild {
  border-left: 3px solid var(--text-muted);
  background: var(--bg-tertiary);
  border-radius: var(--radius-sm);
  padding: 10px 12px;
  margin-bottom: 16px;
  font-size: 0.8rem;
  line-height: 1.5;
  color: var(--text-secondary);
}
.info-wild h4 { font-size: 0.78rem; margin-bottom: 4px; color: var(--text-primary); }
.info-wild.wild-allowed { border-left-color: var(--wild-allowed); }
.info-wild.wild-tolerated { border-left-color: var(--wild-tolerated); }
.info-wild.wild-restricted { border-left-color: var(--wild-restricted); }
.info-wild.wild-prohibited { border-left-color: var(--wild-prohibited); }

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

/* 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 MapLibre GL chrome on minimap */
.dash-minimap .maplibregl-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;
}

.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; }

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

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

/* 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; nav is mirrored). 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)); }
}


/* Low-battery 3D suggestion banner (Android battery API only). */
#nav-battery-suggest {
  position: absolute;
  top: calc(64px + env(safe-area-inset-top, 0px));
  left: 50%;
  transform: translateX(-50%);
  z-index: 14;
  max-width: 92vw;
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 8px 12px;
  background: rgba(20,14,10,0.92);
  border: 1px solid rgba(255,180,60,0.4);
  border-radius: 10px;
  font-size: 0.82rem;
  color: var(--text-primary);
}
#nav-battery-suggest button {
  padding: 5px 10px;
  border: 1px solid rgba(255,255,255,0.2);
  border-radius: 6px;
  background: rgba(255,255,255,0.08);
  color: var(--text-primary);
  font-size: 0.78rem;
  cursor: pointer;
}
#nav-battery-suggest button:hover { background: rgba(255,255,255,0.16); }

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

#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;
}

/* Fixed camera warning — same geometry family as #nav-turn, red-edged, taking
   the slot directly under the turn banner (top offset clears the ~66px turn
   banner sitting at top:12px). A "possible" camera is amber and visibly softer:
   it must never read as a confirmed one. */
#nav-camera {
  position: absolute;
  top: calc(86px + env(safe-area-inset-top, 0px));
  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; }

/* "Worth a Stop" heads-up — same geometry as #nav-camera so they share the slot
   under the turn banner cleanly, but purple-edged and it yields to the camera
   warning: when a camera is showing (#nav-overlay.cam-visible) this pill drops
   below it — safety information outranks scenery. Tap = dismiss for the ride. */
#nav-poi {
  position: absolute;
  top: calc(86px + env(safe-area-inset-top, 0px));
  left: 50%;
  transform: translateX(-50%);
  z-index: 8;
  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; }
#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); }
/* Scenery yields to the camera warning rather than overlapping it. */
#nav-overlay.cam-visible #nav-poi { top: calc(160px + 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; }

/* 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)); }
  #nav-camera { top: calc(140px + env(safe-area-inset-top, 0px)); }
  #nav-poi { top: calc(140px + env(safe-area-inset-top, 0px)); }
  #nav-overlay.cam-visible #nav-poi { top: calc(214px + env(safe-area-inset-top, 0px)); }
}

/* ===== Social sign-in buttons (js/auth.js _renderSocialButtons) ===== */
/* Ported from NZ (Trailhead lineage). 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); }

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

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

/* ===== 2D | 3D mode switch (⬅ NZ 64526ee / USA) ===== */
#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; }

/* Basemap switch (Topo | Sat) — a pill stacked directly ABOVE the 2D/3D
   toggle, same left edge and the same 62px gap at both breakpoints. EU shipped
   without it: the pair existed only inside the Layers panel, so on the main map
   there was no way to reach satellite without opening the sidebar, unlike every
   other region. Same .basemap-btn contract as the sidebar pair, so
   Layers.setupBasemapSelector wires these too and keeps .active in step across
   both. */
#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);
}
#basemap-switch .basemap-btn i { font-size: 0.95rem; }
body.dashboard-active #basemap-switch,
body.nav-active #basemap-switch { display: none !important; }

/* One-time 3D notices (software-GL warning, governor floor) — never blocking */
.mode-notice {
  position: fixed;
  top: 18px; left: 50%;
  transform: translateX(-50%);
  z-index: 2500;
  max-width: min(92vw, 560px);
  display: flex; align-items: center; gap: 10px;
  padding: 12px 16px;
  background: var(--bg-secondary);
  border: 1px solid var(--warning);
  border-radius: var(--radius);
  color: var(--text-primary);
  font-size: 0.85rem;
  box-shadow: var(--shadow);
}
.mode-notice i { color: var(--warning); }
.mode-notice .mode-notice-ok {
  margin-left: 6px;
  padding: 8px 16px;
  min-height: 40px;
  background: var(--accent); color: #fff;
  border: none; border-radius: var(--radius-sm);
  font-weight: 700; cursor: pointer;
}
@media (max-width: 768px) {
  #mode-3d-switch { left: 12px; bottom: 84px; }
  #basemap-switch { left: 12px; bottom: 146px; }
}

/* ===== AI route planner (ported from NZ) ===== */
.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); }
.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; }

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


/* ===== 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 notice in nav. Appended at the END on purpose: this stylesheet
   carries duplicated .radar-note blocks, so a rule placed 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; }
}
