/* GPX Rider dark UI — implements the Claude Design handoff (screens 2a
   route briefing, 4a gallery overlay, 5a settings dialog). Reusable
   components: .btn variants, .panel-card, .stat-tile, .switch,
   .setting-row / .setting-slider, .icon-btn, .status-dot. */

:root {
  color-scheme: dark;
  /* surfaces */
  --bg: #0e1116;
  --bar: #12151a;
  --card: #161a21;
  --line: rgba(255, 255, 255, 0.08);
  --line-soft: rgba(255, 255, 255, 0.06);
  --line-strong: rgba(255, 255, 255, 0.14);
  /* text */
  --ink: #e8eaef;
  --ink-bright: #f2f3f6;
  --muted: #9aa0ac;
  --faint: #7c828e;
  --faintest: #5f646e;
  /* accents */
  --accent: #f6a52c;
  --accent-ink: #12151a;
  --blue: #5aa9ff;
  --blue-soft: #7fc0ff;
  --green: #4ec06f;
  --red: #e4574c;
  --salmon: #e08a6f;
  /* grade palette (matches profile.mjs + gallery mini profiles) */
  --grade-down: #57b877;
  --grade-climb: #e8b74e;
  --grade-steep: #d9542f;
  /* fonts */
  --font-ui: "Space Grotesk", ui-sans-serif, system-ui, sans-serif;
  --font-num: "JetBrains Mono", ui-monospace, monospace;
  --font-mono: "IBM Plex Mono", ui-monospace, monospace;
  --font-serif: "Spectral", Georgia, serif;
}

* {
  box-sizing: border-box;
}

/* components set their own display; the hidden attribute must still win */
[hidden] {
  display: none !important;
}

html,
body {
  height: 100%;
  margin: 0;
}

body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-ui);
}

@keyframes livepulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.35; }
}

@keyframes logoPulse {
  0%,
  100% {
    box-shadow: 0 0 5px 1px rgba(246, 165, 44, 0.55);
    opacity: 0.7;
  }
  50% {
    box-shadow: 0 0 13px 3px rgba(246, 165, 44, 1);
    opacity: 1;
  }
}

/* ---- app shell: top bar + map | control panel ---------------------------- */

.app-shell {
  display: flex;
  flex-direction: column;
  height: 100vh;
  min-height: 620px;
}

.top-bar {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  height: 62px;
  padding: 0 22px;
  background: var(--bar);
  border-bottom: 1px solid rgba(255, 255, 255, 0.07);
}

.top-bar-group {
  display: flex;
  align-items: center;
  gap: 14px;
  min-width: 0;
}

.brand {
  display: flex;
  align-items: center;
  gap: 9px;
  text-decoration: none;
}

.brand-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--accent);
  animation: logoPulse 2s ease-in-out infinite;
}

.brand-name {
  font: 600 13px/1 var(--font-mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink);
}

.top-bar-divider {
  width: 1px;
  height: 22px;
  background: rgba(255, 255, 255, 0.1);
}

.gpx-chip {
  display: flex;
  align-items: center;
  gap: 9px;
  min-width: 0;
  padding: 8px 12px;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.09);
  border-radius: 10px;
}

.gpx-chip-tag {
  font: 600 11px/1 var(--font-mono);
  letter-spacing: 0.05em;
  color: var(--blue-soft);
}

.gpx-chip-name {
  overflow: hidden;
  font: 500 12px/1 var(--font-mono);
  color: #c7cad2;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ---- buttons -------------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 36px;
  padding: 8px 14px;
  border: 1px solid transparent;
  border-radius: 10px;
  font: 600 12px/1 var(--font-ui);
  cursor: pointer;
  background: transparent;
  color: var(--ink);
}

.btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.btn-ghost {
  border-color: rgba(255, 255, 255, 0.1);
  color: rgba(255, 255, 255, 0.82);
}

.btn-ghost:not(:disabled):hover {
  border-color: rgba(255, 255, 255, 0.25);
  background: rgba(255, 255, 255, 0.04);
}

.btn-blue {
  border-color: rgba(90, 169, 255, 0.55);
  background: rgba(90, 169, 255, 0.18);
  color: #c4e0ff;
}

.btn-blue:not(:disabled):hover {
  background: rgba(90, 169, 255, 0.28);
}

.btn-accent {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
}

.btn-accent:not(:disabled):hover {
  filter: brightness(1.08);
}

.btn-outline-blue {
  border-color: rgba(127, 192, 255, 0.35);
  color: var(--blue-soft);
}

.btn-outline-blue:not(:disabled):hover {
  background: rgba(127, 192, 255, 0.1);
}

.btn-outline-danger {
  border-color: rgba(224, 138, 111, 0.4);
  color: var(--salmon);
}

.btn-outline-danger:not(:disabled):hover {
  background: rgba(224, 138, 111, 0.1);
}

.btn-sm {
  min-height: 32px;
  padding: 7px 12px;
  font-size: 11px;
}

.count-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 19px;
  height: 19px;
  padding: 0 5px;
  background: var(--blue);
  border-radius: 5px;
  font: 700 10px/1 var(--font-mono);
  color: var(--bg);
}

.icon-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 11px;
  background: rgba(255, 255, 255, 0.06);
  color: rgba(255, 255, 255, 0.8);
  cursor: pointer;
}

.icon-btn:hover {
  background: rgba(255, 255, 255, 0.1);
}

.file-picker {
  position: relative;
}

.file-picker input {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  opacity: 0;
  pointer-events: none;
}

.file-picker span {
  display: contents;
}

/* ---- map pane -------------------------------------------------------------- */

.app-body {
  flex: 1;
  display: flex;
  min-height: 0;
}

.map-pane {
  flex: 1;
  position: relative;
  min-width: 0;
  background: #0b0d10;
}

.map-viewport {
  position: absolute;
  inset: 0;
}

.map-viewport.fullscreen-mode {
  position: fixed;
  inset: 0;
  z-index: 40;
  background: #000;
}

/* "Theater mode": pins the map viewport to an exact CSS-pixel box, centered
   over a dimmed backdrop (the huge box-shadow spread), so a screen recording
   captures a consistent size without needing the browser window itself
   resized (most browsers block scripted resizing of a window/tab they didn't
   open via window.open()). The size is RECORDING_MAP_VIEWPORT_* from
   tuning.yaml, stamped onto these variables at boot by initTheaterModeUi —
   never hardcode it here. Shrinks via max-width/height if the browser window
   itself is smaller than the recording size. */
.map-viewport.theater-mode {
  position: fixed;
  inset: 0;
  z-index: 45;
  width: var(--recording-viewport-w, 1280px);
  height: var(--recording-viewport-h, 720px);
  max-width: 100vw;
  max-height: 100vh;
  margin: auto;
  background: #0b0d10;
  box-shadow: 0 0 0 100vmax rgba(4, 6, 9, 0.86);
}

/* Optional per-overlay hiding while in theater mode (Demo mode panel
   checkboxes), for a clean showcase recording. The classes are set
   independent of theater mode itself, so these rules only bite once
   .theater-mode is also present. */
.map-viewport.theater-mode.theater-hide-clock #fullscreenClock {
  display: none;
}

.map-viewport.theater-mode.theater-hide-meters #fullscreenTrainingMeters {
  display: none;
}

.map-viewport.theater-mode.theater-hide-dock #fullscreenOverlayBottom {
  display: none;
}

.map-viewport.theater-mode.theater-hide-climb-banner #climbBanner {
  display: none;
}

.map-viewport.theater-mode.theater-hide-demo-chip #demoBanner {
  display: none;
}

.map-viewport.theater-mode.theater-hide-controls .map-actions,
.map-viewport.theater-mode.theater-hide-controls #resetCameraControl,
.map-viewport.theater-mode.theater-hide-controls #mapOverviewControl,
.map-viewport.theater-mode.theater-hide-controls #climbOverviewControl {
  display: none;
}

