/* GeoCharge for Tesla — styles.
   Target: Tesla in-car browser, landscape ~1000–1400px wide, touch-first.
   Dark theme by default (night driving). Accent matches geocharge.ge. */

/* Dark is the default (night driving). The light theme below repaints the same
   surfaces for daylight; the attribute is set before first paint by the
   bootstrap script in index.html, so there is no dark flash on a light car. */
:root {
  color-scheme: dark;
  --bg:        #0d1216;
  --surface:   #151c22;
  --surface-2: #1c252d;
  --border:    #263038;
  --text:      #eef3f6;
  --text-dim:  #9fb0bb;
  --accent:    #2bd594;
  --accent-dk: #1fae78;
  --busy:      #f5a623;
  --out:       #6b7a85;
  --danger:    #e5544b;
  /* Green/orange used as TEXT rather than as a fill. On a dark surface the
     brand colours themselves read fine, so these are the same colours here and
     only darken in the light theme, where bright green on white does not. */
  --accent-ink: #2bd594;
  --busy-ink:   #f5a623;
  /* Slate: the source publishes no live availability (Turkey's registry). */
  --unknown:     #4F7C9E;
  --unknown-ink: #8FB6D1;
  /* Light blue: City Hall's free posts, which have no status at all. Distinct
     from the slate above so the two are never read as the same thing. */
  --cityhall:     #4FC3F7;
  --cityhall-ink: #9BDBFA;
  --scrim:     rgba(13, 18, 22, 0.7);
  --shadow-sm: 0 6px 20px rgba(0, 0, 0, 0.3);
  --shadow-md: 0 8px 26px rgba(0, 0, 0, 0.4);
  --shadow-lg: 0 12px 34px rgba(0, 0, 0, 0.55);
  --radius:    14px;
  --touch:     48px; /* minimum touch target */
}

/* Daylight. Fills keep the brand green — near-black ink on #2bd594 is readable
   on white too — so only the ink tokens, the surfaces and the shadows move. */
:root[data-theme='light'] {
  color-scheme: light;
  --bg:        #e8edf1;
  --surface:   #ffffff;
  --surface-2: #eef2f5;
  --border:    #d2dbe1;
  --text:      #0f171d;
  --text-dim:  #5a6772;
  --out:       #5a6772;
  --danger:    #c3352c;
  --accent-ink: #067a52;
  --busy-ink:   #96590a;
  --unknown-ink: #3a6d94;
  --cityhall-ink: #0d6c98;
  --scrim:     rgba(20, 32, 41, 0.45);
  --shadow-sm: 0 4px 14px rgba(16, 32, 45, 0.12);
  --shadow-md: 0 8px 22px rgba(16, 32, 45, 0.16);
  --shadow-lg: 0 14px 34px rgba(16, 32, 45, 0.2);
}

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

html, body {
  height: 100%;
  background: var(--bg);
  color: var(--text);
  font-family: 'Poppins', 'Noto Sans Georgian', system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
  overflow: hidden;
}

body { display: flex; flex-direction: column; }

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

button {
  font: inherit;
  color: inherit;
  background: none;
  border: none;
  cursor: pointer;
}

/* ── Top bar ─────────────────────────────────────────────────────── */
.topbar {
  display: flex;
  align-items: center;
  gap: 20px;
  padding: 10px 20px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  min-height: 64px;
  flex-shrink: 0;
}

.topbar__brand {
  display: flex;
  align-items: center;
  gap: 12px;
  /* It is a button now (tap = reload + back to the start view), but it must
     still read as the logo, so it keeps no chrome of its own. */
  min-height: var(--touch);
  padding: 0 6px;
  margin-left: -6px;
  border: 0;
  border-radius: var(--radius);
  background: none;
  color: inherit;
  cursor: pointer;
}
.topbar__brand:active { background: var(--surface-2); }
.topbar__mark  { height: 34px; }
.topbar__title { font-size: 22px; font-weight: 700; white-space: nowrap; }

/* The station counter used to live here and carried `margin-left: auto`. It is
   gone — a number nobody acts on, sitting in the one place where width is
   scarce — so the actions block does the pushing now. */
.topbar__actions { display: flex; align-items: center; gap: 14px; margin-left: auto; }

/* A word plus its icon. The word is what shows; the icon takes over when the
   bar runs out of room (see fitTopbar in ui.js). */
.btn--labelled { display: inline-flex; align-items: center; gap: 10px; }
.btn__ico { display: none; }

.btn {
  min-height: var(--touch);
  padding: 0 22px;
  border-radius: var(--radius);
  background: var(--surface-2);
  border: 1px solid var(--border);
  font-size: 17px;
  font-weight: 500;
}
.btn:active { background: var(--border); }

.btn--toggle.is-active {
  background: var(--accent);
  border-color: var(--accent);
  color: #0d1216;
}

.btn--ghost { background: transparent; color: var(--text-dim); }

/* Icon-only button (the day/night switch). Square, so the topbar row keeps one
   height, and it shows the theme it switches TO. */
.btn--icon {
  width: var(--touch);
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--text);
}
/* Car picker: the button IS the car, drawn in the chosen model and colour, so
   the driver sees what will appear on the map without opening anything. */
.btn--car { padding: 0 4px; }
.car-badge { display: block; width: 38px; height: 38px; }
.car-badge svg { display: block; width: 100%; height: 100%; }
.car-menu { min-width: 260px; padding: 10px; }
.car-menu__label {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  color: var(--text-dim);
  margin: 6px 4px 8px;
}
.car-menu__label + .car-menu__label, h3.car-menu__label ~ h3.car-menu__label { margin-top: 14px; }
.car-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: var(--touch);
  padding: 0 10px;
  border-radius: calc(var(--radius) - 4px);
  text-align: left;
  font-size: 17px;
}
.car-item:active { background: var(--border); }
.car-item.is-on { background: var(--surface); }
.car-item__art { flex: 0 0 auto; width: 34px; height: 34px; }
.car-item__art svg { display: block; width: 100%; height: 100%; }
.car-item__name { flex: 1 1 auto; }
.car-item__tick { flex: 0 0 auto; width: 20px; color: var(--accent-ink); }
.car-colors { display: flex; gap: 10px; padding: 2px 4px 4px; }
.car-swatch {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: 2px solid transparent;
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.25);
}
.car-swatch.is-on { outline: 3px solid var(--accent); outline-offset: 2px; }

