/* GoSEQ design system — one set of tokens, one type scale, one card style. */
/* Plus Jakarta Sans (OFL, bundled in fonts/ so it works offline) */
@font-face { font-family: 'Jakarta'; src: url('../fonts/jakarta.woff2') format('woff2'); font-weight: 200 800; font-style: normal; font-display: swap; }
:root {
  /* UI revamp phase 2 (UI-PHASE2.md): one set of colour tokens. --muted is text-2 (second lines); --text-3 is meta only. */
  --bg: #F6F3EF; --surface: #FFFFFF; --surface-2: #EFEBE6; --surface-3: #E6E0DA; --text: #1B1614; --muted: #5E5550; --text-2: var(--muted); --text-3: #81776F; --line: rgba(27, 22, 20, .10);
  --accent: #C0352A; --accent-soft: #FDE7E1; --on-accent: #FFFFFF; --ok: #0E7A4A; --ok-soft: #E1F3E9; --sun: #FFB21E; --warn: #9A5300; --warn-soft: #FFF1DC; --bad: #B42318; --bad-soft: #FDE8E6;
  --brand-grad: linear-gradient(135deg, #FF9152 0%, #F0513E 55%, #B8264A 100%);
  --shadow: 0 1px 2px rgba(0, 0, 0, .05), 0 6px 20px rgba(0, 0, 0, .06); --shadow-up: 0 -6px 30px rgba(0, 0, 0, .14);
  --elev-1: 0 1px 2px rgba(0, 0, 0, .05), 0 2px 8px rgba(0, 0, 0, .04); --elev-2: var(--shadow); --elev-3: var(--shadow-up);
  /* spacing on a 4/8 grid; a 16 px screen edge (Apple's compact margin) */
  --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px; --sp-5: 20px; --sp-6: 24px; --sp-8: 32px; --sp-12: 48px;
  --edge: 16px; --card-pad: 16px; --card-gap: 12px; --section-gap: 24px;
  /* radii: 8 badges, 12 inputs and small tiles, 16 inner panels, 24 cards, 28 sheet tops, pill buttons and chips */
  --r-badge: 8px; --r-chip: 12px; --r-inner: 16px; --r-card: 24px; --r-panel: 28px; --r-pill: 999px;
  /* one type scale (css font sizes from 12 to 32 px map onto these; under 12 is map/badge micro type, 34 and up display numbers) */
  --fs-cap: 12px; --fs-foot: 13px; --fs-sub: 15px; --fs-body: 16px; --fs-row: 17px; --fs-title3: 20px; --fs-title2: 24px; --fs-title: 28px; --fs-count: 40px; --fs-hero: 64px;
  --fs-label: var(--fs-cap); --fs-detail: var(--fs-sub); --fs-card: var(--fs-title3);
  /* one primary: the accent pill, 52 px (sign-in keeps its own ink button) */
  --btn-h: 52px; --main-bg: var(--accent); --main-fg: var(--on-accent); --ring: color-mix(in srgb, var(--text) 30%, transparent);
  --r: var(--r-card); --r-sm: var(--r-chip); --nav-h: 64px; /* Capacitor 8 passes the status/navigation bar sizes as --safe-area-inset-* (Android WebViews don't always fill env()) */
  --safe-top: var(--safe-area-inset-top, env(safe-area-inset-top, 0px)); --safe-bot: var(--safe-area-inset-bottom, env(safe-area-inset-bottom, 0px));
  --font: "Jakarta", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  color-scheme: light;
}
:root[data-theme="dark"] {
  /* a darker base and lighter second lines than 3.9.67, for contrast; elevation is a 1 px light ring plus a deeper shadow */
  --bg: #0F0D0C; --surface: #1A1716; --surface-2: #24201E; --surface-3: #2E2927; --text: #F6F1EE; --muted: #BBB1AB; --text-3: #978C86; --line: rgba(246, 241, 238, .12);
  --accent: #FF7A66; --accent-soft: #3A1A16; --on-accent: #2B0D05; --ok: #4CD39A; --ok-soft: #173427; --sun: #FFC23D; --warn: #F2B35C; --warn-soft: #3A2A12; --bad: #FF8A7E; --bad-soft: #3D1A17;
  --shadow: 0 0 0 1px rgba(255, 255, 255, .06), 0 6px 20px rgba(0, 0, 0, .45); --elev-1: 0 0 0 1px rgba(255, 255, 255, .06), 0 2px 8px rgba(0, 0, 0, .35); color-scheme: dark;
}
* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html, body { margin: 0; height: 100%; background: var(--bg); color: var(--text); font: 16px/1.4 var(--font); -webkit-font-smoothing: antialiased; overscroll-behavior: none; }
button, input, select { font: inherit; color: inherit; }
button { cursor: pointer; border: 0; background: none; padding: 0; }
input { outline: none; }
/* a clear focus ring for keyboard and switch users (not on tap) */
:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; border-radius: 8px; }
input:focus-visible { outline: none; box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 45%, transparent); }
h1:focus, h2:focus, .overlay:focus { outline: none; }
/* lists clip what spills out of them (overflow: hidden, for the rounded corners), so the ring goes inside there */
.list :focus-visible { outline-offset: -3px; }
/* a text box's ring goes round its whole field (the textarea itself has no edge to ring) */
.field:has(textarea:focus-visible) { box-shadow: var(--shadow), 0 0 0 3px color-mix(in srgb, var(--accent) 45%, transparent); }
.updp-fb textarea:focus-visible { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 45%, transparent); }
[hidden] { display: none !important; }
.i { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; flex: none; }
.i.sm { width: 18px; height: 18px; } .i.lg { width: 26px; height: 26px; }

/* ---------- app shell ---------- */
#app { position: fixed; inset: 0; display: flex; flex-direction: column; }
.screen { position: absolute; inset: 0; bottom: calc(var(--nav-h) + var(--safe-bot)); overflow-y: auto; padding: calc(var(--safe-top) + 12px) 16px 24px; -webkit-overflow-scrolling: touch; }
.screen.full { bottom: 0; padding: 0; overflow: hidden; }
/* The clock and battery sit over the app: a strip of the page colour behind them, so scrolled content never runs
   under the time. Not on the map, which runs full-bleed under the status bar the way map apps do. */
body::before { content: ""; position: fixed; left: 0; right: 0; top: 0; height: var(--safe-top); z-index: 20; background: var(--bg); pointer-events: none; }
@supports (background: color-mix(in srgb, red 50%, blue)) { body::before { background: color-mix(in srgb, var(--bg) 86%, transparent); -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px); } }
body[data-tab="map"]::before { display: none; }
.nav { position: fixed; left: 0; right: 0; bottom: 0; height: calc(var(--nav-h) + var(--safe-bot)); padding-bottom: var(--safe-bot); display: grid; grid-template-columns: repeat(4, 1fr); background: var(--surface); border-top: 1px solid var(--line); z-index: 20; }
.nav button { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; font-size: var(--fs-cap); line-height: 1.2; font-weight: 600; color: var(--muted); white-space: nowrap; min-width: 0; }
.nav button[aria-current="page"] { color: var(--accent); }
.nav button[aria-current="page"] .i { stroke-width: 2.4; }
body.overlay-open .nav { display: none; }

/* ---------- type ---------- */
h1 { font-size: var(--fs-title); line-height: 1.15; margin: 0; letter-spacing: -.02em; font-weight: 700; }
h2 { font-size: var(--fs-title3); margin: 0; letter-spacing: -.01em; font-weight: 700; }
.label { font-size: var(--fs-foot); font-weight: 600; color: var(--muted); }
.muted { color: var(--muted); } .small { font-size: var(--fs-sub); } .tiny { font-size: var(--fs-foot); }
.section { margin: 26px 0 10px; display: flex; align-items: baseline; justify-content: space-between; }
.section h2 { font-size: var(--fs-row); }
.link { color: var(--accent); font-weight: 600; font-size: var(--fs-sub); padding: 8px 0; }

/* ---------- surfaces ---------- */
.card { background: var(--surface); border-radius: var(--r); box-shadow: var(--shadow); padding: 18px; }
.row { display: flex; align-items: center; gap: 12px; }
.list { background: var(--surface); border-radius: var(--r); box-shadow: var(--shadow); overflow: hidden; }
.list > * + * { border-top: 1px solid var(--line); }
.item { display: flex; align-items: center; gap: 12px; width: 100%; padding: 14px 16px; text-align: left; min-height: 56px; }
.item:active { background: var(--surface-2); }
.item .grow { flex: 1; min-width: 0; }
.item b { font-weight: 600; font-size: var(--fs-body); white-space: normal; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; overflow-wrap: anywhere; }
.item small { color: var(--muted); font-size: var(--fs-sub); margin-top: 1px; line-height: 1.35; white-space: normal; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; overflow-wrap: anywhere; }
.ico { width: 38px; height: 38px; border-radius: 12px; display: grid; place-items: center; background: var(--surface-2); color: var(--text); flex: none; }
.ico.accent { background: var(--accent-soft); color: var(--accent); }