.map-viewport.theater-mode.theater-hide-minimap #minimap {
  display: none;
}

#map {
  position: absolute;
  inset: 0;
}

#map gmp-map-3d {
  display: block;
  width: 100%;
  height: 100%;
}

/* visibility (not display:none) keeps the Google map instance laid out, so
   re-enabling the minimap never shows stale gray tiles needing a resize */
#minimap.minimap-hidden {
  visibility: hidden;
}

#minimap {
  width: 150px;
  height: 150px;
  overflow: hidden;
  border-radius: 12px;
  border: 1px solid rgba(255, 255, 255, 0.14);
  box-shadow: 0 3px 14px rgba(0, 0, 0, 0.45);
  pointer-events: none;
}

.map-actions {
  display: flex;
  align-items: flex-start;
  gap: 8px;
}

/* Our own buttons leave the shot while a screenshot is being captured;
   Google's attribution must always stay in. */
.map-viewport.capturing .map-actions {
  visibility: hidden;
}

/* Developer camera-debug overlay: a translucent readout under the action
   buttons, top-right. Shown in windowed and fullscreen; kept out of
   screenshots like the buttons. */
.camera-debug {
  min-width: 168px;
  padding: 9px 11px;
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: 12px;
  background: rgba(13, 16, 21, 0.62);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  color: rgba(255, 255, 255, 0.85);
  /* Selectable: the box captures the pointer (so a drag over it selects text
     to copy, rather than panning the map underneath) and allows text
     selection. It's small and out of the way, so it doesn't get in the way of
     map interaction elsewhere. */
  pointer-events: auto;
  user-select: text;
  -webkit-user-select: text;
  cursor: text;
}

.map-viewport.capturing .camera-debug {
  visibility: hidden;
}

.camera-debug-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 7px;
  user-select: none;
  -webkit-user-select: none;
}

.camera-debug-title {
  font: 700 9px/1 var(--font-mono);
  letter-spacing: 0.14em;
  color: var(--accent);
}

.camera-debug-toggle {
  display: inline-grid;
  place-items: center;
  flex: none;
  width: 19px;
  height: 19px;
  padding: 0;
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 5px;
  background: rgba(255, 255, 255, 0.08);
  color: rgba(255, 255, 255, 0.78);
  cursor: pointer;
}

.camera-debug-toggle:hover {
  background: rgba(255, 255, 255, 0.14);
  color: #fff;
}

.camera-debug-toggle-icon {
  transition: transform 120ms ease;
}

.camera-debug.collapsed {
  min-width: 128px;
}

.camera-debug.collapsed .camera-debug-head {
  margin-bottom: 0;
}

.camera-debug.collapsed .camera-debug-toggle-icon {
  transform: rotate(-90deg);
}

.camera-debug.collapsed .camera-debug-body {
  display: none;
}

.camera-debug-body {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 2px 12px;
  margin: 0;
  font: 500 11px/1.35 var(--font-mono);
}

.camera-debug-body dt {
  color: rgba(255, 255, 255, 0.5);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.camera-debug-body dd {
  margin: 0;
  text-align: right;
  color: rgba(255, 255, 255, 0.92);
  font-variant-numeric: tabular-nums;
}

.map-action-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: 12px;
  background: rgba(13, 16, 21, 0.55);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  color: rgba(255, 255, 255, 0.85);
  cursor: pointer;
}

.map-action-btn:hover {
  border-color: rgba(255, 255, 255, 0.3);
}

/* Toggle buttons (center-on-rider): amber while active, plain white when
   off — matching the amber accent used for "on" states elsewhere. */
.map-action-btn[aria-pressed="true"] {
  border-color: rgba(246, 165, 44, 0.5);
  color: var(--accent);
}

.map-action-btn:disabled {
  opacity: 0.42;
  cursor: default;
}

.map-action-btn:disabled:hover {
  border-color: rgba(255, 255, 255, 0.14);
}

.map-overview-control {
  position: relative;
  display: flex;
  height: 42px;
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: 12px;
  background: rgba(13, 16, 21, 0.55);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  color: rgba(255, 255, 255, 0.85);
}

.map-overview-control:hover {
  border-color: rgba(255, 255, 255, 0.3);
}

.map-overview-control.active {
  border-color: rgba(246, 165, 44, 0.5);
  color: var(--accent);
}

.map-overview-control .map-action-btn {
  width: 40px;
  height: 40px;
  border: 0;
  border-radius: 0;
  background: transparent;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  color: inherit;
}

.map-overview-control .map-action-btn:hover {
  border-color: transparent;
  background: rgba(255, 255, 255, 0.08);
}

.icon-segment-focus {
  display: none;
}

.map-climb-overview-control.segment-focus .icon-climb-focus {
  display: none;
}

.map-climb-overview-control.segment-focus .icon-segment-focus {
  display: block;
}

.map-overview-toggle {
  border-radius: 11px 0 0 11px !important;
}

.map-overview-menu-btn {
  width: 29px !important;
  border-left: 1px solid rgba(255, 255, 255, 0.16) !important;
  border-radius: 0 11px 11px 0 !important;
}

.map-overview-menu {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 132px;
  padding: 6px;
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: 12px;
  background: rgba(13, 16, 21, 0.74);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.4);
  z-index: 8;
}

.map-overview-menu[hidden] {
  display: none;
}

.map-overview-menu button {
  display: flex;
  align-items: center;
  width: 100%;
  min-height: 32px;
  padding: 0 10px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: rgba(255, 255, 255, 0.82);
  font: 700 12px/1 var(--font-ui);
  text-align: left;
  cursor: pointer;
}

.map-overview-menu button:hover {
  background: rgba(255, 255, 255, 0.09);
  color: #fff;
}

.map-overview-menu button[aria-checked="true"] {
  background: rgba(246, 165, 44, 0.16);
  color: var(--accent);
}

.icon-fs-exit {
  display: none;
}

.map-viewport.fullscreen-mode .icon-fs-enter {
  display: none;
}

.map-viewport.fullscreen-mode .icon-fs-exit {
  display: block;
}

/* Simulation button: play triangle by default, stop square while running. */
.icon-sim-stop {
  display: none;
}

#startBtn.sim-running .icon-sim-play {
  display: none;
}

#startBtn.sim-running .icon-sim-stop {
  display: inline;
}

/* ---- ride HUD --------------------------------------------------------------
   The clock chip, climb banner, training meters and data dock are children of
   .map-viewport, so the same component renders in the setup map and follows it
   into fullscreen. A shared glass surface (--fs-glass*) ties them together. */

:root {
  --fs-glass-bg: rgba(13, 16, 21, 0.3);
  --fs-glass-border: rgba(255, 255, 255, 0.14);
  --fs-label: rgba(255, 255, 255, 0.5);
  --fs-dock-inset: 12px;
  --fs-dock-gap: 10px;
}

.map-action-btn-settings {
  display: flex;
}

/* ---- HUD layout regions (screen-manager.mjs) -------------------------------
   Four flex stacks the screen manager places registered HUD components into:
   left / center / right columns plus a full-width bottom stack. Features
   never absolutely position their own HUD elements — ordering inside a
   column is the registration weight, spacing is the region gap, and hiding a
   component collapses its slot. Insets and their phone adjustments live here
   once instead of per component. */

.map-viewport {
  --hud-inset: 24px;
  --hud-gap: 12px;
  --hud-bottom-inset-x: 24px;
  --hud-bottom-inset-y: 36px;
  /* Side columns stop above the bottom stack: map's bottom strip (Google
     attribution) + the live measured bottom-region height + a gap. */
  --hud-bottom-clearance: calc(36px + var(--fs-dock-height, 210px) + 12px);
}