.theme-toggle__sun, .theme-toggle__moon { display: none; }
:root:not([data-theme='light']) .theme-toggle__sun { display: block; }
:root[data-theme='light'] .theme-toggle__moon { display: block; }

.lang-switch {
  display: flex;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}
.lang-switch__btn {
  min-height: var(--touch);
  min-width: 56px;
  font-size: 16px;
  font-weight: 600;
  color: var(--text-dim);
}
.lang-switch__btn.is-active { background: var(--accent); color: #0d1216; }

/* Every topbar dropdown anchors to its own wrapper. Without this the menu
   falls back to the initial containing block: `right: 0` still lands under the
   button by luck, but `top: calc(100% + 8px)` becomes eight pixels below the
   whole viewport, so the menu opens correctly and is simply never on screen. */
.country-select,
.fav-select,
.car-select { position: relative; }

/* Country button: flags only. The label used to read "🇬🇪 Countries", which
   spent topbar width on a word the flag already carries. */
.btn--flags { padding: 0 12px; }
.country-flags { display: inline-flex; align-items: center; gap: 7px; }
.flag {
  display: block;
  width: 27px;
  height: 18px;
  border-radius: 3px;
  /* A white flag (Georgia's) needs an edge of its own or it dissolves into the
     light theme's button. */
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.22);
}

/* ── Country picker (topbar) ─────────────────────────────────────── */
/* Anchored dropdown rather than a native <select>: the driver picks several
   countries at once, and Tesla's browser renders native select popups badly. */
.country-menu {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  z-index: 40;
  min-width: 240px;
  padding: 6px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
}
.country-menu.is-hidden { display: none; }
.country-item {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: var(--touch);
  padding: 0 12px;
  font-size: 17px;
  text-align: left;
  border-radius: calc(var(--radius) - 4px);
}
.country-item:active { background: var(--border); }
.country-item__box {
  flex: 0 0 auto;
  width: 22px;
  color: var(--text-dim);
}
.country-item.is-on .country-item__box { color: var(--accent-ink); }
.country-item__flag { flex: 0 0 auto; display: inline-flex; }
.country-item__flag .flag { width: 24px; height: 16px; }
.country-item__name { flex: 1 1 auto; }
.country-item__count { flex: 0 0 auto; color: var(--text-dim); font-size: 14px; }

/* The in-car window is not one width: park the car and Tesla widens its own
   left menu, which narrows the browser under a page that is already open. The
   top row then ran off the right edge and took the language switch with it
   (reported from the car, 2026-09-02). Breakpoints alone cannot catch that, so
   ui.js measures the row and adds these two classes in order until it fits:
   first everything tightens, then the two worded buttons become their icons. */
.topbar.is-tight { gap: 10px; padding: 8px 10px; }
.topbar.is-tight .topbar__actions { gap: 8px; }
.topbar.is-tight .btn { padding: 0 12px; font-size: 16px; }
.topbar.is-tight .badge { padding: 6px 10px; font-size: 13px; }
.topbar.is-tight .lang-switch__btn { min-width: 44px; }
.topbar.is-tight .btn--flags { padding: 0 8px; }
.topbar.is-tight .car-badge { width: 32px; height: 32px; }

.topbar.is-icons .btn--labelled {
  width: var(--touch);
  padding: 0;
  justify-content: center;
}
.topbar.is-icons .btn--labelled .btn__ico { display: block; }
.topbar.is-icons .btn--labelled .btn__txt { display: none; }
.topbar.is-icons .flag { width: 22px; height: 15px; }
.topbar.is-icons .topbar__mark { height: 28px; }

/* Narrow in-car screens (Model 3/Y sit around 1000–1100 CSS px). The row is
   fixed-height and must not wrap or scroll, so it tightens instead: the word
   GeoCharge goes, the mark stays, buttons lose padding. */
@media (max-width: 1250px) {
  .topbar { gap: 12px; padding: 10px 12px; }
  .topbar__actions { gap: 8px; }
  .topbar__title { display: none; }
  .btn { padding: 0 14px; }
  .lang-switch__btn { min-width: 46px; }
  .car-badge { width: 34px; height: 34px; }
}

/* ── Icons ────────────────────────────────────────── */
/* Every symbol the app used to draw with a character is an SVG now; js/icons.js
   says why. These rules are what makes one sit where a character sat. */
.ico { display: block; flex-shrink: 0; }
/* The icon rules below set `display` on elements that are sometimes hidden with
   the `hidden` attribute (the search field's ✕). An author `display` beats the
   browser's own [hidden] rule, so say it here once and loudly. */
[hidden] { display: none !important; }
/* Icons that belong INSIDE a line of prose ride the text instead of blocking it. */
.seg__sub .ico,
.seg__badge .ico,
.opt-divider .ico { display: inline-block; vertical-align: -0.18em; }

.search-bar__clear,
.panel__close,
.search-row__star,
.search-row__ico,
.fav-item__act,
.fav-item__ico,
.fav-chip__ico,
.fav-icon,
.country-item__box,
.car-item__tick,
.trip-stop__ar,
.seg__chev,
.opt-uturn,
.trip-add__ico,
.seg__badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* ── Map stage ───────────────────────────────────────────────────── */
.stage { position: relative; flex: 1; overflow: hidden; }
#map   { position: absolute; inset: 0; }

