/*
 * Klarspur driver app — components. Tokens live in tokens.css (load first).
 * Mobile first; Tesla density via [data-surface="tesla"]; landscape layout via min-width 900px.
 * Guide: docs/DESIGN.md
 */

/* ---------- Base ---------- */
*, *::before, *::after { box-sizing: border-box; }
[hidden] { display: none !important; } /* never let a component display rule defeat [hidden] */
html, body {
  margin: 0; height: 100%;
  background: var(--ks-bg); color: var(--ks-text);
  font-family: var(--ks-font); font-size: var(--ks-text-md); line-height: var(--ks-leading);
  -webkit-text-size-adjust: 100%; -webkit-tap-highlight-color: transparent;
}
body { overflow: hidden; }
h1, h2, h3, p { margin: 0; }
a { color: var(--ks-accent); }
.ks-sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.ic {
  width: 1.25em; height: 1.25em; flex: none;
  fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
}
.ic--lg { width: 1.6em; height: 1.6em; }
.visually-hidden {
  position: absolute !important; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}
:focus { outline: none; }
:focus-visible { outline: none; box-shadow: var(--ks-focus-ring); }
.muted { color: var(--ks-muted); }

/* ---------- App shell (0.2.5: full-bleed map, every control floats above it) ----------
   The map always fills the whole screen: on-screen keyboards, panels and banners never shrink it (no black
   bands). Floating chrome keeps --ks-float-gap + safe-area from the edges; layout.js measures what it covers
   (--ks-ui-top/-bottom/-left/-top-right) so map overlays and the camera padding stay clear of it.
   --ks-vv-top (keyboard.js) follows a visual viewport that was panned down for the keyboard (iOS), so the
   top-anchored chrome stays on screen. */
.app {
  position: fixed; inset: 0; overflow: hidden;
  --ks-edge-top: calc(env(safe-area-inset-top, 0px) + var(--ks-banner-h, 0px) + var(--ks-vv-top, 0px) + var(--ks-float-gap));
  --ks-edge-left: calc(env(safe-area-inset-left, 0px) + var(--ks-float-gap));
  --ks-edge-right: calc(env(safe-area-inset-right, 0px) + var(--ks-float-gap));
  --ks-edge-bottom: calc(env(safe-area-inset-bottom, 0px) + var(--ks-float-gap));
}
.glass, .top-strip, .dock, .maneuver-card, .trip-bar {
  background: var(--ks-surface-glass);
  border: 1px solid var(--ks-border);
  box-shadow: var(--ks-shadow-2);
  -webkit-backdrop-filter: blur(var(--ks-glass-blur)); backdrop-filter: blur(var(--ks-glass-blur));
}

/* ---------- Top strip (floating app bar) ---------- */
.top-strip {
  position: absolute; z-index: var(--ks-z-chrome);
  top: var(--ks-edge-top); left: var(--ks-edge-left); right: var(--ks-edge-right);
  display: flex; align-items: center; gap: var(--ks-space-3);
  min-height: calc(var(--ks-tap) + var(--ks-space-2));
  padding: var(--ks-space-1) var(--ks-space-1) var(--ks-space-1) var(--ks-space-4);
  border-radius: var(--ks-radius-pill);
}
.brand {
  display: inline-flex; align-items: center; gap: var(--ks-space-2);
  font-weight: var(--ks-weight-bold); font-size: var(--ks-text-lg); letter-spacing: -0.01em;
  margin-right: auto;
}
.brand-mark {
  width: 22px; height: 22px; border-radius: 7px;
  background: linear-gradient(135deg, var(--ks-accent) 0 50%, transparent 50%), var(--ks-surface-3);
  box-shadow: inset 0 0 0 2px var(--ks-accent);
}
.top-actions { display: flex; align-items: center; gap: var(--ks-space-1); flex: none; }
/* Full screen toggle: icon only. No resume prompt. */
.fs-btn { min-width: var(--ks-tap); display: inline-flex; align-items: center; justify-content: center; }
/* Guidance: the bar shrinks to its actions (menu, full screen); the maneuver card owns the top */
body.ks-guidance .brand, body.ks-guidance #btnLogin, body.ks-guidance .sync-indicator, body.ks-guidance .gamification-chip { display: none; }
body.ks-guidance .top-strip { left: auto; padding: var(--ks-space-1); }

/* ---------- Maneuver card (guidance): arrow + distance dominate, text is secondary ---------- */
.maneuver-card {
  position: absolute; z-index: var(--ks-z-chrome);
  top: var(--ks-edge-top); left: var(--ks-edge-left); right: calc(var(--ks-edge-right) + var(--ks-tap) * 2 + var(--ks-space-3));
  display: grid; grid-template-columns: var(--ks-maneuver-icon) minmax(0, 1fr); align-items: center; gap: var(--ks-space-3);
  padding: var(--ks-space-2);
  background: var(--ks-surface-glass-strong);
  border-radius: calc(var(--ks-radius-card) + var(--ks-space-2));
}
.maneuver-icon {
  position: relative; display: grid; place-items: center;
  width: var(--ks-maneuver-icon); height: var(--ks-maneuver-icon);
  border-radius: var(--ks-radius-card); background: var(--ks-accent); color: var(--ks-on-accent);
}
.maneuver-icon .ic { width: 70%; height: 70%; stroke-width: 2.4; }
.maneuver-exit {
  position: absolute; right: -6px; bottom: -6px; min-width: 1.8em; height: 1.8em; padding: 0 0.3em;
  display: grid; place-items: center; border-radius: var(--ks-radius-pill);
  background: var(--ks-bg); color: var(--ks-text); border: 2px solid var(--ks-accent);
  font-size: var(--ks-text-sm); font-weight: var(--ks-weight-bold); font-variant-numeric: tabular-nums;
}
.maneuver-body { min-width: 0; display: grid; gap: 2px; }
.maneuver-dist {
  font-size: var(--ks-text-display); font-weight: var(--ks-weight-bold); line-height: var(--ks-leading-tight);
  letter-spacing: -0.02em; font-variant-numeric: tabular-nums; white-space: nowrap;
}
.maneuver-dist:empty { display: none; }
.maneuver-dist small { font-size: 0.5em; font-weight: var(--ks-weight-medium); margin-left: 0.15em; color: var(--ks-muted); letter-spacing: 0; }
.maneuver-text {
  font-size: var(--ks-text-lg); color: var(--ks-text); opacity: 0.85; line-height: var(--ks-leading-tight);
  /* up to two lines: long Swiss street names stay readable next to the menu buttons */
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2;
  overflow: hidden; overflow-wrap: anywhere;
}
.maneuver-text:empty { display: none; }
.maneuver-card.is-rerouting .maneuver-icon { background: var(--ks-surface-3); color: var(--ks-accent); }
.maneuver-card.is-rerouting .maneuver-icon .ic { animation: ks-spin 1.2s linear infinite; }
.maneuver-then {
  grid-column: 1 / -1; justify-self: start; display: inline-flex; align-items: center; gap: var(--ks-space-2);
  padding: 2px var(--ks-space-3); border-radius: var(--ks-radius-pill);
  background: var(--ks-surface-2); color: var(--ks-muted); font-size: var(--ks-text-sm); font-weight: var(--ks-weight-medium);
}
.maneuver-then .ic { color: var(--ks-text); }

