/* Charge point map. Design tokens first; components only use these variables.
   The stylesheet is split in cascade order: style.css, style-sheets.css, style-details.css, style-extras.css (see index.html). */
@font-face { font-family:Inter; src:url('/web/vendor/inter/InterVariable.woff2') format('woff2'); font-weight:100 900; font-display:swap; }
/* Sizes (v12: about 13 % smaller than before). Type in rem so the browser/system font size applies; CSS px already
   follow device pixel density and zoom, so there is no own DPI scaling. Floors: touch targets 44 px, running text 14 px. */
:root {
  --font: Inter, system-ui, sans-serif;
  --fs-xs: .6875rem; --fs-sm: .75rem; --fs-md: .875rem; --fs-lg: .9375rem; --fs-xl: 1.0625rem; --fs-2xl: 1.5rem;
  --fs-body: max(14px, var(--fs-md));
  --fw-medium: 500; --fw-semibold: 600; --fw-bold: 700;
  --space-1: 4px; --space-2: 7px; --space-3: 10px; --space-4: 14px; --space-5: 18px; --space-6: 21px;
  --radius-sm: 7px; --radius-md: 11px; --radius-lg: 14px; --radius-sheet: 21px; --radius-pill: 999px;
  --touch: 44px; --control: 44px; --control-sm: 32px;
  --icon: 21px; --icon-sm: 18px; --switch-w: 38px; --switch-h: 22px; --chip-h: 34px; --glyph: 36px;
  --button: 46px; --button-gap: 12px; --edge: calc(14px + env(safe-area-inset-right));
  /* Right column: ? | gap | +/- group | gap | position. */
  --top: calc(14px + env(safe-area-inset-top)); --group-gap: 16px; --zoom-button: 44px; --bottom: max(var(--edge), env(safe-area-inset-bottom));
  /* Shared sheet width and mobile top clearance. */
  --sheet-top: calc(22px + env(safe-area-inset-top)); --sheet-max: 480px;
  --dur-sheet: 340ms; --dur-fast: 150ms; --ease-out: cubic-bezier(.22,.9,.24,1);
  --shadow-fab: 0 3px 16px #0005; --shadow-sheet: 0 -6px 32px #0004; --shadow-card: 0 24px 64px #0005, 0 2px 8px #0003;
  --search-blue: #2563eb; --search-blue-core: #153784; /* core = dimColor(--search-blue, 44), as station pins */
  --follow: #1f83ff; --on-follow: #fff;
  /* Controls: every map button shares one opaque surface; floating bars (search, live, toast) share one translucent surface. */
  --ctl-bg: var(--bg); --ctl-bg-hover: var(--surface); --ctl-bg-active: var(--surface-2); --ctl-border: var(--border); --ctl-fg: var(--text);
  --ctl-shadow: var(--shadow-fab); --ctl-ring: var(--accent); --float-bg: var(--button-bg); --float-border: var(--border); --float-blur: 8px;
}
:root, :root[data-theme="light"] {
  color-scheme: light;
  --bg: #fff; --surface: #f2f4f7; --surface-2: #e6eaef; --text: #17212f; --muted: #4f5c6e;
  --border: #d5dbe2; --border-strong: #9aa5b3; --accent: #0756b4; --on-accent: #fff; --accent-soft: #0756b41a;
  --button-bg: #ffffffe6; --scrim: #0f172a66;
  --pin-badge-bg: #ffffff; --pin-badge-border: #8794a3; --pin-badge-text: #17212f; /* = BADGE_TONES.light (pins.mjs) */
  --free: #16a660; --free-text: #0b7a45; --busy: #e0474c; --busy-text: #b42328; --out: #5b6470; --unknown: #b8c0ca;
  --warn-bg: #fff4d6; --warn-text: #7a4a00; --warn-border: #f0c96a; --error-bg: #fde8e8; --error-text: #9b1c20; --error-border: #f2a9ab;
}
:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: #171e28; --surface: #212a36; --surface-2: #2c3644; --text: #f0f4f9; --muted: #b3bfcd;
  --border: #354253; --border-strong: #64748b; --accent: #5ea2ff; --on-accent: #0a1422; --accent-soft: #5ea2ff24;
  --button-bg: #171e28e6; --scrim: #00000080;
  --pin-badge-bg: #151c26; --pin-badge-border: #4a5568; --pin-badge-text: #e6ebf2; /* = BADGE_TONES.dark (pins.mjs) */
  --free: #2fc77d; --free-text: #4fdb94; --busy: #f0646a; --busy-text: #ff8a8f; --out: #7a8492; --unknown: #4c5869;
  --warn-bg: #3a2c0c; --warn-text: #ffd47a; --warn-border: #6b5418; --error-bg: #401a1d; --error-text: #ffb3b6; --error-border: #7a2e33;
}