/* The route line while navigating. Ours rather than the map's, because Google's
   own overlay layer is re-projected on a slower schedule than the ground it
   sits on and the line swam over the road (js/route-canvas.js). It is painted
   from the same camera, in the same frame, and never takes a tap. */
.route-canvas {
  position: absolute;
  inset: 0;
  z-index: 5;
  pointer-events: none;
}

/* Google draws its own furniture inside the map — the logo strip, "Map data
   ©2026", the scale bar, "keyboard shortcuts" — and writes it in Georgian,
   because the API is loaded with language=ka. It also hard-codes
   `font-family: Roboto, Arial` on those elements inline, and the car's browser
   has no Georgian glyph in either face, so on a real Tesla the whole
   bottom-right corner arrived as a row of empty boxes. The family has to beat
   an inline style, hence !important, and the type goes up a size: Google's
   10px is unreadable at arm's length in a moving car. */
.gm-style,
.gm-style * {
  font-family: 'Noto Sans Georgian', 'Poppins', system-ui, sans-serif !important;
}
.gm-style .gm-style-cc span,
.gm-style .gm-style-cc a,
.gm-style a[href*='maps.google.com'] { font-size: 12px !important; }

.map-error {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--danger);
  font-size: 20px;
}

/* ── Search ──────────────────────────────────────────────────────── */
#search-box {
  position: absolute;
  top: 16px;
  left: 50%;
  transform: translateX(-50%);
  width: min(520px, 46vw);
  z-index: 15;
}
.search-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  height: 52px;
  padding: 0 14px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
}
.search-bar__ico { font-size: 17px; opacity: 0.8; }
.search-bar input {
  flex: 1;
  min-width: 0;
  background: none;
  border: none;
  outline: none;
  font: inherit;
  font-size: 17px;
  color: var(--text);
}
.search-bar__clear {
  width: 38px;
  height: 38px;
  border-radius: 50%;
  color: var(--text-dim);
  background: var(--surface-2);
}
#search-results {
  margin-top: 8px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  display: none;
  max-height: 60vh;
  overflow-y: auto;
}
#search-results.is-open { display: block; }
.search-group {
  padding: 10px 16px 6px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.6px;
  color: var(--text-dim);
  text-transform: uppercase;
}
.search-row {
  display: flex;
  align-items: center;
  width: 100%;
  border-top: 1px solid var(--border);
}
.search-row__go {
  display: flex;
  align-items: center;
  gap: 12px;
  flex: 1 1 auto;
  min-width: 0;
  min-height: var(--touch);
  padding: 8px 4px 8px 16px;
  text-align: left;
}
.search-row__go:active { background: var(--surface-2); }
.search-row__ico { color: var(--text-dim); }
.search-row__txt { display: flex; flex-direction: column; min-width: 0; }
/* One line each. The star takes 48px off the row, so a long place name that
   used to just fit now wraps to two or three lines and the list starts jumping
   about as the driver types. */
.search-row__main,
.search-row__sub {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.search-row__main { font-size: 16px; color: var(--text); }
.search-row__sub  { font-size: 13px; color: var(--text-dim); }
/* Saves the result as a favourite instead of going there. Full touch height so
   it can be hit without hitting the row it sits on. */
.search-row__star {
  flex: 0 0 auto;
  width: var(--touch);
  align-self: stretch;
  min-height: var(--touch);
  color: var(--text-dim);
  background: none;
}
.search-row__star:active { background: var(--surface-2); color: var(--accent-ink); }

/* ── Map controls ────────────────────────────────────────────────── */
/* One bottom-LEFT column holds every over-the-map control, so they can never
   sit on top of each other: recenter (drive mode) → traffic → my location →
   zoom. Left, because that is the driver's side of the car and the far edge of
   a 15" screen is a stretch at the wheel. Bottom-anchored, so hiding any of
   them just closes the gap.
   The 44px bottom clears the Google logo, which sits in this same corner and
   must stay visible (Maps terms). */
.map-controls {
  position: absolute;
  bottom: 44px;
  left: 16px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 12px;
  z-index: 15;
}
.map-ctrl {
  width: 52px;
  height: 52px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 14px;
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--text);
  box-shadow: var(--shadow-sm);
}
.map-ctrl.is-active { background: var(--accent); border-color: var(--accent); color: #0d1216; }
.map-ctrl:active { background: var(--border); }

/* Zoom pair, drawn as one block the way a map user expects. Replaces the Maps
   API's own control, which put itself in this same corner underneath these
   buttons — and at half the size of a target you can hit while moving. */
.map-zoom {
  display: flex;
  flex-direction: column;
  border-radius: 14px;
  overflow: hidden;
  box-shadow: var(--shadow-sm);
}
.map-zoom .map-ctrl { border-radius: 0; box-shadow: none; }
.map-zoom .map-ctrl + .map-ctrl { margin-top: -1px; } /* one shared divider, not two */

/* ── History button ──────────────────────────────────────────────── */
/* Glued to the left edge of the search field at any width. The search box is
   centred and `min(520px, 46vw)` wide, so half of it is `min(260px, 23vw)`;
   right-anchoring past that keeps a 12px gap on a 1000px car screen and on a
   1280px one alike. It cannot go on the RIGHT: the saved-places rail is there,
   and at 1000px only 34px separate the two. */
.map-pill {
  position: absolute;
  top: 16px;
  right: calc(50% + min(260px, 23vw) + 12px);
  display: flex;
  align-items: center;
  gap: 8px;
  height: 52px;
  padding: 0 18px;
  border-radius: 14px;
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--text);
  box-shadow: var(--shadow-sm);
  font-size: 16px;
  font-weight: 500;
  white-space: nowrap;
  z-index: 15;
}
.map-pill:active { background: var(--border); }

/* Past trips. Wider than the naming dialog and scrolling, because twenty rows
   will not fit on a car screen. */