.hud-region {
  position: absolute;
  z-index: 10;
  display: flex;
  flex-direction: column;
  gap: var(--hud-gap);
  /* The containers span map area; only the components themselves take input,
     so the map stays draggable everywhere between them. */
  pointer-events: none;
}

.hud-region > * {
  pointer-events: auto;
  /* Components keep their intrinsic size — a short column must never squash
     them (the columns already end above the bottom stack, so overflow there
     means the viewport is genuinely too small, not a layout error). */
  flex-shrink: 0;
}

/* Pins a component to the far end of its column (minimap, bottom-right). */
.hud-align-end {
  margin-top: auto;
}

.hud-region-left {
  top: var(--hud-inset);
  left: var(--hud-inset);
  bottom: var(--hud-bottom-clearance);
  align-items: flex-start;
}

.hud-region-right {
  top: var(--hud-inset);
  right: var(--hud-inset);
  bottom: var(--hud-bottom-clearance);
  align-items: flex-end;
}

.hud-region-center {
  top: var(--hud-inset);
  left: 50%;
  transform: translateX(-50%);
  max-width: calc(100% - 2 * var(--hud-inset));
  align-items: center;
  gap: 10px;
}

/* One full-width panel/stack; children stretch across it. */
.hud-region-bottom {
  left: var(--hud-bottom-inset-x);
  right: var(--hud-bottom-inset-x);
  bottom: var(--hud-bottom-inset-y);
  align-items: stretch;
  gap: 10px;
}

/* top-left: local time + elapsed + ridden distance */
.fs-clock {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 11px 16px;
  border-radius: 12px;
  background: var(--fs-glass-bg);
  border: 1px solid rgba(255, 255, 255, 0.12);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
}

.fs-clock-time,
.fs-clock-elapsed {
  font: 600 17px/1 var(--font-num);
  color: #fff;
}

.fs-clock-elapsed {
  color: rgba(255, 255, 255, 0.72);
}

.fs-clock-sep {
  width: 1px;
  height: 15px;
  background: rgba(255, 255, 255, 0.18);
}

.fs-clock-dist {
  font: 600 15px/1 var(--font-num);
  color: var(--blue-soft);
}

.fs-clock-ascent {
  font: 600 15px/1 var(--font-num);
  color: var(--accent);
}

.fs-training-meters {
  display: grid;
  width: 184px;
  gap: 8px;
}

.fs-zone-meter {
  display: grid;
  gap: 6px;
  padding: 10px 12px;
  border: 1px solid var(--fs-glass-border);
  border-radius: 10px;
  background: var(--fs-glass-bg);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
}

.fs-zone-label,
.fs-zone-meta {
  font: 600 9px/1 var(--font-ui);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--fs-label);
}

.fs-zone-meter strong {
  font: 600 20px/1 var(--font-num);
  color: #fff;
}

.fs-zone-track {
  position: relative;
  height: 5px;
  overflow: visible;
  border-radius: 3px;
  background: rgba(255, 255, 255, 0.14);
}

.fs-zone-fill {
  position: absolute;
  top: -4px;
  bottom: -4px;
  left: 0;
  width: 2px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.96);
  box-shadow:
    0 0 0 1px rgba(255, 255, 255, 0.18),
    0 0 8px rgba(255, 255, 255, 0.9),
    0 0 14px rgba(255, 255, 255, 0.55);
  transform: translateX(-50%);
  transition: left 0.18s ease, opacity 0.18s ease;
}

.fs-zone-fill.is-empty {
  opacity: 0;
}

/* top-center: climb banner */
.climb-banner {
  display: block;
  min-width: 420px;
  padding: 14px 20px 15px;
  border-radius: 16px;
  background: var(--fs-glass-bg);
  border: 1px solid var(--fs-glass-border);
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
}

.climb-banner-ahead {
  display: flex;
  align-items: center;
  gap: 22px;
}

.cb-lead {
  flex: none;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* "climb N of M" ordinal, matching the setup page's live climb status. */
.cb-order {
  font: 600 9px/1 var(--font-mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.45);
}

.climb-banner-on .cb-order {
  display: block;
  margin-bottom: 11px;
}

.cb-category {
  align-self: flex-start;
  padding: 6px 9px;
  border-radius: 6px;
  font: 700 10px/1 var(--font-mono);
  letter-spacing: 0.06em;
  color: var(--accent-ink);
  background: var(--accent);
}

.cb-in {
  display: flex;
  align-items: baseline;
  gap: 5px;
}

.cb-in-label {
  font: 600 8px/1 var(--font-ui);
  letter-spacing: 0.13em;
  color: var(--fs-label);
}

.cb-in-value {
  font: 600 26px/1 var(--font-num);
  letter-spacing: -0.02em;
  color: var(--accent);
}

.cb-in-unit {
  font: 500 11px/1 var(--font-ui);
  color: var(--fs-label);
}

.cb-mini {
  flex: none;
  width: 150px;
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.cb-mini-bars {
  height: 40px;
  display: flex;
  align-items: flex-end;
  gap: 1.5px;
}

.cb-mini-bars i {
  flex: 1;
  border-radius: 1px 1px 0 0;
}

.cb-mini-alts {
  display: flex;
  justify-content: space-between;
  font: 500 9px/1 var(--font-mono);
  color: rgba(255, 255, 255, 0.45);
}

.cb-divider {
  align-self: stretch;
  width: 1px;
  background: rgba(255, 255, 255, 0.12);
}

.cb-stats {
  display: flex;
  gap: 24px;
}

.cb-stat span {
  display: block;
  font: 600 8px/1 var(--font-ui);
  letter-spacing: 0.13em;
  color: var(--fs-label);
}

.cb-stat strong {
  display: block;
  margin-top: 6px;
  font: 600 16px/1 var(--font-num);
  color: #fff;
}

.cb-stat-accent {
  color: var(--accent) !important;
}

.climb-banner-on {
  display: block;
}

.segment-banner {
  display: grid;
  gap: 11px;
}

.cb-progress {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 13px;
}

.cb-progress-track {
  position: relative;
  height: 5px;
  border-radius: 3px;
  background: rgba(255, 255, 255, 0.14);
  overflow: hidden;
}

.cb-progress-fill {
  height: 100%;
  border-radius: 3px;
  transition: width 0.2s ease;
}

/* bottom data dock */
.fs-dock {
  /* Relative: .fs-dock-top-tools inside anchors to the dock's own corner.
     The bottom region places the dock; its 36px inset leaves the map's
     bottom strip clear for the Google logo/legal notices (ToS). */
  position: relative;
  width: 100%;
  display: block;
  padding: var(--fs-dock-inset);
  border-radius: 20px;
  background: rgba(11, 14, 19, 0.1);
  border: 1px solid rgba(255, 255, 255, 0.16);
  backdrop-filter: blur(34px) saturate(1.2);
  -webkit-backdrop-filter: blur(34px) saturate(1.2);
}

.fs-dock-top-tools {
  position: absolute;
  top: var(--fs-dock-inset);
  right: var(--fs-dock-inset);
  z-index: 3;
  display: flex;
  align-items: center;
  gap: 6px;
}

.fs-dock-toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: 7px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  background: rgba(255, 255, 255, 0.06);
  color: rgba(255, 255, 255, 0.75);
  cursor: pointer;
}

.fs-dock-toggle:hover {
  border-color: rgba(255, 255, 255, 0.3);
}

.fs-dock-metric-wrap {
  flex: none;
  display: flex;
  align-items: stretch;
  gap: 8px;
}

.fs-dock-field-controls {
  flex: none;
  display: grid;
  align-self: center;
  gap: 6px;
}

.fs-dock-field-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 7px;
  color: rgba(255, 255, 255, 0.78);
  background: rgba(255, 255, 255, 0.06);
  font: 700 13px/1 var(--font-ui);
  cursor: pointer;
}

