/* =========================================================
   Ibadan Routes design system
   Palette: blue, from deep navy #03195b through #1951fc to pale #cbe9fd.
   Amber is kept for one job only - telling the destination apart from the
   start, and marking the cheapest fare - because a second blue could not.
   Mobile first (320–414px), then tablet and desktop layouts.
   ========================================================= */
:root {
  --primary: #1951FC;          /* actions, links, selected states, bus */
  --primary-hover: #0B2CB1;
  --primary-50: #EDF5FE;       /* tint behind icons and selected rows */
  --primary-100: #CBE9FD;
  --secondary: #03195B;        /* deep navy: headings, dark surfaces */
  --accent: #F5A524;           /* destination, cheapest fare */
  --accent-ink: #4A3000;       /* text on amber */
  --accent-50: #FFF5DE;
  --bg: #F4F7FD;
  --surface: #FFFFFF;
  --surface-2: #EDF2FA;
  --line: #DCE5F3;
  --line-strong: #BFCFE6;
  --text: #0A1838;
  --text-2: #51607D;
  --success: #0E7A55;
  --success-50: #E5F5EE;
  --warning: #9A5B00;
  --warning-50: #FFF3DA;
  --error: #C2362B;
  --error-50: #FDECEA;

  /* transport modes: icon + label always shown, colour is a helper only */
  --m-bus: var(--primary);
  --m-keke: #C98600;
  --m-okada: var(--secondary);
  --m-ride: var(--success);
  --m-walk: #7A8294;

  --radius: 12px;
  --radius-sm: 8px;
  --radius-pill: 999px;
  --shadow-1: 0 1px 2px rgba(3, 25, 91, .07), 0 1px 3px rgba(3, 25, 91, .06);
  --shadow-2: 0 8px 28px rgba(3, 25, 91, .16);
  --topbar-h: 56px;
  --tabbar-h: 64px;
  --font: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --ease: cubic-bezier(.2, .8, .2, 1);
  color-scheme: light;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) { --primary: #3781FC; --primary-hover: #6AA3FD; --primary-50: #23262B; --primary-100: #30343A;
    --secondary: #CBE9FD; --accent: #FFB940; --accent-ink: #2B1C00; --accent-50: #2A2418;
    --bg: #000000; --surface: #15171A; --surface-2: #22262B; --line: #3A4046; --line-strong: #525A61;
    --text: #E7E9EA; --text-2: #A7AEB4;
    --success: #43C98F; --success-50: #15241E; --warning: #F2B451; --warning-50: #28231A;
    --error: #FF7B6F; --error-50: #2A1B1A;
    --m-keke: #F2B13B; --m-okada: #C9CFE6; --m-walk: #8C93A8;
    --shadow-1: 0 1px 2px rgba(0, 0, 0, .6); --shadow-2: 0 10px 30px rgba(0, 0, 0, .7);
    color-scheme: dark; }
}
:root[data-theme="dark"] { --primary: #3781FC; --primary-hover: #6AA3FD; --primary-50: #23262B; --primary-100: #30343A;
    --secondary: #CBE9FD; --accent: #FFB940; --accent-ink: #2B1C00; --accent-50: #2A2418;
    --bg: #000000; --surface: #15171A; --surface-2: #22262B; --line: #3A4046; --line-strong: #525A61;
    --text: #E7E9EA; --text-2: #A7AEB4;
    --success: #43C98F; --success-50: #15241E; --warning: #F2B451; --warning-50: #28231A;
    --error: #FF7B6F; --error-50: #2A1B1A;
    --m-keke: #F2B13B; --m-okada: #C9CFE6; --m-walk: #8C93A8;
    --shadow-1: 0 1px 2px rgba(0, 0, 0, .6); --shadow-2: 0 10px 30px rgba(0, 0, 0, .7);
    color-scheme: dark; }

/* ---------- Base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0; font-family: var(--font); font-size: 16px; line-height: 1.5; color: var(--text); background: var(--bg);
  -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;
}
h1, h2, h3, h4 { margin: 0; line-height: 1.25; color: var(--text); }
p { margin: 0; }
a { color: var(--primary); }
button, input, select, textarea { font: inherit; color: inherit; }
button {
  cursor: pointer;
  /* Safari applies its own layout inside a native button, which pushes centred content
     off to one side. Opting out of the native appearance makes every browser agree. */
  appearance: none; -webkit-appearance: none;
}
/* Any button that holds nothing but an icon gets no padding, so grid centring is the only
   thing deciding where that icon sits. The explicit list covers browsers without :has(). */
.icon-btn, .swap, .count-btn, .tab, .avatar, .brand-mark, .ic-lead, .map-btn, .mode-chip, .rc-chev { padding: 0; }
/* :where() keeps this at zero specificity, so a button that sets its own padding - like
   the Listen button, whose label is a bare text node beside the icon - still wins. */