.onboard__card.history-card { width: 620px; padding: 22px; gap: 10px; }
.history-list { max-height: 58vh; overflow-y: auto; }
.hist-item .fav-item__go { padding: 6px 12px; }
/* When the trip was, in a column of its own so the dates line up down the list
   rather than trailing behind names of every different length. */
.hist-item__when {
  flex: 0 0 auto;
  padding-left: 10px;
  font-size: 14px;
  color: var(--text-dim);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

/* ── Favourites ──────────────────────────────────────────────────── */
/* Quick navigation, top right of the map. One tap starts driving there, which
   is the whole reason these are on the map rather than only in the menu. The
   column is empty (and so invisible) until the driver stars something. */
.fav-rail {
  position: absolute;
  top: 16px;
  right: 16px;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 10px;
  z-index: 15;
}
.fav-chip {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 52px;
  max-width: 220px;
  padding: 0 16px;
  border-radius: 14px;
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--text);
  box-shadow: var(--shadow-sm);
  font-size: 17px;
  font-weight: 500;
}
.fav-chip:active { background: var(--border); }
.fav-chip__ico { color: var(--accent-ink); }
.fav-chip__name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* The full list: navigate, rename, remove. */
.fav-menu { min-width: 300px; padding: 10px; }
.fav-menu__empty {
  padding: 4px 8px 8px;
  color: var(--text-dim);
  font-size: 15px;
  line-height: 1.5;
  max-width: 280px;
}
.fav-item { display: flex; align-items: center; gap: 4px; }
.fav-item__go {
  display: flex;
  align-items: center;
  gap: 12px;
  flex: 1 1 auto;
  min-width: 0;
  min-height: var(--touch);
  padding: 0 12px;
  font-size: 17px;
  text-align: left;
  border-radius: calc(var(--radius) - 4px);
}
.fav-item__go:active { background: var(--border); }
.fav-item__ico { flex: 0 0 auto; color: var(--text-dim); }
.fav-item__txt { display: flex; flex-direction: column; min-width: 0; }
.fav-item__name,
.fav-item__sub { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Routes carry a second line: how many stops, or how far is left on one the
   driver is halfway through. */
.fav-item__sub { font-size: 13px; color: var(--text-dim); }
.fav-item__sub.is-accent { color: var(--accent-ink); font-weight: 600; }
.fav-item__act {
  flex: 0 0 auto;
  width: 44px;
  height: var(--touch);
  border-radius: calc(var(--radius) - 4px);
  color: var(--text-dim);
  background: none;
}
.fav-item__act:active { background: var(--border); }

/* Naming a favourite. Narrower than the onboarding card it borrows its look
   from: it is one field and four icons, not a page of text. */
/* Qualified with .onboard__card on purpose: that rule sets width: 520px and
   sits further down the file, so an unqualified .fav-dialog width loses. */
.onboard__card.fav-dialog { width: 460px; gap: 14px; }
.fav-dialog__place { color: var(--text-dim); font-size: 15px; margin: -6px 0 0; }
.fav-icons { display: flex; gap: 10px; }
.fav-icon {
  width: 56px;
  height: 56px;
  border-radius: 14px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  color: var(--text);
}
.fav-icon.is-on { background: var(--accent); border-color: var(--accent); color: #0d1216; }
.fav-dialog__actions { display: flex; justify-content: flex-end; gap: 12px; }

/* An unfinished trip, offered once when the app opens. It borrows the
   destination card's position and chrome — same slot, same shape, so the
   driver reads it the same way — and adds the two lines that say which trip
   this is and how far is left. */
.resume-card { gap: 4px; }
.resume-card__label {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  color: var(--text-dim);
}
.resume-card__name {
  font-size: 20px;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.resume-card__sub { font-size: 15px; color: var(--accent-ink); }
.resume-card .dest-card__actions { margin-top: 8px; }
/* The from-phone card carries three actions rather than two, so its buttons
   lose the wide padding they do not need. A single PLACE from the phone has a
   fourth (plan the route there), which is one too many for a row a driver can
   still hit — those wrap into a 2x2 grid instead of four slivers. */
#inbox-card .dest-card__actions .btn { padding: 0 12px; }
#inbox-card.is-place .dest-card__actions { flex-wrap: wrap; }
#inbox-card.is-place .dest-card__actions .btn { flex: 1 1 44%; }

/* ── Destination card ────────────────────────────────────────────── */
.dest-card {
  position: absolute;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%);
  width: min(460px, 50vw);
  padding: 18px 20px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-md);
  z-index: 16;
}
.dest-card__name { font-size: 18px; font-weight: 600; padding-right: 40px; margin-bottom: 14px; }
.dest-card__actions { display: flex; gap: 10px; }
.dest-card__actions .btn { flex: 1; }

.loading {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg);
  font-size: 20px;
  color: var(--text-dim);
  z-index: 30;
  transition: opacity 0.3s;
}
.loading.is-hidden { opacity: 0; pointer-events: none; }

/* ── Station panel ───────────────────────────────────────────────── */
.panel {
  position: absolute;
  top: 16px;
  right: 16px;
  bottom: 16px;
  width: 380px;
  max-width: 40vw;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 24px;
  overflow-y: auto;
  z-index: 20;
  transform: translateX(calc(100% + 24px));
  transition: transform 0.25s ease;
}
.panel.is-open { transform: translateX(0); }

.panel__close {
  position: absolute;
  top: 12px;
  right: 12px;
  width: var(--touch);
  height: var(--touch);
  border-radius: 50%;
  font-size: 20px;
  color: var(--text-dim);
  background: var(--surface-2);
}

