/* ═══════════════════════════════════════════════════════
   mydiodia — Aegean Blueprint sibling, polished v2
   Warm editorial · refined typography · subtle motion
   ═══════════════════════════════════════════════════════ */

:root {
  /* Warm paper base */
  --paper:       #faf7f0;
  --paper-2:     #f3eedf;
  --paper-3:     #e8e0c8;
  --line:        #ddd5bf;
  --line-strong: #b8ad8e;

  /* Ink scale */
  --ink:         #1a1f2e;
  --ink-2:       #3a4050;
  --ink-3:       #5e6578;
  --muted:       #8a8f9e;

  /* Aegean accent — the hero blue */
  --aegean:      #2a6b9e;
  --aegean-dark: #1e4f78;
  --aegean-lt:   #d6e5ef;

  /* Verdict scale */
  --go:          #2e7a4a;
  --go-bg:       #e6f0e9;
  --go-soft:     #5a9970;
  --go-soft-bg:  #eaf3ed;
  --stop:        #b8502d;
  --stop-bg:     #f5e2d5;
  --stop-soft:   #c4805f;
  --stop-soft-bg:#f3e2d6;

  --terracotta:  #c4613d;

  /* Typography */
  --font-display: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
  --font-body:    'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
  --font-mono:    'JetBrains Mono', monospace;
  --font-serif:   'DM Serif Display', 'Georgia', serif; /* reserved for hero text only */

  /* Layout */
  --topbar-h:   54px;
  --bar-h:      72px;
  --panel-h:    320px;
  --sp-w:       460px;
  --radius-sm:  3px;   /* scrollbars, tiny chips, internal corners */
  --radius:     5px;   /* default control & card corner */
  --radius-lg:  10px;  /* prominent panels, modals */
  --radius-pill: 999px;

  /* Motion */
  --ease:       cubic-bezier(0.4, 0.0, 0.2, 1);
  --ease-out:   cubic-bezier(0.0, 0.0, 0.2, 1);

  /* Shadows */
  --shadow-sm:  0 1px 2px rgba(26,31,46,0.06);
  --shadow:    0 2px 10px rgba(26,31,46,0.07), 0 1px 3px rgba(26,31,46,0.05);
  --shadow-md: 0 6px 20px rgba(26,31,46,0.09), 0 2px 5px rgba(26,31,46,0.06);
  --shadow-lg: 0 14px 40px rgba(26,31,46,0.13), 0 4px 10px rgba(26,31,46,0.06);

  /* ═══════════════════════════════════════════════════════════════
     R54 DESIGN SYSTEM — Phase 1 tokens
     ───────────────────────────────────────────────────────────────
     These are the canonical tokens for typography, weights, leadings,
     borders, elevations, and spacing. Adopting them in Phase 2 (button
     + surface migration) and Phase 3 (typography + color migration).
     Existing legacy variables above remain in place — Phase 1 is purely
     additive so no visual regressions ship.
     See DESIGN_SYSTEM.md for the full rationale.
     ═══════════════════════════════════════════════════════════════ */

  /* Type scale — 6 sizes (rem-based, 15.5px html base).
     R98: tightened the ramp; previously hardcoded outliers at 0.6/0.62/
     0.65/0.66/0.68/0.7rem all collapse to either --text-micro or
     --text-caption. The hero size is named so desktop and mobile can
     share the treatment. */
  --text-micro:   0.64rem;   /* badges, units, micro-footnotes, mono captions */
  --text-caption: 0.7rem;    /* labels, hints, sub-lines, tier labels */
  --text-sm:      0.78rem;   /* default UI text, pill labels, button text */
  --text-base:    0.92rem;   /* inputs, body, default reading */
  --text-lg:      1.05rem;   /* headings inside panels (rp-title, sp-title) */
  --text-xl:      1.4rem;    /* page-level titles */
  --text-hero:    2.1rem;    /* result panel hero number (desktop + mobile) */

  /* Backward-compat alias — older rules use --text-xs via fallback to
     0.72rem. Resolve to --text-caption so behavior is unified. */
  --text-xs:      var(--text-caption);

  /* Font weights — semantic names */
  --weight-regular:  400;    /* body prose, advice text */
  --weight-medium:   500;    /* default UI (labels, inputs, pills) */
  --weight-semibold: 600;    /* headings, prominent labels */
  --weight-bold:     700;    /* primary buttons, hero numbers */

  /* Line heights — 3 values */
  --leading-tight:  1.2;     /* headings, single-line UI */
  --leading-normal: 1.4;     /* default UI text */
  --leading-prose:  1.5;     /* reading-length paragraphs */

  /* Radii — adds --radius-xl on top of existing --radius-{sm, base, lg, pill} */
  --radius-xl:    16px;      /* floating panels (#bottom-bar, #results-panel) */

  /* Borders — 3 widths with semantic intent */
  --border-hair:    1px;     /* cards, surfaces, dividers (default) */
  --border-thick:   1.5px;   /* inputs, inputs-on-card */
  --border-stress:  2px;     /* active tabs, focus rings */

  /* R98 — Interaction tokens. Use these for hover/focus/active states
     across buttons, pills, and other interactive surfaces so the whole
     site has a single, consistent feel.

     --focus-ring: applied via `outline` on :focus-visible. 2px aegean
     with 2px offset — visible but not aggressive. Use on every button.

     --press-scale: subtle scale-down on :active. Mimics a physical
     button press without distracting motion. Apply via transform.

     --transition-fast: matched to the perceptual sweet spot for UI
     feedback (under 200ms). All hover/focus transitions should use
     this duration. Slower for explicit animations only. */
  --focus-ring:        2px solid var(--aegean);
  --focus-ring-offset: 2px;
  --press-scale:       0.97;
  --transition-fast:   0.15s;

  /* Elevations — 4 levels for shadows. The legacy --shadow-* names above
     remain for now; Phase 2 will migrate to --elev-*. */
  --elev-0: none;
  --elev-1: 0 1px 2px rgba(26,31,46,0.04), 0 1px 3px rgba(26,31,46,0.05);
  --elev-2: 0 4px 12px rgba(26,31,46,0.08), 0 2px 4px rgba(26,31,46,0.05);
  --elev-3: 0 8px 24px rgba(26,31,46,0.12), 0 2px 6px rgba(26,31,46,0.06);

  /* Spacing scale — for paddings/gaps that should match across components */
  --space-1:  4px;
  --space-2:  8px;
  --space-3:  12px;
  --space-4:  16px;
  --space-5:  24px;
  --space-6:  32px;

  /* Semantic color aliases (for upcoming Phase 3 — currently unused). */
  --surface:          var(--paper);          /* default card surface */
  --surface-raised:   var(--paper);          /* floating panels */
  --surface-inset:    var(--paper-2);        /* inset chips, pill tracks */
  --surface-selected: var(--aegean);         /* active/selected pill */
  --text-primary:     var(--ink);
  --text-secondary:   var(--ink-3);
  --text-muted:       var(--muted);
  --text-on-accent:   var(--paper);          /* white text on aegean buttons */
  --border-default:   var(--line);
  --border-strong:    var(--line-strong);
}

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { font-size: 15.5px; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
body {
  font-family: var(--font-body);
  background: var(--paper);
  color: var(--ink);
  height: 100dvh;
  overflow: hidden;
  line-height: 1.5;
  font-feature-settings: 'cv11', 'ss01', 'ss03';
}

/* ══════════════════════════════════════
   TOPBAR — refined
   ══════════════════════════════════════ */
#topbar {
  position: fixed; top: 0; left: 0; right: 0;
  z-index: 1000; height: var(--topbar-h);
  background: var(--paper);
  border-bottom: 1px solid var(--line);
  display: flex; align-items: center; padding: 0 18px; gap: 14px;
}
.logo {
  font-family: var(--font-display);
  font-weight: var(--weight-bold);
  font-size: var(--text-xl);
  letter-spacing: -0.025em;
  line-height: 1;
  color: var(--ink);
  flex-shrink: 0;
  user-select: none;
  cursor: pointer;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 9px;
  transition: transform 0.25s var(--ease), color 0.18s var(--ease);
}
.logo:hover { transform: translateY(-1px); }
.logo:hover .logo-glyph { transform: scale(1.05); }
.logo:active { transform: translateY(0); }
.logo-glyph {
  flex-shrink: 0;
  transition: transform 0.25s var(--ease);
}
.logo-text {
  /* "my" prefix: muted gray, less weight */
  color: var(--muted);
  font-weight: var(--weight-medium);
}
.logo-text .logo-mid {
  /* "dio" middle: bold dark ink — the main reading anchor */
  color: var(--ink);
  font-weight: var(--weight-bold);
}
.logo em,
.logo-text em {
  /* "dia" suffix: italic aegean blue — the brand flourish */
  font-style: italic;
  font-weight: var(--weight-medium);
  color: var(--aegean);
  font-variation-settings: "opsz" 144, "SOFT" 80;
}
.topbar-sep { width: 1px; height: 22px; background: var(--line); flex-shrink: 0; }
.topbar-right {
  margin-left: auto;
  display: flex; align-items: center; gap: 7px;
  flex-shrink: 0;
}
.btn-ghost {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  background: transparent;
  border: 1px solid var(--line);
  color: var(--ink-2);
  padding: 6px 12px;
  cursor: pointer;
  border-radius: var(--radius);
  transition: all 0.18s var(--ease);
  display: flex; align-items: center; gap: 6px;
  white-space: nowrap;
  letter-spacing: -0.005em;
}
.btn-ghost:hover {
  border-color: var(--aegean);
  color: var(--aegean-dark);
  background: var(--aegean-lt);
  transform: translateY(-1px);
  box-shadow: var(--shadow-sm);
}

/* ══════════════════════════════════════
   LANGUAGE FLAG TOGGLE
   ══════════════════════════════════════ */
.btn-lang-flag {
  display: inline-flex;
  align-items: center;
  background: var(--paper-2);
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  padding: 3px;
  gap: 1px;
  cursor: pointer;
  font-family: var(--font-body);
  transition: border-color 0.18s var(--ease), box-shadow 0.18s var(--ease);
}
.btn-lang-flag:hover {
  border-color: var(--aegean);
  box-shadow: 0 0 0 3px var(--aegean-lt);
}
.flag-option {
  padding: 4px 8px 3px;
  font-size: var(--text-base);
  line-height: 1;
  border-radius: var(--radius-pill);
  transition: all 0.2s var(--ease);
  display: inline-flex;
  align-items: center;
  cursor: pointer;
  filter: grayscale(0.6) opacity(0.55);
}
.flag-option:hover { filter: grayscale(0) opacity(1); }
.flag-option.active {
  background: var(--aegean-lt);
  filter: grayscale(0) opacity(1);
  box-shadow: 0 1px 4px rgba(42,107,158,0.18);
  transform: scale(1.05);
}

/* ══════════════════════════════════════
   VEHICLE DROPDOWN — top-right global mode
   Sits next to the language flag. The trigger button shows the
   currently-selected vehicle (emoji + full name + caret); clicking it
   reveals a menu with the four options. The selected vehicle drives
   every price display on the site.
   ══════════════════════════════════════ */
.veh-toggle {
  position: relative;
  display: inline-block;
  font-family: var(--font-body);
}
.veh-current {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--paper-2);
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  padding: 5px 10px 5px 12px;
  font-size: var(--text-sm);
  color: var(--ink);
  cursor: pointer;
  transition: border-color 0.18s var(--ease), box-shadow 0.18s var(--ease);
}
.veh-current:hover,
.veh-current[aria-expanded="true"] {
  border-color: var(--aegean);
  box-shadow: 0 0 0 3px var(--aegean-lt);
}
.veh-current .veh-emoji {
  font-size: var(--text-base);
  line-height: 1;
}
.veh-current .veh-label {
  line-height: 1;
  font-weight: var(--weight-medium);
  letter-spacing: -0.005em;
}
.veh-caret {
  font-size: var(--text-caption);
  color: var(--muted);
  margin-left: 2px;
  transform: translateY(-1px);
  transition: transform 0.18s var(--ease);
}
.veh-current[aria-expanded="true"] .veh-caret {
  transform: translateY(-1px) rotate(180deg);
}

/* Menu panel — anchored below the trigger, right-aligned so it doesn't
   overflow the topbar on narrow viewports. */
.veh-menu {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  min-width: 170px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: 0 8px 24px rgba(26,31,46,0.12), 0 2px 6px rgba(26,31,46,0.06);
  padding: 4px;
  z-index: 1000;
  display: flex;
  flex-direction: column;
  gap: 1px;
}
/* The HTML `hidden` attribute applies `display: none` via the UA stylesheet,
   but our `.veh-menu { display: flex }` overrides that. Force hidden to win
   when it's set on this element (open/close is toggled via menu.hidden). */
.veh-menu[hidden] { display: none; }
.veh-option {
  display: flex;
  align-items: center;
  gap: 10px;
  background: transparent;
  border: none;
  padding: 8px 12px;
  font-size: var(--text-sm);
  font-family: var(--font-body);
  color: var(--ink);
  text-align: left;
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: background 0.12s var(--ease);
}
.veh-option:hover {
  background: var(--aegean-lt);
}
.veh-option.active {
  background: var(--aegean-lt);
  font-weight: var(--weight-semibold);
}
.veh-option .veh-emoji {
  font-size: var(--text-lg);
  line-height: 1;
}
.veh-option .veh-label {
  line-height: 1.2;
}

/* ── Inline page-header vehicle picker ──────────────────────────────────
   Used on the Routes and Tolls pages: a "Prices for: [pill]" line under
   the page title. Identical component as the topbar one (same .veh-toggle
   markup, same .veh-menu, same JS), with a slightly smaller pill so it
   reads as in-flow content rather than as a chrome control. */
.page-vehicle {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 10px;
  font-family: var(--font-body);
}
.page-vehicle-prefix {
  font-size: var(--text-sm);
  color: var(--ink-3);
  font-weight: var(--weight-medium);
}
/* Inline modifier: shorter, smaller text. Same hover/open affordance. */
.veh-toggle--inline .veh-current {
  padding: 4px 8px 4px 10px;
  font-size: var(--text-sm);
}
.veh-toggle--inline .veh-current .veh-emoji {
  font-size: var(--text-base);
}
/* Anchor the inline menu to the LEFT of its trigger so it expands toward
   the page content instead of overflowing the right edge. The topbar
   variant keeps `right: 0` (its default) so it doesn't run off the page
   on narrow viewports — this only adjusts the inline instances. */
.veh-toggle--inline .veh-menu {
  right: auto;
  left: 0;
  min-width: 170px;
}

/* ══════════════════════════════════════
   MAP
   ══════════════════════════════════════ */
#map-container {
  /* R58: was bottom: var(--bar-h) (72px) — that reserved space at the
     bottom for the OLD horizontal bottom-bar. The new design has a
     floating panel at top-left and (on mobile) a peek strip; neither
     uses bottom: 0 globally. Map fills to viewport bottom on desktop;
     the mobile media query overrides to bottom: 48px (above peek). */
  position: fixed; top: var(--topbar-h); left: 0; right: 0;
  bottom: 0; z-index: 1;
}
#map { width: 100%; height: 100%; }
.leaflet-container { background: #ece9e3 !important; }
.leaflet-control-attribution {
  background: rgba(250,247,240,0.9) !important;
  color: var(--muted) !important;
  font-size: var(--text-micro) !important;
  font-family: var(--font-body) !important;
  backdrop-filter: blur(6px);
  border-top-left-radius: var(--radius);
}
.leaflet-control-attribution a { color: var(--ink-2) !important; }
.leaflet-control-zoom {
  border: 1px solid var(--line-strong) !important;
  border-radius: var(--radius) !important;
  overflow: hidden;
  box-shadow: var(--shadow-sm) !important;
  margin-top: 12px !important;
  margin-left: 12px !important;
}
.leaflet-control-zoom a {
  background: var(--paper) !important;
  color: var(--ink) !important;
  border-color: var(--line) !important;
  font-size: var(--text-lg) !important;
  line-height: 28px !important;
  width: 28px !important; height: 28px !important;
  font-family: var(--font-body) !important;
  transition: all 0.15s var(--ease) !important;
}
.leaflet-control-zoom a:hover {
  background: var(--aegean-lt) !important;
  color: var(--aegean) !important;
}

/* ══════════════════════════════════════
   TOLL MARKERS
   ══════════════════════════════════════ */
.toll-marker {
  width: 12px; height: 12px;
  border: 2px solid var(--paper);
  border-radius: 50%;
  cursor: pointer;
  transition: transform 0.22s var(--ease), box-shadow 0.22s var(--ease);
  box-shadow: 0 1px 3px rgba(26,31,46,0.3);
}
.toll-marker:hover {
  transform: scale(1.7);
  box-shadow: 0 0 0 3px rgba(250,247,240,0.85), 0 4px 12px rgba(26,31,46,0.35);
  z-index: 9999 !important;
}
/* Active toll dot — bigger, green, glowing ring */
.toll-marker.active {
  width: 14px; height: 14px;
  border: 2.5px solid #ffffff;
  box-shadow:
    0 0 0 2px rgba(31,88,40,0.25),
    0 0 0 6px rgba(31,88,40,0.12),
    0 2px 6px rgba(0,0,0,0.35);
  z-index: 9999 !important;
}

/* Small side-toll dot — used at low zoom (< ZOOM_THRESHOLD_FRONTAL_PILL).
   At country-level zoom the regular 11px side dots create visual noise
   against the 48 frontal markers; this 6px variant fades them back so
   the user can read the trunk-route structure. As they zoom in to plan
   a specific section, the dots grow to the regular size at the same
   threshold where frontals grow into pills. */
.toll-marker-side-small {
  width: 6px;
  height: 6px;
  border-width: 1px;
  box-shadow: 0 1px 2px rgba(26,31,46,0.25);
}
.toll-marker-side-small:hover {
  transform: scale(2);
}

/* ══════════════════════════════════════
   FRONTAL TOLL PILLS — perpendicular to the highway

   Frontal tolls are main-line plazas that block ALL traffic on the
   highway. The pill shape (rounded rectangle, oriented perpendicular
   to the road) reads as a "barrier across the road" — matching how a
   real toll plaza looks from above.

   Each frontal toll has a `bearing` field (compass degrees) computed
   from its bypass pre_exit→post_merge geometry. JS sets the rotation
   inline as `transform: translate(-50%,-50%) rotate(<bearing>deg)`.
   The Leaflet icon container is sized as a square ≥ the pill long
   side so the rotated bounding box never clips.

   Pills only appear at zoom ≥ ZOOM_THRESHOLD_FRONTAL_PILL (currently
   11). Below that, frontals revert to the same circle as bridges.
   ══════════════════════════════════════ */
.toll-marker-frontal {
  /* Size is set inline in JS (longSide × shortSide); the inner div is
     absolutely positioned at center of the icon container so rotation
     happens around the toll's geographic point. */
  position: absolute;
  border-radius: var(--radius);
  border: 1.5px solid var(--paper);
  box-shadow: 0 1px 3px rgba(26,31,46,0.35), 0 0 0 0.5px rgba(0,0,0,0.06);
  transition: filter 0.18s var(--ease);
}
.toll-marker-frontal:hover {
  /* Subtle brightening on hover (we can't apply scale because rotation
     is already on transform; scale would compound and look weird). */
  filter: brightness(1.12) drop-shadow(0 2px 4px rgba(26,31,46,0.4));
  z-index: 9999 !important;
}
.toll-marker-frontal.active {
  border: 2px solid #ffffff;
  box-shadow:
    0 0 0 2px rgba(31,88,40,0.28),
    0 0 0 6px rgba(31,88,40,0.14),
    0 2px 6px rgba(0,0,0,0.35);
}

/* ══════════════════════════════════════
   TOLL NAME LABELS — refined
   Soft mint pill in resting state, deep motorway-sign green when active.
   Echoes the Greek motorway signage in both states; default is muted so
   ~50 labels don't dominate the map, active is bold so it pops.
   ══════════════════════════════════════ */
.toll-name-label {
  display: inline-block;
  background: rgba(214,233,218,0.95);
  border: 1px solid rgba(85,140,100,0.35);
  color: #1f5828;
  font-family: var(--font-body);
  font-weight: var(--weight-semibold);
  font-style: normal;
  font-size: var(--text-caption);
  letter-spacing: 0.01em;
  padding: 2px 10px 3px;
  border-radius: var(--radius-pill);
  white-space: nowrap;
  box-shadow:
    0 1px 2px rgba(31,88,40,0.10),
    0 3px 8px rgba(31,88,40,0.06);
  cursor: pointer;
  transform: translateX(-50%) translateY(-7px);
  text-rendering: optimizeLegibility;
  transition: transform 0.18s var(--ease), box-shadow 0.18s var(--ease), background 0.18s var(--ease), color 0.18s var(--ease);
  text-transform: uppercase;
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}
.toll-name-label:hover {
  transform: translateX(-50%) translateY(-9px);
  box-shadow:
    0 2px 4px rgba(31,88,40,0.16),
    0 6px 16px rgba(31,88,40,0.14);
  background: rgba(197,224,203,0.98);
  border-color: rgba(85,140,100,0.55);
}
/* Active state: deep motorway-sign green */
.toll-name-label.active {
  background: linear-gradient(180deg, #2a6e35 0%, #1f5828 100%);
  border-color: rgba(255,255,255,0.95);
  color: #ffffff;
  text-shadow: 0 1px 0 rgba(0,0,0,0.2);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.18),
    0 1px 2px rgba(0,0,0,0.3),
    0 4px 12px rgba(0,0,0,0.18);
}

/* ══════════════════════════════════════
   RAMP SIGNS (EXIT / ENTER on map)
   Auto-size to content so any language label fits.
   Two-tone: colored label + lighter place-name section.
   ══════════════════════════════════════ */
.ramp-icon-wrap {
  width: auto !important;
  height: auto !important;
}
.ramp-sign {
  display: inline-flex;
  align-items: stretch;
  color: #ffffff;
  font-family: 'Arial Black', 'Inter', sans-serif;
  font-size: 9px;
  font-weight: var(--weight-bold);
  border-radius: var(--radius-sm);
  border: 1.5px solid white;
  white-space: nowrap;
  box-shadow: 0 1px 4px rgba(0,0,0,0.3);
  letter-spacing: 0.5px;
  line-height: 1.1;
  transform: translateX(-50%);
  pointer-events: auto;
  overflow: hidden;
  padding: 3px 7px 3px;
  gap: 6px;
}
.ramp-sign-name {
  font-family: 'Inter', sans-serif;
  font-weight: var(--weight-bold);
  letter-spacing: 0.02em;
  padding-left: 6px;
  border-left: 1px solid rgba(255,255,255,0.5);
  text-transform: uppercase;
  font-size: 8px;
  align-self: center;
}
.ramp-sign-exit  { background: var(--aegean); }   /* Aegean blue for EXIT */
.ramp-sign-entry { background: var(--go); }   /* go green for RE-ENTER */

/* ══════════════════════════════════════
   DIRECTION-OF-TRAVEL ARROWS ON BYPASS / HIGHWAY LINES
   Dropped at the midpoint of each route line, rotated to match the bearing
   of travel. Colors match the line they sit on so the user can tell at a
   glance which arrow belongs to which route.
   ══════════════════════════════════════ */
.dir-arrow-wrap {
  background: transparent;
  border: none;
  pointer-events: none;
}
.dir-arrow {
  width: 22px;
  height: 22px;
  display: flex;
  align-items: center;
  justify-content: center;
  filter: drop-shadow(0 1px 2px rgba(0,0,0,0.25));
  transform-origin: center center;
}
.dir-arrow svg { display: block; }
.dir-arrow-bypass  { color: var(--aegean); }   /* match the blue bypass line (local road) */
.dir-arrow-highway { color: var(--go); }   /* match the green highway line (motorway) */

/* ══════════════════════════════════════
   RAMPS TOGGLE INSIDE LEGEND
   ══════════════════════════════════════ */
.legend-divider {
  height: 1px;
  background: var(--line);
  margin: 6px 12px;
}
.legend-ramps-btn {
  display: flex;
  width: calc(100% - 12px);
  margin: 4px 6px 8px;
  align-items: center;
  gap: 9px;
  background: transparent;
  border: 1px solid transparent;
  color: var(--ink-2);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  letter-spacing: -0.005em;
  padding: 7px 10px;
  border-radius: var(--radius);
  cursor: pointer;
  transition: all 0.18s var(--ease);
  text-align: left;
}
.legend-ramps-btn:hover {
  background: var(--paper-2);
  color: var(--ink);
}
.legend-ramps-btn.active {
  background: var(--aegean-lt);
  color: var(--aegean-dark);
  border-color: var(--aegean);
  font-weight: var(--weight-semibold);
}
.legend-ramps-icon {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  flex-shrink: 0;
}
.legend-ramps-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px; height: 14px;
  font-family: 'Arial Black', sans-serif;
  font-size: 7px;
  font-weight: var(--weight-bold);
  color: white;
  letter-spacing: 0.5px;
  border-radius: var(--radius-sm);
  box-shadow: 0 1px 2px rgba(26,31,46,0.25);
}
.legend-ramps-badge-exit  { background: var(--aegean); }
.legend-ramps-badge-entry { background: var(--go); }