.fs-dock-field-btn:disabled {
  cursor: default;
  opacity: 0.38;
}

.fs-dock-toggle svg {
  transition: transform 0.2s ease;
}

/* Expanded: chevron points down (collapse); collapsed: points up (expand). */
.fs-dock.collapsed .fs-dock-toggle svg {
  transform: rotate(180deg);
}

.fs-dock-body {
  display: flex;
  align-items: stretch;
  gap: var(--fs-dock-gap);
}

/* Give the expanded road-ahead view a little more breathing room without
   changing the compact collapsed strip. */
.fs-dock:not(.collapsed) .fs-dock-body {
  min-height: 186px;
}

/* Two rows of tiles; the column count and tile width are set from JS to fit
   however many data fields the user enabled in Settings (fewer = wider, up to
   eight = narrower). See layoutMetricTiles() in app.js. */
.fs-dock-metrics {
  display: grid;
  height: 100%;
  grid-template-rows: repeat(2, 1fr);
  grid-auto-flow: column;
  grid-auto-columns: var(--metric-tile-w, 150px);
  gap: 8px;
  align-content: center;
}

.fs-tile {
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 10px 12px;
  border-radius: 10px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  background: rgba(255, 255, 255, 0.05);
  cursor: grab;
  user-select: none;
}

.fs-tile.dragging {
  opacity: 0.45;
}

.fs-tile.drag-over {
  border-color: rgba(246, 165, 44, 0.78);
  background: rgba(246, 165, 44, 0.12);
}

.fs-tile-label {
  font: 600 10px/1 var(--font-ui);
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--fs-label);
}

.fs-tile-value {
  margin-top: 7px;
  font: 600 20px/1 var(--font-num);
  letter-spacing: -0.02em;
  color: #fff;
}

.fs-dock-sep {
  flex: none;
  width: 1px;
  background: rgba(255, 255, 255, 0.1);
}

.fs-dock-right {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.fs-road-head {
  display: flex;
  align-items: center;
  margin-bottom: 6px;
  min-height: 26px;
  padding-right: 168px;
}

.fs-road-title {
  display: flex;
  align-items: center;
  gap: 9px;
  min-width: 0;
}

.fs-road-eyebrow {
  flex: none;
  font: 600 12px/1 var(--font-ui);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.72);
}

.fs-road-note {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font: 500 11px/1 var(--font-mono);
  color: rgba(255, 255, 255, 0.4);
}

.profile-series-toggle {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

.profile-series-toggle button {
  min-height: 24px;
  padding: 0 7px;
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: 7px;
  color: rgba(255, 255, 255, 0.62);
  background: rgba(255, 255, 255, 0.05);
  font: 600 9px/1 var(--font-ui);
  cursor: pointer;
}

.profile-series-toggle button[data-profile-series="speed"] {
  --series-active-color: var(--blue);
  --series-active-ink: #06101b;
}

.profile-series-toggle button[data-profile-series="power"] {
  --series-active-color: var(--accent);
  --series-active-ink: var(--accent-ink);
}

.profile-series-toggle button[data-profile-series="heartRate"] {
  --series-active-color: var(--red);
  --series-active-ink: #fff;
}

.fs-dock-series-toggle button {
  min-width: 38px;
  min-height: 26px;
}

.profile-series-toggle button[aria-pressed="true"] {
  color: var(--series-active-ink, #11141a);
  background: var(--series-active-color, var(--accent));
  border-color: transparent;
}

.fs-road-stat {
  display: flex;
  align-items: baseline;
  gap: 7px;
}

.fs-road-stat span {
  font: 600 10px/1 var(--font-ui);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--fs-label);
}

.fs-road-stat strong {
  font: 600 15px/1 var(--font-num);
  color: #fff;
}

.fs-road-stat-accent {
  color: var(--accent) !important;
}

.fs-road-plot {
  position: relative;
  flex: 1;
  min-height: 92px;
}

.fs-dock-progress {
  display: flex;
  gap: var(--fs-dock-gap);
  margin-top: 8px;
}

.fs-bar {
  flex: 1;
}

.fs-bar-head {
  display: flex;
  justify-content: space-between;
  margin-bottom: 5px;
}

.fs-bar-head span:first-child {
  font: 600 10px/1 var(--font-ui);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.55);
}

.fs-bar-value {
  font: 600 12px/1 var(--font-num);
  color: #fff;
}

.fs-bar-value-accent {
  color: var(--accent);
}

.fs-bar-track {
  height: 6px;
  border-radius: 5px;
  background: rgba(255, 255, 255, 0.14);
  overflow: hidden;
}

.fs-bar-fill {
  height: 100%;
  border-radius: 5px;
  transition: width 0.2s ease;
}

.fs-bar-fill-blue {
  background: var(--blue);
}

.fs-bar-fill-amber {
  background: var(--accent);
}

/* Collapsed dock: drop the road-ahead profile, shrink the tiles into a single
   inline strip, and keep the two progress bars beside each other. */
.fs-dock.collapsed .fs-dock-body {
  align-items: center;
  gap: var(--fs-dock-gap);
}

.fs-dock.collapsed .fs-dock-metrics {
  display: flex;
  gap: 16px;
}

.fs-dock.collapsed .fs-dock-metric-wrap {
  align-items: center;
}

.fs-dock.collapsed .fs-dock-body {
  padding-right: 0;
}

.fs-dock.collapsed .fs-dock-right {
  padding-right: 40px;
}

.fs-dock.collapsed .fs-dock-field-controls {
  display: flex;
  gap: 6px;
}

.fs-dock.collapsed .fs-dock-top-tools {
  top: 50%;
  transform: translateY(-50%);
}

.fs-dock.collapsed .fs-dock-series-toggle {
  display: none;
}

.fs-dock.collapsed .fs-tile {
  padding: 0;
  border: none;
  background: none;
  border-radius: 0;
}

.fs-dock.collapsed .fs-tile-value {
  margin-top: 6px;
  font-size: 20px;
}

.fs-dock.collapsed .fs-road-head,
.fs-dock.collapsed .fs-road-plot {
  display: none;
}

.fs-dock.collapsed .fs-dock-progress {
  gap: var(--fs-dock-gap);
  margin-top: 0;
}

.fs-dock.collapsed .fs-bar-track {
  height: 5px;
}

#profile {
  width: 100%;
  height: 128px;
  cursor: pointer;
  touch-action: none;
}

#profile.profile-translucent {
  position: absolute;
  inset: 0;
  height: 100%;
  border-radius: 10px;
}

/* ---- control panel --------------------------------------------------------- */

.control-pane {
  width: 556px;
  flex: none;
  display: flex;
  flex-direction: column;
  gap: 15px;
  padding: 22px 26px;
  overflow-y: auto;
  background: var(--bar);
  border-left: 1px solid rgba(255, 255, 255, 0.07);
}

.stat-grid {
  display: grid;
  gap: 1px;
  overflow: hidden;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: 12px;
}

.stat-grid-4 {
  grid-template-columns: repeat(4, 1fr);
  flex: none;
}

.stat-grid-live {
  grid-template-columns: repeat(5, 1fr);
}

.stat-tile {
  padding: 13px;
  background: var(--card);
  min-width: 0;
}

.stat-label {
  display: block;
  font: 600 9px/1 var(--font-ui);
  letter-spacing: 0.11em;
  color: var(--faint);
  text-transform: uppercase;
}

.stat-value {
  display: block;
  margin-top: 9px;
  font: 600 19px/1 var(--font-num);
  color: var(--ink-bright);
  letter-spacing: -0.02em;
  white-space: nowrap;
}