/* ---------- Trip bar (guidance): remaining time + compact End ---------- */
.trip-bar {
  position: absolute; z-index: var(--ks-z-chrome);
  left: var(--ks-edge-left); right: var(--ks-edge-right); bottom: var(--ks-edge-bottom);
  display: flex; align-items: center; gap: var(--ks-space-3); flex-wrap: wrap;
  padding: var(--ks-space-2) var(--ks-space-4) var(--ks-space-2) var(--ks-space-2);
  border-radius: var(--ks-radius-pill);
}
.trip-main {
  display: grid; min-width: 0; flex: 1; line-height: 1.2;
  grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "eta delay" "meta meta";
  column-gap: var(--ks-space-2); align-items: baseline;
}
.trip-eta { grid-area: eta; font-size: var(--ks-text-xl); font-weight: var(--ks-weight-bold); color: var(--ks-accent); letter-spacing: -0.01em; font-variant-numeric: tabular-nums; }
.trip-meta { grid-area: meta; color: var(--ks-muted); font-size: var(--ks-text-sm); font-variant-numeric: tabular-nums; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.trip-delay {
  grid-area: delay; color: var(--ks-warning); font-size: var(--ks-text-sm); font-weight: var(--ks-weight-medium);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.trip-delay[hidden] { display: none; }
.trip-status { flex-basis: 100%; color: var(--ks-muted); font-size: var(--ks-text-sm); padding: 0 var(--ks-space-2) var(--ks-space-1); }
.trip-status:empty { display: none; }
.trip-status.warn { color: var(--ks-warning); }
.trip-status.ok { color: var(--ks-accent); }
.trip-bar:has(.trip-status:not(:empty)) { border-radius: calc(var(--ks-radius-card) + var(--ks-space-2)); }
/* End: icon only, discreet danger tint; first tap arms ("End?"), a second tap within 4 s ends */
.stop-btn {
  appearance: none; flex: none; display: inline-flex; align-items: center; justify-content: center; gap: var(--ks-space-2);
  min-width: var(--ks-tap-confirm); height: var(--ks-tap-confirm); padding: 0; cursor: pointer;
  border: 1px solid rgba(255, 92, 92, 0.4); border-radius: var(--ks-radius-pill);
  background: var(--ks-danger-soft); color: var(--ks-danger);
  font: var(--ks-weight-bold) var(--ks-text-md) var(--ks-font);
  transition: background-color var(--ks-dur-fast) var(--ks-ease), color var(--ks-dur-fast) var(--ks-ease);
}
.stop-btn .ic { width: 1.5em; height: 1.5em; stroke-width: 2.4; }
.stop-confirm { display: none; }
.stop-btn.is-armed { background: var(--ks-danger); color: #1A0505; padding: 0 var(--ks-space-5) 0 var(--ks-space-4); }
.stop-btn.is-armed .stop-confirm { display: inline; }
.stop-btn:active { filter: brightness(0.92); }

/* Discreet gamification chip (D15): never larger or brighter than the next turn */
.gamification-chip {
  display: inline-flex; align-items: center; gap: var(--ks-space-1);
  min-height: 32px; padding: 0 var(--ks-space-3);
  border-radius: var(--ks-radius-pill);
  background: var(--ks-accent-soft); color: var(--ks-text);
  border: 1px solid rgba(62, 207, 142, 0.3);
  font-size: var(--ks-text-sm); font-weight: var(--ks-weight-medium); white-space: nowrap;
}
.sync-indicator {
  display: inline-flex; align-items: center; gap: var(--ks-space-1);
  color: var(--ks-muted); font-size: var(--ks-text-xs);
}
.sync-indicator .ic { width: 1.1em; height: 1.1em; }
.sync-indicator.ok { color: var(--ks-accent); }
.sync-indicator.warn { color: var(--ks-warning); }
.sync-indicator .sync-label { display: none; }

/* ---------- Map stage (full screen, always) ---------- */
.map-stage { position: absolute; inset: 0; z-index: var(--ks-z-map); }
.map-surface { position: absolute; inset: 0; z-index: var(--ks-z-map); overflow: hidden; background: var(--ks-bg); }
.map-placeholder {
  display: grid; place-items: center;
  background:
    linear-gradient(transparent 0 calc(100% - 1px), rgba(154, 168, 188, 0.06) 0) 0 0 / 48px 48px,
    linear-gradient(90deg, transparent 0 calc(100% - 1px), rgba(154, 168, 188, 0.06) 0) 0 0 / 48px 48px,
    radial-gradient(120% 90% at 50% 40%, #121A24 0%, var(--ks-bg) 70%);
}
/* Fallback = quiet banner (top-right, under the floating chrome), so pins and the route keep the canvas */
.map-fallback {
  position: absolute; z-index: 1;
  top: calc(max(var(--ks-ui-top, 0px), var(--ks-ui-top-right, 0px)) + var(--ks-space-3)); right: var(--ks-edge-right);
  display: flex; align-items: center; gap: var(--ks-space-2);
  max-width: min(22rem, calc(100% - 11rem)); padding: var(--ks-space-2) var(--ks-space-3);
  background: var(--ks-surface-glass); border: 1px solid var(--ks-border); border-radius: var(--ks-radius-card);
  color: var(--ks-muted); font-size: var(--ks-text-sm); line-height: 1.3;
}
.map-fallback > .ic { width: 1.5em; height: 1.5em; color: var(--ks-muted); }
.map-fallback > div { min-width: 0; }
body.ks-guidance .map-fallback { display: none; } /* guidance: keep the canvas calm */
.map-fallback-title { color: var(--ks-text); font-weight: var(--ks-weight-medium); }
.map-fallback-body { font-size: var(--ks-text-xs); }
.map-dev-hint {
  margin-top: var(--ks-space-3); padding: var(--ks-space-2) var(--ks-space-3);
  border: 1px dashed var(--ks-warning); border-radius: var(--ks-radius-sm);
  color: var(--ks-warning); font: var(--ks-text-xs)/1.4 var(--ks-font-mono); text-align: left; overflow-wrap: anywhere;
}
.map-surface.map-live { display: block; }
.map-canvas { width: 100%; height: 100%; }
html[data-theme="dark"] .map-canvas { background: var(--ks-map-night); }
/* Compact collapsible map credit (i): bottom-left so Melden/FAB on the right stays clear. */
.map-attribution {
  position: absolute; left: var(--ks-edge-left); right: auto;
  bottom: calc(var(--ks-ui-bottom, 0px) + var(--ks-space-1)); z-index: 2;
  max-width: min(14rem, calc(100% - var(--ks-tap-confirm) - 3 * var(--ks-space-4)));
  background: rgba(21, 27, 36, 0.88); color: var(--ks-muted); font-size: 0.65rem;
  border-radius: var(--ks-radius-pill); box-shadow: var(--ks-shadow-1);
}
.map-attribution-toggle {
  list-style: none; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.5rem; height: 1.5rem; min-width: 1.5rem; min-height: 1.5rem;
  padding: 0; border-radius: 50%;
  font: var(--ks-weight-bold) 0.7rem/1 var(--ks-font); color: var(--ks-text);
}
.map-attribution-toggle::-webkit-details-marker { display: none; }
.map-attribution-text { display: none; padding: 0 var(--ks-space-2) 2px; overflow-wrap: anywhere; }
.map-attribution[open] { border-radius: var(--ks-radius-card); padding-bottom: 2px; }
.map-attribution[open] .map-attribution-toggle { border-radius: var(--ks-radius-card) var(--ks-radius-card) 0 0; }
.map-attribution[open] .map-attribution-text { display: block; }
.map-demo-badge {
  position: absolute; left: calc(50% + var(--ks-ui-left, 0px) / 2); top: calc(max(var(--ks-ui-top, 0px), var(--ks-ui-top-right, 0px)) + var(--ks-space-2)); transform: translateX(-50%); z-index: 2;
  background: var(--ks-warning-soft); color: var(--ks-warning); border: 1px solid var(--ks-warning);
  font-size: var(--ks-text-xs); font-weight: var(--ks-weight-medium);
  padding: 2px var(--ks-space-3); border-radius: var(--ks-radius-pill); pointer-events: none;
}
/* During guidance the maneuver card owns the top centre — tuck the badge under the menu stack. */
body.ks-guidance .map-demo-badge {
  left: auto; right: var(--ks-edge-right); transform: none;
  top: calc(var(--ks-ui-top-right, 0px) + var(--ks-tap) + var(--ks-space-2) + var(--ks-space-2));
}

.map-surface .maplibregl-ctrl-top-right {
  /* Below the legend control (layout.js --ks-legend-bottom), so +/− stay visible and tappable. */
  top: calc(max(var(--ks-ui-top-right, 0px), var(--ks-legend-bottom, 0px)) + var(--ks-space-2));
  right: calc(var(--ks-edge-right) - 10px);
  z-index: 2;
}
body:not(.ks-guidance) .map-surface .maplibregl-ctrl-top-right {
  top: calc(max(var(--ks-ui-top, 0px), var(--ks-ui-top-right, 0px), var(--ks-legend-bottom, 0px)) + var(--ks-space-2));
}
body.ks-guidance .map-surface .maplibregl-ctrl-top-right { display: none; } /* pinch zoom; keep the guidance canvas calm */

/* Overlays share the map stage; only their children take pointer events */
.map-overlays { position: absolute; inset: 0; z-index: var(--ks-z-map-overlay); pointer-events: none; }
.map-overlays > * { pointer-events: auto; }

/* Legend toggle: compact round control under the top-right menu pill (not under the maneuver card).
   --ks-ui-top-right = menu/app-bar pill; during guidance --ks-ui-top is the maneuver card and must not push this down.
   Open panel: fixed mid-right (below the button stack, above Melden), above chrome so the maneuver card never covers it. */
.legend {
  position: absolute; left: auto; right: var(--ks-edge-right);
  top: calc(var(--ks-ui-top-right, 0px) + var(--ks-space-2));
  background: var(--ks-surface-glass); border: 1px solid var(--ks-border);
  border-radius: 50%; font-size: var(--ks-text-sm); color: var(--ks-text);
  box-shadow: var(--ks-shadow-1); width: var(--ks-tap); height: var(--ks-tap);
}
/* Planning (no guidance yet): still under the full-width / pill bar. */
body:not(.ks-guidance) .legend {
  top: calc(max(var(--ks-ui-top, 0px), var(--ks-ui-top-right, 0px)) + var(--ks-space-2));
}
.legend-toggle, .legend summary {
  list-style: none; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; gap: var(--ks-space-2);
  width: var(--ks-tap); height: var(--ks-tap); min-width: var(--ks-tap); min-height: var(--ks-tap);
  padding: 0; border-radius: 50%;
}
.legend-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
.legend summary::-webkit-details-marker { display: none; }
.legend[open] {
  background: transparent; border-color: transparent; box-shadow: none;
}
.legend[open] .legend-toggle,
.legend[open] summary {
  background: var(--ks-surface-glass); border: 1px solid var(--ks-border); box-shadow: var(--ks-shadow-1);
  color: var(--ks-accent);
}
/* Raise overlays above chrome while open: map-overlays is a lower stacking context than the maneuver card. */
body.ks-legend-open .map-overlays { z-index: calc(var(--ks-z-chrome) + 1); }
.legend-panel {
  display: none;
}
.legend[open] .legend-panel {
  display: flex; flex-direction: column;
  position: fixed;
  right: var(--ks-edge-right);
  top: calc(var(--ks-ui-top-right, 0px) + var(--ks-tap) + var(--ks-space-2) + var(--ks-space-2));
  width: min(18rem, calc(100vw - 2 * var(--ks-space-4)));
  max-height: calc(
    100dvh
    - (var(--ks-ui-top-right, 0px) + var(--ks-tap) + var(--ks-space-2) + var(--ks-space-2))
    - (var(--ks-ui-bottom, 0px) + var(--ks-tap-confirm) + var(--ks-space-3) + var(--ks-space-3))
  );
  z-index: var(--ks-z-dropdown);
  background: var(--ks-surface-glass-strong); border: 1px solid var(--ks-border);
  border-radius: var(--ks-radius-card); box-shadow: var(--ks-shadow-2);
  -webkit-backdrop-filter: blur(var(--ks-glass-blur)); backdrop-filter: blur(var(--ks-glass-blur));
  color: var(--ks-text); overflow: hidden;
}
body:not(.ks-guidance) .legend[open] .legend-panel {
  top: calc(max(var(--ks-ui-top, 0px), var(--ks-ui-top-right, 0px)) + var(--ks-tap) + var(--ks-space-2) + var(--ks-space-2));
  max-height: calc(
    100dvh
    - (max(var(--ks-ui-top, 0px), var(--ks-ui-top-right, 0px)) + var(--ks-tap) + var(--ks-space-2) + var(--ks-space-2))
    - (var(--ks-ui-bottom, 0px) + var(--ks-tap-confirm) + var(--ks-space-3) + var(--ks-space-3))
  );
}
.legend-panel-head {
  display: flex; align-items: center; justify-content: space-between; gap: var(--ks-space-2);
  padding: var(--ks-space-1) var(--ks-space-1) var(--ks-space-1) var(--ks-space-3);
  border-bottom: 1px solid var(--ks-border); flex: none;
}
.legend-panel-title { font-weight: var(--ks-weight-bold); font-size: var(--ks-text-md); min-width: 0; }
.legend-close {
  display: inline-flex; align-items: center; justify-content: center;
  width: var(--ks-tap); height: var(--ks-tap); min-width: var(--ks-tap); min-height: var(--ks-tap);
  padding: 0; border: 0; border-radius: 50%; background: transparent; color: var(--ks-muted); cursor: pointer;
}
.legend-close:hover { color: var(--ks-text); }
.legend-close:active { background: var(--ks-surface-3); }
/* Sections (0.3.13): Traffic, Community, Charging. One grid for every row: fixed icon column + label. */
.legend-body {
  overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
  min-height: 0; flex: 1 1 auto;
}
.legend-section { padding: var(--ks-space-3); }
.legend-section + .legend-section { border-top: 1px solid var(--ks-border); }
.legend-section-title {
  display: block; margin: 0 0 var(--ks-space-2);
  font: var(--ks-weight-bold) var(--ks-text-xs)/1.3 var(--ks-font);
  letter-spacing: 0.06em; text-transform: uppercase; color: var(--ks-muted);
}
.legend-section-head {
  display: flex; align-items: center; justify-content: space-between; gap: var(--ks-space-3);
  margin: calc(var(--ks-space-2) * -1) 0;
}
.legend-section-head .legend-section-title {
  flex: 1 1 auto; margin: 0; min-height: var(--ks-tap); display: flex; align-items: center; cursor: pointer;
}
.legend-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.legend-list li, .legend-row {
  display: grid; grid-template-columns: 20px minmax(0, 1fr); align-items: center; column-gap: var(--ks-space-2);
  min-height: 22px; line-height: 1.3;
}
.legend-list--cols { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--ks-space-3); }
.legend-list li.legend-empty { display: block; min-height: 0; color: var(--ks-muted); font-size: var(--ks-text-xs); }
.legend-icon { display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; }
.legend-subfilters { display: grid; gap: var(--ks-space-3); margin-top: var(--ks-space-3); }
.legend-row { cursor: pointer; padding-top: var(--ks-space-3); border-top: 1px solid var(--ks-border); }
.legend-row input[type="checkbox"] { width: 16px; height: 16px; margin: 0; accent-color: var(--ks-accent); cursor: pointer; }
.legend-fields {
  display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center;
  column-gap: var(--ks-space-3); row-gap: var(--ks-space-2);
}
.legend-field-label { color: var(--ks-muted); font-size: var(--ks-text-sm); }
.legend .select--legend {
  min-height: 36px; padding: 0 32px 0 var(--ks-space-3);
  font-size: var(--ks-text-sm); border-radius: var(--ks-radius-sm); background-color: var(--ks-surface-2);
  background-position: calc(100% - 16px) 50%, calc(100% - 11px) 50%;
}
.switch-input--sm { width: 44px; height: 26px; }
.switch-input--sm::after { width: 20px; height: 20px; }
.switch-input--sm:checked::after { left: 21px; }
/* While the legend is open the panel owns the right column; +/- would peek out behind it. */
body.ks-legend-open .map-surface .maplibregl-ctrl-top-right { visibility: hidden; pointer-events: none; }
[data-surface="tesla"] .legend[open] .legend-panel { width: min(22rem, calc(100vw - 2 * var(--ks-space-4))); }
[data-surface="tesla"] .legend-list li, [data-surface="tesla"] .legend-row { grid-template-columns: 24px minmax(0, 1fr); min-height: 28px; }
[data-surface="tesla"] .legend-icon { width: 24px; height: 24px; }
[data-surface="tesla"] .legend-row input[type="checkbox"] { width: 22px; height: 22px; }
[data-surface="tesla"] .legend .select--legend { min-height: var(--ks-tap); }
[data-surface="tesla"] .switch-input--sm { width: 56px; height: 32px; }
[data-surface="tesla"] .switch-input--sm::after { width: 26px; height: 26px; }
[data-surface="tesla"] .switch-input--sm:checked::after { left: 27px; }
/* Narrow portrait guidance: bottom sheet above the trip bar (Melden yields while open). */
@media (max-width: 480px) and (orientation: portrait) {
  body.ks-guidance .legend[open] .legend-panel {
    top: auto;
    left: var(--ks-edge-left);
    right: var(--ks-edge-right);
    bottom: calc(var(--ks-ui-bottom, 0px) + var(--ks-space-3));
    width: auto;
    max-height: min(60vh, 28rem);
  }
  body.ks-legend-open.ks-guidance .fab { visibility: hidden; pointer-events: none; }
}
.swatch { width: 12px; height: 12px; border-radius: 3px; flex: none; }
.swatch--traffic { background: var(--ks-traffic); }
.swatch--traffic-clear { background: var(--ks-accent); }
.swatch--traffic-slow { background: var(--ks-warning); }
.swatch--traffic-jam { background: var(--ks-danger); }
.swatch--roadwork { background: var(--ks-warning); border-radius: 2px; }
.swatch--community { background: var(--ks-community); border-radius: 50% 50% 50% 0; transform: rotate(-45deg); }
.ks-roadwork {
  width: 28px; height: 28px; border-radius: 6px; pointer-events: none;
  display: flex; align-items: center; justify-content: center;
  background: var(--ks-surface); border: 2px solid var(--ks-warning);
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.45);
}
.ks-roadwork .ic { width: 16px; height: 16px; color: var(--ks-warning); }
/* Official incidents (0.3.4): closure and accident share the roadwork tile, in the danger colour. */
.swatch--closure, .swatch--accident { background: var(--ks-danger); border-radius: 2px; }
.swatch--accident { border-radius: 50%; }
.ks-incident--closure, .ks-incident--accident { border-color: var(--ks-danger); }
.ks-incident--closure .ic, .ks-incident--accident .ic { color: var(--ks-danger); }
/* Tappable official incidents (0.3.35): the 28 px tile sits in a full tap target (invisible ring). */
.ks-incident-tap {
  width: var(--ks-tap); height: var(--ks-tap); margin: 0; padding: 0; border: 0; background: transparent;
  display: grid; place-items: center; cursor: pointer; pointer-events: auto; border-radius: 10px;
  -webkit-tap-highlight-color: transparent;
}
.ks-incident-tap:focus-visible { outline: none; }
.ks-incident-tap:focus-visible .ks-roadwork, .ks-incident-tap:hover .ks-roadwork { box-shadow: 0 0 0 3px var(--ks-accent), 0 1px 4px rgba(0, 0, 0, 0.45); }
[data-surface="tesla"] .ks-incident-tap .ks-roadwork { width: 34px; height: 34px; }
[data-surface="tesla"] .ks-incident-tap .ks-roadwork .ic { width: 20px; height: 20px; }

/* Report FAB — thumb zone, bottom-right; sits above the trip bar, clear of the left attribution. */
.fab {
  position: absolute; right: var(--ks-edge-right); bottom: calc(var(--ks-ui-bottom, 0px) + var(--ks-space-3) + var(--ks-fab-lift, 0px));
  transition: bottom var(--ks-dur-base) var(--ks-ease);
  display: inline-flex; align-items: center; justify-content: center; gap: var(--ks-space-2);
  min-width: var(--ks-tap-confirm); min-height: var(--ks-tap-confirm); padding: 0 var(--ks-space-4);
  border: 2px solid var(--ks-community); border-radius: var(--ks-radius-pill);
  background: var(--ks-surface); color: var(--ks-text);
  font: var(--ks-weight-bold) var(--ks-text-md) var(--ks-font); cursor: pointer;
  box-shadow: var(--ks-shadow-2);
}
.fab .ic { color: var(--ks-community); }
.fab:active { background: var(--ks-surface-3); }

/* Guidance follow view (issue #37): position puck + Re-centre after the driver panned the map */
.ks-puck { width: 40px; height: 40px; pointer-events: none; }
.ks-puck svg { width: 100%; height: 100%; display: block; filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.45)); }
.ks-puck circle { fill: var(--ks-surface); stroke: var(--ks-accent); stroke-width: 3; }
.ks-puck path { fill: var(--ks-accent); }
/* Wingman state (0.3.57): dashed outer ring while the position is shared; count badge is its own marker. */
.ks-puck .ks-puck-ring { display: none; }
.ks-puck--sharing .ks-puck-ring { display: block; fill: none; stroke: var(--ks-accent); stroke-width: 2; stroke-dasharray: 3 3; }
.ks-puck-badge {
  min-width: 20px; height: 20px; padding: 0 5px; border-radius: 10px; box-sizing: border-box;
  display: flex; align-items: center; justify-content: center;
  font: 700 12px/1 var(--ks-font, system-ui, sans-serif); color: var(--ks-on-accent, #06210f);
  background: var(--ks-accent); border: 2px solid var(--ks-surface); box-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
  pointer-events: none;
}
.ks-puck-badge.is-sharing { border-style: dashed; }
.swatch-car { position: relative; width: 16px; height: 16px; border-radius: 50%; background: var(--ks-surface); border: 2px solid var(--ks-accent); box-sizing: border-box; }
.swatch-car--ring { outline: 2px dashed var(--ks-accent); outline-offset: 2px; }
.swatch-car-badge {
  position: absolute; top: -8px; right: -9px; min-width: 12px; height: 12px; border-radius: 6px; box-sizing: border-box;
  display: flex; align-items: center; justify-content: center; font: 700 8px/1 system-ui, sans-serif;
  color: var(--ks-on-accent, #06210f); background: var(--ks-accent);
}
.ks-peer {
  position: relative; width: 28px; height: 28px; opacity: 0.92;
  pointer-events: auto; cursor: pointer; border: 0; padding: 0; background: transparent;
}
.ks-peer svg { width: 100%; height: 100%; display: block; filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.5)); pointer-events: none; }
.ks-peer circle { fill: var(--ks-surface-2, #1a2330); stroke: #7AA2FF; stroke-width: 2.5; }
.ks-peer path { fill: #7AA2FF; }
.maplibregl-popup.ks-peer-popup .maplibregl-popup-content {
  max-width: 12rem; padding: 4px 10px; border-radius: var(--ks-radius-pill);
  background: var(--ks-surface-glass, rgba(20, 28, 40, 0.92)); color: var(--ks-text);
  border: 1px solid var(--ks-border-strong); box-shadow: var(--ks-shadow-2);
  font: var(--ks-weight-medium) var(--ks-text-sm) / 1.25 var(--ks-font);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.maplibregl-popup.ks-peer-popup .maplibregl-popup-tip {
  border-top-color: var(--ks-surface-glass, rgba(20, 28, 40, 0.92));
}
.swatch--peer { background: #7AA2FF; border-radius: 50% 50% 50% 0; transform: rotate(-45deg); }
.swatch--charging { background: #3ECF8E; border-radius: 50%; box-shadow: 0 0 0 2px #FF6600; }
/* Same colours as the charging pins (charging.js colorFor) and route delay lines. */
.swatch--line { width: 18px; height: 5px; border-radius: 3px; }
.swatch--dot { border-radius: 50%; }
.swatch--ch-available { background: #3ECF8E; }
.swatch--ch-partial { background: #FFB020; }
.swatch--ch-occupied { background: #FF5C5C; }
.swatch--ch-unknown { background: #9AA8BC; }
.menu-settings .setting-block {
  background: var(--ks-surface-2); padding: var(--ks-space-2) var(--ks-space-4);
  display: grid; gap: var(--ks-space-2);
}
.setting-info {
  appearance: none; display: inline-flex; align-items: center; justify-content: center;
  width: var(--ks-tap); height: var(--ks-tap); min-width: var(--ks-tap); min-height: var(--ks-tap);
  margin: calc((var(--ks-tap) - 1.5rem) / -2) calc((var(--ks-tap) - 1.5rem) / -2)
    calc((var(--ks-tap) - 1.5rem) / -2) calc(var(--ks-space-1) * -1);
  padding: 0; border: 0; border-radius: 50%; background: transparent; color: var(--ks-muted);
  cursor: pointer;
}
.setting-info .ic { width: 1.15em; height: 1.15em; }
.setting-info[aria-expanded="true"] { color: var(--ks-accent); }
.setting-info:focus-visible { outline: 2px solid var(--ks-accent); outline-offset: 2px; }
.setting-hint {
  display: none; color: var(--ks-muted); font-size: var(--ks-text-sm); font-weight: 400;
  margin: 0; line-height: 1.35; max-width: none; width: 100%;
}
.setting-hint:not([hidden]) { display: block; }
body.ks-guest #presenceRow { display: none; }
/* Re-centre: top-left under the maneuver card; hidden while already following (JS [hidden]). */
.map-recenter {
  position: absolute; left: var(--ks-edge-left); top: calc(var(--ks-ui-top, 0px) + var(--ks-space-2));
  bottom: auto; transform: none;
  display: inline-flex; align-items: center; justify-content: center; gap: var(--ks-space-2);
  width: var(--ks-tap); height: var(--ks-tap); min-width: var(--ks-tap); min-height: var(--ks-tap);
  padding: 0;
  border: 1px solid var(--ks-border-strong); border-radius: 50%;
  background: var(--ks-surface-glass); color: var(--ks-text);
  font: var(--ks-weight-bold) var(--ks-text-sm) var(--ks-font); cursor: pointer; box-shadow: var(--ks-shadow-2);
}
.map-recenter .ic { color: var(--ks-accent); width: 1.35em; height: 1.35em; }
.map-recenter-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
.map-recenter[hidden] { display: none; }
/* Wide landscape: show the label as a compact pill under the maneuver column. */
@media (min-width: 900px) and (min-aspect-ratio: 1/1) {
  .map-recenter {
    width: auto; padding: 0 var(--ks-space-4); border-radius: var(--ks-radius-pill);
  }
  .map-recenter-label {
    position: static; width: auto; height: auto; clip-path: none; overflow: visible;
  }
}

/* ---------- Dock = plan panel (0.2.7: always anchored at the top) ----------
   Narrow screens: app bar, then the plan panel flush below it, then the map. Wide landscape: top-left
   column beside the app bar pill (media query below). Never at the bottom: an on-screen keyboard rises from
   the bottom (Tesla: ~55 % of the screen, not reported to the page), so the destination field and its
   suggestions (opening downward) stay above it. The panel ends above the keyboard inset (--ks-kb, keyboard.js)
   and scrolls inside itself. --ks-strip-h = measured app bar height (layout.js); the fallback matches it. */
.dock {
  --ks-dock-top: calc(var(--ks-edge-top) + var(--ks-strip-h, calc(var(--ks-tap) + var(--ks-space-2) + 2px)) + var(--ks-float-gap));
  position: absolute; z-index: var(--ks-z-chrome);
  top: var(--ks-dock-top); bottom: auto;
  left: var(--ks-edge-left); right: var(--ks-edge-right);
  display: grid; gap: var(--ks-space-3); align-content: start;
  /* 100dvh tracks the visual viewport (iOS keyboard); 100% keeps older browsers working. */
  max-height: calc(100% - var(--ks-dock-top) - var(--ks-edge-bottom));
  max-height: calc(100dvh - var(--ks-dock-top) - var(--ks-edge-bottom));
  overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
  padding: var(--ks-space-3);
  background: var(--ks-surface-glass-strong);
  border-radius: var(--ks-radius-sheet);
}
/* Keyboard open: end above the overlay keyboard (--ks-kb). When the layout already shrank
   (interactive-widget=resizes-content), keyboard.js leaves --ks-kb at 0 so this does not double-count. */
.ks-kb-open .dock {
  max-height: calc(100% - var(--ks-dock-top) - var(--ks-kb, 0px) - var(--ks-float-gap));
  max-height: calc(100dvh - var(--ks-dock-top) - var(--ks-kb, 0px) - var(--ks-float-gap));
}
body.ks-guidance .dock { display: none; }
/* While a place is typed the map overlays step aside, so nothing floats next to the suggestions */
body.ks-searching .fab, body.ks-searching .legend, body.ks-searching .map-recenter { display: none; }

/* From/To. Default: only "To" (its own full-width row) + a smaller "From: My location · Change start" line
   under it; the From field opens on request (then a swap button gets its own column). */
.route-fields {
  position: relative; display: grid; grid-template-columns: minmax(0, 1fr);
  column-gap: var(--ks-space-2); row-gap: var(--ks-space-2); align-items: center;
}
.route-fields.has-origin { grid-template-columns: minmax(0, 1fr) auto; }
.route-fields .place-search { grid-column: 1; }
.route-fields.has-origin .place-search--origin { grid-row: 1; }
.route-fields.has-origin .place-search--dest { grid-row: 2; }
.route-fields.has-origin .place-search--via,
.route-fields.has-origin .via-add { grid-row: 3; }
/* Via stop (0.3.36, signed-in only): a quiet "+ Via stop" link under "To" (only once a destination is
   set); it reveals one via field with the same search, removable with ×. Guests never see it. */
.via-add {
  grid-column: 1; justify-self: start; color: var(--ks-accent);
  margin-top: calc(-1 * var(--ks-space-2)); padding: 0 var(--ks-space-4);
}
body[data-tier="guest"] .via-add, body[data-tier="guest"] .place-search--via { display: none; }
#viaSearch { padding-right: calc(var(--ks-tap) + var(--ks-space-1)); }
.place-search { position: relative; display: grid; gap: var(--ks-space-1); }
.origin-row {
  grid-column: 1 / -1; display: flex; align-items: center; gap: var(--ks-space-2);
  min-height: var(--ks-tap); padding-left: var(--ks-space-4); color: var(--ks-muted); font-size: var(--ks-text-sm);
}
.origin-from::after { content: ":"; }
.origin-row .field-dot { position: static; flex: none; }
.origin-summary { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.origin-summary #originSummaryText { color: var(--ks-text); font-weight: var(--ks-weight-medium); }
.origin-row .btn { flex: none; color: var(--ks-accent); padding: 0 var(--ks-space-3); }
.route-fields.has-origin .origin-row { display: none; }
.field-hint { color: var(--ks-warning); font-size: var(--ks-text-sm); padding: 0 var(--ks-space-1); }
.field-label { font-size: var(--ks-text-sm); color: var(--ks-muted); font-weight: var(--ks-weight-medium); }
.route-fields .field-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
.field { position: relative; display: flex; align-items: center; }
.field-dot {
  position: absolute; left: var(--ks-space-4); width: 10px; height: 10px; border-radius: 50%; pointer-events: none;
}
.field-dot--origin { border: 2px solid var(--ks-muted); }
.field-dot--dest { background: var(--ks-accent); }
.field-dot--via { background: var(--ks-bg); border: 3px solid var(--ks-accent); }
.field--place .input { padding-left: calc(var(--ks-space-4) + 20px); }
/* Place fields: large touch target (>= 56 px, Tesla 68 px) and a larger, readable font */
.field--place .input { min-height: max(56px, var(--ks-tap-primary)); font-size: var(--ks-text-lg); }
#originSearch { padding-right: calc(var(--ks-tap) + var(--ks-space-1)); }
/* Swap sits in its own column, vertically centred between both fields (only with the From field open) */
.icon-btn--swap {
  grid-column: 2; grid-row: 1 / span 2;
  background: var(--ks-surface-2); border: 1px solid var(--ks-border); color: var(--ks-muted);
}
.icon-btn--swap:hover { color: var(--ks-text); }

.input, .select {
  width: 100%; min-height: var(--ks-tap-primary);
  padding: 0 var(--ks-space-4);
  background: var(--ks-bg); color: var(--ks-text);
  border: 1px solid var(--ks-border); border-radius: var(--ks-radius-card);
  font: var(--ks-text-md) var(--ks-font);
  transition: border-color var(--ks-dur-fast) var(--ks-ease);
}
.input::placeholder { color: var(--ks-placeholder); }
.input:hover, .select:hover { border-color: var(--ks-border-strong); }
.input:focus-visible, .select:focus-visible { border-color: var(--ks-accent); box-shadow: 0 0 0 3px var(--ks-accent-soft); }
.input[aria-invalid="true"] { border-color: var(--ks-danger); }
input[type="search"]::-webkit-search-cancel-button { display: none; }
.select {
  appearance: none; padding-right: 40px; cursor: pointer;
  background-image: linear-gradient(45deg, transparent 50%, var(--ks-muted) 50%), linear-gradient(135deg, var(--ks-muted) 50%, transparent 50%);
  background-position: calc(100% - 20px) 50%, calc(100% - 15px) 50%;
  background-size: 5px 5px; background-repeat: no-repeat;
}
.select--compact { width: auto; min-height: var(--ks-tap); background-color: var(--ks-surface-2); }

/* Autocomplete */
.ac-list {
  position: absolute; z-index: var(--ks-z-dropdown); left: 0; right: 0; top: calc(100% + var(--ks-space-1));
  display: flex; flex-direction: column; padding: var(--ks-space-1);
  max-height: 40vh; overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
  background: var(--ks-surface-2); border: 1px solid var(--ks-border-strong);
  border-radius: var(--ks-radius-card); box-shadow: var(--ks-shadow-2);
}
/* In-flow inside the scrolling dock: never clipped by overflow:hidden parents. The list itself
   scrolls when longer than the room above the keyboard (search mode caps it with dvh below). */
.dock .ac-list {
  position: static; max-height: min(40vh, 16rem); box-shadow: none;
  overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
}
.ac-item {
  display: flex; align-items: center; gap: var(--ks-space-3);
  min-height: var(--ks-tap); padding: var(--ks-space-2) var(--ks-space-3);
  background: transparent; border: 0; border-radius: var(--ks-radius-sm);
  color: var(--ks-text); font: var(--ks-text-md) var(--ks-font); text-align: left; cursor: pointer;
}
.ac-item { user-select: none; -webkit-user-select: none; touch-action: manipulation; -webkit-tap-highlight-color: transparent; }
.ac-item .ic { flex: none; color: var(--ks-muted); }
.ac-label { flex: 1; min-width: 0; overflow: hidden; overflow-wrap: anywhere; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; }
.ac-dist { flex: none; color: var(--ks-muted); font-size: var(--ks-text-sm); font-variant-numeric: tabular-nums; }
.ac-item:hover, .ac-item[aria-selected="true"] { background: var(--ks-surface-3); box-shadow: none; }
.ac-empty { padding: var(--ks-space-3); color: var(--ks-muted); font-size: var(--ks-text-sm); }
.provider-flag, .picked { display: none; }

/* Route summary */
.route-summary { display: flex; align-items: center; justify-content: space-between; gap: var(--ks-space-3); padding: var(--ks-space-1) var(--ks-space-1) 0; }
.route-summary-main { display: flex; align-items: baseline; gap: var(--ks-space-3); }
.route-eta { font-size: var(--ks-text-2xl); font-weight: var(--ks-weight-bold); color: var(--ks-accent); letter-spacing: -0.02em; }
.route-dist { color: var(--ks-muted); font-size: var(--ks-text-md); }
body.ks-guidance .route-summary { display: none; }

/* Premium EV charging-stop plan (route summary + map markers) */
.ev-plan-block {
  display: grid;
  gap: var(--ks-space-2);
  padding: var(--ks-space-2) var(--ks-space-1) 0;
}
body.ks-guidance .ev-plan-block { display: none; }
.ev-plan-status {
  margin: 0;
  font-size: var(--ks-text-sm);
  color: var(--ks-muted);
}
.ev-plan-status.ok { color: var(--ks-accent); }
.ev-plan-status.warn { color: var(--ks-warning); }
.ev-plan-status.error { color: var(--ks-danger); }
.ev-plan-stops {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--ks-space-1);
  max-height: 9.5rem;
  overflow-y: auto;
}
.ev-plan-stop-btn {
  display: flex;
  align-items: center;
  gap: var(--ks-space-3);
  width: 100%;
  text-align: left;
  min-height: var(--ks-tap);
  padding: var(--ks-space-2) var(--ks-space-3);
  border-radius: var(--ks-radius-md);
  border: 1px solid var(--ks-border);
  background: var(--ks-surface-2);
  color: var(--ks-text);
  cursor: pointer;
}
.ev-plan-stop-btn:hover { background: var(--ks-surface-3); }
.ev-plan-stop-btn:focus-visible { box-shadow: var(--ks-focus-ring); outline: none; }
.ev-plan-stop-main { display: grid; gap: 2px; flex: 1; min-width: 0; }
.ev-plan-stop-main strong { font-size: var(--ks-text-sm); }
.ev-plan-stop-btn .ic { flex: none; color: var(--ks-accent); }
.ev-plan-totals {
  font-size: var(--ks-text-sm);
  color: var(--ks-muted);
  font-variant-numeric: tabular-nums;
}
.ks-charge-stop {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: 2px solid #0B0F14;
  background: var(--ks-accent, #3ECF8E);
  color: #0B0F14;
  display: grid;
  place-items: center;
  padding: 0;
  cursor: pointer;
  box-shadow: 0 1px 4px rgba(0,0,0,.35);
}
.ks-charge-stop .ic { width: 16px; height: 16px; }
.ks-charge-stop--mcharge {
  background: #FF6600;
  border-color: #0B0F14;
  color: #fff;
}
[data-theme="light"] .ks-charge-stop { border-color: #fff; }
@media (min-width: 900px) {
  .ev-plan-stops { max-height: 14rem; }
}


/* ---------- Buttons ---------- */
.actions { display: grid; gap: var(--ks-space-2); }
.actions-row { display: flex; gap: var(--ks-space-2); }
.actions-row > .btn { flex: 1; }
.btn, button.btn {
  appearance: none; display: inline-flex; align-items: center; justify-content: center; gap: var(--ks-space-2);
  min-height: var(--ks-tap); min-width: var(--ks-tap); padding: 0 var(--ks-space-5);
  border: 1px solid transparent; border-radius: var(--ks-radius-pill);
  font: var(--ks-weight-bold) var(--ks-text-md)/1.2 var(--ks-font); text-align: center; text-decoration: none;
  cursor: pointer; user-select: none;
  transition: background-color var(--ks-dur-fast) var(--ks-ease), border-color var(--ks-dur-fast) var(--ks-ease);
}
.btn--primary { background: var(--ks-accent); color: var(--ks-on-accent); min-height: var(--ks-tap-primary); }
.btn--primary:hover { background: var(--ks-accent-hover); }
.btn--primary:active { background: var(--ks-accent-pressed); }
.btn--secondary { background: var(--ks-surface-2); color: var(--ks-text); border-color: var(--ks-border-strong); }
.btn--secondary:hover { background: var(--ks-surface-3); }
.btn--ghost { background: transparent; color: var(--ks-text); }
.btn--ghost:hover { background: var(--ks-surface-2); }
.btn--danger { background: var(--ks-danger); color: #1A0505; }
.btn--danger-ghost { background: var(--ks-danger-soft); color: var(--ks-danger); border-color: rgba(255, 92, 92, 0.4); }
.btn--sm { min-height: var(--ks-tap); padding: 0 var(--ks-space-4); font-size: var(--ks-text-sm); } /* smaller type, never a smaller target */
.btn--block { width: 100%; }
.btn:disabled, .btn[aria-disabled="true"] { opacity: 0.45; cursor: not-allowed; }
.btn.is-loading { position: relative; color: transparent !important; }
.btn.is-loading::after {
  content: ""; position: absolute; width: 1.2em; height: 1.2em; border-radius: 50%;
  border: 2px solid currentColor; border-color: var(--ks-on-accent) var(--ks-on-accent) transparent transparent;
  animation: ks-spin 0.8s linear infinite;
}
/* Report confirm / Still there / All clear — D7.18 */
.btn-confirm { min-height: var(--ks-tap-confirm); min-width: var(--ks-tap-confirm); font-size: var(--ks-text-lg); white-space: normal; }
/* Faster-route offer: time saving under the label, countdown digits + a draining bar on the timed button */
.btn--countdown { position: relative; overflow: hidden; gap: var(--ks-space-3); }
.btn-stack { display: inline-flex; flex-direction: column; align-items: center; line-height: 1.15; }
.btn-sub { font-size: var(--ks-text-sm); font-weight: var(--ks-weight-medium); opacity: 0.85; }
.btn-sub:empty { display: none; }
.btn-count {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  min-width: 1.9em; height: 1.9em; border-radius: 50%;
  background: rgba(0, 0, 0, 0.18); font-variant-numeric: tabular-nums;
}
.btn-count[hidden] { display: none; }
.btn--countdown::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 4px;
  background: currentColor; opacity: 0.55; transform: scaleX(0); transform-origin: left;
}
.btn--countdown.is-counting::after { transform: scaleX(1); animation: ks-drain var(--ks-countdown, 5s) linear forwards; }
@keyframes ks-drain { to { transform: scaleX(0); } }
@media (prefers-reduced-motion: reduce) { .btn--countdown.is-counting::after { animation: none; transform: scaleX(0); } }

.icon-btn {
  appearance: none; display: inline-grid; place-items: center; flex: none;
  width: var(--ks-tap); height: var(--ks-tap); padding: 0;
  border: 0; border-radius: var(--ks-radius-pill);
  background: transparent; color: var(--ks-text); cursor: pointer;
}
.icon-btn:hover { background: var(--ks-surface-2); }
.icon-btn--inline { position: absolute; right: 2px; color: var(--ks-muted); }
[data-surface="tesla"] .icon-btn .ic, [data-surface="tesla"] .btn .ic { width: 1.5em; height: 1.5em; }

/* ---------- Chips ---------- */
.chip {
  display: inline-flex; align-items: center; gap: var(--ks-space-1);
  min-height: 24px; padding: 0 var(--ks-space-2); border-radius: var(--ks-radius-pill);
  font-size: var(--ks-text-xs); font-weight: var(--ks-weight-medium); white-space: nowrap;
  background: var(--ks-surface-3); color: var(--ks-muted);
}
.chip--warning { background: var(--ks-warning-soft); color: var(--ks-warning); }
.chip--premium { background: rgba(91, 159, 255, 0.14); color: #A9C9FF; }
.chip--community { background: var(--ks-community-soft); color: var(--ks-community); }
.chip--success { background: var(--ks-accent-soft); color: var(--ks-accent); }

/* ---------- Status / hints ---------- */
.status-line { color: var(--ks-muted); font-size: var(--ks-text-sm); min-height: 0; }
.status-line:empty { display: none; }
.status-line.error { color: var(--ks-danger); }
.status-line.warn { color: var(--ks-warning); }
.status-line.ok { color: var(--ks-accent); }
.hint { color: var(--ks-muted); font-size: var(--ks-text-sm); text-align: center; }
.form-note { color: var(--ks-muted); font-size: var(--ks-text-sm); margin: 0; }
body:not(.ks-guest) #guestHint { display: none; }
body:not(.ks-guest) #guestCoach { display: none; }
.guest-coach {
  display: grid; gap: var(--ks-space-2);
  padding: var(--ks-space-3);
  margin: 0 0 var(--ks-space-2);
  border-radius: var(--ks-radius-card);
  background: var(--ks-accent-soft);
  border: 1px solid var(--ks-accent);
}
.guest-coach[hidden] { display: none; }
.guest-coach-body { margin: 0; color: var(--ks-text); font-size: var(--ks-text-sm); text-align: left; }
.guest-coach .btn { justify-self: end; }
body:not(.ks-guest) #btnLogin { display: none; }
body.ks-guest .sync-indicator { display: none; }
body.ks-guest #btnAccount { display: none; }
body.ks-guest #signedInMenu { display: none; }

/* ---------- Sheets (bottom sheet; soft-gate D15.4 — never a full-screen trap) ---------- */
.sheet-backdrop {
  position: fixed; inset: 0; z-index: var(--ks-z-backdrop);
  background: var(--ks-scrim); opacity: 0; pointer-events: none;
  transition: opacity var(--ks-dur-base) var(--ks-ease);
}
.sheet-backdrop.open { opacity: 1; pointer-events: auto; }
.sheet {
  position: fixed; left: 0; right: 0; bottom: var(--ks-kb, 0px); z-index: var(--ks-z-sheet);
  width: 100%; max-width: 560px; margin: 0 auto; overflow-y: auto; overscroll-behavior: contain;
  max-height: calc((100vh - var(--ks-kb, 0px)) * 0.88); max-height: calc((100dvh - var(--ks-kb, 0px)) * 0.88);
  display: grid; gap: var(--ks-space-3); align-content: start;
  padding: var(--ks-space-3) calc(var(--ks-safe-extra) + var(--ks-space-2)) calc(env(safe-area-inset-bottom, 0px) + var(--ks-space-5));
  background: var(--ks-surface); color: var(--ks-text);
  border-radius: var(--ks-radius-sheet) var(--ks-radius-sheet) 0 0;
  box-shadow: var(--ks-shadow-3);
  transform: translateY(110%); transition: transform var(--ks-dur-base) var(--ks-ease);
}
.sheet::before {
  content: ""; justify-self: center; width: 40px; height: 4px; border-radius: 2px; background: var(--ks-border-strong);
}
.sheet.open { transform: translateY(0); }
.sheet--gate { z-index: calc(var(--ks-z-sheet) + 1); } /* soft-gate may open above a feature sheet */
.sheet--tall { min-height: 50vh; }
.sheet-head { display: flex; align-items: center; justify-content: space-between; gap: var(--ks-space-2); }
.sheet-title { font-size: var(--ks-text-xl); font-weight: var(--ks-weight-bold); letter-spacing: -0.01em; }
.sheet-lead { font-size: var(--ks-text-lg); font-weight: var(--ks-weight-medium); padding-top: var(--ks-space-2); }
.sheet-meta { color: var(--ks-muted); font-size: var(--ks-text-sm); }
.sheet-meta:empty { display: none; }
.sheet-body { display: grid; gap: var(--ks-space-3); align-content: start; }
.sheet-body-text { color: var(--ks-muted); }
.sheet-actions { display: flex; gap: var(--ks-space-2); flex-wrap: wrap; }
.sheet-actions--stack { flex-direction: column; align-items: stretch; }
.sheet-actions--stack .btn--sm { align-self: center; }
/* Incident sheet (0.3.35): compact facts list; wraps to one column on narrow phones. */
/* "What's here?" (0.3.37): small sheet, no scrim (the pin on the map stays visible) */
.here-title { display: flex; align-items: center; gap: var(--ks-space-2); }
.here-title .ic { width: 22px; height: 22px; color: var(--ks-accent); flex: none; }
.here-address { font-size: var(--ks-text-lg); font-weight: var(--ks-weight-medium); overflow-wrap: anywhere; }
.here-address.is-muted { color: var(--ks-muted); font-weight: normal; font-size: var(--ks-text-md); }
.here-coords { color: var(--ks-muted); font-size: var(--ks-text-sm); font-variant-numeric: tabular-nums; user-select: text; }
.ks-here-pin { width: 30px; height: 40px; color: var(--ks-accent); pointer-events: none; filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.5)); }
.ks-here-pin .ic { width: 30px; height: 40px; fill: var(--ks-accent); stroke: #0B0F14; }
/* No browser callout / text selection while pressing the map (long press = "What's here?") */
.maplibregl-canvas { -webkit-touch-callout: none; -webkit-user-select: none; user-select: none; }
.incident-title { display: flex; align-items: center; gap: var(--ks-space-2); }
.incident-title .ic { width: 22px; height: 22px; color: var(--ks-warning); flex: none; }
.incident--danger .incident-title .ic { color: var(--ks-danger); }
.incident-text { font-size: var(--ks-text-lg); line-height: 1.4; overflow-wrap: anywhere; }
.incident-facts { display: grid; grid-template-columns: max-content 1fr; gap: var(--ks-space-1) var(--ks-space-3); margin: 0; }
.incident-facts dt { color: var(--ks-muted); font-size: var(--ks-text-sm); padding-top: 2px; }
.incident-facts dd { margin: 0; overflow-wrap: anywhere; }
@media (max-width: 360px) { .incident-facts { grid-template-columns: 1fr; } .incident-facts dd { margin-bottom: var(--ks-space-1); } }
.incident-credit { color: var(--ks-muted); font-size: var(--ks-text-sm); }
.incident-credit a { color: inherit; text-decoration: underline; }
.upsell {
  padding: var(--ks-space-3) var(--ks-space-4); border-radius: var(--ks-radius-card);
  background: rgba(91, 159, 255, 0.1); border: 1px solid rgba(91, 159, 255, 0.3); color: #C8DBFF; font-size: var(--ks-text-sm);
}

/* Live vehicle data in the EV sheet (0.3.38) */
.vd-block { display: grid; gap: var(--ks-space-2); margin: var(--ks-space-3) 0; }
.vd-card { display: grid; gap: var(--ks-space-2); padding: var(--ks-space-3); border-radius: var(--ks-radius-card); background: var(--ks-surface-2); }
.vd-card p { margin: 0; }
.vd-soc { font-size: var(--ks-text-lg, 1.1rem); }
.vd-toggle { display: flex; align-items: center; gap: var(--ks-space-2); font-size: var(--ks-text-sm, 0.9rem); cursor: pointer; }
.vd-toggle .switch-input { flex: none; }
.vd-loc { opacity: 0.85; }
.origin-row .origin-vehicle { display: inline-flex; align-items: center; gap: var(--ks-space-1); }
.origin-row .origin-vehicle .ic { width: 1.1em; height: 1.1em; }
.origin-row .origin-vehicle.is-stale { color: var(--ks-warning, #c47b00); }
/* Manual charge level per EV profile (0.3.40). */
.ev-soc-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--ks-space-2); padding: var(--ks-space-1) var(--ks-space-4) 0; }
.ev-soc-row .field-label { margin: 0; }
.ev-soc-row .ev-soc-input { width: 6.5rem; flex: 0 0 auto; }
.ev-soc-row .ev-soc-source { flex: 1 1 12rem; }

/* Menu */
.menu-section {
  display: flex; align-items: center; gap: var(--ks-space-2);
  margin-top: var(--ks-space-2); color: var(--ks-muted);
  font-size: var(--ks-text-xs); font-weight: var(--ks-weight-bold); letter-spacing: 0.06em; text-transform: uppercase;
}
.menu-section .chip { text-transform: none; letter-spacing: 0; }
.menu-list { display: grid; background: var(--ks-surface-2); border-radius: var(--ks-radius-card); overflow: hidden; }
.menu-item {
  appearance: none; display: flex; align-items: center; gap: var(--ks-space-3);
  min-height: var(--ks-tap-primary); padding: 0 var(--ks-space-4);
  background: transparent; border: 0; border-bottom: 1px solid var(--ks-border);
  color: var(--ks-text); font: var(--ks-weight-medium) var(--ks-text-md) var(--ks-font); text-align: left; cursor: pointer;
}
.menu-item:last-child { border-bottom: 0; }
.menu-item .ic { color: var(--ks-muted); }
.menu-item:hover, .menu-item:active { background: var(--ks-surface-3); }
.menu-settings { display: grid; gap: 1px; background: var(--ks-border); border-radius: var(--ks-radius-card); overflow: hidden; }
.menu-settings .setting-row { background: var(--ks-surface-2); padding: var(--ks-space-2) var(--ks-space-4); }
.setting-row {
  display: flex; align-items: center; justify-content: space-between; gap: var(--ks-space-3);
  min-height: var(--ks-tap-primary);
}
.setting-label { display: inline-flex; align-items: center; gap: var(--ks-space-3); }
.setting-label .ic { color: var(--ks-muted); }
.setting-value { color: var(--ks-muted); font-size: var(--ks-text-sm); }
.setting-row.is-disabled .setting-label { color: var(--ks-muted); }
.select:disabled { opacity: 0.5; cursor: not-allowed; }
.hint--left { text-align: left; margin: var(--ks-space-2) var(--ks-space-1) 0; }
.setting-value.ok { color: var(--ks-accent); }
.setting-value.warn { color: var(--ks-warning); }
.app-legal {
  display: flex; justify-content: center; flex-wrap: wrap; gap: var(--ks-space-1) var(--ks-space-4);
  padding-top: var(--ks-space-3); font-size: var(--ks-text-sm);
}
.app-legal a { color: var(--ks-muted); text-decoration: none; min-height: var(--ks-tap); display: inline-flex; align-items: center; }
.app-legal a:hover { color: var(--ks-text); text-decoration: underline; }
/* Version number on its own line under the legal links; opens What's new */
.app-legal .app-version { flex-basis: 100%; justify-content: center; font-variant-numeric: tabular-nums; }

/* Segmented control */
.segmented { display: inline-flex; padding: 3px; gap: 3px; background: var(--ks-bg); border-radius: var(--ks-radius-pill); border: 1px solid var(--ks-border); }
.segmented button {
  appearance: none; display: inline-flex; align-items: center; justify-content: center; gap: var(--ks-space-1);
  min-height: calc(var(--ks-tap) - 8px); padding: 0 var(--ks-space-3);
  border: 0; border-radius: var(--ks-radius-pill); background: transparent; color: var(--ks-muted);
  font: var(--ks-weight-medium) var(--ks-text-sm) var(--ks-font); cursor: pointer;
}
.segmented button[aria-pressed="true"] { background: var(--ks-surface-3); color: var(--ks-text); }
.segmented--block { display: flex; }
.segmented--block button { flex: 1; min-height: var(--ks-tap); }

/* Switch (voice) */
.switch {
  appearance: none; position: relative; width: 56px; height: 32px; flex: none; padding: 0;
  border: 0; border-radius: var(--ks-radius-pill); background: var(--ks-accent); cursor: pointer;
}
.switch::after {
  content: ""; position: absolute; top: 3px; left: 27px; width: 26px; height: 26px; border-radius: 50%;
  background: var(--ks-on-accent); transition: left var(--ks-dur-fast) var(--ks-ease);
}
.switch[aria-pressed="true"] { background: var(--ks-surface-3); }  /* pressed = muted */
.switch[aria-pressed="true"]::after { left: 3px; background: var(--ks-muted); }
.switch-input {
  appearance: none; position: relative; width: 56px; height: 32px; flex: none; margin: 0;
  border-radius: var(--ks-radius-pill); background: var(--ks-surface-3); cursor: pointer;
}
.switch-input::after {
  content: ""; position: absolute; top: 3px; left: 3px; width: 26px; height: 26px; border-radius: 50%;
  background: var(--ks-muted); transition: left var(--ks-dur-fast) var(--ks-ease);
}
.switch-input:checked { background: var(--ks-accent); }
.switch-input:checked::after { left: 27px; background: var(--ks-on-accent); }

/* Handoff targets / report type tiles */
.target-grid, .type-grid { display: grid; gap: var(--ks-space-2); }
.target-grid { grid-template-columns: repeat(3, 1fr); }
.type-grid { grid-template-columns: repeat(3, 1fr); }
.target-btn, .type-tile {
  appearance: none; display: grid; justify-items: center; align-content: center; gap: var(--ks-space-2);
  min-height: calc(var(--ks-tap-confirm) + 28px); padding: var(--ks-space-3) var(--ks-space-2);
  background: var(--ks-surface-2); color: var(--ks-text);
  border: 2px solid transparent; border-radius: var(--ks-radius-card);
  font: var(--ks-weight-medium) var(--ks-text-sm)/1.2 var(--ks-font); text-align: center; cursor: pointer;
}
.target-btn:hover, .type-tile:hover { background: var(--ks-surface-3); }
.type-tile .ic { color: var(--ks-community); }
.type-tile[aria-checked="true"] { border-color: var(--ks-community); background: var(--ks-community-soft); }
.type-tile { position: relative; overflow: hidden; }
.type-tile__ring {
  position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  background: conic-gradient(var(--ks-community) calc(var(--ks-report-progress, 0) * 1turn), transparent 0);
  opacity: 0; mask: radial-gradient(farthest-side, transparent calc(100% - 4px), #000 calc(100% - 3px));
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 4px), #000 calc(100% - 3px));
}
.type-tile.is-counting .type-tile__ring { opacity: 1; }
.subtype-row { display: grid; gap: var(--ks-space-2); margin-top: var(--ks-space-2); }
.subtype-chips {
  display: flex; flex-wrap: wrap; gap: var(--ks-space-2);
}
.subtype-chip {
  appearance: none; min-height: var(--ks-tap-primary); padding: 0 var(--ks-space-4);
  border-radius: var(--ks-radius-pill); border: 2px solid var(--ks-border-strong);
  background: var(--ks-surface-2); color: var(--ks-text);
  font: var(--ks-weight-medium) var(--ks-text-sm)/1.2 var(--ks-font); cursor: pointer;
}
.subtype-chip:hover { background: var(--ks-surface-3); }
.subtype-chip[aria-pressed="true"] {
  border-color: var(--ks-community); background: var(--ks-community-soft);
}
/* Modifiers (0.3.54): toggles on top of the primary choice. Fixed-width mark (+ → ✓) so a toggle never shifts the row. */
.subtype-chips--modifiers { padding-top: var(--ks-space-2); border-top: 1px dashed var(--ks-border-strong); }
.subtype-chip--modifier { display: inline-flex; align-items: center; gap: var(--ks-space-2); border-style: dashed; }
.subtype-chip--modifier::before { content: "+"; display: inline-block; width: 1em; text-align: center; font-weight: var(--ks-weight-bold); }
.subtype-chip--modifier[aria-pressed="true"] { border-style: solid; }
.subtype-chip--modifier[aria-pressed="true"]::before { content: "✓"; color: var(--ks-community); }
.subtype-chip[aria-pressed="true"] { box-shadow: inset 0 0 0 1px var(--ks-community); }
.subtype-chip { min-width: var(--ks-tap); touch-action: manipulation; }
html[data-surface="tesla"] .subtype-chip {
  min-height: var(--ks-tap-confirm); font-size: var(--ks-text-md);
}

.report-extras { display: grid; gap: var(--ks-space-2); }
.photo-block { display: flex; align-items: center; gap: var(--ks-space-3); flex-wrap: wrap; }
.photo-block .hint { text-align: left; }
.btn--file { cursor: pointer; }
.vote-actions { display: flex; flex-wrap: wrap; gap: var(--ks-space-3); }
.vote-actions .btn-confirm { flex: 1 1 140px; }
.report-photo img { display: block; width: 100%; max-height: 240px; object-fit: contain; border-radius: var(--ks-radius-card); background: var(--ks-bg); }

/* Forms */
.form-grid { display: grid; gap: var(--ks-space-2); }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--ks-space-3); }
.form-row > div { display: grid; gap: var(--ks-space-1); }
.chip-group { border: 0; padding: 0; margin: var(--ks-space-2) 0; display: flex; flex-wrap: wrap; gap: var(--ks-space-2); }
.chip-group legend { margin-bottom: var(--ks-space-2); }
.chip-check { position: relative; }
.chip-check input { position: absolute; opacity: 0; inset: 0; margin: 0; cursor: pointer; }
.chip-check span {
  display: inline-flex; align-items: center; min-height: var(--ks-tap); padding: 0 var(--ks-space-4);
  border-radius: var(--ks-radius-pill); border: 1px solid var(--ks-border-strong); color: var(--ks-muted);
}
.chip-check input:checked + span { border-color: var(--ks-accent); background: var(--ks-accent-soft); color: var(--ks-text); }
.chip-check input:focus-visible + span { box-shadow: var(--ks-focus-ring); }
#captchaMount { font-size: var(--ks-text-sm); color: var(--ks-muted); }
#captchaMount:empty { display: none; }

/* Lists (library, voice, cosmetics, leaderboard) */
.library-cols { display: grid; gap: var(--ks-space-4); }
.list-title { font-size: var(--ks-text-sm); color: var(--ks-muted); font-weight: var(--ks-weight-bold); margin-bottom: var(--ks-space-2); }
.list-head { display: flex; align-items: center; justify-content: space-between; margin-top: var(--ks-space-2); }
.list-head .list-title { margin: 0; }
.library-list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--ks-space-2); }
.library-list > li.muted, .library-list > li.error, .empty-state {
  padding: var(--ks-space-4); border-radius: var(--ks-radius-card);
  border: 1px dashed var(--ks-border-strong); color: var(--ks-muted); font-size: var(--ks-text-sm); text-align: center;
}
.library-list > li.error { color: var(--ks-danger); border-color: rgba(255, 92, 92, 0.4); }
.lib-item, .library-list button:not(.btn) {
  appearance: none; display: flex; align-items: center; gap: var(--ks-space-3); width: 100%;
  min-height: var(--ks-tap-primary); padding: var(--ks-space-2) var(--ks-space-4);
  background: var(--ks-surface-2); color: var(--ks-text);
  border: 1px solid transparent; border-radius: var(--ks-radius-card);
  font: var(--ks-weight-medium) var(--ks-text-md) var(--ks-font); text-align: left; cursor: pointer;
}
.library-list button:not(.btn):hover { background: var(--ks-surface-3); }
.library-list button:disabled { opacity: 0.55; cursor: not-allowed; }
.library-list .equipped > button, .library-item.equipped > button { border-color: var(--ks-accent); }
.library-list > li.lib-row { display: flex; align-items: center; gap: var(--ks-space-1); }
.library-list > li.lib-row > .lib-item { flex: 1 1 auto; min-width: 0; }
.library-list > li.lib-row > button.lib-act {
  flex: 0 0 auto; width: var(--ks-tap); padding: 0; justify-content: center;
  background: transparent; color: var(--ks-muted);
}
.library-list > li.lib-row > button.lib-act:hover { background: var(--ks-surface-2); color: var(--ks-text); }
.library-list > li.lib-row > button.lib-act[data-act="delete"]:hover { color: var(--ks-danger); }
.auth-social { margin-bottom: var(--ks-space-2); }
.auth-social-or { text-align: center; margin: 0; }
.lib-item-sub { color: var(--ks-muted); font-size: var(--ks-text-sm); font-weight: var(--ks-weight-regular); margin-left: auto; text-align: right; }
.board-list > li {
  display: flex; align-items: center; gap: var(--ks-space-3); min-height: var(--ks-tap);
  padding: var(--ks-space-2) var(--ks-space-4); background: var(--ks-surface-2); border-radius: var(--ks-radius-card);
}
.board-list > li.equipped { border: 1px solid var(--ks-accent); }

/* Stats (profile) */
.stat-row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--ks-space-2); }
.stat { display: grid; gap: var(--ks-space-1); padding: var(--ks-space-4); background: var(--ks-surface-2); border-radius: var(--ks-radius-card); }
.stat-value { font-size: var(--ks-text-2xl); font-weight: var(--ks-weight-bold); line-height: 1.1; min-height: 1.1em; }
.stat-label { color: var(--ks-muted); font-size: var(--ks-text-sm); }
#profileTrust { font-size: var(--ks-text-xl); }
.stat-chip { justify-self: start; margin-top: var(--ks-space-2); }
.stat-sub { display: block; color: var(--ks-muted); font-size: var(--ks-text-sm); font-weight: var(--ks-weight-medium); }
#profileTrust[data-low="1"] { color: var(--ks-warning); }
.skeleton {
  display: inline-block; width: 4ch; height: 0.9em; border-radius: var(--ks-radius-sm);
  background: linear-gradient(90deg, var(--ks-surface-3), #2E3A4D, var(--ks-surface-3)); background-size: 200% 100%;
  animation: ks-shimmer 1.2s ease-in-out infinite;
}

/* ---------- Toast ---------- */
.ks-toast {
  position: fixed; left: 50%; z-index: var(--ks-z-toast);
  /* Top of the map, under the chrome: never over sheet actions or the next turn (iteration 3) */
  top: calc(max(var(--ks-ui-top, 0px), var(--ks-edge-top)) + var(--ks-space-3));
  transform: translateX(-50%) translateY(-8px); opacity: 0; pointer-events: none;
  max-width: min(90vw, 26rem); padding: var(--ks-space-3) var(--ks-space-5);
  background: var(--ks-surface-2); color: var(--ks-text);
  border: 1px solid rgba(62, 207, 142, 0.4); border-radius: var(--ks-radius-card);
  box-shadow: var(--ks-shadow-2); font-size: var(--ks-text-sm); font-weight: var(--ks-weight-medium); text-align: center;
  transition: opacity var(--ks-dur-fast) var(--ks-ease), transform var(--ks-dur-fast) var(--ks-ease);
}
.ks-toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }

/* ---------- Banners ---------- */
.status-banner { position: absolute; top: 0; left: 0; right: 0; z-index: calc(var(--ks-z-chrome) + 1); }
.status-banner, .trust-notice {
  flex: none; padding: var(--ks-space-2) var(--ks-space-4);
  padding-top: calc(env(safe-area-inset-top, 0px) + var(--ks-space-2));
  font-size: var(--ks-text-sm); color: var(--ks-text);
  background: var(--ks-warning-soft); border-bottom: 2px solid var(--ks-warning);
}
.status-banner[data-severity="critical"] { background: var(--ks-danger-soft); border-bottom-color: var(--ks-danger); }
.status-banner[data-severity="info"] { background: var(--ks-accent-soft); border-bottom-color: var(--ks-accent); }

/* ---------- Community pins (D12 community orange; tap → detail / G-VOTE) ---------- */
.ks-pin-layer { position: absolute; inset: 0; pointer-events: none; z-index: 5; }
.ks-community-pin {
  position: absolute; pointer-events: auto; width: var(--ks-tap); height: var(--ks-tap); margin: 0; padding: 0;
  border: 0; background: transparent; cursor: pointer; transform: translate(-50%, -100%);
  display: grid; place-items: center;
}
.ks-community-pin .ks-pin-dot {
  width: 24px; height: 24px; border-radius: 50% 50% 50% 0; transform: rotate(-45deg);
  background: var(--ks-community);
  box-shadow: 0 0 0 2px var(--ks-bg), 0 2px 8px rgba(0, 0, 0, 0.45);
}
[data-surface="tesla"] .ks-community-pin .ks-pin-dot { width: 32px; height: 32px; }
.ks-community-pin:focus-visible, .ks-community-pin:hover { box-shadow: none; }
.ks-community-pin:focus-visible .ks-pin-dot, .ks-community-pin:hover .ks-pin-dot { box-shadow: 0 0 0 3px var(--ks-accent), 0 2px 8px rgba(0, 0, 0, 0.45); }
.maplibregl-marker .ks-community-pin { position: relative; transform: none; }
/* Opposite-direction report (0.3.54): small two-way badge on the pin, same pin otherwise. */
.ks-community-pin .ks-pin-badge {
  position: absolute; top: 0; right: 0; width: 18px; height: 18px; border-radius: 50%;
  display: grid; place-items: center; background: var(--ks-bg); color: var(--ks-community);
  box-shadow: 0 0 0 2px var(--ks-community); pointer-events: none;
}
.ks-community-pin .ks-pin-badge .ic { width: 12px; height: 12px; }

/* ---------- Cosmetics (K light): map car icon + chip skins ---------- */
.map-car-icon {
  position: absolute; top: 72%; left: 50%; transform: translate(-50%, -50%);
  width: 36px; height: 36px; border-radius: 50%; background: var(--ks-accent);
  box-shadow: 0 0 0 3px rgba(62, 207, 142, 0.35); opacity: 0.85; pointer-events: none;
}
.map-car-icon::after {
  content: ""; position: absolute; inset: 8px; background: var(--ks-on-accent); border-radius: 4px 4px 6px 6px;
  clip-path: polygon(20% 60%, 35% 30%, 65% 30%, 80% 60%, 75% 75%, 25% 75%);
}
.map-placeholder.ks-car-default .map-car-icon { background: var(--ks-accent); }
.map-placeholder.ks-car-teal .map-car-icon { background: #2dd4bf; box-shadow: 0 0 0 3px rgba(45, 212, 191, 0.4), 0 0 16px #2dd4bf66; }
.map-placeholder.ks-car-amber .map-car-icon { background: var(--ks-warning); box-shadow: 0 0 0 3px rgba(255, 176, 32, 0.4); }
.map-placeholder.ks-car-premium .map-car-icon { background: linear-gradient(135deg, #e8eef7, #5b9fff 55%, #3ecf8e); box-shadow: 0 0 0 3px #5b9fff88, 0 0 20px #3ecf8e55; }
.gamification-chip.ks-chip-glow { box-shadow: 0 0 10px rgba(62, 207, 142, 0.45); border-color: var(--ks-accent); }
.gamification-chip.ks-chip-premium { background: linear-gradient(90deg, rgba(91, 159, 255, 0.22), rgba(62, 207, 142, 0.2)); border-color: #5b9fff; }
.cosmetic-swatch {
  display: inline-block; width: 20px; height: 20px; border-radius: 50%; flex: none;
  border: 1px solid var(--ks-border-strong);
}
.cosmetic-swatch.ks-car-default, .cosmetic-swatch.ks-chip-default { background: var(--ks-accent); }
.cosmetic-swatch.ks-car-teal { background: #2dd4bf; }
.cosmetic-swatch.ks-car-amber { background: var(--ks-warning); }
.cosmetic-swatch.ks-car-premium { background: linear-gradient(135deg, #e8eef7, #5b9fff); }
.cosmetic-swatch.ks-chip-glow { background: var(--ks-accent); box-shadow: 0 0 6px var(--ks-accent); }
.cosmetic-swatch.ks-chip-premium { background: #5b9fff; }

/* ---------- Tesla density tweaks ---------- */
[data-surface="tesla"] .fab-label { display: inline; }
[data-surface="tesla"] .type-grid { grid-template-columns: repeat(3, 1fr); }
[data-surface="tesla"] .report-extras { display: none; } /* Tesla: type + confirm only (D7) */
[data-surface="tesla"] .sheet { max-width: 720px; }
.fab-label { display: none; }

/* ---------- Landscape (desktop, Tesla, phone landscape): plan panel top-left, app bar pill top-right ---------- */
@media (min-width: 760px) and (min-aspect-ratio: 1/1) {
  .dock {
    --ks-dock-top: var(--ks-edge-top);
    right: auto; width: min(var(--ks-dock-width, 400px), 48vw);
  }
  .top-strip { left: auto; }
  .brand { margin-right: var(--ks-space-2); }
}
@media (min-width: 900px) and (min-aspect-ratio: 1/1) {
  .fab-label { display: inline; }
  .maneuver-card { right: auto; width: min(34rem, 44vw); }
  .trip-bar { right: auto; width: min(30rem, 44vw); }
  .sheet { bottom: calc(env(safe-area-inset-bottom, 0px) + var(--ks-safe-extra) + var(--ks-kb, 0px)); border-radius: var(--ks-radius-sheet); }
  .library-cols { grid-template-columns: repeat(3, 1fr); }
}

/* ---------- Typing a place: search mode (phone + Tesla) ----------
   While a place field has focus the panel shows only that field and its suggestions. Route summary,
   actions and the other fields step aside so the list is not crushed into a sliver above the keyboard
   (iOS Safari bug: the dock max-height ends above the keyboard while other chrome still claimed the
   space). The list scrolls inside itself, capped with dvh so it fits in the visual viewport. */
body.ks-searching .dock > :not(.route-fields),
body.ks-searching .route-fields > :not(.is-active) { display: none; }
body.ks-searching .dock .ac-list {
  max-height: calc(100vh - var(--ks-dock-top) - var(--ks-kb, 0px) - var(--ks-tap-primary) - 5 * var(--ks-float-gap));
  max-height: calc(100dvh - var(--ks-dock-top) - var(--ks-kb, 0px) - var(--ks-tap-primary) - 5 * var(--ks-float-gap));
}
/* Tesla in-car: also hide the app bar and pin the field to the top of the screen (keyboard covers ~55 %). */
[data-surface="tesla"] body.ks-searching .dock { --ks-dock-top: calc(env(safe-area-inset-top, 0px) + var(--ks-vv-top, 0px) + var(--ks-float-gap)); }
[data-surface="tesla"] body.ks-searching .top-strip { display: none; }

/* ---------- Tesla in-car browser: sheets open from the top ----------
   The in-car keyboard covers the lower half of the screen and the browser does not report it, so form
   sheets (sign-in, reports) sit at the top and end above the keyboard inset (keyboard.js). html.ks-in-car
   is set from the user agent (surface.js); wide desktop windows keep the Tesla density with bottom sheets. */
.ks-in-car .sheet {
  top: calc(env(safe-area-inset-top, 0px) + var(--ks-safe-extra)); bottom: auto;
  max-height: calc(100vh - var(--ks-kb, 0px) - 2 * var(--ks-safe-extra));
  max-height: calc(100dvh - var(--ks-kb, 0px) - 2 * var(--ks-safe-extra));
  border-radius: var(--ks-radius-sheet);
  transform: translateY(calc(-100% - 2 * var(--ks-safe-extra)));
}
.ks-in-car .sheet.open { transform: translateY(0); }
.ks-in-car .sheet::before { display: none; } /* drag handle belongs to bottom sheets */

/* Guidance in landscape: the non-modal faster-route offer sits beside the maneuver card and trip bar
   (left column, --ks-ui-left) and left of the menu pill, so the next maneuver stays readable. */
@media (min-width: 900px) and (min-aspect-ratio: 1/1) {
  body.ks-guidance #detourSheet {
    left: calc(var(--ks-ui-left, 0px) + var(--ks-float-gap));
    right: calc(var(--ks-edge-right) + var(--ks-tap) * 2 + var(--ks-space-4));
    width: auto; max-width: 560px; margin: 0;
  }
}

/* ---------- Motion ---------- */
@keyframes ks-spin { to { transform: rotate(360deg); } }
@keyframes ks-shimmer { from { background-position: 100% 0; } to { background-position: -100% 0; } }
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; animation: none !important; }
}

/* ---------- Wingman (0.3.46) ---------- */
.wingman-qr {
  display: flex; align-items: center; justify-content: center;
  min-height: 180px; margin: var(--ks-space-3) 0;
  background: #fff; border-radius: var(--ks-radius-md, 12px);
  padding: var(--ks-space-3);
}
.wingman-qr img { display: block; width: 180px; height: 180px; }
.wingman-actions { margin-bottom: var(--ks-space-3); }
.wingman-list { display: flex; flex-direction: column; gap: var(--ks-space-2); margin-bottom: var(--ks-space-3); }
.wingman-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--ks-space-2); padding: var(--ks-space-2) 0;
  border-bottom: 1px solid var(--ks-border, rgba(127,127,127,.25));
}
.wingman-join-banner {
  position: fixed; left: var(--ks-edge-left, 12px); right: var(--ks-edge-right, 12px);
  top: calc(var(--ks-safe-top, 0px) + var(--ks-space-2));
  z-index: 80; padding: var(--ks-space-3);
  background: var(--ks-surface, #111); color: var(--ks-fg, #fff);
  border-radius: var(--ks-radius-md, 12px); text-align: center;
  box-shadow: 0 8px 24px rgba(0,0,0,.35);
}
body.ks-wingman #btnWingman,
body.ks-wingman #btnAccount,
body.ks-guest #btnWingman { display: none; }
body.ks-wingman #accountForm,
body.ks-wingman #accountPlan,
body.ks-wingman #accountData,
body.ks-wingman #btnLibrary,
body.ks-wingman #btnSavePlace,
body.ks-wingman #btnSaveTrip,
body.ks-wingman #hereSave,
body.ks-wingman #btnProfile,
body.ks-wingman #btnEv,
body.ks-wingman #btnVoice,
body.ks-wingman #btnCosmetics,
body.ks-wingman #signedInMenu { display: none !important; }
/* Wingman live/staleness chip (0.3.49) */
.wingman-live {
  display: none; position: absolute; left: 50%; transform: translateX(-50%);
  top: calc(max(var(--ks-ui-top, 0px), var(--ks-edge-top)) + var(--ks-space-2));
  z-index: calc(var(--ks-z-chrome) + 2);
  padding: 4px 10px; border-radius: 999px;
  font-size: var(--ks-text-xs, .75rem); font-weight: var(--ks-weight-semibold);
  background: var(--ks-surface-2); color: var(--ks-text);
  border: 1px solid rgba(62, 207, 142, 0.45); box-shadow: var(--ks-shadow-1);
  pointer-events: none; white-space: nowrap;
}
body.ks-wingman .wingman-live { display: block; }
.wingman-live.is-stale { border-color: rgba(240, 180, 40, 0.7); color: var(--ks-warning, #c90); }
.wingman-live.is-lost { border-color: rgba(220, 60, 60, 0.7); color: var(--ks-danger, #e44); }
/* ---------- Wingman co-driver bar + stops sheet (0.3.56) ---------- */
/* The driver's navigation is theirs: a passenger cannot end it, and edits stops in the sheet, not in the plan form. */
body.ks-wingman .trip-bar, /* ETA, distance and state live in the co-driver bar */
body.ks-wingman #btnStop,
body.ks-wingman #btnAddVia,
body.ks-wingman #viaBlock { display: none !important; }
.wingman-bar {
  display: none; position: absolute; z-index: var(--ks-z-chrome);
  left: var(--ks-edge-left); right: var(--ks-edge-right);
  bottom: calc(max(var(--ks-wb-bottom, 0px), env(safe-area-inset-bottom, 0px)) + var(--ks-float-gap));
  gap: var(--ks-space-2); padding: var(--ks-space-2);
  background: var(--ks-surface-glass); border: 1px solid var(--ks-border); box-shadow: var(--ks-shadow-2);
  -webkit-backdrop-filter: blur(var(--ks-glass-blur)); backdrop-filter: blur(var(--ks-glass-blur));
  border-radius: calc(var(--ks-radius-card) + var(--ks-space-2));
}
body.ks-wingman.ks-guidance .wingman-bar,
body.ks-wingman.ks-route-ready .wingman-bar { display: grid; }
.wb-stats { display: flex; align-items: center; gap: var(--ks-space-3); min-width: 0; }
.wb-speed {
  appearance: none; display: inline-flex; align-items: baseline; gap: var(--ks-space-1);
  min-height: var(--ks-tap); min-width: 6.5rem; padding: 0 var(--ks-space-3); justify-content: center;
  border: 1px solid var(--ks-border); border-radius: var(--ks-radius-pill); background: var(--ks-surface-2); color: var(--ks-text);
  font-family: var(--ks-font); cursor: pointer; align-items: center;
}
.wb-speed-val { font-size: var(--ks-text-xl); font-weight: var(--ks-weight-bold); font-variant-numeric: tabular-nums; line-height: 1; }
.wb-speed-unit { font-size: var(--ks-text-xs); color: var(--ks-muted); }
.wb-speed.is-stale .wb-speed-val { color: var(--ks-muted); }
.wb-trip { display: grid; min-width: 0; flex: 1; line-height: 1.2; }
.wb-eta { font-size: var(--ks-text-lg, 1.1rem); font-weight: var(--ks-weight-bold); color: var(--ks-accent); font-variant-numeric: tabular-nums; }
.wb-dist { font-size: var(--ks-text-sm); color: var(--ks-muted); font-variant-numeric: tabular-nums; }
.wb-fresh { flex: none; font-size: var(--ks-text-xs); font-weight: var(--ks-weight-semibold); color: var(--ks-accent); white-space: nowrap; }
.wb-fresh.is-delayed { color: var(--ks-warning, #c90); }
.wb-fresh.is-lost { color: var(--ks-danger, #e44); }
.wb-actions { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--ks-space-2); }
.wb-btn {
  appearance: none; position: relative; display: inline-flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  min-height: var(--ks-tap-primary); padding: var(--ks-space-1) var(--ks-space-2);
  border: 0; border-radius: var(--ks-radius-card); background: var(--ks-surface-3); color: var(--ks-text);
  font: var(--ks-weight-semibold) var(--ks-text-xs) var(--ks-font); cursor: pointer; -webkit-tap-highlight-color: transparent;
}
.wb-btn:active { transform: scale(.97); }
.wb-btn .ic { width: 1.4em; height: 1.4em; }
.wb-count {
  position: absolute; top: 4px; right: 8px; min-width: 1.4em; padding: 0 4px; border-radius: 999px;
  background: var(--ks-accent); color: var(--ks-on-accent, #04210f); font-size: var(--ks-text-xs); font-weight: var(--ks-weight-bold); text-align: center;
}
.wb-count[hidden] { display: none; }
@media (min-width: 900px) and (min-aspect-ratio: 1/1) {
  .wingman-bar { right: auto; width: min(30rem, 44vw); }
}
.ws-search { display: grid; gap: var(--ks-space-2); margin-bottom: var(--ks-space-3); position: relative; }
.ws-mode[hidden] { display: none; }
.ws-changing { display: flex; align-items: center; justify-content: space-between; gap: var(--ks-space-2); color: var(--ks-muted); font-size: var(--ks-text-sm); }
.ws-list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--ks-space-2); }
.ws-row { display: grid; gap: var(--ks-space-2); padding: var(--ks-space-2); border-radius: var(--ks-radius-card); background: var(--ks-surface-2); border: 1px solid transparent; }
.ws-row.is-changing { border-color: var(--ks-accent); }
.ws-head { display: flex; align-items: center; gap: var(--ks-space-3); min-width: 0; }
.ws-ix {
  flex: none; display: inline-flex; align-items: center; justify-content: center; width: 2rem; height: 2rem; border-radius: 50%;
  background: var(--ks-surface-3); font-weight: var(--ks-weight-bold); font-variant-numeric: tabular-nums;
}
.ws-row.is-charge .ws-ix { background: var(--ks-accent-soft); color: var(--ks-accent); }
.ws-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: var(--ks-weight-medium); }
.ws-ops { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--ks-space-2); }
.ws-op {
  appearance: none; display: inline-flex; align-items: center; justify-content: center;
  min-height: 3rem; border: 0; border-radius: var(--ks-radius-card); background: var(--ks-surface-3); color: var(--ks-text); cursor: pointer;
}
.ws-op:disabled { opacity: .4; cursor: default; }
.ws-op--remove { color: var(--ks-danger, #e44); }
.is-busy .ws-list { opacity: .7; }
.sheet-subtitle { font-size: var(--ks-font-sm, .9rem); font-weight: 600; margin: var(--ks-space-3) 0 var(--ks-space-2); }