/* Side-toll dot — yellow indicator on the side-tolls toggle button */
.legend-side-dot {
  display: inline-block;
  width: 11px; height: 11px;
  background: #f4c430;  /* light yellow */
  border-radius: 50%;
  box-shadow: 0 1px 2px rgba(26,31,46,0.25), inset 0 0 0 1px rgba(0,0,0,0.08);
}
.legend-ramps-label { flex: 1; }
.legend-ramps-state {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  color: var(--muted);
  padding: 2px 6px;
  background: var(--paper-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  flex-shrink: 0;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.legend-ramps-btn.active .legend-ramps-state {
  background: var(--paper);
  border-color: var(--aegean);
  color: var(--aegean-dark);
}

/* ══════════════════════════════════════
   HOVER TOOLTIP — refined
   ══════════════════════════════════════ */
.toll-tooltip {
  position: fixed; z-index: 9999;
  display: none; pointer-events: none;
  background: var(--paper);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  min-width: 270px;
  font-family: var(--font-body);
  overflow: hidden;
  animation: tooltipIn 0.18s var(--ease-out);
}
@keyframes tooltipIn {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: translateY(0); }
}
.tt-header {
  padding: 10px 14px 8px;
  border-bottom: 1px solid var(--line);
  display: flex; align-items: flex-start; justify-content: space-between; gap: 10px;
}
.tt-name {
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  font-size: var(--text-lg);
  letter-spacing: -0.02em;
  color: var(--ink);
  line-height: 1.15;
  font-variation-settings: "opsz" 144, "SOFT" 30;
}
.tt-name-gr {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: var(--weight-regular);
  font-size: var(--text-sm);
  color: var(--muted);
  margin-top: 2px;
}
.tt-sub {
  font-size: var(--text-micro);
  color: var(--muted);
  margin-top: 4px;
  letter-spacing: 0.005em;
}
.tt-sub em { font-style: italic; color: var(--aegean); }
.tt-badge {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  font-weight: var(--weight-semibold);
  letter-spacing: 0.08em;
  padding: 3px 8px;
  border: 1px solid currentColor;
  border-radius: var(--radius);
  white-space: nowrap; flex-shrink: 0;
}
.tt-direction {
  padding: 5px 14px;
  font-size: var(--text-caption);
  color: var(--ink-2);
  background: var(--paper-2);
  border-bottom: 1px solid var(--line);
  display: flex; align-items: center; gap: 6px;
}
.tt-prices {
  padding: 8px 14px;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 6px;
}
.price-cell {
  display: flex; flex-direction: row; align-items: center; justify-content: center;
  gap: 5px;
  padding: 5px 6px;
  background: var(--paper-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  transition: transform 0.15s var(--ease);
}
.price-cell .vehicle-icon { font-size: var(--text-base); line-height: 1; }
.price-cell .vehicle-label {
  display: none;  /* icon alone is enough; label was redundant and ate vertical space */
}
.price-cell .price-val {
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  font-size: var(--text-base);
  letter-spacing: -0.02em;
  color: var(--ink);
  font-variation-settings: "opsz" 144;
}
.price-cell .price-val .eur {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: var(--weight-regular);
  font-size: var(--text-micro);
  color: var(--muted);
  margin-right: 1px;
  vertical-align: 1px;
}
.tt-notes {
  padding: 6px 14px 8px;
  font-family: var(--font-display);
  font-style: italic;
  font-size: var(--text-caption);
  color: var(--ink-3);
  line-height: 1.45;
  border-top: 1px solid var(--line);
  background: var(--paper-2);
}

/* ══════════════════════════════════════
   LEGEND — refined
   ══════════════════════════════════════ */
#legend {
  position: fixed; top: calc(var(--topbar-h) + 12px); right: 12px;
  z-index: 900;
  background: var(--paper);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  min-width: 220px;
  transition: right 0.3s var(--ease), opacity 0.2s, transform 0.2s;
  max-height: calc(100dvh - var(--topbar-h) - var(--bar-h) - 24px);
  overflow-y: auto;
  overflow-x: hidden;
}
#legend::-webkit-scrollbar { width: 4px; }
#legend::-webkit-scrollbar-thumb { background: var(--line-strong); border-radius: var(--radius-sm); }
#legend.hidden { opacity: 0; transform: translateY(-8px); pointer-events: none; }

/* ══════════════════════════════════════
   MAP CONTROLS STACK (top-right of map)

   Three vertically-stacked icon buttons grouped in a single rounded card:
   basemap, legend, side-tolls. Replaces the previous topbar buttons
   (#legend-toggle, #basemap-toggle) and the bottom-right floating pill
   (#side-tolls-toggle), consolidating map-specific controls inside the
   map itself — Google Maps convention.

   The card uses hairline separators between buttons and a single shared
   border/shadow so the group reads as one control rather than three
   floating buttons.
   ══════════════════════════════════════ */
.map-controls {
  position: fixed;
  top: calc(var(--topbar-h) + 12px);
  right: 12px;
  z-index: 850;
  display: flex;
  flex-direction: column;
  background: var(--paper);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  overflow: hidden;
}
/* Hide on routes/tolls pages — these controls are map-specific.
   Mirrors the existing `#page-map:not(.page-active) #legend` pattern. */
#page-map:not(.page-active) #map-controls,
#page-map:not(.page-active) #mc-basemap-popover { display: none; }
/* Hide controls + open popover whenever the toll side-panel is open.
   The user is examining a specific toll — they're not changing basemap
   or filtering side tolls in that moment. When the panel closes the
   controls reappear. Matches the same hide-on-panel-open pattern that
   already applies to #bottom-bar and #legend on mobile. */
body.panel-open #map-controls,
body.panel-open #mc-basemap-popover,
body.results-open #map-controls,
body.results-open #mc-basemap-popover,
body.results-open #legend { display: none !important; }

.mc-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  background: transparent;
  border: none;
  color: var(--ink-2);
  cursor: pointer;
  position: relative;
  transition: background 0.15s var(--ease), color 0.15s var(--ease);
}
.mc-btn:hover { background: var(--paper-2); color: var(--ink); }
.mc-btn:not(:last-child) { border-bottom: 1px solid var(--line); }
.mc-btn[aria-expanded="true"],
.mc-btn[aria-pressed="true"] { background: var(--aegean-lt); color: var(--aegean-dark); }

/* Side-tolls button — special-cased so the on-state uses YELLOW (matching
   the actual side-toll markers on the map) instead of the generic aegean
   tint other pressed buttons get. The visual rhyme — yellow button
   controls yellow dots — makes the button's purpose obvious without a
   text label. The toll dot inside the SVG (the small filled circle at
   the end of the off-ramp branch) is the most prominent on/off signal:
   bright yellow when active, washed-out grey when not. */
#mc-side-btn[aria-pressed="true"] {
  background: #fef6d8;          /* very light yellow */
  color: #4a3500;               /* dark brown — readable on yellow */
}
#mc-side-btn[aria-pressed="true"] .mc-side-toll-dot {
  fill: #c89e1a;                /* same yellow used for actual side-toll markers */
}
#mc-side-btn[aria-pressed="false"] {
  /* Off-state: mute the entire icon so it reads as inactive. The strokes
     stay; the toll-dot fades. */
  color: var(--ink-3);
}
#mc-side-btn[aria-pressed="false"] .mc-side-toll-dot {
  fill: var(--ink-3);
  opacity: 0.45;
}

/* Basemap popover: anchored to the right under the basemap button. Same
   visual language as the .veh-menu / .overflow-menu — small dropdown card
   with simple option buttons. */
.mc-popover {
  position: fixed;
  top: calc(var(--topbar-h) + 12px);   /* aligned with top of controls stack */
  right: calc(12px + 36px + 6px);      /* sit to the LEFT of the stack */
  z-index: 860;
  min-width: 150px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: 0 8px 24px rgba(26,31,46,0.12), 0 2px 6px rgba(26,31,46,0.06);
  padding: 4px;
  display: flex;
  flex-direction: column;
  gap: 1px;
  font-family: var(--font-body);
}
.mc-popover[hidden] { display: none; }
.mc-popover-option {
  display: flex;
  align-items: center;
  gap: 10px;
  background: transparent;
  border: none;
  padding: 8px 12px;
  font-size: var(--text-sm);
  color: var(--ink);
  text-align: left;
  border-radius: var(--radius-sm);
  cursor: pointer;
  font-family: inherit;
  transition: background 0.12s var(--ease);
}
.mc-popover-option:hover { background: var(--aegean-lt); }
.mc-popover-option.active {
  background: var(--aegean-lt);
  font-weight: var(--weight-semibold);
  color: var(--aegean-dark);
}
.mc-popover-option.active::before {
  content: '✓';
  font-size: 0.85em;
  color: var(--aegean);
  margin-right: -2px;
}
/* Reserve space for the checkmark on inactive options so they align. */
.mc-popover-option:not(.active)::before {
  content: '';
  display: inline-block;
  width: 0.85em;
  margin-right: -2px;
}

/* Adjust legend panel position so it doesn't collide with the controls
   stack. Legend now sits to the LEFT of the stack. */
#legend { right: calc(12px + 36px + 8px); }

.legend-title {
  padding: 11px 14px 9px;
  font-family: var(--font-display);
  font-style: italic;
  font-weight: var(--weight-regular);
  font-size: var(--text-sm);
  letter-spacing: -0.005em;
  color: var(--ink-2);
  border-bottom: 1px solid var(--line);
}
#legend-list { padding: 5px 5px; }
.legend-item {
  cursor: pointer;
  display: flex; align-items: center; gap: 10px;
  padding: 7px 10px;
  border-radius: var(--radius);
  transition: background 0.15s var(--ease), opacity 0.18s var(--ease);
  user-select: none;
  margin-bottom: 1px;
}
.legend-item:hover { background: var(--paper-2); }
.legend-item.active-filter {
  background: var(--aegean-lt);
  box-shadow: 0 0 0 1px var(--aegean) inset;
}
.legend-item.dimmed-filter { opacity: 0.32; }
.legend-dot {
  width: 11px; height: 11px;
  border-radius: 50%;
  flex-shrink: 0;
  box-shadow: 0 1px 3px rgba(26,31,46,0.22);
}
.legend-text { flex: 1; min-width: 0; }
.legend-label {
  font-family: var(--font-display);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--ink);
  letter-spacing: -0.01em;
}
.legend-sub {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: var(--weight-regular);
  font-size: var(--text-micro);
  color: var(--muted);
  margin-top: 1px;
}
.legend-count {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  color: var(--muted);
  padding: 2px 6px;
  background: var(--paper-2);
  border-radius: var(--radius);
  flex-shrink: 0;
  border: 1px solid var(--line);
}
.active-filter .legend-count {
  background: var(--paper);
  color: var(--aegean-dark);
  border-color: var(--aegean);
}

/* ══════════════════════════════════════
   TOLL SIDE PANEL — refined editorial
   ══════════════════════════════════════ */
#toll-side-panel {
  position: fixed; top: var(--topbar-h); right: 0;
  width: var(--sp-w); bottom: var(--bar-h);
  z-index: 800;
  background: var(--paper);
  border-left: 1px solid var(--line);
  box-shadow: -16px 0 48px rgba(26,31,46,0.12), -2px 0 8px rgba(26,31,46,0.04);
  display: flex; flex-direction: column;
  transform: translateX(100%);
  transition: transform 0.34s var(--ease);
}
#toll-side-panel.open { transform: translateX(0); }

/* Top control bar — minimal */
.sp-header {
  padding: 13px 22px 11px;
  display: flex; align-items: center; justify-content: space-between;
  flex-shrink: 0;
  background: var(--paper);
  border-bottom: 1px solid rgba(0,0,0,0.04);
}
.sp-header-title {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: var(--weight-regular);
  font-size: var(--text-sm);
  color: var(--muted);
  letter-spacing: 0.005em;
}
.sp-close {
  background: transparent;
  border: 1px solid var(--line);
  color: var(--muted);
  font-family: var(--font-body);
  font-size: var(--text-caption);
  font-weight: var(--weight-medium);
  padding: 4px 10px;
  cursor: pointer;
  border-radius: var(--radius-pill);
  transition: all 0.18s var(--ease);
  letter-spacing: 0.005em;
}
.sp-close:hover {
  background: var(--stop-bg);
  border-color: var(--stop);
  color: var(--stop);
}

.sp-scroll { flex: 1; overflow-y: auto; }
.sp-scroll::-webkit-scrollbar { width: 5px; }
.sp-scroll::-webkit-scrollbar-thumb { background: var(--line); border-radius: var(--radius-sm); }
.sp-scroll::-webkit-scrollbar-thumb:hover { background: var(--line-strong); }

/* Hero block — toll identity */
.sp-header-inner {
  padding: 28px 26px 24px;
  background:
    linear-gradient(180deg, rgba(255,255,255,0.5) 0%, transparent 100%),
    var(--paper);
  position: relative;
}
.sp-header-inner::after {
  /* Soft separator at the bottom of the hero */
  content: '';
  position: absolute;
  left: 26px; right: 26px; bottom: 0;
  height: 1px;
  background: linear-gradient(90deg, transparent 0%, var(--line) 30%, var(--line) 70%, transparent 100%);
}
.sp-hwy-badge {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-display);
  font-style: italic;
  font-weight: var(--weight-medium);
  font-size: var(--text-sm);
  letter-spacing: 0.005em;
  color: var(--ink) !important;
  margin-bottom: 14px;
  padding: 0;
  background: none !important;
  box-shadow: none;
  border-radius: 0;
}
.sp-hwy-badge::before {
  content: '';
  width: 11px;
  height: 11px;
  border-radius: 50%;
  /* The inline style sets the var --hwy-color; we use it here for the dot */
  background: var(--hwy-color, var(--aegean));
  box-shadow: 0 1px 3px rgba(26,31,46,0.25);
  flex-shrink: 0;
}
.sp-name {
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  font-size: var(--text-hero);
  letter-spacing: -0.028em;
  color: var(--ink);
  line-height: 1.02;
  margin-bottom: 6px;
  font-variation-settings: "opsz" 144, "SOFT" 30;
}
.sp-name-gr {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: var(--weight-regular);
  font-size: var(--text-base);
  color: var(--muted);
  margin-bottom: 16px;
  font-variation-settings: "opsz" 144, "SOFT" 80;
  letter-spacing: -0.005em;
}
.sp-operator {
  font-size: var(--text-caption);
  color: var(--muted);
  font-family: var(--font-body);
  letter-spacing: 0.005em;
  line-height: 1.5;
  padding-top: 14px;
  border-top: 1px dashed rgba(0,0,0,0.08);
}
.sp-operator strong { color: var(--ink); font-weight: var(--weight-medium); }

/* Editorial section labels */
.sp-section-title {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: var(--weight-medium);
  font-size: var(--text-caption);
  color: var(--aegean);
  padding: 14px 26px 6px;
  display: flex;
  align-items: center;
  gap: 12px;
  letter-spacing: 0.005em;
  font-variation-settings: "opsz" 144, "SOFT" 70;
  border-bottom: none;
}
.sp-section-title::before {
  content: '';
  display: inline-block;
  width: 18px; height: 1px;
  background: currentColor;
  opacity: 0.7;
}

/* Prices — single-vehicle headline. This is the main number on the panel,
   so make it visually prominent. The vehicle emoji is large (matches the
   visual weight of the price), and the price itself uses display font.
   The price-row sits inside the header (.sp-header-inner) so it stays
   visually grouped with the toll name; on desktop it's a full-width row
   below the name; on mobile (see media query) it's grid-positioned next
   to the name to save vertical space. */
.sp-price-row {
  display: flex; justify-content: space-between; align-items: center;
  padding: 8px 0;
  font-size: var(--text-lg);
}
.sp-price-row > span {
  color: var(--ink-2);
  font-family: var(--font-body);
  font-weight: var(--weight-regular);
  letter-spacing: -0.005em;
  display: inline-flex;
  align-items: center;
  gap: 12px;
}
.sp-emoji { font-size: 2.4rem; line-height: 1; }
.sp-vlabel { display: inline; font-size: var(--text-base); }
.sp-price-row strong {
  color: var(--ink);
  font-weight: var(--weight-semibold);
  font-family: var(--font-display);
  font-size: var(--text-hero);
  letter-spacing: -0.025em;
  font-variation-settings: "opsz" 144;
}

.sp-direction {
  padding: 11px 22px 14px;
  font-family: var(--font-display);
  font-weight: var(--weight-regular);
  font-size: var(--text-base);
  color: var(--ink-2);
  border-bottom: 1px solid var(--line);
  line-height: 1.45;
  letter-spacing: -0.005em;
}
.sp-direction em { font-style: italic; color: var(--aegean); }

.sp-notes {
  padding: 12px 22px 14px;
  font-family: var(--font-display);
  font-style: italic;
  font-weight: var(--weight-regular);
  font-size: var(--text-sm);
  color: var(--ink-3);
  line-height: 1.55;
  border-bottom: 1px solid var(--line);
  background: var(--paper-2);
}

.sp-no-bypass {
  padding: 16px 22px;
  font-family: var(--font-display);
  font-style: italic;
  font-size: var(--text-sm);
  color: var(--stop);
}

.sp-bypass-title { display: none; }

/* Direction filter pills */
.sp-dir-filter {
  display: flex;
  gap: 5px;
  padding: 10px 22px 6px;
  flex-wrap: wrap;
}
.sp-filter-btn {
  font-family: var(--font-body);
  font-size: var(--text-caption);
  font-weight: var(--weight-semibold);
  letter-spacing: -0.005em;
  background: var(--paper-2);
  color: var(--ink-2);
  border: 1px solid var(--line);
  padding: 5px 11px;
  border-radius: var(--radius-pill);
  cursor: pointer;
  transition: all 0.18s var(--ease);
}
.sp-filter-btn:hover {
  border-color: var(--aegean);
  color: var(--aegean-dark);
  background: var(--paper);
}
.sp-filter-btn.active {
  background: var(--aegean);
  border-color: var(--aegean-dark);
  color: var(--paper);
  box-shadow: 0 1px 4px rgba(42,107,158,0.3);
}
/* Side-toll panels — direction pills go yellow instead of blue.
   Color matches the yellow toll markers (#f4c430).
   Darker text on yellow for legibility. */
#toll-side-panel.side-toll .sp-filter-btn:hover {
  border-color: #c89e1a;
  color: #6e4f00;
}
#toll-side-panel.side-toll .sp-filter-btn.active {
  background: #f4c430;
  border-color: #c89e1a;
  color: #4a3500;
  box-shadow: 0 1px 4px rgba(244,196,48,0.45);
}
#toll-side-panel.side-toll .sp-filter-btn.sp-filter-both.active {
  background: #f4c430;
  border-style: solid;
}
/* "Both directions" pill is visually secondary, separated by a thin gap */
.sp-filter-btn.sp-filter-both {
  margin-left: 6px;
  background: transparent;
  border-style: dashed;
  font-weight: var(--weight-medium);
}
.sp-filter-btn.sp-filter-both.active {
  background: var(--aegean);
  border-style: solid;
  font-weight: var(--weight-semibold);
}

/* Direction blocks — refined */
.sp-dir { transition: opacity 0.22s var(--ease), border-color 0.22s var(--ease), background 0.22s var(--ease); }
.sp-dir {
  padding: 14px 22px 16px 19px; /* slim left padding to compensate the 5px active border */
  border-bottom: 1px solid var(--line);
  border-left: 5px solid var(--line);
  background: var(--paper);
  opacity: 0.45;
  cursor: pointer; /* whole block is clickable to select this direction */
}
.sp-dir:hover:not(.active) {
  background: rgba(46,122,74,0.04);
  border-left-color: rgba(46,122,74,0.5);
  opacity: 0.7;
}
.sp-dir.active {
  border-left: 5px solid var(--go);
  /* Richer left-to-right tint so the selected direction reads at a glance —
     the previous gradient stopped at 30%, this one extends further with a
     slightly more saturated start color. */
  background: linear-gradient(to right, rgba(46,122,74,0.13) 0%, rgba(46,122,74,0.04) 50%, var(--paper) 100%);
  opacity: 1;
  cursor: default;
}
.sp-dir.dimmed { opacity: 0.32; }
.sp-dir:last-child { border-bottom: none; }
.sp-dir-label {
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  font-size: var(--text-base);
  letter-spacing: -0.015em;
  color: var(--ink);
  margin-bottom: 8px;
  font-variation-settings: "opsz" 144, "SOFT" 30;
}
.sp-dir-exits {
  display: flex; flex-direction: column; gap: 5px;
  margin-bottom: 6px;
}
.sp-exit-tag, .sp-entry-tag {
  font-size: var(--text-sm);
  padding: 5px 11px;
  border-radius: var(--radius);
  display: flex; align-items: center; gap: 7px;
  font-family: var(--font-body);
  letter-spacing: -0.005em;
  background: var(--paper);
}
.sp-tag-icon {
  flex-shrink: 0;
  /* Stroke inherits each tag's text color via currentColor on the SVG */
}
.sp-tag-text {
  /* Flex item that wraps cleanly when ramp names are long */
  min-width: 0;
}
.sp-exit-tag {
  color: var(--aegean-dark);
  border: 1px solid var(--aegean);
  box-shadow: inset 0 0 0 1px rgba(42,107,158,0.06);
}
.sp-entry-tag {
  color: #1f5a35;
  border: 1px solid var(--go);
  box-shadow: inset 0 0 0 1px rgba(46,122,74,0.06);
}

/* Confidence indicator — between exit/entry tags and the comparison block.
   `verified` directions render no badge (clean state). `auto` shows a quiet
   provenance line. `approximate` shows a visible amber warning so the user
   knows to verify before relying on the bypass. */
.sp-confidence {
  font-size: var(--text-caption);
  padding: 6px 10px;
  border-radius: var(--radius);
  margin-top: 6px;
  font-family: var(--font-body);
  letter-spacing: -0.005em;
  line-height: 1.35;
  cursor: help;
}
.sp-conf-auto {
  color: #5a6678;
  background: rgba(42,107,158,0.05);
  border: 1px dashed rgba(42,107,158,0.25);
}
.sp-conf-approximate {
  color: #8a5a1a;
  background: #fef3df;
  border: 1px solid #e8c178;
  font-weight: var(--weight-medium);
}

/* Bypass vs highway comparison block — refined */
.sp-dir-compare {
  margin-top: 10px;
  padding: 10px 12px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  /* Define the column structure once at the container level so all rows
     share the same column tracks (€s, χλμ, λεπ all line up vertically). */
  display: grid;
  grid-template-columns: 9px 1fr auto auto auto;
  row-gap: 0;
}
/* Compare table rows: each row is a subgrid that inherits the parent's
   5 column tracks, so values in column 3 (money), 4 (distance), and 5
   (time) align cleanly across rows regardless of content width. */
.sp-cmp-row {
  display: grid;
  grid-template-columns: subgrid;
  grid-column: 1 / -1;          /* span all 5 of the parent's columns */
  align-items: center;
  column-gap: 11px;
  font-family: var(--font-body);
  font-size: var(--text-sm);
  padding: 6px 0;
}
.sp-cmp-row + .sp-cmp-row { border-top: 1px dashed var(--line); }
.sp-cmp-dot {
  width: 9px; height: 9px;
  border-radius: 50%;
  flex-shrink: 0;
  box-shadow: 0 1px 2px rgba(26,31,46,0.22);
}
.sp-cmp-label {
  color: var(--ink-2);
  font-weight: var(--weight-medium);
  letter-spacing: -0.005em;
}
/* The .sp-cmp-vals wrapper from the HTML still exists for semantic grouping,
   but visually we want its three children to participate in the row's grid
   directly. `display: contents` makes the wrapper invisible to layout so
   .sp-cmp-money/dist/time become grid items of the parent .sp-cmp-row. */
.sp-cmp-vals {
  display: contents;
  color: var(--ink);
  font-family: var(--font-mono);
  font-size: var(--text-caption);
  font-weight: var(--weight-medium);
  font-variant-numeric: tabular-nums;
}
.sp-cmp-money {
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  font-size: var(--text-sm);
  letter-spacing: -0.015em;
  text-align: right;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}
.sp-cmp-dist, .sp-cmp-time {
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-family: var(--font-mono);
  font-size: var(--text-caption);
  font-weight: var(--weight-medium);
  color: var(--ink);
}

/* Διαφορά row — no dot, so the label spans the first two grid columns. */
/* Διαφορά row — sits at the bottom of the same table as a third row.
   Soft horizontal-gradient tint (transparent at edges → tinted in center)
   so the row feels like an integrated summary, not a hard-edged stripe. */
.sp-cmp-row.sp-cmp-diff {
  margin-top: 4px;
  padding: 8px 0;       /* keep horizontal at 0 so column alignment is preserved */
  border-top: 1px solid var(--line);
  background: transparent;
  transition: background 0.18s var(--ease);
}
.sp-cmp-row.sp-cmp-diff.savings {
  background: linear-gradient(
    to right,
    rgba(46, 122, 74, 0.0)  0%,
    rgba(46, 122, 74, 0.08) 20%,
    rgba(46, 122, 74, 0.08) 80%,
    rgba(46, 122, 74, 0.0)  100%
  );
}
.sp-cmp-row.sp-cmp-diff.cost {
  background: linear-gradient(
    to right,
    rgba(184, 80, 45, 0.0)  0%,
    rgba(184, 80, 45, 0.08) 20%,
    rgba(184, 80, 45, 0.08) 80%,
    rgba(184, 80, 45, 0.0)  100%
  );
}
.sp-cmp-diff-label {
  font-weight: var(--weight-semibold);
  color: var(--ink);
  grid-column: 1 / span 2;   /* fill the dot + label area */
}
/* Color-coded diff values: savings → green, cost → amber-red, zero → muted. */
.sp-cmp-money.savings, .sp-cmp-dist.savings, .sp-cmp-time.savings { color: #2d7a3a; }
.sp-cmp-money.cost,    .sp-cmp-dist.cost,    .sp-cmp-time.cost    { color: #a45533; }
.sp-cmp-money.zero,    .sp-cmp-dist.zero,    .sp-cmp-time.zero    { color: var(--ink-3); }

/* ══════════════════════════════════════
   BOTTOM BAR
   ══════════════════════════════════════ */
#bottom-bar {
  position: fixed;
  bottom: 0; left: 0; right: 0;
  z-index: 500;
  height: var(--bar-h);
  background: linear-gradient(180deg, var(--paper) 0%, var(--paper-2) 100%);
  border-top: 1px solid var(--line-strong);
  display: flex; align-items: center;
  padding: 0 20px; gap: 12px;
  box-shadow: 0 -6px 24px rgba(26,31,46,0.06);
}
.bar-label {
  font-family: var(--font-body);
  font-weight: var(--weight-medium);
  font-size: var(--text-caption);
  color: var(--muted);
  white-space: nowrap;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.bar-input {
  height: 44px;
  background: var(--paper);
  border: 1.5px solid var(--line);
  color: var(--ink);
  font-family: var(--font-body);
  font-weight: var(--weight-medium);
  font-size: var(--text-base);
  padding: 0 14px;
  outline: none;
  border-radius: var(--radius);
  transition: all 0.18s var(--ease);
  min-width: 0;
  letter-spacing: -0.005em;
  box-shadow: 0 1px 2px rgba(0,0,0,0.03);
}
.bar-input::placeholder { color: var(--muted); }
.bar-input:focus {
  border-color: var(--aegean);
  background: var(--paper);
  box-shadow: 0 0 0 3px var(--aegean-lt), 0 1px 2px rgba(0,0,0,0.03);
}
.swap-btn {
  height: 44px; width: 40px;
  background: var(--paper);
  border: 1.5px solid var(--line);
  color: var(--ink-2);
  font-size: var(--text-lg);
  cursor: pointer;
  border-radius: var(--radius);
  transition: all 0.18s var(--ease);
  flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 1px 2px rgba(0,0,0,0.03);
}
.swap-btn:hover {
  background: var(--aegean-lt);
  border-color: var(--aegean);
  color: var(--aegean);
  transform: rotate(180deg);
}
.bar-select {
  height: 44px;
  background: var(--paper);
  border: 1.5px solid var(--line);
  color: var(--ink);
  font-family: var(--font-body);
  font-weight: var(--weight-medium);
  font-size: var(--text-base);
  padding: 0 14px;
  outline: none;
  border-radius: var(--radius);
  cursor: pointer;
  -webkit-appearance: none;
  transition: border-color 0.18s var(--ease);
  flex-shrink: 0;
  box-shadow: 0 1px 2px rgba(0,0,0,0.03);
}
.bar-select:focus { border-color: var(--aegean); }
.bar-sep { width: 1px; height: 30px; background: var(--line); flex-shrink: 0; }

.tv-compact {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-shrink: 1;
  min-width: 0;
  padding: 0 4px;
}
.tv-compact-sentence {
  display: flex;
  align-items: center;
  gap: 6px;
  line-height: 1.2;
  flex-shrink: 1;
  min-width: 0;
}
.tv-compact .lbl {
  font-family: var(--font-body);
  font-weight: var(--weight-medium);
  font-size: var(--text-sm);
  color: var(--ink-2);
  white-space: nowrap;
  letter-spacing: -0.005em;
}
.tv-compact .lbl-suffix {
  font-size: var(--text-sm);
  color: var(--muted);
  white-space: normal;
  flex-shrink: 1;
  min-width: 0;
  max-width: 220px;
  line-height: 1.25;
}
.tv-compact .val {
  font-family: var(--font-body);
  color: var(--paper);
  /* Background tracks the slider's --fill-color so the value pill shifts
     green→amber→red in sync. Falls back to aegean blue before JS runs. */
  background: var(--fill-color, var(--aegean));
  width: 88px;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0;
  padding: 4px 8px 5px;
  border-radius: var(--radius-lg);
  box-shadow: 0 1px 3px rgba(0,0,0,0.18);
  line-height: 1;
  transition: background 0.15s var(--ease);
}
.tv-compact .val-num {
  font-weight: var(--weight-bold);
  font-size: var(--text-lg);
  letter-spacing: -0.025em;
  line-height: 1.1;
}
.tv-compact .val-tier {
  font-style: italic;
  font-weight: var(--weight-medium);
  font-size: var(--text-micro);
  letter-spacing: 0.02em;
  color: rgba(255,255,255,0.82);
  text-align: center;
  line-height: 1.15;
  margin-top: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}
.tv-compact input[type="range"] {
  width: 110px;
  flex-shrink: 0;
}
/* Desktop shows long phrase, mobile uses short phrase (toggled in media query) */
.tv-compact .tv-mobile { display: none; }
.tv-compact .tv-desktop { display: inline; }
/* Range slider — visible track with "filled" left portion driven by --fill
   (set in JS on input). Fill color shifts green→amber→red as the user
   slides right (--fill-color, also set in JS) to visually communicate
   "tolerating more delay." Thumb is large enough to read as draggable. */
input[type="range"] {
  width: 110px;
  -webkit-appearance: none;
  height: 8px;
  background: linear-gradient(
    to right,
    var(--fill-color, var(--aegean)) 0%,
    var(--fill-color, var(--aegean)) var(--fill, 50%),
    rgba(42,107,158,0.18) var(--fill, 50%),
    rgba(42,107,158,0.18) 100%
  );
  outline: none;
  border: none;
  cursor: pointer;
  border-radius: var(--radius);
  box-shadow: inset 0 1px 2px rgba(0,0,0,0.10);
}
input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 20px; height: 20px;
  background: var(--paper);
  border: 3px solid var(--fill-color, var(--aegean));
  border-radius: 50%;
  cursor: grab;
  box-shadow: 0 2px 5px rgba(0,0,0,0.18), 0 0 0 1px rgba(255,255,255,0.6) inset;
  transition: transform 0.15s var(--ease), box-shadow 0.15s var(--ease), border-color 0.15s var(--ease);
}
input[type="range"]::-webkit-slider-thumb:hover {
  transform: scale(1.12);
  box-shadow: 0 3px 8px rgba(0,0,0,0.22), 0 0 0 1px rgba(255,255,255,0.6) inset;
}
input[type="range"]:active::-webkit-slider-thumb { cursor: grabbing; transform: scale(1.18); }
input[type="range"]::-moz-range-thumb {
  width: 20px; height: 20px;
  background: var(--paper);
  border: 3px solid var(--fill-color, var(--aegean));
  border-radius: 50%;
  cursor: grab;
  box-shadow: 0 2px 5px rgba(0,0,0,0.18);
}
input[type="range"]::-moz-range-progress {
  background: var(--fill-color, var(--aegean));
  border-radius: var(--radius);
  height: 8px;
}
input[type="range"]::-moz-range-track {
  background: rgba(42,107,158,0.18);
  border-radius: var(--radius);
  height: 8px;
}

/* ─── Tolerance control: prose ⇄ pill modes ──────────────────────────────
   The tolerance control has two visual modes, toggled by .is-pill-mode on
   .tv-control. Prose mode (default for first-time visitors) shows the full
   sentence + slider inline. Pill mode (default for returning visitors)
   shows a compact button with a stopwatch icon + number, opening a popover
   on click. Switch happens via JS on first slider interaction.

   The slider element is moved (via appendChild) between .tv-compact (prose)
   and .tv-popover-slot (pill). Single source of truth, single set of
   listeners — see calculator.js for the move logic. */

.tv-control {
  position: relative;       /* anchor for absolutely-positioned popover */
  display: flex;
  align-items: center;
  flex-shrink: 1;
  min-width: 0;
}
.tv-control:not(.is-pill-mode) .tv-mode-pill { display: none; }
.tv-control.is-pill-mode      .tv-mode-prose { display: none; }

/* Pill button: icon + number + caret. Mirrors the size/spacing of the
   topbar btn-ghost so it visually rhymes with the rest of the bar. */
.tv-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 0 10px;
  height: 36px;
  border: 1px solid var(--paper-3);
  background: var(--paper);
  color: var(--ink-2);
  border-radius: var(--radius);
  font-family: var(--font-body);
  font-weight: var(--weight-semibold);
  font-size: var(--text-base);
  letter-spacing: -0.01em;
  cursor: pointer;
  transition: border-color 0.15s var(--ease), background 0.15s var(--ease), box-shadow 0.15s var(--ease);
}
.tv-pill:hover {
  border-color: var(--aegean);
  background: var(--paper-2);
}
.tv-pill[aria-expanded="true"] {
  border-color: var(--aegean);
  background: var(--aegean-lt);
  color: var(--aegean-dark);
  box-shadow: inset 0 1px 2px rgba(26,31,46,0.06);
}
.tv-pill-icon {
  flex-shrink: 0;
  color: var(--aegean);
  /* The icon color tracks the slider's current --fill-color, set on
     #tv-control by JS. Falls back to aegean if JS hasn't run yet. */
  color: var(--fill-color, var(--aegean));
  transition: color 0.15s var(--ease);
}
.tv-pill-num {
  font-variant-numeric: tabular-nums;
  min-width: 1ch;
  text-align: center;
}
.tv-pill-caret {
  font-size: var(--text-caption);
  color: var(--muted);
  margin-left: -2px;
}