.stat-value-sm {
  font-size: 14px;
}

.stat-detail {
  display: block;
  margin-top: 6px;
  font: 500 9px/1.3 var(--font-ui);
  color: var(--faint);
}

/* ---- cards ------------------------------------------------------------------ */

.panel-card {
  flex: none;
  padding: 14px 16px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--card);
}

.panel-card-flush {
  padding: 0;
  overflow: hidden;
}

.panel-card-zone-help {
  overflow: visible;
}

.panel-card-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
}

.panel-card-title {
  font: 600 11px/1 var(--font-ui);
  letter-spacing: 0.13em;
  color: #c2c6cf;
  text-transform: uppercase;
}

.panel-card-hint {
  margin: 6px 0 0;
  font: 400 11px/1.4 var(--font-ui);
  color: var(--faint);
}

.gallery-export-card {
  display: grid;
  gap: 13px;
}

.gallery-export-fields {
  display: grid;
  gap: 11px;
}

.gallery-export-fields label {
  display: grid;
  gap: 7px;
}

.gallery-export-fields label > span {
  font: 600 9px/1 var(--font-ui);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--faint);
}

.gallery-export-fields input,
.gallery-export-fields textarea {
  width: 100%;
  min-width: 0;
  border: 1px solid rgba(255, 255, 255, 0.09);
  border-radius: 9px;
  background: rgba(255, 255, 255, 0.045);
  color: var(--ink);
  font: 500 12px/1.4 var(--font-ui);
}

.gallery-export-fields input {
  height: 35px;
  padding: 0 11px;
}

.gallery-export-fields textarea {
  resize: vertical;
  padding: 10px 11px;
}

.gallery-export-fields input:disabled,
.gallery-export-fields textarea:disabled {
  opacity: 0.55;
}

.gallery-metadata-output {
  max-height: 320px;
  font-family: var(--font-mono);
  font-size: 11px;
  color: #cbd6e6;
}

.profile-legend {
  display: flex;
  align-items: center;
  gap: 13px;
}

.profile-head-tools {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  justify-content: flex-end;
}

.profile-legend span {
  display: flex;
  align-items: center;
  gap: 5px;
  font: 500 10px/1 var(--font-ui);
  color: #8b909c;
}

.profile-legend i {
  width: 8px;
  height: 8px;
  border-radius: 2px;
}

.rider-zone-form {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
  padding: 12px 14px;
  border-top: 1px solid var(--line);
}

.rider-zone-form label {
  display: grid;
  gap: 6px;
}

.rider-zone-form span {
  font: 600 9px/1 var(--font-ui);
  letter-spacing: 0.11em;
  color: var(--faint);
  text-transform: uppercase;
}

.rider-zone-form input {
  min-width: 0;
  height: 34px;
  padding: 0 9px;
  border: 1px solid var(--line-strong);
  border-radius: 8px;
  color: var(--ink);
  background: rgba(255, 255, 255, 0.04);
  font: 600 13px/1 var(--font-num);
}

.zone-editor {
  display: grid;
  gap: 12px;
  padding: 12px 14px 14px;
  border-top: 1px solid var(--line);
}

.zone-editor-note {
  margin: 0;
  font: 400 11px/1.45 var(--font-ui);
  color: var(--faint);
}

.zone-editor-section {
  position: relative;
  display: grid;
  gap: 7px;
}

.zone-editor-title {
  display: flex;
  align-items: center;
  gap: 6px;
  font: 600 9px/1 var(--font-ui);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #c2c6cf;
}

.zone-help-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 17px;
  height: 17px;
  padding: 0;
  border: 1px solid var(--line-strong);
  border-radius: 50%;
  color: var(--faint);
  background: rgba(255, 255, 255, 0.04);
  font: 700 10px/1 var(--font-ui);
  cursor: pointer;
}

.zone-help-btn[aria-expanded="true"] {
  color: var(--accent);
  border-color: rgba(246, 165, 44, 0.55);
  background: rgba(246, 165, 44, 0.12);
}

.zone-help-popover {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  gap: 7px 10px;
  padding: 10px 12px;
  border: 1px solid var(--line-strong);
  border-radius: 10px;
  color: var(--ink);
  background: rgba(18, 22, 29, 0.96);
  box-shadow: 0 16px 34px rgba(0, 0, 0, 0.38);
}

.zone-help-popover[hidden] {
  display: none;
}

.zone-help-popover strong {
  font: 700 10px/1.25 var(--font-ui);
  color: var(--ink-bright);
}

.zone-help-popover span {
  font: 500 10px/1.35 var(--font-ui);
  color: var(--muted);
}

.zone-summary {
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: 8px;
  color: var(--ink);
  background: rgba(255, 255, 255, 0.035);
  font: 500 11px/1.45 var(--font-mono);
}

/* ---- climbs ----------------------------------------------------------------- */

.climbs-section {
  margin-top: 11px;
  padding-top: 11px;
  border-top: 1px solid var(--line-soft);
}

.climbs-section[hidden] {
  display: none;
}

.climb-status {
  display: flex;
  align-items: baseline;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 9px;
}

.climb-status strong {
  font: 600 12px/1.3 var(--font-ui);
  color: var(--accent);
}

.climb-status span {
  font: 500 11px/1.3 var(--font-mono);
  color: var(--muted);
}

.climbs-list {
  display: grid;
  gap: 5px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.climbs-list li {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  padding: 7px 10px;
  border: 1px solid var(--line-soft);
  border-radius: 8px;
  font: 500 11px/1.3 var(--font-mono);
  color: #c2c6cf;
}

.climbs-list li.active {
  border-color: rgba(246, 165, 44, 0.45);
  background: rgba(246, 165, 44, 0.08);
}

.climbs-list li.focused {
  border-color: rgba(255, 255, 255, 0.7);
  background: rgba(246, 165, 44, 0.12);
  box-shadow: 0 0 14px rgba(246, 165, 44, 0.28);
}

.climbs-list li.climb-seekable {
  cursor: pointer;
}

.climbs-list li.climb-seekable:hover,
.climbs-list li.climb-seekable:focus-visible {
  border-color: var(--line-strong);
  background: rgba(255, 255, 255, 0.04);
  outline: none;
}

.climbs-list .climb-index {
  color: var(--faintest);
}

.climbs-list .climb-grade {
  color: var(--grade-climb);
  font-weight: 600;
}

/* ---- ride progress ----------------------------------------------------------- */

.progress-wrap {
  display: grid;
  gap: 7px;
  margin-top: 13px;
}

progress {
  width: 100%;
  height: 6px;
  overflow: hidden;
  border: 0;
  border-radius: 4px;
  background: rgba(255, 255, 255, 0.12);
}

progress::-webkit-progress-bar {
  background: rgba(255, 255, 255, 0.12);
}

progress::-webkit-progress-value {
  background: var(--blue);
  border-radius: 4px;
}

progress::-moz-progress-bar {
  background: var(--blue);
  border-radius: 4px;
}

/* Ascent progress: amber so climbing progress reads apart from distance. */
progress.ascent-progress::-webkit-progress-value {
  background: var(--accent);
}

progress.ascent-progress::-moz-progress-bar {
  background: var(--accent);
}

.progress-note {
  font: 500 10px/1.3 var(--font-mono);
  color: var(--faint);
}

.stat-grid-live {
  margin-top: 13px;
}

/* ---- connections -------------------------------------------------------------- */

.connection-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 13px 16px;
}

.connection-row + .connection-row {
  border-top: 1px solid var(--line-soft);
}

.connection-info {
  display: flex;
  align-items: center;
  gap: 11px;
  min-width: 0;
}

.status-dot {
  flex: none;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: #4b5058;
}