/* Base */
* { box-sizing: border-box; }
body { margin: 0; font: var(--fs-body)/1.45 var(--font); font-variant-numeric: tabular-nums; color: var(--text); background: var(--bg); -webkit-tap-highlight-color: transparent; }
/* App feel: UI chrome is neither selectable nor shows a text cursor. Only real content opts in with .u-text
   (help text, sources, address, EVSE ids, prices); everything interactive shows a pointer. */
body { -webkit-user-select: none; user-select: none; cursor: default; }
.u-text { -webkit-user-select: text; user-select: text; cursor: text; }
a, button, summary, label.chip, label.choice, [role="option"], input[type="range"], input[type="checkbox"] { cursor: pointer; }
#map { position: fixed; inset: 0; }
a { color: var(--accent); }
[hidden] { display: none !important; }
:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
h2, h3 { margin: 0; letter-spacing: -.01em; }
button { font: inherit; color: inherit; cursor: pointer; }
svg { width: var(--icon); height: var(--icon); fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; flex-shrink: 0; }

/* Buttons */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2); min-height: var(--control); padding: 0 var(--space-5);
  border: 0; border-radius: var(--radius-md); font-size: var(--fs-md); font-weight: var(--fw-semibold); text-decoration: none; transition: filter var(--dur-fast), background var(--dur-fast); }
.btn svg { width: var(--icon-sm); height: var(--icon-sm); }
.btn-primary { background: var(--accent); color: var(--on-accent); }
.btn-primary svg { fill: currentColor; stroke: none; }
.btn-primary:hover { filter: brightness(1.08); } .btn-primary:active { filter: brightness(.94); }
.btn-secondary { background: var(--surface); color: var(--text); }
.btn-secondary:hover { background: var(--surface-2); }

.btn-icon { display: inline-grid; place-items: center; flex-shrink: 0; padding: 0; }

/* Map buttons: one shape for FABs and MapLibre zoom; surface, hover and focus live in style-controls.css (tokens --ctl-*). */
.fab, .maplibregl-ctrl-group button { position: relative; display: grid; place-items: center; width: var(--button); height: var(--button); padding: 0; }
.position-fab { position: fixed; z-index: 2; right: var(--edge); bottom: calc(var(--bottom) + var(--button) + var(--button-gap)); }
.map-fabs { position: fixed; z-index: 2; right: var(--edge); bottom: var(--bottom); display: flex; flex-direction: column; gap: var(--button-gap); }
.badge { position: absolute; top: -3px; right: -3px; min-width: 18px; height: 18px; padding: 0 5px; border-radius: var(--radius-pill); font-size: var(--fs-xs); line-height: 18px; font-weight: var(--fw-bold); background: var(--accent); color: var(--on-accent); }
/* Right column, bottom up: filter, position, zoom (above 1024 px the column hangs from the top, see style-sheets.css). */
.maplibregl-ctrl-top-right { right: var(--edge); top: auto; bottom: calc(var(--bottom) + 2 * var(--button) + var(--button-gap) + var(--group-gap)); }
.maplibregl-ctrl-top-right .maplibregl-ctrl { margin: 0; }
/* Short screens (phone landscape, 360x640 with browser bars): smaller buttons so the top column and
   the bottom pair never meet. */
@media (max-height: 500px) {
  :root { --button: 44px; --zoom-button: 44px; --group-gap: 10px; --button-gap: 10px; --top: calc(10px + env(safe-area-inset-top)); --bottom: max(var(--edge), env(safe-area-inset-bottom)); }
  .fab svg, .maplibregl-ctrl-group svg { width: var(--icon-sm); height: var(--icon-sm); }
}