/* Popover: floats above the bar. The arrow points down at the pill. */
.tv-popover {
  position: absolute;
  bottom: calc(100% + 12px);    /* sit above the bar with breathing room */
  left: 50%;
  transform: translateX(-50%);
  width: 280px;
  padding: 14px 14px 12px;
  background: var(--paper);
  border: 1px solid var(--paper-3);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  z-index: 300;                  /* above bottom-bar (which is ~200) */
  animation: tv-popover-in 0.18s var(--ease-out) backwards;
}
.tv-popover[hidden] { display: none; }
@keyframes tv-popover-in {
  from { opacity: 0; transform: translateX(-50%) translateY(4px); }
  to   { opacity: 1; transform: translateX(-50%) translateY(0); }
}
.tv-popover-arrow {
  position: absolute;
  bottom: -7px;
  left: 50%;
  transform: translateX(-50%) rotate(45deg);
  width: 14px;
  height: 14px;
  background: var(--paper);
  border-right: 1px solid var(--paper-3);
  border-bottom: 1px solid var(--paper-3);
}
.tv-popover-question {
  font-size: var(--text-sm);
  color: var(--ink-2);
  line-height: 1.35;
  margin-bottom: 14px;
}
.tv-popover-row {
  display: flex;
  align-items: center;
  gap: 12px;
}
.tv-popover-slot {
  flex: 1;
  display: flex;
  align-items: center;
  min-width: 0;
}
/* When the slider is mounted inside the popover slot, stretch it. */
.tv-popover-slot input[type="range"] {
  width: 100%;
}
.tv-popover-val {
  font-family: var(--font-body);
  font-weight: var(--weight-bold);
  font-size: var(--text-lg);
  color: var(--paper);
  background: var(--fill-color, var(--aegean));
  min-width: 36px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 8px;
  border-radius: var(--radius);
  font-variant-numeric: tabular-nums;
  transition: background 0.15s var(--ease);
}
.tv-popover-tier {
  margin-top: 8px;
  text-align: center;
  font-size: var(--text-sm);
  font-style: italic;
  color: var(--muted);
  min-height: 1em;
  font-variant: italic;
}

.analyse-btn {
  height: 48px;
  background: linear-gradient(180deg, var(--aegean) 0%, var(--aegean-dark) 100%);
  border: none;
  color: var(--paper);
  font-family: var(--font-body);
  font-weight: var(--weight-bold);
  font-size: var(--text-base);
  letter-spacing: 0.01em;
  padding: 0 28px;
  cursor: pointer;
  border-radius: var(--radius);
  display: flex; align-items: center; gap: 8px;
  transition: all 0.18s var(--ease);
  white-space: nowrap;
  flex-shrink: 0;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.15),
    0 2px 8px rgba(42,107,158,0.35),
    0 4px 16px rgba(42,107,158,0.18);
  position: relative;
}
.analyse-btn::before {
  content: '→';
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  margin-right: 4px;
  transition: transform 0.18s var(--ease);
}
.analyse-btn:hover {
  background: linear-gradient(180deg, var(--aegean-dark) 0%, var(--aegean-dark) 100%);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.2),
    0 4px 14px rgba(42,107,158,0.45),
    0 8px 24px rgba(42,107,158,0.25);
  transform: translateY(-1px);
}
.analyse-btn:hover::before { transform: translateX(3px); }
.analyse-btn:active { transform: translateY(0) scale(0.98); }
.analyse-btn:disabled {
  background: var(--line-strong);
  cursor: not-allowed;
  box-shadow: none;
}
.analyse-btn:disabled::before { display: none; }
.btn-spinner {
  width: 14px; height: 14px;
  border: 2px solid rgba(250,247,240,0.35);
  border-top-color: var(--paper);
  border-radius: 50%;
  animation: spin 0.6s linear infinite;
  display: none;
}
.loading .btn-spinner { display: block; }
.loading.analyse-btn::before { display: none; }
@keyframes spin { to { transform: rotate(360deg); } }

.error-pill {
  font-family: var(--font-body);
  font-size: var(--text-caption);
  color: var(--stop);
  background: var(--stop-bg);
  border: 1px solid var(--stop);
  padding: 5px 12px;
  border-radius: var(--radius);
  display: none;
  white-space: nowrap;
  /* R69: flex layout so an optional Retry button can sit next to the
     message text without overflowing on narrow input islands. */
  align-items: center;
  gap: 8px;
}
.error-pill.visible { display: inline-flex; }
.error-pill-text {
  /* R69: allow the message to wrap at long error texts. */
  white-space: normal;
  line-height: var(--leading-tight);
}
.error-pill-retry {
  font-family: var(--font-body);
  font-size: var(--text-caption);
  font-weight: var(--weight-semibold);
  color: var(--paper);
  background: var(--stop);
  border: 1px solid var(--stop);
  padding: 3px 8px;
  border-radius: var(--radius);
  cursor: pointer;
  white-space: nowrap;
  flex-shrink: 0;
}
.error-pill-retry:hover {
  filter: brightness(1.1);
}

/* ══════════════════════════════════════
   RESULTS PANEL
   ══════════════════════════════════════ */
#results-panel {
  position: fixed;
  /* Was bottom: var(--bar-h) — that left a strip of the panel's head
     visible when closed (the bar-h gap sat above the original horizontal
     bottom-bar; now that the bottom-bar is a small floating card, the
     strip leaks into view at the bottom). Anchored to the viewport
     bottom now, so the closed translateY(100%) hides it completely. */
  bottom: 0; left: 0; right: 0;
  z-index: 400;
  background: var(--paper);
  border-top: 1px solid var(--line-strong);
  box-shadow: 0 -8px 32px rgba(26,31,46,0.12);
  transform: translateY(100%);
  transition: transform 0.32s var(--ease), visibility 0s linear 0.32s;
  max-height: var(--panel-h);
  display: flex; flex-direction: column;
  /* R49: explicit visibility hidden when closed — defensive against any
     situation where translateY(100%) doesn't move the panel fully off
     screen (e.g., empty content collapses the panel to small height). */
  visibility: hidden;
}
#results-panel.open {
  transform: translateY(0);
  visibility: visible;
  transition: transform 0.32s var(--ease), visibility 0s linear 0s;
}

.rp-head {
  display: flex; align-items: center;
  padding: 14px 22px;
  /* R58: was a gradient (paper-2 → paper); user reported header looking
     transparent. Switched to solid paper-2 with explicit background-color
     so no shorthand quirk can make it transparent. */
  background: var(--paper-2);
  background-color: var(--paper-2);
  border-bottom: 1px solid var(--line);
  gap: 16px;
  flex-shrink: 0;
}
.rp-title {
  font-family: var(--font-body);
  font-weight: var(--weight-bold);
  font-size: var(--text-lg);
  letter-spacing: -0.02em;
  color: var(--ink);
  flex-shrink: 0;
}
.rp-stats {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  flex: 1;
  min-width: 0;
}

/* ════════════════════════════════════════════════════════════════════════
   R95 — Mobile-first results panel block
   ════════════════════════════════════════════════════════════════════════
   On screens > 720px, the .rp-mobile block is hidden and .rp-cmp table
   is shown. On ≤720px (phones), .rp-mobile takes over with a hero number,
   "vs motorway" comparison card, and a collapsible details breakdown —
   answering the primary question (what does this trip cost?) at a glance
   and tucking the table-like detail behind one tap.

   The same DOM serves both — JS renders both blocks, CSS picks one.
   ════════════════════════════════════════════════════════════════════════ */

.rp-mobile {
  display: none;          /* desktop default — hidden */
}

@media (max-width: 720px) {
  .rp-mobile { display: flex; flex-direction: column; gap: 10px; }
  .rp-cmp    { display: none; }     /* hide desktop table on phones */
}

.rp-hero {
  padding: 2px 2px 0;
}
.rp-hero-cost {
  font-family: var(--font-display);
  font-size: var(--text-hero);
  font-weight: var(--weight-regular);
  letter-spacing: -0.025em;
  color: var(--ink);
  line-height: 1.05;
  font-variant-numeric: tabular-nums;
}
.rp-hero-sub {
  font-size: var(--text-sm);
  color: var(--ink-2);
  margin-top: 3px;
  font-variant-numeric: tabular-nums;
}