.panel__head     { display: flex; align-items: center; gap: 14px; padding-right: 52px; }
.panel__logo     { width: 46px; height: 46px; object-fit: contain; border-radius: 10px;
                   background: #fff; padding: 5px; flex-shrink: 0; }
.panel__name     { font-size: 22px; font-weight: 600; }
.panel__provider { color: var(--text-dim); margin: 4px 0 14px; font-size: 16px; }
.panel__nav      { margin-top: 18px; }

.panel__status {
  display: inline-block;
  padding: 8px 18px;
  border-radius: 999px;
  font-size: 15px;
  font-weight: 600;
}
.status--free { background: rgba(43, 213, 148, 0.15); color: var(--accent-ink); }
.status--busy { background: rgba(245, 166, 35, 0.15); color: var(--busy-ink); }
.status--out  { background: rgba(107, 122, 133, 0.2);  color: var(--out); }
/* Registry data (Turkey): no live availability, so neither green nor orange. */
.status--unknown { background: rgba(79, 124, 158, 0.18); color: var(--unknown-ink); }
/* City Hall's free posts: no status of any kind, and a colour of their own. */
.status--cityhall { background: rgba(79, 195, 247, 0.18); color: var(--cityhall-ink); }

.panel__meta {
  display: flex;
  gap: 28px;
  margin: 18px 0;
  padding: 14px 16px;
  background: var(--surface-2);
  border-radius: var(--radius);
}
.panel__meta > div { display: flex; flex-direction: column; gap: 4px; }
.label { color: var(--text-dim); font-size: 13px; }
.panel__power, .panel__price { font-size: 18px; font-weight: 600; }

.panel__ports-title { font-size: 15px; color: var(--text-dim); margin-bottom: 10px; }

.port {
  display: flex;
  justify-content: space-between;
  align-items: center;
  min-height: var(--touch);
  padding: 0 16px;
  margin-bottom: 8px;
  background: var(--surface-2);
  border-radius: var(--radius);
  border-left: 4px solid var(--out);
  font-size: 16px;
}
.port--free { border-left-color: var(--accent); }
.port--busy { border-left-color: var(--busy); }
/* A plug the operator publishes no live state for (Tegeta's Porsche
   destination chargers). Same slate as the station badge: not free, not broken,
   simply not reported. */
.port--unknown { border-left-color: var(--unknown); }
/* The "i" on an unknown plug, sitting where a price would be. Full touch height
   so it is hittable on a moving car's screen. */
.port__info {
  width: var(--touch);
  height: var(--touch);
  margin-left: 12px;
  flex: 0 0 auto;
  border-radius: 50%;
  border: 1px solid rgba(79, 124, 158, 0.55);
  background: rgba(79, 124, 158, 0.18);
  color: var(--unknown-ink);
  font-size: 19px;
  font-weight: 700;
  font-style: italic;
  font-family: Georgia, 'Times New Roman', serif;
  cursor: pointer;
}
.port__info:hover { background: rgba(79, 124, 158, 0.3); }
.port__type   { font-weight: 600; }
.port__right  { display: flex; flex-direction: column; align-items: flex-end; gap: 2px; }
.port__status { color: var(--text-dim); }
.port__sub    { font-size: 12px; color: var(--busy-ink); opacity: 0.85; }
.port--free .port__status { color: var(--accent-ink); }
.port--busy .port__status { color: var(--busy-ink); }
.port--unknown .port__status { color: var(--unknown-ink); }
/* The line under a City Hall socket saying why there is no status. It wraps, so
   it drops the row's fixed height and reads as prose rather than a value. */
.port--note {
  display: block;
  min-height: 0;
  padding: 12px 16px;
  border-left-color: var(--cityhall);
  color: var(--text-dim);
  font-size: 13px;
  line-height: 1.45;
}

/* Freshness line + refresh button. The button is a full touch target rather
   than a small icon: this is read and pressed in a car, often while parked
   badly, so it has to be hittable without aiming. */
.panel__freshness {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-top: 14px;
}
.panel__freshness-text { flex: 1; min-width: 0; }
.panel__updated { color: var(--text-dim); font-size: 13px; }
.panel__source  { color: var(--text-dim); font-size: 12px; opacity: 0.8; margin-top: 2px; }
.panel__source.is-live { color: var(--accent-ink); opacity: 1; }

.panel__refresh {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
  min-height: var(--touch);
  padding: 0 18px;
  border-radius: var(--radius);
  background: var(--surface-2);
  border: 1px solid var(--border);
  color: var(--text);
  font-size: 15px;
  font-weight: 500;
}
.panel__refresh:active { background: var(--border); }
.panel__refresh[disabled] { opacity: 0.55; }
.panel__refresh.is-busy .panel__refresh-icon {
  animation: gc-spin 0.8s linear infinite;
}
@keyframes gc-spin { to { transform: rotate(360deg); } }
/* Drivers who prefer no motion still get the disabled state as feedback. */
@media (prefers-reduced-motion: reduce) {
  .panel__refresh.is-busy .panel__refresh-icon { animation: none; }
}

/* What the refresh actually achieved. Green only when something really moved;
   anything else stays quiet, so the button can never imply it found news it
   did not. */
.panel__refresh-note { margin-top: 8px; font-size: 13px; color: var(--text-dim); min-height: 18px; }
.panel__refresh-note.is-changed { color: var(--accent-ink); }
.panel__refresh-note.is-failed  { color: var(--busy-ink); }

/* ── Filter drawer ───────────────────────────────────────────────── */
.drawer {
  position: absolute;
  top: 16px;
  left: 16px;
  bottom: 16px;
  width: 420px;
  max-width: 44vw;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 24px;
  overflow-y: auto;
  z-index: 20;
  transform: translateX(calc(-100% - 24px));
  transition: transform 0.25s ease;
}
.drawer.is-open { transform: translateX(0); }

.drawer__head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
}
.drawer__head h2 { font-size: 22px; }
.drawer__head .panel__close { position: static; }

.drawer__label {
  font-size: 15px;
  color: var(--text-dim);
  margin: 18px 0 10px;
}

.chip-row { display: flex; flex-wrap: wrap; gap: 10px; }