.status-dot.connected {
  background: var(--green);
  box-shadow: 0 0 0 4px rgba(78, 192, 111, 0.16);
}

.connection-name {
  font: 600 13px/1 var(--font-ui);
  color: var(--ink);
}

.connection-status {
  margin-top: 5px;
  font: 500 11px/1 var(--font-mono);
  color: var(--faint);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.demo-card {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.demo-card-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
}

.demo-card-actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  flex-wrap: wrap;
}

.theater-hud-toggles {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px 14px;
  padding-top: 12px;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}

.theater-hud-toggles-label {
  font: 500 11px/1 var(--font-mono);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--faint);
  flex: 1 0 100%;
}

.theater-hud-toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12.5px;
  color: var(--muted);
  cursor: pointer;
  user-select: none;
}

.theater-hud-toggle input {
  accent-color: var(--accent);
  width: 14px;
  height: 14px;
  cursor: pointer;
}

.demo-card-actions .btn {
  white-space: nowrap;
}

.demo-card .btn[aria-pressed="true"] {
  color: #1b1205;
  border-color: rgba(246, 165, 44, 0.9);
  background: var(--accent);
}

.demo-banner {
  max-width: 100%;
  padding: 8px 12px;
  border: 1px solid rgba(246, 165, 44, 0.45);
  border-radius: 999px;
  color: #ffe4b6;
  background: rgba(18, 16, 12, 0.78);
  box-shadow: 0 14px 34px rgba(0, 0, 0, 0.32);
  font: 700 10px/1 var(--font-ui);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-align: center;
  white-space: normal;
  pointer-events: none;
  animation: demoBannerPulse 1.55s ease-in-out infinite;
}

.demo-banner[hidden] {
  display: none;
}

@keyframes demoBannerPulse {
  0%,
  100% {
    opacity: 0.76;
  }
  50% {
    opacity: 1;
  }
}

/* ---- FIT buffer ----------------------------------------------------------------- */

.recording-indicator {
  display: flex;
  align-items: center;
  gap: 7px;
  font: 600 11px/1 var(--font-ui);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--red);
}

.recording-indicator[hidden] {
  display: none;
}

.recording-pulse {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--red);
  animation: livepulse 1.6s ease-in-out infinite;
}

.rec-stats {
  display: flex;
  gap: 26px;
  flex-wrap: wrap;
  margin: 14px 0 0;
}

.rec-stats div {
  display: flex;
  flex-direction: column-reverse;
}

.rec-stats dt {
  margin-top: 6px;
  font: 500 9px/1 var(--font-ui);
  letter-spacing: 0.1em;
  color: var(--faint);
  text-transform: uppercase;
}

.rec-stats dd {
  margin: 0;
  font: 600 16px/1 var(--font-num);
  color: var(--ink-bright);
}

.button-row {
  display: flex;
  gap: 8px;
  margin-top: 15px;
}

.button-row .btn {
  flex: 1;
}

/* ---- simulation ------------------------------------------------------------------ */

.speed-control {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 14px;
}

.speed-label {
  font: 600 9px/1 var(--font-ui);
  letter-spacing: 0.11em;
  color: var(--faint);
  text-transform: uppercase;
}

.speed-control input {
  flex: 1;
}

.speed-control output {
  min-width: 60px;
  text-align: right;
  font: 600 13px/1 var(--font-num);
  color: var(--ink-bright);
}

input[type="range"] {
  accent-color: var(--accent);
}

/* ---- help note -------------------------------------------------------------------- */

.help-note {
  display: flex;
  align-items: flex-start;
  gap: 11px;
  flex: none;
  margin-top: auto;
  padding: 13px 15px;
  border: 1px dashed rgba(255, 255, 255, 0.15);
  border-radius: 12px;
  font: 400 12px/1.55 var(--font-ui);
  color: var(--muted);
}

.help-note-mark {
  margin-top: 1px;
  font: 700 12px/1 var(--font-mono);
  color: var(--blue-soft);
}

.help-note a {
  color: var(--ink);
  text-decoration: none;
  border-bottom: 1px solid rgba(255, 255, 255, 0.28);
}

/* ---- settings dialog (5a): category rail + panel ----------------------------------- */

.settings-dialog {
  width: min(1000px, calc(100vw - 48px));
  height: min(660px, calc(100vh - 48px));
  padding: 0;
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 20px;
  overflow: hidden;
  color: var(--ink);
  background: rgba(18, 21, 27, 0.9);
  backdrop-filter: blur(24px);
  -webkit-backdrop-filter: blur(24px);
  box-shadow: 0 40px 80px -20px rgba(0, 0, 0, 0.8);
}

.settings-dialog[open] {
  display: flex;
}

dialog::backdrop {
  background: rgba(8, 11, 16, 0.72);
  backdrop-filter: blur(9px);
  -webkit-backdrop-filter: blur(9px);
}

.settings-rail {
  width: 236px;
  flex: none;
  display: flex;
  flex-direction: column;
  padding: 24px 16px;
  background: rgba(11, 14, 19, 0.5);
  border-right: 1px solid rgba(255, 255, 255, 0.07);
}

.settings-rail-eyebrow {
  padding: 0 10px 4px;
  font: 500 11px/1 var(--font-mono);
  letter-spacing: 0.2em;
  color: var(--accent);
  text-transform: uppercase;
}

.settings-tabs {
  display: flex;
  flex-direction: column;
  gap: 3px;
  margin-top: 16px;
}

.settings-tab {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 12px;
  border: 1px solid transparent;
  border-radius: 10px;
  background: transparent;
  font: 500 14px/1 var(--font-ui);
  color: var(--muted);
  text-align: left;
  cursor: pointer;
}

.settings-tab:hover {
  color: var(--ink);
}

.settings-tab.active {
  background: rgba(246, 165, 44, 0.14);
  border-color: rgba(246, 165, 44, 0.3);
  color: var(--accent);
  font-weight: 600;
}

.settings-tab svg {
  flex: none;
}

.settings-rail-foot {
  margin-top: auto;
  padding: 10px;
  font: 400 11px/1.5 var(--font-mono);
  color: var(--faintest);
}

.settings-main {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-width: 0;
  /* Let this flex child shrink below its content height so the scroll area
     below (.settings-body) is what overflows — without it, on the mobile
     column layout the panel content spills past the fixed-height dialog and
     the page behind scrolls instead (issue #13). */
  min-height: 0;
}

.settings-head {
  flex: none;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  padding: 24px 26px 18px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.07);
}

.settings-panel-title {
  font: 500 20px/1 var(--font-serif);
  color: var(--ink-bright);
}

.settings-panel-subtitle {
  margin-top: 7px;
  font: 400 12px/1.4 var(--font-ui);
  color: #8b909c;
}

.settings-body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  /* Keep an over-scroll at the top/bottom of the panel from chaining out to
     the page behind the dialog. */
  overscroll-behavior: contain;
  padding: 22px 26px;
}

.settings-panel {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.settings-panel[hidden] {
  display: none;
}

.settings-divider {
  height: 1px;
  background: rgba(255, 255, 255, 0.07);
  margin: 6px 0;
}

.settings-section-label {
  font: 600 11px/1 var(--font-ui);
  letter-spacing: 0.13em;
  color: #c2c6cf;
  text-transform: uppercase;
}

.settings-note {
  margin: 0;
  font: 400 12px/1.5 var(--font-ui);
  color: #8b909c;
}

.settings-foot {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 16px 26px;
  border-top: 1px solid rgba(255, 255, 255, 0.07);
}

.settings-foot-note {
  font: 500 12px/1 var(--font-ui);
  color: #8b909c;
}

/* setting rows: text left, control right */

.setting-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}

.setting-row-text {
  display: flex;
  flex-direction: column;
  gap: 5px;
  min-width: 0;
}