.rp-vs {
  background: var(--save-bg, #e8f3ec);
  border-radius: 10px;
  padding: 9px 12px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.rp-vs--neutral {
  background: var(--paper-2, #faf7f0);
}
.rp-vs-line {
  font-size: var(--text-sm);
  color: #1f5a35;
  display: flex;
  align-items: baseline;
  gap: 6px;
  flex-wrap: wrap;
  line-height: 1.35;
}
.rp-vs--neutral .rp-vs-line {
  color: var(--ink-2);
}
.rp-vs-label {
  font-weight: var(--weight-medium);
}
.rp-vs-amt {
  font-weight: var(--weight-semibold);
  font-variant-numeric: tabular-nums;
  font-size: var(--text-lg);
  color: #1f5a35;
}
.rp-vs-cmp {
  color: #2d7a3a;
  font-weight: var(--weight-medium);
  font-size: var(--text-caption);
}
.rp-vs-extra {
  font-size: var(--text-caption);
  color: #b34d2a;
  font-variant-numeric: tabular-nums;
  font-weight: var(--weight-medium);
}

.rp-breakdown {
  border-top: 1px solid var(--line);
  padding-top: 8px;
}
.rp-breakdown-summary {
  /* Custom marker (▾ rotates on open) for cross-browser consistency.
     Native <summary> default has a triangle in iOS that doesn't match
     our type. */
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 4px 0;
  font-size: var(--text-caption);
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: var(--weight-semibold);
  -webkit-tap-highlight-color: transparent;
}
.rp-breakdown-summary::-webkit-details-marker { display: none; }
.rp-breakdown-summary-icon {
  display: inline-block;
  transition: transform 0.2s ease;
  font-size: var(--text-sm);
}
.rp-breakdown[open] .rp-breakdown-summary-icon {
  transform: rotate(180deg);
}
.rp-breakdown-body {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 6px 0 2px;
}
.rp-breakdown-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-size: var(--text-sm);
  gap: 12px;
}
.rp-breakdown-row span:first-child {
  color: var(--ink-2);
}
.rp-breakdown-row span:last-child {
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  text-align: right;
}
.rp-breakdown-row strong {
  font-weight: var(--weight-semibold);
  color: var(--ink);
}
.rp-breakdown-row--meta {
  font-size: var(--text-caption);
  color: var(--muted);
  padding-top: 2px;
  border-top: 1px dashed var(--line);
  margin-top: 2px;
}
.rp-breakdown-row--meta:first-of-type {
  margin-top: 4px;
}

/* (R94: the .rp-headline pill was removed. The Δ row at the top of
   the .rp-cmp grid carries the same information now, with each cell
   aligned vertically over its corresponding column.) */

.rp-stat {
  display: flex;
  flex-direction: column;
  gap: 1px;
  line-height: 1.2;
}
.rp-stat-label {
  font-family: var(--font-body);
  font-size: var(--text-micro);
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-weight: var(--weight-semibold);
}
.rp-stat strong {
  color: var(--ink);
  font-weight: var(--weight-bold);
  font-family: var(--font-body);
  font-size: var(--text-lg);
  letter-spacing: -0.02em;
}
.rp-stat.sm strong { font-size: var(--text-base); }
.rp-stat.green strong { color: var(--go); }
.rp-stat.red strong   { color: var(--terracotta); }
.rp-stat-divider {
  width: 1px;
  height: 30px;
  background: var(--line);
  align-self: center;
}

/* ════════════════════════════════════════════════════════════════════════
   Side-panel comparison table (R94 — v4 layout)
   ════════════════════════════════════════════════════════════════════════
   Structure: 4-column grid, 4 rows.
     Row 1 (head):  [ROUTE] [€] [KM] [TIME]      ← column headers, mono caps
     Row 2 (delta): [Διαφορά]  [−€X] [+Y] [+Z λ] ← soft green tint band
     Row 3:         [Motorway · 22 μετωπ.]  [€58.55] [879] [8h 38m]
     Row 4:         [Bypasses · 16 μετωπ. + 5 πλευρ.]  [€39.00] [903] [9h 38m]

   The toll counts now flow INSIDE the row label cell on a single line per
   row — much more legible than the old 5th tag column that ate space at
   the right edge. Numbers are right-aligned and tabular so columns scan
   cleanly top-to-bottom. The Δ row sits at the top with a tinted background
   so its cells visually align over their corresponding data cells below.
   ════════════════════════════════════════════════════════════════════════ */
/* ════════════════════════════════════════════════════════════════════════
   R98 — Desktop hero block
   ════════════════════════════════════════════════════════════════════════
   Anchors the user's eye on the recommended trip cost before they read
   the comparison table. Mirrors the mobile hero structure (.rp-hero +
   .rp-vs) so both viewports use the same emphasis pattern, but lives
   inside .rp-cmp's grid as a row that spans all columns. Hidden on
   mobile via the parent .rp-cmp's display:none.
   ════════════════════════════════════════════════════════════════════════ */

.rp-desktop-hero {
  grid-column: 1 / -1;        /* span across all 4 grid columns */
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 4px 0 14px;
  border-bottom: 1px solid var(--line);
  margin-bottom: 4px;
}
.rp-desktop-hero-cost {
  font-family: var(--font-display);
  font-size: var(--text-hero);
  font-weight: var(--weight-regular);
  letter-spacing: -0.025em;
  color: var(--ink);
  line-height: 1.05;
  font-variant-numeric: tabular-nums;
}
.rp-desktop-hero-sub {
  font-size: var(--text-sm);
  color: var(--ink-2);
  font-variant-numeric: tabular-nums;
}
.rp-desktop-hero-vs {
  background: var(--save-bg, #e8f3ec);
  border-radius: 10px;
  padding: 8px 12px;
  display: flex;
  align-items: baseline;
  gap: 8px;
  flex-wrap: wrap;
  font-size: var(--text-sm);
  color: #1f5a35;
  margin-top: 4px;
  width: fit-content;
}
.rp-desktop-hero-vs-label {
  font-weight: var(--weight-medium);
}
.rp-desktop-hero-vs-amt {
  font-weight: var(--weight-semibold);
  font-variant-numeric: tabular-nums;
  font-size: var(--text-lg);
  color: #1f5a35;
}
.rp-desktop-hero-vs-cmp {
  color: #2d7a3a;
  font-weight: var(--weight-medium);
  font-size: var(--text-caption);
}

.rp-cmp {
  display: grid;
  grid-template-columns: 1fr auto auto auto;
  column-gap: 16px;
  row-gap: 6px;
  align-items: baseline;
  flex: 1;
  min-width: 0;
}
.rp-cmp-row { display: contents; }

/* ── Header row (column labels) ─────────────────────────────── */
.rp-cmp-row.head .rp-cmp-label,
.rp-cmp-row.head .rp-cmp-money,
.rp-cmp-row.head .rp-cmp-dist,
.rp-cmp-row.head .rp-cmp-time {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  font-weight: var(--weight-semibold);
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  padding-bottom: 4px;
  border-bottom: 1px solid var(--line);
  margin-bottom: 4px;
  text-align: right;
  display: block;       /* override the flex-with-counts layout for the header */
}
.rp-cmp-row.head .rp-cmp-label { text-align: left; }

/* ── Δ row ──────────────────────────────────────────────────── */
.rp-cmp-row.delta .rp-cmp-label,
.rp-cmp-row.delta .rp-cmp-money,
.rp-cmp-row.delta .rp-cmp-dist,
.rp-cmp-row.delta .rp-cmp-time {
  background: rgba(232, 243, 236, 0.6);     /* soft green wash */
  padding-top: 7px;
  padding-bottom: 8px;
  border-bottom: 1px solid rgba(45, 132, 81, 0.18);
  margin-bottom: 6px;
}
/* Neutral variant — when the route has no AVOIDs, the Δ row becomes
   informational rather than celebratory. */
.rp-cmp-row.delta--neutral .rp-cmp-label,
.rp-cmp-row.delta--neutral .rp-cmp-money,
.rp-cmp-row.delta--neutral .rp-cmp-dist,
.rp-cmp-row.delta--neutral .rp-cmp-time {
  background: var(--paper-2, #faf7f0);
  border-bottom-color: var(--line);
}
.rp-cmp-row.delta .rp-cmp-label .rp-cmp-label-name {
  font-weight: var(--weight-semibold);
  color: var(--ink);
}
.rp-cmp-row.delta .rp-cmp-money {
  color: #2d8451;       /* green — savings */
  font-weight: var(--weight-semibold);
}
.rp-cmp-row.delta--neutral .rp-cmp-money {
  color: var(--ink-2);
  font-style: italic;
  font-weight: var(--weight-medium);
}
.rp-cmp-row.delta .rp-cmp-dist,
.rp-cmp-row.delta .rp-cmp-time {
  color: #b34d2a;       /* warm-orange — extras (cost of bypassing) */
  font-weight: var(--weight-semibold);
}
.rp-cmp-row.delta--neutral .rp-cmp-dist,
.rp-cmp-row.delta--neutral .rp-cmp-time {
  color: var(--muted);
  font-weight: var(--weight-medium);
}

/* ── Standard data rows (Motorway / Bypasses) ───────────────── */
/* Label cell becomes a flex container so the row name + toll count
   chip can flow inline. Wraps to a second line on very narrow viewports. */
.rp-cmp-label {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  color: var(--ink-2);
  font-weight: var(--weight-medium);
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 6px;
  min-width: 0;
  padding: 0 8px;
}
.rp-cmp-label-name {
  font-weight: var(--weight-medium);
  color: var(--ink-2);
  white-space: nowrap;
}
.rp-cmp-label-count {
  font-family: var(--font-mono);
  font-size: var(--text-caption);
  color: var(--muted);
  letter-spacing: 0.02em;
  font-weight: var(--weight-medium);
}
.rp-cmp-label-count strong {
  font-family: var(--font-body);
  color: var(--ink);
  font-weight: var(--weight-semibold);
  font-variant-numeric: tabular-nums;
}
.rp-cmp-label-sep {
  color: var(--muted);
  opacity: 0.4;
}

.rp-cmp-money {
  font-family: var(--font-body);
  font-weight: var(--weight-semibold);
  font-size: var(--text-base);
  text-align: right;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
  letter-spacing: -0.01em;
  padding: 0 8px;
  white-space: nowrap;
}
.rp-cmp-dist, .rp-cmp-time {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  text-align: right;
  font-variant-numeric: tabular-nums;
  color: var(--ink-2);
  font-weight: var(--weight-medium);
  white-space: nowrap;
  padding: 0 8px;
}
/* R74: km cell may carry a `title` tooltip with the motorway breakdown
   for the bypass row. The dotted underline is a discreet cue that
   there's more info on hover — same convention as <abbr>. */
.rp-cmp-dist[title] {
  text-decoration: underline dotted var(--muted);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  cursor: help;
}

/* ════════════════════════════════════════════════════════════════════════
   R96 — Fuel cost UI (desktop comparison table)
   ════════════════════════════════════════════════════════════════════════
   Three additions, ALL conditional on settings.fuelEnabled (the JS
   simply doesn't render these elements when fuel is off):
     1. .rp-cmp-money-sub — a small purple mono "+ €X καύσιμο" line
        sitting under the toll cost in each money cell. Discreet — does
        not compete with the primary toll number.
     2. .rp-cmp-row.total — a bottom row showing combined toll + fuel
        for the recommended scenario. Bold money figure with a small
        scenario-name caption next to the label.
     3. (mobile counterparts handled below)
   ════════════════════════════════════════════════════════════════════════ */

.rp-cmp-money-sub {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  font-weight: var(--weight-medium);
  color: #8a5cb5;                       /* purple — fuel theme */
  font-variant-numeric: tabular-nums;
  margin-top: 1px;
  letter-spacing: 0.01em;
}

.rp-cmp-row.total .rp-cmp-label,
.rp-cmp-row.total .rp-cmp-money,
.rp-cmp-row.total .rp-cmp-dist,
.rp-cmp-row.total .rp-cmp-time {
  border-top: 1px dashed var(--line);
  padding-top: 8px;
  margin-top: 4px;
}
.rp-cmp-row.total .rp-cmp-label-name {
  font-weight: var(--weight-semibold);
  color: var(--ink);
}
.rp-cmp-row.total .rp-cmp-label-count {
  font-style: italic;
}
.rp-cmp-row.total .rp-cmp-money {
  font-weight: var(--weight-bold);
  font-size: var(--text-base);
}

/* ════════════════════════════════════════════════════════════════════════
   R96 — Mobile fuel breakdown block (.rp-mob-fuel)
   ════════════════════════════════════════════════════════════════════════
   Sits between the green "vs" card and the "Αναλυτικά" details disclosure
   when fuel is on. Shows the toll + fuel breakdown for the recommended
   scenario and the formula that produced the fuel number — so the user
   trusts the math.
   ════════════════════════════════════════════════════════════════════════ */

.rp-mob-fuel {
  background: var(--paper-2, #faf7f0);
  border-radius: 10px;
  border-left: 3px solid var(--ink, #1a1f2e);
  padding: 10px 12px;
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.rp-mob-fuel-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-size: var(--text-sm);
}
.rp-mob-fuel-row span {
  color: var(--ink-2);
}
.rp-mob-fuel-row strong {
  font-weight: var(--weight-semibold);
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.rp-mob-fuel-row + .rp-mob-fuel-formula {
  margin-top: 4px;
}
.rp-mob-fuel-formula {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.01em;
}

.rp-close {
  margin-left: auto;
  background: transparent;
  border: 1px solid var(--line);
  color: var(--muted);
  cursor: pointer;
  font-size: var(--text-sm);
  line-height: 1;
  padding: 6px 9px;
  border-radius: var(--radius-pill);
  transition: all 0.15s var(--ease);
  flex-shrink: 0;
}
.rp-close:hover { background: var(--stop-bg); border-color: var(--stop); color: var(--stop); }

/* Take-away action buttons (print, download). Sit in the header next to
   the close button. Quiet outlined style — they're secondary actions, the
   primary focus is the toll-list content below. R45: previously unstyled
   and rendering with browser-default chunky chrome that clashed with the
   rest of the panel. Now match the design vocabulary of .rp-close + the
   floating panel — 1px border, subtle hover, tabular-numeric padding. */
.rp-actions {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-left: auto;
  flex-shrink: 0;
}
.rp-action {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  background: transparent;
  border: 1px solid var(--line);
  color: var(--ink-2);
  cursor: pointer;
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  line-height: 1;
  padding: 6px 10px;
  border-radius: var(--radius-pill);
  transition: all 0.15s var(--ease);
  white-space: nowrap;
}
.rp-action:hover {
  background: var(--aegean-lt);
  border-color: var(--aegean);
  color: var(--aegean);
}
.rp-action svg { flex-shrink: 0; }

/* R77: Print-mode segmented control. Two-state toggle (Full / Summary)
   styled as a compact pill with a sliding indicator. The actual radio
   inputs are visually hidden but kept in the tab order for keyboard
   navigation; the labels carry the visual styling and click handlers. */
.rp-print-mode {
  display: inline-flex;
  align-items: center;
  background: var(--paper-2, #faf7f0);
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  padding: 2px;
  font-family: var(--font-body);
  font-size: var(--text-caption);
  font-weight: var(--weight-medium);
  flex-shrink: 0;
}
.rp-print-mode input[type="radio"] {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0,0,0,0);
  white-space: nowrap;
  border: 0;
}
.rp-print-mode label {
  display: inline-block;
  padding: 3px 8px;
  border-radius: var(--radius-pill);
  color: var(--ink-2);
  cursor: pointer;
  user-select: none;
  transition: background 0.15s var(--ease), color 0.15s var(--ease);
  white-space: nowrap;
  line-height: 1;
}
.rp-print-mode input[type="radio"]:checked + label {
  background: var(--ink, #1a1f2e);
  color: var(--paper, #faf8f3);
}
.rp-print-mode input[type="radio"]:focus-visible + label {
  outline: 2px solid var(--aegean);
  outline-offset: 2px;
}
/* When .rp-actions is followed by .rp-close, drop margin-left:auto on
   .rp-actions so they stack inline cleanly to the right of .rp-stats. */
.rp-head .rp-actions + .rp-close { margin-left: 0; }

.rp-body {
  flex: 1;
  overflow-y: auto;
  padding: 0;
}
.rp-body::-webkit-scrollbar { width: 6px; }
.rp-body::-webkit-scrollbar-thumb { background: var(--line-strong); border-radius: var(--radius-sm); }

/* AI advice — prominent at top */
.rp-advice {
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: 1.5;
  color: var(--ink);
  background: linear-gradient(135deg, var(--aegean-lt) 0%, rgba(196,151,32,0.08) 100%);
  border-left: 3px solid var(--aegean);
  padding: 14px 22px;
  margin: 0;
  letter-spacing: -0.005em;
}

/* Toll chips section */
.rp-chips {
  padding: 14px 22px 18px;
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  align-content: flex-start;
}

/* TOLL CHIPS */
.toll-chip {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 12px;
  border-radius: var(--radius);
  border-left: 3px solid;
  background: var(--paper-2);
  border-top: 1px solid var(--line);
  border-right: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  font-size: var(--text-sm);
  cursor: pointer;
  transition: box-shadow 0.18s var(--ease), transform 0.1s;
  flex-wrap: wrap;
  /* Expanded chips share a consistent width so multiple tile cleanly per
     row. Narrow enough to fit 3 across at desktop; wraps gracefully on
     mobile via the parent's flex-wrap. */
  flex: 0 1 320px;
  max-width: 360px;
  min-width: 260px;
}
.toll-chip:hover { box-shadow: var(--shadow); transform: translateY(-1px); }
.toll-chip.verdict-PAY            { border-left-color: var(--stop); }
.toll-chip.verdict-AVOID          { border-left-color: var(--go); }
.toll-chip.verdict-MARGINAL_AVOID { border-left-color: var(--go-soft); }
.toll-chip.verdict-MARGINAL_PAY   { border-left-color: var(--stop-soft); }

.chip-name {
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  font-size: var(--text-sm);
  color: var(--ink);
  letter-spacing: -0.015em;
}
.chip-price {
  font-family: var(--font-mono);
  font-size: var(--text-caption);
  color: var(--muted);
}
.chip-verdict {
  font-family: var(--font-body);
  font-size: var(--text-micro);
  font-weight: var(--weight-bold);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 2px 7px;
  border-radius: var(--radius-sm);
}
.verdict-PAY            .chip-verdict { background: var(--stop-bg);  color: var(--stop); }
.verdict-AVOID          .chip-verdict { background: var(--go-bg);    color: var(--go); }
.verdict-MARGINAL_AVOID .chip-verdict { background: var(--go-soft-bg);   color: var(--go-soft); }
.verdict-MARGINAL_PAY   .chip-verdict { background: var(--stop-soft-bg); color: var(--stop-soft); }
.chip-reason {
  display: none;
  width: 100%;
  padding-top: 7px;
  border-top: 1px dashed var(--line);
  margin-top: 4px;
}
/* Compact 3-row money/dist/time comparison inside each chip when expanded.
   Same conceptual layout as the side panel and the analyze stats header,
   but smaller and tighter to fit inline within a chip.
   First row is the column-headers strip (€ · χλμ · λεπ) which lets data
   cells drop unit suffixes for tighter columns. */
.chip-cmp {
  display: grid;
  grid-template-columns: 1fr auto auto auto;
  column-gap: 7px;
  row-gap: 2px;
  align-items: center;
  font-family: var(--font-body);
  width: 100%;
}
/* R89: while Mapbox is fetching the real bypass route, mark the chip's
   distance cells as "refining" so the user knows the haversine-estimate
   km values are placeholders that will update. Subtle pulse on opacity
   — not a spinner (would be too loud for a 200-500ms operation), just
   enough motion to signal "this is in flight." Cleared per-chip when
   its route resolves. */
.chip-cmp[data-refining="1"] .chip-cmp-dist {
  animation: chip-refining-pulse 1.2s ease-in-out infinite;
}
@keyframes chip-refining-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.45; }
}
/* Honor user prefers-reduced-motion: drop the animation, just show
   muted color so the signal still exists without movement. */
@media (prefers-reduced-motion: reduce) {
  .chip-cmp[data-refining="1"] .chip-cmp-dist {
    animation: none;
    opacity: 0.55;
  }
}
.chip-cmp-row { display: contents; }
.chip-cmp-row.chip-cmp-head > * {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  font-weight: var(--weight-semibold);
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding-bottom: 4px;
  border-bottom: 1px solid var(--line);
  margin-bottom: 3px;
  text-align: right;
}
.chip-cmp-h-blank { /* corner cell — keeps grid alignment without text */ }
.chip-cmp-label {
  font-size: var(--text-caption);
  color: var(--ink-2);
  font-weight: var(--weight-medium);
}
/* Inline exit→entry text appended to the Παράκαμψη label.
   Smaller and muted so the row's main weight stays on the label/numbers. */
.chip-cmp-route {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  color: var(--muted);
  font-weight: var(--weight-regular);
  margin-left: 6px;
  letter-spacing: 0;
}
.chip-cmp-money {
  font-weight: var(--weight-semibold);
  font-size: var(--text-sm);
  text-align: right;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
  letter-spacing: -0.01em;
}
.chip-cmp-dist, .chip-cmp-time {
  font-family: var(--font-mono);
  font-size: var(--text-caption);
  text-align: right;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
  font-weight: var(--weight-medium);
  white-space: nowrap;
}
.chip-cmp-row.diff > * {
  padding-top: 4px;
  border-top: 1px dashed var(--line);
  margin-top: 3px;
}
.chip-cmp-row.diff .chip-cmp-label { font-weight: var(--weight-semibold); color: var(--ink); }
.chip-cmp .savings { color: #2d7a3a; }
.chip-cmp .cost    { color: #a45533; }
.chip-cmp .zero    { color: var(--muted); }
.chip-tags {
  margin-top: 6px;
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  color: var(--muted);
  letter-spacing: 0;
  width: 100%;
}
.chip-tags-noby {
  font-style: italic;
  font-family: var(--font-display);
}

/* LEAFLET POPUPS */
.leaflet-popup-content-wrapper {
  background: var(--paper) !important;
  border: 1px solid var(--line-strong) !important;
  border-radius: var(--radius) !important;
  box-shadow: var(--shadow-lg) !important;
  padding: 0 !important;
}
.leaflet-popup-content { margin: 0 !important; font-family: var(--font-body) !important; }
.leaflet-popup-tip { background: var(--paper) !important; }
.leaflet-popup-close-button {
  color: var(--muted) !important;
  font-size: var(--text-base) !important;
  padding: 5px 7px !important;
  top: 2px !important; right: 2px !important;
}
.map-popup { padding: 11px 13px; min-width: 170px; }
.map-popup-name {
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  font-size: var(--text-base);
  color: var(--ink);
  margin-bottom: 4px;
  letter-spacing: -0.015em;
}
.map-popup-verdict {
  font-family: var(--font-body);
  font-size: var(--text-micro);
  font-weight: var(--weight-bold);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  margin-bottom: 5px;
}
.map-popup-verdict.PAY            { color: var(--stop); }
.map-popup-verdict.AVOID          { color: var(--go); }
.map-popup-verdict.MARGINAL_AVOID { color: var(--go-soft); }
.map-popup-verdict.MARGINAL_PAY   { color: var(--stop-soft); }
.map-popup-reason {
  font-family: var(--font-display);
  font-style: italic;
  font-size: var(--text-caption);
  color: var(--ink-2);
  line-height: 1.5;
}

/* Tooltips on bypass routes */
.bypass-tooltip {
  background: var(--paper) !important;
  border: 1px solid var(--line-strong) !important;
  color: var(--ink) !important;
  font-family: var(--font-body) !important;
  font-size: var(--text-caption) !important;
  border-radius: var(--radius) !important;
  box-shadow: var(--shadow) !important;
  padding: 6px 10px !important;
}
.bypass-tooltip::before { display: none !important; }
.ramp-tooltip {
  background: var(--paper) !important;
  border: 1px solid var(--line-strong) !important;
  color: var(--ink) !important;
  font-family: var(--font-body) !important;
  font-size: var(--text-caption) !important;
  border-radius: var(--radius) !important;
  box-shadow: var(--shadow) !important;
  padding: 6px 10px !important;
}
.ramp-tooltip::before { display: none !important; }

/* ══════════════════════════════════════
   HELP POPOVER + OVERFLOW MENU
   ══════════════════════════════════════ */

/* Overflow menu (··· in topbar) — folds rare actions (help, feedback) into
   a single dropdown so they stop competing with primary nav. Mirrors the
   .veh-toggle/.veh-menu pattern for visual consistency. */
.overflow-toggle {
  position: relative;
  display: inline-block;
  font-family: var(--font-body);
}
.overflow-trigger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 6px 10px;
  cursor: pointer;
}
.overflow-trigger[aria-expanded="true"] {
  background: var(--paper-2);
  border-color: var(--ink-3);
  color: var(--ink);
}
.overflow-trigger svg {
  flex-shrink: 0;
  opacity: 0.75;
  transition: opacity 0.15s var(--ease);
}
.overflow-trigger:hover svg,
.overflow-trigger[aria-expanded="true"] svg { opacity: 1; }

.overflow-menu {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  min-width: 170px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: 0 8px 24px rgba(26,31,46,0.12), 0 2px 6px rgba(26,31,46,0.06);
  padding: 4px;
  z-index: 1000;
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.overflow-menu[hidden] { display: none; }
.overflow-option {
  display: flex;
  align-items: center;
  gap: 10px;
  background: transparent;
  border: none;
  padding: 9px 12px;
  font-size: var(--text-sm);
  font-family: var(--font-body);
  color: var(--ink);
  text-align: left;
  border-radius: var(--radius-sm);
  cursor: pointer;
  text-decoration: none;
  transition: background 0.12s var(--ease);
}
.overflow-option:hover { background: var(--aegean-lt); }
.overflow-option svg {
  flex-shrink: 0;
  opacity: 0.7;
  color: var(--ink-2);
}
.overflow-option:hover svg { opacity: 1; }

/* Help popover — replaces the previous full-screen help-modal. Anchored
   below the overflow trigger (positioned by JS via getBoundingClientRect
   so it works even though help-popover sits at <body> level rather than
   inside .overflow-toggle). Sections are <details> for native disclosure. */
.help-popover {
  position: fixed;
  width: 320px;
  max-height: calc(100dvh - 80px);
  overflow-y: auto;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: 0 14px 40px rgba(26,31,46,0.18), 0 4px 10px rgba(26,31,46,0.08);
  padding: 14px 16px 16px;
  z-index: 1500;
  font-family: var(--font-body);
  animation: help-popover-in 0.18s var(--ease-out) backwards;
}
.help-popover[hidden] { display: none; }
@keyframes help-popover-in {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}
.help-popover-arrow {
  position: absolute;
  top: -7px;
  width: 14px;
  height: 14px;
  background: var(--paper);
  border-left: 1px solid var(--line);
  border-top: 1px solid var(--line);
  transform: rotate(45deg);
  /* Horizontal position set inline by JS to point at the trigger center. */
}
.help-popover-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding-bottom: 10px;
  margin-bottom: 6px;
  border-bottom: 1px solid var(--line);
}
.help-popover-title {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: var(--weight-regular);
  font-size: var(--text-base);
  color: var(--ink-2);
}
.help-popover-close {
  background: transparent;
  border: none;
  color: var(--muted);
  cursor: pointer;
  font-size: var(--text-base);
  padding: 4px 8px;
  border-radius: var(--radius-sm);
  transition: color 0.15s var(--ease), background 0.15s var(--ease);
}
.help-popover-close:hover {
  color: var(--ink);
  background: var(--paper-2);
}

.help-section-d {
  margin: 8px 0;
  padding: 0;
}
.help-section-d + .help-section-d {
  border-top: 1px solid var(--line);
  padding-top: 10px;
  margin-top: 10px;
}
.help-section-summary {
  display: flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
  list-style: none;
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  font-size: var(--text-base);
  color: var(--ink);
  letter-spacing: -0.01em;
  padding: 4px 0;
}
.help-section-summary::-webkit-details-marker { display: none; }
.help-section-summary::marker { content: ''; }
.help-section-summary::after {
  content: '▾';
  margin-left: auto;
  font-size: var(--text-caption);
  color: var(--muted);
  transition: transform 0.18s var(--ease);
}
.help-section-d[open] .help-section-summary::after {
  transform: rotate(180deg);
}
.help-section-icon {
  font-size: var(--text-lg);
  color: var(--aegean);
  width: 22px;
  text-align: center;
  flex-shrink: 0;
}
.help-section-d-body {
  font-size: var(--text-sm);
  color: var(--ink-2);
  line-height: 1.55;
  padding: 8px 0 4px 32px;   /* indented under the summary icon */
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* Color-key chips inside section 2 — readable but not loud. The colors
   are taken from the verdict palette (avoid=green, pay=amber-red, marginal=
   amber). Pulled out of inline styles for cleaner markup. */
.help-legend-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 12px;
  margin-top: 6px;
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
}
.help-color-avoid    { color: #2d7a3a; }
.help-color-pay      { color: var(--stop); }
.help-color-marginal { color: #b8860b; }

/* ══════════════════════════════════════
   PAGE NAVIGATION (multi-page hash routing)
   ══════════════════════════════════════ */
.topbar-nav {
  display: flex;
  gap: 2px;
  margin-right: 16px;
  flex: 1;
  min-width: 0;
}
.nav-link {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: var(--weight-medium);
  font-size: var(--text-base);
  letter-spacing: -0.005em;
  color: var(--muted);
  padding: 6px 14px;
  cursor: pointer;
  border-radius: var(--radius);
  transition: all 0.18s var(--ease);
  text-decoration: none;
  white-space: nowrap;
  font-variation-settings: "opsz" 144, "SOFT" 60;
}
.nav-link:hover {
  background: var(--paper-2);
  color: var(--ink);
}
.nav-link.active {
  background: var(--aegean-lt);
  color: var(--aegean-dark);
  font-weight: var(--weight-semibold);
}

.page {
  display: none;
}
.page.page-active {
  display: block;
}

/* When the map page is inactive, hide its fixed-position descendants */
#page-map:not(.page-active) #legend,
#page-map:not(.page-active) #toll-side-panel,
#page-map:not(.page-active) #results-panel,
#page-map:not(.page-active) #bottom-bar,
#page-map:not(.page-active) #first-tip,
#page-map:not(.page-active) #map-container { display: none; }
#page-routes,
#page-tolls,
#page-about {
  position: fixed;
  top: var(--topbar-h);
  left: 0; right: 0; bottom: 0;
  overflow-y: auto;
  background: var(--paper);
}
#page-routes::-webkit-scrollbar,
#page-tolls::-webkit-scrollbar,
#page-about::-webkit-scrollbar { width: 8px; }
#page-routes::-webkit-scrollbar-thumb,
#page-tolls::-webkit-scrollbar-thumb,
#page-about::-webkit-scrollbar-thumb { background: var(--line-strong); border-radius: var(--radius); }

.page-content {
  max-width: 1200px;
  margin: 0 auto;
  padding: 36px 32px 60px;
}
.page-header { margin-bottom: 28px; }
.page-title {
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  font-size: 2.4rem;
  letter-spacing: -0.025em;
  color: var(--ink);
  line-height: 1.05;
  margin-bottom: 6px;
  font-variation-settings: "opsz" 144, "SOFT" 30;
}
.page-subtitle {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: var(--weight-regular);
  font-size: var(--text-base);
  color: var(--muted);
  letter-spacing: 0.005em;
  font-variation-settings: "opsz" 144, "SOFT" 80;
}

.page-toolbar {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 24px;
  padding: 14px 16px;
  background: var(--paper-2);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
}
.page-toolbar-label {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: var(--weight-regular);
  font-size: var(--text-sm);
  color: var(--muted);
  letter-spacing: 0.005em;
}
.page-toolbar .bar-input { flex: 1; min-width: 200px; }
.page-toolbar .bar-select { min-width: 180px; }

/* ── Routes matrix ── */
/* ── R70: Routes-page filter UI ─────────────────────────────
   The "Από / Προς / Καθαρισμός" row above the routes grid. The selects
   were getting only default browser styling (~20px wide for empty
   content) — proper sizing makes them usable. */
.routes-filter {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 14px;
}
.rfilter-row {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.rfilter-label {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  color: var(--ink-2);
  font-weight: var(--weight-medium);
}
.rfilter-select {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  padding: 6px 28px 6px 10px;
  /* Use a custom arrow so the select looks consistent across browsers
     and matches our other controls. The native arrow is hidden via
     appearance: none and we paint our own with a background SVG. */
  appearance: none;
  -webkit-appearance: none;
  background: var(--paper) url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'><path d='M1 1l5 5 5-5' stroke='%231a1f2e' stroke-width='1.6' fill='none' stroke-linecap='round' stroke-linejoin='round'/></svg>") no-repeat right 9px center / 10px 7px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  color: var(--ink);
  cursor: pointer;
  min-width: 160px;
  height: 32px;
  transition: border-color 0.15s var(--ease), background-color 0.15s var(--ease);
}
.rfilter-select:hover {
  border-color: var(--aegean);
}
.rfilter-select:focus-visible {
  outline: 2px solid var(--aegean);
  outline-offset: 2px;
  border-color: var(--aegean);
}
.rfilter-swap, .rfilter-clear {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  color: var(--ink-2);
  cursor: pointer;
  height: 32px;
  padding: 0 12px;
  transition: background-color 0.15s var(--ease),
              border-color     0.15s var(--ease),
              color            0.15s var(--ease);
}
.rfilter-swap {
  width: 32px;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.rfilter-swap:hover, .rfilter-clear:hover {
  background: var(--aegean-lt);
  border-color: var(--aegean);
  color: var(--aegean);
}
.routes-filter-summary {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  color: var(--ink-2);
}

/* Mobile: stack the row tighter, give selects more width. */
@media (max-width: 640px) {
  .rfilter-row { gap: 6px; }
  .rfilter-select { flex: 1 1 120px; min-width: 0; }
}

.routes-grid {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow-x: auto;
  overflow-y: visible;
  box-shadow: var(--shadow-sm);
  -webkit-overflow-scrolling: touch;
}
.routes-grid::-webkit-scrollbar { height: 8px; }
.routes-grid::-webkit-scrollbar-thumb { background: var(--line-strong); border-radius: var(--radius); }
.routes-grid-table {
  border-collapse: collapse;
  font-family: var(--font-body);
  font-size: var(--text-sm);
  /* No fixed width - let columns size naturally */
}
.routes-grid-table th,
.routes-grid-table td {
  padding: 6px 9px;
  text-align: center;
  border-right: 1px solid rgba(0,0,0,0.04);
  border-bottom: 1px solid rgba(0,0,0,0.04);
  vertical-align: middle;
}
.routes-grid-table thead th {
  position: sticky; top: 0;
  background: var(--paper-2);
  font-family: var(--font-body);
  font-weight: var(--weight-semibold);
  font-size: var(--text-caption);
  color: var(--ink);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  white-space: nowrap;
  z-index: 5;
  height: 44px;
}
.routes-grid-table thead th.routes-corner {
  background: var(--paper-2);
  z-index: 6;
}
.routes-grid-table tbody th {
  position: sticky; left: 0;
  background: var(--paper-2);
  font-family: var(--font-body);
  font-weight: var(--weight-semibold);
  font-size: var(--text-caption);
  color: var(--ink);
  text-align: left;
  padding-left: 12px;
  white-space: nowrap;
  border-right: 1px solid var(--line);
  z-index: 4;
}
.routes-cell {
  cursor: pointer;
  transition: background 0.12s, filter 0.12s;
  min-width: 92px;
}
.routes-cell:hover { filter: brightness(0.96); }
/* R63: heatmap tier classes — soft tints that progress from green
   (cheap per km) through yellow to terracotta (expensive). Tints kept
   gentle so the cell text stays comfortably readable. */
.routes-cell.rc-tier-0 { background: rgba(46, 122, 74, 0.10); }   /* free */
.routes-cell.rc-tier-1 { background: rgba(46, 122, 74, 0.07); }   /* ≤0.03 */
.routes-cell.rc-tier-2 { background: rgba(196, 158, 26, 0.08); }  /* ≤0.06 */
.routes-cell.rc-tier-3 { background: rgba(184, 80, 45, 0.08); }   /* ≤0.09 */
.routes-cell.rc-tier-4 { background: rgba(184, 80, 45, 0.16); }   /* >0.09 */

/* R63: heatmap legend — color-coded stops matching the cell tier tints.
   Lives above the routes-grid table; gives users a quick reference for
   what each cell's color means in €/km terms. */
.routes-legend {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin: 12px 0 18px 0;
  font-family: var(--font-body);
  font-size: var(--text-sm);
  color: var(--ink-2);
}
.routes-legend .rl-title {
  font-weight: var(--weight-semibold);
  color: var(--ink);
  margin-right: 4px;
}
.routes-legend .rl-scale {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  flex-wrap: wrap;
}
.routes-legend .rl-stop {
  display: inline-flex;
  align-items: center;
  padding: 4px 10px;
  font-family: var(--font-mono);
  font-size: var(--text-caption);
  color: var(--ink);
  border: 1px solid rgba(0, 0, 0, 0.06);
  border-radius: 999px;
  white-space: nowrap;
}
.routes-legend .tier-free  { background: rgba(46, 122, 74, 0.10); }
.routes-legend .tier-low   { background: rgba(46, 122, 74, 0.07); }
.routes-legend .tier-mid   { background: rgba(196, 158, 26, 0.16); }
.routes-legend .tier-high  { background: rgba(184, 80, 45, 0.12); }
.routes-legend .tier-peak  { background: rgba(184, 80, 45, 0.22); }
.routes-cell-empty {
  background: repeating-linear-gradient(45deg, transparent, transparent 8px, rgba(0,0,0,0.02) 8px, rgba(0,0,0,0.02) 12px);
  cursor: default;
  pointer-events: none;
}
.routes-cell-self {
  background: rgba(0,0,0,0.04);
  cursor: default;
  pointer-events: none;
}
.routes-cell .rc-price {
  font-family: var(--font-body);
  font-weight: var(--weight-bold);
  font-size: var(--text-base);
  letter-spacing: -0.02em;
  color: var(--ink);
  line-height: 1.1;
}
.routes-cell .rc-meta {
  font-family: var(--font-body);
  font-size: var(--text-micro);
  color: var(--muted);
  margin-top: 2px;
  white-space: nowrap;
  letter-spacing: 0;
}
.routes-cell .rc-perkm {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  color: var(--aegean);
  margin-top: 1px;
  white-space: nowrap;
  font-weight: var(--weight-medium);
}
.routes-cell-na {
  font-family: var(--font-body);
  font-style: italic;
  font-size: var(--text-caption);
  color: var(--muted);
}

/* ── Tolls table ── */
.tolls-table-wrap {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  /* Horizontal scroll on narrow viewports — the table has 8 columns of
     data-dense content and tries hard to maintain readable widths;
     allow scroll rather than squish columns into illegibility on
     mobile. Vertical overflow stays clipped. */
  overflow-x: auto;
  overflow-y: hidden;
  box-shadow: var(--shadow-sm);
}
/* Mobile horizontal-scroll affordance: layered backgrounds reveal a soft
   gradient on the right edge when the table overflows offscreen. Uses
   the well-known "scrolling shadows" technique (Roman Komarov):
     • Two background layers per side (outer = "shadow cover", inner =
       gradient itself). The cover hides the gradient when there's no
       content beyond that edge.
     • background-attachment: local on the cover (scrolls with content),
       scroll on the gradient (stays at viewport edge).
     • At scroll-start the right-side cover moves left out of view,
       revealing the right-edge gradient → user sees "more →".
   Only the right side is shown (we don't need a left fade because the
   table starts at scroll-position 0 by default). */
@media (max-width: 640px) {
  .tolls-table-wrap {
    background:
      linear-gradient(to left, var(--paper), var(--paper) 70%, transparent) right center / 32px 100% no-repeat local,
      linear-gradient(to left, transparent, var(--paper-3) 0%, transparent 32px) right center / 32px 100% no-repeat scroll,
      var(--paper);
  }
}
.tolls-table {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--font-body);
  font-size: var(--text-sm);
  /* Fixed layout so per-column widths are honored exactly — needed for
     the four equal-width vehicle-price columns. With `auto`, longer
     prices like €33.70 expand individual cat columns and they stop
     looking aligned. */
  table-layout: fixed;
  /* Below this width, columns become unreadable. Triggers horizontal
     scroll in .tolls-table-wrap on mobile. */
  min-width: 760px;
}
.tolls-table thead th {
  background: var(--paper-2);
  padding: 12px 14px;
  text-align: left;
  font-family: var(--font-body);
  font-weight: var(--weight-semibold);
  font-size: var(--text-caption);
  color: var(--ink-2);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  border-bottom: 1px solid var(--line);
  cursor: pointer;
  white-space: nowrap;
  user-select: none;
  position: relative;
  transition: background 0.15s var(--ease), color 0.15s var(--ease);
}
.tolls-table thead th[data-sort]::after {
  content: ' ⇅';
  font-size: 0.85em;
  color: var(--ink-3);
  opacity: 0.45;
  margin-left: 4px;
  transition: opacity 0.15s var(--ease), color 0.15s var(--ease);
  letter-spacing: 0;
}
.tolls-table thead th[data-sort]:hover {
  background: var(--paper);
  color: var(--aegean-dark);
}
.tolls-table thead th[data-sort]:hover::after { opacity: 1; color: var(--aegean); }
.tolls-table thead th.sorted-asc {
  color: var(--aegean-dark);
  background: var(--aegean-lt);
}
.tolls-table thead th.sorted-asc::after  {
  content: ' ↑';
  color: var(--aegean);
  opacity: 1;
  font-weight: var(--weight-bold);
}
.tolls-table thead th.sorted-desc {
  color: var(--aegean-dark);
  background: var(--aegean-lt);
}
.tolls-table thead th.sorted-desc::after {
  content: ' ↓';
  color: var(--aegean);
  opacity: 1;
  font-weight: var(--weight-bold);
}
.tolls-table tbody tr {
  border-bottom: 1px solid rgba(0,0,0,0.05);
  transition: background 0.12s;
}
.tolls-table tbody tr:hover { background: var(--paper-2); }
.tolls-table tbody td {
  padding: 11px 14px;
  vertical-align: middle;
}
.tolls-table .tolls-name {
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  font-size: var(--text-base);
  color: var(--ink);
  letter-spacing: -0.015em;
  cursor: pointer;
  font-variation-settings: "opsz" 144, "SOFT" 30;
}
.tolls-table .tolls-name:hover { color: var(--aegean); text-decoration: underline; }

/* Per-column widths for table-layout: fixed. The four cat columns
   (3-6) are equal at 90px; the others get hand-tuned widths so their
   content (name, highway chip, bypass directions, verdict pill) fits
   without overflow. Total ≈ 1100px on a 1280px viewport. */
.tolls-table thead th:nth-child(1),
.tolls-table tbody td:nth-child(1) { width: 22%; }    /* Name */
.tolls-table thead th:nth-child(2),
.tolls-table tbody td:nth-child(2) { width: 13%; }    /* Highway */
.tolls-table thead th:nth-child(7),
.tolls-table tbody td:nth-child(7) { width: 14%; }    /* Bypass */
.tolls-table thead th:nth-child(8),
.tolls-table tbody td:nth-child(8) { width: 23%; }    /* Verdict */

/* Vehicle-price columns (cat1..cat4 = 3rd..6th columns). Equal width
   so the four prices align in a clean money-table grid; right-align
   the numbers since prices read better stacked on the right. */
.tolls-table thead th:nth-child(3),
.tolls-table thead th:nth-child(4),
.tolls-table thead th:nth-child(5),
.tolls-table thead th:nth-child(6),
.tolls-table tbody td:nth-child(3),
.tolls-table tbody td:nth-child(4),
.tolls-table tbody td:nth-child(5),
.tolls-table tbody td:nth-child(6) {
  width: 7%;
  padding-left: 6px;
  padding-right: 10px;
  text-align: right;
}
/* The sort-indicator pseudo-element sits on the right of the header
   text — pull it inline when right-aligned so it reads as part of the
   label rather than floating in trailing whitespace. */
.tolls-table thead th:nth-child(3)::after,
.tolls-table thead th:nth-child(4)::after,
.tolls-table thead th:nth-child(5)::after,
.tolls-table thead th:nth-child(6)::after {
  margin-left: 2px;
}
.tolls-table .tolls-hwy-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-mono);
  font-size: var(--text-caption);
  font-weight: var(--weight-medium);
  letter-spacing: 0.04em;
  color: var(--ink-2);
}
.tolls-table .tolls-hwy-dot {
  width: 9px; height: 9px;
  border-radius: 50%;
  flex-shrink: 0;
  box-shadow: 0 1px 2px rgba(26,31,46,0.2);
}
.tolls-table .tolls-price {
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  font-size: var(--text-base);
  letter-spacing: -0.015em;
  color: var(--ink);
  font-variation-settings: "opsz" 144;
  white-space: nowrap;
}
.tolls-table .tolls-bypass {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  color: var(--ink-2);
  white-space: nowrap;
}
.tolls-table .tolls-bypass-stack {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 3px;
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  color: var(--ink-2);
}
.tolls-table .tolls-bypass-line {
  white-space: nowrap;
  letter-spacing: -0.005em;
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
/* Confidence indicator inline with each bypass-direction line in the table.
   tbc-auto    = small subtle blue dot (data is reliable)
   tbc-approx  = amber warning glyph (verify before relying on this) */
.tolls-bypass-conf {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: var(--text-caption);
  cursor: help;
}
.tolls-bypass-conf.tbc-auto {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: rgba(42,107,158,0.5);
}
.tolls-bypass-conf.tbc-approx {
  color: #b8761a;
  font-weight: var(--weight-semibold);
}
.tolls-table .tolls-bypass-na {
  font-family: var(--font-display);
  font-style: italic;
  font-size: var(--text-sm);
  color: var(--muted);
}

/* ── Tolls page advisor toolbar additions ── */
.tolls-toolbar {
  flex-wrap: wrap;
  gap: 10px 14px;
}
.tolls-toolbar .toolbar-divider {
  width: 1px;
  height: 28px;
  background: var(--line);
  flex-shrink: 0;
}
.tolls-toolbar .bar-input { min-width: 180px; flex: 1 1 200px; }
.tolls-toolbar .bar-select { min-width: 140px; }
.tolls-toolbar #tolls-vehicle { min-width: 130px; }

.tolls-time-control {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  flex-shrink: 0;
  cursor: pointer;
  padding: 4px 8px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--paper);
  transition: border-color 0.15s var(--ease), box-shadow 0.15s var(--ease);
}
.tolls-time-control:hover,
.tolls-time-control:focus-within {
  border-color: var(--aegean);
  box-shadow: 0 0 0 3px rgba(42,107,158,0.08);
}
.tolls-time-label {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: var(--weight-regular);
  font-size: var(--text-sm);
  color: var(--muted);
  letter-spacing: 0.005em;
  white-space: nowrap;
}
.tolls-time-pill {
  display: inline-flex;
  align-items: baseline;
  gap: 4px;
  padding: 4px 10px;
  background: var(--aegean);
  color: var(--paper);
  border-radius: var(--radius-pill);
  box-shadow: 0 1px 3px rgba(42,107,158,0.3);
  white-space: nowrap;
  font-family: var(--font-body);
}
.tolls-time-pill .tolls-time-num {
  font-weight: var(--weight-bold);
  font-size: var(--text-base);
  letter-spacing: -0.025em;
  min-width: 14px;
  text-align: center;
}
.tolls-time-pill .tolls-time-suffix {
  font-size: var(--text-caption);
  font-weight: var(--weight-medium);
  opacity: 0.85;
  letter-spacing: 0.005em;
}
.tolls-time-slider {
  width: 150px;
  height: 8px;
  flex-shrink: 0;
  -webkit-appearance: none;
  appearance: none;
  background: linear-gradient(
    to right,
    var(--aegean) 0%,
    var(--aegean) var(--fill, 50%),
    rgba(42,107,158,0.18) var(--fill, 50%),
    rgba(42,107,158,0.18) 100%
  );
  border-radius: var(--radius);
  cursor: grab;
  outline: none;
  border: none;
  box-shadow: inset 0 1px 2px rgba(0,0,0,0.10);
}
.tolls-time-slider:active { cursor: grabbing; }
.tolls-time-slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 20px; height: 20px;
  background: var(--paper);
  border: 3px solid var(--aegean);
  border-radius: 50%;
  cursor: grab;
  box-shadow: 0 2px 5px rgba(42,107,158,0.45), 0 0 0 1px rgba(255,255,255,0.6) inset;
  transition: transform 0.12s var(--ease);
}
.tolls-time-slider::-webkit-slider-thumb:hover { transform: scale(1.15); }
.tolls-time-slider:active::-webkit-slider-thumb { cursor: grabbing; transform: scale(1.18); }
.tolls-time-slider::-moz-range-thumb {
  width: 20px; height: 20px;
  background: var(--paper);
  border: 3px solid var(--aegean);
  border-radius: 50%;
  cursor: grab;
  box-shadow: 0 2px 5px rgba(42,107,158,0.45);
}
.tolls-time-slider::-moz-range-progress {
  background: var(--aegean);
  border-radius: var(--radius);
  height: 8px;
}
.tolls-time-slider::-moz-range-track {
  background: rgba(42,107,158,0.18);
  border-radius: var(--radius);
  height: 8px;
}

.tolls-avoid-toggle {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--ink-2);
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
}
.tolls-avoid-toggle input[type="checkbox"] {
  width: 16px;
  height: 16px;
  margin: 0;
  cursor: pointer;
  accent-color: var(--go);
}
.tolls-avoid-toggle:hover { color: var(--ink); }

.tolls-count {
  margin-left: auto;
  font-family: var(--font-display);
  font-style: italic;
  font-weight: var(--weight-regular);
  font-size: var(--text-sm);
  color: var(--muted);
  white-space: nowrap;
  letter-spacing: 0.005em;
}

/* Active vehicle column gets a subtle highlight in the price cells.
   Quiet — the verdict column does the loud signaling. */
.tolls-table .tolls-price.active {
  color: var(--aegean-dark);
  text-shadow: 0 0 0.5px rgba(42,107,158,0.25);
}
/* Stronger active-column treatment: tint the whole cell background +
   left border so the column visually stands out from its neighbors.
   Header gets the same treatment so the column-strip reads as a unit
   from top to bottom. Uses :has() (Chrome/Safari/Edge/Firefox 2022+);
   gracefully degrades to just the text-color rule above. */
.tolls-table tbody td:has(.tolls-price.active) {
  background: rgba(42, 107, 158, 0.06);
  box-shadow: inset 1px 0 0 rgba(42, 107, 158, 0.18);
}
/* Data-driven header highlight: the renderer sets data-active="true" on
   the header that matches the active vehicle (set in pages.js). */
.tolls-table thead th[data-active="true"] {
  background: rgba(42, 107, 158, 0.10);
  color: var(--aegean-dark);
  box-shadow: inset 1px 0 0 rgba(42, 107, 158, 0.25);
}
.tolls-table thead th[data-active="true"]::after {
  color: var(--aegean);
  opacity: 0.85;
}

/* ── Verdict pill in tolls table ── */
.tolls-verdict-stack {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
}
.tolls-verdict {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border-radius: var(--radius-pill);
  font-family: var(--font-body);
  font-weight: var(--weight-semibold);
  font-size: var(--text-caption);
  letter-spacing: 0.005em;
  white-space: nowrap;
  border: 1px solid transparent;
}
.tolls-verdict .tv-arrow {
  font-family: var(--font-mono);
  font-weight: var(--weight-bold);
  font-size: var(--text-sm);
  line-height: 1;
  opacity: 0.7;
  margin-right: -1px;
}
.tolls-verdict .tv-icon {
  font-weight: var(--weight-bold);
  font-size: var(--text-sm);
  line-height: 1;
}
.tolls-verdict .tv-label {
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: var(--text-caption);
}
.tolls-verdict .tv-sub {
  font-family: var(--font-mono);
  font-weight: var(--weight-medium);
  font-size: var(--text-caption);
  opacity: 0.78;
  margin-left: 2px;
}
.tolls-verdict-AVOID {
  background: rgba(46,122,74,0.12);
  color: #1f5828;
  border-color: rgba(46,122,74,0.3);
}
.tolls-verdict-MARGINAL_AVOID {
  background: rgba(90,153,112,0.12);
  color: #3d6e54;
  border-color: rgba(90,153,112,0.3);
}
.tolls-verdict-MARGINAL_PAY {
  background: rgba(196,128,95,0.10);
  color: #8a4d33;
  border-color: rgba(196,128,95,0.28);
}
.tolls-verdict-PAY {
  background: rgba(184,80,45,0.10);
  color: #8c3d22;
  border-color: rgba(184,80,45,0.28);
}
.tolls-verdict-none {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: var(--weight-regular);
  font-size: var(--text-sm);
  color: var(--muted);
  background: transparent;
  border: none;
  padding: 0;
}

/* Mobile adjustments for the new pages */
@media (max-width: 740px) {
  .topbar-nav { gap: 0; margin-right: 8px; }
  .nav-link { padding: 5px 9px; font-size: var(--text-sm); }
  .page-content { padding: 22px 16px 40px; }
  .page-title { font-size: 1.7rem; }
  .page-subtitle { font-size: var(--text-sm); }
  .page-toolbar { flex-wrap: wrap; padding: 10px 12px; }
  .page-toolbar .bar-input,
  .page-toolbar .bar-select { width: 100%; min-width: auto; }
  /* Tolls advisor controls stay compact even on mobile — they're small enough
     to share a row, and stretching them full-width feels off for short labels. */
  .tolls-toolbar #tolls-vehicle { width: auto; min-width: 110px; flex: 0 0 auto; }
  .tolls-toolbar .toolbar-divider { display: none; }
  .tolls-toolbar .tolls-time-control { flex: 1 1 100%; justify-content: space-between; }
  .tolls-toolbar .tolls-time-slider { flex: 1; max-width: 200px; min-width: 100px; }
  .tolls-toolbar .tolls-time-slider::-webkit-slider-thumb { width: 22px; height: 22px; }
  .tolls-toolbar .tolls-time-slider::-moz-range-thumb { width: 22px; height: 22px; }
  .tolls-toolbar .tolls-avoid-toggle { flex: 1 1 100%; }
  .tolls-toolbar .tolls-count { margin-left: 0; flex: 1 1 100%; text-align: right; }
  .routes-grid-table { font-size: var(--text-caption); }
  .routes-grid-table th, .routes-grid-table td { padding: 6px 8px; }
  .routes-grid-table tbody th { font-size: var(--text-caption); padding-left: 10px; }
  .routes-cell .rc-price { font-size: var(--text-sm); }
  .routes-cell .rc-meta { font-size: var(--text-micro); }
  .tolls-table { font-size: var(--text-sm); }
  .tolls-table thead th, .tolls-table tbody td { padding: 8px 10px; }
  .tolls-verdict { padding: 3px 7px; font-size: var(--text-caption); }
  .tolls-verdict .tv-label { font-size: var(--text-micro); }
}
/* Below 640px: collapse the routes matrix to price-only cells.
   The km/tolls/€-per-km detail makes cells unreadable when forced into a
   16-wide horizontally scrolling table on phones. Tap a cell to jump to
   the map view where the full breakdown is shown. */
@media (max-width: 640px) {
  .routes-cell { min-width: 64px; padding: 8px 6px; }
  .routes-cell .rc-meta,
  .routes-cell .rc-perkm { display: none; }
  .routes-cell .rc-price { font-size: var(--text-sm); }
  .routes-grid-table th, .routes-grid-table td { padding: 5px 6px; }
  .routes-grid-table tbody th { font-size: var(--text-caption); padding-left: 8px; padding-right: 8px; }
  .routes-grid-table thead th { font-size: var(--text-micro); }
}
@media (max-width: 640px) {
  .topbar-sep     { display: none; }

  /* Hide Leaflet's +/- zoom controls on mobile. Pinch-to-zoom and
     double-tap-to-zoom are universally familiar mobile gestures, and the
     buttons add no functionality while occupying valuable top-left
     real estate near the topbar. Standard map-app convention (Google
     Maps, Apple Maps) hides them on mobile. */
  .leaflet-control-zoom { display: none; }

  #legend {
    right: 6px;
    min-width: 175px;
    max-width: calc(100vw - 12px);
  }

  /* Side panel as bottom sheet — leaves 50% of screen for the map above */
  #toll-side-panel {
    width: 100%;
    top: auto;
    bottom: 0;
    height: 50vh;
    max-height: 50vh;
    border-left: none;
    border-top: 1px solid var(--line-strong);
    box-shadow: 0 -8px 32px rgba(26,31,46,0.14);
    transform: translateY(100%);
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  }
  #toll-side-panel.open { transform: translateY(0); }

  /* When panel open on mobile, hide bottom bar and resize map */
  body.panel-open #bottom-bar { display: none; }
  body.panel-open #map-container { bottom: 50vh !important; }
  body.panel-open #results-panel { display: none; }
  body.panel-open #legend { display: none; }

  /* Tighter side panel content on mobile so more fits in the smaller sheet */
  .sp-header { padding: 9px 14px; padding-top: 14px; }
  /* Mobile header is a 2-column grid: badge spans full width on top,
     then toll name on the left + price on the right of the second row.
     This keeps the price visible without burning a separate row of
     vertical real estate — important on small viewports where the
     side panel is a bottom sheet competing with the map. */
  .sp-header-inner {
    padding: 14px 16px 12px;
    display: grid;
    grid-template-columns: 1fr auto;
    grid-template-areas:
      "badge   badge"
      "name    price"
      "namegr  price";
    column-gap: 10px;
    align-items: center;
  }
  .sp-header-inner .sp-hwy-badge { grid-area: badge; }
  .sp-header-inner .sp-name      { grid-area: name; align-self: end; }
  .sp-header-inner .sp-name-gr   { grid-area: namegr; align-self: start; }
  .sp-header-inner .sp-price-row { grid-area: price; align-self: center; }
  .sp-name { font-size: var(--text-xl); margin-bottom: 2px; line-height: 1.1; }
  .sp-name-gr { font-size: var(--text-sm); margin-bottom: 0; }
  .sp-section-title { padding: 8px 16px 4px; font-size: var(--text-micro); }
  /* Compact price chip on mobile: emoji left, big price right.
     Previously this was a 4-column grid of cells; now it's a single
     inline pill that lives in the header grid. */
  .sp-price-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 10px;
    background: var(--paper-2);
    border: 1px solid rgba(0,0,0,0.05);
    border-radius: var(--radius);
  }
  .sp-price-row > span { display: inline-flex; align-items: center; gap: 0; line-height: 1; }
  .sp-price-row .sp-emoji { font-size: var(--text-xl); }
  .sp-price-row .sp-vlabel { display: none; }   /* hide text label on mobile */
  .sp-price-row strong { font-size: var(--text-base); letter-spacing: -0.02em; }

  .sp-direction { padding: 9px 16px 12px; font-size: var(--text-sm); }
  .sp-dir { padding: 11px 16px 13px; }
  .sp-dir-label { font-size: var(--text-base); margin-bottom: 6px; }
  .sp-dir-compare { padding: 8px 10px; }
  .sp-dir-filter { padding: 8px 16px 5px; gap: 4px; }
  .sp-filter-btn { padding: 4px 9px; font-size: var(--text-caption); }

  /* Visual handle bar at the top of the sheet for affordance */
  #toll-side-panel.open::before {
    content: '';
    position: absolute;
    top: 6px;
    left: 50%;
    transform: translateX(-50%);
    width: 40px;
    height: 4px;
    background: var(--line-strong);
    border-radius: var(--radius-sm);
    z-index: 10;
  }

  #bottom-bar {
    /* R48: removed `min-height: var(--bar-h)` (was 72px). The new
       floating-panel design is vertical and wants to size to content;
       the old min-height was for the original horizontal strip. */
    height: auto;
    flex-wrap: wrap;
    padding: 8px 10px;
    gap: 6px;
    row-gap: 8px;
  }
  .bar-input { flex: 1; min-width: 80px; height: 40px; font-size: var(--text-base); }
  .swap-btn  { height: 40px; }
  .bar-label { display: none; }
  .bar-sep { display: none; }
  .bar-select { height: 40px; font-size: var(--text-sm); flex: 1; }

  /* Slider control on mobile: short phrase, sentence + slider on its own row */
  .tv-compact {
    width: 100%;
    flex-direction: column;
    align-items: stretch;
    gap: 10px;
    order: 9;
    padding: 8px 4px 14px;
    background: var(--paper-2);
    border-radius: var(--radius);
    margin-top: 4px;
  }
  .tv-compact .tv-desktop { display: none; }
  .tv-compact .tv-mobile  { display: inline; }
  .tv-compact-sentence {
    flex-wrap: nowrap;
    justify-content: center;
    align-items: center;
    gap: 8px;
    padding: 0 8px;
  }
  .tv-compact .lbl,
  .tv-compact .lbl-suffix {
    font-size: var(--text-sm);
    white-space: nowrap;
  }
  .tv-compact .val {
    width: 96px;
    padding: 5px 8px 6px;
  }
  .tv-compact .val-num {
    font-size: var(--text-lg);
  }
  .tv-compact .val-tier {
    font-size: var(--text-micro);
  }
  .tv-compact input[type="range"] {
    width: calc(100% - 16px);
    margin: 0 8px;
    height: 6px;
  }
  .tv-compact input[type="range"]::-webkit-slider-thumb {
    width: 24px; height: 24px;
    border-width: 2.5px;
  }
  .tv-compact input[type="range"]::-moz-range-thumb {
    width: 24px; height: 24px;
    border-width: 2.5px;
  }

  /* ── Tolerance control on mobile ──────────────────────────────────────
     In prose mode (first visit), the existing .tv-compact column-flex
     layout above does the work. In pill mode, dissolve .tv-control with
     display:contents so the pill sits inline with the From/To inputs
     instead of consuming a full row below them. The popover (when
     opened) gets order:9 to wrap to its own row below the inputs while
     staying above the order:10 analyse button. */
  .tv-control {
    width: 100%;
    order: 9;
    flex-direction: column;
    align-items: stretch;
  }
  .tv-control.is-pill-mode {
    display: contents;
  }
  .tv-control.is-pill-mode .tv-pill {
    /* Inline pill — slot it after the To input. flex-shrink:0 prevents
       the bar's wrap behaviour from making it disappear when squeezed. */
    height: 40px;
    padding: 0 12px;
    font-size: var(--text-base);
    flex-shrink: 0;
  }
  .tv-control.is-pill-mode .tv-pill-icon { width: 16px; height: 16px; }
  .tv-control.is-pill-mode .tv-popover {
    /* Popover wraps to its own row below the inputs (order 9) but still
       above the analyse button (order 10). */
    order: 9;
    width: 100%;
  }
  .tv-pill {
    height: 40px;
    padding: 0 14px;
    font-size: var(--text-base);
  }
  .tv-pill-icon { width: 16px; height: 16px; }
  /* On mobile, popover stretches to bar width and renders below the bar
     (the bar lives at the top of the bottom-bar's column layout, so the
     popover ends up just under the pill — no need to fight viewport edges). */
  .tv-popover {
    position: static;
    transform: none;
    width: 100%;
    margin-top: 8px;
    animation-name: tv-popover-in-mobile;
  }
  @keyframes tv-popover-in-mobile {
    from { opacity: 0; transform: translateY(-4px); }
    to   { opacity: 1; transform: translateY(0); }
  }
  .tv-popover-arrow { display: none; }   /* no arrow needed in flow layout */
  .tv-popover-question { font-size: var(--text-sm); }
  /* Bigger slider thumb inside the popover on mobile, matching the
     prose-mode .tv-compact slider thumb size. */
  .tv-popover-slot input[type="range"] {
    height: 6px;
  }
  .tv-popover-slot input[type="range"]::-webkit-slider-thumb {
    width: 24px; height: 24px;
    border-width: 2.5px;
  }
  .tv-popover-slot input[type="range"]::-moz-range-thumb {
    width: 24px; height: 24px;
    border-width: 2.5px;
  }

  .analyse-btn {
    width: 100%;
    height: 48px;
    font-size: var(--text-base);
    font-weight: var(--weight-semibold);
    justify-content: center;
    order: 10;
    margin-top: 4px;
  }
  .error-pill { width: 100%; order: 11; }

  /* R52/R53: map fills full available height down to the peek strip
     (48px). The island is `position: fixed` and floats over the map's
     bottom portion when expanded — no need to reserve space for it.
     When the island is collapsed, only the peek shows, so the map
     occupies everything from below the topbar to above the peek with
     no blank gap.

     Was: bottom: var(--bar-actual-h, 116px) — that reserved space for
     the expanded island even when collapsed, leaving a huge blank gap. */
  #map-container { bottom: 48px; }
  #results-panel { bottom: 48px; max-height: 60vh; }

  /* Compact topbar buttons on mobile */
  #legend-toggle,
  #basemap-toggle { display: none; } /* both have drawer equivalents on mobile */

  /* Vehicle dropdown: tighter padding on mobile. The full label stays */
  /* visible — vehicle selection is essential, not optional like feedback. */
  .veh-current { padding: 4px 8px 4px 10px; font-size: var(--text-sm); }
  .veh-current .veh-label { display: none; } /* show emoji only on mobile */
  .veh-menu { min-width: 150px; }
  /* Inline page-header pill has more space (it's in document flow, not in
     the cramped topbar), so keep its label visible on mobile too. */
  .veh-toggle--inline .veh-current .veh-label { display: inline; }
  .toll-tooltip { min-width: 220px; max-width: calc(100vw - 20px); }
}

@media (max-width: 400px) {
  .bar-input { font-size: var(--text-sm); }
  .bar-select { font-size: var(--text-sm); }
}

/* ══════════════════════════════════════
   READABILITY OVERRIDES (after font swap to Inter)
   Inter doesn't have italic styles that flatter UI text the way Fraunces did,
   so we drop italics from functional UI elements while keeping them in genuinely
   typographic content (notes, taglines).
   ══════════════════════════════════════ */
.legend-title,
.legend-sub,
.sp-section-title,
.sp-header-title,
.sp-direction,
.bar-label,
.tv-compact .lbl,
.page-subtitle,
.page-toolbar-label,
.routes-grid-table thead th,
.routes-grid-table tbody th,
.tt-sub em,
.sp-direction em,
.sp-cmp-diff,
.sp-name-gr,
.tt-name-gr,
.help-subtitle,
.legend-ramps-state,
.flag-option {
  font-style: normal !important;
}

/* Restore italics for genuinely typographic flourishes */
.sp-notes,
.help-tip,
.tt-notes {
  font-style: italic;
}

/* Inter looks better at slightly heavier weights for display text */
.page-title,
.sp-name,
.help-logo,
.logo {
  letter-spacing: -0.025em;
}
/* Logo's middle "dio" stays bold; the "my" prefix and italic "dia" keep their lighter weights. */
.logo-text .logo-mid,
.help-logo-text .logo-mid,
.mobile-drawer-logo .logo-mid {
  font-weight: var(--weight-bold);
}

/* Section labels — small, uppercase, looks better in sans-serif */
.sp-section-title,
.legend-title {
  text-transform: uppercase;
  letter-spacing: 0.06em !important;
  font-size: var(--text-caption);
  font-weight: var(--weight-semibold);
}

/* ══════════════════════════════════════
   HAMBURGER BUTTON + MOBILE DRAWER
   ══════════════════════════════════════ */
.hamburger-btn {
  display: none;   /* shown only on mobile via media query below */
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  width: 38px;
  height: 38px;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  color: var(--ink);
  flex-shrink: 0;
  transition: background 0.18s var(--ease), border-color 0.18s var(--ease);
  padding: 0;
}
.hamburger-btn:hover {
  background: var(--paper-2);
  border-color: var(--aegean);
}

.mobile-drawer {
  position: fixed; inset: 0;
  z-index: 9000;
  pointer-events: none;
  visibility: hidden;
}
.mobile-drawer.open {
  pointer-events: auto;
  visibility: visible;
}
.mobile-drawer-overlay {
  position: absolute; inset: 0;
  background: rgba(26,31,46,0.45);
  opacity: 0;
  transition: opacity 0.28s var(--ease);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
}
.mobile-drawer.open .mobile-drawer-overlay { opacity: 1; }

.mobile-drawer-panel {
  position: absolute;
  top: 0; right: 0; bottom: 0;
  width: 84%;
  max-width: 320px;
  background: var(--paper);
  box-shadow: -16px 0 48px rgba(26,31,46,0.18);
  display: flex;
  flex-direction: column;
  transform: translateX(100%);
  transition: transform 0.32s var(--ease);
  padding: 16px 0;
}
.mobile-drawer.open .mobile-drawer-panel { transform: translateX(0); }

.mobile-drawer-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 4px 22px 18px;
  border-bottom: 1px solid var(--line);
}
.mobile-drawer-logo {
  font-family: var(--font-display);
  font-weight: var(--weight-medium);
  font-size: var(--text-xl);
  letter-spacing: -0.025em;
  color: var(--muted);
}
.mobile-drawer-logo .logo-mid {
  color: var(--ink);
  font-weight: var(--weight-bold);
}
.mobile-drawer-logo em {
  font-style: italic;
  font-weight: var(--weight-medium);
  color: var(--aegean);
}
.mobile-drawer-close {
  background: transparent;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  width: 36px; height: 36px;
  font-size: var(--text-base);
  color: var(--muted);
  cursor: pointer;
  transition: all 0.15s var(--ease);
}
.mobile-drawer-close:hover {
  background: var(--stop-bg);
  border-color: var(--stop);
  color: var(--stop);
}