/* Position button: outline when off, filled blue while following. */
.position-fab svg .core { transition: fill var(--dur-fast); }
.fab[aria-pressed="true"], .fab[aria-pressed="true"]:is(:hover, :focus, :active) { background: var(--follow) !important; color: var(--on-follow); border-color: var(--follow) !important; }
.position-fab[data-follow="on"] svg .core, .position-fab[data-follow="locating"] svg .core { fill: currentColor; }
.position-fab[data-follow="locating"] { color: var(--follow); }
.locating::after { content: ''; position: absolute; inset: -4px; border-radius: 50%; border: 3px solid transparent; border-top-color: var(--follow); animation: spin .9s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

/* Map overlays */
/* Width: always at least 16 px clear of the right button column (edge + button), at any width; text wraps. */
/* Live info bubble: hangs from the status dot at the left of the search bar. */
.popover { position: fixed; z-index: 5; top: calc(var(--top) + var(--search-h) + 8px); left: calc(14px + env(safe-area-inset-left));
  width: min(280px, calc(100vw - 28px - env(safe-area-inset-left) - env(safe-area-inset-right))); overflow-wrap: anywhere;
  padding: var(--space-3) var(--space-4); border-radius: var(--radius-md); background: var(--bg); color: var(--text); border: 1px solid var(--border); filter: drop-shadow(0 3px 8px #0000004d) drop-shadow(0 0 1px #00000040); font-size: var(--fs-sm); line-height: 1.45; }
/* Arrow under the badge centre (--arrow-x is set from the badge position on open). Two triangles: the outer
   one in the border colour, the inner one in the bubble colour; drop-shadow (not box-shadow) so the
   arrow carries the same shadow as the bubble. */
.popover::before, .popover::after { content: ''; position: absolute; width: 0; height: 0; border-style: solid; border-color: transparent; border-top-width: 0; }
.popover::before { top: -11px; left: calc(var(--arrow-x, 32px) - 11px); border-width: 0 11px 11px; border-bottom-color: var(--border); }
.popover::after { top: -10px; left: calc(var(--arrow-x, 32px) - 10px); border-width: 0 10px 10px; border-bottom-color: var(--bg); }
.popover p { margin: 0; }
.live-dot { width: 10px; height: 10px; border-radius: 50%; background: #c7881c; }
.live-badge[data-state="open"] .live-dot { background: #22a767; animation: live-pulse 4s ease-in-out infinite; }
@keyframes live-pulse { 50% { opacity: .45; } }
.maplibregl-ctrl-bottom-left { left: calc(16px + env(safe-area-inset-left)); bottom: max(calc(16px + env(safe-area-inset-left)), env(safe-area-inset-bottom)); }
.maplibregl-ctrl-bottom-left .maplibregl-ctrl { margin: 0; }
/* The fixed-size anchor alone participates in MapLibre layout. The 28 px flag
   shares its background and opens into the map from the actual control dock. */
.map-credits { position: relative; width: 26px; height: 28px; color: var(--muted); font: 11px/20px var(--font); }
.map-credits .map-credits-toggle { position: absolute; top: 1px; left: 0; z-index: 1; width: 26px; height: 26px; padding: 0; font: italic 700 16px/1 Georgia, serif; }
.map-credits-toggle::after { content: ''; position: absolute; inset: -10px; }
.map-credits-text { position: absolute; top: 50%; left: 0; --flag-offset: -8px; width: max-content; max-width: calc(100vw - 104px - env(safe-area-inset-left) - env(safe-area-inset-right)); padding: 4px 8px 4px 30px; border-radius: 14px; background: var(--ctl-bg); box-shadow: 0 0 0 1px var(--ctl-border), var(--ctl-shadow); white-space: normal; pointer-events: none; transform: translateY(-50%); transition: opacity 160ms ease-out, transform 160ms ease-out, display 160ms allow-discrete; }
.map-credits[data-position="bottom-right"] .map-credits-text { left: auto; right: 0; --flag-offset: 8px; padding: 4px 30px 4px 8px; }
.map-credits-text[hidden] { opacity: 0; transform: translate(var(--flag-offset), -50%); }
@starting-style { .map-credits-text { opacity: 0; transform: translate(var(--flag-offset), -50%); } }
@media (prefers-reduced-motion: reduce) { .map-credits-text { transition: none; } }
/* Links win over the invisible part of the anchor's 44 px hit target. */
.map-credits a { position: relative; z-index: 2; pointer-events: auto; }
.map-credits a { color: var(--text); text-decoration: none; }
.map-credits a:is(:hover, :focus-visible) { text-decoration: underline; text-underline-offset: 2px; }
/* Toast: top centre in the badge row, same pill and type size as the live badge. The side margins keep
   it clear of the live badge (left) and the ? button (right), also at 360 px; long text wraps. */
.toast { --toast-side: calc(84px + max(env(safe-area-inset-left), env(safe-area-inset-right)));
  position: fixed; z-index: 6; top: calc(var(--top) + var(--search-h) + var(--search-gap)); left: 50%; transform: translateX(-50%); width: max-content; max-width: min(420px, calc(100vw - 2 * var(--toast-side)));
  display: flex; align-items: center; gap: 6px; margin: 0; padding: 4px 12px; min-height: 26px; border-radius: 13px;
  font-size: var(--fs-xs); font-weight: var(--fw-medium); line-height: 1.35; box-shadow: 0 1px 5px #0002; cursor: pointer; overflow-wrap: anywhere;
  background: var(--toast-bg); color: var(--toast-text); border: 1px solid var(--toast-border); animation: toast-in var(--dur-fast) var(--ease-out); }
.toast[data-level="info"] { --toast-bg: var(--button-bg); --toast-text: var(--muted); --toast-border: var(--border); }
.toast[data-level="warn"] { --toast-bg: var(--warn-bg); --toast-text: var(--warn-text); --toast-border: var(--warn-border); }
.toast[data-level="error"] { --toast-bg: var(--error-bg); --toast-text: var(--error-text); --toast-border: var(--error-border); padding-right: 4px; }
.toast-text { min-width: 0; }
.toast-close { position: relative; display: grid; place-items: center; flex-shrink: 0; width: 20px; height: 20px; padding: 0; border: 0; border-radius: 50%; background: transparent; color: inherit; }
/* 44 px touch target around the small glyph. */
.toast-close::after { content: ''; position: absolute; inset: -12px; }
.toast-close svg { width: 14px; height: 14px; stroke-width: 2.5; }
@keyframes toast-in { from { opacity: 0; transform: translate(-50%, -6px); } }
.position { width: 22px; height: 22px; border-radius: 50%; background: var(--follow); border: 3px solid white; box-shadow: 0 0 0 6px #1f83ff33; }
/* Same size and build as the station pin sprites (--pin-scale = PIN_SIZE / 100 in pins.mjs); no shadow, like them. */
.search-origin { --pin-scale: .9; width: calc(40px * var(--pin-scale)); height: calc(52px * var(--pin-scale)); pointer-events: none; }
.search-origin > svg { display: block; width: 100%; height: 100%; overflow: visible; }
.search-origin-pin { fill: var(--search-blue); stroke: #0e131a; stroke-width: 1; }
.search-origin-core { fill: var(--search-blue-core); stroke: none; }
.search-origin-aim { fill: none; stroke: #fff; stroke-width: 2; }
.search-origin-label { position: absolute; top: calc(100% + 3px * var(--pin-scale)); left: 50%; transform: translateX(-50%); box-sizing: border-box; width: max-content;
  /* Station badge tones and geometry; the query label is slightly larger than a site badge. */
  max-width: calc(160px * var(--pin-scale)); height: calc(22px * var(--pin-scale)); padding: 0 calc(7px * var(--pin-scale) - 1px);
  border: 1px solid var(--pin-badge-border); border-radius: calc(6px * var(--pin-scale)); background: var(--pin-badge-bg); color: var(--pin-badge-text);
  font: 600 calc(12.5px * var(--pin-scale))/calc(22px * var(--pin-scale) - 2px) var(--font); font-variant-numeric: normal; text-align: center;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* Heading chevron: a 64 px box centred on the dot (rotated about its centre), vector so it stays sharp on HiDPI; fill = --follow, white outline like the dot. */
.heading { position: absolute; left: -24px; top: -24px; width: 64px; height: 64px; transform-origin: 32px 32px; pointer-events: none;
  background: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2064%2064%22%3E%3Cpath%20d%3D%22M32%206%20L43.5%2018%20L32%2014.5%20L20.5%2018%20Z%22%20fill%3D%22%231f83ff%22%20stroke%3D%22%23fff%22%20stroke-width%3D%221.6%22%20stroke-linejoin%3D%22round%22%2F%3E%3C%2Fsvg%3E") center / 100% 100% no-repeat; }