.setting-row-label {
  font: 600 13px/1.2 var(--font-ui);
  color: var(--ink);
}

.setting-row-hint {
  font: 400 11px/1.4 var(--font-ui);
  color: #8b909c;
}

.setting-slider {
  display: flex;
  flex-direction: column;
  gap: 9px;
}

.setting-slider-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
}

.setting-slider-head label {
  font: 600 13px/1 var(--font-ui);
  color: var(--ink);
}

.setting-slider-head output {
  font: 600 13px/1 var(--font-num);
  color: var(--ink-bright);
}

.camera-readout {
  display: block;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.04);
  font: 400 11px/1.5 var(--font-mono);
  color: var(--faint);
}

select {
  min-height: 38px;
  padding: 0 10px;
  border: 1px solid var(--line-strong);
  border-radius: 10px;
  color: var(--ink);
  background: var(--card);
  font: 600 13px/1 var(--font-ui);
}

input[type="color"] {
  width: 64px;
  height: 32px;
  padding: 2px;
  border: 1px solid var(--line-strong);
  border-radius: 8px;
  background: var(--card);
}

.api-key-control {
  display: grid;
  gap: 8px;
}

.api-key-control[hidden] {
  display: none;
}

.api-key-row {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 8px;
}

.api-key-row input {
  min-height: 40px;
  padding: 0 12px;
  border: 1px solid var(--line-strong);
  border-radius: 10px;
  color: var(--ink);
  background: rgba(255, 255, 255, 0.04);
  font: 500 12px/1 var(--font-mono);
}

/* toggle switch component */

.switch {
  position: relative;
  display: inline-flex;
  flex: none;
  cursor: pointer;
}

.switch input {
  position: absolute;
  inset: 0;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}

.switch-track {
  display: block;
  width: 38px;
  height: 22px;
  border-radius: 11px;
  background: rgba(255, 255, 255, 0.14);
  transition: background 0.15s;
}

.switch-knob {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--ink);
  transition: left 0.15s, background 0.15s;
}

.switch input:checked + .switch-track {
  background: var(--accent);
}

.switch input:checked + .switch-track .switch-knob {
  left: 19px;
  background: var(--accent-ink);
}

.switch input:focus-visible + .switch-track {
  outline: 2px solid var(--blue);
  outline-offset: 2px;
}

/* HUD field toggle rows */

.hud-order-list {
  display: grid;
  gap: 8px;
}

.hud-order-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.04);
  cursor: grab;
}

.hud-order-row.dragging {
  opacity: 0.45;
}

.hud-order-row.drag-over {
  border-color: rgba(246, 165, 44, 0.75);
  background: rgba(246, 165, 44, 0.08);
}

.hud-order-handle {
  flex: none;
  padding: 4px 6px;
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.08);
  font: 700 9px/1 var(--font-ui);
  color: var(--faint);
  text-transform: uppercase;
}

.hud-order-text {
  display: flex;
  align-items: baseline;
  gap: 8px;
  min-width: 0;
  flex: 1;
}

.hud-order-text span {
  font: 600 13px/1 var(--font-ui);
  color: var(--ink);
}

.hud-order-text i {
  font: 500 11px/1 var(--font-mono);
  color: var(--faint);
  font-style: normal;
}

.hud-count-control {
  display: flex;
  align-items: center;
  gap: 8px;
}

.hud-count-control output {
  min-width: 48px;
  text-align: center;
  font: 600 13px/1 var(--font-num);
  color: var(--ink-bright);
}

.field-toggle-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}

.field-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 13px 15px;
  border: 1px solid var(--line);
  border-radius: 11px;
  background: rgba(255, 255, 255, 0.04);
}

.field-toggle-text {
  display: flex;
  align-items: baseline;
  gap: 8px;
  min-width: 0;
}

.field-toggle-text span {
  font: 600 13px/1 var(--font-ui);
  color: var(--ink);
}

.field-toggle-text i {
  font: 500 10px/1 var(--font-mono);
  font-style: normal;
  color: var(--faintest);
}

/* ---- gallery overlay (4a) ------------------------------------------------------------ */

.gallery-dialog {
  width: 100vw;
  height: 100vh;
  max-width: 100vw;
  max-height: 100vh;
  padding: 0;
  border: 0;
  color: var(--ink);
  background: transparent;
  font-family: var(--font-ui);
}

.gallery-dialog[open] {
  display: flex;
  flex-direction: column;
}

.gallery-head {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 26px 32px 20px;
}

.gallery-head-title {
  display: flex;
  align-items: baseline;
  gap: 14px;
}

.gallery-title {
  font: 500 30px/1 var(--font-serif);
  color: #f5f6f8;
}

.gallery-count {
  font: 600 12px/1 var(--font-mono);
  letter-spacing: 0.06em;
  color: #8b909c;
  text-transform: uppercase;
}

.gallery-head-actions {
  display: flex;
  align-items: center;
  gap: 12px;
}

.gallery-attribution {
  font: 400 12px/1 var(--font-ui);
  color: var(--faint);
}

.gallery-head-actions .icon-btn {
  width: 42px;
  height: 42px;
  border-radius: 12px;
}

.gallery-scroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 4px 32px 32px;
}

.gallery-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 18px;
}

.gallery-card {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border: 1px solid rgba(255, 255, 255, 0.09);
  border-radius: 15px;
  background: rgba(20, 24, 30, 0.72);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
}

.gallery-card.loaded {
  border-color: rgba(246, 165, 44, 0.55);
  box-shadow: 0 0 0 1px rgba(246, 165, 44, 0.25);
}

.gallery-card-thumb {
  position: relative;
  height: 150px;
  background: var(--card);
}

.gallery-card-map,
.gallery-card-map > * {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.gallery-card-preview-status {
  position: absolute;
  left: 12px;
  bottom: 11px;
  z-index: 1;
  font: 600 10px/1 var(--font-mono);
  color: rgba(255, 255, 255, 0.72);
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.9);
}

.gallery-card-thumb::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(8, 11, 16, 0.32) 0%, rgba(8, 11, 16, 0) 30%, rgba(8, 11, 16, 0.15) 60%, rgba(8, 11, 16, 0.7) 100%);
  pointer-events: none;
}

.gallery-card-loaded-badge {
  position: absolute;
  top: 11px;
  right: 11px;
  z-index: 1;
  padding: 6px 8px;
  border-radius: 6px;
  background: var(--accent);
  font: 700 9px/1 var(--font-mono);
  letter-spacing: 0.1em;
  color: var(--accent-ink);
}

.gallery-card-attribution {
  position: absolute;
  bottom: 8px;
  left: 11px;
  z-index: 1;
  font: 400 9px/1 var(--font-mono);
  color: rgba(255, 255, 255, 0.7);
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.8);
}

.gallery-card-preview-tools {
  display: flex;
  align-items: stretch;
  height: 48px;
  background: rgba(10, 13, 18, 0.5);
  border-bottom: 1px solid var(--line-soft);
}

.gallery-card-profile {
  display: flex;
  align-items: flex-end;
  gap: 1px;
  flex: 1;
  min-width: 0;
  padding: 0 3px;
}

.gallery-card-profile i {
  flex: 1 1 0;
  border-radius: 1.5px 1.5px 0 0;
}

.gallery-card-view-toggle {
  width: 48px;
  flex: 0 0 48px;
  padding: 5px;
  border: 0;
  border-left: 1px solid var(--line-soft);
  background: rgba(255, 255, 255, 0.035);
  font: 700 9px/1.15 var(--font-mono);
  letter-spacing: 0.04em;
  color: var(--blue-soft);
  text-transform: uppercase;
  cursor: pointer;
}

.gallery-card-view-toggle:hover,
.gallery-card-view-toggle[aria-pressed="true"] {
  background: rgba(10, 132, 255, 0.13);
  color: #8cc8ff;
}