.mobile-drawer-nav {
  display: flex;
  flex-direction: column;
  padding: 14px 12px;
  gap: 2px;
}
.mobile-nav-link {
  display: block;
  font-family: var(--font-body);
  font-weight: var(--weight-semibold);
  font-size: var(--text-lg);
  letter-spacing: -0.01em;
  color: var(--ink);
  padding: 14px 18px;
  border-radius: var(--radius);
  text-decoration: none;
  cursor: pointer;
  transition: all 0.15s var(--ease);
}
.mobile-nav-link:hover { background: var(--paper-2); }
.mobile-nav-link.active {
  background: var(--aegean-lt);
  color: var(--aegean-dark);
}

.mobile-drawer-divider {
  height: 1px;
  background: var(--line);
  margin: 8px 22px;
}

.mobile-drawer-actions {
  display: flex;
  flex-direction: column;
  padding: 8px 12px;
  gap: 2px;
}
.mobile-drawer-action {
  display: flex;
  align-items: center;
  gap: 12px;
  font-family: var(--font-body);
  font-weight: var(--weight-medium);
  font-size: var(--text-base);
  color: var(--ink-2);
  padding: 12px 18px;
  border-radius: var(--radius);
  text-decoration: none;
  background: transparent;
  border: none;
  cursor: pointer;
  text-align: left;
  width: 100%;
  transition: all 0.15s var(--ease);
}
.mobile-drawer-action:hover {
  background: var(--paper-2);
  color: var(--ink);
}
.mobile-drawer-action svg { flex-shrink: 0; opacity: 0.7; }
.mobile-drawer-action:hover svg { opacity: 1; }

@media (max-width: 640px) {
  /* On mobile: show hamburger, hide nav + overflow menu (their items go in
     the drawer instead). */
  .hamburger-btn { display: inline-flex; }
  .topbar-nav,
  .overflow-toggle { display: none !important; }
  /* Logo stays visible, language toggle stays visible */
}

/* ── Site footer (legal/credits) ──────────────────────────────────────────
   Lives inside the routes and tolls page wrappers. Map page has no footer
   (the canvas is the whole page; credits live in the help drawer instead). */