/* ---------- controls ---------- */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-height: 50px; padding: 0 18px; border-radius: 14px; font-weight: 700; font-size: var(--fs-body); background: var(--surface-2); color: var(--text); }
.btn.primary { background: var(--accent); color: var(--on-accent); }
.btn.block { width: 100%; }
.btn.sm { min-height: 38px; padding: 0 14px; font-size: var(--fs-sub); border-radius: 11px; }
.btn.on { background: var(--accent-soft); color: var(--accent); }
/* a reminder that can't reach you: GoSEQ's notifications are switched off in Android */
.btn.off-warn { background: var(--warn-soft); color: var(--warn); }
.btn:active { transform: scale(.98); }
.chip { display: inline-flex; align-items: center; gap: 6px; min-height: 40px; padding: 0 14px; border-radius: 999px; background: var(--surface); box-shadow: var(--shadow); font-weight: 600; font-size: var(--fs-sub); white-space: nowrap; }
.chip[aria-pressed="true"] { background: var(--text); color: var(--bg); }
.chips { display: flex; gap: 8px; overflow-x: auto; padding: 2px 16px 6px; margin: 0 -16px; scrollbar-width: none; }
.chips::-webkit-scrollbar { display: none; }
.seg { display: flex; background: var(--surface-2); border-radius: 12px; padding: 3px; gap: 3px; }
.seg button { flex: 1; min-height: 44px; border-radius: 10px; font-weight: 600; font-size: var(--fs-sub); color: var(--muted); }
.seg button[aria-pressed="true"] { background: var(--surface); color: var(--accent); font-weight: 700; box-shadow: 0 1px 4px rgba(0, 0, 0, .1), inset 0 0 0 1.5px var(--accent); }
.field { display: block; background: var(--surface); border-radius: 14px; padding: 10px 14px; box-shadow: var(--shadow); position: relative; }
.field span { display: block; font-size: var(--fs-foot); font-weight: 600; color: var(--muted); }
.field input, .field select { width: 100%; border: 0; background: transparent; font-size: var(--fs-row); padding: 3px 0; }
.searchbar { display: flex; align-items: center; gap: 12px; width: 100%; min-height: 54px; padding: 0 16px; border-radius: 16px; background: var(--surface); box-shadow: var(--shadow); color: var(--muted); font-size: var(--fs-row); text-align: left; }
.toggle::before { content: ""; position: absolute; inset: -8px -6px; }
.toggle { position: relative; width: 50px; height: 30px; border-radius: 99px; background: var(--surface-2); flex: none; transition: background .15s; }
.toggle::after { content: ""; position: absolute; top: 3px; left: 3px; width: 24px; height: 24px; border-radius: 50%; background: #fff; box-shadow: 0 1px 3px rgba(0, 0, 0, .25); transition: transform .15s; }
.toggle[aria-checked="true"] { background: var(--accent); } .toggle[aria-checked="true"]::after { transform: translateX(20px); }
/* off: an edge and a darker knob, so the switch and which way it's set stand out from the card (3:1), as Android's do */
.toggle:not([aria-checked="true"]) { box-shadow: inset 0 0 0 2px var(--muted); } .toggle:not([aria-checked="true"])::after { background: var(--muted); box-shadow: none; transform: scale(.8); }

/* ---------- route badges ---------- */
.badge { display: inline-flex; align-items: center; justify-content: center; gap: 4px; min-width: 42px; height: 28px; padding: 0 8px; border-radius: 8px; font-weight: 800; font-size: var(--fs-sub); background: var(--text); color: var(--bg); white-space: nowrap; flex: none; }
.badge .i { width: 15px; height: 15px; stroke-width: 2.4; }
.arrow { color: var(--muted); font-weight: 700; }
.live { display: inline-flex; align-items: center; gap: 5px; color: var(--ok); font-weight: 700; }
.live::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.late { color: var(--bad); font-weight: 600; } .early { color: var(--warn); font-weight: 600; }

/* ---------- home ---------- */
.top { display: flex; align-items: center; justify-content: space-between; margin: 4px 0 14px; }
.logo { display: flex; align-items: center; gap: 8px; font-weight: 800; font-size: var(--fs-title3); letter-spacing: -.02em; }
.logo svg { width: 28px; height: 28px; }
.trip-card { padding: 20px; }
.trip-head { display: flex; align-items: center; gap: 10px; margin-bottom: 4px; }
.trip-head .grow { flex: 1; min-width: 0; }
.trip-when { font-size: var(--fs-sub); color: var(--muted); font-weight: 600; }
.trip-dest { font-size: var(--fs-row); font-weight: 700; }
.big { font-size: 34px; font-weight: 800; letter-spacing: -.03em; line-height: 1.08; margin: 14px 0 4px; font-variant-numeric: tabular-nums; }
.big em { font-style: normal; color: var(--accent); }
.sub { font-size: var(--fs-body); color: var(--muted); margin: 0 0 16px; }
.sub b { color: var(--text); font-weight: 600; }
.steps { list-style: none; margin: 0 0 16px; padding: 0; position: relative; }
.steps li { position: relative; display: grid; grid-template-columns: 72px 1fr; gap: 10px; padding: 7px 0 7px 22px; font-size: var(--fs-sub); line-height: 1.35; }
.steps li::before { content: ""; position: absolute; left: 3px; top: 13px; width: 10px; height: 10px; border-radius: 50%; border: 2.5px solid var(--accent); background: var(--surface); z-index: 1; }
.steps li::after { content: ""; position: absolute; left: 8px; top: 20px; bottom: -8px; width: 2px; background: var(--line); }
.steps li:last-child::after { display: none; }
.steps li.walk::before { border-style: dotted; border-color: var(--muted); }
.steps li.change::before { background: var(--accent); }
.steps time { font-weight: 700; font-variant-numeric: tabular-nums; }
.note { display: flex; gap: 10px; align-items: flex-start; padding: 12px 14px; border-radius: 14px; background: var(--surface-2); font-size: var(--fs-sub); margin: 0 0 14px; }
.note.warn { background: var(--warn-soft); } .note.bad { background: var(--bad-soft); }
.rider-on { display: flex; align-items: center; gap: 6px; margin: 10px 2px 0; }
/* How full is it? (js/community.js): asked once on board, and what riders said */
.crowd-ask .btn { background: var(--bg); border: 1px solid var(--line); }
.crowd-ask .btn.ghost { background: none; border-color: transparent; color: var(--muted); }
.crowd-now, .crowd-done { margin: 10px 2px 0; }
.crowd-now b { color: var(--text); }
.crowd-done .link { padding: 0 0 0 4px; font-size: var(--fs-foot); }
.v-spd { color: var(--text); font-variant-numeric: tabular-nums; }
#share-bus-note .helped { display: block; font-size: var(--fs-foot); font-weight: 700; color: var(--accent); margin-bottom: 2px; }
.note b { display: block; } .note b.in { display: inline; }   /* bold inside a sentence stays in the sentence */
.actions { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.actions .btn { font-size: var(--fs-sub); padding: 0 12px; }
.also { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-top: 14px; font-size: var(--fs-sub); color: var(--muted); }
.also button { padding: 6px 10px; border-radius: 99px; background: var(--surface-2); font-weight: 600; color: var(--text); font-size: var(--fs-sub); }
.empty { text-align: center; padding: 26px 18px; }
.empty h2 { margin-bottom: 6px; }
.empty p { color: var(--muted); margin: 0 0 16px; }
.setup .field { margin-bottom: 10px; box-shadow: none; background: var(--surface-2); }
.dep { display: flex; align-items: center; gap: 12px; padding: 12px 16px; min-height: 56px; width: 100%; text-align: left; }
.dep .grow { flex: 1; min-width: 0; }
.dep b { font-size: var(--fs-body); white-space: normal; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; overflow-wrap: anywhere; }
.dep small { font-size: var(--fs-sub); color: var(--muted); line-height: 1.35; white-space: normal; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; overflow-wrap: anywhere; }
.dep .mins { font-size: var(--fs-title3); font-weight: 800; font-variant-numeric: tabular-nums; text-align: right; }
.dep .mins small { font-size: var(--fs-cap); font-weight: 600; text-align: right; }
.dep.sched .mins { font-size: var(--fs-body); font-weight: 700; color: var(--muted); }
/* a cancelled service (departures(…, { cancelled: true })): shown, struck through, never the next bus */
.dep.cancelled b, .dep.cancelled .mins { text-decoration: line-through; color: var(--muted); }
/* (no fading on top: the struck-through grey text must still read at 4.5:1) */

/* ---------- overlays (search, ride, editors) ---------- */
.overlay { position: fixed; inset: 0; z-index: 40; background: var(--bg); display: flex; flex-direction: column; animation: up .2s ease-out; }
@keyframes up { from { transform: translateY(24px); opacity: 0; } }
.overlay-top { display: flex; align-items: center; gap: 8px; padding: calc(var(--safe-top) + 10px) 12px 10px; }
.overlay-body { flex: 1; overflow-y: auto; padding: 4px 16px 32px; }
.iconbtn { width: 44px; height: 44px; border-radius: 12px; display: grid; place-items: center; flex: none; }
.iconbtn:active { background: var(--surface-2); }
.search-input { flex: 1; min-height: 50px; border-radius: 14px; background: var(--surface); box-shadow: var(--shadow); padding: 0 16px; font-size: var(--fs-row); border: 0; }
.fromrow { display: flex; align-items: center; gap: 10px; margin: 0 0 12px; padding: 12px 16px; border-radius: 14px; background: var(--surface); box-shadow: var(--shadow); width: 100%; text-align: left; font-size: var(--fs-sub); }
.fromrow b { font-weight: 600; }
.group { font-size: var(--fs-foot); font-weight: 700; color: var(--muted); margin: 18px 4px 8px; }
.opt { display: block; width: 100%; text-align: left; padding: 16px; }
.opt + .opt { border-top: 1px solid var(--line); }
.opt-top { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.opt-top .grow { flex: 1; }
.opt-time { font-size: var(--fs-row); font-weight: 800; font-variant-numeric: tabular-nums; }
.opt-meta { font-size: var(--fs-sub); color: var(--muted); margin-top: 4px; }
.walk-steps { margin: 8px 0 0; padding: 0; list-style: none; font-size: var(--fs-sub); }
.walk-steps li { padding: 8px 0; border-top: 1px solid var(--line); display: flex; justify-content: space-between; gap: 12px; }
.walk-steps li span { color: var(--muted); flex: none; }
details.walk { margin-top: 10px; } details.walk summary { font-weight: 600; color: var(--accent); padding: 8px 0; list-style: none; }

/* ---------- bottom sheet (map) ---------- */
.sheet { position: absolute; left: 0; right: 0; bottom: 0; z-index: 12; background: var(--surface); border-radius: 22px 22px 0 0; box-shadow: var(--shadow-up); display: flex; flex-direction: column; max-height: 88%; transition: height .25s cubic-bezier(.2, .8, .2, 1); touch-action: none; }
.sheet .grip { flex: none; padding: 14px 0 12px; display: grid; place-items: center; cursor: grab; position: relative; }
/* a small spinner just right of the handle while bus positions refresh */
.sheet .grip .sheet-spin { position: absolute; left: calc(50% + 30px); top: 7px; width: 18px; height: 18px; opacity: 0; transition: opacity .2s; pointer-events: none; }
.sheet .grip .sheet-spin circle { stroke: var(--accent); stroke-dasharray: 89, 200; stroke-dashoffset: -35; }
.sheet .grip .sheet-spin.on { opacity: 1; }
.sheet .grip::after { content: ""; position: absolute; left: 0; right: 0; top: -13px; height: 44px; }   /* a 44 px target without a taller sheet (as the trip screen's handle) */
.sheet .grip::before { content: ""; width: 40px; height: 5px; border-radius: 3px; background: var(--line); background: rgba(128, 128, 128, .4); }
/* the tab bar sits over the sheet, so the last row needs room to clear it — without this you can scroll to
   the end and still not reach it */
.sheet-body { flex: 1; overflow-y: auto; padding: 0 16px calc(16px + var(--nav-h) + var(--safe-bot)); touch-action: pan-y; }
.sheet-head { display: flex; align-items: flex-start; gap: 10px; margin-bottom: 10px; touch-action: none; cursor: grab; }
.sheet[data-state="peek"] .sheet-body { touch-action: none; }
.sheet-head .grow { flex: 1; min-width: 0; }
.sheet-head h2 { font-size: var(--fs-title3); }

/* ---------- map ---------- */
.mv { position: absolute; inset: 0; overflow: hidden; isolation: isolate; contain: paint; background: #E8E6E0; touch-action: none; user-select: none; }
:root[data-theme="dark"] .mv { background: #1B2322; }
.mv-world, .mv-tiles, .mv-back, .mv-stops, .mv-markers, .mv-lines { position: absolute; inset: 0; }
/* 6 Oct: each tile layer is its own stacking context. With HERE tiles the filter is none, so the tiles' own z-index (1–3)
   used to escape and paint over the stop pins, lines and any legend on the map. */
.mv-tiles, .mv-back, .mv-traffic { isolation: isolate; z-index: 0; }
.mv-lines { z-index: 1; } .mv-stops { z-index: 2; } .mv-markers { z-index: 3; } .mv-attr { z-index: 4; }
.mv-lines { width: 100%; height: 100%; pointer-events: none; overflow: visible; }
.mv-tile { position: absolute; left: 0; top: 0; width: 256px; height: 256px; opacity: 0; transition: opacity .2s; user-select: none; -webkit-user-drag: none; }
.mv-tile.in { opacity: 1; }
.mv-back .mv-tile { opacity: 1; }
.mv-tiles, .mv-back { filter: saturate(.55) contrast(.94) brightness(1.03); }
:root[data-theme="dark"] .mv-tiles, :root[data-theme="dark"] .mv-back { filter: invert(1) hue-rotate(180deg) brightness(.9) contrast(.9) saturate(.7); }
.mv-back { pointer-events: none; transition: opacity .18s; }
.mv-stops, .mv-markers { pointer-events: none; transition: opacity .12s; }
.mv-stop { position: absolute; left: 0; top: 0; width: 14px; height: 14px; margin: -7px 0 0 -7px; border-radius: 50%; background: #fff; border: 2.5px solid #5E6966; pointer-events: auto; }
.mv-stop::after { content: ""; position: absolute; inset: -10px; }
.mv-marker { position: absolute; left: 0; top: 0; transform: translate(-50%, -50%); pointer-events: auto; display: flex; align-items: center; gap: 4px; height: 30px; padding: 0 8px 0 6px; border-radius: 10px; background: var(--c, #121A18); color: var(--t, #fff); font-weight: 800; font-size: var(--fs-foot); box-shadow: 0 2px 8px rgba(0, 0, 0, .25); border: 2px solid #fff; white-space: nowrap; }
.mv-marker .i { width: 15px; height: 15px; stroke-width: 2.4; }
.mv-marker::after { content: ""; position: absolute; inset: -8px; }
.mv-marker.sel { transform: translate(-50%, -50%) scale(1.15); z-index: 3; box-shadow: 0 0 0 4px rgba(196, 57, 31, .35), 0 2px 8px rgba(0, 0, 0, .3); }
/* your own bus while you're on it: one pill, "66 You", in place of the blue dot */
.mv-marker.you { z-index: 4; box-shadow: 0 0 0 5px rgba(26, 115, 232, .3), 0 2px 8px rgba(0, 0, 0, .3); }
.mv-marker .mv-you { margin-left: 2px; padding: 1px 5px; border-radius: 6px; background: var(--t, #fff); color: var(--c, #121A18); font-size: 11px; line-height: 15px; }
.mv-marker:active { scale: .94; }
/* the bus's speed beside its number, or "Stuck" (mapscreen.js speedTag) */
.mv-marker .mv-spd { margin-left: 3px; padding: 1px 5px; border-radius: 6px; background: color-mix(in srgb, var(--t, #fff) 20%, transparent); font-size: 11px; line-height: 15px; font-weight: 700; font-variant-numeric: tabular-nums; }
.mv-marker .mv-spd small { font-size: 9px; margin-left: 1px; opacity: .85; }
.mv-marker .mv-spd.stuck { background: #F2A900; color: #1B1500; }
.mv-marker .mv-spd.stopped { opacity: .75; }   /* a bus at a stop or a light: nothing's wrong, so no warning colour */
/* placed and turned by headArrow() in mapscreen.js: just outside the pill, pointing the way the bus is going */
.mv-marker .hd { position: absolute; width: 0; height: 0; border: 5px solid transparent; border-bottom: 6px solid var(--c, #121A18); border-top: 0; }
.mv-user { position: absolute; left: 0; top: 0; width: 18px; height: 18px; margin: -9px 0 0 -9px; border-radius: 50%; background: #1A73E8; border: 3px solid #fff; box-shadow: 0 0 0 6px rgba(26, 115, 232, .2); pointer-events: none; }
.mv-line-halo { fill: none; stroke: #fff; stroke-width: 9; stroke-linecap: round; stroke-linejoin: round; opacity: .9; }
.mv-line { fill: none; stroke: var(--accent); stroke-width: 5; stroke-linecap: round; stroke-linejoin: round; }
/* a trip's path, coloured by speed (mapview drawSegs): walking dashed, riding solid, all on one white halo */
.mv-seg-halo { fill: none; stroke: #fff; stroke-width: 10; stroke-linecap: round; stroke-linejoin: round; opacity: .9; }
.mv-seg { fill: none; stroke-width: 6; stroke-linecap: round; stroke-linejoin: round; }
/* the map credit sits top-right, under the map's own controls, where no sheet or panel ever covers it */
/* the support console's spinner (worker/public/support): one accent-coloured arc, on a small card in the middle of the map */
.mv-loading { position: absolute; left: 50%; top: 42%; z-index: 2; display: grid; place-items: center; width: 48px; height: 48px; margin: -24px 0 0 -24px; border-radius: 50%; background: var(--surface, #fff); color: var(--accent); box-shadow: 0 2px 10px rgba(0, 0, 0, .18); pointer-events: none; opacity: 0; scale: .8; transition: opacity .2s, scale .2s; }
.mv-loading.on { opacity: 1; scale: 1; }
.mv-loading .spinner { width: 26px; height: 26px; }
.mv-loading .spinner circle { stroke-dasharray: 89, 200; stroke-dashoffset: -35; }   /* with reduce motion on, a still arc rather than a dot */
.mv-attr { position: absolute; right: 8px; top: calc(var(--safe-top) + 74px); font-size: 11px; line-height: 1; color: #333; background: rgba(255, 255, 255, .82); padding: 4px 7px; border-radius: 6px; z-index: 2; text-decoration: none; }
.ride-map .mv-attr { top: auto; right: auto; left: 8px; bottom: 24px; }   /* bottom left, just above the card: along the top it sat behind Share and Get home safe */
.pin-map .mv-attr { top: auto; bottom: 8px; }        /* never over the pin you're placing */
/* the Map tab: under the zoom buttons, right-aligned with them (level with them, the credit ran under the buttons,
   cut off at "OpenStreetMap con", and under the "Route 60 only" pill) */
#map .mv-attr { right: 12px; top: calc(var(--safe-top) + 177px); }
.map-top { position: absolute; left: 12px; right: 12px; top: calc(var(--safe-top) + 10px); z-index: 10; display: flex; gap: 8px; }
.map-top .searchbar { flex: 1; }
.fab { width: 50px; height: 50px; border-radius: 14px; background: var(--surface); box-shadow: var(--shadow); display: grid; place-items: center; flex: none; }
.zoom { position: absolute; right: 12px; z-index: 10; display: flex; flex-direction: column; border-radius: 14px; overflow: hidden; background: var(--surface); box-shadow: var(--shadow); top: calc(var(--safe-top) + 72px); }
.zoom button { width: 50px; height: 48px; display: grid; place-items: center; }
.zoom button + button { border-top: 1px solid var(--line); }
.pill { position: absolute; z-index: 10; left: 50%; transform: translateX(-50%); top: calc(var(--safe-top) + 72px); display: flex; align-items: center; gap: 8px; padding: 10px 14px; border-radius: 99px; background: var(--text); color: var(--bg); font-weight: 700; font-size: var(--fs-sub); box-shadow: var(--shadow); }

/* ---------- ride ---------- */
.ride-map { position: relative; flex: 1; min-height: 12%; }
.ride-map .recenter { position: absolute; right: 12px; bottom: 34px; z-index: 10; color: var(--accent); }   /* above the panel's rounded top */
.ride-map .recenter[hidden] { display: none; }
/* map-first: the trip card is a sheet over the bottom of the map. Small, it holds what matters now (at most ~56% of
   the screen, so the map stays the main thing); opened (dragged up, flicked, or by its handle), every detail: 88%, and
   never up under the buttons along the top. ride.js moves it: while it moves (.moving) its height is held in px and
   whatever is above the card's height slides over the map (--lift) instead of squeezing it. */
.ride-sheet { background: var(--surface); border-radius: 22px 22px 0 0; box-shadow: var(--shadow-up); margin-top: calc(-18px - var(--lift, 0px)); position: relative; z-index: 11; display: flex; flex-direction: column; max-height: 56%; }
.ride-sheet.open { max-height: min(88%, calc(100% - var(--safe-top) - 72px)); }
/* the card with Check my stop on it and no room left: a little taller, rather than the check behind "More" (ride.js fitCard) */
.ride-sheet.tall:not(.open) { max-height: 68%; }
.ride-sheet.moving { max-height: none; will-change: height, transform; overflow: hidden; }
.ride-sheet.moving .ride-panel { overflow-y: hidden; }
/* the card and the peek don't scroll (what doesn't fit is behind "More"), so a finger anywhere on them moves the sheet */
.ride-sheet:not(.open):not(.flat) .ride-panel { overflow-y: hidden; touch-action: none; }
/* peek: the first line, the big words and the buttons */
.ride-sheet.peek:not(.open) .ride-now > :not(.phase-row):not(.big) { display: none; }
.ride-sheet.peek:not(.open) .ride-now .big { margin-bottom: 8px; }
.ride-sheet.flat { max-height: 64%; }
.ride-grip { flex: none; width: 100%; height: 26px; display: grid; place-items: center; touch-action: none; cursor: grab; border-radius: 22px 22px 0 0; }
.ride-grip span { width: 44px; height: 5px; border-radius: 3px; background: color-mix(in srgb, var(--text) 32%, transparent); transition: background .15s; }
.ride-grip:active span { background: var(--accent); }
.ride-grip[hidden] { display: block; visibility: hidden; height: 12px; }
.ride-panel { padding: 0 18px; flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; }
.ride-panel, .plan-sheet, .plan-body, #sb, .ns-sheet { overflow-anchor: none; }
.ns-list { min-height: 160px; }
.ride-current-step { position: absolute; right: 16px; bottom: calc(64px + var(--safe-bot)); z-index: 4; border-radius: 999px; padding: 10px 14px; background: var(--accent); color: white; box-shadow: var(--shadow-up); font-weight: 700; }
.ride-current-step[hidden] { display: none; }
.ride-sheet:not(.open) .ride-more { display: none; }
.ride-more { padding-top: 4px; border-top: 1px solid var(--line); margin-top: 4px; }
.ride-more > :first-child { margin-top: 12px; }
/* the card: the one instruction, big enough to read at arm's length in the sun, and a line (two at most) of detail */
.ride-now .phase { font-size: var(--fs-sub); }
.ride-now .big { font-size: clamp(30px, 9.4vw, 38px); line-height: 1.05; }
.ride-sheet:not(.open) .ride-now .sub { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; margin-bottom: 12px; }
.ride-now .sub .badge { height: 24px; min-width: 36px; font-size: var(--fs-foot); vertical-align: 1px; }
.big-badge { display: inline-block; vertical-align: .12em; margin-right: 2px; }
.big-badge .badge { height: 32px; min-width: 46px; font-size: var(--fs-row); border-radius: 9px; }
.ride-now .walkcard.walk-now { margin: 0 0 10px; padding: 0; background: none; }
.ride-now .walk-now .spare { margin-top: 0; }
.ride-sheet:not(.open) .walk-now .guide { padding: 10px 12px; margin-bottom: 8px; }
.ride-sheet:not(.open) .walk-now .guide-arrow { width: 44px; height: 44px; }
.ride-now .chase-go { margin: 2px 0 4px; min-height: 46px; }
.ride-sheet:not(.open) .walk-now .guide-then, .ride-sheet:not(.open) .walk-now .guide-foot { display: none; }
.ride-now .progress { margin: 4px 0 14px; }
/* "I'm on the bus" and "I'm here" stay put while the rest scrolls: on a moving bus you shouldn't have to
   hunt for the one button that matters. */
.ride-panel .actions { position: sticky; bottom: 0; background: var(--surface); padding: 10px 0 calc(12px + var(--safe-bot)); margin-top: 4px; z-index: 2; }
/* the room under the card is the buttons' own (so they sit on the bottom edge: the safe area is counted once, and nothing scrolls past underneath them); a screen that doesn't end in buttons keeps the panel's */
.ride-panel > :last-child:not(.actions) { margin-bottom: calc(18px + var(--safe-bot)); }
.ride-panel .actions::before { content: ""; position: absolute; left: 0; right: 0; top: -18px; height: 18px; background: linear-gradient(to top, var(--surface), transparent); pointer-events: none; }
.also button { min-height: 44px; }
.phase { font-size: var(--fs-foot); font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: var(--accent); }
.progress { height: 6px; border-radius: 3px; background: var(--surface-2); overflow: hidden; margin: 14px 0; }
.progress i { display: block; height: 100%; background: var(--accent); border-radius: 3px; transition: width .6s; }
.upcoming { list-style: none; margin: 0 0 14px; padding: 0; }
.upcoming li { display: flex; justify-content: space-between; gap: 10px; padding: 9px 0; border-top: 1px solid var(--line); font-size: var(--fs-sub); }
.upcoming li.target { font-weight: 700; color: var(--accent); }

/* Chasing it: one screen you can read mid-sprint — the bus's countdown against yours, and buttons big enough
   to hit without looking. */
.chase-go { background: var(--accent-soft); color: var(--accent); font-weight: 800; margin-bottom: 10px; }
.chase-v.v-make { color: var(--ok); } .chase-v.v-tight { color: var(--warn); } .chase-v.v-behind { color: var(--bad); }
.race { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin: 14px 0; }
.race-col { padding: 12px 14px; border-radius: 16px; background: var(--surface-2); }
.race-col.you { background: var(--accent-soft); }
.race-col small { display: block; font-size: var(--fs-label); font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; }
.race-col.you small { color: var(--accent); }
.race-col b { display: block; margin: 2px 0; font-size: var(--fs-title); font-weight: 800; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.race-col span { display: block; font-size: var(--fs-foot); color: var(--muted); font-variant-numeric: tabular-nums; }
.chase-acts .btn { min-height: 62px; font-size: var(--fs-row); }
.how { display: flex; gap: 8px; margin: 12px 0 2px; }
.how-b { display: inline-flex; align-items: center; gap: 6px; padding: 8px 14px; min-height: 40px; border-radius: 99px; background: var(--surface-2); color: var(--muted); font-weight: 700; font-size: var(--fs-sub); border: 0; }
.how-b.on { background: var(--accent-soft); color: var(--accent); }
.how-note { margin: 8px 2px 0; }
.chase-lag { display: flex; gap: 6px; align-items: flex-start; margin: 10px 2px 0; line-height: 1.35; }
.chase-lag .i { flex: none; margin-top: 1px; }
.link.block { display: block; width: 100%; margin-top: 10px; text-align: center; background: none; border: 0; }

/* centred by margins, not by left:50% — that capped its shrink-to-fit width at half the screen, so every
   message wrapped into a narrow tooltip no matter how short it was */
#toast { position: fixed; left: 0; right: 0; width: fit-content; margin-inline: auto; bottom: calc(var(--nav-h) + var(--safe-bot) + 14px); transform: translateY(10px); background: var(--text); color: var(--bg); padding: 12px 18px; border-radius: 14px; font-weight: 600; font-size: var(--fs-sub); z-index: 100; opacity: 0; transition: opacity .2s, transform .2s; max-width: calc(100% - 32px); text-align: center; }
#toast.show { opacity: 1; transform: translateY(0); }
.suggest { position: absolute; left: 0; right: 0; top: calc(100% + 6px); z-index: 30; background: var(--surface); border-radius: 14px; box-shadow: 0 12px 32px rgba(0, 0, 0, .18); overflow: hidden; }
/* Material spinner: the arc's head races ahead while its tail catches up, as the whole thing rotates. */
.spinner { width: 22px; height: 22px; flex: none; animation: spin-rotate 1.4s linear infinite; }
.spinner circle { fill: none; stroke: var(--accent); stroke-width: 5; stroke-linecap: round; stroke-dasharray: 1, 200; stroke-dashoffset: 0; animation: spin-dash 1.4s ease-in-out infinite, spin-color 5.6s ease-in-out infinite; }
.spinner.light circle { stroke: currentColor; animation: spin-dash 1.4s ease-in-out infinite; }
.spinner.big { width: 44px; height: 44px; }
.button-busy { display: inline-flex; align-items: center; justify-content: center; gap: 8px; cursor: progress; }
.button-busy-arc { display: inline-flex; flex: none; align-items: center; }
.button-busy-arc .spinner { width: 19px; height: 19px; }
.button-busy > .i { display: none; }
.save-row .saved { animation: appear var(--motion-duration) var(--motion-easing) both; }
.panel-busy { min-height: 72px; display: flex; align-items: center; justify-content: center; gap: 10px; color: var(--muted); font-size: var(--fs-sub); font-weight: 600; }
.panel-busy .spinner { width: 25px; height: 25px; }
.inline-busy { display: inline-flex; align-items: center; gap: 8px; }
.inline-busy .spinner { width: 18px; height: 18px; }
@media (prefers-reduced-motion: reduce) { .button-busy .spinner circle, .panel-busy .spinner circle, .inline-busy .spinner circle, .trip-wait .spinner circle { stroke-dasharray: 89, 200; stroke-dashoffset: -35; } }
@keyframes spin-rotate { to { transform: rotate(360deg); } }
@keyframes spin-dash { 0% { stroke-dasharray: 1, 200; stroke-dashoffset: 0; } 50% { stroke-dasharray: 89, 200; stroke-dashoffset: -35; } 100% { stroke-dasharray: 89, 200; stroke-dashoffset: -124; } }
@keyframes spin-color { 0%, 100% { stroke: var(--accent); } 25% { stroke: #F0513E; } 50% { stroke: #FFB21E; } 75% { stroke: #B8264A; } }
@keyframes spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
  /* lines that draw themselves start hidden (dashoffset at full length): show them drawn */
  .mv-line.draw, .mv-line-halo.draw, .account-card .synced .i, .ob-art-route, .ob-tick circle, .ob-tick path, .up-tick { stroke-dashoffset: 0 !important; }
}

/* ================= motion =================
   Purposeful only: things move when they change, never on a timer, and all of it is switched off by the
   phone's "reduce motion" setting (see the prefers-reduced-motion rule above). */
:root { --spring: cubic-bezier(.2, .9, .25, 1.05); --ease: cubic-bezier(.2, .8, .2, 1); --motion-duration: 320ms; --motion-fast: 180ms; --motion-easing: var(--ease); }
.screen.enter { animation: screenIn var(--motion-duration) var(--motion-easing); }
@keyframes screenIn { from { opacity: 0; transform: translateY(10px); } }
.nav { position: fixed; }
.nav .ind { position: absolute; top: 6px; left: 0; width: calc(100% / 4); height: 52px; display: grid; place-items: center; pointer-events: none; transition: transform .32s var(--spring); }
.nav .ind::before { content: ""; width: min(76px, calc(100% - 8px)); height: 52px; border-radius: 18px; background: var(--accent-soft); }
.nav button { position: relative; z-index: 1; }
.nav button .i { transition: transform .2s var(--spring); }
.nav button[aria-current="page"] .i { transform: translateY(-1px) scale(1.06); }
.appear { animation: appear var(--motion-duration) var(--motion-easing) both; }
@keyframes appear { from { opacity: 0; transform: translateY(12px) scale(.985); } }
.stagger > * { animation: appear var(--motion-duration) var(--motion-easing) both; }
.plan-sheet .stagger > *, .ride-panel .appear, .plan-sheet .appear { animation-duration: 220ms; }
.stagger > *:nth-child(2) { animation-delay: 35ms; } .stagger > *:nth-child(3) { animation-delay: 70ms; } .stagger > *:nth-child(4) { animation-delay: 105ms; }
.stagger > *:nth-child(5) { animation-delay: 140ms; } .stagger > *:nth-child(6) { animation-delay: 175ms; } .stagger > *:nth-child(n+7) { animation-delay: 200ms; }
.roll { display: inline-block; animation: roll .42s var(--spring); }
@keyframes roll { from { transform: translateY(55%); opacity: 0; } }
@keyframes pulse { 50% { opacity: .3; transform: scale(.8); } }
.skel { display: block; border-radius: 10px; background: linear-gradient(90deg, var(--surface-2) 25%, var(--bg) 50%, var(--surface-2) 75%); background-size: 200% 100%; animation: shimmer 1.3s linear infinite; }
@keyframes shimmer { to { background-position: -200% 0; } }
.overlay.closing { animation: down var(--motion-duration) var(--motion-easing) forwards; pointer-events: none; }
@keyframes down { to { transform: translateY(30px); opacity: 0; } }
.ring .i { animation: ring .7s ease-in-out; transform-origin: 50% 10%; }
@keyframes ring { 15% { transform: rotate(18deg); } 35% { transform: rotate(-14deg); } 55% { transform: rotate(9deg); } 75% { transform: rotate(-5deg); } }
.pop { animation: pop .34s var(--spring); }
@keyframes pop { from { transform: scale(.92); opacity: .6; } }
.chip, .item, .dep, .opt, .fab, .iconbtn, .seg button { transition: transform .12s, background-color .15s; }
.chip:active, .fab:active, .iconbtn:active { transform: scale(.94); }
.item:active, .dep:active, .opt:active { transform: scale(.99); }
.sheet { transition: height var(--motion-duration) var(--motion-easing); }
/* (UI phase 2) the infinite get-off pulse is retired: ui2.css gives the get-off moment one 600 ms pulse, then still */
.suggest, .uni-results { animation: appear .18s var(--ease); }
#toast { transition: opacity .2s, transform .28s var(--spring); }
/* exit: motion.js leave() adds this, then removes or hides the element when it ends */
.leaving { animation: leave .2s ease-in forwards !important; pointer-events: none; }
@keyframes leave { to { opacity: 0; transform: translateY(6px) scale(.98); } }

/* ---------- accounts ---------- */
.avatar { display: inline-grid; place-items: center; border-radius: 50%; background: var(--accent); color: var(--on-accent); font-weight: 800; object-fit: cover; flex: none; }
.account-card, .account-cta { display: flex; align-items: center; gap: 14px; width: 100%; text-align: left; margin-bottom: 4px; }
.account-card .grow, .account-cta .grow { flex: 1; min-width: 0; }
.account-card b, .account-cta b { display: block; font-size: var(--fs-row); }
.account-card small, .account-cta small { display: block; color: var(--muted); font-size: var(--fs-sub); }
.account-card .synced { display: flex; align-items: center; gap: 4px; color: var(--accent); font-weight: 600; font-size: var(--fs-foot); margin-top: 2px; }
.account-cta { border: 1.5px solid var(--accent-soft); }
.avatar-edit { position: relative; display: inline-block; cursor: pointer; line-height: 0; }
/* the little + badge only — not the initials circle, which is also a span when there's no photo yet */
.avatar-edit > span:not(.avatar) { position: absolute; right: 0; bottom: 0; width: 30px; height: 30px; border-radius: 50%; background: var(--surface); box-shadow: var(--shadow); display: grid; place-items: center; }
.err { color: var(--bad); font-weight: 600; font-size: var(--fs-sub); margin: 6px 4px 0; }
.greet { font-size: var(--fs-title); font-weight: 800; letter-spacing: -.02em; margin: -4px 0 14px; }
.stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.stats .card { padding: 14px 12px; }
.stats b { display: block; font-size: var(--fs-title3); font-weight: 800; letter-spacing: -.02em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.stats small { color: var(--muted); font-size: var(--fs-foot); }
#h-me { border-radius: 50%; }


/* ================= lots more motion ================= */
/* launch */
#splash { position: fixed; inset: 0; z-index: 200; background: var(--bg); display: grid; place-content: center; justify-items: center; gap: 14px; transition: opacity .45s var(--ease), transform .45s var(--ease); }
#splash.out { opacity: 0; transform: scale(1.06); pointer-events: none; }
#splash svg { width: 96px; height: 96px; animation: pop .6s var(--spring) both; }
#splash .sp-word { font-weight: 800; font-size: var(--fs-title); letter-spacing: -.03em; animation: appear .5s .45s var(--ease) both; }
#splash .spinner { margin-top: 10px; animation: spin-rotate 1.4s linear infinite, appear .4s .7s both; }
@keyframes draw { to { stroke-dashoffset: 0; } }
@keyframes dotpop { to { transform: scale(1); } }
.nav { animation: navIn .5s .25s var(--spring) both; }
@keyframes navIn { from { transform: translateY(100%); } }

/* ripples */
.ripple-box { position: absolute; inset: 0; overflow: hidden; border-radius: inherit; pointer-events: none; }
.ripple { position: absolute; border-radius: 50%; background: currentColor; opacity: .14; transform: scale(0); pointer-events: none; animation: ripple .6s var(--ease) forwards; }
@keyframes ripple { to { transform: scale(1); opacity: 0; } }

/* tabs */
.nav button.bounce .i { animation: tabBounce .5s var(--spring); }
@keyframes tabBounce { 30% { transform: translateY(-5px) scale(1.18); } 60% { transform: translateY(1px) scale(.96); } }

/* home */
.greet { animation: greetIn .6s var(--spring) both; will-change: transform, opacity; }
@keyframes greetIn { from { opacity: 0; transform: translateX(-16px); } }
.greet .wave { display: inline-block; transform-origin: 70% 70%; animation: wave 1.6s .5s ease-in-out 2; }
@keyframes wave { 10%, 30% { transform: rotate(16deg); } 20%, 40% { transform: rotate(-8deg); } 50% { transform: rotate(0); } }
.searchbar { transition: transform .2s var(--spring), box-shadow .2s; }
.searchbar:active { transform: scale(.98); }
.chips > * { animation: appear .35s var(--spring) both; }
.chips > *:nth-child(2) { animation-delay: .05s; } .chips > *:nth-child(3) { animation-delay: .1s; } .chips > *:nth-child(4) { animation-delay: .15s; } .chips > *:nth-child(n+5) { animation-delay: .2s; }
.trip-card.appear .trip-head { animation: appear .4s .05s var(--ease) both; }
.trip-card.appear .big { animation: bigIn .55s .1s var(--spring) both; }
@keyframes bigIn { from { opacity: 0; transform: translateY(14px) scale(.96); } }
.trip-card.appear .sub, .trip-card.appear .note { animation: appear .4s .18s var(--ease) both; }
.trip-card.appear .badge { animation: pop .45s .25s var(--spring) both; }
.trip-card.appear .steps li { animation: stepIn .45s var(--ease) both; }
.trip-card.appear .steps li:nth-child(1) { animation-delay: .22s; } .trip-card.appear .steps li:nth-child(2) { animation-delay: .3s; } .trip-card.appear .steps li:nth-child(3) { animation-delay: .38s; }
.trip-card.appear .steps li:nth-child(4) { animation-delay: .46s; } .trip-card.appear .steps li:nth-child(5) { animation-delay: .54s; } .trip-card.appear .steps li:nth-child(n+6) { animation-delay: .62s; }
@keyframes stepIn { from { opacity: 0; transform: translateX(-10px); } }
.trip-card.appear .steps li::before { animation: dotpop2 .4s var(--spring) both; animation-delay: inherit; }
@keyframes dotpop2 { from { transform: scale(0); } }
.trip-card.appear .steps li::after { transform-origin: top; animation: lineDown .4s var(--ease) both; animation-delay: inherit; }
@keyframes lineDown { from { transform: scaleY(0); } }
.trip-card.appear .actions .btn { animation: appear .4s .6s var(--spring) both; }
.trip-card.appear .actions .btn + .btn { animation-delay: .66s; }
.trip-card.appear .also button { animation: pop .35s .72s var(--spring) both; }
.bigrow { display: flex; align-items: center; gap: 14px; }
.bigrow .big { flex: 1; }
.cd-ring { width: 52px; height: 52px; flex: none; transform: rotate(-90deg); margin-top: 8px; }
.cd-ring circle { fill: none; stroke-width: 5; }
.cd-ring .bg { stroke: var(--surface-2); }
.cd-ring .fg { stroke: var(--accent); stroke-linecap: round; transition: stroke-dashoffset .9s var(--ease); }
.trip-card.appear .cd-ring .fg { animation: ringIn 1s .2s var(--ease) both; }
@keyframes ringIn { from { stroke-dashoffset: 132; } }
.cd-ring.urgent { animation: urgent 1s ease-in-out 3; } .cd-ring.urgent.calm { animation: none; }
@keyframes urgent { 50% { transform: rotate(-90deg) scale(1.1); } }
.btn.primary { position: relative; }
@keyframes sheen { 0% { background-position: 150% 0; } 40%, 100% { background-position: -100% 0; } }
.fresh .list > *, .fresh .section h2, .fresh .card { animation: appear .38s var(--ease) both; }
.fresh .list > :nth-child(2) { animation-delay: .04s; } .fresh .list > :nth-child(3) { animation-delay: .08s; } .fresh .list > :nth-child(4) { animation-delay: .12s; } .fresh .list > :nth-child(5) { animation-delay: .16s; } .fresh .list > :nth-child(n+6) { animation-delay: .2s; }

/* pull to refresh */
.ptr { height: 0; opacity: 0; display: grid; place-items: center; overflow: hidden; transition: height .25s var(--ease), opacity .2s; }
.ptr .spinner { width: 30px; height: 30px; animation: none; }
.ptr .spinner circle { animation: none; stroke-dasharray: 80, 200; }
.ptr.go .spinner { animation: spin-rotate 1.4s linear infinite; }
.ptr.go .spinner circle { animation: spin-dash 1.4s ease-in-out infinite, spin-color 5.6s ease-in-out infinite; }

/* map */
.mv-marker { animation: markerIn .45s var(--spring) both; }
@keyframes markerIn { from { scale: .2; opacity: 0; } }
.mv-marker.sel::before { content: ""; position: absolute; inset: -4px; border-radius: 14px; border: 3px solid var(--c, var(--accent)); animation: selPulse 1.6s ease-out infinite; pointer-events: none; }
@keyframes selPulse { from { opacity: .8; transform: scale(.9); } to { opacity: 0; transform: scale(1.6); } }
.mv-stop { animation: markerIn .35s var(--spring) both; }
.mv-user::after { content: ""; position: absolute; inset: -3px; border-radius: 50%; background: rgba(26, 115, 232, .35); animation: userPulse 2s ease-out infinite; }
@keyframes userPulse { from { transform: scale(1); opacity: .8; } to { transform: scale(3.2); opacity: 0; } }
.mv-line.draw, .mv-line-halo.draw { stroke-dasharray: 1; stroke-dashoffset: 1; animation: draw .9s var(--ease) forwards; }
.mv-line.walk { stroke: #1A73E8; stroke-dasharray: .012 .02; }
.zoom button:active .i, .fab:active .i { transform: scale(.85); transition: transform .1s; }

/* sheets & overlays */
.overlay { animation: sheetUp var(--motion-duration) var(--motion-easing); }
@keyframes sheetUp { from { transform: translateY(40px); opacity: 0; } }
.overlay.fresh .overlay-body > * { animation: appear .35s var(--ease) both; }
.overlay.fresh .overlay-body > :nth-child(2) { animation-delay: .04s; } .overlay.fresh .overlay-body > :nth-child(3) { animation-delay: .08s; } .overlay.fresh .overlay-body > :nth-child(4) { animation-delay: .12s; } .overlay.fresh .overlay-body > :nth-child(n+5) { animation-delay: .16s; }
.search-input { animation: grow .4s var(--spring) both; transform-origin: left; }
@keyframes grow { from { transform: scaleX(.9); opacity: 0; } }
.appear .sheet-head .badge, .appear .sheet-head .ico { animation: pop .45s .05s var(--spring) both; }

/* ride */
.progress i { position: relative; overflow: hidden; }
.progress i::after { content: ""; position: absolute; inset: 0; background: repeating-linear-gradient(-45deg, rgba(255, 255, 255, .25) 0 8px, transparent 8px 16px); background-size: 22px 22px; animation: stripes .8s linear infinite; }
@keyframes stripes { to { background-position: 22px 0; } }
.mv-marker.sel .i { animation: bob 1.2s ease-in-out infinite; }
@keyframes bob { 50% { transform: translateY(-2px); } }
.upcoming li.target { animation: targetGlow 1.8s ease-in-out infinite; }
@keyframes targetGlow { 50% { color: var(--text); } }

/* account & me */
.fresh .avatar, .pop-in .avatar { animation: pop .5s var(--spring) both; }   /* only on a first look: Me and Home redraw often */
.account-card .synced .i { stroke-dasharray: 30; stroke-dashoffset: 30; animation: draw2 .6s .3s var(--ease) forwards; }
@keyframes draw2 { to { stroke-dashoffset: 0; } }
.fresh .stats .card, .pop-in .stats .card { animation: pop .5s var(--spring) both; }
.fresh .stats .card:nth-child(2), .pop-in .stats .card:nth-child(2) { animation-delay: .08s; } .fresh .stats .card:nth-child(3), .pop-in .stats .card:nth-child(3) { animation-delay: .16s; }
.toggle::after { transition: transform .3s var(--spring); }
.toggle[aria-checked="true"]::after { animation: knob .3s var(--spring); }
@keyframes knob { 50% { width: 30px; } }
.seg button { transition: background-color .2s, color .2s, transform .2s var(--spring); }
.err.pop { animation: shake .4s ease-in-out; }
@keyframes shake { 20%, 60% { transform: translateX(-6px); } 40%, 80% { transform: translateX(6px); } }

/* toast */
#toast.show { animation: toastIn .45s var(--spring); }
@keyframes toastIn { from { transform: translateY(30px) scale(.9); } }
.confetti { position: fixed; inset: 0; z-index: 300; pointer-events: none; width: 100vw; height: 100vh; }

/* theme switch: circular reveal (View Transitions) */
::view-transition-old(root), ::view-transition-new(root) { animation: none; mix-blend-mode: normal; }

/* ================= onboarding ================= */
.ob-progress { flex: 1; height: 6px; border-radius: 3px; background: var(--surface-2); overflow: hidden; margin: 0 6px; }
.ob-progress i { display: block; height: 100%; width: 0; border-radius: 3px; background: var(--accent); transition: width .5s var(--spring); }
.ob-body { overflow-x: hidden; }
.ob-stage { position: relative; min-height: 100%; }
.ob-pane { padding: 8px 4px 24px; }
.ob-pane.in-right { animation: obInR .42s var(--spring) both; } .ob-pane.in-left { animation: obInL .42s var(--spring) both; }
.ob-pane.out-left { position: absolute; inset: 0; animation: obOutL .3s var(--ease) forwards; } .ob-pane.out-right { position: absolute; inset: 0; animation: obOutR .3s var(--ease) forwards; }
@keyframes obInR { from { opacity: 0; transform: translateX(60px); } } @keyframes obInL { from { opacity: 0; transform: translateX(-60px); } }
@keyframes obOutL { to { opacity: 0; transform: translateX(-60px); } } @keyframes obOutR { to { opacity: 0; transform: translateX(60px); } }
.ob-title { font-size: var(--fs-title); line-height: 1.12; letter-spacing: -.03em; margin: 8px 0 8px; }
.ob-lead { color: var(--muted); font-size: var(--fs-row); margin: 0 0 22px; }
.ob-field { margin-bottom: 10px; }
.ob-field input { font-size: var(--fs-title3); }
.ob-field input.bad { color: var(--bad); }
.ob-emoji { width: 64px; height: 64px; border-radius: 20px; background: var(--accent-soft); color: var(--accent); display: grid; place-items: center; animation: pop .6s var(--spring) both, float 3s 1s ease-in-out infinite; }
.ob-emoji .i { width: 30px; height: 30px; }
@keyframes float { 50% { transform: translateY(-5px) rotate(-3deg); } }
.ob-preview { font-size: var(--fs-title3); font-weight: 800; letter-spacing: -.02em; min-height: 30px; margin: 12px 4px 18px; color: var(--accent); }
.ob-check { display: flex; align-items: center; gap: 6px; color: var(--accent); font-weight: 700; margin: 4px 4px 14px; animation: pop .35s var(--spring); }
.ob-meter { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; margin: 4px 2px 6px; }
.ob-meter i { height: 6px; border-radius: 3px; background: var(--surface-2); transition: background .3s, transform .3s var(--spring); }
.ob-meter i.s0, .ob-meter i.s1 { background: var(--bad); transform: scaleY(1.3); } .ob-meter i.s2 { background: #E8A200; transform: scaleY(1.3); } .ob-meter i.s3, .ob-meter i.s4 { background: var(--accent); transform: scaleY(1.3); }
.ob-meter-label { font-size: var(--fs-sub); font-weight: 600; color: var(--muted); margin: 0 4px 16px; min-height: 18px; }
.ob-hero { display: grid; place-items: center; margin: 4px 0 6px; }
.ob-art { width: 100%; max-width: 300px; }
.ob-art-route { stroke-dasharray: 1; stroke-dashoffset: 1; animation: draw 1.1s .2s var(--ease) forwards; }
.ob-art-bus { offset-path: path('M20 95 C70 95 60 50 110 50 S150 20 200 22'); offset-rotate: auto; animation: busRide 3.2s 1s ease-in-out infinite alternate; }
@keyframes busRide { from { offset-distance: 0%; } to { offset-distance: 100%; } }
.ob-perks { list-style: none; margin: 8px 0 24px; padding: 0; }
.ob-perks li { display: flex; gap: 14px; align-items: flex-start; padding: 12px 0; animation: appear .45s var(--ease) both; }
.ob-perks li:nth-child(1) { animation-delay: .3s; } .ob-perks li:nth-child(2) { animation-delay: .42s; } .ob-perks li:nth-child(3) { animation-delay: .54s; }
.ob-perks b { display: block; font-size: var(--fs-body); } .ob-perks span span, .ob-perks li > span:last-child { color: var(--muted); font-size: var(--fs-sub); }
.ob-perks li > span:last-child b { color: var(--text); }
.ob-creating { display: grid; justify-items: center; gap: 10px; padding-top: 18vh; }
.ob-done { display: grid; justify-items: center; padding-top: 12vh; }
.ob-done .btn { margin-top: 12px; }
.ob-tick svg { width: 96px; height: 96px; }
.ob-tick circle { fill: var(--accent-soft); stroke: var(--accent); stroke-width: 3; stroke-dasharray: 151; stroke-dashoffset: 151; animation: tickCircle .6s var(--ease) forwards; }
.ob-tick path { fill: none; stroke: var(--accent); stroke-width: 5; stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 40; stroke-dashoffset: 40; animation: tickCircle .4s .5s var(--spring) forwards; }
.ob-tick { animation: pop .6s var(--spring) both; }
@keyframes tickCircle { to { stroke-dashoffset: 0; } }

/* audit: minimum 40px touch targets */
.also button { min-height: 40px; padding: 0 12px; }
.toggle::before { content: ""; position: absolute; inset: -8px -4px; }
.actions .btn { min-height: 48px; }

/* audit fixes */
.big { font-size: clamp(27px, 8.6vw, 34px); }
/* centred with margins (not a transform, which the appear animation would override) and allowed to wrap on narrow screens */
#offline { position: fixed; z-index: 30; top: calc(var(--safe-top) + 8px); left: 12px; right: 12px; margin: 0 auto; width: fit-content; max-width: calc(100% - 24px); text-align: center; padding: 8px 14px; border-radius: 16px; background: var(--warn-soft); color: var(--warn); font-weight: 700; font-size: var(--fs-foot); box-shadow: var(--shadow); animation: appear .3s var(--spring); }
/* on the Map, sit under the search bar instead of on top of it */
body[data-tab="map"] #offline { top: calc(var(--safe-top) + 72px); }
/* Home and Me make room for it: it sat on top of "Good morning" and the page title */
.screen:not(.full) { transition: padding-top .25s var(--ease); }
body:has(> #offline:not([hidden]):not(.leaving)) .screen:not(.full) { padding-top: calc(var(--safe-top) + 56px); }

/* ================= logo ================= */
.logo svg, .logo .logo-mark { width: 30px; height: 30px; }
.lg-glow { opacity: 0; }
/* launch: the stop's pole rises, the sign pops up with the sun, then the "go" arrow slides in and the sun glows */
#splash .sp-logo { width: 112px; height: 112px; animation: pop .6s var(--spring) both; filter: drop-shadow(0 12px 24px rgba(184, 38, 74, .35)); }
#splash .lg-pole, .active .in-logo .lg-pole { transform-box: fill-box; transform-origin: 50% 100%; animation: poleUp .35s .05s var(--spring) both; }
@keyframes poleUp { from { transform: scaleY(0); } }
#splash .lg-sign, .active .in-logo .lg-sign { transform-box: fill-box; transform-origin: center; animation: dotpop2 .45s .25s var(--spring) both; }
#splash .lg-arrow, .active .in-logo .lg-arrow { animation: arrowIn .35s .55s var(--spring) both; }
@keyframes arrowIn { from { transform: translateX(-7px); opacity: 0; } }
#splash .lg-glow, .active .in-logo .lg-glow { transform-box: fill-box; transform-origin: center; animation: glow 1.8s 1.2s ease-out infinite; }
@keyframes glow { 0% { opacity: .7; transform: scale(1); } 100% { opacity: 0; transform: scale(1.8); } }
#splash .spinner { width: 26px; height: 26px; }
#splash .sp-word { animation-delay: .4s; }

/* ================= first-time intro ================= */
/* Four scenes, one idea each: big type, and art that shows the real thing. Every animation plays once and ends in
   the frame the reduced-motion version shows from the start. */
.intro-overlay { background: var(--bg); }
.intro { position: relative; display: flex; flex-direction: column; height: 100%; padding: calc(var(--safe-top) + 8px) 0 calc(var(--safe-bot) + 16px); overflow: hidden; }
/* one warm glow behind the art; it stays put */
.intro::before { content: ""; position: absolute; left: 50%; top: 4%; width: 560px; height: 560px; margin-left: -280px; border-radius: 50%; background: radial-gradient(closest-side, var(--accent-soft), transparent); pointer-events: none; }
.in-top { display: flex; align-items: center; gap: 18px; padding: 0 20px; min-height: 44px; position: relative; z-index: 2; }
/* progress: one segment per scene, filled up to the one on screen */
.in-dots { flex: 1; display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: 6px; }
.in-dots i { display: grid; align-items: center; height: 44px; cursor: pointer; }   /* the bars stay 4 px; the row they're in is 44 px anyway, so each is a 44 px target */
.in-dots i::before, .in-dots i::after { content: ""; grid-area: 1 / 1; height: 4px; border-radius: 2px; }
.in-dots i::before { background: rgba(128, 128, 128, .25); }
.in-dots i::after { background: var(--accent); transform: scaleX(0); transform-origin: left; transition: transform .45s var(--ease); }
.in-dots i.on::after, .in-dots i.done::after { transform: none; }
.in-skip { font-weight: 700; color: var(--muted); padding: 10px 4px; min-height: 44px; }
.in-track { flex: 1; min-height: 0; display: flex; touch-action: pan-y; position: relative; z-index: 1; }
.in-slide { flex: 0 0 100%; min-height: 0; display: flex; flex-direction: column; padding: 0 24px; user-select: none; }
.in-art { flex: 1; min-height: 0; display: grid; place-items: center; position: relative; }
.in-copy { padding: 12px 2px 22px; }
.in-title { margin: 0 0 12px; font-size: clamp(34px, 10.5vw, 46px); line-height: 1; letter-spacing: -.045em; font-weight: 800; text-wrap: balance; }
.in-title em { font-style: normal; color: var(--accent); }
.in-title .stop { margin-left: -.06em; }     /* Jakarta's heavy full stop sits a gap away from the letter before it */
.in-copy p { margin: 0; max-width: 34ch; font-size: var(--fs-row); line-height: 1.45; color: var(--muted); text-wrap: pretty; }
.in-slide.active .in-title { animation: inUp .6s .08s var(--spring) both; }
.in-slide.active .in-copy p { animation: inUp .6s .16s var(--ease) both; }
@keyframes inUp { from { opacity: 0; transform: translateY(14px); } }
.in-bottom { padding: 0 20px; display: grid; gap: 8px; position: relative; z-index: 2; }
.in-bottom .btn.primary { min-height: 56px; font-size: var(--fs-row); border-radius: 16px; }
.in-signin { background: none; }
/* a column of values behind a one-line window: the minutes (and the clock) count down in place */
.in-tick { display: inline-block; height: 1.2em; overflow: hidden; vertical-align: top; }
.in-tick > span { display: block; transform: translateY(-75%); }
.in-tick > span > span { display: block; height: 1.2em; line-height: 1.2em; white-space: nowrap; }
.active .in-tick > span { animation: inTick 3.6s steps(3, end) 1s both; }
@keyframes inTick { from { transform: none; } to { transform: translateY(-75%); } }

/* 1 — the promise: your lock screen, counting you down */
.in-lock { position: relative; width: min(300px, 78vw); padding: 30px 14px 16px; border-radius: 36px; text-align: center; color: #F4EFEC; overflow: hidden;
  background: radial-gradient(90% 60% at 85% 0%, rgba(255, 145, 82, .55), transparent 62%), radial-gradient(80% 60% at 0% 100%, rgba(184, 38, 74, .45), transparent 62%), linear-gradient(170deg, #2C1611, #131110 75%);
  box-shadow: 0 30px 70px rgba(19, 17, 16, .32), inset 0 0 0 1px rgba(255, 255, 255, .08); }
.in-lock-date { font-size: var(--fs-sub); font-weight: 600; opacity: .8; }
.in-lock-time { font-size: 78px; font-weight: 300; letter-spacing: -.035em; line-height: 1.2; font-variant-numeric: tabular-nums; }
.in-notif { margin-top: 26px; padding: 12px 14px 13px; border-radius: 20px; text-align: left; background: rgba(255, 255, 255, .14); -webkit-backdrop-filter: blur(20px); backdrop-filter: blur(20px); box-shadow: 0 10px 30px rgba(0, 0, 0, .25); }
.in-notif-top { display: flex; align-items: center; gap: 7px; font-size: var(--fs-label); }
.in-notif-top span:last-child { margin-left: auto; opacity: .7; }
.in-notif-ico, .in-notif-ico .logo-mark { display: block; width: 20px; height: 20px; }
.in-notif-t { margin-top: 6px; font-size: var(--fs-row); font-weight: 800; letter-spacing: -.01em; line-height: 1.2; }
.in-notif-t .in-tick { color: #FF8A63; }
.in-notif-b { margin-top: 3px; font-size: var(--fs-sub); line-height: 1.35; opacity: .85; }
.active .in-lock { animation: inLift .8s var(--spring) both; }
.active .in-notif { animation: inDrop .7s .5s var(--spring) both; }
@keyframes inLift { from { opacity: 0; transform: translateY(30px) scale(.94); } }
@keyframes inDrop { from { opacity: 0; transform: translateY(-26px) scale(.96); } }

/* 2 — worked out backwards: 8:30 arrives first, 7:42 lands last */
.in-ledger { width: min(330px, 86vw); padding: 4px 18px; border-radius: 24px; background: var(--surface); box-shadow: 0 24px 60px rgba(0, 0, 0, .14); }
.in-row { display: grid; grid-template-columns: 78px 1fr; gap: 12px; align-items: baseline; padding: 14px 0; border-top: 1px solid var(--line); }
.in-row:first-child { border-top: 0; }
.in-row time { font-size: var(--fs-title3); font-weight: 700; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.in-row span { font-size: var(--fs-detail); line-height: 1.35; color: var(--muted); }
.in-row b { display: block; font-size: var(--fs-body); color: var(--text); }
.in-row.lead time { font-size: var(--fs-title); font-weight: 800; letter-spacing: -.045em; color: var(--accent); }
.in-row.end time { color: var(--muted); font-weight: 600; }
.active .in-row { animation: inRow .55s var(--spring) both; animation-delay: calc(.2s + (var(--d) - 1) * .34s); }
.active .in-row.lead { animation-name: inLand; animation-duration: .75s; }
@keyframes inRow { from { opacity: 0; transform: translateY(16px); } }
@keyframes inLand { from { opacity: 0; transform: translateY(20px) scale(.92); } }

/* 3 — live map: the bus runs its route once, the stops count down, and the get-off alert arrives */
.in-map { position: relative; width: 300px; height: 200px; zoom: 1.12; border-radius: 22px; overflow: hidden; background: var(--surface); box-shadow: 0 24px 60px rgba(0, 0, 0, .14); }
.active .in-map { animation: cardIn .7s var(--spring) both; }
@keyframes cardIn { from { opacity: 0; transform: translateY(30px) scale(.94); } }
.in-map svg { width: 100%; height: 100%; }
.in-street { stroke: var(--surface-2); stroke-width: 14; fill: none; }
.in-route { fill: none; stroke: var(--accent); stroke-width: 7; stroke-linecap: round; stroke-dasharray: 1; stroke-dashoffset: 0; }
.active .in-route { animation: inDraw 1.1s .3s var(--ease) both; }
@keyframes inDraw { from { stroke-dashoffset: 1; } }
.in-stop { fill: var(--surface); stroke: var(--accent); stroke-width: 4; transform-box: fill-box; transform-origin: center; }
.active .in-stop { animation: dotpop2 .5s var(--spring) both; } .active .in-stop.s2 { animation-delay: .9s; }
.in-bus { position: absolute; left: 0; top: 0; display: flex; align-items: center; gap: 3px; height: 28px; padding: 0 8px 0 6px; border-radius: 9px; background: #E463A4; color: #1D1D1D; font-weight: 800; font-size: var(--fs-foot); border: 2px solid #fff; box-shadow: 0 3px 10px rgba(0, 0, 0, .25);
  offset-path: path('M30 170 C90 170 80 100 150 100 S220 40 280 35'); offset-rotate: 0deg; offset-distance: 88%; translate: -50% -50%; }
.in-bus .i { width: 15px; height: 15px; }
.active .in-bus { animation: busGo 3.6s 1s ease-in-out both; }
@keyframes busGo { from { offset-distance: 0%; } to { offset-distance: 88%; } }
.in-stops-left { position: absolute; left: 12px; top: 12px; padding: 7px 11px; border-radius: 99px; background: var(--surface); box-shadow: var(--shadow); font-size: var(--fs-foot); font-weight: 800; line-height: 1.2; }
.in-toast { position: absolute; left: 12px; right: 12px; bottom: 12px; display: flex; gap: 8px; align-items: center; padding: 10px 12px; border-radius: 12px; background: var(--text); color: var(--bg); font-weight: 700; font-size: var(--fs-sub); }
.active .in-toast { animation: inToast .5s 4.5s var(--spring) both; }
@keyframes inToast { from { opacity: 0; transform: translateY(14px); } }
.active .in-toast .i { animation: ring .7s 4.9s ease-in-out both; }

/* 4 — set it once: the week, the holidays, and someone following along */
.in-set { width: min(330px, 88vw); display: grid; gap: 14px; justify-items: center; }
.in-week { display: grid; grid-template-columns: repeat(7, 1fr); gap: 6px; width: 100%; }
.in-day { background: var(--surface); border-radius: 14px; padding: 11px 0; text-align: center; box-shadow: var(--shadow); }
.in-day small { display: block; font-size: var(--fs-cap); font-weight: 700; color: var(--muted); }
.in-day b { display: block; font-size: var(--fs-label); margin-top: 4px; font-variant-numeric: tabular-nums; }
.in-day.on { background: var(--accent); } .in-day.on small, .in-day.on b { color: var(--on-accent); }
.in-day.off { opacity: .55; }
.active .in-day { animation: dayIn .5s var(--spring) both; animation-delay: calc(var(--i) * 80ms + .2s); }
@keyframes dayIn { from { opacity: 0; transform: translateY(18px) scale(.85); } }
.in-hol { display: flex; gap: 8px; align-items: center; padding: 10px 14px; border-radius: 99px; background: var(--surface); box-shadow: var(--shadow); font-weight: 700; font-size: var(--fs-sub); }
.in-follow { display: flex; gap: 12px; align-items: center; width: 100%; padding: 14px 16px; border-radius: 18px 18px 18px 6px; background: var(--surface); box-shadow: 0 20px 50px rgba(0, 0, 0, .12); font-size: var(--fs-detail); line-height: 1.35; color: var(--muted); }
.in-follow b { display: block; font-size: var(--fs-sub); color: var(--text); }
.in-follow-dot { flex: none; width: 10px; height: 10px; border-radius: 50%; background: var(--ok); box-shadow: 0 0 0 4px var(--ok-soft); }
.active .in-hol { animation: inUp .5s .9s var(--spring) both; }
.active .in-follow { animation: inUp .6s 1.25s var(--spring) both; }

/* short phones (iPhone SE, small Androids): the art steps down so the words and the button still fit */
@media (max-height: 720px) { .in-art { zoom: .8; } .in-title { font-size: var(--fs-title); } .in-copy { padding-bottom: 14px; } }

/* trip insights (reliability + weather) */
.insights { display: flex; flex-wrap: wrap; gap: 6px; margin: -6px 0 14px; }
.insight { display: inline-flex; align-items: center; gap: 6px; padding: 7px 11px; border-radius: 99px; font-size: var(--fs-foot); font-weight: 600; background: var(--surface-2); }
.trip-card.appear .insight { animation: pop .4s var(--spring) both; }
.insight.ok { background: var(--ok-soft); color: var(--ok); } .insight.warn { background: var(--warn-soft); color: var(--warn); }
.insight.wx { background: color-mix(in srgb, #1A73E8 12%, transparent); color: #1558B0; }
:root[data-theme="dark"] .insight.wx { color: #8AB4F8; }
.rescue { border: 2px solid var(--warn); }

.streak { display: flex; align-items: center; gap: 14px; margin-bottom: 8px; background: linear-gradient(120deg, #FFF3D6, var(--surface)); }
:root[data-theme="dark"] .streak { background: linear-gradient(120deg, #3A2A12, var(--surface)); }
.streak b { font-size: var(--fs-title); font-weight: 800; display: block; } .streak small { color: var(--muted); }
.flame { width: 48px; height: 48px; border-radius: 16px; display: grid; place-items: center; background: #FFB300; color: #fff; animation: flicker 1.8s ease-in-out infinite; }
.flame .i { width: 26px; height: 26px; }
@keyframes flicker { 50% { transform: scale(1.08) rotate(-4deg); } }

/* Ask GoSEQ */
.ask-card { border-radius: var(--r); padding: 16px; margin-bottom: 12px; background: linear-gradient(135deg, var(--accent-soft), var(--surface)); box-shadow: var(--shadow); animation: appear .35s var(--spring) both; }
.ask-head { display: flex; gap: 12px; align-items: center; margin-bottom: 12px; }
.ask-head b { display: block; font-size: var(--fs-row); } .ask-head small { color: var(--muted); font-size: var(--fs-sub); }
.ask-spark { width: 38px; height: 38px; border-radius: 12px; display: grid; place-items: center; flex: none; color: #fff; background: radial-gradient(circle at 50% 30%, rgba(255, 226, 122, .5), transparent 60%), linear-gradient(135deg, #FF9152, #F0513E 55%, #B8264A); }
.ask-spark .i { width: 24px; height: 24px; transform-origin: 30% 90%; animation: chat 3.2s 1s ease-in-out 2; }
@keyframes chat { 0%, 70%, 100% { transform: none; } 76% { transform: rotate(-7deg) scale(1.06); } 84% { transform: rotate(4deg); } 92% { transform: rotate(-2deg); } }
.ask-ex { display: flex; flex-wrap: wrap; gap: 8px; }
.ask-ex button { padding: 9px 12px; min-height: 40px; border-radius: 99px; background: var(--surface); box-shadow: var(--shadow); font-weight: 600; font-size: var(--fs-sub); }
.ask-row { background: linear-gradient(90deg, var(--accent-soft), transparent); }
.ask-row b { color: var(--accent); }
.searchbar .hint { color: var(--muted); font-size: var(--fs-sub); }
.note-warn { border-left: 4px solid var(--warn, #F59F00); animation: appear .3s var(--spring) both; }
.opt-note { display: flex; gap: 6px; align-items: center; margin-top: 6px; font-size: var(--fs-sub); font-weight: 600; color: var(--accent); }
.nearby-cta { display: flex; gap: 12px; align-items: center; width: 100%; text-align: left; margin-bottom: 12px; color: var(--text); }
.nearby-cta small { display: block; color: var(--muted); font-size: var(--fs-foot); }
.opt-from { display: flex; gap: 6px; align-items: center; margin-top: 6px; font-size: var(--fs-sub); color: var(--muted); }
.opt-from b { color: var(--text); font-weight: 600; }
/* a day of trips: places as dots on one line, each trip a card between them */
.day-card { padding: 14px 16px; margin-bottom: 4px; }
.day-card.still, .day-card.still .ask-spark .i { animation: none; }
.day { position: relative; margin: 12px 0 0; padding-left: 28px; }
.day::before { content: ""; position: absolute; left: 10px; top: 18px; bottom: 22px; width: 2px; border-radius: 2px; background: linear-gradient(var(--accent), color-mix(in srgb, var(--accent) 25%, transparent)); }
.day-stop { position: relative; display: flex; gap: 10px; padding: 8px 4px; }
.day-stop b { display: block; font-size: var(--fs-body); } .day-stop small { display: block; color: var(--muted); font-size: var(--fs-sub); margin-top: 2px; }
.day-dot { position: absolute; left: -24px; top: 12px; width: 14px; height: 14px; border-radius: 50%; background: var(--bg); border: 3px solid var(--accent); }
.day-stop.start .day-dot, .day-stop.end .day-dot { background: var(--accent); box-shadow: 0 0 0 4px var(--accent-soft); }
.day-leg { display: block; width: 100%; text-align: left; margin: 4px 0; padding: 14px 16px; border-radius: var(--r); background: var(--surface); box-shadow: var(--shadow); transition: transform .15s var(--ease); }
.day-leg:active { transform: scale(.985); }
.day-leg.day-late { box-shadow: inset 4px 0 0 var(--warn), var(--shadow); }
.day-leg.quiet { background: none; box-shadow: none; padding: 6px 4px; }
.day-leg .opt-meta .i { width: 14px; height: 14px; vertical-align: -2px; color: var(--accent); }
.day-warn { display: flex; gap: 6px; align-items: center; margin-top: 8px; font-size: var(--fs-sub); font-weight: 600; color: var(--warn); }
.day-stay { display: flex; align-items: center; gap: 5px; width: max-content; margin-top: 6px; padding: 3px 10px; border-radius: 99px; background: var(--accent-soft); color: var(--accent); font-weight: 600; font-size: var(--fs-foot); }
.day-stay .i { width: 14px; height: 14px; }
.day-back { color: var(--accent); } .day-back .muted { font-size: var(--fs-sub); }
/* first launch: the timetable download. The ring's front grows to three quarters of the circle, then its back
   catches up, while the whole ring turns. */
#dl { position: fixed; inset: 0; z-index: 35; background: var(--bg); display: flex; flex-direction: column; align-items: center; justify-content: safe center; overflow-y: auto; padding: calc(var(--safe-top) + 24px) 28px calc(var(--safe-bot) + 24px); text-align: center; --p: 0; transition: opacity .45s var(--ease), transform .45s var(--ease); }
#dl > * { flex: none; }
#dl.out { opacity: 0; transform: scale(1.04); pointer-events: none; }
.dl-ring { position: relative; width: 148px; height: 148px; display: grid; place-items: center; margin-bottom: 26px; }
@media (max-height: 700px) { .dl-ring { width: 116px; height: 116px; margin-bottom: 16px; } .dl-logo { width: 68px !important; height: 68px !important; } .dl-sub { margin-bottom: 16px; } .dl-steps { margin-top: 16px; gap: 8px; } }
.dl-logo { width: 88px; height: 88px; filter: drop-shadow(0 10px 22px rgba(184, 38, 74, .3)); }
#dl .lg-glow { transform-box: fill-box; transform-origin: center; animation: glow 1.8s ease-out infinite; }
.dl-spin { position: absolute; inset: 0; width: 100%; height: 100%; animation: spin-rotate 2s linear infinite; }
.dl-track { fill: none; stroke: var(--line); stroke-width: 5; }
.dl-arc { fill: none; stroke: url(#dl-arc-g); stroke-width: 5; stroke-linecap: round; stroke-dasharray: 1 400; animation: dl-dash 1.5s ease-in-out infinite; }
@keyframes dl-dash { 0% { stroke-dasharray: 1 400; stroke-dashoffset: 0; } 50% { stroke-dasharray: 254 400; stroke-dashoffset: -40; } 100% { stroke-dasharray: 254 400; stroke-dashoffset: -338; } }
.dl-title { font-size: var(--fs-title2); font-weight: 800; letter-spacing: -.02em; margin: 0 0 6px; }
.dl-sub { color: var(--muted); margin: 0 0 24px; max-width: 300px; font-size: var(--fs-sub); line-height: 1.4; }
.dl-bar { width: min(320px, 100%); height: 10px; border-radius: 99px; background: var(--line); overflow: hidden; position: relative; }
.dl-bar i { position: absolute; left: 0; top: 0; bottom: 0; width: calc(var(--p) * 100%); min-width: 10px; border-radius: inherit; overflow: hidden; background: linear-gradient(90deg, #FFB21E, #F0513E 55%, #B8264A); transition: width .35s var(--ease); }
.dl-bar i::after { content: ""; position: absolute; inset: 0; background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .5), transparent); transform: translateX(-100%); animation: dl-shine 1.6s ease-in-out infinite; }
@keyframes dl-shine { to { transform: translateX(100%); } }
.dl-row { width: min(320px, 100%); display: flex; justify-content: space-between; gap: 12px; margin-top: 12px; font-size: var(--fs-sub); font-weight: 600; }
.dl-what { text-align: left; } .dl-pct { font-variant-numeric: tabular-nums; color: var(--accent); }
.dl-detail { width: min(320px, 100%); text-align: left; margin: 2px 0 0; min-height: 18px; font-size: var(--fs-foot); color: var(--muted); font-variant-numeric: tabular-nums; }
.dl-steps { list-style: none; padding: 0; margin: 26px 0 0; width: min(320px, 100%); display: grid; gap: 11px; text-align: left; }
.dl-steps li { display: flex; align-items: center; gap: 10px; font-size: var(--fs-sub); color: var(--muted); transition: color .3s; }
.dl-steps li.now { color: var(--text); font-weight: 600; } .dl-steps li.done { color: var(--text); }
.dl-tick { width: 20px; height: 20px; border-radius: 50%; border: 2px solid var(--line); flex: none; position: relative; transition: background .3s, border-color .3s; }
.dl-steps li.now .dl-tick { border-color: var(--accent); border-right-color: transparent; animation: spin-rotate .9s linear infinite; }
.dl-steps li.done .dl-tick { background: var(--ok); border-color: var(--ok); }
.dl-steps li.done .dl-tick::after { content: ""; position: absolute; left: 5.5px; top: 2px; width: 5px; height: 10px; border: solid #fff; border-width: 0 2.5px 2.5px 0; transform: rotate(45deg); }
.dl-full { margin: 18px 0 0; width: min(320px, 100%); padding: 12px 14px; border-radius: 14px; background: var(--warn-soft); color: var(--warn); font-size: var(--fs-sub); text-align: left; } .dl-full b { display: block; margin-bottom: 2px; }
.dl-err { margin-top: 22px; width: min(320px, 100%); } .dl-err p { margin: 0 0 12px; color: var(--muted); font-size: var(--fs-sub); } .dl-err b { display: block; color: var(--text); font-size: var(--fs-body); margin-bottom: 2px; }
#dl.failed .dl-spin, #dl.failed .dl-arc, #dl.failed .dl-bar i::after, #dl.failed li.now .dl-tick { animation-play-state: paused; }
#dl.failed .dl-arc { stroke: var(--muted); }
#dl.done .dl-spin, #dl.done .dl-bar i::after { animation: none; }
#dl.done .dl-arc { animation: none; stroke-dasharray: 340 0; stroke: var(--ok); transition: stroke .3s; }
#dl.done .dl-logo { animation: pop .5s var(--spring); }
#dl.replay .dl-steps li .dl-tick::after, #dl.replay .dl-steps li .dl-tick { animation: pop .35s var(--spring) both; animation-delay: calc(var(--k) * 110ms + .15s); }
#dl.replay .dl-arc { animation: dl-close .7s var(--ease) both; }
@keyframes dl-close { from { stroke-dasharray: 254 400; stroke: #F0513E; } }
/* 6-digit codes: six boxes over one real input (so paste and the phone's code suggestion both work) */
.code-in { position: relative; margin: 22px auto 6px; max-width: 360px; }
.code-real { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; z-index: 1; font-size: var(--fs-body); color: transparent; caret-color: transparent; background: none; border: 0; }
.code-cells { display: grid; grid-template-columns: repeat(6, 1fr); gap: 8px; }
.code-cells i { font-style: normal; position: relative; height: 60px; display: grid; place-items: center; border-radius: 14px; background: var(--surface); box-shadow: var(--shadow); border: 2px solid transparent; font-size: var(--fs-title); font-weight: 800; font-variant-numeric: tabular-nums; color: var(--text); transition: border-color .15s; }
.code-cells i.full { animation: code-pop .24s var(--spring); }
.code-cells i.on { border-color: var(--accent); }
.code-cells i.on::after { content: ""; width: 2px; height: 26px; border-radius: 2px; background: var(--accent); animation: code-caret 1s steps(1) infinite; }
@keyframes code-pop { 50% { transform: scale(1.1); } }
@keyframes code-caret { 50% { opacity: 0; } }
.code-in.bad .code-cells { animation: code-shake .42s; } .code-in.bad .code-cells i { border-color: var(--bad); }
@keyframes code-shake { 20%, 60% { transform: translateX(-9px); } 40%, 80% { transform: translateX(9px); } }
.code-in.busy .code-cells i { animation: code-wait .9s ease-in-out infinite; animation-delay: calc(var(--k) * 80ms); color: var(--accent); }
@keyframes code-wait { 50% { transform: translateY(-5px); } }
/* two-step verification screens */
.nw { white-space: nowrap; }
#ts-done:disabled { opacity: .45; }
.ts-page { padding: 6px 4px 28px; }
.ts-hero { width: 76px; height: 76px; border-radius: 24px; display: grid; place-items: center; margin: 10px auto 18px; color: #fff; background: radial-gradient(circle at 50% 28%, rgba(255, 226, 122, .45), transparent 62%), linear-gradient(135deg, #FF9152, #F0513E 55%, #B8264A); box-shadow: 0 14px 30px rgba(184, 38, 74, .3); animation: pop .5s var(--spring) both; }
.ts-hero .i { width: 38px; height: 38px; }
.ts-hero.on { background: radial-gradient(circle at 50% 28%, rgba(255, 255, 255, .3), transparent 62%), linear-gradient(135deg, #43C585, #1B9A5E); box-shadow: 0 14px 30px rgba(27, 154, 94, .3); }
.ts-title { font-size: var(--fs-title); font-weight: 800; letter-spacing: -.02em; line-height: 1.15; text-align: center; margin: 0 0 8px; }
.ts-sub { font-size: var(--fs-title3); font-weight: 800; text-align: center; margin: 0 0 2px; }
.ts-lead { text-align: center; color: var(--muted); font-size: var(--fs-sub); line-height: 1.45; max-width: 340px; margin: 0 auto 18px; } .ts-lead b { color: var(--text); }
.ts-step { text-align: center; font-size: var(--fs-cap); font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: var(--accent); margin: 0 0 6px; }
.ts-links { display: flex; justify-content: center; flex-wrap: wrap; gap: 6px 20px; margin-top: 14px; } .ts-links .link:disabled { color: var(--muted); opacity: 1; }
.ts-opt { display: flex; align-items: center; gap: 14px; width: 100%; text-align: left; padding: 16px; margin-top: 10px; border-radius: var(--r); background: var(--surface); box-shadow: var(--shadow); transition: transform .15s var(--ease); } .ts-opt:active { transform: scale(.985); }
.ts-opt b { display: block; font-size: var(--fs-body); } .ts-opt small { display: block; color: var(--muted); font-size: var(--fs-sub); line-height: 1.4; margin-top: 3px; }
.ts-opt b em { display: inline-block; white-space: nowrap; font-style: normal; font-size: 11px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; color: var(--ok); background: var(--ok-soft); padding: 2px 8px; border-radius: 99px; margin-left: 6px; vertical-align: 2px; }
.ts-opt-ico { width: 46px; height: 46px; flex: none; display: grid; place-items: center; border-radius: 15px; background: var(--accent-soft); color: var(--accent); }
a.btn { text-decoration: none; }
.ts-or { display: flex; align-items: center; gap: 10px; margin: 18px 0 14px; color: var(--muted); font-size: var(--fs-foot); } .ts-or::before, .ts-or::after { content: ""; flex: 1; height: 1px; background: var(--line); }
.ts-qr { width: 184px; margin: 0 auto; padding: 14px; border-radius: 18px; background: #fff; box-shadow: var(--shadow); } .ts-qr svg { display: block; width: 100%; height: auto; }
.ts-key { display: flex; align-items: center; justify-content: center; gap: 10px; width: 100%; padding: 13px 14px; border-radius: 14px; background: var(--surface); box-shadow: var(--shadow); font: 700 15px/1.4 ui-monospace, 'SF Mono', Menlo, monospace; letter-spacing: .06em; color: var(--text); }
.ts-key-rows { display: grid; gap: 2px; text-align: center; } .ts-key-rows span { white-space: nowrap; } .ts-key .i { flex: none; color: var(--accent); }
.ts-backups { list-style: none; margin: 0; padding: 14px; display: grid; grid-template-columns: 1fr 1fr; gap: 10px; border-radius: var(--r); background: var(--surface); box-shadow: var(--shadow); }
.ts-backups li { padding: 10px 4px; border-radius: 11px; background: var(--bg); text-align: center; font: 700 17px/1.2 ui-monospace, 'SF Mono', Menlo, monospace; letter-spacing: .05em; animation: appear .35s var(--spring) both; animation-delay: calc(var(--k) * 45ms); }
.ts-pill { flex: none; padding: 4px 10px; border-radius: 99px; font-size: var(--fs-cap); font-weight: 800; background: var(--ok-soft); color: var(--ok); } .ts-pill.off { background: var(--line); color: var(--muted); }
.steps li.drive::before { background: var(--accent); }
.note.lift { width: 100%; text-align: left; margin-top: 12px; color: var(--text); background: var(--accent-soft); }
.note.lift > .i:first-child { color: var(--accent); }
.note.lift > .i:last-child { margin-left: auto; align-self: center; opacity: .6; }
/* route sheet */
.route-near { display: grid; gap: 2px; width: 100%; text-align: left; margin-bottom: 4px; }
.route-near b { font-size: var(--fs-row); }
.route-next { display: grid; gap: 2px; width: 100%; text-align: left; margin: 8px 0 4px; padding: 12px 16px; min-height: 56px; }
.route-next b { font-size: var(--fs-body); line-height: 1.3; }
.route-next small { font-size: var(--fs-foot); color: var(--muted); }
/* the Map's route view: your nearest stop on the line (steady, not the pulsing selected stop) and the next vehicle to reach it */
.mv-stop.near:not(.sel) { width: 18px; height: 18px; margin: -9px 0 0 -9px; background: var(--accent); border: 3px solid #fff; box-shadow: 0 1px 4px rgba(0, 0, 0, .35); z-index: 2; }
.mv-marker.next:not(.sel) { z-index: 3; box-shadow: 0 0 0 3px var(--surface), 0 0 0 5px var(--c, var(--accent)), 0 2px 8px rgba(0, 0, 0, .3); }
.route-times { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.route-times span { padding: 4px 10px; border-radius: 99px; background: var(--surface-2); font-weight: 700; font-size: var(--fs-sub); }
.route-times span.live { background: var(--ok-soft); color: var(--ok); }
.route-stops { list-style: none; margin: 0; padding: 0 0 8px 8px; }
.route-stops li { position: relative; padding-left: 22px; }
.route-stops li::before { content: ""; position: absolute; left: 3px; top: 50%; width: 10px; height: 10px; margin-top: -6px; border-radius: 50%; border: 2.5px solid var(--accent); background: var(--surface); z-index: 1; }
.route-stops li::after { content: ""; position: absolute; left: 8px; top: 0; bottom: 0; width: 2px; background: var(--line); }
.route-stops li:first-child::after { top: 50%; } .route-stops li:last-child::after { bottom: 50%; }
.route-stops button { width: 100%; text-align: left; padding: 10px 4px; min-height: 40px; font-size: var(--fs-sub); }
.route-stops button.here { font-weight: 800; color: var(--accent); }
.link { display: inline-flex; align-items: center; gap: 6px; }
.steps .side { display: flex; align-items: center; gap: 4px; margin-top: 2px; font-size: var(--fs-foot); color: var(--muted); }
.steps .side .i { width: 14px; height: 14px; }
/* walking to the stop */
.walkcard { margin-top: 14px; padding: 14px; border-radius: var(--r-sm); background: var(--surface-2); }
.walk-head { display: flex; gap: 10px; align-items: center; } .walk-head .i { color: var(--accent); }
.walk-head b { display: block; } .walk-head small { color: var(--muted); font-size: var(--fs-sub); }
.walk-head .live-dist { font-weight: 600; font-size: var(--fs-sub); margin-top: 2px; font-variant-numeric: tabular-nums; }
.side-note { display: flex; gap: 6px; align-items: center; margin-top: 8px; font-size: var(--fs-sub); font-weight: 600; }
.side-note .i { color: var(--accent); }
.walk-dir { margin-top: 10px; } .walk-dir summary { font-weight: 700; cursor: pointer; padding: 6px 0; min-height: 40px; display: flex; align-items: center; }
.walk-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; } .walk-actions .btn { flex: 1 1 auto; }
.item.here b { color: var(--accent); }
.item .side { display: flex; align-items: center; gap: 4px; margin-top: 2px; font-size: var(--fs-foot); color: var(--muted); } .item .side .i { width: 14px; height: 14px; }
.check { display: flex; gap: 10px; align-items: center; font-weight: 600; min-height: 44px; } .check input { width: 22px; height: 22px; accent-color: var(--accent); }
.stop-use { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 12px; }
.side-l { display: flex; align-items: center; gap: 4px; margin-top: 2px; } .side-l .i { width: 14px; height: 14px; }
.alts .item small { display: block; -webkit-line-clamp: unset; white-space: normal; overflow: visible; }
.list.wrap .item small { display: block; -webkit-line-clamp: unset; white-space: normal; overflow: visible; text-overflow: clip; }
#h-me { position: relative; } #h-me::before { content: ""; position: absolute; inset: -5px; }
/* map: Nearby rows list departures under the stop name; zoomed-out buses are simple dots */
.deps-inline { display: flex; flex-wrap: wrap; gap: 6px 12px; margin-top: 6px; }
.deps-inline > span { display: inline-flex; align-items: center; gap: 6px; font-size: var(--fs-sub); }
.deps-inline b { font-weight: 700; font-variant-numeric: tabular-nums; } .deps-inline b.live-t { color: var(--ok); }
.mv-marker.dot { width: 12px; height: 12px; padding: 0; border-radius: 50%; border: 2px solid #fff; box-shadow: 0 1px 3px rgba(0, 0, 0, .35); }
.item small.full, .item b.full { display: block; -webkit-line-clamp: unset; }
/* "Hurry!": the only urgent state, so it gets a gentle nudge (off with reduce-motion) */
.big.hurry em { color: var(--bad); display: inline-block; }
.big.hurry.shake em { animation: hurry 1.2s ease-in-out 3; }
@keyframes hurry { 0%, 100% { transform: none; } 15% { transform: translateX(-2px) rotate(-2deg); } 30% { transform: translateX(2px) rotate(2deg); } 45% { transform: none; } }
.hurry-note { margin: 12px 0 0; }
.spare { display: flex; align-items: center; gap: 6px; margin-top: 8px; font-size: var(--fs-sub); font-weight: 600; }
.spare.ok { color: var(--ok); } .spare.warn { color: var(--warn); } .spare.bad { color: var(--bad); } .spare b { margin-right: 2px; }
.also .back-to { background: none; box-shadow: none; color: var(--accent); font-weight: 700; display: inline-flex; align-items: center; gap: 4px; }
.cta-wrap { position: relative; } .cta-x { position: absolute; top: 6px; right: 6px; z-index: 2; }
/* your usual bus / school bus */
.tag-row { margin: 12px 0 -6px; } .bus-tag { display: inline-flex; align-items: center; gap: 5px; padding: 4px 10px; border-radius: 99px; background: var(--accent-soft); color: var(--accent); font-size: var(--fs-foot); font-weight: 700; }
.bus-tag.school { background: var(--warn-soft); color: var(--warn); } .bus-tag .i { width: 14px; height: 14px; }
.card-links { display: flex; flex-wrap: wrap; gap: 4px 18px; margin-top: 6px; } .card-links .link { display: inline-flex; align-items: center; gap: 6px; }
.bus-row { align-items: center; } .bus-row.is-usual { background: color-mix(in srgb, var(--accent-soft) 60%, transparent); }
.bus-pick { display: flex; flex-direction: column; gap: 6px; flex: none; }
.bus-pick button { min-width: 78px; min-height: 40px; padding: 0 10px; border-radius: 99px; font-weight: 700; font-size: var(--fs-foot); background: var(--surface-2); }
.bus-pick button[aria-pressed="true"] { background: var(--accent); color: var(--on-accent); }
.daypick { display: flex; gap: 6px; margin: -2px 0 12px; } .daypick button { flex: 1; min-height: 44px; border-radius: 12px; background: var(--surface-2); font-weight: 700; font-size: var(--fs-sub); } .daypick button[aria-pressed="true"] { background: var(--accent); color: var(--on-accent); }
/* reminder steps: wraps onto two rows (9 choices) */
.daypick.leads { flex-wrap: wrap; margin: 10px 0 4px; } .daypick.leads button { flex: 1 0 calc(20% - 6px); min-width: 58px; font-size: var(--fs-detail); } .daypick.leads button:last-child { flex-basis: calc(40% - 6px); }
/* "The S740 bus will be here in 13 min" on the Home card */
.bus-eta { display: flex; align-items: center; gap: 10px; margin: 2px 0 6px; padding: 10px 12px; border-radius: 14px; background: var(--surface-2); font-size: var(--fs-body); line-height: 1.3; }
.bus-eta .grow { min-width: 0; } .bus-eta b { font-weight: 700; } .bus-eta .when { color: var(--accent); font-weight: 800; white-space: nowrap; }
.bus-eta .live { font-size: var(--fs-label); }
.bus-eta.soon { background: color-mix(in srgb, var(--accent) 12%, var(--surface-2)); }
/* at the stop: the bus is less than a minute away */
.big.lookup { color: var(--accent); animation: lookup 1.1s ease-in-out infinite alternate; }
@keyframes lookup { from { transform: none; } to { transform: translateY(-3px); } }
@media (prefers-reduced-motion: reduce) { .big.lookup { animation: none; } }
/* the stop's number as its sign shows it ("STOP 35"), on the walk to the stop and while you wait */
.stop-chip { flex: none; display: inline-flex; flex-direction: column; align-items: center; justify-content: center; min-width: 54px; padding: 5px 8px 6px; border-radius: 8px; background: var(--accent); color: var(--on-accent); font-weight: 900; font-size: var(--fs-title2); line-height: 1; font-variant-numeric: tabular-nums; }
.stop-chip small { font-size: 10px; font-weight: 800; letter-spacing: .1em; margin-bottom: 3px; }
.stop-sign { display: flex; gap: 10px; align-items: center; margin-top: 12px; font-size: var(--fs-sub); }
.phase .ride-spd { font-weight: 600; font-variant-numeric: tabular-nums; }
/* Home: "Where to? Ask GoSEQ" with a mic to say it */
.searchrow { position: relative; }
.searchbar.ask-bar { min-height: 62px; padding: 8px 16px 8px 12px; }
.searchbar.ask-bar.has-mic { padding-right: 64px; }
.searchbar.ask-bar .ask-spark { flex: none; }
.searchbar.ask-bar .grow { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.searchbar .sb-main { color: var(--text); font-weight: 600; } .searchbar .sb-main b { color: var(--accent); font-weight: 700; }
.searchbar.ask-bar .hint { font-size: var(--fs-detail); color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mic { position: absolute; right: 9px; top: 50%; transform: translateY(-50%); width: 46px; height: 46px; border-radius: 50%; display: grid; place-items: center; background: var(--accent); color: var(--on-accent); box-shadow: 0 4px 14px color-mix(in srgb, var(--accent) 35%, transparent); }
.mic:active { transform: translateY(-50%) scale(.92); }
.overlay-top .mic-sm { color: var(--accent); }
/* ride: a gentle nudge to thank the driver */
.thanks { display: flex; align-items: center; gap: 8px; margin: -8px 0 14px; font-size: var(--fs-sub); color: var(--muted); }
.thanks .i { width: 16px; height: 16px; color: var(--accent); }
/* Driver greetings (greet.js): one short line, never a pop-up */
.greet { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; margin: -4px 0 14px; font-size: var(--fs-sub); line-height: 1.35; color: var(--text); }
.greet > span:first-child { flex: 1 1 200px; }
.greet .greet-wish { display: block; margin-top: 2px; font-size: var(--fs-foot); color: var(--muted); }
.greet .greet-said { font-size: var(--fs-sub); white-space: nowrap; }
.greet .greet-said.on { color: var(--muted); }
/* ride: live data from before a break, said quietly */
.ride-stale { display: flex; align-items: center; gap: 6px; margin: -6px 0 12px; }
.ride-stale .i { width: 15px; height: 15px; flex: none; }
/* colour themes */
.swatches { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px 6px; margin-top: 12px; }
.swatch { display: flex; flex-direction: column; align-items: center; gap: 6px; min-height: 48px; position: relative; cursor: pointer; }
.swatch .dot { width: 44px; height: 44px; border-radius: 50%; background: var(--sw); display: grid; place-items: center; color: #fff; box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .08); transition: transform .2s var(--spring), box-shadow .2s; }
.swatch .dot .i { width: 18px; height: 18px; stroke-width: 3; opacity: 0; transform: scale(.5); transition: opacity .15s, transform .2s var(--spring); }
.swatch[aria-checked="true"] .dot { box-shadow: 0 0 0 3px var(--surface), 0 0 0 5px var(--accent); }
.swatch[aria-checked="true"] .dot .i { opacity: 1; transform: none; }
.swatch:active .dot { transform: scale(.92); }
.swatch small { font-size: var(--fs-label); color: var(--muted); font-weight: 600; } .swatch[aria-checked="true"] small { color: var(--text); }
.swatch.custom .dot { background: conic-gradient(from 0deg, #FF5A5A, #FFC23D, #7BD66A, #2FC3D6, #4A6CF7, #B45CE6, #FF5A5A); }
.swatch.custom[aria-checked="true"] .dot { background: var(--sw); }
.swatch.custom .dot .i { opacity: 1; transform: none; }
.swatch.custom input { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer; border: 0; padding: 0; }
/* live turn-by-turn walking guidance */
.guide { margin: 0 0 12px; padding: 14px 14px 12px; border-radius: 16px; background: var(--accent); color: var(--on-accent); }
.guide-main { display: flex; align-items: center; gap: 12px; }
.guide-arrow { width: 52px; height: 52px; flex: none; display: grid; place-items: center; border-radius: 14px; background: color-mix(in srgb, var(--on-accent) 16%, transparent); }
.guide .turn { width: 36px; height: 36px; fill: none; stroke: currentColor; stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round; }
.guide-dist { font-size: var(--fs-title); font-weight: 800; line-height: 1.1; letter-spacing: -.01em; }
.guide-text { font-size: var(--fs-body); font-weight: 600; line-height: 1.3; margin-top: 2px; }
.guide-then { display: flex; align-items: center; gap: 6px; margin-top: 10px; padding-top: 10px; border-top: 1px solid color-mix(in srgb, var(--on-accent) 22%, transparent); font-size: var(--fs-sub); font-weight: 600; }
.guide-then .turn { width: 18px; height: 18px; stroke-width: 2.4; flex: none; }
.guide-foot { margin-top: 10px; font-size: var(--fs-detail); opacity: .85; font-weight: 600; }
.guide.now .guide-arrow { animation: navpulse 1s ease-in-out infinite alternate; }
@keyframes navpulse { to { background: color-mix(in srgb, var(--on-accent) 32%, transparent); } }
.guide.rerouting { display: flex; align-items: center; gap: 12px; } .guide.rerouting .guide-dist { font-size: var(--fs-row); } .guide.rerouting .guide-arrow { animation: navpulse .7s ease-in-out infinite alternate; }
@media (prefers-reduced-motion: reduce) { .guide.now .guide-arrow, .guide.rerouting .guide-arrow { animation: none; } }
.guide-list li { align-items: center; justify-content: flex-start; } .guide-list .turn { width: 20px; height: 20px; flex: none; fill: none; stroke: var(--muted); stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.guide-list li.cur { font-weight: 700; } .guide-list li.cur .turn { stroke: var(--accent); }
.mv-marker.dot.turn { width: 16px; height: 16px; background: var(--accent); border: 3px solid #fff; }
/* a live trip tucked away (Back): tap to return */
.trip-pill { position: fixed; left: 12px; right: 12px; bottom: calc(var(--nav-h) + var(--safe-bot) + 10px); z-index: 25; display: flex; align-items: center; gap: 12px; min-height: 56px; padding: 10px 14px; border-radius: 16px; background: var(--text); color: var(--bg); box-shadow: var(--shadow-up); text-align: left; animation: markerIn .4s var(--spring) both; }
.trip-pill b { display: block; font-size: var(--fs-sub); } .trip-pill small { display: block; font-size: var(--fs-foot); opacity: .78; }
.trip-pill .pulse-dot { width: 10px; height: 10px; flex: none; border-radius: 50%; background: var(--ok); animation: pulse 2s ease-in-out infinite; }
body.overlay-open .trip-pill { display: none; }
.check-row { display: flex; align-items: center; gap: 12px; min-height: 48px; margin: 8px 2px 0; font-weight: 600; cursor: pointer; }
.check-row input { width: 22px; height: 22px; accent-color: var(--accent); flex: none; }
/* "Is this your home?": move the map under a fixed pin */
.pin-map { position: relative; flex: 1; min-height: 50vh; }
.pin-center { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -100%); z-index: 3; pointer-events: none; color: var(--accent); filter: drop-shadow(0 3px 4px rgba(0, 0, 0, .35)); }
.pin-center .i { width: 44px; height: 44px; stroke-width: 2.4; fill: var(--surface); }
.pin-foot { padding: 16px 16px calc(16px + var(--safe-bot)); background: var(--surface); }

/* tap targets: at least 44-48 px everywhere */
.chip { min-height: 44px; }
/* links keep their place in a sentence, but get a finger-sized hit area */
.link { position: relative; } .link::after { content: ""; position: absolute; inset: -12px -6px; }
.bus-pick button { min-height: 44px; min-width: 64px; }
.mv-stop::after { content: ""; position: absolute; inset: -14px; }

.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
/* search: the place you're going, with one-tap save */
.save-row { display: flex; align-items: center; gap: 8px; margin: 0 2px 10px; min-height: 44px; }
.save-row b { font-size: var(--fs-sub); } .save-row .saved { display: inline-flex; align-items: center; gap: 4px; color: var(--ok); font-weight: 700; font-size: var(--fs-sub); }

/* ---- support ---- */
/* Me → Help & support (js/support.js): help articles, a message to GoSEQ Support, and the conversation, with the same
   Freshdesk-style status colours as support.goseq.app. */
:root { --st-open: #1D5FB8; --st-open-bg: #E3EDFB; --st-pending: #A45A00; --st-pending-bg: #FFF1DC; --st-waiting: #6B3FC4; --st-waiting-bg: #EFE8FC; --st-resolved: #137347; --st-resolved-bg: #E1F3E9; --st-closed: #6B625D; --st-closed-bg: #EFEBE6; }
:root[data-theme="dark"] { --st-open: #8DBAF5; --st-open-bg: #1E3350; --st-pending: #F2B35C; --st-pending-bg: #3A2A12; --st-waiting: #C4A8FF; --st-waiting-bg: #2D2346; --st-resolved: #4CD39A; --st-resolved-bg: #173427; --st-closed: #A99F99; --st-closed-bg: #272322; }
.sup-search { display: flex; align-items: center; gap: 10px; min-height: 54px; padding: 0 16px; border-radius: 16px; background: var(--surface); box-shadow: var(--shadow); color: var(--muted); }
.sup-search input { flex: 1; min-width: 0; min-height: 50px; border: 0; background: none; font-size: var(--fs-row); color: var(--text); }
.sup-search:focus-within { box-shadow: var(--shadow), 0 0 0 3px color-mix(in srgb, var(--accent) 40%, transparent); }
.sup-faq summary { display: flex; align-items: center; gap: 12px; min-height: 56px; padding: 14px 16px; font-weight: 600; font-size: var(--fs-body); line-height: 1.35; cursor: pointer; list-style: none; }
.sup-faq summary::-webkit-details-marker { display: none; }
.sup-faq summary .i { margin-left: auto; color: var(--muted); transform: rotate(90deg); transition: transform .2s var(--ease); }
.sup-faq[open] summary .i { transform: rotate(-90deg); color: var(--accent); }
.sup-faq summary:active { background: var(--surface-2); }
.sup-a { padding: 0 16px 16px; color: var(--muted); font-size: var(--fs-sub); line-height: 1.5; animation: appear .25s var(--ease) both; }
.sup-a p { margin: 0 0 8px; } .sup-a p:last-child { margin: 0; } .sup-a b { color: var(--text); font-weight: 600; } .sup-a a, .sup-bubble a { color: var(--accent); font-weight: 600; }
.sup-none { margin: 18px 4px 0; }
.sup-cta { display: grid; gap: 4px; margin-bottom: 18px; }   /* first thing on the support screen */ .sup-cta b { font-size: var(--fs-row); } .sup-cta small { margin-bottom: 12px; color: var(--muted); font-size: var(--fs-sub); line-height: 1.4; }
.sup-pill { display: inline-flex; align-items: center; gap: 6px; flex: none; padding: 4px 10px 4px 8px; border-radius: 99px; font-size: var(--fs-foot); font-weight: 700; line-height: 1.3; white-space: nowrap; color: var(--st-open); background: var(--st-open-bg); }
.sup-pill::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.sup-pill.s-pending { color: var(--st-pending); background: var(--st-pending-bg); } .sup-pill.s-waiting { color: var(--st-waiting); background: var(--st-waiting-bg); }
.sup-pill.s-resolved { color: var(--st-resolved); background: var(--st-resolved-bg); } .sup-pill.s-closed { color: var(--st-closed); background: var(--st-closed-bg); }
.sup-dot { display: inline-block; width: 8px; height: 8px; margin-right: 6px; border-radius: 50%; background: var(--accent); vertical-align: 1px; }
.field textarea { display: block; width: 100%; min-height: 110px; padding: 3px 0; border: 0; background: transparent; font: inherit; font-size: var(--fs-row); line-height: 1.4; color: inherit; resize: vertical; outline: none; }
.sup-opt { font-style: normal; font-weight: 500; }
.sup-diag { align-items: flex-start; font-weight: 600; } .sup-diag input { margin-top: 1px; }
.sup-diag small { display: block; margin-top: 2px; font-size: var(--fs-foot); font-weight: 500; line-height: 1.4; color: var(--muted); }
/* the conversation */
.sup-title { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sup-head { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; margin: 2px 0 4px; } .sup-head small { color: var(--muted); font-size: var(--fs-sub); }
.sup-ref { display: block; margin: 0 0 4px; font-size: var(--fs-foot); font-variant-numeric: tabular-nums; }
.sup-chat { display: flex; flex-direction: column; gap: 14px; margin: 0; padding: 14px 0 8px; list-style: none; }
.sup-row { display: flex; gap: 8px; align-items: flex-end; } .sup-row.me { flex-direction: row-reverse; }
.sup-av { flex: none; display: grid; place-items: center; width: 30px; height: 30px; overflow: hidden; border-radius: 9px; } .sup-av .logo-mark { width: 30px; height: 30px; display: block; }
.sup-av.isaac { border-radius: 50%; background: var(--text); color: var(--bg); font-weight: 800; font-size: var(--fs-foot); }
.sup-col { display: grid; gap: 3px; min-width: 0; max-width: calc(100% - 38px); } .me .sup-col { justify-items: end; max-width: 86%; }
.sup-meta { padding: 0 4px; font-size: var(--fs-label); font-weight: 600; color: var(--muted); }
.sup-meta .ai { margin-left: 5px; padding: 1px 6px; border-radius: 6px; background: var(--surface-2); font-size: 11px; font-weight: 700; }
.sup-bubble { padding: 11px 14px; border-radius: 18px 18px 18px 6px; background: var(--surface); box-shadow: var(--shadow); font-size: var(--fs-body); line-height: 1.45; white-space: pre-wrap; overflow-wrap: anywhere; }
.me .sup-bubble { border-radius: 18px 18px 6px 18px; background: var(--accent); color: var(--on-accent); box-shadow: none; } .me .sup-bubble a { color: inherit; }
.sup-row.isaac .sup-bubble { box-shadow: var(--shadow), inset 0 0 0 1.5px color-mix(in srgb, var(--text) 35%, transparent); }
.sup-bubble.typing { justify-self: start; display: inline-flex; align-items: center; gap: 5px; min-height: 44px; padding: 0 16px; }
.sup-bubble .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--muted); opacity: .35; animation: supDot 1.2s ease-in-out infinite; }
.sup-bubble .dot:nth-child(2) { opacity: .6; animation-delay: .15s; } .sup-bubble .dot:nth-child(3) { opacity: .85; animation-delay: .3s; }
@keyframes supDot { 0%, 60%, 100% { transform: none; opacity: .35; } 30% { transform: translateY(-5px); opacity: 1; } }
.sup-tw::after { content: ""; display: inline-block; width: 2px; height: 1.1em; margin-left: 2px; vertical-align: -3px; background: currentColor; opacity: .6; animation: supCaret .9s steps(1) infinite; }
@keyframes supCaret { 50% { opacity: 0; } }
.sup-sys { align-self: center; max-width: 88%; font-size: var(--fs-detail); line-height: 1.4; text-align: center; color: var(--muted); }
.sup-chat > .new { animation: appear .3s var(--ease) both; }
.sup-compose { flex: none; padding: 8px 12px calc(10px + var(--safe-bot)); background: var(--bg); border-top: 1px solid var(--line); }
.sup-box { display: flex; align-items: flex-end; gap: 8px; padding: 6px 6px 6px 14px; border-radius: 16px; background: var(--surface); box-shadow: var(--shadow); }
.sup-box:focus-within { box-shadow: var(--shadow), 0 0 0 2px color-mix(in srgb, var(--accent) 45%, transparent); }
.sup-box textarea { flex: 1; min-width: 0; min-height: 40px; max-height: 30vh; padding: 9px 0; border: 0; background: none; font: inherit; font-size: var(--fs-body); line-height: 1.4; color: inherit; resize: none; outline: none; }
.sup-send { flex: none; display: grid; place-items: center; width: 44px; height: 44px; border-radius: 12px; background: var(--accent); color: var(--on-accent); }
.sup-send[disabled] { opacity: .5; }
.sup-attach { flex: none; display: grid; place-items: center; width: 44px; height: 44px; margin-right: -4px; border-radius: 12px; color: var(--muted); }
.sup-attach:active { background: var(--surface-2); } .sup-attach[disabled] { opacity: .4; }
/* a screenshot or photo: a thumbnail that opens full size, or a file to save when the WebView can't show it */
.sup-bubble.sup-pic { padding: 0; background: none; box-shadow: none; white-space: normal; }
.sup-pic > button { display: block; padding: 0; border-radius: 14px; }
.sup-pic img { display: block; max-width: min(220px, 100%); max-height: 300px; width: auto; height: auto; border-radius: 14px; background: var(--surface-2); box-shadow: var(--shadow); }
.sup-pic-wait { display: grid; place-items: center; width: 160px; height: 120px; border-radius: 14px; background: var(--surface-2); }
.sup-file { display: flex; align-items: center; gap: 10px; max-width: 260px; min-height: 56px; padding: 10px 14px; border-radius: 14px; background: var(--surface); box-shadow: var(--shadow); color: var(--text); text-decoration: none; }
.sup-row .sup-bubble .sup-file { color: var(--text); font-weight: 500; }
.sup-file b { display: block; font-size: var(--fs-detail); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .sup-file small { display: block; font-size: var(--fs-foot); color: var(--muted); }
.sup-sending .sup-bubble { display: inline-flex; align-items: center; gap: 9px; opacity: .8; }
.sup-sending .sup-bubble span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 200px; }
.sup-full { display: grid; place-items: center; } .sup-full img { display: block; max-width: 100%; max-height: calc(100vh - 140px); border-radius: 12px; }
.sup-foot { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; padding: 6px 4px 0; }
.sup-foot small { flex: 1; min-width: 0; font-size: var(--fs-foot); line-height: 1.35; }
.sup-foot .link { margin-left: auto; }
.sup-person { display: inline-flex; align-items: center; gap: 6px; min-height: 40px; padding: 0 14px 0 10px; border-radius: 99px; background: var(--surface); box-shadow: var(--shadow); font-weight: 600; font-size: var(--fs-sub); color: var(--text); }
.sup-person:active { background: var(--surface-2); }
/* waiting for Isaac: the banner above the reply box */
.sup-banner { display: flex; align-items: center; gap: 10px; margin: 0 0 8px; padding: 10px 12px; border-radius: 14px; background: var(--st-pending-bg); font-size: var(--fs-detail); font-weight: 600; line-height: 1.35; }
.sup-banner .sup-av { width: 26px; height: 26px; font-size: var(--fs-cap); }
.sup-sys.waiting { color: var(--text); font-weight: 600; }
/* the handover dividers run the full width */
.sup-div { display: flex; align-items: center; gap: 10px; font-size: var(--fs-detail); font-weight: 700; text-align: center; }
.sup-div::before, .sup-div::after { content: ""; flex: 1 1 14px; height: 1px; background: color-mix(in srgb, var(--text) 22%, transparent); }
.sup-div span { display: inline-flex; align-items: center; gap: 7px; }
.sup-div .sup-av { width: 22px; height: 22px; border-radius: 7px; font-size: 11px; } .sup-div .sup-av.isaac { border-radius: 50%; } .sup-div .sup-av .logo-mark { width: 22px; height: 22px; }
/* the summary, and "Did this sort it out?" */
.sup-card { padding: 14px 16px; border-radius: 16px; background: var(--surface); box-shadow: var(--shadow); }
.sup-card b { display: block; font-size: var(--fs-body); }
.sup-card ul { margin: 6px 0 0; padding-left: 20px; list-style: disc; font-size: var(--fs-sub); line-height: 1.45; } .sup-card li + li { margin-top: 3px; }
.sup-ask { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 12px; } .sup-ask b { flex: 1 1 150px; }
.sup-ask-btns { display: flex; gap: 8px; } .sup-ask-btns .btn { min-height: 44px; font-size: var(--fs-sub); padding: 0 14px; }
.sup-ask:not(.live) { align-self: center; padding: 0; background: none; box-shadow: none; } .sup-ask:not(.live) b { font-size: var(--fs-detail); font-weight: 400; color: var(--muted); } .sup-ask:not(.live) .sup-ask-btns { display: none; }
/* a closed chat: rating, save a copy, start a new chat */
.sup-end { margin: 16px 0 4px; padding: 16px; border-radius: 18px; background: var(--surface-2); }
.sup-end h3 { margin: 0 0 8px; font-size: var(--fs-row); } .sup-end h3:focus { outline: none; }
.sup-stars { display: flex; gap: 2px; margin: 4px 0 10px; }
.sup-stars button { display: grid; place-items: center; width: 46px; height: 46px; border-radius: 10px; color: var(--muted); }
.sup-stars svg { width: 30px; height: 30px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linejoin: round; }
.sup-stars button.on { color: #D99100; } .sup-stars button.on svg { fill: currentColor; }
.sup-thanks { display: flex; align-items: center; gap: 8px; margin: 0 0 12px; font-weight: 600; } .sup-thanks .i { color: var(--ok); }
.sup-end-btns { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 4px; } .sup-end-btns .btn { flex: 1 1 150px; min-height: 46px; font-size: var(--fs-sub); }
.sup-end .btn:not(.primary) { background: var(--surface); box-shadow: var(--shadow); }
.sup-follow { margin: 2px 0 0; } .sup-follow .link { padding: 0; font-size: var(--fs-sub); }
/* your requests, and picking up from another phone */
.sup-who { margin: 10px 4px 0; line-height: 1.45; } .sup-who b { color: var(--text); } .sup-who .link { padding: 4px 0; font-size: var(--fs-sub); }
.sup-other { margin-top: 14px; }
.sup-as { margin: 0 4px 12px; } .sup-as b { color: var(--text); } .sup-as .link { padding: 0; font-size: var(--fs-sub); }
.sup-verify { margin-top: 14px; }
.sup-lead b { color: var(--text); } .sup-lead:focus { outline: none; }
.sup-code { font-size: var(--fs-title3) !important; letter-spacing: .3em; font-variant-numeric: tabular-nums; }
.sup-links { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 0 12px; margin-top: 6px; }

/* ---- "Update required" (js/update.js): the whole screen, a Mac-style install. The ring waits as the app's 3/4 arc,
   fills as the update downloads, and the cloud's arrow becomes a tick when it's in. ---- */
.upd { position: fixed; inset: 0; z-index: 300; display: grid; place-items: center; padding: max(24px, env(safe-area-inset-top)) 20px max(24px, env(safe-area-inset-bottom));
  background: color-mix(in srgb, var(--bg) 94%, transparent); -webkit-backdrop-filter: blur(30px) saturate(1.2); backdrop-filter: blur(30px) saturate(1.2); animation: upd-in .45s var(--ease) both; }
.upd.out { animation: upd-out .3s var(--ease) both; }
.upd-card { width: min(100%, 380px); display: grid; justify-items: center; text-align: center; gap: 0; animation: upd-rise .6s .05s var(--spring) both; }
.upd-ring { position: relative; width: 132px; height: 132px; margin-bottom: 26px; }
.upd-svg { position: absolute; inset: 0; width: 100%; height: 100%; transform: rotate(-90deg); overflow: visible; }
.upd-trk { fill: none; stroke: var(--line); stroke-width: 7; }
.upd-bar { fill: none; stroke: url(#upd-g); stroke-width: 7; stroke-linecap: round; opacity: 0; transition: stroke-dashoffset .35s var(--ease), opacity .3s; }
.upd-spin { fill: none; stroke: var(--accent); stroke-width: 7; stroke-linecap: round; stroke-dasharray: 1, 400; transform-origin: 60px 60px; animation: upd-rot 1.2s linear infinite, upd-dash 1.2s cubic-bezier(.45, .05, .35, 1) infinite, upd-hue 2.4s ease-in-out infinite; transition: opacity .3s; }
.upd-icon { position: absolute; inset: 14px; width: calc(100% - 28px); height: calc(100% - 28px); fill: none; stroke-linecap: round; stroke-linejoin: round; }
.up-cloud { fill: var(--accent-soft); stroke: var(--accent); stroke-width: 4.5; transition: fill .4s, stroke .4s; }
.up-arrow { stroke: var(--accent); stroke-width: 4.5; animation: upd-drop 1.6s var(--ease) infinite; transition: opacity .25s; }
.up-tick { stroke: var(--on-accent); stroke-width: 5.5; stroke-dasharray: 34; stroke-dashoffset: 34; opacity: 0; }
.upd-ring[data-state="down"] .upd-bar, .upd-ring[data-state="done"] .upd-bar { opacity: 1; }
.upd-ring[data-state="down"] .upd-spin, .upd-ring[data-state="done"] .upd-spin, .upd-ring[data-state="fail"] .upd-spin { opacity: 0; animation-play-state: paused; }
.upd-ring[data-state="done"] { animation: upd-pop .6s var(--spring); }
.upd-ring[data-state="done"] .up-cloud { fill: var(--accent); }
.upd-ring[data-state="done"] .up-arrow { opacity: 0; animation: none; }
.upd-ring[data-state="done"] .up-tick { opacity: 1; animation: upd-tick .45s .15s var(--ease) forwards; }
.upd-ring[data-state="fail"] .up-cloud { fill: var(--surface-2); stroke: var(--muted); }
.upd-ring[data-state="fail"] .up-arrow { stroke: var(--muted); animation: none; }
.upd h1 { margin: 0 0 8px; font-size: var(--fs-title); line-height: 1.2; letter-spacing: -.02em; }
.upd-lead { margin: 0 0 14px; color: var(--muted); font-size: var(--fs-body); line-height: 1.5; }
.upd-notes { margin: 0 0 16px; padding: 12px 16px 12px 32px; width: 100%; text-align: left; border-radius: 14px; background: var(--surface); border: 1px solid var(--line); font-size: var(--fs-sub); line-height: 1.45; }
.upd-notes li + li { margin-top: 4px; }
.upd-status { margin: 4px 0 10px; min-height: 22px; font-size: var(--fs-sub); font-weight: 600; font-variant-numeric: tabular-nums; }
.upd-meter { width: min(100%, 240px); height: 5px; border-radius: 99px; background: var(--line); overflow: hidden; }
.upd-meter span { display: block; height: 100%; width: 0; border-radius: inherit; background: linear-gradient(90deg, #FF9152, #F0513E 55%, #B8264A); transition: width .35s var(--ease); }
.upd[data-state="wait"] .upd-meter span { width: 30% !important; animation: upd-slide 1.2s ease-in-out infinite; }
.upd[data-state="fail"] .upd-meter { visibility: hidden; }
.upd-acts { display: grid; gap: 8px; width: 100%; margin-top: 22px; }
.upd-acts:empty { display: none; }
.upd-acts .btn { width: 100%; }
.upd-acts .btn.ghost { background: none; color: var(--accent); min-height: 44px; }
@keyframes upd-in { from { opacity: 0; } }
@keyframes upd-out { to { opacity: 0; } }
@keyframes upd-rise { from { opacity: 0; transform: translateY(18px) scale(.97); } }
@keyframes upd-rot { to { transform: rotate(360deg); } }
@keyframes upd-dash { 0% { stroke-dasharray: 1, 400; stroke-dashoffset: 0; } 50% { stroke-dasharray: 254, 400; stroke-dashoffset: -43; } 100% { stroke-dasharray: 254, 400; stroke-dashoffset: -334; } }
@keyframes upd-hue { 0%, 100% { stroke: var(--accent); } 50% { stroke: color-mix(in srgb, var(--accent) 70%, #FFB01C); } }
@keyframes upd-drop { 0% { transform: translateY(-7px); opacity: 0; } 30%, 70% { opacity: 1; } 100% { transform: translateY(7px); opacity: 0; } }
@keyframes upd-tick { to { stroke-dashoffset: 0; } }
@keyframes upd-pop { 40% { transform: scale(1.06); } }
@keyframes upd-slide { from { transform: translateX(-100%); } to { transform: translateX(340%); } }
@media (prefers-reduced-motion: reduce) { .upd-spin, .updp-hero[data-state="checking"] .a { stroke-dasharray: 254, 400; } .up-tick { stroke-dashoffset: 0; } }
/* trip history: how each trip ended, and "Plan again" */
.trip-row { align-items: flex-start; }
.trip-end { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; flex: none; }
.trip-status { padding: 3px 9px; border-radius: 99px; font-size: var(--fs-label); font-weight: 700; background: var(--surface-2); color: var(--muted); white-space: nowrap; }
/* the theme's own green and amber (AA on their tint, light and dark: #1E9E5A and #B87400 were 2.9:1 and 3.2:1) */
.trip-status.good { background: color-mix(in srgb, var(--ok) 14%, transparent); color: color-mix(in srgb, var(--ok) 82%, var(--text)); }
.trip-status.warn { background: var(--warn-soft); color: var(--warn); }
.trip-status.live { background: var(--accent-soft); color: var(--accent); }
.trip-end .link { min-height: 32px; font-size: var(--fs-detail); }


/* "GoSEQ is out of date" (js/update.js): a sheet from the bottom, once a day at most per update */
.upd-sheet { position: fixed; inset: 0; z-index: 290; display: flex; align-items: flex-end; justify-content: center; background: rgba(12, 8, 6, .42); animation: upd-in .3s var(--ease) both; }
.upd-sheet.out { animation: upd-out .28s var(--ease) both; }
.upd-sheet.out .upds-card { animation: upds-down .28s var(--ease) both; }
.upds-card { width: min(100%, 520px); max-height: 88vh; overflow-y: auto; padding: 10px 20px calc(20px + var(--safe-bottom, 0px)); border-radius: 26px 26px 0 0; background: var(--bg); box-shadow: 0 -10px 40px rgba(0, 0, 0, .18); animation: upds-up .45s var(--spring) both; }
.upds-grab { width: 40px; height: 5px; margin: 0 auto 14px; border-radius: 99px; background: var(--line); }
.upds-head { display: flex; gap: 14px; align-items: flex-start; margin-bottom: 12px; }
.upds-head h2 { margin: 2px 0 4px; font-size: var(--fs-title3); letter-spacing: -.02em; }
.upds-head p { margin: 0; color: var(--muted); font-size: var(--fs-sub); line-height: 1.45; }
.upds-head p b { color: var(--text); font-weight: 600; }
.upds-logo { position: relative; flex: none; width: 58px; height: 58px; }
.upds-logo .logo-mark { width: 58px; height: 58px; display: block; filter: drop-shadow(0 6px 14px rgba(184, 38, 74, .28)); }
.upds-new { position: absolute; right: -8px; top: -6px; padding: 2px 7px; border-radius: 99px; background: var(--accent); color: var(--on-accent); font-size: 11px; font-weight: 800; letter-spacing: .02em; box-shadow: 0 0 0 3px var(--bg); animation: upds-pop .5s .3s var(--spring) both; }
.upds-card h3 { margin: 6px 0 8px; font-size: var(--fs-sub); color: var(--muted); }
.upds-fine { margin: 10px 0 0; text-align: center; color: var(--muted); font-size: var(--fs-foot); }
@keyframes upds-up { from { transform: translateY(100%); } }
@keyframes upds-down { to { transform: translateY(100%); } }
@keyframes upds-pop { from { transform: scale(0); } }

/* Me → Updates */
.upd-dot { display: inline-block; width: 8px; height: 8px; margin-left: 8px; border-radius: 50%; background: var(--accent); vertical-align: 2px; box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 50%, transparent); animation: upd-pulse 2s ease-out infinite; }
@keyframes upd-pulse { to { box-shadow: 0 0 0 8px transparent; } }
.updp-hero { display: grid; justify-items: center; text-align: center; gap: 2px; padding: 22px 18px 18px; margin-top: 4px; border-radius: var(--r); background: var(--surface); box-shadow: var(--shadow); }
.updp-hero h3 { margin: 12px 0 2px; font-size: var(--fs-title3); letter-spacing: -.02em; }
.updp-hero p { margin: 0; color: var(--muted); font-size: var(--fs-sub); }
.updp-hero p b { color: var(--text); font-weight: 600; }
.updp-ring { position: relative; width: 104px; height: 104px; display: grid; place-items: center; }
.updp-ring .updp-arc { position: absolute; inset: 0; width: 100%; height: 100%; transform: rotate(-90deg); }
.updp-arc circle { fill: none; stroke-width: 6; stroke-linecap: round; }
.updp-arc .t { stroke: var(--line); }
.updp-arc .a { stroke: var(--ok); stroke-dasharray: 340 400; transition: stroke .3s; }
.updp-ring .logo-mark { width: 62px; height: 62px; display: block; }
.updp-hero[data-state="new"] .a, .updp-hero[data-state="store"] .a { stroke: var(--accent); }
.updp-hero[data-state="checking"] .a { stroke: var(--accent); stroke-dasharray: 1, 400; transform-origin: 60px 60px; animation: upd-rot 1.2s linear infinite, upd-dash 1.2s cubic-bezier(.45, .05, .35, 1) infinite, upd-hue 2.4s ease-in-out infinite; }
.updp-hero[data-state="fail"] .a, .updp-hero[data-state="off"] .a { stroke: var(--muted); stroke-dasharray: 0 400; }
.updp-badge { position: absolute; right: 2px; bottom: 4px; display: grid; place-items: center; min-width: 28px; height: 28px; padding: 0 6px; border-radius: 99px; box-shadow: 0 0 0 3px var(--surface); font-weight: 800; font-size: var(--fs-foot); animation: upds-pop .45s var(--spring) both; }
.updp-badge.ok { background: var(--ok); color: #fff; }
.updp-badge.ok .i { width: 16px; height: 16px; stroke-width: 3; }
.updp-badge.new { background: var(--accent); color: var(--on-accent); }
.updp-acts { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin-top: 14px; width: 100%; }
.updp-acts .btn { flex: 1 1 150px; }
.updp-acts .btn[disabled] { opacity: .7; }
.updp-fine { margin: 8px 0 0; color: var(--muted); font-size: var(--fs-foot); line-height: 1.45; }
.updp > .updp-fine { margin: 18px 4px 0; }
.updp-log { list-style: none; margin: 0; padding: 4px 0 0 4px; }
.updp-log > li { position: relative; display: flex; gap: 14px; padding: 0 0 18px; }
.updp-log > li:not(:last-child)::before { content: ""; position: absolute; left: 6px; top: 16px; bottom: -2px; width: 2px; background: var(--line); }
.updp-dot { flex: none; width: 14px; height: 14px; margin-top: 3px; border-radius: 50%; background: var(--surface); border: 2px solid var(--line); position: relative; z-index: 1; }
.updp-log .cur .updp-dot { background: var(--ok); border-color: var(--ok); box-shadow: 0 0 0 4px var(--ok-soft); }
.updp-log .next .updp-dot { background: var(--accent); border-color: var(--accent); box-shadow: 0 0 0 4px var(--accent-soft); }
.updp-log b { font-size: var(--fs-body); font-weight: 700; }
.updp-log small { display: block; color: var(--muted); font-size: var(--fs-detail); margin-top: 1px; }
.updp-log ul { margin: 6px 0 0; padding-left: 18px; font-size: var(--fs-sub); line-height: 1.45; }
.updp-tag { display: inline-block; margin-left: 8px; padding: 1px 8px; border-radius: 99px; background: var(--ok-soft); color: var(--ok); font-size: var(--fs-cap); font-weight: 700; vertical-align: 2px; }
.updp-tag.new { background: var(--accent-soft); color: var(--accent); }
.updp-empty { color: var(--muted); padding: 8px 0 12px; }
.updp-fb { display: grid; gap: 10px; padding: 14px; }
.updp-fb > * + * { border-top: 0 !important; }
.updp-moods { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; }
.updp-moods button { display: grid; justify-items: center; gap: 4px; padding: 10px 4px; min-height: 76px; border-radius: 14px; background: var(--surface-2); font-size: var(--fs-label); font-weight: 600; color: var(--muted); line-height: 1.2; transition: transform .15s var(--ease), background-color .2s, color .2s; }
.updp-moods button span { font-size: var(--fs-title); line-height: 1; transition: transform .3s var(--spring); }
.updp-moods button[aria-checked="true"] { background: var(--accent-soft); color: var(--accent); box-shadow: inset 0 0 0 2px var(--accent); }
.updp-moods button[aria-checked="true"] span { transform: scale(1.18); }
.updp-moods button:active { transform: scale(.95); }
.updp-fb textarea, .updp-fb input { width: 100%; padding: 12px 14px; border-radius: 12px; border: 1px solid var(--line); background: var(--bg); color: var(--text); font: inherit; font-size: var(--fs-body); resize: vertical; }
.updp-fb input { min-height: 48px; }
.updp-thanks { display: grid; justify-items: center; text-align: center; gap: 4px; padding: 18px 8px; animation: appear .4s var(--spring) both; }
.updp-thanks span { font-size: 38px; }
.updp-thanks small { color: var(--muted); font-size: var(--fs-sub); }

/* the support console's spinner (worker/public/support/support.css), for buttons that are waiting: Check for updates, Send */
.arcspin { display: inline-block; flex: none; width: 20px; height: 20px; animation: upd-rot 1.2s linear infinite; }
.arcspin circle { fill: none; stroke: currentColor; stroke-width: 5; stroke-linecap: round; }
.arcspin .trk { opacity: .16; }
.arcspin .arc { stroke-dasharray: 94, 200; transform-origin: 25px 25px; animation: arc-dash 1.2s cubic-bezier(.45, .05, .35, 1) infinite, arc-hue 2.4s ease-in-out infinite; }
@keyframes arc-dash { 0% { stroke-dasharray: 1, 200; stroke-dashoffset: 0; } 50% { stroke-dasharray: 94, 200; stroke-dashoffset: -16; } 100% { stroke-dasharray: 94, 200; stroke-dashoffset: -124; } }
@keyframes arc-hue { 0%, 100% { stroke: currentColor; } 50% { stroke: color-mix(in srgb, currentColor 70%, #FFB01C); } }
.updp-hero + .list { margin-top: 12px; }
/* Me: what needs you (an update waiting, a reply from GoSEQ Support) sits at the top */
.me-attn { margin: 4px 0 18px; box-shadow: var(--shadow), inset 0 0 0 2px var(--accent); animation: appear .4s var(--spring) both; }
.me-attn .item b { color: var(--accent); }
.updp-who { display: grid; grid-template-columns: 1fr; gap: 6px; }
.updp-who label { font-size: var(--fs-foot); font-weight: 700; color: var(--muted); margin-top: 2px; }
.updp-seen { margin: 0; padding: 10px 12px; border-radius: 12px; background: var(--accent-soft); color: var(--text); font-size: var(--fs-detail); line-height: 1.45; }
.updp-seen b { color: var(--accent); }

/* a trip's path on its page (accountui.js tripPath): the map, coloured by speed, and its key */
.trip-map { position: relative; height: 260px; border-radius: var(--radius, 18px); overflow: hidden; box-shadow: var(--shadow); margin-bottom: 8px; }
.trip-map.skel { display: block; }
.speed-key { display: flex; justify-content: space-between; gap: 4px 12px; flex-wrap: wrap; font-size: var(--fs-label); color: var(--muted); margin: 0 4px 12px; }
.speed-key .key-part { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
.speed-key .ramp { width: 70px; height: 8px; border-radius: 4px; }
.speed-key .key-line { width: 20px; height: 0; border-top: 4px solid #3987e5; }
.speed-key .key-line.dashed { border-top-style: dotted; margin-left: 6px; }
.trip-speeds b .unit { font-size: var(--fs-foot); font-weight: 700; color: var(--muted); }
.trip-speeds { margin-bottom: 12px; }
.trip-share { margin: 0 0 8px; }
.trip-share .btn { flex: 1; }
.resume-toast { position: fixed; left: 16px; right: 16px; bottom: calc(var(--nav-h) + var(--safe-bot) + 14px); z-index: 30; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 14px 16px; border-radius: 18px; background: var(--surface); color: var(--text); box-shadow: var(--shadow), 0 8px 30px rgba(0, 0, 0, .18); animation: appear .35s var(--ease) both; max-width: 520px; margin-inline: auto; }
.resume-toast > span { flex: 1 1 100%; }
.resume-toast .btn { flex: 1; }
/* a place in search results: the row plans a trip there, the map button just shows where it is */
.item-pair { display: flex; align-items: center; }
.item-pair > .item { flex: 1; min-width: 0; }
.item-pair > .iconbtn { margin-right: 6px; color: var(--accent); }
.mv-pin { position: absolute; left: 0; top: 0; width: 40px; height: 40px; margin: -38px 0 0 -20px; color: var(--accent); pointer-events: none; filter: drop-shadow(0 3px 4px rgba(0, 0, 0, .35)); }
.mv-pin .i { width: 40px; height: 40px; stroke-width: 2.4; fill: var(--surface); }
/* the stop whose times are open */
.mv-stop.sel { width: 22px; height: 22px; margin: -11px 0 0 -11px; background: var(--accent); border: 4px solid #fff; box-shadow: 0 0 0 4px rgba(196, 57, 31, .35), 0 2px 6px rgba(0, 0, 0, .35); z-index: 2; }
.mv-stop.sel::before { content: ""; position: absolute; inset: -8px; border-radius: 50%; border: 3px solid var(--accent); animation: selPulse 1.6s ease-out infinite; }
/* a stop's times: pick one route, and see later ones */
.stop-routes { display: flex; gap: 6px; overflow-x: auto; margin: 0 0 10px; padding: 2px; scrollbar-width: none; }
.stop-routes .chip { flex: none; }

/* ================= motion, round three: nothing changes without moving ================= */
/* desktop (the web app): everything you can click answers the pointer. Phones have no hover, so this is mouse-only. */
.btn, .link, .chip, .item, .dep, .opt, .iconbtn, .fab, .searchbar, .nav button, .day-leg, .fromrow { transition: transform .18s var(--spring), background-color .18s, box-shadow .2s, color .15s, opacity .15s; }
@media (hover: hover) and (pointer: fine) {
  .item:hover, .dep:hover, .opt:hover, .day-leg:hover, .fromrow:hover { background-color: color-mix(in srgb, var(--surface-2) 70%, transparent); }
  .btn:hover { transform: translateY(-1px); box-shadow: 0 4px 12px rgba(0, 0, 0, .12); }
  .btn.primary:hover { box-shadow: 0 6px 16px color-mix(in srgb, var(--accent) 35%, transparent); }
  .chip:hover, .fab:hover, .searchbar:hover { transform: translateY(-1px); box-shadow: 0 6px 16px rgba(0, 0, 0, .14); }
  .iconbtn:hover { background: var(--surface-2); }
  .iconbtn:hover .i, .nav button:hover .i { transform: scale(1.1); }
  .link:hover { opacity: .75; }
  .mv-marker:not(.sel):not(.you):hover { transform: translate(-50%, -50%) scale(1.08); z-index: 3; }
  .mv-stop:hover { transform: scale(1.25); }
  .item:hover > .i:last-child, .item:hover > svg.i:last-child, .opt:hover .opt-time { transform: translateX(2px); }
}
.item > .i:last-child, .opt-time { transition: transform .2s var(--spring); }
.mv-stop { transition: transform .15s var(--spring); }
.iconbtn .i, .nav button .i { transition: transform .2s var(--spring); }

/* opening things: a trip option, "All directions", a help answer */
.opt-body.opening { animation: appear .32s var(--ease) both; }
.opt-body.opening .steps li { animation: stepIn .4s var(--ease) both; }
.opt-body.opening .steps li:nth-child(2) { animation-delay: .05s; } .opt-body.opening .steps li:nth-child(3) { animation-delay: .1s; } .opt-body.opening .steps li:nth-child(n+4) { animation-delay: .15s; }
.opt-body.opening .actions .btn { animation: pop .4s .12s var(--spring) both; }
.opt .opt-time { display: inline-block; }
details.opening[open] > :not(summary) { animation: appear .28s var(--ease) both; }   /* motion.js: only when you open it, not when a redraw rebuilds it open */
.walk-dir summary::after { content: ""; width: 8px; height: 8px; margin-left: 8px; border: solid currentColor; border-width: 0 2px 2px 0; transform: rotate(45deg) translateY(-2px); transition: transform .25s var(--spring); }
.walk-dir[open] summary::after { transform: rotate(225deg) translateY(-2px); }

/* Leave now / Leave at / Arrive by: the one you pick springs in */
.seg button.picked { animation: pop .35s var(--spring); }

/* departures: minutes roll as they count down (ui.js roll) */
.mins .roll { display: inline-block; }

/* the map: a dropped pin, the open stop, a stop's route chips and its later times */
.mv-pin:not([hidden]) { animation: pinDrop .5s var(--spring) both; transform-origin: 50% 100%; }
@keyframes pinDrop { 0% { opacity: 0; transform: translateY(-40px) scale(.6); } 60% { opacity: 1; transform: translateY(2px) scale(1.05, .92); } 100% { transform: none; } }
.mv-pin::after { content: ""; position: absolute; left: 50%; bottom: -2px; width: 14px; height: 5px; margin-left: -7px; border-radius: 50%; background: rgba(0, 0, 0, .25); animation: pinShadow .5s var(--spring) both; }
@keyframes pinShadow { from { transform: scale(.2); opacity: 0; } }
.mv-stop.sel { animation: stopSel .4s var(--spring) both; }
@keyframes stopSel { from { transform: scale(.5); } }
.stop-routes .chip { animation: appear .3s var(--spring) both; }
.stop-routes .chip:nth-child(2) { animation-delay: .03s; } .stop-routes .chip:nth-child(3) { animation-delay: .06s; } .stop-routes .chip:nth-child(4) { animation-delay: .09s; } .stop-routes .chip:nth-child(n+5) { animation-delay: .12s; }
.stop-routes.still .chip { animation: none; }
.stop-routes .chip[aria-pressed="true"] { transition: background-color .2s, color .2s; }
.dep.arrive { animation: appear .32s var(--ease) both; }
.list.swap > * { animation: appear .28s var(--ease) both; }
.list.swap > :nth-child(2) { animation-delay: .03s; } .list.swap > :nth-child(3) { animation-delay: .06s; } .list.swap > :nth-child(4) { animation-delay: .09s; } .list.swap > :nth-child(n+5) { animation-delay: .12s; }
.item-pair > .iconbtn:active .i { transform: scale(.85); }
.walk-dir summary { list-style: none; } .walk-dir summary::-webkit-details-marker { display: none; }
/* the map sheet's grip is a button: tap or arrow keys to resize it */
.sheet .grip { width: 100%; border: 0; background: none; color: inherit; font: inherit; -webkit-tap-highlight-color: transparent; }
.sheet .grip:focus-visible { outline: none; }
.sheet .grip:focus-visible::before { background: var(--accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 35%, transparent); }
/* bus markers leaving the map (scale:, since transform centres them) */
.mv-marker.leaving { pointer-events: none; animation: mvLeave .2s var(--ease) both; }
@keyframes mvLeave { to { opacity: 0; scale: .6; } }
/* the "Route 199 only" pill leaving */
#m-route.leaving { pointer-events: none; animation: pillLeave .2s var(--ease) both; }
@keyframes pillLeave { to { opacity: 0; transform: translateY(-8px) scale(.94); } }

/* Home-screen widgets (widgets.js): a phone home screen with your real next bus drawn as the widget — on Home
   (the "Put your next bus on your home screen" card), in Me → Widgets, and in the intro */
.wg-screen { position: relative; display: grid; grid-template-columns: minmax(0, 1fr); gap: 12px; padding: 16px 14px; border-radius: 22px; overflow: hidden; background: linear-gradient(150deg, #FF9152, #F0513E 55%, #7A1F45); box-shadow: var(--shadow); }
.wg-apps { display: grid; gap: 14px; padding: 0 6px; }
.wg-apps i { aspect-ratio: 1; border-radius: 26%; background: rgba(255, 255, 255, .28); }
.wg-widget { background: var(--surface); color: var(--text); border-radius: 18px; padding: 12px 14px; box-shadow: 0 8px 24px rgba(0, 0, 0, .22); text-align: left; animation: wgPop .6s .15s var(--spring, ease) both; }
.wg-top { display: flex; align-items: center; gap: 6px; font-size: var(--fs-cap); color: var(--muted); white-space: nowrap; }
.wg-badge { padding: 2px 7px; border-radius: 7px; background: var(--accent); color: var(--on-accent); font-weight: 800; font-size: var(--fs-cap); }
.wg-dest { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.wg-big { margin-top: 4px; font-size: var(--fs-title3); font-weight: 800; letter-spacing: -.01em; }
.wg-big em { font-style: normal; color: var(--accent); }
.wg-sub { font-size: var(--fs-label); color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
@keyframes wgPop { from { opacity: 0; transform: translateY(10px) scale(.9); } }
@media (prefers-reduced-motion: reduce) { .wg-widget { animation: none; } }
/* the one on Home: a strip of home screen (the widget above a row of apps), then the words and the button */
.wg-screen { --app: 44px; }
.wg-apps { grid-template-columns: repeat(4, var(--app)); justify-content: space-between; }
.wg-screen.small { --app: 34px; gap: 10px; padding: 14px 16px 12px; border-radius: 18px; }
.wg-screen.small .wg-apps:first-child, .wg-screen.small .wg-arr { display: none; }
.wg-nudge { position: relative; margin-top: 12px; padding: 14px; }
.wg-nudge .wg-copy { position: relative; padding: 14px 4px 2px; }
.wg-nudge .wg-copy b { display: block; padding-right: 36px; font-size: var(--fs-row); line-height: 1.25; }
.wg-nudge .wg-copy small { display: block; margin: 4px 0 12px; font-size: var(--fs-sub); color: var(--muted); }
.wg-nudge .btn { width: 100%; }
.wg-x { position: absolute; top: 6px; right: -6px; width: 40px; height: 40px; color: var(--muted); }
/* the sheet */
.wg-sheet .wg-screen { margin: 4px 0 16px; }
.wg-lede { margin: 0 2px 16px; color: var(--muted); }
.note.ok { background: var(--ok-soft); } .note.ok > .i { color: var(--ok); }
.wg-steps { margin: 0 0 8px; padding: 0; list-style: none; counter-reset: wg; display: grid; gap: 12px; }
.wg-steps li { counter-increment: wg; display: flex; gap: 12px; align-items: flex-start; font-size: var(--fs-sub); }
.wg-steps li::before { content: counter(wg); flex: none; display: grid; place-items: center; width: 26px; height: 26px; border-radius: 50%; background: var(--accent-soft); color: var(--accent); font-weight: 800; font-size: var(--fs-sub); }
.wg-lock { margin: 10px 2px 0; }
.in-widget { width: min(320px, 86vw); }
.in-slide:not(.active) .in-widget .wg-widget { animation: none; opacity: 0; }
/* waiting on GoSEQ's servers (accountui.js cloudSpinner): the spinner circling a cloud */
.cloud-spin { position: relative; display: inline-grid; place-items: center; flex: none; }
.cloud-spin > .i { position: absolute; color: var(--accent); }
.srv-wait { display: flex; align-items: center; gap: 14px; }
/* opening Me while signed in (me.js coverWhile): "downloading your info" over the page, above everything but the tabs */
#me-cover { position: fixed; left: 0; right: 0; top: 0; bottom: calc(var(--nav-h) + var(--safe-bot)); z-index: 15; background: var(--bg); display: grid; place-content: center; justify-items: center; gap: 6px; padding: 24px; text-align: center; transition: opacity .25s var(--ease); }
#me-cover .cloud-spin { margin-bottom: 14px; }
#me-cover .cloud-spin .spinner { width: 64px; height: 64px; }
#me-cover .cloud-spin > .i { width: 26px; height: 26px; }
#me-cover h2 { margin: 0; }
#me-cover p { margin: 0; }
#me-cover.out { opacity: 0; pointer-events: none; }

/* ---------- live trip: "Take a later one" (later.js) ---------- */
/* low-key: a small chip under the instruction, never competing with "I'm on the 60" */
.later-chip { box-shadow: none; background: var(--surface-2); min-height: 40px; font-size: var(--fs-sub); margin: -6px 0 12px; color: var(--text); }
.later-chip .i { color: var(--accent); }
/* a bottom sheet over the trip (the trip stays in sight above it), not a whole new page */
.overlay.later-sheet { top: auto; max-height: 82%; border-radius: 22px 22px 0 0; background: var(--surface); box-shadow: 0 0 0 100vmax rgba(0, 0, 0, .38), var(--shadow-up); }
.later-sheet .overlay-top { padding-top: 12px; }
.later-sheet .overlay-body { padding-bottom: calc(20px + var(--safe-bot)); }
.later-intro { margin: 0 0 12px; }
.later-list { box-shadow: none; background: var(--surface-2); }
.later-row { gap: 12px; align-items: center; }
.later-row + .later-row { border-top: 1px solid var(--line); }
.later-when { flex: none; display: flex; flex-direction: column; align-items: flex-end; text-align: right; }
.later-when b { display: block; white-space: nowrap; font-size: var(--fs-title3); font-weight: 800; line-height: 1.1; font-variant-numeric: tabular-nums; }
.later-when b small { font-size: var(--fs-foot); font-weight: 700; }
.later-when small { font-size: var(--fs-foot); color: var(--muted); font-variant-numeric: tabular-nums; }
.later-badges { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; margin-bottom: 3px; }
.later-row .grow small b.in { display: inline; font-size: inherit; color: var(--text); font-weight: 700; }
.later-cost { font-weight: 700; } .later-cost.ok { color: var(--ok); } .later-cost.warn { color: var(--warn); } .later-cost.bad { color: var(--bad); }
.later-note { color: var(--text) !important; }
.later-foot { margin: 10px 2px 0; }

/* ---------- live trip: which way the bus comes from (compass.js) ---------- */
.compass { display: flex; align-items: center; gap: 12px; margin: -4px 0 12px; }
.compass .grow { min-width: 0; }
.compass b { display: block; font-size: var(--fs-sub); font-weight: 700; line-height: 1.3; }
.compass small { display: block; font-size: var(--fs-sub); color: var(--muted); line-height: 1.35; }
.compass .link { padding: 4px 0 0; font-size: var(--fs-sub); }
/* a dial the size of a thumb: a ring for "north-ish doesn't matter", the arrow is all there is to read */
.compass-dial { flex: none; width: 52px; height: 52px; border-radius: 50%; display: grid; place-items: center; background: var(--accent-soft); color: var(--accent); box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--accent) 35%, transparent); }
.compass-arrow { width: 34px; height: 34px; display: grid; place-items: center; transition: transform .15s linear; will-change: transform; }
.compass-arrow svg { width: 34px; height: 34px; fill: var(--accent); stroke: var(--surface); stroke-width: 1.2; stroke-linejoin: round; }
.compass.words .compass-dial { width: 40px; height: 40px; background: var(--surface-2); color: var(--text); box-shadow: none; }
.compass.words b { font-weight: 600; }
@media (prefers-reduced-motion: reduce) { .compass-arrow { transition: none; } }

/* ---------- live trip map: the stop that matters now, flagged with the number on its sign ---------- */
.mv-marker.stopflag { flex-direction: column; gap: 0; height: auto; min-width: 40px; padding: 3px 7px 4px; border-radius: 8px; background: var(--accent); color: var(--on-accent); font-size: var(--fs-row); font-weight: 900; line-height: 1; font-variant-numeric: tabular-nums; transform: translate(-50%, calc(-100% - 14px)); box-shadow: 0 2px 8px rgba(0, 0, 0, .3); z-index: 2; pointer-events: none; }
.mv-marker.stopflag small { font-size: 8px; font-weight: 800; letter-spacing: .1em; margin-bottom: 2px; }
.mv-marker.stopflag::before { content: ""; position: absolute; left: 50%; bottom: -6px; margin-left: -6px; border: 6px solid transparent; border-bottom: 0; border-top-color: var(--accent); }
.mv-marker.stopflag.off { background: var(--text); color: var(--bg); } .mv-marker.stopflag.off::before { border-top-color: var(--text); }
.mv-marker.stopflag.word { font-size: var(--fs-foot); white-space: nowrap; } /* a street, not a number: "STOP · Settlement Rd" */
.later-when b small { display: inline; font-size: var(--fs-sub); color: inherit; }

/* ---------- the trip card (ride.js), October 2026 ---------- */
/* the first line: what's happening, the speed, and the moment's "Big view"; it's part of the handle (drag it, or tap
   it to open the details) */
.ride-now .phase-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; min-height: 36px; }
.ride-now .phase-row .phase { min-width: 0; }
.ride-sheet:not(.open) .phase-row { touch-action: none; cursor: grab; }
/* the handle: a taller strip, the bar, and "More" so it's plain there's more */
.ride-grip { height: 30px; position: relative; }
.ride-grip::after { content: ""; position: absolute; left: 0; right: 0; top: -14px; height: 44px; }   /* a 44 px target without a taller card */
.ride-grip .grip-bar { width: 52px; height: 5px; border-radius: 3px; background: color-mix(in srgb, var(--text) 32%, transparent); transition: background .15s; }
.ride-grip:active .grip-bar { background: var(--accent); }
.ride-grip .grip-more { white-space: nowrap; position: absolute; right: 16px; top: 50%; transform: translateY(-50%); width: auto; height: auto; display: inline-flex; align-items: center; gap: 4px; padding: 3px 10px; border-radius: 99px; background: var(--surface-2); color: var(--text); font-size: var(--fs-cap); font-weight: 700; }
.ride-grip .grip-more::after { content: "↑"; font-weight: 800; }
.ride-sheet.open .ride-grip .grip-more::after { content: "↓"; }
.ride-grip[hidden] .grip-more { display: none; }
/* the small card: what doesn't fit goes behind "More", never half under the buttons (fitCard) */
.ride-sheet:not(.open) .ride-now > .tucked { display: none; }
.ride-sheet:not(.open) .ride-panel .actions::before { display: none; }
/* "I'm off the 60" */
.ride-panel .actions .off-btn { gap: 8px; }
/* Share, top right of the map */
.map-top .grow { flex: 1; }
.share-fab { width: auto; padding: 0 16px 0 13px; gap: 7px; display: inline-flex; align-items: center; font-weight: 700; font-size: var(--fs-sub); color: var(--text); }
.share-fab .i { width: 20px; height: 20px; color: var(--accent); }
/* Check my stop, as an invitation the first time at a stop */
.check-invite { display: flex; align-items: center; gap: 10px; margin: -2px 0 12px; padding: 8px 6px 8px 10px; border-radius: 16px; background: var(--accent-soft); color: var(--text); cursor: pointer; }
.check-invite .ci-ico { flex: none; width: 36px; height: 36px; border-radius: 12px; display: grid; place-items: center; background: var(--surface); color: var(--accent); }
.check-invite .ci-ico .i { width: 22px; height: 22px; }
.check-invite b { display: block; font-size: var(--fs-sub); } .check-invite small { display: block; font-size: var(--fs-detail); color: var(--text); opacity: .8; }
.check-invite .btn.sm { min-height: 44px; }
.check-invite .ci-x { width: 36px; height: 36px; color: var(--muted); position: relative; }
.check-invite .ci-x::after, .act-row > .chip::after, .ride-now .mo-pill::after { content: ""; position: absolute; inset: -4px; }   /* 44 px to tap, the same size to look at */
.act-row > .chip, .ride-now .mo-pill { position: relative; }
/* a narrow phone: the invitation is its question and the button (three lines of it pushed the chips under the buttons) */
@media (max-width: 379px) { .ride-now .check-invite small { display: none; } }
/* Walk 13 min · Uber · Lime */
.alts { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin: 0 0 12px; font-size: var(--fs-sub); }
.alts-l { display: inline-flex; align-items: center; gap: 6px; font-weight: 700; color: var(--text); margin-right: 2px; }
.alts-l .i { color: var(--accent); }
.alts .alt { display: inline-flex; align-items: center; min-height: 38px; padding: 0 14px; border-radius: 999px; background: var(--surface-2); color: var(--text); font-weight: 700; text-decoration: none; }
/* hazard lights: the bus has been stopped over 30 s */
.mv-marker .mv-hz { position: absolute; top: 50%; width: 9px; height: 9px; margin-top: -4.5px; border-radius: 50%; background: #FFB000; box-shadow: 0 0 0 2px #fff, 0 0 10px 3px rgba(255, 176, 0, .75); animation: mv-hz 1.3s steps(1, end) infinite; pointer-events: none; }
.mv-marker .mv-hz.l { left: -9px; } .mv-marker .mv-hz.r { right: -9px; }
@keyframes mv-hz { 50% { opacity: .15; box-shadow: 0 0 0 2px #fff; } }
@media (prefers-reduced-motion: reduce) { .mv-marker .mv-hz { animation: none; } }
.ride-sheet:not(.open) .jb.jb-short .jb-next { display: none; }
/* Find stop · Check my stop · Take a later one: one row that scrolls sideways */
.act-row { display: flex; align-items: center; gap: 8px; overflow-x: auto; margin: -6px -18px 12px; padding: 2px 18px; scrollbar-width: none; touch-action: pan-x; overscroll-behavior-x: contain; }
.act-row::-webkit-scrollbar { display: none; }
.act-row > * { flex: none; margin: 0 !important; }
.act-row .check-invite { max-width: 320px; padding: 6px 4px 6px 8px; gap: 8px; }
.act-row .check-invite b { font-size: var(--fs-sub); } .act-row .check-invite small { font-size: var(--fs-label); }
/* The word STOP on a stop-number badge takes the badge's own ink (--on-accent, picked to read on your colour, light or
   dark), never a grey handed down by whatever the badge sits in (.walk-head small, .item small, .dep small made it
   --muted: dark grey on the blue). */
.stop-chip.stop-chip small, .fs-chip.fs-chip small, .mo-chip.mo-chip small, .jb-chip.jb-chip small, .mv-marker.stopflag small { color: inherit; opacity: 1; }
.stop-chip.stop-chip small { display: block; margin-top: 0; line-height: 1; white-space: nowrap; overflow: visible; -webkit-line-clamp: unset; }
/* Full screen on/off, in the sheet's top row (left of the handle; More/Less is on the right) */
.ride-full { position: absolute; left: 12px; top: 4px; z-index: 2; display: inline-flex; align-items: center; gap: 4px; height: 24px; padding: 0 10px 0 8px; border-radius: 99px; background: var(--surface-2); color: var(--text); font-size: var(--fs-cap); font-weight: 700; white-space: nowrap; }
.ride-full::after { content: ""; position: absolute; left: -8px; right: -8px; top: -12px; height: 44px; }   /* 44 px to tap */
/* a card with no details ("Are you on it?"): the handle's row is kept (invisible) for this button, as the rule further
   down means to; the global [hidden] { display: none !important } won, so the button sat on the card's first line
   ("YOUR 60 HAS LEFT …") */
.ride-sheet > .ride-grip[hidden] { display: block !important; visibility: hidden; }
.ride-full .i { width: 14px; height: 14px; flex: none; }
.ride-full[data-on="1"] { background: var(--accent-soft); box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--accent) 55%, transparent); }
.ride-full:active { background: var(--accent); color: var(--on-accent); }
.ride-sheet .ride-grip[hidden] { height: 30px; }   /* (screens with no details keep the row, for Full screen) */
/* 44 px to tap, the same size to look at (as the trip card's chips above): small buttons, the routine card's controls,
   the big-view pills, Uber/Lime, Search's example asks and the Ask sheet's chips */
.h-kick .iconbtn.sm, .h-next button, .btn.sm, .mo-pill, .alts .alt, .ask-ex button, .ak-chip { position: relative; }
.h-kick .iconbtn.sm::after, .h-next button::after, .btn.sm::after, .mo-pill::after, .alts .alt::after, .ask-ex button::after, .ak-chip::after { content: ""; position: absolute; inset: -4px; }
.h-kick .iconbtn.sm::after { inset: -6px; } .btn.sm::after, .alts .alt::after { inset: -3px; } .ask-ex button::after, .ak-chip::after { inset: -2px; }
/* Toasts clear of the buttons: over a full-screen moment, Find my stop or Check my stop they sat on the main button
   ("You're at the stop" over "Check my stop"); on the trip screen they show over the map, under its top buttons. */
body:has(> .mo:not(.closing), > .fs, > .cs) #toast { bottom: calc(var(--safe-bot) + 132px); }
body:has(#r-sheet):not(:has(> .mo:not(.closing), > .fs, > .cs)) #toast { bottom: auto; top: calc(var(--safe-top) + 72px); transform: translateY(-10px); }
body:has(#r-sheet):not(:has(> .mo:not(.closing), > .fs, > .cs)) #toast.show { transform: translateY(0); animation-name: toastInTop; }
@keyframes toastInTop { from { transform: translateY(-30px) scale(.9); } }

/* ================= sign-in screens =================
   Sign in, forgot password, the sign-in code and create-account onboarding, in the style of the support console's
   sign-in: a letter-spaced overline, a big two-line headline, a muted lead, labelled roomy fields, a dark full-width
   button with a trailing arrow, an "or" divider and a small lock note. Theme tokens only, so light and dark both work. */
.si-page { max-width: 440px; margin: 0 auto; padding: 18px 4px 32px; }
.si-mark { margin: 0 0 18px; }
.si-mark .ob-art { max-width: 220px; display: block; }
.si-over { margin: 0 0 12px; color: var(--accent); font-size: var(--fs-cap); font-weight: 750; letter-spacing: .16em; text-transform: uppercase; line-height: 1.4; }
.si-title { margin: 0 0 12px; color: var(--text); font-size: 36px; font-weight: 750; line-height: 1.1; letter-spacing: -.045em; text-wrap: balance; }
.si-lead { margin: 0 0 26px; color: var(--muted); font-size: var(--fs-body); line-height: 1.55; } .si-lead b { color: var(--text); }
.si-label { display: block; margin: 16px 0 8px; color: var(--text); font-size: var(--fs-sub); font-weight: 650; }
.si-label:first-child { margin-top: 0; }
.si-input { display: block; width: 100%; min-height: 54px; padding: 14px 16px; border: 1px solid color-mix(in srgb, var(--text) 18%, transparent); border-radius: 14px; background: var(--surface); color: var(--text); font-size: var(--fs-row); transition: border-color .15s, box-shadow .15s; }
.si-input::placeholder { color: var(--muted); opacity: .8; }
.si-input:focus, .si-input:focus-visible { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 35%, transparent); }
.si-input.bad { border-color: var(--bad); color: var(--bad); }
.si-pw { position: relative; }
.si-pw .si-input { padding-right: 56px; }
.si-eye { position: absolute; right: 5px; top: 50%; transform: translateY(-50%); width: 44px; height: 44px; display: grid; place-items: center; border-radius: 10px; color: var(--muted); }
.si-eye:active { background: var(--surface-2); }
.si-eye svg { width: 20px; height: 20px; }
.si-eye .si-eye-off { display: none; } .si-eye[aria-pressed="true"] .si-eye-on { display: none; } .si-eye[aria-pressed="true"] .si-eye-off { display: block; }
.si-page .err { margin: 12px 2px 0; }
/* the dark ink button: near-black on the light theme, near-white on the dark one (var(--text) on var(--bg)), so the
   label and a busy spinner (spinner('light') draws in currentColor) keep strong contrast in both */
.btn.si-go { width: 100%; min-height: 54px; margin-top: 22px; border-radius: 14px; background: var(--text); color: var(--bg); font-size: var(--fs-body); font-weight: 700; box-shadow: 0 6px 16px color-mix(in srgb, var(--text) 16%, transparent); transition: transform .15s, box-shadow .15s; }
.btn.si-go::after { content: "→"; font-weight: 600; margin-left: 2px; transition: transform .2s var(--ease, ease); }
.btn.si-go:active::after { transform: translateX(3px); }
.btn.si-go:disabled { cursor: progress; }
.btn.si-go:disabled::after { content: none; }
.btn.si-go .spinner.light { width: 20px; height: 20px; }
.btn.si-go:focus-visible { outline: 3px solid var(--accent); outline-offset: 3px; }
.si-links { display: flex; flex-wrap: wrap; gap: 6px 20px; margin: 14px 2px 0; }
.si-links .link:disabled { color: var(--muted); opacity: 1; }
.si-or { display: flex; align-items: center; gap: 12px; margin: 24px 0 14px; color: var(--muted); font-size: var(--fs-sub); }
.si-or::before, .si-or::after { content: ""; flex: 1; height: 1px; background: var(--line); }
.btn.si-alt { width: 100%; min-height: 52px; border-radius: 14px; background: var(--surface); color: var(--text); border: 1px solid color-mix(in srgb, var(--text) 14%, transparent); font-size: var(--fs-body); font-weight: 650; }
.si-note { display: flex; gap: 8px; align-items: flex-start; margin: 24px 2px 0; color: var(--muted); font-size: var(--fs-foot); line-height: 1.5; }
.si-note .i { width: 16px; height: 16px; flex: none; margin-top: 1px; }
.si-small { margin: 14px 2px 0; color: var(--muted); font-size: var(--fs-sub); line-height: 1.5; }
.si-page .code-in { margin: 4px 0 6px; max-width: 380px; }
.si-page .check-row { margin-top: 14px; }
/* onboarding panes use the same type */
.ob-pane.si-page { padding-top: 14px; }
.ob-pane .ob-meter { margin-top: 10px; }
@media (max-width: 360px) { .si-title { font-size: var(--fs-title); } }
@media (prefers-reduced-motion: reduce) { .si-input, .btn.si-go, .btn.si-go::after { transition: none; } .btn.si-go:active::after { transform: none; } }
/* the sign-in sheet's name field is hidden when signing in: the email label then opens the form */
.si-page form > [hidden]:first-child + .si-label { margin-top: 0; }
.si-page form > .si-label:first-child { margin-top: 0; }
.si-page .ob-free { margin: 10px 0 0; }
.si-page .ob-perks { margin: 14px 0 20px; }
.si-page .ob-preview { margin: 14px 2px 4px; }

/* ---- 3.9.20: sign in, email first (accountui openAuth) ---- */
.si-step.in-right { animation: obInR .36s var(--spring) both; } .si-step.in-left { animation: obInL .36s var(--spring) both; }
/* the hand-off: the full-width button shrinks into a round arc spinner (motion.js spinner, the app's Material arc) */
.btn.si-go { transition: transform .15s, box-shadow .15s, width .32s var(--ease, ease), border-radius .32s var(--ease, ease), padding .32s; }
.btn.si-go.si-morph { display: flex; width: 54px; padding: 0; margin-left: auto; margin-right: auto; border-radius: 27px; }
.btn.si-go.si-morph .spinner.light { width: 24px; height: 24px; }
/* step 2: whose account (this phone's memory only), the email as a chip with "Not you?" */
.si-face { margin: 0 0 16px; line-height: 0; } .si-face .avatar { box-shadow: 0 0 0 4px var(--accent-soft); }
.si-chip { display: inline-flex; align-items: center; gap: 4px; max-width: 100%; margin: 4px 0 6px; padding: 4px 4px 4px 14px; border-radius: 999px; border: 1px solid color-mix(in srgb, var(--text) 14%, transparent); background: var(--surface); font-size: var(--fs-sub); }
.si-chip-mail { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text); font-weight: 600; }
.si-chip-x { flex: none; min-height: 36px; padding: 0 12px; border-radius: 999px; color: var(--accent); font-weight: 700; font-size: var(--fs-sub); position: relative; }
.si-chip-x::after { content: ""; position: absolute; inset: -4px 0; }
.si-chip-x:active { background: var(--surface-2); }
.si-hide { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; overflow: hidden; }
.si-steps { position: relative; }
/* reduced motion: no slide or shrink (the global rule), and the busy arc stays an arc rather than a dot */
@media (prefers-reduced-motion: reduce) { .si-page .spinner circle, .si-go .spinner circle { stroke-dasharray: 89, 200; stroke-dashoffset: -35; } }

/* ---- 3.9.20: onboarding's welcome, sign-in always in reach ---- */
/* "Sign in" in the top bar, beside the ✕ (every step until the code is sent) */
.ob-top-signin { flex: none; min-height: 44px; padding: 0 8px; font-size: var(--fs-body); font-weight: 700; }
/* short phones: tighter, a smaller picture, so "Let's go" and "I already have an account" both show without scrolling */
@media (max-height: 940px) {
  .ob-welcome.si-page { padding-top: 4px; padding-bottom: 16px; }
  .ob-welcome .si-mark { margin-bottom: 10px; } .ob-welcome .si-mark .ob-art { max-width: 160px; }
  .ob-welcome .si-over { margin-bottom: 6px; }
  .ob-welcome .si-title { font-size: var(--fs-title); margin-bottom: 8px; }
  .ob-welcome .si-lead { font-size: var(--fs-sub); }
  .ob-welcome .ob-perks { margin: 8px 0 14px; } .ob-welcome .ob-perks li { padding: 7px 0; gap: 12px; }
  .ob-welcome .ob-perks b { font-size: var(--fs-sub); } .ob-welcome .ob-perks li > span:last-child { font-size: var(--fs-sub); line-height: 1.4; }
  .ob-welcome .si-or { margin: 10px 0 8px; }
  .ob-welcome .ob-skip { margin-top: 4px !important; }
}
@media (max-height: 760px) {
  .ob-welcome .si-mark .ob-art { max-width: 120px; }
  .ob-welcome .si-title { font-size: var(--fs-title); }
  .ob-welcome .ob-perks li { padding: 5px 0; }
  .ob-welcome .ob-perks li > span:last-child { font-size: var(--fs-detail); }
  .ob-welcome .btn.si-go, .ob-welcome .btn.si-alt { min-height: 48px; }
}
@media (max-height: 680px) {
  .ob-welcome .si-mark { display: none; }
  .ob-welcome .si-title { font-size: var(--fs-title); }
  .ob-welcome .si-lead { font-size: var(--fs-sub); } .ob-welcome .ob-free { font-size: var(--fs-detail); line-height: 1.4; margin-top: 6px; }
  .ob-welcome .ob-perks { margin: 6px 0 10px; } .ob-welcome .ob-perks li { padding: 4px 0; }
  .ob-welcome .ob-perks li > span:last-child { font-size: var(--fs-foot); line-height: 1.35; }
  .ob-welcome .btn.si-go, .ob-welcome .btn.si-alt { min-height: 46px; }
  .ob-welcome .si-or { margin: 8px 0 6px; }
}

/* ---- 3.9.20: a code being checked (codeinput.js busy): dimmed boxes, the arc and "Checking…" under them ---- */
.code-in.busy .code-cells { opacity: .55; transition: opacity .2s; }
.code-wait { display: flex; align-items: center; justify-content: center; gap: 10px; margin: 14px 0 4px; max-width: 380px; color: var(--text); font-size: var(--fs-sub); font-weight: 650; animation: appear .2s var(--ease) both; }
.code-wait .spinner.light { width: 26px; height: 26px; color: color-mix(in srgb, var(--accent) 72%, var(--text)); }
.si-page .code-wait { justify-content: flex-start; }
@media (prefers-reduced-motion: reduce) { .code-wait .spinner circle { stroke-dasharray: 89, 200; stroke-dashoffset: -35; } }
/* the "You're all set" screen's one choice: Show which bus is coming */
.ob-done .ob-pref { width: 100%; margin: 18px 0 4px; text-align: left; }
.ob-done .ob-pref small { line-height: 1.4; }
/* the arc starts part-way through its grow-and-shrink, so it is a clear 3/4 arc from the first frame, not a dot */
.btn.si-go .spinner circle, .code-wait .spinner circle { animation-delay: -.55s; }
.btn.si-go .spinner, .code-wait .spinner { animation-delay: -.3s; }

/* Phone sign-in: each step enters smoothly; the same Material arc stays in the
   action button while an SMS, verification or profile save is in flight. */
.ph-flow .ph-pane.ph-in { animation: ph-enter .24s var(--ease) both; }
@keyframes ph-enter { from { opacity: 0; transform: translateY(8px); } }
.ph-flow .ph-action { display: flex; align-items: center; justify-content: center; gap: 9px; margin-top: 14px; }
.ph-flow .ph-action .spinner { width: 20px; height: 20px; }
.ph-flow .ph-action:disabled { opacity: .82; }
.btn[aria-busy="true"] { display: flex; align-items: center; justify-content: center; gap: 9px; }
.btn[aria-busy="true"] .spinner { width: 20px; height: 20px; }
.ph-flow #ph-code { margin: 18px 0 8px; }
.ph-flow .si-links { margin-top: 16px; }
.ph-success { text-align: center; padding: 18px 0 8px; }
.ph-success svg { width: 54px; height: 54px; fill: none; stroke: var(--accent); stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; }
.ph-success circle { stroke-dasharray: 145; }
.ph-success path { stroke-dasharray: 36; }
.ph-success .si-title { margin: 10px 0 4px; }
.ph-success p { color: var(--muted); }
@media (prefers-reduced-motion: no-preference) {
  .ph-success circle { animation: ph-draw .35s ease-out both; }
  .ph-success path { animation: ph-draw .25s .18s ease-out both; }
  @keyframes ph-draw { from { stroke-dashoffset: 150; } to { stroke-dashoffset: 0; } }
}
@media (prefers-reduced-motion: reduce) {
  .ph-flow .ph-pane.ph-in, .ph-success circle, .ph-success path { animation: none; stroke-dashoffset: 0; }
  .ph-flow .spinner circle, .btn[aria-busy="true"] .spinner circle { stroke-dasharray: 89, 200; stroke-dashoffset: -35; }
}

/* ---- "How do you get to the bus?" in a routine, and the stop picker (dropoff.js, 3.9.22) ---- */
.ac-seg button { flex: 1 1 auto; white-space: nowrap; font-size: var(--fs-detail); padding: 0 10px; }
@media (max-width: 370px) { .ac-seg button { font-size: var(--fs-sub); padding: 0 8px; } }
.ac-sub { margin: 14px 4px 8px; font-size: var(--fs-foot); font-weight: 600; color: var(--muted); }
.ac-stop { margin-top: 8px; border-radius: 14px; background: var(--surface); box-shadow: var(--shadow); overflow: hidden; }
.ac-stop .item { min-height: 60px; }
.ac-stop.ac-in { animation: appear .32s var(--ease) both; }
.ac-note { display: flex; gap: 8px; align-items: flex-start; margin: 12px 4px 4px; line-height: 1.4; }
.ac-note .i { width: 16px; height: 16px; flex: none; margin-top: 2px; color: var(--accent); }
.ds-lead { margin: 0 4px 12px; line-height: 1.4; }
.ds-field { margin-bottom: 4px; }
.ds-list .item { align-items: flex-start; padding-top: 14px; padding-bottom: 14px; }
.ds-list .item > .i { margin-top: 4px; }
.ds-list .item.on b { color: var(--accent); }
.ds-routes { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; align-items: center; }
.ds-routes .badge { height: 24px; min-width: 38px; font-size: var(--fs-foot); border-radius: 7px; }
.ds-r { display: inline-flex; align-items: center; gap: 0; border-radius: 9px; }
.ds-r em { font-style: normal; font-size: var(--fs-label); font-weight: 800; letter-spacing: .02em; padding: 0 7px 0 6px; color: var(--accent); }
.ds-r.ex, .ds-r.sc { background: color-mix(in srgb, var(--accent) 12%, transparent); box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--accent) 45%, transparent); }
.ds-more { font-size: var(--fs-foot); font-weight: 700; color: var(--muted); }
.ds-wait .spinner { width: 18px; height: 18px; }
.ds-loading { display: flex; flex-direction: column; align-items: center; gap: 12px; padding: 40px 0; color: var(--muted); font-weight: 600; animation: appear .3s var(--ease) both; }
.ds-more-loading { display: flex; justify-content: center; padding: 14px 0; }
.ds-empty { margin: 18px 4px; line-height: 1.45; }
.ds-first { animation: appear .28s var(--ease) both; }
.s-way { margin-bottom: 14px; }
.setup .row > .field { min-width: 0; }
.s-way-stop { margin-top: 8px; border-radius: 14px; background: var(--surface-2); min-height: 60px; }
.s-way-stop.ac-in { animation: appear .32s var(--ease) both; }

/* a marker that appears while the map follows a bus doesn't pop in (it'd flash at the edges) */
.mv-marker.nopop { animation: none; }
/* a marker that has popped in (or came in quietly) still fades out when it goes: .nopop came later in this file and
   cancelled the fade, so those blinked out instead */
.mv-marker.nopop.leaving { animation: mvLeave .2s var(--ease) both; }
/* a stop dot pops in once, not again each time the Map tab is shown */
.mv-stop.nopop:not(.sel) { animation: none; }
/* a bus driving empty to the start of its run (mapscreen.js): outlined, not filled */
.mv-marker.pos { background: var(--surface, #fff); color: var(--c, #121A18); border: 2px dashed var(--c, #121A18); box-shadow: 0 1px 4px rgba(0, 0, 0, .18); opacity: .9; }
.mv-marker.pos.sel { opacity: 1; }
.v-pos { margin: 0 0 10px; }

/* the People tab's badge: someone is on a shared trip right now, or a request waits (people.js). A dot, never a count. */
.nav button { position: relative; }
.nav .nav-badge { position: absolute; top: 9px; left: calc(50% + 7px); width: 10px; height: 10px; border-radius: 50%; background: var(--accent); box-shadow: 0 0 0 2px var(--surface); }
.nav .nav-badge[hidden] { display: none; }

/* Bigger tap targets (app audit S22): the look stays, the area that answers a tap grows to about 44 px */
.link, span.pro-badge[role="button"], .tr-link { position: relative; }
.link::after, span.pro-badge[role="button"]::after, .tr-link::after { content: ""; position: absolute; inset: -7px -6px; }
span.pro-badge[role="button"]::after { inset: -14px -8px; }
.wg-x, .ak-x.sm { min-width: 44px; min-height: 44px; }
.tr-chip, .ak-chip { min-height: 44px; }

/* NightLink (night.js): a small moon on the route chip, the line page's note, the security note */
.badge.night { gap: 3px; }
.badge .i.moon { width: 12px; height: 12px; margin-left: 1px; fill: currentColor; stroke: none; opacity: .92; }
.note.night-line .i { color: var(--accent, currentColor); flex: none; margin-top: 2px; }
.note.night-sec .i { flex: none; margin-top: 2px; }
.night-src { display: inline; font-size: var(--fs-cap); opacity: .85; white-space: nowrap; }
.night-src a, .note.night-gen a { color: inherit; text-decoration: underline; }
.note.night-gen { font-size: var(--fs-foot); }
.note.night-hint { align-items: center; }
.v-kn { font-size: 11px; opacity: .8; font-weight: 600; }
.v-spd.v-still { font-weight: 600; opacity: .85; }
/* (5 Oct) a stretch of a vehicle's line that isn't on a real shape (a straight join, a ferry's 3-point "shape"): dashed and fainter */
.mv-line.guess { stroke-width: 4; stroke-dasharray: 1 9; opacity: .75; }
.mv-line.guess.walk { stroke-dasharray: 1 9; }
/* (5 Oct) last-resort net only: the page itself never scrolls sideways (sim s52 checks nothing overflows in the first place) */
html, body { overflow-x: hidden; overflow-x: clip; }   /* (hidden first: a WebView older than Chrome 90 has no clip, and the map page could then briefly go wider than the screen) */

/* ---- the tilted ("3D") map (mapview.js): the tile plane is laid back; stops stand up; a fog softens the far edge ---- */
.mv { --fog: 232, 230, 224; --sky: 206, 220, 236; }
/* (v115) the fog follows the tiles, not the app: HERE day tiles in a dark app get the light fog, night tiles the dark one */
:root[data-theme="dark"]:not(.mv-here) .mv, :root.mv-night .mv { --fog: 27, 35, 34; --sky: 30, 40, 58; }
.mv-plane { position: absolute; inset: 0; }
.mv-fog { position: absolute; left: 0; right: 0; top: 0; height: 0; z-index: 1; pointer-events: none; opacity: 0; transition: opacity .3s;
  background: linear-gradient(to bottom, rgba(var(--sky), .9) 0, rgba(var(--sky), 0) var(--ss, 8%)), linear-gradient(to bottom, rgba(var(--fog), 1) 0, rgba(var(--fog), 1) var(--fs, 60%), rgba(var(--fog), .6) calc(var(--fs, 60%) + (100% - var(--fs, 60%)) * .4), rgba(var(--fog), .22) calc(var(--fs, 60%) + (100% - var(--fs, 60%)) * .72), rgba(var(--fog), 0) 100%); }
.mv-3d .mv-fog { opacity: 1; }
.mv-3d .mv-stops { transform-style: preserve-3d; }
.mv-3d .mv-stop { rotate: var(--bb, 0 0 1 0deg); }
/* (item 16) the heading notch shows on a turned 3D map too: mapscreen.js draws it relative to the map's turn */
.zoom .tilt-btn { font-size: var(--fs-sub); font-weight: 800; letter-spacing: .02em; color: var(--text); }
.zoom .tilt-btn[aria-pressed="true"] { background: var(--text); color: var(--bg); }
.zoom .tilt-btn[hidden] { display: none; }
#map .traffic-btn { top: calc(var(--safe-top) + 228px); }          /* (below the 3D button, now the third in the zoom pill) */
.fab.tilt-fab { position: absolute; right: 12px; bottom: 34px; z-index: 10; font-size: var(--fs-sub); font-weight: 800; color: var(--text); }
.fab.tilt-fab[aria-pressed="true"] { background: var(--text); color: var(--bg); }
.fab.tilt-fab[hidden] { display: none; }
.ride-map .recenter:not([hidden]) ~ .tilt-fab { bottom: 92px; }
/* 3D buildings (Pro): the canvas sits between the tile plane and the markers; the button is a second tilt-style button */
.mv-bld { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; opacity: 0; transition: opacity .25s; }
#map.has-bld .traffic-btn { top: calc(var(--safe-top) + 276px); }   /* (one more slot down: the Buildings button is the fourth in the zoom pill) */
.zoom .bld-btn { position: relative; display: grid; place-items: center; color: var(--text); }
.zoom .bld-btn[aria-pressed="true"] { background: var(--text); color: var(--bg); }
.zoom .bld-btn[hidden], .fab.bld-fab[hidden] { display: none; }
.bld-btn .pro-badge, .bld-fab .pro-badge { position: absolute; top: -3px; right: -3px; font-size: 8px; line-height: 1; padding: 2px 3px; pointer-events: none; }
.fab.bld-fab { bottom: 92px; display: grid; place-items: center; }
.fab.bld-fab[aria-pressed="true"] { background: var(--text); color: var(--bg); }
.ride-map .recenter:not([hidden]) ~ .tilt-fab.bld-fab { bottom: 150px; }

/* (6 Oct) centring and the horizon: your dot and the dropped pin sit above the tiles, lines, stop pins and bus pills (only the sheet and the
   buttons cover them); the map keeps everything inside its own box, and in 3D far pills shrink and fade out (mapview.js fade()) */
.mv-user, .mv-pin { z-index: 5; }
.mv-attr { z-index: 6; }
/* Ride pack (v106): riders on board, the fare line, Thank the driver, Me's week of fares */
.aboard-line { display: flex; align-items: center; gap: 6px; margin: 8px 2px 0; }
.fare-line { display: flex; align-items: center; gap: 6px; margin: 8px 4px 0; font-size: var(--fs-detail, 14px); color: var(--muted); }
.fare-line b { color: var(--text); font-weight: 650; }
.kudos-card .kd-note textarea { display: block; width: 100%; min-height: 84px; padding: 12px 14px; border-radius: 12px; border: 1px solid var(--line); background: var(--surface, var(--bg)); color: var(--text); font: inherit; font-size: var(--fs-body); line-height: 1.4; resize: none; }
.kudos-card .kd-count { margin: 6px 4px 0; text-align: right; }
.me-fares { margin-top: 12px; }
.me-fares .item { cursor: default; }

/* the bars along the top of a map are only as wide as their buttons: the gaps between (and the spacer) let a finger through to the map */
.map-top { pointer-events: none; }
.map-top > * { pointer-events: auto; }
.map-top > .grow, .map-top > span.grow { pointer-events: none; }
/* the loading spinner sits in a corner on the trip map, never over the middle of it */
.ride-map .mv-loading { left: 28px; top: calc(var(--safe-top) + 84px); margin: 0; width: 36px; height: 36px; }

/* the other buses on the trip map: smaller, faded, under your own bus pill (z 4) and above the route line; the same route a touch stronger */
.ride-map .mv-marker.other { z-index: 2; opacity: .6; transform: translate(-50%, -50%) scale(.82); box-shadow: none; }
.ride-map .mv-marker.other.same { opacity: .8; z-index: 3; box-shadow: 0 0 0 2px rgba(255, 255, 255, .7); }
.ride-map .mv-marker.sel { z-index: 5; }
.map-top > .sg-trip { pointer-events: none; }
.map-top > .sg-trip > * { pointer-events: auto; }
.ride-map .mv-marker.sel.stale { opacity: .75; }

/* ---- v127 smooth bus (mapview.js, busmotion.js): pills stand on their spot in 3D; stops keep their size through a zoom ---- */
/* In the laid-back map a pill centred on its road read as floating over the roofs. Tilted, it stands on a short stem whose
   foot is the bus's place (mapview.js place(): STEM = 9 px below the pill's bottom edge), with a small shadow on the ground. */
.mv-foot { display: none; }
.mv-3d .mv-marker.mv-st > .mv-foot { display: block; position: absolute; left: 50%; top: calc(100% + 2px); width: 0; height: 9px; pointer-events: none; }
.mv-3d .mv-marker.mv-st > .mv-foot::before { content: ""; position: absolute; left: -1.5px; top: 0; width: 3px; height: 8px; border-radius: 0 0 2px 2px; background: var(--c, #121A18); box-shadow: 0 0 0 1px #fff; }
.mv-3d .mv-marker.mv-st > .mv-foot::after { content: ""; position: absolute; left: -6px; top: 7px; width: 12px; height: 4px; border-radius: 50%; background: rgba(0, 0, 0, .28); }
.mv-3d .mv-marker.mv-st.other > .mv-foot { opacity: .8; }
/* during a pinch or the zoom animation the tile world is scaled; the stops inside it are scaled back (--zk), the markers sit outside it */
.mv-stop { scale: var(--zk, 1); }
/* service-type tags beside a route badge (svctags.js): Metro, BUZ, Rocket, Express… a tap says what it means */
.svc-tag { display: inline-flex; align-items: center; height: 20px; padding: 0 6px; margin-left: 4px; border-radius: 6px; border: 1px solid var(--line, rgba(127,127,127,.35)); color: var(--muted); font-size: var(--fs-foot, 12px); font-weight: 700; white-space: nowrap; cursor: pointer; flex: none; vertical-align: middle; }
.ns-row small .svc-tag { margin-left: 0; height: 18px; }

/* ---- v140 (Atlas, 9 Oct): map flicker ---- */
/* tiles kept for panning or zooming back: hidden, picture and all */
.mv-tile.off { display: none; }
/* a bus with no fix for 2 minutes (or past what the last one can say): dimmed and dashed, never drawn as live */
.mv-marker.est, .mv-marker.stale { --mv-op: .55; opacity: .55; border-style: dashed; filter: saturate(.5); }
.mv-marker.est.sel, .mv-marker.stale.sel { --mv-op: .7; opacity: .7; }
/* a big correction: a quick fade out and in at the right place */
.mv-marker.reseat { animation: mvReseat .42s ease-out; }
@keyframes mvReseat { 0% { opacity: 0; } 100% { opacity: var(--mv-op, 1); } }
/* the Map tab's panel and buttons over a moving map: no live blur (it was worked out again for every frame of the map under it) */
:root[data-style="glass"] #map :is(.sheet, .searchbar, .fab, .zoom) { -webkit-backdrop-filter: none; backdrop-filter: none; background: color-mix(in srgb, var(--surface) 96%, transparent); }
/* the panel on its own layer; while it's dragged it moves by a transform, not its height */
#map .sheet { contain: layout style; }
#map .sheet.dragging { will-change: transform; transition: none; }
/* (Hearth, 10 Oct) Me → "Invite a mate": the subtitle on its own line, like the other cards ("Invite a mateYou both get…") */
.gv-card .grow { min-width: 0; }
.gv-card .grow b, .gv-card .grow small { display: block; }
.gv-card .grow small { color: var(--muted); font-weight: 500; margin-top: 2px; }
/* (Hearth, 10 Oct) the app went wide for a moment and snapped back as Search opened (its "School by 8:30" chips run past the card
   while it animates in): a sheet's body never scrolls sideways, and the Ask card clips its own chip row from the start */
.overlay { overflow-x: hidden; overflow-x: clip; }
.overlay-body { overflow-x: hidden; }
.ask-card { overflow: hidden; }
.ask-card > div, .bus-body, .ns-row .grow { min-width: 0; }

/* ---- Atlas lines (10 Oct): direction chevrons on a bus's line, a clearer heading notch, the "Starts" flag (items 16, 22) ---- */
.mv-chev { fill: none; stroke: #fff; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; opacity: .95; }
.mv-chev.draw { animation: chevIn .5s .55s var(--ease) both; }
@keyframes chevIn { from { opacity: 0; } to { opacity: .95; } }
.mv-marker .hd { border-width: 0 6px 8px; filter: drop-shadow(0 0 1.2px #fff) drop-shadow(0 0 .6px #fff); }
.mv-marker.dot .hd { display: none; }
.mv-marker.startflag { --c: var(--text); background: var(--surface, #fff); color: var(--text); box-shadow: 0 0 0 2px var(--text), 0 2px 6px rgba(0, 0, 0, .25); z-index: 2; pointer-events: none; }
.mv-marker.startflag::before { border-top-color: var(--text); }
@media (prefers-reduced-motion: reduce) { .mv-chev.draw { animation: none; } }
.mv-marker .mv-more { margin-left: 3px; padding: 0 5px; border-radius: 8px; background: var(--t, #fff); color: var(--c, #121A18); font-size: 11px; font-weight: 800; line-height: 16px; }   /* (item 18) buses folded under this pill */

/* (10 Oct) "Back to the bus": above the sheet, bottom right, like the locate button (mapscreen.js syncBackBus) */
#map .fab.back-bus { position: absolute; right: 12px; top: auto; z-index: 6; display: flex; align-items: center; gap: 2px; width: auto; padding: 0 12px; }
#map .fab.back-bus[hidden] { display: none; }
#map .fab.back-bus .bb-arrow { width: 16px; height: 16px; }
.why-short { line-height: 1.35; }
.v-spd .v-est { font-weight: 600; opacity: .75; }
.mv-stop::after { inset: -15px; }   /* (10 Oct) a 44 px tap target at least, whatever the dot's size */
.mv-stop.sm::after { inset: -17px; }

/* (10 Oct, SAFETY) an uncertain position: a soft halo growing with the fix's age; and the tapped bus's "somewhere in here" band */
.mv-marker.unc { outline: var(--unc, 4px) solid color-mix(in srgb, var(--c, #121A18) 22%, transparent); outline-offset: 0; }
.mv-band { fill: none; stroke: var(--accent); stroke-width: 14; stroke-linecap: round; stroke-linejoin: round; opacity: .18; }

/* (11 Oct) TransLink's train line numbers (trainline.js): a small outlined chip inside a train's badge, "[T6] Beenleigh" */
.badge .tl-code, .mo-badge .tl-code { display: inline-block; font-weight: 800; font-size: .86em; line-height: 1.3; padding: 0 4px; border-radius: 5px; box-shadow: inset 0 0 0 1.5px currentColor; letter-spacing: .01em; }
.tln-chip { display: inline-flex; align-items: center; height: 22px; padding: 0 6px; margin-right: 8px; font-size: var(--fs-foot); font-weight: 800; vertical-align: 2px; border-radius: 6px; }
.bus-card .bus-run { font-variant-numeric: tabular-nums; opacity: .8; }

.updp-moods button span .i { width: 24px; height: 24px; }
.updp-thanks span .i { width: 34px; height: 34px; color: var(--accent); }