button:where(:has(> svg.ic:only-child)) { padding: 0; }
[hidden] { display: none !important; }
.sr-only { position: absolute !important; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.ic { width: 20px; height: 20px; flex: none; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
:focus-visible { outline: 3px solid var(--primary); outline-offset: 2px; border-radius: 6px; }
.skip { position: absolute; left: 12px; top: -48px; z-index: 100; background: var(--primary); color: #fff; padding: 10px 14px; border-radius: var(--radius-sm); }
.skip:focus { top: 8px; }
/* the brand colour is light in dark mode, so white text on it fails contrast */
:root[data-theme="dark"] .skip { color: #0B0B0C; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .skip { color: #0B0B0C; } }
.meta { color: var(--text-2); font-size: .875rem; }
.err { color: var(--error); font-size: .875rem; min-height: 1.2em; margin-top: 8px; }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 48px; padding: 0 18px; border-radius: var(--radius); border: 1px solid transparent;
  font-weight: 700; font-size: 1rem; text-decoration: none; transition: background .15s, transform .1s, border-color .15s;
}
.btn:active { transform: scale(.98); }
.btn:disabled { opacity: .55; cursor: not-allowed; }
.btn-primary { background: var(--primary); color: #fff; }
.btn-primary:hover { background: var(--primary-hover); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .btn-primary { color: #0B0B0C; }
}
:root[data-theme="dark"] .btn-primary { color: #0B0B0C; }
.btn-secondary { background: var(--surface); color: var(--text); border-color: var(--line-strong); }
.btn-secondary:hover { background: var(--surface-2); }
.btn-ghost { background: transparent; color: var(--primary); }
.btn-ghost:hover { background: var(--primary-50); }
.btn-wa { background: #1FAF54; color: #fff; }
.btn-wa:hover { background: #17964a; }
.btn-block { width: 100%; }
.btn-sm { min-height: 44px; padding: 0 12px; font-size: .9rem; font-weight: 600; }
.icon-btn {
  display: inline-grid; place-items: center; width: 44px; height: 44px; border-radius: var(--radius-pill);
  border: 0; background: transparent; color: var(--text);
}
.icon-btn:hover { background: var(--surface-2); }
.link-btn { background: none; border: 0; padding: 8px 0; color: var(--primary); font-weight: 600; display: inline-flex; align-items: center; gap: 6px; min-height: 44px; }

/* ---------- Chips & toggles ---------- */
.chip {
  display: inline-flex; align-items: center; gap: 6px; min-height: 44px; padding: 0 14px;
  border-radius: var(--radius-pill); border: 1px solid var(--line-strong); background: var(--surface);
  font-size: .9rem; font-weight: 600; color: var(--text); white-space: nowrap;
}
.chip .ic { width: 18px; height: 18px; color: var(--primary); }
.chip:hover { border-color: var(--primary); }
.toggle-chip { position: relative; display: inline-flex; }
.toggle-chip input { position: absolute; opacity: 0; inset: 0; margin: 0; cursor: pointer; }
.toggle-chip > span {
  display: inline-flex; align-items: center; gap: 6px; min-height: 36px; padding: 0 12px;
  border-radius: var(--radius-pill); border: 1px solid var(--line-strong); background: var(--surface);
  font-size: .85rem; font-weight: 600; color: var(--text-2); white-space: nowrap; transition: background .15s, color .15s, border-color .15s;
}
.toggle-chip .ic { width: 16px; height: 16px; }
.toggle-chip input:checked + span { background: var(--primary-50); border-color: var(--primary); color: var(--primary); }
.toggle-chip input:checked + span::after { content: "✓"; font-weight: 800; margin-left: 2px; }
.toggle-chip input:focus-visible + span { outline: 3px solid var(--primary); outline-offset: 2px; }

/* ---------- Badges ---------- */
.tag { display: inline-flex; align-items: center; gap: 4px; padding: 3px 9px; border-radius: 6px; font-size: .72rem; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; }
.tag-cheapest { background: var(--accent); color: var(--accent-ink); }
.tag-fastest { background: var(--primary-50); color: var(--primary); }
.tag-easiest, .tag-balanced, .tag-accessible, .tag-fewestTransfers { background: var(--success-50); color: var(--success); }
.tag-nightFriendly { background: var(--secondary); color: var(--bg); }
.tag-preferRide { background: var(--surface-2); color: var(--text); }
.rec { display: inline-flex; align-items: center; gap: 4px; font-size: .75rem; font-weight: 700; color: var(--primary); }
.rec .ic { width: 14px; height: 14px; fill: currentColor; }
/* fare trust: icon + text, never colour alone */
.trust { display: inline-flex; align-items: center; gap: 5px; font-size: .78rem; font-weight: 600; padding: 2px 8px; border-radius: var(--radius-pill); white-space: nowrap; }
.trust .ic { width: 14px; height: 14px; }
.trust-estimate { color: var(--text-2); border: 1px dashed var(--line-strong); }
.trust-verified { color: var(--success); background: var(--success-50); }
.trust-reported { color: var(--primary); background: var(--primary-50); }
.trust-outdated { color: var(--warning); background: var(--warning-50); }
.paid-badge { font-size: .7rem; font-weight: 700; padding: 2px 7px; border-radius: 5px; background: var(--surface-2); color: var(--text-2); border: 1px solid var(--line); }
.mode {
  display: inline-flex; align-items: center; gap: 5px; font-size: .85rem; font-weight: 600; color: var(--text);
}
.mode .ic { color: var(--mc, var(--text-2)); width: 18px; height: 18px; }
.mode-sep { color: var(--text-2); width: 14px; height: 14px; }

/* ---------- Inputs ---------- */
.input { width: 100%; min-height: 48px; padding: 10px 12px; border: 1px solid var(--line-strong); border-radius: var(--radius-sm); background: var(--surface); color: var(--text); }
.input:focus { outline: 2px solid var(--primary); outline-offset: -1px; border-color: var(--primary); }
.input-lg { font-size: 1.4rem; font-weight: 700; }
textarea.input { min-height: 88px; resize: vertical; }
.stack { display: grid; gap: 6px; margin-top: 14px; font-size: .9rem; font-weight: 600; }
.check { display: flex; align-items: center; gap: 10px; margin-top: 12px; min-height: 44px; font-size: .95rem; }
.check input { width: 20px; height: 20px; accent-color: var(--primary); }
fieldset { border: 0; padding: 0; margin: 14px 0 0; }
legend { font-size: .9rem; font-weight: 600; margin-bottom: 8px; }
.radios { display: flex; flex-wrap: wrap; gap: 8px; }
.radios label { position: relative; display: inline-flex; align-items: center; gap: 6px; min-height: 44px; padding: 0 12px; border: 1px solid var(--line-strong); border-radius: var(--radius-pill); font-size: .9rem; cursor: pointer; }
.radios input { accent-color: var(--primary); }
.radios label:has(input:checked) { border-color: var(--primary); background: var(--primary-50); color: var(--primary); font-weight: 600; }

/* ---------- App shell ---------- */
.offline-bar {
  position: sticky; top: 0; z-index: 60; display: flex; align-items: center; gap: 8px; justify-content: center;
  padding: 8px 16px; background: var(--secondary); color: var(--bg); font-size: .85rem;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .offline-bar { background: var(--surface-2); color: var(--text); }
}
:root[data-theme="dark"] .offline-bar { background: var(--surface-2); color: var(--text); }
.topbar {
  position: sticky; top: 0; z-index: 50; height: var(--topbar-h); display: flex; align-items: center; gap: 4px;
  padding: 0 8px 0 12px; background: var(--surface); border-bottom: 1px solid var(--line);
}
.brand { display: flex; align-items: center; gap: 10px; text-decoration: none; color: var(--text); font-weight: 800; font-size: 1.05rem; letter-spacing: -.01em; margin-right: auto; }
.brand-mark { display: grid; place-items: center; width: 32px; height: 32px; border-radius: 9px; background: var(--primary); color: #fff; }
.brand-mark .ic { width: 18px; height: 18px; color: #fff; }
.trip-title {
  flex: 1; min-width: 0; text-align: left; border: 0; background: var(--surface-2); border-radius: var(--radius-sm);
  min-height: 44px; padding: 0 12px; font-weight: 700; font-size: .95rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.lang-pick {
  display: inline-flex; align-items: center; gap: 6px; min-height: 44px; padding: 0 10px;
  border: 1px solid var(--line); border-radius: var(--radius-pill); background: var(--surface);
  color: var(--text); font-size: .9rem; font-weight: 600;
}
.lang-pick .ic { width: 18px; height: 18px; color: var(--text-2); }
.lang-pick .chev { width: 16px; height: 16px; }
.lang-pick:hover { border-color: var(--primary); }

.lang-body { display: grid; gap: 12px; padding: 0 4px 8px; }
.lang-body h2 { font-size: 1.25rem; font-weight: 800; letter-spacing: -.02em; margin: 0; }
.lang-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.lang-row {
  display: flex; align-items: center; gap: 12px; width: 100%; min-height: 56px; padding: 10px 14px;
  border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface-2); color: var(--text); text-align: left;
}
.lang-names { flex: 1; min-width: 0; display: grid; gap: 1px; }
.lang-names b { font-weight: 700; font-size: 1rem; }
.lang-names small { color: var(--text-2); font-size: .8rem; }
.lang-row .tick { color: var(--primary); opacity: 0; flex: none; }
.lang-row[aria-current="true"] { border-color: var(--primary); background: var(--primary-50); }
.lang-row[aria-current="true"] .tick { opacity: 1; }
.top-nav { display: none; }
body:not([data-view="results"]) .only-results { display: none !important; }
body[data-view="results"] .only-home { display: none !important; }

.shell { display: flex; flex-direction: column; }
.panel { order: 2; min-width: 0; overflow-x: hidden; padding: 16px 16px calc(var(--tabbar-h) + 24px); outline: none; }
.view { animation: viewIn .22s var(--ease); }
@keyframes viewIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
.view-title { font-size: 1.5rem; font-weight: 800; margin: 4px 0 16px; }

/* Map: supporting element. Hidden on mobile home, shown above the results sheet. */
.map-pane { order: 1; position: relative; display: none; background: var(--surface-2); }
body[data-view="results"] .map-pane { display: block; height: 34vh; min-height: 200px; transition: height .25s var(--ease); }
body[data-view="results"].map-big .map-pane { height: 62vh; }
body.picking .map-pane { display: block; height: 62vh; }
#map { position: absolute; inset: 0; z-index: 0; }
.map-ctrls { position: absolute; right: 10px; bottom: 34px; z-index: 5; display: grid; gap: 8px; }
.map-btn { display: grid; place-items: center; width: 44px; height: 44px; border-radius: var(--radius-pill); border: 1px solid var(--line); background: var(--surface); color: var(--text); box-shadow: var(--shadow-1); }
.map-hint { position: absolute; left: 10px; bottom: 10px; z-index: 5; margin: 0; padding: 4px 10px; border-radius: var(--radius-pill); background: color-mix(in srgb, var(--surface) 92%, transparent); font-size: .75rem; color: var(--text-2); max-width: calc(100% - 80px); }
body[data-view="results"] .panel {
  position: relative; margin-top: -16px; border-radius: 18px 18px 0 0; background: var(--bg); padding-top: 10px; z-index: 2;
  box-shadow: 0 -6px 18px rgba(3, 25, 91, .09);
}
.sheet-grip { width: 40px; height: 4px; border-radius: 4px; background: var(--line-strong); margin: 0 auto 12px; }

.tabbar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 40; height: calc(var(--tabbar-h) + env(safe-area-inset-bottom));
  padding-bottom: env(safe-area-inset-bottom); display: grid; grid-template-columns: repeat(3, 1fr);
  background: var(--surface); border-top: 1px solid var(--line);
}
.tab { display: grid; place-items: center; align-content: center; gap: 2px; border: 0; background: none; color: var(--text-2); font-size: .75rem; font-weight: 600; }
.tab .ic { width: 22px; height: 22px; }
.tab[aria-current="page"] { color: var(--primary); }
.tab[aria-current="page"] .ic { stroke-width: 2.4; }

/* ---------- Home ---------- */
.hero { margin: 4px 0 14px; }
.hero h1 { font-size: 1.6rem; font-weight: 800; letter-spacing: -.02em; }
.hero p { color: var(--text-2); margin-top: 4px; }
.search { background: var(--surface); border: 1px solid var(--line); border-radius: 16px; padding: 12px; box-shadow: var(--shadow-1); }
.search-fields { position: relative; padding-right: 48px; }
.field-row { position: relative; display: flex; align-items: center; gap: 4px; min-height: 52px; border-radius: var(--radius); background: var(--surface-2); padding-left: 10px; }
.field-row + .field-err + .field-row, .field-row + .field-row { margin-top: 8px; }
.field-row:focus-within { box-shadow: inset 0 0 0 2px var(--primary); background: var(--surface); }
.field-row[aria-invalid="true"] { box-shadow: inset 0 0 0 2px var(--error); }
/* a block container leaves the inline icon sitting on the text baseline, a few pixels
   above the middle of the field; centring the box removes that gap */
.field-ic { display: grid; place-items: center; }
.field-ic .ic { width: 20px; height: 20px; }
.field-ic.origin { color: var(--primary); }
.field-ic.dest { color: var(--m-keke); }
.combo { position: relative; flex: 1; min-width: 0; }
.combo input { width: 100%; min-height: 52px; border: 0; background: transparent; padding: 0 4px 0 6px; font-size: 1rem; font-weight: 600; outline: none; text-overflow: ellipsis; }
.combo input::placeholder { color: var(--text-2); font-weight: 400; }
.field-act { display: grid; place-items: center; width: 44px; height: 44px; border: 0; background: none; color: var(--text-2); border-radius: var(--radius-pill); }
.field-act:hover { color: var(--primary); background: var(--primary-50); }
.field-act.saved .ic { fill: var(--accent); stroke: var(--accent); }
.swap {
  position: absolute; right: 0; top: 50%; margin-top: -22px; z-index: 3; display: grid; place-items: center; width: 44px; height: 44px;
  border-radius: var(--radius-pill); border: 1px solid var(--line-strong); background: var(--surface); color: var(--text); box-shadow: var(--shadow-1);
  transition: transform .2s var(--ease);
}
.swap:active { transform: rotate(180deg); }
.field-err { color: var(--error); font-size: .85rem; font-weight: 600; margin: 4px 0 0 40px; }
.opts { display: flex; gap: 8px; margin: 12px 0; overflow-x: auto; padding-bottom: 2px; scrollbar-width: none; min-width: 0; min-inline-size: 0; max-width: 100%; }
.opts::-webkit-scrollbar { display: none; }
.suggest {
  position: absolute; z-index: 30; left: -40px; right: -44px; top: calc(100% + 6px); margin: 0; padding: 6px; list-style: none;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow-2); max-height: 320px; overflow-y: auto;
  overscroll-behavior: contain;  /* scrolling the list must not scroll the page behind it */
  -webkit-overflow-scrolling: touch;
}
/* On a phone the panel scrolls and clips anything inside it, so the list is taken out of
   the panel and positioned against the viewport instead (top is set in app.js). */
@media (max-width: 719px) {
  .suggest { position: absolute; left: 8px; right: 8px; max-height: min(60vh, 420px); }
}
.suggest li { display: flex; align-items: center; gap: 10px; padding: 10px; border-radius: var(--radius-sm); cursor: pointer; min-height: 48px; }
.suggest li .ic { color: var(--text-2); }
.suggest li .s-main { font-weight: 600; }
.suggest li small { display: block; color: var(--text-2); font-size: .8rem; font-weight: 400; }
.suggest li.active, .suggest li[data-i]:hover { background: var(--surface-2); }
.suggest li.head { min-height: 0; cursor: default; padding: 8px 10px 4px; font-size: .72rem; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--text-2); }
.suggest li.empty { cursor: default; display: block; color: var(--text-2); }
.suggest li.missing { color: var(--primary); font-weight: 600; }
/* wrapping beats sideways scrolling here: on a 320px screen "Pick on map" was pushed
   off the edge, where nothing suggested it existed */
.quick { display: flex; flex-wrap: wrap; gap: 8px; margin: 14px 0 4px; min-width: 0; }
.block { margin-top: 22px; }
.block-title { font-size: .8rem; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--text-2); margin-bottom: 8px; }
.rows { list-style: none; margin: 0; padding: 0; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; }
.rows li + li { border-top: 1px solid var(--line); }
.row-btn { display: flex; align-items: center; gap: 12px; width: 100%; min-height: 56px; padding: 10px 14px; border: 0; background: none; text-align: left; text-decoration: none; color: var(--text); }
.row-btn:hover { background: var(--surface-2); }
.row-btn .ic-lead { display: grid; place-items: center; width: 36px; height: 36px; border-radius: 10px; background: var(--primary-50); color: var(--primary); flex: none; }
.row-btn .ic-lead.amber { background: var(--accent-50); color: var(--m-keke); }
.row-btn .row-main { flex: 1; min-width: 0; }
/* a route label is the whole point of its row, so let it take a second line on a narrow
   screen rather than hiding the destination behind an ellipsis */
.row-btn .row-main b { display: block; font-weight: 600; }
.row-btn .row-main small { color: var(--text-2); font-size: .82rem; }
.row-btn > .ic:last-child { color: var(--text-2); }
.row-with-x { display: flex; align-items: center; }
.row-with-x .row-btn { flex: 1; }
.chip-row { display: flex; flex-wrap: wrap; gap: 8px; }
.arrived { margin-top: 12px; }

/* ---------- Results ---------- */
.notice { display: flex; gap: 8px; align-items: flex-start; font-size: .82rem; color: var(--text-2); margin: 0 2px 12px; }
.notice .ic { width: 16px; height: 16px; margin-top: 2px; }
.notice button { margin-left: 4px; }
.route-card {
  background: var(--surface); border: 1px solid var(--line); border-radius: 16px; margin-bottom: 12px; overflow: hidden;
  transition: border-color .15s, box-shadow .15s;
}
.route-card.selected { border-color: var(--primary); box-shadow: 0 0 0 1px var(--primary); }
.route-card.recommended { box-shadow: var(--shadow-1); }
.rc-sum { display: block; width: 100%; text-align: left; border: 0; background: none; padding: 14px 14px 12px; color: var(--text); }
.rc-top { display: flex; align-items: center; gap: 8px; justify-content: space-between; }
.rc-top-l { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.rc-chev { color: var(--text-2); transition: transform .2s var(--ease); }
.route-card.open .rc-chev { transform: rotate(180deg); }
.rc-fare { display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 10px; margin-top: 8px; }
.amt { font-size: 1.75rem; font-weight: 800; letter-spacing: -.02em; font-variant-numeric: tabular-nums; line-height: 1.1; }
/* A highlighter band under the cheapest fare, drawn as a flat inset bar. It sits low on
   purpose: any higher and the edge crossed the digits, so the number read as a struck-out,
   cancelled price. */
.route-card.is-cheapest .amt { box-shadow: inset 0 -.18em 0 var(--accent-50); }
.rc-meta { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 12px; margin-top: 6px; color: var(--text-2); font-size: .92rem; font-weight: 600; }
.rc-meta > span { display: inline-flex; align-items: center; gap: 5px; }
.rc-meta .ic { width: 16px; height: 16px; }
.rc-modes { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 6px; margin-top: 10px; }
.rc-flag { display: flex; align-items: flex-start; gap: 6px; margin-top: 10px; font-size: .82rem; color: var(--warning); font-weight: 600; }
.rc-flag .ic { width: 16px; height: 16px; margin-top: 1px; }
.rc-detail { border-top: 1px solid var(--line); padding: 14px; animation: openIn .22s var(--ease); }
@keyframes openIn { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
.rc-why { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px; }
.rc-why span { font-size: .8rem; padding: 4px 9px; border-radius: var(--radius-pill); background: var(--surface-2); color: var(--text-2); font-weight: 600; }
.rc-rel { font-size: .82rem; color: var(--text-2); margin-bottom: 14px; display: flex; align-items: center; gap: 6px; }
.rc-rel b { color: var(--text); }
.rc-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 16px; }
.rc-actions .btn { min-height: 44px; font-size: .88rem; padding: 0 10px; white-space: nowrap; min-width: 0; }
.rc-actions .btn span { overflow: hidden; text-overflow: ellipsis; }
.rc-actions .btn-start { grid-column: 1 / -1; min-height: 52px; font-size: 1rem; }
.rc-links { display: flex; flex-wrap: wrap; gap: 4px 16px; margin-top: 8px; }
.rc-links .link-btn { font-size: .85rem; color: var(--text-2); }
.save-route.saved .ic { fill: var(--accent); stroke: var(--accent); animation: pop .3s var(--ease); }
@keyframes pop { 50% { transform: scale(1.3); } }

/* ---------- Journey timeline ---------- */
.timeline { list-style: none; margin: 0; padding: 0; }
.tl { position: relative; display: grid; grid-template-columns: 36px 1fr; gap: 12px; padding-bottom: 18px; }
.tl::before { content: ""; position: absolute; left: 17px; top: 36px; bottom: 0; width: 2px; background: var(--line-strong); }
.tl.walk::before { width: 0; background: none; border-left: 2px dashed var(--m-walk); }
.tl:last-child { padding-bottom: 0; }
.tl:last-child::before { display: none; }
.tl-node { display: grid; place-items: center; width: 36px; height: 36px; border-radius: 50%; background: var(--surface); border: 2px solid var(--mc, var(--line-strong)); color: var(--mc, var(--text-2)); z-index: 1; }
.tl-node .ic { width: 18px; height: 18px; }
.tl.endpoint .tl-node { background: var(--mc); color: #fff; border-color: var(--mc); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .tl.endpoint .tl-node { color: var(--bg); }
}
:root[data-theme="dark"] .tl.endpoint .tl-node { color: var(--bg); }
.tl-title { font-size: 1rem; font-weight: 700; padding-top: 6px; }
.tl-title .tl-time { font-weight: 600; color: var(--text-2); font-size: .85rem; margin-left: 4px; white-space: nowrap; }
.tl-sub { color: var(--text-2); font-size: .88rem; margin-top: 2px; }
.facts { display: grid; gap: 8px; margin-top: 10px; }
.fact { display: grid; grid-template-columns: 96px 1fr; gap: 8px; font-size: .92rem; align-items: start; }
.fact .k { color: var(--text-2); font-size: .74rem; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; padding-top: 2px; }
.fact .v { font-weight: 600; }
.fact .v em { display: block; font-style: normal; font-weight: 400; font-size: .8rem; color: var(--text-2); }
.info-btn { background: none; border: 0; color: var(--primary); padding: 0 0 0 4px; vertical-align: middle; }
.info-btn .ic { width: 16px; height: 16px; }
.tl-fare { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 10px; margin-top: 12px; }
.tl-fare .amt { font-size: 1.25rem; }
.tl-fare .sub { display: inline-flex; align-items: center; gap: 4px; color: var(--text-2); font-size: .85rem; }
.tl-fare .sub .ic { width: 14px; height: 14px; }
.tl-note { font-size: .82rem; color: var(--text-2); margin-top: 6px; }
.tl-avail { display: flex; align-items: center; gap: 6px; font-size: .82rem; margin-top: 6px; color: var(--text-2); }
.tl-avail .ic { width: 16px; height: 16px; }
.calm-alert { display: flex; gap: 8px; align-items: flex-start; margin-top: 8px; padding: 8px 10px; border-radius: var(--radius-sm); background: var(--warning-50); color: var(--warning); font-size: .84rem; font-weight: 600; }
.calm-alert .ic { width: 16px; height: 16px; margin-top: 2px; }
.calm-tip { display: flex; gap: 8px; align-items: flex-start; margin-top: 8px; font-size: .84rem; color: var(--text-2); }
.calm-tip .ic { width: 16px; height: 16px; margin-top: 2px; color: var(--primary); }
.cta-inline { margin-top: 6px; font-size: .88rem; font-weight: 600; color: var(--primary); background: none; border: 0; padding: 6px 0; display: inline-flex; gap: 6px; align-items: center; min-height: 44px; }
.cta-inline .ic { width: 16px; height: 16px; }
.tl-tools { margin-top: 6px; }
.tl-tools > summary { list-style: none; cursor: pointer; display: inline-flex; align-items: center; gap: 6px; font-size: .88rem; font-weight: 600; color: var(--primary); min-height: 44px; }
.tl-tools > summary::-webkit-details-marker { display: none; }
.tl-tools > summary .ic { width: 16px; height: 16px; transition: transform .2s; }
.tl-tools[open] > summary .ic { transform: rotate(180deg); }
.tools-body { display: grid; gap: 10px; padding: 6px 0 2px; }
.tool { background: var(--surface-2); border-radius: var(--radius-sm); padding: 10px 12px; }
.tool h5 { margin: 0 0 6px; font-size: .74rem; font-weight: 700; color: var(--text-2); text-transform: uppercase; letter-spacing: .04em; }
.tool ul { margin: 0; padding-left: 18px; font-size: .88rem; }
.tool .row { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.hag-in { width: 130px; }
.hagout p { margin-top: 8px; font-size: .9rem; }
.hagout q { font-weight: 700; }

/* "Tell the driver": the signature component */
.tell {
  margin-top: 12px; border-radius: var(--radius); background: var(--primary-50); padding: 12px 12px 10px;
  border-left: 4px solid var(--primary);
}
.tell-head { display: flex; align-items: center; gap: 6px; font-size: .72rem; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: var(--primary); }
.tell-head .ic { width: 16px; height: 16px; }
.tell-main { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 4px; }
.tell-phrase { font-size: 1.3rem; font-weight: 800; color: var(--text); letter-spacing: -.01em; }
.tell-alt { font-size: .9rem; color: var(--text-2); margin-top: 2px; }
.tell-audio {
  display: inline-flex; align-items: center; gap: 6px; flex: none; min-height: 44px; padding: 0 14px;
  border-radius: var(--radius-pill); border: 0; background: var(--primary); color: #fff; font-weight: 700; font-size: .88rem;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .tell-audio { color: var(--bg); }
}
:root[data-theme="dark"] .tell-audio { color: var(--bg); }
.tell-audio.playing { animation: pulse 1s infinite; }
@keyframes pulse { 50% { opacity: .7; } }
.tell-ask { font-size: .82rem; color: var(--text-2); margin-top: 8px; }

/* Night / safety panel: calm and factual */
.info-panel { display: flex; gap: 10px; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 12px; margin-bottom: 12px; }
.info-panel > .ic { color: var(--primary); width: 22px; height: 22px; flex: none; margin-top: 1px; }
.info-panel h2 { font-size: .95rem; font-weight: 700; }
.info-panel ul { margin: 6px 0 0; padding-left: 18px; font-size: .88rem; color: var(--text-2); }
.info-panel .links { display: flex; flex-wrap: wrap; gap: 4px 14px; margin-top: 6px; font-size: .88rem; font-weight: 600; }

/* "Around" listings: always after every route option */
.around { margin-top: 24px; padding-top: 16px; border-top: 1px solid var(--line); }
.around h2 { font-size: .95rem; font-weight: 700; margin-bottom: 8px; }
.around .rows { margin-bottom: 8px; }

/* ---------- States ---------- */
.state { text-align: center; padding: 28px 12px; }
.state-ic { display: inline-grid; place-items: center; width: 56px; height: 56px; border-radius: 50%; background: var(--surface-2); color: var(--text-2); margin-bottom: 12px; }
.state-ic .ic { width: 26px; height: 26px; }
.state h2 { font-size: 1.1rem; font-weight: 700; }
.state p { color: var(--text-2); margin: 6px auto 0; max-width: 34ch; }
.state .state-actions { display: flex; flex-direction: column; gap: 8px; margin: 18px auto 0; max-width: 300px; }
.skeleton { height: 128px; border-radius: 16px; margin-bottom: 12px; background: var(--surface-2); animation: breathe 1.2s ease-in-out infinite; }
@keyframes breathe { 50% { opacity: .55; } }

/* ---------- Toast ---------- */
.toast {
  position: fixed; left: 50%; bottom: calc(var(--tabbar-h) + 16px + env(safe-area-inset-bottom)); z-index: 80;
  transform: translateX(-50%); display: flex; align-items: center; gap: 12px; width: max-content; max-width: min(92vw, 420px);
  padding: 12px 16px; border-radius: var(--radius); background: var(--secondary); color: var(--bg);
  font-size: .9rem; font-weight: 600; box-shadow: var(--shadow-2); animation: toastIn .25s var(--ease);
}
.toast button { border: 0; background: none; color: var(--accent); font-weight: 700; padding: 6px 0; white-space: nowrap; }
@keyframes toastIn { from { opacity: 0; transform: translate(-50%, 10px); } to { opacity: 1; transform: translate(-50%, 0); } }

/* ---------- Bottom sheets (dialogs) ---------- */
dialog.sheet {
  border: 0; padding: 16px 16px calc(16px + env(safe-area-inset-bottom)); margin: auto 0 0; width: 100%; max-width: 100%;
  max-height: 88vh; overflow-y: auto; border-radius: 20px 20px 0 0; background: var(--surface); color: var(--text);
  box-shadow: var(--shadow-2);
}
dialog.sheet[open] { animation: sheetUp .25s var(--ease); }
@keyframes sheetUp { from { transform: translateY(40px); opacity: .4; } to { transform: none; opacity: 1; } }
dialog.sheet::backdrop { background: rgba(10, 14, 30, .45); }
.sheet-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin: -4px -4px 8px 0; }
.sheet-head h2 { font-size: 1.1rem; font-weight: 700; }
.sheet h3 { font-size: 1.15rem; font-weight: 800; margin-bottom: 8px; }
.sheet-actions { display: flex; flex-direction: column; gap: 8px; margin-top: 16px; }
.share-preview { white-space: pre-wrap; font-family: var(--font); font-size: .88rem; background: #E8F7EA; color: #102414; border-radius: 10px 10px 10px 2px; padding: 12px; margin: 0; max-height: 40vh; overflow-y: auto; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .share-preview { background: #12301c; color: #e6f5ea; }
}
:root[data-theme="dark"] .share-preview { background: #12301c; color: #e6f5ea; }
#hubBody dl { margin: 0; display: grid; gap: 2px; }
#hubBody dt { font-size: .74rem; text-transform: uppercase; letter-spacing: .04em; color: var(--text-2); margin-top: 12px; font-weight: 700; }
#hubBody dd { margin: 0; }
#hubBody dd em { color: var(--text-2); font-style: normal; }
#hubBody img { max-width: 100%; border-radius: 8px; }
.avail { list-style: none; margin: 4px 0 0; padding: 0; display: grid; gap: 8px; }
/* "Are vehicles available here now?" - the Yes/No pair had no gap of its own, so the two
   buttons fused into one box, and the label could not shrink, which pushed them off the
   edge on a narrow screen. The label now gives way and the pair stays whole. */
.avail li { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 8px 10px; align-items: center; }
/* the status stacks under the mode name on every row, so one row wrapping cannot make
   the list look ragged next to the buttons */
.avail li > span:first-child { flex: 1 1 140px; min-width: 0; display: flex; flex-direction: column; align-items: flex-start; gap: 2px; }
.avail .row { display: flex; gap: 8px; flex: none; }
.avail .row .btn { min-width: 80px; justify-content: center; }
.av-common { color: var(--success); font-weight: 700; } .av-some { color: var(--warning); font-weight: 700; } .av-hard { color: var(--error); font-weight: 700; }
.level { font-size: 1.05rem; font-weight: 800; margin: 4px 0 8px; display: flex; gap: 8px; align-items: center; }
#tipsBody ul { padding-left: 18px; } #tipsBody li { margin: 8px 0; }
.emergency a { display: inline-flex; gap: 8px; align-items: center; font-weight: 800; color: var(--error); text-decoration: none; min-height: 44px; }

/* ---------- Leaflet ---------- */
.leaflet-container { font-family: var(--font); background: var(--surface-2); }
.leaflet-control-zoom a { width: 36px !important; height: 36px !important; line-height: 36px !important; }
.leaflet-tooltip.lbl { background: rgba(255, 255, 255, .94); border: 0; border-radius: 6px; box-shadow: 0 1px 3px rgba(0, 0, 0, .2); color: #111827; font: 600 11px/1.2 var(--font); padding: 2px 6px; }
.leaflet-tooltip.lbl::before { display: none; }
.hide-labels .leaflet-tooltip.lbl:not(.hub) { display: none; }
.pin-mk { width: 28px; height: 28px; border-radius: 50%; display: grid; place-items: center; color: #fff; font: 800 12px var(--font); border: 3px solid #fff; box-shadow: 0 1px 6px rgba(0, 0, 0, .35); }
.pin-mk.a { background: #1951FC; } .pin-mk.b { background: #C98600; }
.pop { display: grid; gap: 6px; min-width: 170px; font-family: var(--font); }
.pop strong { font-size: .95rem; }
.pop .pop-row { display: flex; gap: 6px; }
.pop button { flex: 1; min-height: 38px; border-radius: 8px; border: 0; background: #1951FC; color: #fff; font-weight: 700; font-size: .82rem; }
.pop button.info { background: transparent; color: #1951FC; border: 1px solid #1951FC; }

/* ---------- Reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}

/* =========================================================
   Tablet and desktop: list panel + persistent map, nav in the top bar
   ========================================================= */
@media (min-width: 768px) {
  .panel { padding: 24px 24px 40px; }
  .hero h1 { font-size: 2rem; }
  .toast { bottom: 24px; }
  dialog.sheet { margin: auto; max-width: 480px; border-radius: 18px; }
  .topbar { gap: 8px; padding: 0 16px; }
}
/* The top navigation only replaces the bottom tab bar once there is room for both it and
   the trip title. At 768px the two together squeezed the title to 24px, clipping the trip.
   A tablet in portrait keeps the bottom bar, which is normal for that size anyway. */
@media (min-width: 900px) {
  .tabbar { display: none; }
  .top-nav { display: flex; gap: 4px; margin-left: 8px; }
  .nav-btn { display: inline-flex; align-items: center; gap: 6px; min-height: 44px; padding: 0 12px; border: 0; border-radius: var(--radius-sm); background: none; color: var(--text-2); font-weight: 600; font-size: .9rem; }
  .nav-btn[aria-current="page"] { color: var(--primary); background: var(--primary-50); }
  .brand { margin-right: 0; }
  .lang-pick { margin-left: auto; }
  body[data-view="results"] .lang-pick { display: inline-flex !important; }
  body[data-view="results"] .brand { display: flex !important; }
  .trip-title { min-width: 160px; max-width: 360px; }
}
@media (min-width: 960px) {
  .shell { flex-direction: row; height: calc(100vh - var(--topbar-h)); }
  body.is-offline .shell { height: calc(100vh - var(--topbar-h) - 36px); }
  .panel { order: 1; width: 440px; flex: none; overflow-y: auto; border-right: 1px solid var(--line); background: var(--bg); }
  .map-pane, body[data-view="results"] .map-pane, body.picking .map-pane { order: 2; display: block; flex: 1; height: auto; }
  body[data-view="results"] .panel { margin-top: 0; border-radius: 0; box-shadow: none; padding-top: 24px; }
  .sheet-grip, #mapToggle { display: none !important; }
  .view-title { font-size: 1.6rem; }
}
@media (min-width: 1280px) { .panel { width: 480px; } }

/* =========================================================
   Secondary pages (partners, ambassador, business, API, route pages):
   same top bar, tokens, type and components as the app
   ========================================================= */
:root { --card: var(--surface); --ink: var(--text); --muted: var(--text-2); --brand: var(--primary); --warn: var(--warning); --warn-bg: var(--warning-50); }
.page-top .brand { margin-right: auto; }
.page-top .brand span:last-child { white-space: nowrap; }
body:not([data-view]) > .page-head, body:not([data-view]) > main, body:not([data-view]) > footer { max-width: 760px; margin: 0 auto; padding: 0 16px; }
body:not([data-view]) > .page-head { padding-top: 24px; }
body:not([data-view]) > main { padding-bottom: 40px; }
.page-head h1, body:not([data-view]) main h1 { font-size: 1.75rem; font-weight: 800; letter-spacing: -.02em; line-height: 1.2; margin: 0 0 8px; }
.page-head p { color: var(--text-2); font-size: 1.02rem; margin-bottom: 16px; }
body:not([data-view]) > footer { color: var(--text-2); font-size: .85rem; padding-top: 8px; padding-bottom: 40px; }
body:not([data-view]) h2 { font-size: 1.15rem; font-weight: 700; margin: 26px 0 10px; }
body:not([data-view]) h3 { font-size: 1rem; font-weight: 700; margin: 20px 0 8px; }
body:not([data-view]) main p { margin: 0 0 10px; }
body:not([data-view]) main ul { padding-left: 20px; }
body:not([data-view]) main li { margin: 4px 0; }
/* forms as a card, inputs like the app's */
body:not([data-view]) form:not([method="dialog"]) { display: grid; gap: 14px; background: var(--surface); border: 1px solid var(--line); border-radius: 16px; padding: 16px; box-shadow: var(--shadow-1); }
body:not([data-view]) .field { display: grid; gap: 6px; }
body:not([data-view]) .field > label { font-size: .88rem; font-weight: 600; color: var(--text-2); }
body:not([data-view]) main input:not([type=checkbox]):not([type=radio]), body:not([data-view]) main select, body:not([data-view]) main textarea {
  width: 100%; min-height: 48px; padding: 10px 12px; border: 1px solid var(--line-strong); border-radius: var(--radius-sm);
  background: var(--surface-2); color: var(--text); font: inherit;
}
body:not([data-view]) main input:focus, body:not([data-view]) main select:focus, body:not([data-view]) main textarea:focus { outline: 2px solid var(--primary); outline-offset: -1px; background: var(--surface); }
body:not([data-view]) main button:not(.icon-btn) {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-height: 44px; padding: 0 16px;
  border-radius: var(--radius); border: 1px solid var(--line-strong); background: var(--surface); color: var(--text); font-weight: 600;
}
body:not([data-view]) main button.primary { background: var(--primary); color: #fff; border-color: transparent; font-weight: 700; min-height: 50px; }
:root[data-theme="dark"] body:not([data-view]) main button.primary { color: #0B0B0C; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) body:not([data-view]) main button.primary { color: #0B0B0C; } }
body:not([data-view]) .link { background: none; border: 0; color: var(--primary); padding: 0; min-height: 0; font-weight: 600; }
body:not([data-view]) .note { color: var(--text-2); font-size: .92rem; background: var(--surface); border: 1px solid var(--line); border-left: 4px solid var(--primary); padding: 10px 14px; border-radius: var(--radius-sm); margin: 14px 0; }
body:not([data-view]) .badge { font-size: .72rem; font-weight: 700; padding: 2px 8px; border-radius: 999px; background: var(--surface-2); color: var(--text-2); }
body:not([data-view]) .badge.paid { background: var(--primary-50); color: var(--primary); }
/* tables as cards */
body:not([data-view]) main table { width: 100%; border-collapse: separate; border-spacing: 0; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; font-size: .9rem; }
body:not([data-view]) main th, body:not([data-view]) main td { padding: 10px; border-bottom: 1px solid var(--line); text-align: left; }
body:not([data-view]) main tr:last-child td { border-bottom: 0; }
body:not([data-view]) main th { font-size: .75rem; text-transform: uppercase; letter-spacing: .04em; color: var(--text-2); background: var(--surface-2); }
body:not([data-view]) main .plans td:not(:first-child), body:not([data-view]) main .plans th:not(:first-child) { text-align: center; }
body:not([data-view]) main pre { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 12px; overflow-x: auto; font-size: .82rem; }
body:not([data-view]) main code { background: var(--surface-2); padding: 1px 5px; border-radius: 4px; font-size: .86em; }

/* Settings rows that hold a control (e.g. Appearance): label on top, control full width below */
.ic-lead { display: grid; place-items: center; width: 36px; height: 36px; border-radius: 10px; background: var(--primary-50); color: var(--primary); flex: none; }
.row-static { display: grid; grid-template-columns: auto 1fr; align-items: center; gap: 10px 12px; min-height: 56px; padding: 12px 14px; }
.row-static .seg { grid-column: 1 / -1; display: flex; width: 100%; }
.row-static .seg button { flex: 1; justify-content: center; }
@media (min-width: 480px) { .row-static { grid-template-columns: auto 1fr auto; } .row-static .seg { grid-column: auto; width: auto; } }

/* ---------- Live journey ---------- */
.journey-bar {
  position: fixed; z-index: 45; left: 12px; right: 12px; bottom: calc(var(--tabbar-h) + 10px + env(safe-area-inset-bottom));
  display: flex; align-items: center; gap: 10px; padding: 12px 12px 12px 16px; border-radius: 16px;
  background: var(--surface); border: 1px solid var(--line); box-shadow: var(--shadow-2); animation: fadeIn .25s var(--ease);
}
@keyframes fadeIn { from { opacity: 0; } }
.jb-main { flex: 1; min-width: 0; display: grid; gap: 2px; }
.jb-step { font-size: .72rem; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: var(--primary); }
.jb-text { font-weight: 700; font-size: .98rem; line-height: 1.3; }
.jb-sub { font-size: .82rem; color: var(--text-2); }
.jb-actions { display: flex; align-items: center; gap: 4px; flex: none; }
#jbRecenter[aria-pressed="true"] { color: var(--primary); background: var(--primary-50); }
body.journeying .toast { bottom: calc(var(--tabbar-h) + 110px + env(safe-area-inset-bottom)); }
body.journeying .panel { padding-bottom: calc(var(--tabbar-h) + 120px); }
.tl.current .tl-node { box-shadow: 0 0 0 5px var(--primary-100); }
.tl.current .tl-title::after { content: ""; display: inline-block; width: 8px; height: 8px; margin-left: 8px; border-radius: 50%; background: var(--primary); vertical-align: middle; animation: pulse 1.2s infinite; }
.tl.done { opacity: .55; }
.you-dot { width: 18px; height: 18px; border-radius: 50%; background: #1951FC; border: 3px solid #fff; box-shadow: 0 0 0 6px rgba(25, 81, 252, .28), 0 1px 4px rgba(0, 0, 0, .4); }
@media (min-width: 768px) {
  .journey-bar { bottom: 20px; left: auto; right: 20px; width: min(440px, calc(100vw - 40px)); }
  body.journeying .toast { bottom: 130px; }
}
@media (min-width: 960px) {
  .journey-bar { right: auto; left: calc(440px + (100vw - 440px) / 2); transform: translateX(-50%); }
}
@media (min-width: 1280px) { .journey-bar { left: calc(480px + (100vw - 480px) / 2); } }

/* Dark theme: dim the map pictures so they don't glare (route lines and markers stay true colour) */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .leaflet-tile-pane { filter: invert(1) hue-rotate(180deg) brightness(.92) contrast(.88) saturate(.6); }
}
:root[data-theme="dark"] .leaflet-tile-pane { filter: invert(1) hue-rotate(180deg) brightness(.92) contrast(.88) saturate(.6); }

/* ---------- Admin: analytics ---------- */
.stat-block { margin-bottom: 18px; }
.stat-block h3 { font-size: .8rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--text-2); margin-bottom: 8px; }
.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(118px, 1fr)); gap: 8px; margin: 0; }
.stats > div { border: 1px solid var(--line); border-radius: 12px; padding: 10px 12px; background: var(--surface); }
.stats dt { font-size: .78rem; color: var(--text-2); }
.stats dd { margin: 2px 0 0; font-size: 1.4rem; font-weight: 800; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.top-routes { list-style: none; margin: 0; padding: 0; counter-reset: r; }
.top-routes li { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 9px 0; border-bottom: 1px solid var(--line); font-size: .92rem; }
.top-routes li:last-child { border-bottom: 0; }
.top-routes b { font-variant-numeric: tabular-nums; color: var(--primary); }

/* ---------- Paywall ---------- */
.pay-body { text-align: center; }
.pay-lead { font-size: 1.05rem; font-weight: 700; }
.pay-body .meta { margin: 8px auto 0; max-width: 34ch; }
.pay-price { font-size: 1.9rem; font-weight: 800; letter-spacing: -.02em; margin: 16px 0; color: var(--primary); }
.pay-body .btn-wide { margin-top: 8px; }

/* Count on the profile tab: feedback waiting should be visible from any screen,
   without having to go looking for it. */
.avatar, .nav-btn { position: relative; }
.badge {
  position: absolute; top: -3px; right: -7px; min-width: 18px; height: 18px; padding: 0 5px;
  display: grid; place-items: center; border-radius: 9px; border: 2px solid var(--surface);
  background: var(--error); color: #fff; font-size: .68rem; font-weight: 800; line-height: 1;
}
.nav-btn .badge { top: 4px; right: 8px; }

/* ---------- Admin: the feedback queue ---------- */
/* One account sees this, so it is built for scanning a list quickly rather than for looks:
   full-height sheet, the status filter pinned at the top, newest message first. */
/* [open] matters: a dialog is hidden by the browser's own `display: none`, so setting
   display here without it would leave the sheet on screen permanently. */
dialog.sheet.sheet-tall[open] { max-height: 92vh; display: flex; flex-direction: column; }
.seg-wrap { display: flex; flex-wrap: wrap; width: 100%; margin-bottom: 12px; }
.seg-wrap button { flex: 1 1 auto; justify-content: center; }
.admin-body { flex: 1 1 auto; overflow-y: auto; -webkit-overflow-scrolling: touch; }
.fb-card { border: 1px solid var(--line); border-radius: var(--radius); padding: 12px; margin-bottom: 10px; background: var(--surface); }
.fb-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; flex-wrap: wrap; }
.fb-top small { color: var(--text-2); font-size: .8rem; }
.fb-route { font-size: .9rem; color: var(--text-2); margin-top: 6px; }
.fb-msg { margin-top: 8px; white-space: pre-wrap; overflow-wrap: anywhere; }
.fb-acts { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.btn-quiet { min-height: 40px; padding: 0 12px; font-size: .85rem; font-weight: 600; background: var(--surface-2); color: var(--text-2); border-color: var(--line); }
.btn-quiet:hover { background: var(--primary-50); color: var(--primary); }

/* Theme picker (More → Settings) */
.seg { display: inline-flex; padding: 3px; gap: 2px; border-radius: var(--radius-pill); background: var(--surface-2); border: 1px solid var(--line); }
.seg button { min-height: 44px; padding: 0 12px; border: 0; border-radius: var(--radius-pill); background: none; color: var(--text-2); font-weight: 600; font-size: .85rem; display: inline-flex; align-items: center; gap: 5px; }
.seg button .ic { width: 16px; height: 16px; }
.seg button[aria-pressed="true"] { background: var(--surface); color: var(--primary); box-shadow: var(--shadow-1); }

.page-top + main { padding-top: 24px; }
body:not([data-view]) main .plans th, body:not([data-view]) main .plans td { padding: 9px 6px; font-size: .85rem; }
body:not([data-view]) main .plans td:first-child { padding-left: 12px; }

/* Map credit: small, folds into an (i) after a few seconds */
.leaflet-control-attribution.map-credit {
  margin: 0 6px 6px 0 !important; padding: 2px 8px !important; border-radius: 999px; font: 500 10px/1.6 var(--font);
  background: color-mix(in srgb, var(--surface) 85%, transparent) !important; color: var(--text-2); cursor: pointer;
  transition: opacity .3s;
}
.leaflet-control-attribution.map-credit a { color: var(--text-2); text-decoration: none; }
.leaflet-control-attribution.map-credit.folded { width: 18px; height: 18px; padding: 0 !important; overflow: hidden; color: transparent; position: relative; }
.leaflet-control-attribution.map-credit.folded * { visibility: hidden; }
.leaflet-control-attribution.map-credit.folded::after { content: "i"; position: absolute; inset: 0; display: grid; place-items: center; color: var(--text-2); font: 700 10px var(--font); visibility: visible; }

/* =========================================================
   Opening brand animation
   The route line draws itself, the two stops land on it, the name rises.
   It fades on its own after 3.2s, so a boot that never finishes can't trap anyone.
   ========================================================= */
.splash {
  position: fixed; inset: 0; z-index: 9999; display: grid; place-items: center;
  background: var(--bg); animation: splashAuto 3.2s forwards;
}
.splash-inner { display: grid; justify-items: center; gap: 2px; padding: 24px; text-align: center; }
.splash-mark { width: 84px; height: 84px; overflow: visible; fill: none; stroke: var(--primary); stroke-width: 1.6; stroke-linecap: round; }
.splash-mark .sp-line {
  stroke-dasharray: 100; stroke-dashoffset: 100;
  animation: spDraw .9s cubic-bezier(.65, 0, .35, 1) .15s forwards;
}
.splash-mark .sp-dot { opacity: 0; transform-box: fill-box; transform-origin: center; }
.splash-mark .sp-from { animation: spPop .45s cubic-bezier(.34, 1.56, .64, 1) .1s forwards; }
.splash-mark .sp-to { fill: var(--accent); stroke: var(--accent); animation: spPop .45s cubic-bezier(.34, 1.56, .64, 1) 1s forwards; }
.splash-name {
  margin-top: 14px; font-size: 1.6rem; font-weight: 800; letter-spacing: -.03em; color: var(--text);
  opacity: 0; animation: spRise .5s ease-out .75s forwards;
}
.splash-tag { font-size: .92rem; color: var(--text-2); opacity: 0; animation: spRise .5s ease-out .95s forwards; }

@keyframes spDraw { to { stroke-dashoffset: 0; } }
@keyframes spPop { from { opacity: 0; transform: scale(.4); } to { opacity: 1; transform: scale(1); } }
@keyframes spRise { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
/* the safety net: hidden by 3.2s whatever happens */
@keyframes splashAuto { 0%, 88% { opacity: 1; visibility: visible; } 100% { opacity: 0; visibility: hidden; } }

/* the app is ready, so leave early */
.splash.done {
  animation: none; opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity .4s ease, visibility 0s .4s;
}

@media (prefers-reduced-motion: reduce) {
  .splash { animation: splashAuto 1.2s forwards; }
  .splash-mark .sp-line { stroke-dashoffset: 0; animation: none; }
  .splash-mark .sp-dot, .splash-name, .splash-tag { opacity: 1; animation: none; }
}

/* ---------- Accounts ---------- */
.auth-body { display: grid; gap: 12px; padding: 0 4px 8px; }
.auth-body h2 { font-size: 1.25rem; font-weight: 800; letter-spacing: -.02em; margin: 0; }
.auth-why { color: var(--text-2); font-size: .94rem; margin: -6px 0 2px; }
.auth-social { display: grid; gap: 8px; }
.auth-social .btn { width: 100%; justify-content: center; }
.auth-or { display: flex; align-items: center; gap: 10px; color: var(--text-2); font-size: .82rem; }
.auth-or::before, .auth-or::after { content: ""; flex: 1; height: 1px; background: var(--line); }
#authForm { display: grid; gap: 12px; }
#authForm .field { display: grid; gap: 6px; }
#authForm label { font-size: .88rem; font-weight: 600; color: var(--text-2); }
#authForm label .opt { font-weight: 400; }
#authForm input {
  width: 100%; min-height: 48px; padding: 10px 12px; border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm); background: var(--surface-2); color: var(--text); font: inherit;
}
#authForm input:focus { outline: 2px solid var(--primary); outline-offset: -1px; background: var(--surface); }
.btn-wide { width: 100%; justify-content: center; min-height: 50px; }
.auth-error { color: var(--error); font-size: .9rem; margin: 0; }
.auth-switch { text-align: center; color: var(--text-2); font-size: .9rem; margin: 0; }
.auth-later { display: block; margin: 0 auto; color: var(--text-2); }
.auth-gate-note { color: var(--text-2); font-size: .88rem; margin: -4px 0 0; }

/* ---------- Turning location back on ---------- */
.gps-help { display: grid; gap: 12px; padding: 0 4px 8px; }
.gps-help h2 { font-size: 1.2rem; font-weight: 800; letter-spacing: -.02em; margin: 0; }
.gps-steps { counter-reset: gs; list-style: none; padding: 0; margin: 0; display: grid; gap: 8px; }
.gps-steps li {
  counter-increment: gs; position: relative; padding: 12px 14px 12px 46px;
  background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--radius-sm); font-size: .95rem;
}
.gps-steps li::before {
  content: counter(gs); position: absolute; left: 12px; top: 11px; display: grid; place-items: center;
  width: 24px; height: 24px; border-radius: 50%; background: var(--primary-50); color: var(--primary); font-weight: 800; font-size: .8rem;
}
.gps-steps b { font-weight: 700; }
.gps-actions { display: grid; gap: 8px; }

/* ---------- Filters ---------- */
.filter-btn {
  display: inline-flex; align-items: center; gap: 8px; min-height: 44px; padding: 0 16px; margin: 12px 0;
  border: 1px solid var(--line-strong); border-radius: var(--radius-pill); background: var(--surface);
  color: var(--text); font-weight: 600;
}
.filter-btn .ic { width: 18px; height: 18px; color: var(--primary); }
.filter-btn.active { border-color: var(--primary); color: var(--primary); }
.filter-count {
  display: grid; place-items: center; min-width: 20px; height: 20px; padding: 0 6px;
  border-radius: 999px; background: var(--primary); color: #fff; font-size: .72rem; font-weight: 800;
}
:root[data-theme="dark"] .filter-count { color: #0B0B0C; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .filter-count { color: #0B0B0C; } }

.filter-body { display: grid; gap: 18px; padding: 0 4px 8px; }
.filter-body h2 { font-size: 1.25rem; font-weight: 800; letter-spacing: -.02em; margin: 0; }
.filter-group { display: grid; gap: 10px; }
.filter-group h3 { font-size: .78rem; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--text-2); margin: 0; }
.filter-note { color: var(--text-2); font-size: .88rem; margin: 2px 0 0; }

.count-row { display: flex; align-items: center; gap: 12px; padding: 12px 14px; background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--radius-sm); }
.count-main { flex: 1; min-width: 0; display: grid; gap: 2px; }
.count-main b { font-weight: 700; font-size: .95rem; }
.count-main small { color: var(--text-2); font-size: .8rem; }
.counter { display: flex; align-items: center; gap: 4px; flex: none; }
.count-btn {
  display: grid; place-items: center; width: 44px; height: 44px; border-radius: 50%;
  border: 1px solid var(--line-strong); background: var(--surface); color: var(--text); font-size: 1.1rem; font-weight: 700; line-height: 1;
}
.count-btn:hover { border-color: var(--primary); color: var(--primary); }
.count-val { min-width: 24px; text-align: center; font-weight: 800; font-variant-numeric: tabular-nums; }

/* the route options, as full-width rows rather than a scrolling chip strip */
.toggle-row { display: block; }
.toggle-row input { position: absolute; opacity: 0; pointer-events: none; }
.toggle-row > span {
  display: flex; align-items: center; gap: 10px; min-height: 52px; padding: 10px 14px;
  border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface-2); font-weight: 600;
}
.toggle-row .ic { width: 20px; height: 20px; color: var(--text-2); }
.toggle-row input:checked + span { border-color: var(--primary); background: var(--primary-50); color: var(--primary); }
.toggle-row input:checked + span .ic { color: var(--primary); }
.toggle-row input:focus-visible + span { outline: 3px solid var(--primary); outline-offset: 2px; }
.filter-actions { display: grid; grid-template-columns: auto 1fr; gap: 8px; }
.filter-actions .btn { justify-content: center; min-height: 50px; }

/* ---------- Profile drawer ---------- */
.avatar {
  display: grid; place-items: center; width: 24px; height: 24px; border-radius: 50%;
  background: var(--primary-50); color: var(--primary); font-size: .72rem; font-weight: 800; line-height: 1;
}
.avatar .ic { width: 18px; height: 18px; }
.avatar.has-letter { background: var(--primary); color: #fff; }
:root[data-theme="dark"] .avatar.has-letter { color: #0B0B0C; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .avatar.has-letter { color: #0B0B0C; } }
.avatar-lg { width: 44px; height: 44px; font-size: 1.1rem; }
.avatar-lg .ic { width: 24px; height: 24px; }

.drawer-scrim {
  position: fixed; inset: 0; z-index: 60; background: rgba(0, 0, 0, .45);
  opacity: 0; transition: opacity .25s var(--ease);
}
.drawer-open .drawer-scrim { opacity: 1; }

.drawer {
  position: fixed; top: 0; right: 0; bottom: 0; z-index: 61; width: min(420px, 90vw);
  display: flex; flex-direction: column; background: var(--bg); border-left: 1px solid var(--line);
  box-shadow: var(--shadow-2); transform: translateX(100%); transition: transform .26s var(--ease);
  padding-top: env(safe-area-inset-top);
}
.drawer-open .drawer { transform: none; }
.drawer-head {
  display: flex; align-items: center; gap: 12px; padding: 14px 12px 14px 16px; border-bottom: 1px solid var(--line); flex: none;
}
.drawer-who { display: flex; align-items: center; gap: 12px; flex: 1; min-width: 0; }
.drawer-name { display: grid; gap: 1px; min-width: 0; }
.drawer-name b { font-size: 1rem; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.drawer-name small { color: var(--text-2); font-size: .82rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.drawer-body {
  flex: 1; overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
  padding: 8px 16px calc(24px + env(safe-area-inset-bottom));
}
.drawer-body .block { margin-top: 18px; }
.drawer-body .block:first-child { margin-top: 6px; }

@media (prefers-reduced-motion: reduce) {
  .drawer, .drawer-scrim { transition: none; }
}

/* ---------- Link-style buttons inside the app ---------- */
/* .link was only styled on the static pages, so in the app these fell back to a plain
   browser button. */
.link {
  background: none; border: 0; padding: 0; min-height: 0;
  color: var(--primary); font-weight: 600; font-size: inherit; text-align: left;
}
.link:hover { text-decoration: underline; }
.auth-switch .link { min-height: 44px; padding: 0 4px; }
/* standalone link-buttons still need a finger-sized target */
.auth-later, .row-btn .link, .drawer-body .link { min-height: 44px; padding: 0 8px; }

/* ---------- "Check your email" ---------- */
.auth-sent { display: grid; justify-items: center; gap: 10px; text-align: center; padding: 8px 4px 4px; }
.auth-sent-ic {
  display: grid; place-items: center; width: 56px; height: 56px; border-radius: 50%;
  background: var(--primary-50); color: var(--primary); margin-bottom: 2px;
}
.auth-sent-ic .ic { width: 28px; height: 28px; }
.auth-sent h2 { font-size: 1.25rem; font-weight: 800; letter-spacing: -.02em; margin: 0; }
.auth-sent-where { font-size: .98rem; color: var(--text); margin: 0; word-break: break-word; }
.auth-sent-where b { font-weight: 700; }
.auth-sent-hint { font-size: .88rem; color: var(--text-2); margin: 0; }
.auth-sent-actions { display: grid; gap: 8px; width: 100%; margin-top: 8px; }

/* ---------- Drawer: signed out invitation, and the way out ---------- */
.signin-cta {
  display: grid; gap: 4px; padding: 16px; border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--surface);
}
.signin-cta b { font-size: 1rem; font-weight: 700; }
.signin-cta small { color: var(--text-2); font-size: .86rem; margin-bottom: 8px; }
.row-btn.danger { color: var(--error); }
.row-btn.danger .ic-lead { background: var(--error-50); color: var(--error); }
.row-btn.danger .row-main small { color: var(--text-2); }
/* signing out is not navigation, so it gets no chevron */
.row-btn.danger > .ic:last-child { display: none; }
/* a stacked label and detail should stack in every row, not only in link rows */
.row-static .row-main b, .row-static .row-main small { display: block; }
.row-static .row-main small { color: var(--text-2); font-size: .82rem; }

/* Clear the field in one tap. It shows while a field is being edited; the star takes its
   place once a destination is settled, so a field never carries two actions at once. */
.field-clear .ic { width: 18px; height: 18px; color: var(--text-2); }
.field-clear:hover .ic { color: var(--text); }