.chip {
  min-height: var(--touch);
  padding: 0 18px;
  border-radius: 999px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  font-size: 16px;
}
.chip.is-active {
  background: var(--accent);
  border-color: var(--accent);
  color: #0d1216;
  font-weight: 600;
}

.drawer__foot {
  display: flex;
  gap: 12px;
  margin-top: 26px;
}

/* ── Trip planner ────────────────────────────────────────────────── */
/* Stop rows */
.trip-stop {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 10px;
}
.trip-stop__dot {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.trip-stop__input { flex: 1; min-width: 0; min-height: 46px; }
.trip-stop__actions { display: flex; gap: 6px; }
.trip-stop__btn {
  width: 38px;
  height: 38px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 10px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  color: var(--accent-ink);
}
.trip-stop__btn:active { background: var(--border); }
.trip-stop__ar { color: var(--text-dim); }

.trip-add {
  margin: 4px 0 18px;
  display: inline-flex;
  gap: 6px;
  align-items: center;
}

.trip-params {
  display: flex;
  gap: 20px;
  align-items: flex-end;
  margin: 16px 0 6px;
}
.trip-param { display: flex; flex-direction: column; gap: 8px; flex: 1; }
.trip-param b { color: var(--accent-ink); }
.input--small { min-height: 46px; width: 110px; }

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

.trip-summary {
  display: flex;
  gap: 18px;
  font-size: 17px;
  font-weight: 600;
  margin: 14px 0 8px;
  flex-wrap: wrap;
}
.txt-accent { color: var(--accent-ink); }
.txt-danger { color: var(--danger); }
.txt-dim { color: var(--text-dim); font-weight: 400; font-size: 15px; }

/* Charging option blocks */
.opt-divider {
  display: flex;
  align-items: center;
  padding: 4px 0 4px 10px;
  color: var(--text-dim);
  font-size: 12px;
}
.opt-block {
  display: flex;
  gap: 12px;
  padding: 12px;
  margin-bottom: 6px;
  background: var(--surface-2);
  border: 1px solid transparent;
  border-radius: 12px;
}
.opt-block.is-selected {
  background: rgba(43, 213, 148, 0.08);
  border-color: rgba(43, 213, 148, 0.5);
}
.opt-tick {
  width: 24px;
  height: 24px;
  flex-shrink: 0;
  border-radius: 7px;
  border: 1.5px solid var(--text-dim);
  display: flex;
  align-items: center;
  justify-content: center;
  color: #0d1216;
  font-weight: 700;
}
.opt-block.is-selected .opt-tick { background: var(--accent); border-color: var(--accent); }
.opt-body { flex: 1; min-width: 0; }
.opt-title { font-size: 15px; font-weight: 600; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.opt-badge {
  font-size: 10px;
  font-weight: 700;
  color: var(--accent-ink);
  background: rgba(43, 213, 148, 0.18);
  padding: 2px 6px;
  border-radius: 6px;
}
.opt-uturn { color: var(--busy-ink); }
.opt-prov { display: flex; gap: 8px; font-size: 13px; margin-top: 3px; }
.opt-prov b { color: var(--accent-ink); }
.opt-meta { color: var(--text-dim); font-size: 12px; margin-top: 5px; }
/* Provider logo chip on the right of an option block. Logos are drawn for
   light backgrounds, so each sits on a white tile to stay legible. */
.opt-logo { flex-shrink: 0; display: flex; flex-direction: column; gap: 4px; justify-content: center; }
.opt-logo__img {
  height: 26px;
  max-width: 68px;
  object-fit: contain;
  background: #fff;
  border-radius: 6px;
  padding: 3px 6px;
}
.trip-none { padding: 8px 2px; }
.trip-nav { margin-top: 18px; }
.trip-nav:disabled { opacity: 0.4; }
.trip-clear { margin-top: 10px; }
.txt-busy { color: var(--busy-ink); }

/* ── 50 km collapsible charger segments ─────────────────────────────────── */
.trip-seg-hint { margin: 0 2px 12px; font-size: 12px; line-height: 1.35; }
.seg {
  background: var(--surface-2);
  border: 1px solid transparent;
  border-radius: 12px;
  margin-bottom: 8px;
  overflow: hidden;
}
.seg.has-selected { border-color: rgba(43, 213, 148, 0.5); }
.seg__head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px;
  cursor: pointer;
}
.seg__chev {
  flex-shrink: 0;
  color: var(--text-dim);
  transition: transform 0.18s ease;
}
.seg.is-open .seg__chev { transform: rotate(90deg); }
.seg__title { flex: 1; min-width: 0; }
.seg__range { font-size: 15px; font-weight: 600; }
.seg__sub {
  font-size: 12px;
  margin-top: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.seg.has-selected .seg__sub { color: var(--accent-ink); font-weight: 600; }
.seg__badge {
  flex-shrink: 0;
  gap: 4px;
  background: var(--accent);
  color: #0d1216;
  font-size: 12px;
  font-weight: 700;
  padding: 3px 10px;
  border-radius: 20px;
}
.seg__count { flex-shrink: 0; font-size: 13px; }
.seg__body { padding: 0 12px 12px; }
/* Darken blocks inside a segment so they stay distinct from the tile. */
.seg__body .opt-block:not(.is-selected) { background: var(--surface); }

body.is-picking #map { cursor: crosshair; }

/* Places Autocomplete dropdown, restyled for the dark theme. */
.pac-container {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 10px;
  font-family: inherit;
}
.pac-item {
  min-height: var(--touch);
  display: flex;
  align-items: center;
  padding: 0 14px;
  color: var(--text-dim);
  border-top: 1px solid var(--border);
  font-size: 15px;
  cursor: pointer;
}
.pac-item:hover, .pac-item-selected { background: var(--border); }
.pac-item-query { color: var(--text); font-size: 16px; }
.pac-icon { display: none; }

/* ── Gate screens (login / paywall) ──────────────────────────────── */
.gate {
  position: absolute;
  inset: 0;
  display: none;
  /* A card taller than the screen has to stay reachable. `align-items: center`
     would push its top to a negative offset that no scrollbar can reach, so the
     centring is done by the card's own auto margins instead. */
  overflow-y: auto;
  background: var(--bg);
  z-index: 50;
}
.gate.is-open { display: flex; }

.gate__card {
  margin: auto;
  width: 460px;
  max-width: 92vw;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 36px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  text-align: center;
}
.gate__card--wide { width: 640px; }

.gate__logo { height: 40px; margin-bottom: 6px; }
.gate__card h2 { font-size: 26px; }
.gate__subtitle { color: var(--text-dim); font-size: 16px; line-height: 1.5; }

#login-form {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: 8px;
}

.input {
  min-height: 52px;
  padding: 0 18px;
  font: inherit;
  font-size: 17px;
  color: var(--text);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  outline: none;
}
.input:focus { border-color: var(--accent); }

.btn--primary {
  background: var(--accent);
  border-color: var(--accent);
  color: #0d1216;
  font-weight: 600;
}
.btn--primary:active { background: var(--accent-dk); }

.btn--wide {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
}

.gate__divider {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 14px;
  color: var(--text-dim);
  font-size: 14px;
}
.gate__divider::before,
.gate__divider::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--border);
}