.site-footer {
  margin-top: 32px;
  padding: 18px 24px;
  border-top: 1px solid var(--line);
  background: var(--paper);
  font-family: var(--font-body);
  font-size: var(--text-caption);
  color: var(--muted);
  text-align: center;
}
.site-footer-inner {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 6px 10px;
  align-items: center;
  justify-content: center;
  letter-spacing: 0.005em;
}
.site-footer .footer-sep {
  opacity: 0.4;
}
.site-footer .footer-link {
  color: var(--aegean);
  text-decoration: none;
  font-weight: var(--weight-medium);
  border-bottom: 1px solid transparent;
  transition: border-color 0.15s var(--ease);
}
.site-footer .footer-link:hover {
  border-bottom-color: var(--aegean);
}
@media (max-width: 640px) {
  .site-footer { padding: 14px 16px; font-size: var(--text-caption); }
  .site-footer-inner { flex-direction: column; gap: 3px; }
  .site-footer .footer-sep { display: none; }
}

/* ══════════════════════════════════════
   FIRST-VISIT TIP
   Floating card centered near the top of the map page that tells new
   visitors the site's primary action: tap a toll to see if it's worth
   paying or bypassing. Auto-dismisses on first toll click. Persists
   dismissed state in localStorage as `mydiodia.tip.bypass.v1`.
   Wired up by map.js. Toggled via [hidden] attribute, so anything
   that needs to hide it can do so without removing it from the DOM.
   ══════════════════════════════════════ */
.first-tip {
  position: fixed;
  top: calc(var(--topbar-h) + 14px);
  left: 50%;
  transform: translateX(-50%);
  z-index: 920;
  display: flex;
  align-items: center;
  gap: 12px;
  max-width: min(540px, calc(100vw - 24px));
  padding: 10px 12px 10px 16px;
  background: var(--paper);
  border: 1px solid var(--aegean-lt);
  border-left: 3px solid var(--aegean);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  line-height: 1.4;
  color: var(--ink);
  /* Fade in slightly delayed so it doesn't compete with map tile loading */
  animation: first-tip-in 0.4s var(--ease-out) 0.4s backwards;
}
.first-tip[hidden] { display: none; }
.first-tip.is-leaving {
  animation: first-tip-out 0.25s var(--ease) forwards;
}
.first-tip-body {
  flex: 1;
  /* Keep emoji baseline aligned with text */
  display: inline-block;
}
.first-tip-close {
  flex-shrink: 0;
  width: 24px;
  height: 24px;
  border: none;
  background: transparent;
  color: var(--ink-3);
  font-size: var(--text-base);
  line-height: 1;
  cursor: pointer;
  border-radius: var(--radius);
  transition: background-color 0.15s var(--ease), color 0.15s var(--ease);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.first-tip-close:hover {
  background: var(--paper-2);
  color: var(--ink);
}
.first-tip-close:focus-visible {
  outline: 2px solid var(--aegean);
  outline-offset: 1px;
}
@keyframes first-tip-in {
  from { opacity: 0; transform: translate(-50%, -8px); }
  to   { opacity: 1; transform: translate(-50%, 0); }
}
@keyframes first-tip-out {
  to { opacity: 0; transform: translate(-50%, -8px); }
}
/* Mobile: tighten padding/font, allow it to span the screen with margin */
@media (max-width: 640px) {
  .first-tip {
    top: calc(var(--topbar-h) + 8px);
    padding: 9px 10px 9px 13px;
    font-size: var(--text-sm);
    gap: 8px;
    max-width: calc(100vw - 16px);
  }
}

/* ══════════════════════════════════════
   CITY AUTOCOMPLETE DROPDOWN
   Floats above the bottom-bar inputs (#origin / #dest). Positioned via
   JS using the input's bounding rect, so it follows on resize. Opens
   upward because the inputs are pinned to the screen bottom.
   ══════════════════════════════════════ */
.city-ac-dropdown {
  position: fixed;
  z-index: 2000;            /* above bottom-bar (z-500) and side panel */
  background: var(--paper);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  color: var(--ink);
  max-height: 280px;
  overflow-y: auto;
  padding: 4px 0;
  /* Don't let it become absurdly wide on big screens */
  max-width: 320px;
  animation: city-ac-in 0.12s var(--ease-out);
}
.city-ac-dropdown[hidden] { display: none; }
@keyframes city-ac-in {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: translateY(0); }
}
.city-ac-row {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 9px 14px;
  cursor: pointer;
  user-select: none;
  /* Faster than transitioning bg on hover — feels snappier on a list */
}
.city-ac-row.is-active {
  background: var(--aegean-lt);
}
.city-ac-row:hover {
  background: var(--aegean-lt);
}
.city-ac-primary {
  font-weight: var(--weight-medium);
  color: var(--ink);
  letter-spacing: -0.005em;
}
.city-ac-secondary {
  font-size: var(--text-sm);
  color: var(--ink-3);
  font-weight: var(--weight-regular);
}
@media (max-width: 640px) {
  .city-ac-dropdown {
    font-size: var(--text-base);
    max-height: 240px;
    max-width: calc(100vw - 20px);
  }
  .city-ac-row {
    padding: 11px 14px;  /* slightly larger tap target on mobile */
  }
}

/* ══════════════════════════════════════
   BYPASS-CONTEXT SIDE-TOLL MARKERS
   Yellow side-toll dots that appear specifically when a toll's side panel
   is open AND that toll's bypass passes through one or more side tolls.
   They're tied to the inspectLayers lifecycle: cleared when the panel
   closes. Slightly larger + ring of yellow glow so they pop.
   Only added when global side-tolls toggle is OFF (see map.js).
   ══════════════════════════════════════ */
.toll-marker-bypass-side {
  width: 13px; height: 13px;
  border: 2.5px solid var(--paper);
  box-shadow:
    0 0 0 2px rgba(244,196,48,0.45),
    0 0 0 5px rgba(244,196,48,0.18),
    0 2px 6px rgba(0,0,0,0.35);
}
.toll-marker-bypass-side:hover {
  transform: scale(1.5);
}

/* ══════════════════════════════════════
   BYPASS SIDE-TOLL CALLOUT (in side panel)
   Two states:
   - .sp-bypass-sidetolls-some  → amber-ish "you'll still pay X side tolls"
   - .sp-bypass-sidetolls-free  → green "no tolls — fully free"
   Sits between the confidence indicator and the comparison block.
   ══════════════════════════════════════ */
.sp-bypass-sidetolls {
  margin: 6px 0 8px;
  padding: 8px 11px;
  border-radius: var(--radius);
  font-size: var(--text-sm);
  line-height: 1.4;
}
.sp-bypass-sidetolls-some {
  background: rgba(244,196,48,0.12);   /* faint yellow, semantic "side toll" */
  border: 1px solid rgba(200,158,26,0.55);
  color: #5a4500;                       /* dark yellow-brown for legibility */
}
.sp-bypass-sidetolls-free {
  background: var(--go-bg);
  border: 1px solid var(--go);
  color: #1f5a35;
  font-weight: var(--weight-medium);
}
.sp-bypass-sidetolls-title {
  font-weight: var(--weight-medium);
  margin-bottom: 5px;
}
.sp-bypass-sidetolls-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.sp-bypass-sidetoll-item {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 1px 0;
}
.sp-bypass-sidetoll-dot {
  flex-shrink: 0;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: #c89e1a;          /* darker yellow than the toll-marker fill */
  border: 1px solid #6e5612;
}
.sp-bypass-sidetoll-name {
  font-weight: var(--weight-medium);
  color: #4a3500;
}
.sp-bypass-sidetoll-role {
  font-size: var(--text-caption);
  color: #6e5612;
  font-style: italic;
}

/* R53 inline variant: single side toll rendered on one row alongside the
   title for density. e.g. "Παράκαμψη — 1 πλευρικό διόδιο · Καλάμια
   (είσοδος)". The .sp-bypass-sidetolls-inline class is added to the
   container only in the single-toll case; multiple-toll case still uses
   the title-above-list layout. */
.sp-bypass-sidetolls-inline {
  display: flex;
  align-items: baseline;
  gap: 6px;
  flex-wrap: wrap;
}
.sp-bypass-sidetolls-inline .sp-bypass-sidetolls-title {
  margin-bottom: 0;
}
.sp-bypass-sidetolls-inline .sp-bypass-sidetolls-sep {
  color: #c89e1a;
  font-weight: var(--weight-bold);
}
.sp-bypass-sidetolls-inline .sp-bypass-sidetoll-name {
  font-weight: var(--weight-medium);
}

/* ══════════════════════════════════════
   FERRY-MODE BYPASS (Rio-Antirrio bridge)
   When the bypass for a bridge crossing is a ferry, render the schedule
   + fare table here instead of the road-style "you'll still pay X side
   tolls" callout. Visual style: cool aegean-blue accent (it IS the sea)
   to distinguish from the amber side-toll callout and the green
   "fully free" confirmation.
   ══════════════════════════════════════ */
.sp-bypass-ferry {
  background: var(--aegean-lt);
  border: 1px solid #a8cae0;
  border-left: 3px solid var(--aegean);
  color: var(--aegean-dark);
}
.sp-bypass-ferry-title {
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  margin-bottom: 6px;
  color: var(--aegean-dark);
}
.sp-bypass-ferry-schedule {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  font-size: var(--text-caption);
  margin-bottom: 8px;
}
.sp-bypass-ferry-stat {
  background: var(--paper);
  border: 1px solid #c7d8e3;
  border-radius: var(--radius);
  padding: 3px 8px;
  color: var(--aegean-dark);
  font-weight: var(--weight-medium);
}
.sp-bypass-ferry-fare-label {
  font-size: var(--text-caption);
  color: var(--ink-3);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: var(--weight-medium);
  margin-bottom: 4px;
}
.sp-ferry-fare-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 3px 12px;
}
.sp-ferry-fare-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: var(--text-caption);
}
.sp-ferry-fare-veh {
  display: flex; align-items: center; gap: 4px;
  color: var(--ink-2);
}
.sp-ferry-fare-emoji { font-size: var(--text-base); }
.sp-ferry-fare-val {
  font-family: var(--font-mono);
  font-weight: var(--weight-medium);
  color: var(--aegean-dark);
}
@media (max-width: 480px) {
  .sp-ferry-fare-list { grid-template-columns: 1fr; }
}

/* ══════════════════════════════════════
   FERRY PIER MARKERS (Rio-Antirrio)
   Synthetic yellow markers at the two ferry piers, shown when the
   global "Πλευρικά διόδια" toggle is on. Visual hint that they're
   sea crossings rather than road tolls: thin aegean-blue ring over
   the yellow base.
   ══════════════════════════════════════ */
.toll-marker-ferry-pier {
  border: 1.5px solid var(--aegean);
  box-shadow: 0 0 0 1px rgba(255,255,255,0.6), 0 1px 3px rgba(0,0,0,0.3);
}
.toll-marker-ferry-pier:hover {
  transform: scale(1.5);
}

/* ══════════════════════════════════════
   BUMPED SIDE-TOLL MARKER
   When a toll's side panel is open AND its bypass bills a side toll
   that's at the same lat/lng as a ramp pillar, we swap the small 11px
   side-toll dot for this 16px ringed marker, visually offset up-and-left
   so it pops out from behind the green RE-ENTER / blue EXIT pillar.
   The icon's geo anchor still points at the actual toll coord; only the
   visual is shifted. Reverted to the regular dot on panel close.
   ══════════════════════════════════════ */
.toll-marker-bumped {
  width: 16px; height: 16px;
}


/* The print-view element is hidden on screen — it's only used as the
   data source for the popup print window (see printDocument in
   calculator.js). The popup writes its own self-contained HTML with
   inline styles. No @media print rules needed. */
#print-view { display: none; }


/* ════════════════════════════════════════════════════════════════
   FLOATING PANEL (R43)
   ────────────────────────────────────────────────────────────────
   Replaces the horizontal bottom-bar strip. Card hovers above the
   bottom of the viewport, holds vehicle pills + tolerance + From/To
   inputs + Analyse button in a single vertical stack. The previous
   #bottom-bar selector is overridden here — no need to delete the
   earlier rule, the override below wins on cascade order.
   ════════════════════════════════════════════════════════════════ */

#bottom-bar {
  /* R48: panel sized strictly to its content. !important on height
     properties because earlier rules (line 1480 height: var(--bar-h))
     and the mobile media query (min-height: var(--bar-h)) were
     potentially leaking through cascade in some browser/state combos.
     Belt and suspenders: explicit values + !important. */
  position: fixed;
  top: calc(var(--topbar-h, 56px) + 12px);
  left: 12px;
  z-index: 500;
  width: 380px;
  max-width: calc(100vw - 24px);
  height: auto !important;
  min-height: 0 !important;
  max-height: none !important;
  background: var(--paper);
  border: 1px solid var(--line-strong);
  border-radius: 16px;
  padding: 12px 14px;
  box-shadow: 0 8px 24px rgba(26, 31, 46, 0.12), 0 2px 6px rgba(26, 31, 46, 0.06);
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-items: stretch;
}
/* Defensive: any direct child of #bottom-bar gets flex: 0 0 auto so it
   contributes its natural height, never grows. */
#bottom-bar > * { flex: 0 0 auto !important; }

/* The Leaflet zoom buttons live in the top-left by default — same place we
   want our floating panel. Remove them globally; users can still zoom via
   pinch / scroll wheel. (Originally hidden only on mobile via line 3299.) */
.leaflet-control-zoom { display: none !important; }

/* Vehicle pills — segmented control (R50).
   The selected pill expands to fit emoji + label; the other three
   shrink to show only their emoji. Total width stays at 100% of the
   container — sum of widths is constant, what changes is how that
   width is divided.
   The active pill carries the brand-blue background and white text.
   Click any pill to make it active; CSS animates the flex sizing for
   a smooth grow/shrink transition. */
.fp-pills {
  display: flex;
  background: var(--paper-2);
  border-radius: 999px;
  padding: 4px;
  gap: 2px;
}

.fp-pill {
  /* Default (inactive): just enough room for the emoji, equal share
     among the three inactive pills. flex: 1 1 0 means "grow equally
     to fill remaining space, with 0 base size". */
  flex: 1 1 0;
  min-width: 0;
  background: transparent;
  border: 0;
  padding: 8px 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--ink);
  cursor: pointer;
  border-radius: 999px;
  transition: flex 260ms cubic-bezier(.2, .8, .2, 1),
              padding 260ms cubic-bezier(.2, .8, .2, 1),
              background-color 200ms ease,
              color 200ms ease;
}
.fp-pill .fp-pill-icon {
  flex-shrink: 0;
  font-size: 16px;
  line-height: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
}
/* Inactive pills: hide the label (still readable to screen readers via
   aria-label on the button). The emoji centers naturally. */
.fp-pill .fp-pill-label {
  white-space: nowrap;
  overflow: hidden;
  display: none;
}

/* Active pill: grow to fit emoji + label naturally, brand blue
   background, white text. flex: 0 1 auto = "don't grow past content,
   shrink if needed, base size = content's intrinsic width". */
.fp-pill.is-active {
  flex: 0 1 auto;
  background: var(--aegean);
  color: var(--paper);
  padding: 8px 14px;
}
.fp-pill.is-active .fp-pill-label {
  display: inline;
}

.fp-pill:focus-visible {
  outline: 2px solid var(--aegean);
  outline-offset: 2px;
}

/* Question line — soft prompt above the slider. */
.fp-question {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: var(--weight-regular);
  color: var(--muted);
  line-height: 1.35;
  padding: 0 4px;
  margin-top: 2px;
}

/* Slider row — slider + numeric value readout. The slider's inline width
   is governed by flex; the readout is fixed. */
.fp-slider-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 4px;
}
.fp-slider-row input[type="range"] {
  flex: 1;
  min-width: 0;
}
.fp-slider-value {
  display: flex;
  align-items: baseline;
  gap: 3px;
  min-width: 56px;
  justify-content: flex-end;
}
.fp-slider-num {
  font-family: var(--font-body);
  font-size: var(--text-lg);
  font-weight: var(--weight-medium);
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.fp-slider-unit {
  font-family: var(--font-body);
  font-size: var(--text-caption);
  color: var(--muted);
}
.fp-slider-tier {
  font-family: var(--font-body);
  font-size: var(--text-caption);
  color: var(--muted);
  text-align: right;
  padding: 0 4px;
  /* R46: was min-height 14px which reserved space even when empty. Let it
     collapse naturally — the tier text fills it when present. */
  min-height: 0;
  line-height: 1.2;
  margin-top: -4px;
}

/* Route row — origin / swap / destination / analyse. Wraps on narrow
   screens; on desktop everything fits in one line. */
.fp-route-row {
  display: flex;
  align-items: stretch;
  gap: 8px;
  flex-wrap: nowrap;
}
.fp-input {
  flex: 1;
  min-width: 0;
  height: 40px;
  background: var(--paper);
  border: 1.5px solid var(--line);
  color: var(--ink);
  font-family: var(--font-body);
  font-weight: var(--weight-medium);
  font-size: var(--text-base);
  padding: 0 12px;
  outline: none;
  border-radius: var(--radius);
  transition: all 0.18s var(--ease);
}
.fp-input::placeholder { color: var(--muted); }
.fp-input:focus {
  border-color: var(--aegean);
  box-shadow: 0 0 0 3px var(--aegean-lt);
}
.fp-swap {
  flex-shrink: 0;
  height: 40px; width: 40px;
  background: var(--paper);
  border: 1.5px solid var(--line);
  color: var(--ink-2);
  font-size: var(--text-lg);
  cursor: pointer;
  border-radius: var(--radius);
  transition: all 0.18s var(--ease);
  display: flex; align-items: center; justify-content: center;
}
.fp-swap:hover {
  background: var(--aegean-lt);
  border-color: var(--aegean);
  color: var(--aegean);
  transform: rotate(180deg);
}
.fp-analyse {
  /* R48: full width on its own row in the floating panel. */
  width: 100%;
  flex-shrink: 0;
  height: 40px;
  /* Override the .analyse-btn justify-content default so the spinner+
     text are centered. .analyse-btn uses display: flex; align-items:
     center but defaults to justify-content: flex-start which would
     pin content to the left now that the button spans full width. */
  justify-content: center;
  /* All other analyse-btn styling cascades from the existing .analyse-btn
     rule earlier in this file (gradient, hover, etc.). We only override
     the height/padding for the floating-panel context. */
  padding: 0 18px;
  font-size: var(--text-base);
}

/* Defensive: hide any vestigial #vehicle-toggle if it ever shows up. */
#vehicle-toggle { display: none !important; }

/* Hide the floating panel when the results panel is open — same as the
   earlier `body.panel-open #bottom-bar { display: none }` rule, but
   applied unconditionally (the original was inside a mobile media
   query). The map underneath still receives the analyse output. */
body.panel-open #bottom-bar { display: none !important; }

/* Narrow screens: panel returns to bottom-centered for thumb-reach.
   Tighten spacing, allow the route row to wrap. */
@media (max-width: 640px) {
  #bottom-bar {
    top: auto;
    left: 50%;
    bottom: 12px;
    transform: translateX(-50%);
    width: calc(100% - 16px);
    max-width: 640px;
    padding: 10px 12px;
    gap: 8px;
    border-radius: 14px;
  }
  .fp-pill {
    font-size: var(--text-caption);
    gap: 3px;
    padding: 7px 0;
  }
  /* Mobile active pill: keep label-friendly padding so the name fits. */
  .fp-pill.is-active {
    padding: 7px 12px;
  }
  .fp-pill .fp-pill-icon {
    font-size: 14px;
    width: 16px;
    height: 16px;
  }
  .fp-question {
    font-size: var(--text-caption);
  }
  .fp-route-row {
    flex-wrap: wrap;
  }
  .fp-input {
    flex: 1 1 calc(50% - 24px);
  }
  .fp-analyse {
    flex: 1 1 100%;
  }
}

/* Very narrow: hide pill text labels, leave icons only. */
@media (max-width: 380px) {
  .fp-pill .fp-pill-label { display: none; }
  .fp-pill { padding: 9px 0; }
}


/* ════════════════════════════════════════════════════════════════
   RESULTS PANEL — desktop floating window (R45)
   ────────────────────────────────────────────────────────────────
   On viewports ≥ 720px the results panel is a fixed-size window in the
   top-right corner instead of a full-width slide-up sheet. Mirrors the
   floating control panel at top-left for visual symmetry. Mobile keeps
   the slide-up sheet pattern (better for thumb reach + small screens).

   Also harmonises the panel chrome with the floating control panel:
   flat white surface, soft shadow, 1px borders, 16px radius — same
   visual vocabulary across the site.
   ════════════════════════════════════════════════════════════════ */
@media (min-width: 720px) {
  #results-panel {
    /* Top-right floating window. Width chosen to fit toll-list chips
       at one-per-row without horizontal scroll. Internal scroll handles
       long routes. */
    top: calc(var(--topbar-h) + 12px);
    right: 12px;
    bottom: auto;
    left: auto;
    width: 420px;
    max-width: calc(100vw - 24px);
    /* R58: panel is sized to its content, capped at viewport-minus-margin.
       Was max-height: calc(100vh - topbar - 24px) which made the panel
       ALWAYS that tall, even when content was much shorter — leaving a
       visible cream/paper "gap" below the last chip. Now: height auto
       (intrinsic), max-height capped, content scrolls if it exceeds. */
    height: auto !important;
    min-height: 0 !important;
    max-height: calc(100dvh - var(--topbar-h) - 24px);

    /* Match the floating control panel's chrome — flat white card with
       1px border, 16px radius, soft drop shadow. The original styles
       had a top-only border + bottom-emerging shadow that suited the
       slide-up sheet, but look orphaned as a free-floating window. */
    /* R58: !important on background so nothing in the cascade can render
       this panel transparent. The user reported the panel looked
       see-through over the map. */
    background: var(--paper) !important;
    border: 1px solid var(--line-strong);
    border-top: 1px solid var(--line-strong); /* override the slide-up specific */
    border-radius: 16px;
    box-shadow: 0 8px 24px rgba(26, 31, 46, 0.12), 0 2px 6px rgba(26, 31, 46, 0.06);
    overflow: hidden; /* clip rounded corners cleanly when content scrolls */

    /* Slide in from the right instead of up from the bottom. */
    transform: translateX(120%);
    opacity: 0;
    transition: transform 0.32s var(--ease), opacity 0.2s var(--ease);
  }
  #results-panel.open {
    transform: translateX(0);
    opacity: 1;
  }

  /* Header chrome: flat instead of gradient. Border-bottom stays for
     visual section separation. R58: stats row drops below title (was
     getting clipped on the right side because the 420px panel can't
     fit title + 3 stats + 2 actions + close on one row). */
  #results-panel .rp-head {
    background: var(--paper) !important;
    background-color: var(--paper) !important;
    padding: 12px 16px;
    gap: 10px;
    flex-wrap: wrap;
  }
  #results-panel .rp-title {
    font-size: var(--text-base);
    font-weight: var(--weight-semibold);
    letter-spacing: -0.01em;
    flex: 1 1 auto;
    /* Truncate long route names with ellipsis instead of clipping. */
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    min-width: 0;
  }
  #results-panel .rp-stats {
    /* Drop to a new full-width row below the title — give the stats
       breathing room. */
    order: 99;
    flex: 1 1 100%;
    margin-top: 4px;
    padding-top: 8px;
    border-top: 1px solid var(--line);
    flex-wrap: wrap;
    gap: 12px;
    font-size: var(--text-sm);
  }
  #results-panel .rp-actions {
    margin-left: auto;
    flex-shrink: 0;
  }

  /* Body / scroll area: comfortable padding, internal scroll for long
     toll lists. .rp-chips and .rp-stats provide their own internal
     padding by default; we zero those out here so padding doesn't
     compound inside the narrow window. */
  #results-panel .rp-body {
    padding: 0;
    overflow-y: auto;
  }
  #results-panel .rp-chips {
    padding: 12px 16px 16px 16px;
  }
  /* In the narrow desktop window the default min-width: 260px max-width: 360px
     forces chips into a single column. Relax to fit comfortably one-per-row
     using full container width. */
  #results-panel .toll-chip {
    flex: 1 1 auto;
    min-width: 0;
    max-width: none;
  }

  /* Stats: stack instead of horizontal flex on the narrow window. The
     existing .rp-cmp grid layout works fine inside this width. */
  #results-panel .rp-stats {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
  }

  /* Floating control panel STAYS visible when the results window opens —
     they don't overlap (top-left vs top-right) and the user may want to
     tweak vehicle/tolerance and re-analyse without closing results.
     Override the universal `body.panel-open #bottom-bar { display: none }`
     rule we added in R43. */
  body.panel-open #bottom-bar { display: flex !important; }

  /* The highway-filter legend at top-right would overlap the results
     panel which now sits in the same corner. Hide it when results is
     open. (Already hidden on mobile via the < 720px media query elsewhere
     in this file; this just extends that to desktop.) */
  body.panel-open #legend { display: none; }
}


/* ════════════════════════════════════════════════════════════════
   R49 — NUCLEAR HEIGHT FIX
   ────────────────────────────────────────────────────────────────
   The floating panel kept rendering taller than its content despite
   height:auto + max-height:none + flex:0 0 auto on children. Last
   resort: maximum-specificity rule using the body.lang-el|body.lang-en
   classes that the i18n system always sets. Source-order last + high
   specificity + !important = this MUST win.

   R99.2: when the user toggles fuel cost on mobile, the bar grew
   tall enough that the previous 60vh cap clipped the origin/dest
   row off the top. Two fixes:
     - Use viewport-minus-topbar-minus-gap so the bar can grow up to
       just below the topbar without ever going past it
     - Add overflow-y: auto so internal scroll handles the case where
       even that's not enough (very small phones / lots of content)
   ════════════════════════════════════════════════════════════════ */
html body main#page-map #bottom-bar {
  height: auto !important;
  min-height: 0 !important;
  max-height: none !important;
  /* fit-content as belt-and-suspenders: forces the box to its content
     width/height intrinsically. Modern browsers all support it. */
  height: fit-content !important;
  /* Cap absolutely at the viewport height minus topbar minus a small
     gap above the bar so it never clips off-screen. */
  max-height: calc(100vh - var(--topbar-h, 56px) - 24px) !important;
  /* If even that's exceeded (very small phones), let the bar scroll
     internally rather than have content clipped off-screen. */
  overflow-y: auto !important;
  overscroll-behavior: contain;
}
html body main#page-map #bottom-bar > * {
  flex: 0 0 auto !important;
  flex-grow: 0 !important;
  flex-shrink: 0 !important;
}


/* ════════════════════════════════════════════════════════════════
   R51 — MOBILE UX: collapsible input island + peek strip
   ────────────────────────────────────────────────────────────────
   On mobile (≤640px), the input island can be collapsed to a small
   "peek" strip at the bottom. Triggered by:
     - Tapping the X (#fp-close-btn) in the island's top-right corner
     - Swiping down on the island (handled in calculator.js)
     - Successful analyze() — auto-collapses so results panel can show

   When body.fp-collapsed is set:
     - #bottom-bar slides off-screen (translateY(110%))
     - #bottom-bar-peek slides in from the bottom
     - #results-panel anchors above the peek strip
   When body.fp-collapsed is NOT set (default):
     - Island visible at the bottom, peek hidden
   ════════════════════════════════════════════════════════════════ */

/* X close button — hidden on desktop, top-right corner on mobile. */
.fp-close-btn {
  display: none;
  position: absolute;
  top: 8px;
  right: 8px;
  z-index: 10;
  width: 28px;
  height: 28px;
  padding: 0;
  border: 1px solid var(--line);
  background: var(--paper);
  color: var(--ink-2);
  border-radius: 50%;
  cursor: pointer;
  align-items: center;
  justify-content: center;
  transition: background-color 0.15s var(--ease), border-color 0.15s var(--ease);
}
.fp-close-btn:hover {
  background: var(--paper-2);
  border-color: var(--line-strong);
  color: var(--ink);
}
.fp-close-btn:focus-visible {
  outline: 2px solid var(--aegean);
  outline-offset: 2px;
}

/* Peek strip — hidden on desktop, slides up from bottom on mobile when
   #bottom-bar is collapsed. The button covers full bottom width with a
   short height so it's easy to tap without occluding much map. */