.gallery-card-view-toggle:disabled {
  color: var(--faint);
  cursor: wait;
}

.gallery-card-body {
  display: flex;
  flex-direction: column;
  flex: 1;
  padding: 14px 16px 16px;
}

.gallery-card-title {
  margin: 0;
  font: 500 17px/1.1 var(--font-serif);
  color: var(--ink-bright);
}

.gallery-card-desc {
  overflow: hidden;
  margin: 7px 0 0;
  min-height: 52px;
  max-height: 52px;
  font: 400 12px/1.45 var(--font-ui);
  color: var(--muted);
}

.gallery-card-desc p {
  margin: 0;
}

.gallery-card-desc p + p {
  margin-top: 6px;
}

.gallery-card-desc strong {
  color: #d8dbe2;
  font-weight: 700;
}

.gallery-card-desc em {
  font-style: italic;
}

.gallery-card-desc a {
  color: var(--blue-soft);
  text-decoration: none;
}

.gallery-card-class {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 12px;
}

.gallery-card-class i {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex: none;
}

.gallery-card-class span {
  font: 600 11px/1 var(--font-mono);
  letter-spacing: 0.02em;
  color: #c2c6cf;
}

.gallery-card-stats {
  display: flex;
  gap: 22px;
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--line);
}

.gallery-card-stat span {
  display: block;
  font: 600 8px/1 var(--font-ui);
  letter-spacing: 0.13em;
  color: var(--faint);
  text-transform: uppercase;
}

.gallery-card-stat strong {
  display: block;
  margin-top: 6px;
  font: 600 15px/1 var(--font-num);
  color: var(--ink);
}

.gallery-card-stat strong.accent {
  color: var(--accent);
}

.gallery-card-btn {
  margin-top: auto;
  padding: 12px;
  border: 1px solid rgba(246, 165, 44, 0.5);
  border-radius: 10px;
  background: transparent;
  font: 600 13px/1 var(--font-ui);
  color: var(--accent);
  text-align: center;
  cursor: pointer;
}

.gallery-card-body .gallery-card-btn {
  margin-top: 14px;
}

.gallery-card-btn:hover {
  background: rgba(246, 165, 44, 0.1);
}

.gallery-card.loaded .gallery-card-btn {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
}

/* ---- responsive ------------------------------------------------------------------------ */

@media (max-width: 1180px) {
  .control-pane {
    width: 420px;
  }

  .stat-grid-live {
    grid-template-columns: repeat(3, 1fr);
  }

  .gallery-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 860px) {
  .app-shell {
    height: auto;
    min-height: 100vh;
  }

  .app-body {
    flex-direction: column;
  }

  .map-pane {
    min-height: 420px;
    height: 56vh;
  }

  .control-pane {
    width: 100%;
    border-left: 0;
    border-top: 1px solid rgba(255, 255, 255, 0.07);
  }

  .top-bar {
    flex-wrap: wrap;
    height: auto;
    padding: 10px 14px;
  }

  .gallery-grid {
    grid-template-columns: 1fr;
  }

  .settings-dialog {
    flex-direction: column;
    height: min(90vh, 900px);
  }

  .settings-dialog[open] {
    display: flex;
  }

  .settings-rail {
    width: 100%;
    padding: 14px 12px;
    border-right: 0;
    border-bottom: 1px solid rgba(255, 255, 255, 0.07);
  }

  /* A wrapped grid of seven tabs would eat half a short phone dialog, leaving
     a cramped scroll window; keep them on one horizontally-scrolling row so
     the panel below gets the height instead. */
  .settings-tabs {
    flex-direction: row;
    flex-wrap: nowrap;
    gap: 8px;
    margin-top: 12px;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }

  .settings-tabs::-webkit-scrollbar {
    display: none;
  }

  .settings-tab {
    flex: none;
    white-space: nowrap;
  }

  .settings-rail-foot {
    display: none;
  }
}

/* ---- map HUD on phones -----------------------------------------------------
   The dock is laid out for a wide screen: its body is a horizontal row
   (fixed-width metric grid + separator + road-ahead profile) and the collapsed
   strip lays every metric tile inline. Neither fits a phone, so on narrow
   viewports the corner overlays pull in from the edges and the dock stacks
   into a compact, always-fits column. */
@media (max-width: 860px) {
  .map-viewport {
    --hud-inset: 14px;
    --hud-bottom-inset-x: 10px;
    --hud-bottom-inset-y: 12px;
    --hud-bottom-clearance: calc(36px + var(--fs-dock-height, 290px) + 10px);
  }

  .hud-region-center {
    left: var(--hud-inset);
    right: var(--hud-inset);
    max-width: none;
    transform: none;
  }

  .fs-clock {
    gap: 8px;
    padding: 8px 12px;
  }

  .fs-clock-time,
  .fs-clock-elapsed {
    font-size: 15px;
  }

  .fs-clock-dist {
    font-size: 13px;
  }

  .fs-clock-ascent {
    font-size: 13px;
  }

  .fs-training-meters {
    width: 150px;
    gap: 6px;
  }

  .fs-zone-meter {
    padding: 8px 9px;
  }

  .fs-zone-meter strong {
    font-size: 16px;
  }

  /* The banner's desktop min-width (420px) overflows a phone; let it span the
     viewport width instead and drop the centring transform. */
  .climb-banner {
    width: 100%;
    min-width: 0;
    padding: 12px 14px 13px;
  }

  .fs-dock {
    padding: 14px 14px 16px;
    border-radius: 16px;
  }

  .fs-dock-top-tools {
    top: 8px;
    right: 8px;
  }

  .fs-dock-metric-wrap {
    width: 100%;
    align-items: stretch;
  }

  .fs-dock-field-controls {
    align-self: center;
  }

  /* Stack the body: metrics on top, road-ahead below. Keep clear of the
     collapse toggle in the top-right corner. */
  .fs-dock-body {
    flex-direction: column;
    gap: 14px;
    padding-top: 30px;
    padding-right: 0;
  }

  .fs-dock-sep {
    display: none;
  }

  /* Tiles flow into a four-column grid (two rows when all eight are on) that
     fills the width; the JS-set per-tile width no longer applies. */
  .fs-dock-metrics {
    flex: 1;
    grid-template-rows: none;
    grid-auto-flow: row;
    grid-template-columns: repeat(auto-fit, minmax(72px, 1fr));
    grid-auto-columns: auto;
    gap: 8px;
  }

  .fs-tile {
    padding: 9px 10px;
  }

  .fs-tile-label {
    font-size: 8px;
    letter-spacing: 0.08em;
  }

  .fs-tile-value {
    margin-top: 5px;
    font-size: 16px;
  }

  /* Once the body is a column the road plot has no intrinsic height, so pin
     one; compact the header and drop its explanatory note. */
  .fs-road-plot {
    flex: none;
    height: 76px;
    min-height: 0;
  }

  .fs-road-head {
    flex-wrap: wrap;
    gap: 6px 14px;
    margin-bottom: 8px;
    min-height: 0;
    padding-right: 0;
  }

  .fs-road-note {
    display: none;
  }

  .fs-dock-progress {
    gap: 16px;
    margin-top: 10px;
  }

  /* Collapsed on a phone: stretch the stacked sections full width and wrap the
     inline metric strip so eight fields don't run off the edge. */
  .fs-dock.collapsed .fs-dock-body {
    align-items: stretch;
    gap: 14px;
    padding-top: 0;
    padding-right: 0;
  }

  .fs-dock.collapsed .fs-dock-right {
    padding-right: 40px;
  }

  .fs-dock.collapsed .fs-dock-metrics {
    flex-wrap: wrap;
    justify-content: space-between;
    gap: 10px 16px;
  }
}