/* ── Pairing panel (sign in from the phone) ──────────────────────── */
/* The code is the biggest thing on the screen: it is read from the driver's
   seat and typed into a phone held somewhere else. */
.pair { width: 100%; display: flex; flex-direction: column; align-items: center; gap: 10px; }
.pair__code {
  font-size: 52px;
  font-weight: 700;
  letter-spacing: 6px;
  line-height: 1.1;
  padding: 14px 24px;
  border-radius: var(--radius);
  background: var(--surface-2);
  border: 1px solid var(--accent);
  color: var(--accent-ink);
  font-variant-numeric: tabular-nums;
}
.pair__timer { font-size: 14px; color: var(--text-dim); min-height: 20px; }
.pair__steps {
  text-align: left;
  padding-left: 22px;
  margin-top: 4px;
  color: var(--text-dim);
  font-size: 15px;
  line-height: 1.85;
}

/* A car screen is wide and short. Stacked, this panel is 781px tall and the
   price note falls off the bottom of a 590px stage with no way to scroll to it.
   Side by side it is 527px and fits whole, which is the point: the driver reads
   the code and the three steps in one look, without touching anything. */
@media (min-width: 900px) {
  #login-screen .gate__card { width: 900px; }
  .pair {
    display: grid;
    grid-template-columns: auto minmax(320px, 1fr);
    column-gap: 34px;
    row-gap: 8px;
    align-items: center;
    justify-items: center;
  }
  .pair__code  { grid-column: 1; grid-row: 1; }
  .pair__timer { grid-column: 1; grid-row: 2; }
  .pair__steps {
    grid-column: 2;
    grid-row: 1 / span 2;
    justify-self: start;
    margin-top: 0;
    line-height: 1.7;
  }
  /* Both only appear when a code could not be issued, and then they belong
     under the whole panel rather than in either column. */
  #pair-error   { grid-column: 1 / -1; }
  #pair-refresh { grid-column: 1 / -1; width: auto; padding: 0 28px; }
}
/* "Other ways to sign in" — deliberately quiet: it is the exception now. */
.gate__link {
  background: none;
  border: 0;
  color: var(--text-dim);
  font-size: 14px;
  text-decoration: underline;
  min-height: var(--touch);
}

.gate__error { color: var(--danger); font-size: 15px; }
.gate__note  { color: var(--text-dim); font-size: 14px; line-height: 1.5; }
.gate__note--price {
  /* three deliberate lines (paid service / free 24h / how to start it) — HTML
     would otherwise run them together */
  white-space: pre-line;
  margin-top: 4px;
  padding: 10px 14px;
  background: rgba(43, 213, 148, 0.1);
  border: 1px solid rgba(43, 213, 148, 0.3);
  border-radius: 12px;
  color: var(--text);
}

.paywall__row {
  display: flex;
  align-items: center;
  gap: 32px;
  margin: 10px 0;
}

.paywall__steps {
  text-align: left;
  font-size: 17px;
  line-height: 2.1;
  padding-left: 22px;
}

.paywall__qr {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
}
.paywall__qr #qr {
  background: #fff;
  padding: 10px;
  border-radius: 10px;
}

.badge {
  padding: 8px 16px;
  border-radius: 999px;
  font-size: 14px;
  font-weight: 600;
  background: rgba(43, 213, 148, 0.15);
  color: var(--accent-ink);
  white-space: nowrap;
}
.badge--trial { background: rgba(245, 166, 35, 0.15); color: var(--busy-ink); }

.is-hidden { display: none !important; }