.fp-peek {
  display: none;  /* desktop: never visible */
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 500;
  width: 100%;
  height: 48px;
  padding: 0 18px;
  border: none;
  border-top: 1px solid var(--line-strong);
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  cursor: pointer;
  align-items: center;
  justify-content: center;
  gap: 10px;
  box-shadow: 0 -4px 16px rgba(26, 31, 46, 0.08);
  /* Slide-in animation when collapsed state is entered. */
  transform: translateY(100%);
  transition: transform 0.28s var(--ease);
}
.fp-peek:active { background: var(--paper-2); }
.fp-peek-emoji {
  font-size: 18px;
  line-height: 1;
  flex-shrink: 0;
}
.fp-peek-text {
  flex-shrink: 1;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  color: var(--ink-2);
}
.fp-peek-chevron {
  flex-shrink: 0;
  color: var(--muted);
}

/* Mobile-only behavior. */
@media (max-width: 640px) {
  /* Show the X close button on mobile — flex display so the SVG centers. */
  .fp-close-btn { display: flex; }

  /* Make space at the top of the island so the X button doesn't overlap
     the pills row. Add a tiny top padding accommodation. */
  #bottom-bar { padding-top: 14px; padding-right: 14px; }

  /* Default mobile state (NOT collapsed): peek hidden, island visible. */
  .fp-peek {
    display: flex;
    transform: translateY(100%);
    pointer-events: none;
  }

  /* Collapsed state: hide island, slide peek in from bottom. The mobile
     rule at line 4463 sets transform: translateX(-50%) to center the
     panel horizontally; we have to combine both transforms here so the
     collapse slide doesn't un-center the panel. */
  body.fp-collapsed #bottom-bar {
    transform: translateX(-50%) translateY(150%) !important;
    pointer-events: none;
    transition: transform 0.28s var(--ease) !important;
  }
  body.fp-collapsed .fp-peek {
    transform: translateY(0);
    pointer-events: auto;
  }

  /* When the island is collapsed (fp-collapsed) AND the results panel
     is open, results sits ABOVE the peek strip so the peek stays
     tappable. The peek is 48px tall. Note: panel-open is the class
     used for the toll SIDE-PANEL (different feature); we use the
     #results-panel.open selector for the analyze results panel.

     R99.4: !important on max-height because the R99.4 mobile rule
     uses !important too; we want this to win when both apply (more
     vertical space available since the island is collapsed). */
  body.fp-collapsed #results-panel.open {
    bottom: 48px;
    max-height: calc(100dvh - var(--topbar-h) - 48px - 8px) !important;
  }

  /* R51: harmonize results panel chrome with the input island on mobile.
     Same vocabulary: flat white surface (no gradient), 16px top corners,
     soft shadow, tight padding.

     R99.4: previously .rp-head held title+stats+actions and .rp-body held
     chips, with .rp-body being the only scroll container. As R95-R99
     added more content into .rp-stats (mobile hero, vs card, breakdown,
     fuel block, freshness pill), .rp-head grew tall enough to consume
     the entire 320px panel height — leaving zero visible space for the
     chips below (which were technically "scrollable" but had no viewport).

     Fix: make the WHOLE panel scroll vertically. Bump max-height so
     users actually see useful amounts of content. The title scrolls
     out of view when reading chips, which is acceptable on mobile —
     the user can swipe up to bring it back, or tap the X via the
     visible top portion. */
  #results-panel {
    border-top-left-radius: 16px;
    border-top-right-radius: 16px;
    box-shadow: 0 -8px 24px rgba(26, 31, 46, 0.12),
                0 -2px 6px rgba(26, 31, 46, 0.06);
    /* The whole panel scrolls. Override the desktop-narrow flex layout
       (rp-head fixed + rp-body scroll) since on mobile we want one
       continuous scroll surface. */
    overflow-y: auto !important;
    overflow-x: hidden;
    /* Generous height — most of the viewport minus topbar minus a small
       gap. Was 320px (--panel-h), too small once R95-R99 added hero/
       fuel/freshness content into .rp-head. */
    max-height: calc(85dvh - var(--topbar-h, 56px)) !important;
    /* Internal scroll bouncing should not leak to the page behind. */
    overscroll-behavior: contain;
  }
  #results-panel .rp-head {
    background: var(--paper);  /* override the gradient */
    padding: 10px 14px;
    gap: 10px;
    /* Don't lock height — content (title+stats+actions) flows naturally
       and scrolls with the rest of the panel. */
    flex-shrink: 0;
  }
  #results-panel .rp-title {
    font-size: var(--text-base);
    font-weight: var(--weight-semibold);
  }
  #results-panel .rp-body {
    padding: 8px 12px 16px 12px;
    /* The parent panel scrolls now, so .rp-body just flows. Was
       overflow-y: auto which trapped scrolling inside this child. */
    overflow: visible !important;
  }
  /* Take-away action buttons compact on mobile — icon-only. The labels
     are read by screen readers via aria-label. */
  #results-panel .rp-action {
    padding: 6px 8px;
    font-size: 0;  /* hide text — only the icon shows */
    line-height: 0;
  }
  #results-panel .rp-action svg {
    font-size: initial;
  }
  /* Bigger, more obvious close button on mobile. */
  #results-panel .rp-close {
    width: 32px;
    height: 32px;
    padding: 0;
    font-size: var(--text-base);
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }

  /* Original #bottom-bar is repositioned for mobile via earlier rules
     (see line 4446). It's bottom-centered. Add transition so the
     collapse slide is smooth. */
  #bottom-bar {
    transition: transform 0.28s var(--ease) !important;
  }
}


/* ════════════════════════════════════════════════════════════════
   R52 — Mobile results panel cleanup
   ────────────────────────────────────────────────────────────────
   Issues addressed (from user screenshot):
   - Map controls overlapping the results header → hide on mobile
     when the input island is collapsed (which is the case whenever
     results is showing on mobile, due to auto-collapse on analyse).
   - Header content clipping on narrow widths (stats row overflowing) →
     stats row drops below header on mobile.
   - AI advice paragraph dominating the panel → wrapped in <details>
     and default-collapsed on mobile so the toll list is above the fold.
   - Panel covering the entire viewport → cap max-height to 70vh so a
     strip of map stays visible at the top.
   ════════════════════════════════════════════════════════════════ */

/* Collapsible advice — works on all viewports. <details>/summary handles
   the open/closed state natively. We just style it. */
.rp-advice-wrap {
  margin: 8px 0 12px 0;
  background: var(--aegean-lt);
  border-left: 3px solid var(--aegean);
  border-radius: var(--radius);
  overflow: hidden;
}
.rp-advice-summary {
  cursor: pointer;
  list-style: none;          /* hide default disclosure triangle */
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 14px;
  font-family: var(--font-body);
  font-weight: var(--weight-medium);
  font-size: var(--text-sm);
  color: var(--ink);
  user-select: none;
}
.rp-advice-summary::-webkit-details-marker { display: none; } /* Safari */
.rp-advice-icon {
  font-size: 16px;
  line-height: 1;
}
.rp-advice-label {
  flex: 1;
}
.rp-advice-chevron {
  color: var(--muted);
  font-size: 12px;
  transition: transform 0.2s var(--ease);
}
.rp-advice-wrap[open] .rp-advice-chevron {
  transform: rotate(180deg);
}
/* When open, the inner advice text appears under the summary. We zero
   out the <div class="rp-advice"> margin so it sits flush. */
.rp-advice-wrap .rp-advice {
  padding: 0 14px 12px 14px;
  background: transparent;
  border-left: none;
  border-radius: 0;
  margin: 0;
  font-size: var(--text-sm);
  line-height: 1.5;
}

/* Desktop: open by default (plenty of vertical space). */
@media (min-width: 720px) {
  .rp-advice-wrap {
    /* On desktop we open the details automatically via CSS — but native
       <details> doesn't honour CSS for open state. Instead, JS could
       set [open]; or we just leave it user-controlled. Let's leave it
       user-controlled — desktop users get the same teaser-then-expand
       interaction, which keeps the panel scannable. */
  }
}

/* Mobile: tightens further + locks results panel below 70vh. */
@media (max-width: 640px) {
  /* Hide map controls when the island is collapsed (which on mobile
     happens whenever results panel is open, due to auto-collapse on
     analyse). This was previously gated on body.panel-open which fires
     for the toll side-panel, NOT for the results panel. */
  body.fp-collapsed #map-controls,
  body.fp-collapsed #legend,
  body.fp-collapsed #mc-basemap-popover { display: none !important; }

  /* Cap the results panel height so a strip of map stays visible at
     the top — keeps the user oriented to where they are. Was either
     unbounded or `max-height: var(--panel-h)` (320px) which on tall
     phones could still feel like a wall of text. */
  #results-panel {
    max-height: 70vh !important;
  }
  body.fp-collapsed #results-panel.open {
    /* When the island is collapsed (peek showing), results sits above
       the peek. Cap so we don't overlap the topbar. */
    max-height: calc(70vh) !important;
    bottom: 48px;
  }

  /* Header layout: title on its own row; stats row on a separate row.
     Was a horizontal flex that overflowed and clipped the right side. */
  #results-panel .rp-head {
    flex-wrap: wrap;
    padding: 10px 12px 8px 12px;
    gap: 6px;
  }
  #results-panel .rp-title {
    flex: 1 1 auto;
    font-size: var(--text-base);
    /* Truncate long route titles with ellipsis instead of clipping. */
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    min-width: 0;
  }
  #results-panel .rp-stats {
    /* Drop to a new full-width row below the title so values aren't
       cropped on narrow phones. Reorder via flex order. */
    order: 99;
    flex: 1 1 100%;
    margin-top: 4px;
    padding-top: 8px;
    border-top: 1px solid var(--line);
    flex-wrap: wrap;
    gap: 10px;
    font-size: var(--text-sm);
  }
  /* R95: on mobile, the print-mode segmented toggle (Full/Summary) and
     the Print button are hidden — printing is a desktop workflow.
     Save button remains visible as the primary action. Users who really
     want to print on mobile can use the browser's native print function
     (Share → Print on iOS, Chrome menu → Print on Android). */
  #results-panel .rp-actions {
    margin-left: auto;
    margin-right: 6px;
    gap: 4px;
  }
  #results-panel .rp-actions .rp-print-mode,
  #results-panel .rp-actions #rp-action-print {
    display: none;
  }
}


/* ════════════════════════════════════════════════════════════════
   R55 DESIGN SYSTEM — Phase 2: button & surface vocabulary
   ────────────────────────────────────────────────────────────────
   Five canonical button variants and three canonical surface variants.
   Each existing button-like element is migrated below to use one of
   these variants + minimal overrides for its specific context.

   Rules of the road:
   - Buttons inherit a consistent baseline (font, padding rhythm,
     transition timing, focus state) from .btn — variant classes only
     change visual treatment, not the structural rhythm.
   - Surfaces are containers; they don't define padding (their content
     does). This makes layout composition cleaner.
   - Old class names continue to work via the migration rules below;
     no HTML changes required this round.
   ════════════════════════════════════════════════════════════════ */

/* ── Button baseline ─────────────────────────────────────────── */
/* Every button variant starts here. Common: font, transition, focus. */
.btn,
.btn-primary,
.btn-secondary,
.btn-ghost,
.btn-icon,
.pill-segment {
  font-family: var(--font-body);
  font-weight: var(--weight-medium);
  font-size: var(--text-sm);
  line-height: var(--leading-tight);
  border: var(--border-hair) solid transparent;
  border-radius: var(--radius);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  white-space: nowrap;
  transition: background-color 0.15s var(--ease),
              border-color     0.15s var(--ease),
              color            0.15s var(--ease),
              box-shadow       0.15s var(--ease),
              transform        0.15s var(--ease);
  -webkit-tap-highlight-color: transparent;
}
.btn:focus-visible,
.btn-primary:focus-visible,
.btn-secondary:focus-visible,
.btn-ghost:focus-visible,
.btn-icon:focus-visible,
.pill-segment:focus-visible {
  outline: 2px solid var(--aegean);
  outline-offset: 2px;
}
.btn:disabled,
.btn-primary:disabled,
.btn-secondary:disabled,
.btn-ghost:disabled,
.btn-icon:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* ── 1. Primary — the CTA. Aegean gradient, white text, lift on hover.
   44px tall (deliberately taller than 40px secondary/ghost) to keep the
   visual hierarchy that says "this is the most important action". The
   existing .analyse-btn was 48px; 44px is the compromise — slightly
   tighter than before but still distinctly the CTA. ── */
.btn-primary {
  background: linear-gradient(180deg, var(--aegean) 0%, var(--aegean-dark) 100%);
  color: var(--text-on-accent);
  font-weight: var(--weight-bold);
  font-size: var(--text-base);
  padding: 0 var(--space-5);
  height: 44px;
  position: relative;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.15),
    0 2px 8px rgba(42,107,158,0.35),
    0 4px 16px rgba(42,107,158,0.18);
}
.btn-primary:hover {
  background: linear-gradient(180deg, var(--aegean-dark) 0%, var(--aegean-dark) 100%);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.2),
    0 4px 14px rgba(42,107,158,0.45),
    0 8px 24px rgba(42,107,158,0.25);
  transform: translateY(-1px);
}
.btn-primary:active {
  transform: translateY(0) scale(0.98);
}
.btn-primary:disabled {
  background: var(--line-strong);
  box-shadow: none;
}

/* ── 2. Secondary — outlined, ink text, blue tint on hover. ── */
.btn-secondary {
  background: var(--surface);
  color: var(--text-primary);
  border-color: var(--border-default);
  padding: 0 var(--space-4);
  height: 40px;
}
.btn-secondary:hover {
  background: var(--aegean-lt);
  border-color: var(--aegean);
  color: var(--aegean);
}

/* ── 3. Ghost — transparent, line border, ink-2 text. ── */
.btn-ghost {
  background: transparent;
  color: var(--ink-2);
  border-color: var(--border-default);
  padding: 6px 10px;
  font-size: var(--text-sm);
}
.btn-ghost:hover {
  background: var(--aegean-lt);
  border-color: var(--aegean);
  color: var(--aegean);
}

/* ── 4. Icon-only — square, transparent or filled. ── */
.btn-icon {
  background: transparent;
  color: var(--ink-2);
  border-color: var(--border-default);
  padding: 0;
  width: 36px;
  height: 36px;
  flex-shrink: 0;
}
.btn-icon:hover {
  background: var(--aegean-lt);
  border-color: var(--aegean);
  color: var(--aegean);
}
.btn-icon.btn-icon-filled {
  background: var(--surface);
}

/* ── 5. Pill segment — sits inside .pill-track (segmented control). ── */
.pill-segment {
  background: transparent;
  color: var(--text-primary);
  border-color: transparent;
  padding: 8px 0;
  flex: 1 1 0;
  min-width: 0;
  border-radius: var(--radius-pill);
  /* Active state applied via .is-active class. */
}
.pill-segment.is-active {
  background: var(--surface-selected);
  color: var(--text-on-accent);
  flex: 0 1 auto;
  padding: 8px var(--space-4);
}
.pill-track {
  display: flex;
  background: var(--surface-inset);
  border-radius: var(--radius-pill);
  padding: 4px;
  gap: 2px;
}

/* ── Surfaces ────────────────────────────────────────────────── */

/* Card — default flat surface for content cards (toll chips, etc.). */
.surface-card {
  background: var(--surface);
  border: var(--border-hair) solid var(--border-default);
  border-radius: var(--radius);
  box-shadow: var(--elev-1);
}

/* Floating — for fixed-position panels that hover over the map. */
.surface-floating {
  background: var(--surface-raised);
  border: var(--border-hair) solid var(--border-strong);
  border-radius: var(--radius-xl);
  box-shadow: var(--elev-3);
}

/* Sheet — bottom-anchored slide-up panels (mobile bottom sheets). */
.surface-sheet {
  background: var(--surface-raised);
  border-top: var(--border-hair) solid var(--border-strong);
  border-top-left-radius: var(--radius-xl);
  border-top-right-radius: var(--radius-xl);
  box-shadow: 0 -8px 24px rgba(26,31,46,0.12),
              0 -2px 6px rgba(26,31,46,0.06);
}


/* ════════════════════════════════════════════════════════════════
   R55 — Existing classes adopt the new baselines via cascading
   ────────────────────────────────────────────────────────────────
   Each existing class gets the same visual treatment as one of the
   variants by inheriting from it. We do this with selector lists
   rather than HTML changes, so no markup edits needed this round.

   The general pattern: declare the existing class as if it WERE the
   new base, then keep only the rules that distinguish it.
   ════════════════════════════════════════════════════════════════ */

/* analyse-btn → btn-primary
   This rule sits LATER in source order than the original .analyse-btn
   rule (line 1902), so it wins on cascade for properties it sets.
   Properties NOT set here fall through to the original rule (e.g. the
   ::before arrow pseudo-element, the disabled state). */
.analyse-btn {
  font-family: var(--font-body);
  font-weight: var(--weight-bold);
  font-size: var(--text-base);
  line-height: var(--leading-tight);
  background: linear-gradient(180deg, var(--aegean) 0%, var(--aegean-dark) 100%);
  color: var(--text-on-accent);
  border: none;
  height: 44px;                  /* was 48px — slightly tighter, still CTA-height */
  padding: 0 var(--space-5);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  white-space: nowrap;
  border-radius: var(--radius);
  position: relative;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.15),
    0 2px 8px rgba(42,107,158,0.35),
    0 4px 16px rgba(42,107,158,0.18);
  transition: background 0.18s var(--ease),
              transform  0.15s var(--ease),
              box-shadow 0.18s var(--ease);
}

/* Ghost-style buttons: rp-close, rp-action, fp-swap, swap-btn, fp-close-btn,
   sp-close. All get the same outlined-pill treatment. */
.rp-close,
.rp-action,
.sp-close {
  font-family: var(--font-body);
  font-weight: var(--weight-medium);
  font-size: var(--text-caption);
  line-height: var(--leading-tight);
  background: transparent;
  color: var(--ink-2);
  border: var(--border-hair) solid var(--border-default);
  padding: 6px var(--space-3);
  cursor: pointer;
  border-radius: var(--radius-pill);
  transition: background-color 0.15s var(--ease),
              border-color     0.15s var(--ease),
              color            0.15s var(--ease);
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  white-space: nowrap;
  flex-shrink: 0;
}
.rp-close:hover,
.rp-action:hover,
.sp-close:hover {
  background: var(--aegean-lt);
  border-color: var(--aegean);
  color: var(--aegean);
}

/* Swap buttons — square icon-only ghost. */
.swap-btn,
.fp-swap {
  background: var(--surface);
  border: var(--border-hair) solid var(--border-default);
  color: var(--ink-2);
  height: 40px;
  width: 40px;
  padding: 0;
  cursor: pointer;
  border-radius: var(--radius);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: var(--text-base);
  transition: background-color 0.18s var(--ease),
              border-color     0.18s var(--ease),
              color            0.18s var(--ease),
              transform        0.18s var(--ease);
  flex-shrink: 0;
}
.swap-btn:hover,
.fp-swap:hover {
  background: var(--aegean-lt);
  border-color: var(--aegean);
  color: var(--aegean);
  transform: rotate(180deg);
}

/* Map controls — square icon buttons, sit in a stacked container. */
.mc-btn {
  background: transparent;
  border: 0;
  color: var(--ink-2);
  cursor: pointer;
  width: 36px;
  height: 36px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background-color 0.15s var(--ease),
              color            0.15s var(--ease);
}
.mc-btn:hover {
  background: var(--aegean-lt);
  color: var(--aegean);
}

/* Pill-segment migration: the existing fp-pill rules already match the
   new pattern. Just declare its track and pill so Phase 3 can drop the
   ad-hoc colors/sizes. (No visual change here.) */

/* ════════════════════════════════════════════════════════════════════════
   R80 — Saved trips (UI promoted in R92)
   ════════════════════════════════════════════════════════════════════════
   Two surfaces:
     1. Save button (.rp-action--save) — sits in the .rp-actions group
        next to Print. Outline = not saved, filled gold = saved. Disabled
        until an analysis is available. Click to toggle saved state.
        (R92: promoted from a tiny absolute-positioned star inside
        .rp-stats where users couldn't find it.)
     2. Picker modal (.st-modal-*) — full-screen overlay opened from the
        topbar overflow menu. Lists saved trips with load / rename / delete
        actions per row.
   Styling philosophy: matches the SPA's existing palette and design
   tokens (paper, ink, aegean) so it feels native rather than bolted-on.
   ════════════════════════════════════════════════════════════════════════ */

/* ── Save button (R92) ────────────────────────────────────────
   Lives in .rp-actions next to Print. Inherits .rp-action's pill
   styling (matching Print visually). The .rp-action--save modifier
   adds the saved/unsaved gold-fill state machine. Disabled state
   (e.g. before first analyze) is handled via the [disabled] attr.

   Was previously a tiny absolute-positioned star INSIDE .rp-stats
   (.rp-stats-save) — users couldn't find it because it sat behind
   the stats grid content and only appeared on hover. Promoting it
   to a peer of Print makes it the prominent action it should be. */
.rp-action--save {
  /* Star icon turns gold when saved; otherwise inherits muted ink. */
}
.rp-action--save:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  pointer-events: none;
}
.rp-action--save.saved {
  background: #fdf6e1;
  border-color: #e8d088;
  color: #8a6210;
}
.rp-action--save.saved svg {
  fill: #c49320;
  stroke: #8a6210;
}
.rp-action--save.saved:hover {
  background: #f8edc8;
  border-color: #c49320;
  color: #6d4c0a;
}