/* ── Onboarding hint ─────────────────────────────────────────────── */
.onboard {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--scrim);
  z-index: 45;
}
.onboard__card {
  width: 520px;
  max-width: 90vw;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 30px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.onboard__card h3 { font-size: 22px; }
.onboard__card ul { padding-left: 22px; color: var(--text-dim); line-height: 1.9; font-size: 17px; }
/* Prose body (the "why is there no status" explainer). The cap and the scroll
   are a safety net for a screen too small to hold the text, not the normal
   case: at the card width below it reads in full without scrolling on any
   in-car screen. */
.onboard__body {
  color: var(--text-dim);
  font-size: 17px;
  line-height: 1.6;
  max-height: 60vh;
  overflow-y: auto;
}
/* Wider than the onboarding tip card, because this one carries three
   paragraphs: at 520px they needed 490px of height and scrolled, at 860px they
   need 273px and fit whole. Fixed rather than absolute so it centres on the
   VIEWPORT — the overlay's parent is <main>, which starts below the header, and
   on a short screen that pushed the bottom of the card off the display. */
#port-info { position: fixed; }
#port-info .onboard__card { width: 860px; max-width: 92vw; }
/* pre-line so single newlines inside a paragraph survive: the copy breaks some
   lines deliberately, and HTML would otherwise collapse them into one. */
.onboard__body p { margin: 0 0 14px; white-space: pre-line; }
.onboard__body p:last-child { margin-bottom: 0; }

/* ── Drive mode (turn-by-turn) ───────────────────────────────────── */
/* Overlays float over the map; only the cards themselves catch touches. */
.drive { position: absolute; inset: 0; z-index: 25; pointer-events: none; }

/* Hide the normal chrome while driving so the map fills the screen. */
body.is-driving .topbar,
body.is-driving #search-box,
body.is-driving .map-pill,
body.is-driving .fav-rail,
body.is-driving #btn-locate,
body.is-driving #dest-card,
body.is-driving #resume-card,
body.is-driving #inbox-card,
body.is-driving #station-panel,
body.is-driving .drawer { display: none !important; }
/* Traffic is NOT in that list. Jams are the one thing a driver wants to see
   most while actually driving, and it used to disappear the moment navigation
   started — there was no way to switch it on or off for the rest of the trip.
   Zoom stays too, lifted clear of the drive footer (which spans the full width
   on a narrow in-car screen). */
body.is-driving .map-controls { bottom: 112px; }

.drive-banner {
  position: absolute;
  top: 16px;
  left: 16px;
  right: 16px;
  margin: 0 auto;
  max-width: 760px;
  display: flex;
  align-items: center;
  gap: 22px;
  padding: 18px 26px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  pointer-events: auto;
}
.drive-banner__icon { flex-shrink: 0; color: var(--accent-ink); }
.drive-banner__icon svg { width: 60px; height: 60px; display: block; }
.drive-banner__txt { min-width: 0; }
.drive-banner__dist { font-size: 42px; font-weight: 700; line-height: 1; }
.drive-banner__road {
  font-size: 20px;
  color: var(--text-dim);
  margin-top: 8px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.drive-banner.is-arrived .drive-banner__dist { display: none; }
.drive-banner.is-arrived .drive-banner__road { color: var(--accent-ink); font-size: 26px; font-weight: 600; }

.drive-reroute {
  position: absolute;
  top: 130px;
  left: 50%;
  transform: translateX(-50%);
  padding: 10px 22px;
  background: var(--busy);
  color: #0d1216;
  border-radius: 999px;
  font-size: 16px;
  font-weight: 600;
  pointer-events: auto;
}

/* Recenter. The camera follows the car, but the moment the driver drags the map
   that follow stops — otherwise the next GPS fix would yank the map back out
   from under their finger. This button is how they get the follow back, and it
   only appears while the map is off the car. */
.drive-recenter {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 56px;
  padding: 0 24px 0 18px;
  border-radius: 999px;
  background: var(--surface);
  border: 1px solid var(--accent);
  color: var(--accent-ink);
  font-size: 17px;
  font-weight: 600;
  box-shadow: var(--shadow-md);
}
.drive-recenter svg { width: 26px; height: 26px; flex-shrink: 0; }
.drive-recenter:active { background: var(--surface-2); }

.drive-foot {
  position: absolute;
  bottom: 16px;
  left: 16px;
  right: 16px;
  margin: 0 auto;
  max-width: 760px;
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 14px 20px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  pointer-events: auto;
}
/* Distance on the left, then the two time lines. Everything here is nowrap:
   on the car's screen "6.8 კმ" broke after the number and left the unit on a
   line of its own, and the arrival clock did the same under its label. */
.drive-foot__stats {
  display: flex;
  gap: 18px;
  flex: 1;
  min-width: 0;
  align-items: center;
}
#drive-remain { font-size: 24px; font-weight: 700; white-space: nowrap; }
.drive-foot__eta { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
#drive-duration { font-size: 17px; font-weight: 600; white-space: nowrap; }
#drive-eta { font-size: 15px; color: var(--text-dim); white-space: nowrap; }
.drive-foot__btn {
  position: relative;
  width: 52px;
  height: 52px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 12px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  color: var(--text);
}
/* Which recorded voice is speaking, as one letter in the corner of the speaker
   button: ქ / კ, F / M. A letter rather than a symbol, because the car's fonts
   drop symbols (see js/icons.js) but never letters. */
.drive-foot__tag {
  position: absolute;
  right: 5px;
  bottom: 3px;
  font-size: 12px;
  font-weight: 700;
  line-height: 1;
  color: var(--accent-ink);
}
.drive-foot__btn.is-off { color: var(--out); }
.drive-foot__btn:active { background: var(--border); }
.drive-foot__exit { min-height: 52px; padding: 0 28px; }

/* ── Toast ───────────────────────────────────────────────────────── */
.toast {
  position: absolute;
  bottom: 24px;
  left: 50%;
  transform: translate(-50%, 200%);
  padding: 14px 26px;
  background: var(--surface-2);
  border: 1px solid var(--busy);
  border-radius: var(--radius);
  font-size: 16px;
  z-index: 40;
  transition: transform 0.3s ease;
  white-space: nowrap;
}
.toast.is-visible { transform: translate(-50%, 0); }

/* ── Landing (phase 0 fallback, kept for reuse) ──────────────────── */
.landing {
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 20px;
  text-align: center;
  padding: 32px;
}
.landing__logo { height: 56px; }
.landing__title { font-size: 44px; font-weight: 700; }
.landing__subtitle { font-size: 20px; color: var(--text-dim); max-width: 640px; line-height: 1.5; }

/* VL PERFORMANCE BRAND ONLY — no map, charger, routing or auth changes */
.topbar__mark {height: 38px; max-width: 88px; width: auto; object-fit: contain;}
.gate__logo {height: 72px; max-width: min(92%, 260px); width:auto; object-fit: contain;}
@media(max-width:1250px){.topbar__mark {height:34px;max-width:80px;}}