/* ── Modal overlay ───────────────────────────────────────────── */
.st-modal-root {
  position: fixed;
  inset: 0;
  z-index: 9000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
}
.st-modal-root[hidden] { display: none; }
.st-modal-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(26, 31, 46, 0.45);
  backdrop-filter: blur(2px);
}
.st-modal-dialog {
  position: relative;
  width: 100%;
  max-width: 520px;
  max-height: calc(100dvh - 40px);
  background: var(--paper);
  border-radius: 12px;
  border: 1px solid var(--line);
  box-shadow: 0 20px 60px rgba(26, 31, 46, 0.25),
              0 4px 12px rgba(26, 31, 46, 0.10);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  /* Subtle entry animation — modal grows in from 96% scale */
  animation: stModalIn 0.18s var(--ease) both;
}
@keyframes stModalIn {
  from { opacity: 0; transform: scale(0.96); }
  to   { opacity: 1; transform: scale(1); }
}
.st-modal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 16px 18px;
  background: var(--paper-2);
  border-bottom: 1px solid var(--line);
}
.st-modal-head h2 {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  letter-spacing: -0.01em;
  color: var(--ink);
}
.st-modal-close {
  background: transparent;
  border: none;
  width: 32px; height: 32px;
  border-radius: 50%;
  font-size: 18px;
  color: var(--muted);
  cursor: pointer;
  transition: background 0.15s var(--ease), color 0.15s var(--ease);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.st-modal-close:hover { background: var(--line); color: var(--ink); }
.st-modal-close:focus-visible { outline: 2px solid var(--aegean); outline-offset: 1px; }
.st-modal-body {
  flex: 1;
  overflow-y: auto;
  padding: 12px 16px 16px 16px;
}

/* ── List rows ───────────────────────────────────────────────── */
.st-list {
  list-style: none;
  margin: 0; padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.st-row {
  display: flex;
  align-items: stretch;
  gap: 8px;
  padding: 12px 14px;
  background: white;
  border: 1px solid var(--line);
  border-radius: 8px;
  transition: border-color 0.15s var(--ease), box-shadow 0.15s var(--ease);
}
.st-row:hover {
  border-color: var(--aegean-lt);
  box-shadow: 0 1px 4px rgba(42, 107, 158, 0.08);
}
.st-row-main {
  flex: 1;
  min-width: 0;                       /* let children shrink/ellipsize */
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.st-row-name {
  background: transparent;
  border: none;
  padding: 0;
  text-align: left;
  font-family: var(--font-body);
  font-size: var(--text-base);
  font-weight: var(--weight-semibold);
  color: var(--ink);
  cursor: text;                       /* it acts as an editable label */
  letter-spacing: -0.01em;
  line-height: 1.25;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}
.st-row-name:hover { color: var(--aegean); text-decoration: underline; }
.st-row-name:focus-visible { outline: 2px solid var(--aegean); outline-offset: 2px; border-radius: 3px; }

/* R88: inline rename input — replaces .st-row-name when row enters
   rename mode. Visually mirrors the button it replaces (same font, size,
   weight) so the row layout doesn't jump on edit-toggle. */
.st-row-name-input {
  font-family: var(--font-body);
  font-size: var(--text-base);
  font-weight: var(--weight-semibold);
  color: var(--ink);
  letter-spacing: -0.01em;
  line-height: 1.25;
  background: white;
  border: 1px solid var(--aegean);
  border-radius: 4px;
  padding: 4px 8px;
  margin: -4px -8px -4px -8px;        /* offset padding so visible position matches the static label */
  outline: none;
  width: calc(100% + 16px);
  max-width: calc(100% + 16px);
  box-shadow: 0 0 0 3px var(--aegean-lt);
}
.st-row--renaming .st-row-name-input { color: var(--ink); }

/* R88: confirm-delete strip — replaces the entire row contents when
   row enters confirm-delete mode. Soft red accent so the destructive
   action is unambiguous; cancel button is the prominent default. */
.st-row--confirming { border-color: var(--stop, #c4613d); background: #fef7f3; }
.st-row-confirm {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
}
.st-row-confirm-text {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.st-row-confirm-text strong {
  font-size: var(--text-base);
  color: var(--ink);
  font-weight: var(--weight-semibold);
}
.st-row-confirm-name {
  font-size: var(--text-caption);
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.st-row-confirm-actions {
  display: flex;
  gap: 6px;
  flex-shrink: 0;
}
.st-row-btn--cancel {
  /* Inherits .st-row-btn defaults; just ensure it's neutral. */
  background: transparent;
}
.st-row-btn--danger {
  background: var(--stop, #c4613d);
  color: white;
  border-color: var(--stop, #c4613d);
}
.st-row-btn--danger:hover {
  background: #a8502d;
  color: white;
  border-color: #a8502d;
}
.st-row-meta {
  font-size: var(--text-caption);
  color: var(--muted);
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  line-height: 1.3;
}
.st-row-sep { opacity: 0.5; }
.st-row-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 2px;
  font-size: var(--text-caption);
  font-variant-numeric: tabular-nums;
}
.st-row-stat { color: var(--ink); font-weight: var(--weight-semibold); }
.st-row-stat--save { color: var(--go); }
.st-row-stat--muted { color: var(--muted); font-weight: var(--weight-regular); }
/* R100.C: fuel cost pill — purple matches the fuel-block theme. */
.st-row-stat--fuel { color: #8a5cb5; font-weight: var(--weight-regular); }

/* ── Row actions column ──────────────────────────────────────── */
.st-row-actions {
  display: flex;
  flex-direction: column;
  gap: 4px;
  align-items: stretch;
  flex-shrink: 0;
}
.st-row-btn {
  background: transparent;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  font-family: var(--font-body);
  font-size: var(--text-caption);
  font-weight: var(--weight-semibold);
  color: var(--ink-2);
  cursor: pointer;
  padding: 6px 12px;
  transition: all 0.15s var(--ease);
  white-space: nowrap;
  line-height: 1;
}
.st-row-btn:hover {
  background: var(--aegean-lt);
  color: var(--aegean);
  border-color: var(--aegean);
}
.st-row-btn:focus-visible {
  outline: 2px solid var(--aegean);
  outline-offset: 2px;
}
.st-row-btn--load {
  background: var(--aegean);
  color: white;
  border-color: var(--aegean);
}
.st-row-btn--load:hover {
  background: #205074;
  color: white;
  border-color: #205074;
}
.st-row-btn--del {
  width: 28px; height: 28px;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  color: var(--muted);
  align-self: flex-end;
}
.st-row-btn--del:hover {
  background: #fde8e0;
  color: var(--stop);
  border-color: var(--stop);
}

/* ── Empty state ─────────────────────────────────────────────── */
.st-empty {
  text-align: center;
  padding: 32px 16px;
  color: var(--muted);
}
.st-empty p { margin: 0 0 6px 0; }
.st-empty-hint { font-size: var(--text-sm); }

/* ── Mobile tightening ───────────────────────────────────────── */
@media (max-width: 600px) {
  .st-modal-dialog {
    max-height: calc(100dvh - 32px);
    border-radius: 10px;
  }
  .st-modal-head { padding: 12px 14px; }
  .st-modal-body { padding: 10px 12px 14px 12px; }
  .st-row {
    flex-direction: column;
    gap: 8px;
    padding: 10px 12px;
  }
  .st-row-actions {
    flex-direction: row;
    align-items: center;
    gap: 6px;
  }
  .st-row-btn--del { align-self: auto; margin-left: auto; }
  .st-row-btn--load { flex: 1; }
}

/* ════════════════════════════════════════════════════════════════════════
   R83 — Summary mode (results panel filter)
   ════════════════════════════════════════════════════════════════════════
   When the user picks "Περίληψη / Summary" in the print-mode toggle,
   the same toggle ALSO filters the on-screen results panel: only AVOID
   tolls are visible (the actionable ones). PAY tolls hide. The toggle
   thus becomes the visible feedback for itself — no need to click Print
   to see what changed.

   The body class `results-mode-summary` is set/unset by the radio
   change handler in calculator.js (R83 syncResultsToMode).
   ════════════════════════════════════════════════════════════════════════ */

body.results-mode-summary .toll-chip.verdict-PAY,
body.results-mode-summary .toll-chip.verdict-MARGINAL_PAY {
  display: none;
}

/* Empty state for the case where there are zero AVOIDs on the route.
   Always rendered into .rp-chips by renderResults(); shown only when
   in Summary mode AND the chips container is marked as having no
   AVOIDs (renderResults sets data-has-avoids="0" or "1"). */
.rp-summary-empty { display: none; }
body.results-mode-summary .rp-chips[data-has-avoids="0"] .rp-summary-empty {
  display: block;
}
.rp-summary-empty {
  padding: 20px 16px;
  text-align: center;
  color: var(--muted);
  font-size: var(--text-sm);
  background: var(--paper-2);
  border: 1px dashed var(--line);
  border-radius: 6px;
  margin: 8px 0;
}
.rp-summary-empty strong {
  display: block;
  font-size: var(--text-base);
  color: var(--ink);
  margin-bottom: 4px;
}

/* ════════════════════════════════════════════════════════════════════════
   R88 — Mobile touch target expansion
   ════════════════════════════════════════════════════════════════════════
   Apple HIG and Material both recommend ≥44×44 (px or pt) for any
   interactive control. Several of our close/dismiss/action buttons are
   smaller than that for visual reasons (panel headers are tight, save
   star sits in a 28px corner, etc.). This block expands the TAP area
   without changing the visual size — uses an invisible ::before overlay
   that extends beyond the button bounds via negative margins.

   Applied only on touch-likely viewports (max-width: 740px). On desktop
   with a mouse, smaller targets are fine — visual density wins there.
   ════════════════════════════════════════════════════════════════════════ */

@media (max-width: 740px) {
  /* The pattern: position: relative on the button, then a ::before that's
     positioned absolutely with negative inset to extend the click area
     on all sides. Pointer-events: pass through the visible button styling
     (its hover etc. still work) but the bigger area catches touches. */
  .rp-close,
  .sp-close,
  .st-modal-close,
  .first-tip-close,
  .help-popover-close,
  .st-row-btn--del,
  .overflow-trigger-btn {
    position: relative;
  }
  .rp-close::before,
  .sp-close::before,
  .st-modal-close::before,
  .first-tip-close::before,
  .help-popover-close::before,
  .st-row-btn--del::before,
  .overflow-trigger-btn::before {
    content: '';
    position: absolute;
    /* Inset enough so the total tap area is at least 44×44. Most of these
       buttons are 28-32px, so we need to extend ~6-8px on each side. */
    inset: -8px;
    /* Transparent — invisible, but receives pointer events. */
    background: transparent;
    /* Sit above the button content so taps register on the overlay,
       which propagates to the button via event bubbling. */
    z-index: 1;
  }
}

/* ════════════════════════════════════════════════════════════════════════
   R97 — Inline fuel block (in the bottom bar)
   ════════════════════════════════════════════════════════════════════════
   The R96 settings modal was removed in favor of inline controls. The
   fuel block is a bordered card slotted between the vehicle pills and the
   tolerance row in #bottom-bar.

   R97.2: pills moved back into the always-visible .fuel-row alongside
   the toggle (hidden via display:none when off, visible when on). The
   Update button moved into the price input-wrap since it only refreshes
   the price.

   Structure:
     .fuel-block              ← bordered container
       .fuel-row              ← always visible
         .fuel-pills          ← hidden when off; pills+toggle when on
         .fuel-toggle-chip    ← "Καύσιμο" toggle (turns the feature on/off)
       .fuel-expand           ← collapsed by default (grid-template-rows: 0fr)
         .fuel-expand-inner   ← clipped to allow height animation
           .fuel-inputs       ← two columns: price (with Update) + consumption
             .fuel-input-wrap--price
               .fuel-input-controls   ← flex row: input + Update button
                 .fuel-input-row      ← input
                 .fuel-update-btn     ← refresh button (price-only)
             .fuel-input-wrap--consumption
               .fuel-input-row        ← consumption input only
           .fuel-meta         ← "Last updated: 2h ago · openvan.camp"

   Animation: when .fuel-block.on is added, .fuel-expand goes from
   grid-template-rows: 0fr → 1fr in 250ms. The inner div has overflow:hidden
   to clip during transition. No JS measurement of content height needed.
   ════════════════════════════════════════════════════════════════════════ */

.fuel-block {
  display: flex;
  flex-direction: column;
  background: var(--paper-2, #faf7f0);
  border: 1px solid var(--line);
  border-radius: 12px;
  overflow: hidden;
  transition: border-color 0.2s var(--ease, ease);
}
.fuel-block.on {
  border-color: #d4c2e4;
}

/* Top row: pills (left) + toggle chip (right). When the block is off,
   pills are hidden via display:none — only the toggle is visible.
   When on, both share the row with space-between justification. */
.fuel-row {
  display: flex;
  align-items: center;
  justify-content: flex-end;     /* toggle alone aligns right when off */
  gap: 10px;
  padding: 8px 10px;
  flex-wrap: wrap;
  row-gap: 6px;
}
.fuel-block.on .fuel-row {
  justify-content: space-between;
}
/* Pills are hidden when the block is off; visible alongside the toggle
   when on. We use display:none rather than opacity so the layout
   reclaims the space when off (toggle aligns flush right). */
.fuel-pills {
  display: none;
  background: var(--paper, #faf8f3);
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  padding: 2px;
  font-size: var(--text-caption);
  font-weight: var(--weight-medium);
}
.fuel-block.on .fuel-pills {
  display: inline-flex;
}
.fuel-pill {
  padding: 5px 10px;
  border-radius: var(--radius-pill);
  border: none;
  background: transparent;
  font-family: var(--font-body);
  font-size: inherit;
  font-weight: inherit;
  color: var(--ink-2);
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.15s var(--ease, ease),
              color 0.15s var(--ease, ease);
}
.fuel-pill:hover:not(.is-active) { background: rgba(0, 0, 0, 0.04); }
.fuel-pill.is-active {
  background: var(--ink, #1a1f2e);
  color: var(--paper, #faf8f3);
}
.fuel-pill:focus-visible {
  outline: 2px solid var(--aegean);
  outline-offset: 1px;
}

/* Cost toggle chip (anchored right) */
.fuel-toggle-chip {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 10px 5px 8px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--line);
  background: var(--paper, #faf8f3);
  font-family: var(--font-body);
  font-size: var(--text-caption);
  font-weight: var(--weight-semibold);
  color: var(--ink-2);
  cursor: pointer;
  user-select: none;
  transition: background 0.15s var(--ease, ease),
              border-color 0.15s var(--ease, ease),
              color 0.15s var(--ease, ease);
}
.fuel-toggle-chip:hover {
  background: var(--paper-2, #faf7f0);
}
.fuel-toggle-chip.on {
  background: #e8f3ec;
  border-color: #2d8451;
  color: #2d8451;
}
.fuel-toggle-chip:focus-visible {
  outline: 2px solid var(--aegean);
  outline-offset: 1px;
}
.fuel-toggle-knob {
  position: relative;
  width: 24px;
  height: 14px;
  background: #c0c4cd;
  border-radius: 100px;
  flex-shrink: 0;
  transition: background 0.2s var(--ease, ease);
}
.fuel-toggle-chip.on .fuel-toggle-knob { background: #2d8451; }
.fuel-toggle-knob::after {
  content: '';
  position: absolute;
  top: 1px;
  left: 1px;
  width: 12px;
  height: 12px;
  background: white;
  border-radius: 50%;
  transition: left 0.2s var(--ease, ease);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
}
.fuel-toggle-chip.on .fuel-toggle-knob::after { left: 11px; }

/* Expanding sub-row (price + consumption + Update + meta) */
.fuel-expand {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.25s var(--ease, ease);
}
.fuel-block.on .fuel-expand {
  grid-template-rows: 1fr;
}
.fuel-expand-inner {
  overflow: hidden;
}

.fuel-inputs {
  display: flex;
  align-items: flex-end;
  gap: 10px;
  padding: 8px 10px 10px;
  border-top: 1px dashed #d4c2e4;
  flex-wrap: wrap;
  row-gap: 8px;
}
.fuel-input-wrap {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
  flex: 1 1 130px;
}
/* R104.4: with the Update button hidden the price column no longer needs
   to be wider than the consumption column. Equal flex keeps them
   visually balanced side-by-side at all viewport widths. */
.fuel-input-wrap--price       { flex: 1 1 0; }
.fuel-input-wrap--consumption { flex: 1 1 0; }

/* The price column's input + Update button live on the same horizontal
   line. On narrow screens (when the column itself is squeezed), the
   button drops below the input via flex-wrap. */
.fuel-input-controls {
  display: flex;
  align-items: stretch;
  gap: 6px;
  flex-wrap: wrap;
}
.fuel-input-controls .fuel-input-row {
  flex: 1 1 90px;
}
/* R97.1: label is now a flex row [name][unit]. Name is small caps purple
   (the field title), unit is mono muted (the qualifier). Visual hierarchy:
   the field name leads, the unit clarifies. */
.fuel-input-label {
  display: flex;
  align-items: baseline;
  gap: 6px;
  flex-wrap: wrap;
  font-size: var(--text-micro);
  color: #8a5cb5;       /* purple — fuel theme */
  font-weight: var(--weight-semibold);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.fuel-input-unit {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  color: var(--muted);
  font-weight: var(--weight-medium);
  text-transform: none;
  letter-spacing: 0.02em;
  white-space: nowrap;
}
.fuel-input-row {
  display: flex;
  align-items: center;
  background: var(--paper, #faf8f3);
  border: 1px solid #d4c2e4;
  border-radius: 8px;
  height: 34px;
  overflow: hidden;
  transition: border-color 0.15s var(--ease, ease),
              box-shadow 0.15s var(--ease, ease);
}
.fuel-input-row:focus-within {
  border-color: #8a5cb5;
  box-shadow: 0 0 0 2px #f0e8f8;
}
.fuel-input {
  flex: 1;
  min-width: 0;
  border: none;
  background: transparent;
  padding: 0 10px;
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  font-variant-numeric: tabular-nums;
  color: var(--ink);
  height: 100%;
}
.fuel-input:focus { outline: none; }

.fuel-update-btn {
  flex-shrink: 0;
  height: 34px;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 0 10px;
  border: 1px solid #d4c2e4;
  border-radius: 8px;
  background: var(--paper, #faf8f3);
  font-family: var(--font-body);
  font-size: var(--text-caption);
  font-weight: var(--weight-semibold);
  color: #8a5cb5;
  cursor: pointer;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  white-space: nowrap;
  transition: background 0.15s var(--ease, ease),
              border-color 0.15s var(--ease, ease),
              color 0.15s var(--ease, ease);
}
.fuel-update-btn:hover:not(:disabled) {
  background: #f0e8f8;
}
.fuel-update-btn:focus-visible {
  outline: 2px solid var(--aegean);
  outline-offset: 1px;
}
.fuel-update-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}
.fuel-update-btn-arrow {
  font-size: 0.85rem;
  line-height: 1;
  display: inline-block;
}
.fuel-update-btn.loading {
  pointer-events: none;
}
.fuel-update-btn.loading .fuel-update-btn-arrow {
  animation: fuelSpin 1s linear infinite;
}
@keyframes fuelSpin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}
.fuel-update-btn.success {
  background: #e8f3ec;
  border-color: #2d8451;
  color: #2d8451;
}
.fuel-update-btn.error {
  background: #f3e3d8;
  border-color: var(--stop, #c4613d);
  color: var(--stop, #c4613d);
}
@media (prefers-reduced-motion: reduce) {
  .fuel-expand {
    transition: none;
  }
  .fuel-update-btn.loading .fuel-update-btn-arrow {
    animation: none;
  }
}

.fuel-meta {
  font-size: var(--text-micro);
  color: var(--muted);
  font-style: italic;
  padding: 0 10px 8px;
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}
.fuel-meta a {
  color: var(--aegean);
  text-decoration: none;
  border-bottom: 1px dotted var(--aegean);
  font-style: normal;
}
.fuel-meta a:hover { color: #1d4e74; }
.fuel-meta .fresh {
  color: #2d8451;
  font-style: normal;
  font-weight: var(--weight-medium);
}
.fuel-meta .stale {
  color: #b34d2a;
  font-style: normal;
  font-weight: var(--weight-medium);
}
.fuel-meta .err {
  color: var(--stop, #c4613d);
  font-style: normal;
  font-weight: var(--weight-medium);
}

/* ── Mobile: tighter spacing, columns stack, Update wraps below price ── */
@media (max-width: 540px) {
  .fuel-row {
    gap: 6px;
    padding: 6px 8px;
  }
  .fuel-pills { font-size: var(--text-caption); }
  .fuel-pill { padding: 4px 7px; }
  .fuel-toggle-chip {
    font-size: var(--text-caption);
    padding: 4px 8px 4px 6px;
  }
  /* R104.4: at narrow widths price and consumption stay side-by-side
     since both columns are now small (no Update button to host).
     If the flex base ever pushes them too tight, dropping back to
     stacked at <380px is a one-line addition. */
  .fuel-input-controls .fuel-update-btn {
    flex: 1 0 100%;
    justify-content: center;
  }
}

/* ════════════════════════════════════════════════════════════════════════
   R98 — Unified interaction system
   ════════════════════════════════════════════════════════════════════════
   Single source of truth for button feedback. Achieves consistency
   without rewriting individual button styles:
     - All major buttons get a subtle `:active` press transform
     - All :focus-visible rings normalize to var(--focus-ring)
     - prefers-reduced-motion disables transforms

   Applied at the end so these rules win over the per-button overrides.
   ════════════════════════════════════════════════════════════════════════ */

/* Unified press feedback. Buttons scale slightly on tap/click for
   tactile-feeling interaction. Excludes inputs and links (only buttons
   should "press"). */
.analyse-btn:active,
.btn-primary:active,
.btn-secondary:active,
.btn-ghost:active,
.btn-icon:active,
.fp-pill:active,
.fuel-pill:active,
.fuel-toggle-chip:active,
.fuel-update-btn:active:not(:disabled),
.tv-pill:active,
.veh-option:active,
.sp-filter-btn:active,
.sp-dir:active,
.swap-btn:active,
.fp-swap:active,
.st-row-btn:active,
.rp-action--save:active,
.rp-action--print:active,
.rp-action--share:active,
.legend-ramps-btn:active,
.first-tip-close:active,
.fp-close-btn:active,
.overflow-trigger:active {
  transform: scale(var(--press-scale));
  transition: transform var(--transition-fast) ease;
}

/* Unified focus ring. Buttons that already have outline:none + a
   custom inset ring (rare) keep theirs. Most converge here. */
.fp-pill:focus-visible,
.fuel-pill:focus-visible,
.fuel-toggle-chip:focus-visible,
.fuel-update-btn:focus-visible,
.tv-pill:focus-visible,
.fp-close-btn:focus-visible,
.swap-btn:focus-visible,
.fp-swap:focus-visible,
.st-row-btn:focus-visible,
.rp-action--save:focus-visible,
.rp-action--print:focus-visible,
.rp-action--share:focus-visible,
.legend-ramps-btn:focus-visible,
.first-tip-close:focus-visible {
  outline: var(--focus-ring);
  outline-offset: var(--focus-ring-offset);
}

@media (prefers-reduced-motion: reduce) {
  .analyse-btn:active,
  .btn-primary:active,
  .btn-secondary:active,
  .btn-ghost:active,
  .btn-icon:active,
  .fp-pill:active,
  .fuel-pill:active,
  .fuel-toggle-chip:active,
  .fuel-update-btn:active:not(:disabled),
  .tv-pill:active,
  .veh-option:active,
  .sp-filter-btn:active,
  .sp-dir:active,
  .swap-btn:active,
  .fp-swap:active,
  .st-row-btn:active,
  .rp-action--save:active,
  .rp-action--print:active,
  .rp-action--share:active,
  .legend-ramps-btn:active,
  .first-tip-close:active,
  .fp-close-btn:active,
  .overflow-trigger:active {
    transform: none;
  }
}

/* ════════════════════════════════════════════════════════════════════════
   R99 — Trust signals (footer freshness pill + About page + source link)
   ════════════════════════════════════════════════════════════════════════
   Three groups of styles:
     1. Footer redesign — two-row layout with brand+freshness pill on top,
        legal links on bottom. The pill has 3 freshness tiers (fresh/aging/
        stale) coloring a dot indicator.
     2. About page (#page-about) — long-form prose page with sections,
        sources list, methodology explainer.
     3. Side panel source link — small "Πηγή: domain.gr ↗" line under the
        price in the toll detail panel.

   Footer changed from a single line to two rows, so existing footer rules
   that target .site-footer-inner directly still work; we just stack
   .footer-row containers inside.
   ════════════════════════════════════════════════════════════════════════ */

/* ── Footer two-row layout ─────────────────────────────────── */
.site-footer-inner {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.footer-row {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.footer-row--top {
  justify-content: space-between;
}
.footer-row--bottom {
  font-size: var(--text-caption);
  color: var(--muted);
}

/* ── Freshness pill (footer + reusable) ───────────────────── */
.footer-data-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px 3px 8px;
  border-radius: var(--radius-pill);
  background: var(--paper-2, #faf7f0);
  border: 1px solid var(--line);
  font-size: var(--text-micro);
  font-weight: var(--weight-medium);
  color: var(--ink-2);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  cursor: help;
}
.freshness-dot {
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  flex-shrink: 0;
  background: var(--muted);
}
.freshness-fresh .freshness-dot {
  background: #2d8451;       /* green = fresh, <90 days */
  box-shadow: 0 0 0 2px rgba(45, 132, 81, 0.15);
}
.freshness-aging .freshness-dot {
  background: #b58a2a;       /* amber = aging, 90-270 days */
}
.freshness-stale .freshness-dot {
  background: #b34d2a;       /* terracotta = stale, 9+ months */
}
.freshness-fresh {
  border-color: rgba(45, 132, 81, 0.3);
}

/* ════════════════════════════════════════════════════════════════════════
   About page (#page-about)
   ════════════════════════════════════════════════════════════════════════ */

.about-content {
  max-width: 720px;
  margin: 0 auto;
}
.about-content .page-header {
  margin-bottom: 28px;
}

.about-section {
  margin-bottom: 32px;
}
.about-section:last-child {
  margin-bottom: 12px;
}

.about-heading {
  font-family: var(--font-display, var(--font-body));
  font-size: var(--text-lg);
  font-weight: var(--weight-regular);
  letter-spacing: -0.015em;
  color: var(--ink);
  margin: 0 0 10px;
  line-height: var(--leading-tight);
}
.about-subheading {
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--ink-2);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin: 18px 0 8px;
}

.about-section p {
  font-size: var(--text-base);
  line-height: var(--leading-prose);
  color: var(--ink-2);
  margin: 0 0 12px;
}
.about-section p:last-child {
  margin-bottom: 0;
}
.about-section p strong {
  color: var(--ink);
  font-weight: var(--weight-semibold);
}
.about-section a {
  color: var(--aegean);
  text-decoration: none;
  border-bottom: 1px dotted var(--aegean);
}
.about-section a:hover {
  color: #1d4e74;
  border-bottom-style: solid;
}

/* ── About: freshness banner ─────────────────────────────── */
.about-freshness {
  background: var(--paper-2, #faf7f0);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 12px 14px;
  margin: 16px 0 20px;
  font-size: var(--text-sm);
  color: var(--ink-2);
  font-variant-numeric: tabular-nums;
}
.about-freshness.freshness-fresh {
  background: #f1f8f3;
  border-color: rgba(45, 132, 81, 0.25);
}
.about-freshness.freshness-aging {
  background: #faf3e3;
  border-color: rgba(181, 138, 42, 0.3);
}
.about-freshness.freshness-stale {
  background: #f7e9e2;
  border-color: rgba(179, 77, 42, 0.3);
}
.about-freshness-row {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.about-freshness-row + .about-freshness-row {
  margin-top: 4px;
}
.about-freshness-row strong {
  color: var(--ink);
  font-weight: var(--weight-semibold);
}
.about-freshness-row--next {
  font-size: var(--text-caption);
  color: var(--muted);
  padding-left: 15px;       /* aligns with text after dot in row above */
}
.about-freshness-age {
  color: var(--muted);
  font-size: var(--text-caption);
}

/* ── About: sources list ─────────────────────────────────── */
.about-sources-list {
  list-style: none;
  padding: 0;
  margin: 0 0 12px;
  display: grid;
  grid-template-columns: 1fr;
  gap: 8px;
}
.about-sources-list li {
  font-size: var(--text-sm);
  color: var(--ink-2);
  padding: 8px 12px;
  background: var(--paper-2, #faf7f0);
  border: 1px solid var(--line);
  border-radius: 8px;
  line-height: 1.45;
}
.about-sources-list a {
  font-weight: var(--weight-semibold);
}
.about-routes-note {
  font-size: var(--text-caption);
  color: var(--muted);
  font-style: italic;
  margin-top: 12px !important;
}

/* ── About: author section gets a slightly different feel ── */
.about-section--author {
  border-top: 1px solid var(--line);
  padding-top: 24px;
  margin-top: 32px;
}

@media (max-width: 640px) {
  .about-content {
    padding: 0 4px;
  }
  .about-heading {
    font-size: var(--text-base);
  }
  .about-section p {
    font-size: var(--text-sm);
  }
}

/* ════════════════════════════════════════════════════════════════════════
   Side-panel toll detail — source link (R99)
   ════════════════════════════════════════════════════════════════════════ */

.sp-source {
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px dashed var(--line);
  font-size: var(--text-micro);
  color: var(--muted);
  font-family: var(--font-mono);
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}
.sp-source-label {
  font-weight: var(--weight-medium);
}
.sp-source-link {
  color: var(--aegean);
  text-decoration: none;
  border-bottom: 1px dotted var(--aegean);
}
.sp-source-link:hover {
  color: #1d4e74;
  border-bottom-style: solid;
}

/* Mobile: footer rows can wrap; freshness pill drops to its own line */
@media (max-width: 540px) {
  .footer-row--top {
    flex-direction: column;
    align-items: flex-start;
    gap: 4px;
  }
  .footer-data-pill {
    font-size: 0.6rem;
  }
}

/* ════════════════════════════════════════════════════════════════════════
   R99.1 — Result-panel freshness pill
   ════════════════════════════════════════════════════════════════════════
   Renders at the bottom of the result panel (below the comparison table
   on desktop, below the mobile breakdown). Same color tiers as the
   footer pill. Includes a "how this works →" link to the about page.
   ════════════════════════════════════════════════════════════════════════ */

.rp-freshness {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  margin-top: 12px;
  background: var(--paper-2, #faf7f0);
  border: 1px solid var(--line);
  border-radius: 8px;
  font-size: var(--text-micro);
  color: var(--ink-2);
  font-variant-numeric: tabular-nums;
  flex-wrap: wrap;
}
.rp-freshness.freshness-fresh {
  background: #f1f8f3;
  border-color: rgba(45, 132, 81, 0.2);
}
.rp-freshness.freshness-aging {
  background: #faf3e3;
  border-color: rgba(181, 138, 42, 0.25);
}
.rp-freshness.freshness-stale {
  background: #f7e9e2;
  border-color: rgba(179, 77, 42, 0.25);
}
.rp-freshness-text {
  flex: 1;
  min-width: 0;
}
.rp-freshness-more {
  color: var(--aegean);
  text-decoration: none;
  border-bottom: 1px dotted var(--aegean);
  font-weight: var(--weight-medium);
  white-space: nowrap;
}
.rp-freshness-more:hover {
  color: #1d4e74;
  border-bottom-style: solid;
}

/* ════════════════════════════════════════════════════════════════════════
   R99.2 — Drag handle for mobile bottom-bar
   ════════════════════════════════════════════════════════════════════════
   Universal "bottom sheet" pattern: small rounded gray bar centered at the
   top of the panel, signals to mobile users that the panel is draggable.
   Hidden on desktop. Also tappable as an alternative to swipe.
   ════════════════════════════════════════════════════════════════════════ */

.fp-drag-handle {
  display: none;       /* hidden on desktop */
  position: absolute;
  top: 5px;
  left: 50%;
  transform: translateX(-50%);
  width: 56px;
  height: 18px;
  padding: 0;
  border: none;
  background: transparent;
  cursor: grab;
  z-index: 5;          /* above the bar's content but below the X */
}
.fp-drag-handle:active {
  cursor: grabbing;
}
.fp-drag-handle-bar {
  display: block;
  width: 36px;
  height: 4px;
  margin: 0 auto;
  border-radius: 100px;
  background: var(--line-strong, #c0c4cd);
  transition: background var(--transition-fast, 0.15s) ease,
              width var(--transition-fast, 0.15s) ease;
}
.fp-drag-handle:hover .fp-drag-handle-bar,
.fp-drag-handle:focus-visible .fp-drag-handle-bar {
  background: var(--ink-2);
  width: 44px;
}

/* Mobile: show the drag handle and add top padding to the bar so content
   doesn't sit under it. */
@media (max-width: 640px) {
  .fp-drag-handle { display: block; }
  /* The bar already has padding-top: 14px from the .fp-close-btn rule
     (line ~5479). Bump slightly to accommodate the handle (which sits
     above row 1 at top:5). */
  #bottom-bar { padding-top: 18px !important; }
}

@media (prefers-reduced-motion: reduce) {
  .fp-drag-handle-bar { transition: none; }
}

/* ════════════════════════════════════════════════════════════════════════
   R100 — Internal links on routes grid cells
   ════════════════════════════════════════════════════════════════════════
   Each routes-cell wraps its content in an <a href> pointing at the
   prerendered page for that route, when one exists. The anchor needs to
   look the same as the cell content used to (no underline, inherit
   color). It also needs to be a block-level child so right-click "Open
   link in new tab" hits the whole cell area, not just the text.
   ════════════════════════════════════════════════════════════════════════ */

.routes-cell .rc-link {
  display: block;
  color: inherit;
  text-decoration: none;
  /* Negate the parent <td>'s padding so the anchor fills the cell —
     better hit area for "open in new tab" right-click. The td already
     has padding: 6px 9px (or 6px 8px on mobile), so the anchor uses
     margin-negative to extend to the cell edges, then re-pads its own
     content to keep visual layout identical. */
  margin: -6px -9px;
  padding: 6px 9px;
}
.routes-cell .rc-link:hover {
  /* Hover stays on the parent .routes-cell (filter brightness 0.96).
     No additional underline or color change here — keeps the cell's
     existing hover feel. */
}
.routes-cell .rc-link:focus-visible {
  /* Keyboard focus on the link gets the unified focus ring rather than
     the browser default outline, which would clip oddly inside the td. */
  outline: var(--focus-ring);
  outline-offset: -2px;
}

@media (max-width: 720px) {
  .routes-cell .rc-link {
    margin: -6px -8px;
    padding: 6px 8px;
  }
}
@media (max-width: 480px) {
  .routes-cell .rc-link {
    margin: -5px -6px;
    padding: 5px 6px;
  }
}
