/* =========================================================================
   DESIGN TOKENS — "Apple feel" design system
   Everything below is a custom property so every color, radius, shadow,
   font and timing value in the file traces back to one accountable place.
   The original token names (--accent, --ink, --muted, --border, --bg,
   --panel-bg, --danger, --radius, --shadow) are kept as aliases so nothing
   elsewhere in this file (or in app.js, which never reads CSS vars) has to
   change to pick up the new system — they now just point at the new scale.
   ========================================================================= */
:root {
  /* ---- Brand accent (unchanged — this is Waypoint's existing blue) ---- */
  --accent: #2563eb;
  --accent-dark: #1d4ed8;
  --accent-light: #eff4ff;          /* tint used for hover/active backgrounds */
  --accent-tint-weak: rgba(37, 99, 235, 0.12);
  --accent-tint-strong: rgba(37, 99, 235, 0.22);

  /* ---- Neutral / gray scale (iOS system-gray inspired) ---- */
  --gray-50:  #f7f7f9;   /* systemGray6 — faint fills, app background */
  --gray-100: #f0f0f3;   /* systemGray6 (alt) */
  --gray-200: #e4e4e9;   /* systemGray5 — hairlines, chip fills */
  --gray-300: #d3d3d9;   /* systemGray4 */
  --gray-400: #c2c2c9;   /* systemGray3 */
  --gray-500: #a2a2ab;   /* systemGray2 */
  --gray-600: #7c7c86;   /* systemGray */
  --gray-700: #5b5b64;
  --gray-800: #38383f;
  --gray-900: #1c1c1e;

  /* ---- Label (text) hierarchy — iOS: label / secondaryLabel / tertiaryLabel ---- */
  --label-primary: #1c1c1e;
  --label-secondary: #66666f;
  --label-tertiary: #9a9aa3;
  --label-quaternary: #c6c6cc;

  /* ---- Surfaces ---- */
  --surface-bg: #ffffff;            /* base app background */
  --surface-secondary: #f5f5f8;     /* grouped/secondary background (was --panel-bg) */
  --surface-elevated: #ffffff;      /* cards, sheets, popovers */
  --surface-fill: rgba(120, 120, 128, 0.12);   /* subtle neutral fill, e.g. pressed states */
  --surface-fill-strong: rgba(120, 120, 128, 0.2);

  /* ---- Hairlines ---- */
  --separator: #e4e4e9;             /* opaque hairline (was --border) */
  --separator-translucent: rgba(60, 60, 67, 0.14);

  /* ---- Semantic colors ---- */
  --danger: #dc2626;
  --danger-tint: #fef2f2;
  --success: #16a34a;
  --warning: #d97706;

  /* ---- Back-compat aliases (kept so every existing rule below still resolves) ---- */
  --ink: var(--label-primary);
  --muted: var(--label-secondary);
  --border: var(--separator);
  --bg: var(--surface-bg);
  --panel-bg: var(--surface-secondary);

  /* ---- Corner radius scale ---- */
  --radius-xs: 8px;      /* tiny controls: dots, tags */
  --radius-sm: 10px;     /* inputs, chips, small buttons */
  --radius-md: 14px;     /* cards, list rows, panels */
  --radius-lg: 20px;     /* sheets, large modals */
  --radius-xl: 28px;     /* full sheets / drawers */
  --radius-pill: 999px;  /* pills, segmented controls */
  --radius: var(--radius-sm); /* back-compat default */

  /* ---- Elevation (layered, soft shadows — not harsh drop-shadows) ---- */
  --shadow-1: 0 1px 2px rgba(20, 20, 30, 0.05), 0 1px 1px rgba(20, 20, 30, 0.04);
  --shadow-2: 0 6px 20px rgba(20, 20, 30, 0.10), 0 1px 3px rgba(20, 20, 30, 0.06);
  --shadow-3: 0 16px 40px rgba(20, 20, 30, 0.18), 0 4px 10px rgba(20, 20, 30, 0.08);
  --shadow: var(--shadow-2); /* back-compat default */

  /* ---- Materials (iOS-style frosted/translucent chrome) ---- */
  --material-thin: rgba(255, 255, 255, 0.6);
  --material-regular: rgba(255, 255, 255, 0.78);
  --material-thick: rgba(255, 255, 255, 0.92);
  --material-dark: rgba(28, 28, 30, 0.72);
  --material-blur: blur(20px) saturate(180%);
  --material-blur-light: blur(12px) saturate(160%);

  /* ---- Typography ---- */
  --font-system: -apple-system, BlinkMacSystemFont, "SF Pro Display", "SF Pro Text", "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --text-title: 800 26px/1.15 var(--font-system);
  --text-headline: 700 17px/1.25 var(--font-system);
  --text-body: 400 15px/1.45 var(--font-system);
  --tracking-tight: -0.02em;   /* negative tracking for large bold headlines, iOS-style */

  /* ---- Motion ---- */
  --ease-spring: cubic-bezier(0.32, 0.72, 0, 1);   /* sheets, overlays sliding in */
  --ease-snappy: cubic-bezier(0.16, 1, 0.3, 1);     /* small state changes */
  --duration-fast: 0.15s;
  --duration-base: 0.28s;
  --duration-slow: 0.42s;
}

/* =========================================================================
   DARK MODE — toggled explicitly via [data-theme="dark"] on <html> (see
   app.js: THEME_KEY / applyTheme()), defaulting to the OS's color-scheme
   preference on first load before the person ever touches the toggle.
   Modeled on a transit-tracker reference (near-black background, outlined
   cards, oversized "hero number" countdowns, green live/good + blue LIVE
   accents) rather than a simple inverted palette — see the component
   overrides further down (search "[data-theme=\"dark\"]") for where that
   reference's specific look gets applied to Waypoint's own live-data
   surfaces (bus arrivals, weather readout).

   Every token below has a light value up in :root above (unchanged — light
   mode is not touched by this file) and a dark value here. Anything that
   only reads these tokens (almost everything in this file, including the
   --ink/--muted/--border/--bg/--panel-bg aliases) re-themes for free; the
   few rules that hard-code a light-only color instead of a token get their
   own explicit [data-theme="dark"] override alongside their light rule. */
:root[data-theme="dark"] {
  /* ---- Brand accent — a touch brighter so it still pops on near-black ---- */
  --accent: #3b82f6;
  --accent-dark: #60a5fa;
  --accent-light: rgba(59, 130, 246, 0.16);
  --accent-tint-weak: rgba(59, 130, 246, 0.18);
  --accent-tint-strong: rgba(59, 130, 246, 0.3);

  /* ---- Neutral / gray scale — ramp inverted so every existing consumer
     (hover fills, dividers, the weather-sheet drag handle, etc.) keeps
     working without being touched individually ---- */
  --gray-50:  #1c1c1e;
  --gray-100: #232326;
  --gray-200: #2c2c30;
  --gray-300: #3a3a3f;
  --gray-400: #4a4a50;
  --gray-500: #6b6b72;
  --gray-600: #8e8e96;
  --gray-700: #aeaeb5;
  --gray-800: #d1d1d6;
  --gray-900: #f2f2f4;

  /* ---- Label (text) hierarchy ---- */
  --label-primary: #f5f5f7;
  --label-secondary: #9a9aa3;
  --label-tertiary: #6e6e76;
  --label-quaternary: #48484c;

  /* ---- Surfaces — near-black, not just dark gray, per the reference ---- */
  --surface-bg: #000000;
  --surface-secondary: #08080a;
  --surface-elevated: #0e0e11;         /* cards read as "outlined", see below */
  --surface-fill: rgba(255, 255, 255, 0.08);
  --surface-fill-strong: rgba(255, 255, 255, 0.14);

  /* ---- Hairlines — thin, visible borders are what make dark-mode cards
     read as "outlined" instead of just flat-black ---- */
  --separator: rgba(255, 255, 255, 0.16);
  --separator-translucent: rgba(255, 255, 255, 0.14);

  /* ---- Semantic colors — brighter so they hold contrast on black ---- */
  --danger: #ff6961;
  --danger-tint: rgba(255, 105, 97, 0.14);
  --success: #32d74b;                  /* "live / good / on-time" green */
  --warning: #ffb340;

  /* ---- Materials — dark, translucent chrome instead of frosted white ---- */
  --material-thin: rgba(10, 10, 12, 0.6);
  --material-regular: rgba(8, 8, 10, 0.82);
  --material-thick: rgba(4, 4, 5, 0.94);
  --material-dark: rgba(0, 0, 0, 0.82);

  /* ---- Elevation — shadows barely read on near-black, so they're kept
     faint; the outline (--separator) does the visual work instead ---- */
  --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.4);
  --shadow-2: 0 6px 20px rgba(0, 0, 0, 0.5);
  --shadow-3: 0 16px 40px rgba(0, 0, 0, 0.6);
}

/* Before the person has ever touched the toggle (no localStorage choice
   yet), honor the OS's own dark preference. app.js sets data-theme
   explicitly on every load (light or dark) to avoid a flash, which is why
   this rule is scoped to :not([data-theme="light"]) rather than relied on
   alone — an explicit light choice on a dark system must still win. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]):not([data-theme="dark"]) {
    --accent: #3b82f6;
    --accent-dark: #60a5fa;
    --accent-light: rgba(59, 130, 246, 0.16);
    --accent-tint-weak: rgba(59, 130, 246, 0.18);
    --accent-tint-strong: rgba(59, 130, 246, 0.3);
    --gray-50: #1c1c1e; --gray-100: #232326; --gray-200: #2c2c30; --gray-300: #3a3a3f;
    --gray-400: #4a4a50; --gray-500: #6b6b72; --gray-600: #8e8e96; --gray-700: #aeaeb5;
    --gray-800: #d1d1d6; --gray-900: #f2f2f4;
    --label-primary: #f5f5f7;
    --label-secondary: #9a9aa3;
    --label-tertiary: #6e6e76;
    --label-quaternary: #48484c;
    --surface-bg: #000000;
    --surface-secondary: #08080a;
    --surface-elevated: #0e0e11;
    --surface-fill: rgba(255, 255, 255, 0.08);
    --surface-fill-strong: rgba(255, 255, 255, 0.14);
    --separator: rgba(255, 255, 255, 0.16);
    --separator-translucent: rgba(255, 255, 255, 0.14);
    --danger: #ff6961;
    --danger-tint: rgba(255, 105, 97, 0.14);
    --success: #32d74b;
    --warning: #ffb340;
    --material-thin: rgba(10, 10, 12, 0.6);
    --material-regular: rgba(8, 8, 10, 0.82);
    --material-thick: rgba(4, 4, 5, 0.94);
    --material-dark: rgba(0, 0, 0, 0.82);
    --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.4);
    --shadow-2: 0 6px 20px rgba(0, 0, 0, 0.5);
    --shadow-3: 0 16px 40px rgba(0, 0, 0, 0.6);
  }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

* { box-sizing: border-box; }

html, body {
  height: 100%;
  /* Mobile Chrome/WebView bug fix: with plain `height: 100%` chained from
     the viewport, the address bar (or the keyboard) showing/hiding can
     leave the page sized to a stale viewport height until something forces
     a reflow (e.g. a manual refresh) — which is exactly why the fixed
     WhatsApp button could end up positioned outside the visible screen.
     `100dvh` tracks the ACTUAL visible viewport continuously, so browsers
     that support it (effectively all current mobile browsers) never get
     that stale value in the first place. Older browsers just keep the
     100% fallback above. */
  height: 100dvh;
  margin: 0;
  font-family: var(--font-system);
  font-size: 15px;
  line-height: 1.45;
  color: var(--ink);
  background: var(--bg);
  -webkit-tap-highlight-color: transparent;
}

button, input {
  font-family: inherit;
}

/* iOS-style tap feedback: a small scale-down + fade on buttons, and a
   plain fade on links (a bare text link shrinking on tap reads as broken,
   not native — iOS fades links, not scales them). Both ride on top of each
   control's own hover/active rules further down. Reduced-motion users get
   the instant version via the media query above. */
button:not(:disabled),
a {
  transition: transform var(--duration-fast) var(--ease-snappy), opacity var(--duration-fast) var(--ease-snappy), background var(--duration-fast) var(--ease-snappy), border-color var(--duration-fast) var(--ease-snappy), color var(--duration-fast) var(--ease-snappy), box-shadow var(--duration-fast) var(--ease-snappy);
}
button:not(:disabled):active {
  transform: scale(0.96);
  opacity: 0.85;
}
a:active {
  opacity: 0.6;
}

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

#app {
  height: 100%;
  height: 100dvh; /* see html,body comment above */
  display: flex;
  flex-direction: column;
}

#topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 10px 16px;
  padding-top: max(10px, env(safe-area-inset-top));
  border-bottom: 1px solid var(--separator-translucent);
  /* Frosted glass chrome, like a native iOS toolbar — translucent surface +
     blur/saturate over whatever sits behind it (banners appearing below,
     or content in a future scrolling layout), instead of a flat opaque bar. */
  background: var(--material-regular);
  backdrop-filter: var(--material-blur);
  -webkit-backdrop-filter: var(--material-blur);
  z-index: 1000;
}

.topbar-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0; /* never let the action buttons get squeezed by a long brand name */
}

.train-alert-banner {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 9px 14px;
  background: #fef2f2;
  border-bottom: 1px solid #fecaca;
  color: #991b1b;
  font-size: 12.5px;
  font-weight: 600;
}
.train-alert-banner.hidden { display: none; }
.train-alert-icon { flex-shrink: 0; }
.train-alert-text { flex: 1; }
.train-alert-dismiss {
  border: none;
  background: none;
  color: #991b1b;
  opacity: 0.7;
  cursor: pointer;
  padding: 4px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
}
.train-alert-dismiss svg { width: 13px; height: 13px; }
.train-alert-dismiss:hover { opacity: 1; }

/* Solid red (not the light red/amber tint the other banners use) since this
   marks an active, ongoing state the user should be able to spot at a
   glance and consciously end — not just a passive FYI like the alert
   banners above. */
.sos-tracking-banner {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 9px 14px;
  background: var(--danger);
  color: #fff;
  font-size: 12.5px;
  font-weight: 600;
}
.sos-tracking-banner.hidden { display: none; }
.sos-tracking-icon { flex-shrink: 0; }
.sos-tracking-text { flex: 1; }
.sos-tracking-stop {
  border: 1px solid rgba(255,255,255,0.6);
  background: rgba(255,255,255,0.12);
  color: #fff;
  border-radius: 999px;
  padding: 4px 10px;
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
  flex-shrink: 0;
}
.sos-tracking-stop:hover { background: rgba(255,255,255,0.22); }

.offline-banner {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 9px 14px;
  background: #fffbeb;
  border-bottom: 1px solid #fde68a;
  color: #92400e;
  font-size: 12.5px;
  font-weight: 600;
}
.offline-banner.hidden { display: none; }
.offline-banner-icon { flex-shrink: 0; }
.offline-banner-text { flex: 1; }

.brand {
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: 700;
  font-size: 18px;
  min-width: 26px; /* always keep enough room for the flag mark itself — see overflow: hidden below */
  flex: 1 1 auto;  /* claims only the space left over after the topbar action buttons */
  overflow: hidden; /* on a narrow phone, clip the shrinking name/tagline INSIDE this box instead of
                        letting the flag mark spill out and get painted over by the topbar-actions
                        buttons that follow it in the DOM (that overlap was the actual reported bug) */
}

.brand-mark { font-size: 20px; flex-shrink: 0; }

.brand-text {
  display: flex;
  flex-direction: column;
  line-height: 1.2;
  min-width: 0; /* required at every nested flex level for ellipsis truncation to work */
}

.brand-name {
  font-size: 15px;
  font-weight: 700;
  letter-spacing: var(--tracking-tight);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.brand-tagline {
  font-size: 10.5px;
  font-weight: 500;
  color: var(--muted);
  letter-spacing: 0.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.icon-btn {
  /* Kept at the original 38px (not bumped to the ~44px touch-target
     guideline) — the topbar is already tight on a narrow phone (see the
     .brand / .weather-widget comments below about squeezing), and this row
     can hold up to 6 of these side by side. The visual refinements (softer
     border, elevation, frosted-adjacent surface) apply at the same size. */
  border: 1px solid var(--separator);
  background: var(--surface-elevated);
  color: var(--label-primary);
  border-radius: 50%;
  width: 38px;
  height: 38px;
  min-width: 38px;
  font-size: 16px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: var(--shadow-1);
}
.icon-btn svg { width: 17px; height: 17px; display: block; flex-shrink: 0; }
.icon-btn:hover { background: var(--gray-100); }
.icon-btn.small { width: 32px; height: 32px; min-width: 32px; font-size: 14px; }
.icon-btn.small svg { width: 14px; height: 14px; }
.icon-btn.active {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}
.icon-btn.active:hover { background: var(--accent-dark); }

/* SOS: a plain icon-btn would blend into the rest of the topbar, but this
   is a safety control that should read as distinct/urgent even before
   anyone reads the tooltip -- red border/text on the same neutral
   background the other icon buttons use, so it stands out without
   shouting as loud as a solid red fill would in a toolbar full of
   everyday icons. */
.sos-btn {
  border-color: var(--danger);
  color: var(--danger);
}
.sos-btn:hover { background: var(--danger-tint); }

.sos-form { text-align: left; margin: 0 0 14px; display: flex; flex-direction: column; gap: 4px; }
.sos-form-label { font-size: 12px; color: var(--muted); margin-top: 8px; }
.sos-form-label:first-child { margin-top: 0; }
.sos-form-input {
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 11px 12px;
  font-size: 15px;
  width: 100%;
  background: var(--surface-elevated);
  color: var(--label-primary);
}
.sos-form-input:focus { outline: 2px solid var(--accent); outline-offset: 1px; }

.sos-primary-btn {
  display: block;
  width: 100%;
  border: none;
  border-radius: var(--radius-sm);
  padding: 13px;
  min-height: 46px;
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: #fff;
  background: var(--accent);
  cursor: pointer;
  margin-top: 4px;
  box-shadow: var(--shadow-1);
}
.sos-primary-btn:hover { background: var(--accent-dark); }
.sos-primary-btn:disabled { opacity: 0.6; cursor: default; }

.sos-send-btn { background: var(--danger); }
.sos-send-btn:hover { background: #b91c1c; }

.sos-secondary-btn {
  display: block;
  width: 100%;
  border: none;
  background: none;
  color: var(--muted);
  font-size: 12.5px;
  padding: 10px;
  cursor: pointer;
  text-decoration: underline;
}

/* ---- Safety Center — the SOS icon opens a 4-tab sheet (SOS / Contacts /
   Check / Hotlines) instead of just the old single-contact send flow.
   Reuses the .weather-panel-card shell (like Lens does) but taller and
   scrollable, since Hotlines/Check have a lot more content than a single
   confirm screen. ---- */
.safety-card { text-align: left; max-height: 88vh; display: flex; flex-direction: column; padding-top: 26px; }
.safety-tabs {
  display: flex; gap: 3px; background: var(--surface-fill); padding: 4px;
  border-radius: var(--radius-sm); margin: 0 0 14px; flex-shrink: 0;
}
.safety-tab {
  flex: 1; border: none; background: none; padding: 8px 2px; border-radius: var(--radius-xs);
  font-size: 12px; font-weight: 600; color: var(--muted); cursor: pointer; white-space: nowrap;
}
.safety-tab.active { background: var(--surface-elevated); color: var(--ink); box-shadow: var(--shadow-1); }
.safety-body { overflow-y: auto; flex: 1 1 auto; min-height: 0; padding-bottom: 4px; }
.safety-body h3 { margin: 0 0 6px; font-size: 17px; font-weight: 700; letter-spacing: var(--tracking-tight); }
.safety-sub { margin: 0 0 14px; font-size: 12.5px; color: var(--muted); line-height: 1.45; }

.safety-sos-wrap { display: flex; justify-content: center; padding: 6px 0 14px; }
.safety-sos-btn {
  width: 132px; height: 132px; border-radius: 50%; border: none; cursor: pointer;
  background: radial-gradient(circle at 50% 35%, var(--danger), #b91c1c); color: #fff;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  box-shadow: 0 0 0 10px var(--danger-tint), var(--shadow-2);
}
.safety-sos-btn b { font-size: 26px; font-weight: 800; letter-spacing: 0.02em; }
.safety-sos-btn small { font-size: 11.5px; opacity: 0.92; }
.safety-sos-btn:disabled { opacity: 0.7; cursor: default; }

.safety-local-bar {
  display: flex; align-items: center; justify-content: space-between; gap: 8px; flex-wrap: wrap;
  background: var(--danger-tint); border: 1px solid var(--danger); border-radius: var(--radius-md);
  padding: 10px 12px; margin: 0 0 12px;
}
.safety-local-bar .safety-local-label { font-size: 11.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: var(--danger); }
.safety-local-bar .safety-local-name { font-size: 13.5px; font-weight: 700; color: var(--ink); }
.safety-local-acts { display: flex; gap: 6px; flex-wrap: wrap; }
.safety-local-acts a {
  background: var(--danger); color: #fff; border-radius: var(--radius-pill); padding: 7px 11px;
  font-size: 12.5px; font-weight: 700; text-decoration: none;
}

.safety-list { list-style: none; margin: 0 0 14px; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.safety-contact, .safety-hot, .safety-emb {
  border: 1px solid var(--border); background: var(--surface-elevated); border-radius: var(--radius-md);
  padding: 11px 12px; box-shadow: var(--shadow-1);
}
.safety-contact { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.safety-contact-name { font-weight: 700; font-size: 14px; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.safety-contact-phone { font-size: 12.5px; color: var(--muted); }
.safety-contact-acts { display: flex; gap: 6px; flex-shrink: 0; }
.safety-icon-btn {
  width: 34px; height: 34px; border-radius: var(--radius-sm); border: 1px solid var(--border);
  background: var(--surface-bg); display: flex; align-items: center; justify-content: center; cursor: pointer; color: var(--label-primary);
}
.safety-icon-btn svg { width: 16px; height: 16px; }
.safety-empty { text-align: center; color: var(--muted); padding: 20px; border: 1.5px dashed var(--border); border-radius: var(--radius-md); font-size: 13px; margin-bottom: 14px; }

.safety-hot { display: grid; grid-template-columns: 1fr auto; gap: 1px 12px; align-items: center; }
.safety-hot-num { font-size: 22px; font-weight: 800; letter-spacing: 0.02em; }
.safety-hot-what { font-size: 12.5px; color: var(--muted); grid-column: 1; }
.safety-hot a { grid-row: 1 / 3; grid-column: 2; }
.safety-hot.urgent .safety-hot-num { color: var(--danger); }

.safety-where {
  display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 10px;
  background: var(--surface-secondary); border: 1px solid var(--border); border-radius: var(--radius-md);
  padding: 11px 12px; margin: 0 0 12px;
}
.safety-where select { border: 1px solid var(--border); background: var(--surface-elevated); border-radius: var(--radius-sm); padding: 8px 9px; max-width: 100%; color: var(--label-primary); }
.safety-where .safety-where-who { font-weight: 700; font-size: 15.5px; }
.safety-nat { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; width: 100%; border-top: 1px solid var(--border); padding-top: 9px; }

.safety-emb b { font-size: 14px; display: block; margin-bottom: 2px; }
.safety-emb .safety-emb-addr { font-size: 12px; color: var(--muted); margin-bottom: 4px; }
.safety-emb-row { display: flex; justify-content: space-between; align-items: baseline; gap: 4px 12px; flex-wrap: wrap; font-size: 13px; }
.safety-emb-row span { color: var(--muted); }
.safety-emb a { color: var(--accent); font-weight: 600; text-decoration: none; word-break: break-all; }

.safety-tips { margin: 0 0 14px; padding-left: 18px; display: flex; flex-direction: column; gap: 6px; font-size: 13px; color: var(--ink); }

.safety-verdict { border-radius: var(--radius-md); padding: 13px; display: flex; gap: 13px; align-items: center; margin-bottom: 14px; }
.safety-verdict.high { background: color-mix(in srgb, var(--danger) 12%, var(--surface-elevated)); border: 1px solid var(--danger); }
.safety-verdict.mid { background: color-mix(in srgb, var(--warning) 14%, var(--surface-elevated)); border: 1px solid var(--warning); }
.safety-verdict.low { background: color-mix(in srgb, var(--success) 12%, var(--surface-elevated)); border: 1px solid var(--success); }
.safety-score { font-size: 34px; font-weight: 800; flex: 0 0 auto; min-width: 68px; text-align: center; }
.safety-verdict.high .safety-score { color: var(--danger); }
.safety-verdict.mid .safety-score { color: var(--warning); }
.safety-verdict.low .safety-score { color: var(--success); }
.safety-verdict h4 { margin: 0; font-size: 15.5px; font-weight: 700; }
.safety-verdict p { margin: 3px 0 0; font-size: 12.5px; color: var(--ink); }
.safety-flags { list-style: none; margin: 0 0 14px; padding: 0; display: flex; flex-direction: column; gap: 7px; }
.safety-flags li {
  background: var(--surface-elevated); border: 1px solid var(--border); border-left: 3px solid var(--warning);
  border-radius: var(--radius-sm); padding: 9px 11px; font-size: 12.5px;
}
.safety-flags li.hi { border-left-color: var(--danger); }
.safety-flags b { display: block; font-size: 13px; margin-bottom: 2px; }
.safety-flags span { color: var(--muted); }
.safety-preview {
  background: var(--surface-secondary); border: 1px solid var(--border); border-radius: var(--radius-sm);
  padding: 11px; white-space: pre-wrap; word-break: break-word; font-size: 13px; margin-bottom: 8px;
}
.safety-preview mark { background: color-mix(in srgb, var(--danger) 28%, transparent); color: inherit; border-radius: 3px; padding: 0 2px; }
.safety-check-textarea {
  width: 100%; min-height: 130px; resize: vertical; border: 1px solid var(--border); border-radius: var(--radius-sm);
  padding: 11px 12px; font-size: 13.5px; line-height: 1.45; background: var(--surface-elevated); color: var(--label-primary); margin-bottom: 10px;
}
.safety-row { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 4px; }
.safety-row .pill-btn { flex: 1 1 120px; text-align: center; }

/* Icon-only now (text label removed) — falls back to the same plain round
   .icon-btn shape as the notify/SOS buttons next to it instead of the wide
   text-pill shape this used when it showed "Where am I" as well. */
.locate-btn {
  font-size: 16px;
}

.lang-btn {
  width: auto;
  border-radius: var(--radius-pill);
  padding: 0 12px;
  font-size: 12px;
  font-weight: 700;
  color: var(--ink);
  white-space: nowrap;
  display: flex;
  align-items: center;
  gap: 4px;
}
.lang-btn svg { width: 14px; height: 14px; }

.weather-widget {
  border: 1px solid var(--border);
  background: var(--surface-elevated);
  border-radius: var(--radius-pill);
  padding: 6px 12px;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 5px;
  margin-right: 8px;
  box-shadow: var(--shadow-1);
  /* Its text (icon + forecast + PSI/PM2.5/UV suffixes) has no natural
     wrap/shrink point of its own, so without this it was refusing to give up
     an inch of width — starving the brand flag/name next to it down to
     nothing on a narrow phone. min-width: 0 lets it actually participate in
     flex-shrinking instead of always claiming its full text width. */
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.weather-widget:hover { background: var(--gray-100); }
.weather-widget.hidden { display: none; }

/* ---- Weather panel / SOS modal — both render into the same markup
   (.weather-panel-card), so both become iOS-style bottom sheets here:
   anchored to the bottom edge, rounded top corners, a drag-handle bar,
   and a spring-in animation, instead of a small centered dialog. ---- */
.weather-panel {
  position: fixed;
  inset: 0;
  z-index: 2200;
  background: rgba(0,0,0,0.32);
  display: flex;
  align-items: flex-end;
  justify-content: center;
  padding: 0;
  animation: sheet-backdrop-in var(--duration-base) var(--ease-snappy);
}
.weather-panel.hidden { display: none; }

.weather-panel-card {
  position: relative;
  background: var(--material-thick);
  backdrop-filter: var(--material-blur);
  -webkit-backdrop-filter: var(--material-blur);
  border-radius: var(--radius-xl) var(--radius-xl) 0 0;
  box-shadow: var(--shadow-3);
  padding: 30px 20px max(20px, env(safe-area-inset-bottom));
  max-width: 480px;
  width: 100%;
  text-align: center;
  animation: sheet-in var(--duration-slow) var(--ease-spring);
}
/* Drag-handle bar — purely visual (the sheet closes via the ✕ button, not a
   drag gesture) but it is the single strongest "this is a native iOS sheet"
   signal, so it earns its place even without being interactive. */
.weather-panel-card::before {
  content: '';
  position: absolute;
  top: 8px;
  left: 50%;
  transform: translateX(-50%);
  width: 36px;
  height: 5px;
  border-radius: var(--radius-pill);
  background: var(--gray-300);
}

@keyframes sheet-backdrop-in {
  from { opacity: 0; }
  to { opacity: 1; }
}
@keyframes sheet-in {
  from { transform: translateY(100%); }
  to { transform: translateY(0); }
}

.weather-panel-close {
  position: absolute;
  top: 14px;
  right: 12px;
  border: none;
  background: var(--surface-fill);
  border-radius: 50%;
  width: 30px;
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--label-secondary);
  cursor: pointer;
  padding: 0;
}
.weather-panel-close svg { width: 14px; height: 14px; }
.weather-panel-close:hover { color: var(--ink); background: var(--surface-fill-strong); }

.weather-panel-icon { font-size: 40px; line-height: 1; margin-bottom: 10px; margin-top: 6px; }
.weather-panel-headline { margin: 0 0 8px; font-size: 19px; font-weight: 700; letter-spacing: var(--tracking-tight); }
.weather-panel-now { margin: 0 0 14px; font-size: 13px; color: var(--muted); line-height: 1.5; }

/* The mask-advice sub-line under the PSI reading: needs to read as an
   actual instruction, not just more muted metadata, so it gets full-
   strength text color and a bit of weight instead of inheriting
   weather-panel-now's muted gray. */
.weather-panel-mask-advice { display: inline-block; margin-top: 3px; color: var(--ink); font-weight: 600; }

.weather-panel-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  margin: 10px 0 14px;
}
.weather-panel-grid > div {
  display: flex;
  flex-direction: column;
  gap: 2px;
  background: var(--panel-bg);
  border-radius: var(--radius);
  padding: 10px 6px;
}
.weather-panel-label { font-size: 11px; color: var(--muted); }
.weather-panel-value { font-size: 13px; font-weight: 700; }

.weather-panel-note { margin: 0; font-size: 11px; color: var(--muted); }

/* UV Index reference scale — a small colored strip (WHO's 5 bands) shown
   under today's UV reading, with a marker on today's band and a short
   plain-language "what to do" line, since a bare label like "Moderate"
   doesn't tell most people anything actionable on its own. */
.uv-scale {
  display: flex;
  align-items: flex-end;
  gap: 2px;
  margin: 2px 0 6px;
  padding-top: 10px; /* headroom for the current band's caret above it */
}
.uv-scale-band {
  flex: 1;
  /* Fixed height + centered content so every band is the same dimension
     regardless of label length — without this, a longer two-word label
     (e.g. PSI's "Very Unhealthy", vs. UV's shorter labels) wraps to a
     second line and makes just that one band taller than its neighbors. */
  min-height: 30px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 5px 2px 4px;
  text-align: center;
  color: #fff;
  text-shadow: 0 1px 1px rgba(0,0,0,0.25);
  border-radius: 5px;
  position: relative;
  overflow: hidden;
}
.uv-scale-band:first-child { border-top-left-radius: 6px; border-bottom-left-radius: 6px; }
.uv-scale-band:last-child { border-top-right-radius: 6px; border-bottom-right-radius: 6px; }
/* "You are here" — a white ring around the current band, plus a small
   downward-pointing caret floating above it. This used to instead shift the
   whole band up 4px with extra padding ("lifted above the row") — but that
   made the current band's top AND bottom edges no longer line up with its
   neighbors, which just reads as a misaligned/broken row rather than an
   intentional highlight. The ring + caret marks "current" just as clearly
   without throwing off the row's alignment. */
.uv-scale-band.current {
  box-shadow: inset 0 0 0 2px #fff, 0 2px 6px rgba(0,0,0,0.3);
}
.uv-scale-band.current::before {
  content: '';
  position: absolute;
  top: -8px;
  left: 50%;
  transform: translateX(-50%);
  width: 0;
  height: 0;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-top: 6px solid #fff;
  filter: drop-shadow(0 1px 1px rgba(0,0,0,0.3));
}
.uv-scale-range { display: block; font-size: 9.5px; font-weight: 700; line-height: 1.3; }
.uv-scale-label { display: block; font-size: 7.5px; line-height: 1.2; opacity: 0.95; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.uv-scale-advice { margin: 0 0 14px; font-size: 11.5px; color: var(--muted); text-align: left; }
.weather-panel-loading { padding: 20px 0; color: var(--muted); font-size: 13px; }

#body {
  flex: 1;
  display: flex;
  justify-content: center;
  min-height: 0;
  background: var(--panel-bg);
}

#sidebar {
  width: 100%;
  max-width: 480px;
  background: var(--panel-bg);
  display: flex;
  flex-direction: column;
  overflow-y: auto;
}

.tabs {
  display: flex;
  border-bottom: 1px solid var(--border);
  background: var(--bg);
}

.tab-btn {
  flex: 1 1 0;
  min-width: 0;
  /* Icon on top, label underneath — every tab gets the same layout so the
     row lines up whether a label fits on one line or wraps to two. */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  gap: 3px;
  padding: 9px 2px 8px;
  min-height: 44px;
  border: none;
  background: none;
  font-size: 12px;
  line-height: 1.2;
  font-weight: 600;
  color: var(--muted);
  cursor: pointer;
  border-bottom: 3px solid transparent;
}
.tab-icon { font-size: 19px; line-height: 1; }
.tab-label { display: block; max-width: 100%; text-align: center; overflow-wrap: anywhere; text-wrap: balance; }
:lang(ko) .tab-label { word-break: keep-all; } /* wrap Korean at spaces, not mid-word */
.tab-btn:not(.active) .tab-icon { filter: grayscale(0.35); opacity: 0.85; }

.tab-btn.active {
  color: var(--accent);
  border-bottom-color: var(--accent);
}

.tab-btn:active { transform: none; opacity: 0.6; } /* underline tabs read better as a fade than a scale-down */

.panel {
  display: none;
  padding: 16px;
  flex-direction: column;
  gap: 10px;
}
.panel.active { display: flex; }

.search-box {
  position: relative;
  display: flex;
  align-items: center;
}

.search-box input,
.dir-field input {
  width: 100%;
  min-height: 44px;
  padding: 11px 36px 11px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font-size: 15px;
  background: var(--surface-secondary);
  color: var(--label-primary);
}
.search-box input::placeholder,
.dir-field input::placeholder {
  color: var(--label-tertiary);
}
.search-box input:focus,
.dir-field input:focus {
  outline: none;
  background: var(--surface-elevated);
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-tint-weak);
}

.clear-btn {
  position: absolute;
  right: 8px;
  border: none;
  background: none;
  color: var(--muted);
  cursor: pointer;
  font-size: 13px;
  padding: 4px;
  display: none;
  border-radius: 50%;
}
.clear-btn svg { width: 14px; height: 14px; display: block; }
.clear-btn.visible { display: flex; align-items: center; justify-content: center; }

.result-list {
  list-style: none;
  margin: 0;
  padding: 0;
  border-radius: var(--radius-md);
  overflow: hidden;
}
.result-list:not(:empty) {
  border: 1px solid var(--border);
  background: var(--surface-elevated);
}
.result-list.nested {
  position: absolute;
  left: 0;
  right: 0;
  top: 100%;
  z-index: 50;
  margin-top: 4px;
  box-shadow: var(--shadow-2);
}

.result-list li {
  padding: 11px 12px;
  cursor: pointer;
  font-size: 14px;
  border-bottom: 1px solid var(--border);
}
.result-list li:last-child { border-bottom: none; }
.result-list li:hover { background: var(--gray-100); }
.result-list li .r-title { font-weight: 600; display: block; }
.result-list li .r-sub { color: var(--muted); font-size: 12px; }
.result-list li .r-sub .r-line { display: flex; flex-wrap: wrap; gap: 2px 10px; margin-top: 2px; }
.result-list li .r-sub .r-chip { white-space: nowrap; }
.result-list li .r-sub .r-link { color: var(--accent); font-weight: 600; text-decoration: none; }
.result-list li .r-sub .r-link:active { text-decoration: underline; }
.place-contact { display: inline-block; margin: -4px 0 10px; color: var(--accent); font-size: 13px; font-weight: 600; text-decoration: none; }
.result-list li.r-loading { cursor: default; color: var(--muted); }
.result-list li.r-loading:hover { background: none; }

/* Segmented tabs that switch which single category-row is visible — replaces
   the old stacked layout (a labelled row per category, all shown at once),
   which got cluttered once a 4th category (Gourmet Food) was added. */
.category-group-tabs {
  display: flex;
  gap: 6px;
  margin: 4px 0 8px;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  padding-bottom: 2px;
}
.category-group-tab {
  flex: 0 0 auto;
  border: 1px solid var(--border);
  background: var(--surface-elevated);
  border-radius: var(--radius-pill);
  padding: 7px 13px;
  font-size: 12px;
  font-weight: 700;
  color: var(--muted);
  cursor: pointer;
  white-space: nowrap;
}
.category-group-tab.active { border-color: var(--accent); background: var(--accent); color: #fff; box-shadow: var(--shadow-1); }
.category-row {
  display: flex;
  gap: 8px;
  margin: 0 0 4px;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  padding-bottom: 2px;
}
.category-row.hidden { display: none; }
.category-chip {
  flex: 0 0 auto;
  min-width: 64px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  border: 1px solid var(--border);
  background: var(--surface-elevated);
  border-radius: var(--radius-md);
  padding: 9px 8px;
  font-size: 11.5px;
  font-weight: 600;
  color: var(--ink);
  cursor: pointer;
}
.category-chip-icon {
  font-size: 18px;
  height: 22px;
  line-height: 22px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.category-chip:hover { border-color: var(--accent); color: var(--accent); background: var(--accent-light); }
/* Anytime Fitness has no official logo asset embedded here (trademark) — this
   is a generic gym glyph on a small badge tinted to their brand purple, just
   as a visual cue for the category, not a reproduction of their mark. */
.category-chip-icon.af-badge {
  width: 22px;
  border-radius: 50%;
  background: #6e38d5;
  font-size: 12px;
}

.place-card {
  border: 1px solid var(--border);
  background: var(--surface-elevated);
  border-radius: var(--radius-md);
  padding: 16px;
  box-shadow: var(--shadow-1);
}
.place-card.hidden { display: none; }
.place-card h3 { margin: 0 0 4px; font-size: 17px; font-weight: 700; letter-spacing: var(--tracking-tight); }
.place-card p { margin: 0 0 10px; color: var(--muted); font-size: 13px; }

.place-card-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.place-card-actions-secondary { margin-top: 8px; }

/* ---- Attraction info (nearest MRT/LRT + nearby attractions) ---- */
.attraction-info { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--border); }
.attraction-info.hidden { display: none; }
.attraction-loading { margin: 0; font-size: 12.5px; color: var(--muted); }

.attraction-station { display: flex; align-items: flex-start; gap: 10px; }
.attraction-station-icon { font-size: 20px; line-height: 1.3; }
.attraction-station-text { display: flex; flex-direction: column; gap: 2px; }
.attraction-station-text strong { font-size: 13.5px; }
.attraction-station-text span { font-size: 12px; color: var(--muted); }
.attraction-station-none { margin: 0; font-size: 12.5px; color: var(--muted); }

.attraction-nearby { margin-top: 12px; }
.attraction-nearby h4 { margin: 0 0 8px; font-size: 12px; font-weight: 600; color: var(--muted); text-transform: uppercase; letter-spacing: 0.02em; }
.attraction-nearby-list { display: flex; flex-wrap: wrap; gap: 6px; }
.attraction-nearby-chip {
  border: 1px solid var(--border);
  background: var(--surface-elevated);
  border-radius: var(--radius-pill);
  padding: 6px 12px;
  font-size: 12.5px;
  cursor: pointer;
}
.attraction-nearby-chip:hover { border-color: var(--accent); color: var(--accent); background: var(--accent-light); }

.attraction-ticket-btn {
  display: block;
  margin-top: 12px;
  padding: 12px 14px;
  min-height: 44px;
  border-radius: var(--radius-sm);
  background: var(--accent);
  color: #fff;
  text-align: center;
  text-decoration: none;
  font-size: 14px;
  font-weight: 600;
  box-shadow: var(--shadow-1);
}
.attraction-ticket-btn:hover { background: var(--accent-dark); }

.attraction-food-tip {
  margin: 12px 0 0;
  padding: 9px 11px;
  background: #fff7e6;
  border: 1px solid #f5e0a8;
  border-radius: var(--radius-sm);
  font-size: 12.5px;
  color: var(--ink);
}
.attraction-food-tip strong { font-weight: 700; }

/* Same shape as .attraction-food-tip, blue rather than amber so a district's
   "what this covers" note reads as informational rather than a recommendation
   like the food tip. Shown first, at the top of #attractionInfo. */
.attraction-coverage-tip {
  margin: 0 0 12px;
  padding: 9px 11px;
  background: var(--accent-light);
  border: 1px solid var(--accent-tint-strong, var(--accent-light));
  border-radius: var(--radius-sm);
  font-size: 12.5px;
  color: var(--ink);
  line-height: 1.45;
}
.attraction-coverage-tip strong { font-weight: 700; color: var(--accent); }

/* ---- Certified guides on the place card ---- */
.attraction-guides { margin-top: 12px; }
.attraction-guides h4 {
  margin: 0 0 8px; font-size: 12px; font-weight: 600; color: var(--muted);
  text-transform: uppercase; letter-spacing: 0.02em;
  display: flex; align-items: center; gap: 6px;
}
.attraction-guides-badge {
  display: inline-block; padding: 1px 6px; border-radius: 999px;
  background: var(--accent-light); color: var(--accent); font-size: 10px;
  font-weight: 700; letter-spacing: 0.03em;
}
.attraction-guide-card {
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  padding: 10px 12px; margin-bottom: 8px; background: var(--card-bg, #fff);
}
.attraction-guide-card:last-child { margin-bottom: 0; }
.attraction-guide-head { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.attraction-guide-name { font-size: 13.5px; font-weight: 600; color: var(--ink); }
.attraction-guide-verified { font-size: 11px; font-weight: 600; color: #2f9e57; }
.attraction-guide-license {
  font-size: 10px; font-weight: 700; letter-spacing: 0.02em; color: var(--muted);
  border: 1px solid var(--border); border-radius: 999px; padding: 1px 6px;
}
.attraction-guide-meta { margin-top: 2px; font-size: 12px; color: var(--muted); }
.attraction-guide-price { margin-top: 4px; font-size: 13px; font-weight: 600; color: var(--accent, #C0783C); }
.attraction-guide-note {
  margin: 6px 0 0; font-size: 12.5px; font-style: italic; color: var(--ink);
  line-height: 1.45; white-space: pre-line;
}
.attraction-guide-contact {
  display: inline-block; margin-top: 8px; padding: 7px 12px; border-radius: var(--radius-sm);
  background: var(--accent); color: #fff; font-size: 12.5px; font-weight: 600;
  text-decoration: none;
}
.attraction-guide-contact:hover { background: var(--accent-dark); }
.attraction-guide-sample-note {
  margin-top: 8px; font-size: 11.5px; color: var(--muted); font-style: italic;
}
.attraction-guide-availability {
  display: inline-block; margin-top: 8px; margin-left: 8px; padding: 7px 12px; border-radius: var(--radius-sm);
  background: transparent; color: var(--accent); font-size: 12.5px; font-weight: 600;
  text-decoration: none; border: 1px solid var(--accent);
}
.attraction-guide-availability:hover { background: var(--accent); color: #fff; }

/* ---- Concerts (venue transit guides, grouped shows) ---- */
.concerts-note { font-size: 12px; color: var(--muted); margin: 0 0 10px; line-height: 1.4; }
.concert-venue-card {
  border: 1px solid var(--border);
  background: var(--surface-elevated);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-1);
  margin: 0 0 10px;
}
.concert-venue-toggle {
  display: flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  user-select: none;
  list-style: none;
  padding: 12px 14px;
  font-size: 14px;
  font-weight: 700;
}
.concert-venue-toggle::-webkit-details-marker { display: none; }
.concert-venue-toggle::marker { content: ''; }
.concert-venue-toggle::after {
  content: '▾';
  margin-left: auto;
  font-size: 11px;
  color: var(--muted);
  transition: transform 0.2s ease;
}
.concert-venue-card[open] .concert-venue-toggle::after { transform: rotate(-180deg); }
.concert-venue-body { padding: 0 14px 14px; font-size: 13px; line-height: 1.45; }
.concert-venue-body p { margin: 0 0 8px; }
.concert-src { font-size: 11px; color: var(--muted); }
.concert-src a { color: inherit; text-decoration: underline; }
.concert-show-list { display: flex; flex-direction: column; gap: 6px; margin-bottom: 10px; }
.concert-show-list-tbd { margin: 0 0 10px; }
.concert-show-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
/* These chips sit in a one-per-line list next to their date rather than in a
   horizontally-scrolling row, so lay them out icon-beside-text (not the
   icon-above-text column the default .category-chip uses for scroll rows). */
.concert-show-row .category-chip {
  flex-direction: row;
  min-width: 0;
  padding: 6px 10px;
  gap: 5px;
}
.concert-show-row .category-chip-icon { font-size: 15px; height: auto; line-height: 1; }
.concert-show-date { font-size: 11px; color: var(--muted); }

/* Show rows with a tour photo (Melvin-supplied, from the show's own official
   ticketing/promo listing) render as a small card -- photo on top, chip +
   date below -- instead of the plain icon-pill layout above (still used for
   "concert-show-list-tbd" entries with no photo yet, e.g. Jay Chou). */
.concert-show-card {
  flex-direction: column;
  align-items: stretch;
  gap: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface-elevated);
  overflow: hidden;
  cursor: pointer; /* the whole card opens the ticket link, not just the chip */
}
@media (hover: hover) and (pointer: fine) {
  .concert-show-card:hover { border-color: var(--accent); }
}
.concert-show-photo {
  width: 100%;
  aspect-ratio: 2.3 / 1;
  object-fit: cover;
  display: block;
  background: var(--surface-secondary);
}
.concert-show-card .concert-show-info {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  padding: 8px 10px;
}
/* The chip is already inside a bordered photo card, so drop its own
   border/background/shadow here -- otherwise it reads as a card-in-a-card. */
.concert-show-card .category-chip {
  border: none;
  background: none;
  padding: 0;
  box-shadow: none;
  font-size: 12.5px;
}

/* ---- 5 Singapore Must-Eats ---- */
.must-eats-section { margin: 4px 0 14px; }
.must-eats-section.hidden { display: none; }
.must-eats-title { margin: 0 0 8px; font-size: 15px; font-weight: 800; letter-spacing: var(--tracking-tight); }
.must-eat-card {
  position: relative;
  display: flex;
  align-items: center;
  gap: 10px;
  border: 1px solid var(--border);
  background: var(--surface-elevated);
  border-radius: var(--radius-md);
  padding: 11px 12px;
  margin-bottom: 8px;
  box-shadow: var(--shadow-1);
}
.must-eat-icon { font-size: 24px; line-height: 1; flex: 0 0 auto; }
/* Photo preview: on a mouse/trackpad, the dish photo pops up above the card
   on hover (or keyboard focus of its "Find nearby" button). Touch devices
   have no hover concept, so there tapping the card instead pops the same
   photo up full-size in the middle of the screen (with a dimmed backdrop)
   until the user taps again, taps the backdrop, or taps another card. */
.must-eat-preview {
  position: absolute;
  left: 50%;
  bottom: calc(100% + 8px);
  transform: translateX(-50%) translateY(6px) scale(0.96);
  width: 180px;
  height: 120px;
  object-fit: cover;
  border-radius: var(--radius-md);
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.4);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s ease, transform 0.15s ease;
  z-index: 6;
}
@media (hover: hover) and (pointer: fine) {
  .must-eat-card:hover .must-eat-preview,
  .must-eat-card:focus-within .must-eat-preview {
    opacity: 1;
    transform: translateX(-50%) translateY(0) scale(1);
  }
}
@media (hover: none), (pointer: coarse) {
  .must-eat-preview {
    position: fixed;
    top: 50%;
    left: 50%;
    bottom: auto;
    width: min(82vw, 340px);
    height: auto;
    aspect-ratio: 3 / 2;
    object-fit: cover;
    transform: translate(-50%, -50%) scale(0.92);
    box-shadow: 0 20px 50px rgba(0, 0, 0, 0.5);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.15s ease, transform 0.15s ease;
    z-index: 3101;
  }
  .must-eat-card.is-open .must-eat-preview {
    opacity: 1;
    transform: translate(-50%, -50%) scale(1);
    pointer-events: auto;
  }
}
.must-eat-backdrop {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
  z-index: 3100;
}
.must-eat-backdrop.visible { display: block; }
.must-eat-text { flex: 1 1 auto; min-width: 0; }
.must-eat-name { font-size: 14px; font-weight: 700; }
.must-eat-tagline { font-size: 12px; color: var(--muted); margin-top: 1px; }
.must-eat-find-btn {
  flex: 0 0 auto;
  border: none;
  background: var(--accent);
  color: #fff;
  border-radius: var(--radius-pill);
  padding: 8px 13px;
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
  white-space: nowrap;
}
.must-eat-find-btn:hover { background: var(--accent-dark); }

/* ---- Guided Walk cards ----
   Same card layout + photo-preview mechanism as Must-Eats above (hover
   reveal on desktop, tap-to-enlarge with a dimmed backdrop on touch) --
   kept as its own parallel set of classes/rules rather than reusing the
   must-eat-* ones directly, so the two features' markup/JS stay
   independent and one can't accidentally break the other. The icon/name/
   tagline text block styling (.must-eat-icon/.must-eat-text/.must-eat-name/
   .must-eat-tagline) and the full-screen dim backdrop (.must-eat-backdrop)
   genuinely are generic, so those are still shared as-is. */
.guided-walk-card {
  position: relative;
  display: flex;
  align-items: center;
  gap: 10px;
  border: 1px solid var(--border);
  background: var(--surface-elevated);
  border-radius: var(--radius-md);
  padding: 11px 12px;
  margin-bottom: 8px;
  box-shadow: var(--shadow-1);
}
.guided-walk-preview {
  position: absolute;
  left: 50%;
  bottom: calc(100% + 8px);
  transform: translateX(-50%) translateY(6px) scale(0.96);
  width: 180px;
  height: 120px;
  object-fit: cover;
  border-radius: var(--radius-md);
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.4);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s ease, transform 0.15s ease;
  z-index: 6;
}
@media (hover: hover) and (pointer: fine) {
  .guided-walk-card:hover .guided-walk-preview,
  .guided-walk-card:focus-within .guided-walk-preview {
    opacity: 1;
    transform: translateX(-50%) translateY(0) scale(1);
  }
}
@media (hover: none), (pointer: coarse) {
  .guided-walk-preview {
    position: fixed;
    top: 50%;
    left: 50%;
    bottom: auto;
    width: min(82vw, 340px);
    height: auto;
    aspect-ratio: 3 / 2;
    object-fit: cover;
    transform: translate(-50%, -50%) scale(0.92);
    box-shadow: 0 20px 50px rgba(0, 0, 0, 0.5);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.15s ease, transform 0.15s ease;
    z-index: 3101;
  }
  .guided-walk-card.is-open .guided-walk-preview {
    opacity: 1;
    transform: translate(-50%, -50%) scale(1);
    pointer-events: auto;
  }
}
.guided-walk-find-btn {
  flex: 0 0 auto;
  border: none;
  background: var(--accent);
  color: #fff;
  border-radius: var(--radius-pill);
  padding: 8px 13px;
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
  white-space: nowrap;
}
.guided-walk-find-btn:hover { background: var(--accent-dark); }
/* Plain text CTA at the end of the guide-card list, pointing a prospective
   guide at guide-apply.html -- deliberately not styled as another card
   (it's not a place to visit), just a quiet link so it doesn't compete with
   the actual guides above for attention. */
.guided-walk-apply-cta {
  text-align: center;
  font-size: 12.5px;
  color: var(--muted);
  padding: 10px 12px 2px;
  margin-top: 2px;
  border-top: 1px dashed var(--border);
}
.guided-walk-apply-cta a { color: var(--accent); font-weight: 700; text-decoration: none; }
.guided-walk-apply-cta a:hover { text-decoration: underline; }

/* ---- Tix & Tours cards ----
   Same card + photo-preview mechanism as Must-Eats/Guided Walk above,
   again as its own parallel set of classes. A card here can also have no
   .ticket-preview image at all (for an attraction whose photo hasn't been
   added yet) -- it just renders as a plain icon+name+button row with no
   hover/tap photo, nothing extra needed for that case. */
.ticket-card {
  position: relative;
  display: flex;
  align-items: center;
  gap: 10px;
  border: 1px solid var(--border);
  background: var(--surface-elevated);
  border-radius: var(--radius-md);
  padding: 11px 12px;
  margin-bottom: 8px;
  box-shadow: var(--shadow-1);
}
.ticket-preview {
  position: absolute;
  left: 50%;
  bottom: calc(100% + 8px);
  transform: translateX(-50%) translateY(6px) scale(0.96);
  width: 180px;
  height: 120px;
  object-fit: cover;
  border-radius: var(--radius-md);
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.4);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s ease, transform 0.15s ease;
  z-index: 6;
}
@media (hover: hover) and (pointer: fine) {
  .ticket-card:hover .ticket-preview,
  .ticket-card:focus-within .ticket-preview {
    opacity: 1;
    transform: translateX(-50%) translateY(0) scale(1);
  }
}
@media (hover: none), (pointer: coarse) {
  .ticket-preview {
    position: fixed;
    top: 50%;
    left: 50%;
    bottom: auto;
    width: min(82vw, 340px);
    height: auto;
    aspect-ratio: 3 / 2;
    object-fit: cover;
    transform: translate(-50%, -50%) scale(0.92);
    box-shadow: 0 20px 50px rgba(0, 0, 0, 0.5);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.15s ease, transform 0.15s ease;
    z-index: 3101;
  }
  .ticket-card.is-open .ticket-preview {
    opacity: 1;
    transform: translate(-50%, -50%) scale(1);
    pointer-events: auto;
  }
}
.ticket-find-btn {
  flex: 0 0 auto;
  border: none;
  background: var(--accent);
  color: #fff;
  border-radius: var(--radius-pill);
  padding: 8px 13px;
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
  white-space: nowrap;
}
.ticket-find-btn:hover { background: var(--accent-dark); }

/* More Places photo cards -- same hover/tap photo-preview mechanism as
   Must-Eats/Guided Walk/Tix & Tours, kept as its own parallel set of
   classes/rules so none of these four features can break each other. */
.places-card {
  position: relative;
  display: flex;
  align-items: center;
  gap: 10px;
  border: 1px solid var(--border);
  background: var(--surface-elevated);
  border-radius: var(--radius-md);
  padding: 11px 12px;
  margin-bottom: 8px;
  box-shadow: var(--shadow-1);
}
.places-preview {
  position: absolute;
  left: 50%;
  bottom: calc(100% + 8px);
  transform: translateX(-50%) translateY(6px) scale(0.96);
  width: 180px;
  height: 120px;
  object-fit: cover;
  border-radius: var(--radius-md);
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.4);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s ease, transform 0.15s ease;
  z-index: 6;
}
@media (hover: hover) and (pointer: fine) {
  .places-card:hover .places-preview,
  .places-card:focus-within .places-preview {
    opacity: 1;
    transform: translateX(-50%) translateY(0) scale(1);
  }
}
@media (hover: none), (pointer: coarse) {
  .places-preview {
    position: fixed;
    top: 50%;
    left: 50%;
    bottom: auto;
    width: min(82vw, 340px);
    height: auto;
    aspect-ratio: 3 / 2;
    object-fit: cover;
    transform: translate(-50%, -50%) scale(0.92);
    box-shadow: 0 20px 50px rgba(0, 0, 0, 0.5);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.15s ease, transform 0.15s ease;
    z-index: 3101;
  }
  .places-card.is-open .places-preview {
    opacity: 1;
    transform: translate(-50%, -50%) scale(1);
    pointer-events: auto;
  }
}
.places-find-btn {
  flex: 0 0 auto;
  border: none;
  background: var(--accent);
  color: #fff;
  border-radius: var(--radius-pill);
  padding: 8px 13px;
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
  white-space: nowrap;
}
.places-find-btn:hover { background: var(--accent-dark); }

/* ---- Pill buttons — secondary/tertiary action hierarchy ----
   .pill-btn            plain secondary (bordered, neutral)
   .pill-btn.primary    solid accent — the one clear "do this" action in a row
   .pill-btn.ghost      tertiary / plain-text, no border, lowest emphasis */
.pill-btn {
  border: 1px solid var(--border);
  background: var(--surface-elevated);
  border-radius: var(--radius-pill);
  padding: 9px 14px;
  min-height: 38px;
  font-size: 13px;
  cursor: pointer;
  font-weight: 600;
  color: var(--ink);
}
.pill-btn.primary {
  background: var(--accent);
  border-color: var(--accent);
  color: white;
  box-shadow: var(--shadow-1);
}
.pill-btn.ghost {
  background: none;
  border-color: transparent;
  color: var(--muted);
  font-weight: 600;
  box-shadow: none;
}
.pill-btn.ghost:hover { color: var(--accent); border-color: var(--accent); }
.pill-btn:hover { opacity: 0.9; }

.quick-access-row {
  display: flex;
  gap: 8px;
  margin-bottom: 10px;
}
.quick-chip {
  flex: 1;
  border: 1px solid var(--border);
  background: var(--surface-elevated);
  border-radius: var(--radius-pill);
  padding: 9px 10px;
  min-height: 40px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink);
  cursor: pointer;
}
.quick-chip:hover { border-color: var(--accent); color: var(--accent); background: var(--accent-light); }
.quick-chip.unset {
  border-style: dashed;
  color: var(--muted);
}

.nearby-btn {
  display: block;
  width: 100%;
  text-align: center;
  margin-bottom: 10px;
}
.nearby-btn:disabled { opacity: 0.6; cursor: default; }

/* ---------- Nearby stops with live arrivals (Bus Arrival Time tab default) ----------
   Deliberately closer to a reference "nearby stops, live times already
   showing" bus-app layout (light blue ground, white cards, green service
   numbers, bold blue arrival time) than to Waypoint's usual white/grey
   panel styling elsewhere — the point of this section is to read at a
   glance, fast, like a transit-specific app rather than a general map app. */
.nearby-arrivals-section {
  background: var(--accent-light);
  border-radius: var(--radius-md);
  padding: 12px 12px 4px;
  margin-bottom: 4px;
}
.nearby-arrivals-heading {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 16px;
  font-weight: 700;
  letter-spacing: var(--tracking-tight);
  color: var(--ink);
  padding: 0 2px 8px;
}
.nearby-arrivals-refresh {
  border: none;
  background: none;
  line-height: 1;
  color: var(--accent);
  cursor: pointer;
  width: 30px;
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
}
.nearby-arrivals-refresh svg { width: 16px; height: 16px; }
.nearby-arrivals-refresh:hover { background: var(--accent-tint-weak); }
.nearby-arrivals-list .hint { padding: 4px 2px 10px; }

.nearby-stop-group { margin-bottom: 10px; }
.nearby-stop-header {
  display: flex;
  align-items: baseline;
  gap: 6px;
  padding: 8px 4px;
  min-height: 32px;
  cursor: pointer;
  font-size: 13.5px;
}
.nearby-stop-icon { font-size: 13px; }
.nearby-stop-name { font-weight: 700; color: var(--ink); }
.nearby-stop-code { color: var(--muted); font-size: 12px; }
.nearby-stop-distance { margin-left: auto; color: var(--muted); font-size: 12px; }
.nearby-stop-chevron { color: var(--muted); }

.nearby-stop-card {
  background: var(--surface-elevated);
  border-radius: var(--radius-md);
  padding: 10px 12px;
  box-shadow: var(--shadow-1);
}
.nearby-service-row {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 8px 0;
}
.nearby-service-row:not(:last-child) { border-bottom: 1px solid var(--border); }
.nearby-service-no {
  color: #16a34a;
  font-weight: 800;
  font-size: 16px;
  min-width: 34px;
  flex-shrink: 0;
}
.nearby-service-info { flex: 1; min-width: 0; }
.nearby-service-dest {
  color: var(--ink);
  font-size: 13px;
  overflow-wrap: anywhere;
}
.nearby-service-times { text-align: right; flex-shrink: 0; }
.nearby-service-primary {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 4px;
  color: var(--accent);
  font-weight: 800;
  font-size: 16px;
  white-space: nowrap;
}
.nearby-live-icon { font-size: 12px; }
.nearby-service-secondary {
  color: var(--muted);
  font-size: 12px;
  margin-top: 2px;
  white-space: nowrap;
}
.nearby-service-pill {
  display: inline-block;
  border: 1px solid var(--border);
  color: var(--muted);
  border-radius: 999px;
  padding: 3px 10px;
  font-size: 12px;
  font-weight: 700;
  margin: 4px 4px 0 0;
}
.nearby-service-error {
  color: var(--muted);
  font-size: 12.5px;
  padding: 4px 0;
}

.fav-section-divider {
  color: var(--muted);
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  margin: 8px 2px 0;
}

.parked-car-card {
  border: 1px solid var(--border);
  background: var(--surface-elevated);
  border-radius: var(--radius-md);
  padding: 12px;
  margin-bottom: 10px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  box-shadow: var(--shadow-1);
}
.parked-car-card.hidden { display: none; }
.parked-car-info { display: flex; align-items: center; gap: 10px; }
.parked-car-icon { font-size: 22px; flex-shrink: 0; }
.parked-car-title { font-size: 13.5px; font-weight: 700; }
.parked-car-sub { font-size: 12px; color: var(--muted); }
.parked-car-actions { display: flex; gap: 8px; }
.parked-car-actions .pill-btn { flex: 1; text-align: center; }

.hint {
  color: var(--muted);
  font-size: 12.5px;
  margin-top: 4px;
}

.dir-inputs {
  display: flex;
  flex-direction: column;
  gap: 6px;
  position: relative;
}
.dir-field { position: relative; display: flex; align-items: center; }
.dir-dot {
  position: absolute;
  left: -14px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  display: none;
}

#swapBtn { align-self: center; margin: -2px 0; }

/* Segmented control (iOS-style): one bordered track, active segment gets
   its own raised pill instead of each button carrying its own border. */
.mode-select {
  display: flex;
  gap: 2px;
  padding: 3px;
  background: var(--surface-secondary);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}
.mode-btn {
  flex: 1;
  min-height: 38px;
  padding: 8px 0;
  border: none;
  background: none;
  border-radius: calc(var(--radius-sm) - 3px);
  color: var(--label-secondary);
  cursor: pointer;
  font-size: 17px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.mode-btn svg { width: 19px; height: 19px; }
.mode-btn.active {
  background: var(--surface-elevated);
  color: var(--accent);
  box-shadow: var(--shadow-1);
}

.primary-btn {
  padding: 13px;
  min-height: 46px;
  border: none;
  border-radius: var(--radius-sm);
  background: var(--accent);
  color: white;
  font-weight: 600;
  font-size: 15px;
  letter-spacing: -0.01em;
  cursor: pointer;
  box-shadow: var(--shadow-1);
}
.primary-btn:hover:not(:disabled) { background: var(--accent-dark); }
.primary-btn:disabled { background: var(--gray-300); color: var(--label-tertiary); box-shadow: none; cursor: not-allowed; }

/* ---- Plan a Route (multi-stop trip planner) ---- */
.planroute-intro { margin: 0 0 14px; color: var(--muted); font-size: 13.5px; line-height: 1.4; }

.route-picking-banner {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  background: var(--accent-light); color: var(--accent); border-radius: var(--radius-sm);
  padding: 10px 12px; margin-bottom: 12px; font-size: 13px; font-weight: 600;
}
.route-picking-banner.hidden { display: none; }
.route-picking-banner .pill-btn { flex-shrink: 0; }

.route-slots { display: flex; flex-direction: column; gap: 8px; margin-bottom: 14px; }
.route-slot {
  display: flex; align-items: center; gap: 10px; width: 100%;
  border: 1px solid var(--border); background: var(--surface-elevated);
  border-radius: var(--radius-sm); padding: 12px; cursor: pointer; text-align: left;
  font-size: 14px; color: var(--label-secondary);
}
.route-slot.filled { color: var(--ink); border-color: var(--accent); }
.route-slot-num {
  flex-shrink: 0; width: 24px; height: 24px; border-radius: 50%;
  background: var(--surface-secondary); color: var(--label-secondary);
  display: flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 700;
}
.route-slot.filled .route-slot-num { background: var(--accent); color: white; }
.route-slot-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.route-slot-clear {
  flex-shrink: 0; width: 22px; height: 22px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  color: var(--label-tertiary); font-size: 13px;
}
.route-slot-clear.hidden { display: none; }
.route-slot-clear:hover { background: var(--surface-secondary); color: var(--ink); }

.route-mode-select { margin-bottom: 14px; }
.route-mode-btn {
  flex: 1; min-height: 38px; padding: 8px 0; border: none; background: none;
  border-radius: calc(var(--radius-sm) - 3px); color: var(--label-secondary);
  cursor: pointer; font-size: 17px; display: flex; align-items: center; justify-content: center;
}
.route-mode-btn svg { width: 19px; height: 19px; }
.route-mode-btn.active { background: var(--surface-elevated); color: var(--accent); box-shadow: var(--shadow-1); }

.route-plan-result { margin-top: 16px; }
.route-plan-result.hidden { display: none; }
.route-plan-leg {
  border: 1px solid var(--border); background: var(--surface-elevated);
  border-radius: var(--radius-sm); padding: 12px; margin-bottom: 8px;
}
.route-plan-leg-title { display: flex; align-items: center; gap: 8px; font-weight: 600; font-size: 14px; margin-bottom: 4px; }
.route-plan-leg-num {
  flex-shrink: 0; width: 20px; height: 20px; border-radius: 50%; background: var(--accent);
  color: white; font-size: 11px; font-weight: 700; display: flex; align-items: center; justify-content: center;
}
.route-plan-leg-sub { color: var(--muted); font-size: 12.5px; margin-bottom: 8px; }
.route-plan-total { text-align: center; color: var(--muted); font-size: 12.5px; margin-top: 4px; }

.itinerary-options-label {
  font-size: 11px;
  font-weight: 700;
  color: var(--accent);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  margin: 2px 2px 4px;
}
.itinerary-options-label.hidden { display: none; }

.itinerary-options {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.itinerary-options.hidden { display: none; }
.itinerary-option {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 11px 12px;
  min-height: 44px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-elevated);
  cursor: pointer;
  font-size: 13px;
  text-align: left;
}
.itinerary-option:hover { background: var(--gray-100); }
.itinerary-option.active {
  border-color: var(--accent);
  background: var(--accent-light);
}
.itinerary-option .io-modes {
  display: flex;
  align-items: center;
  gap: 3px;
  font-size: 14px;
}
.itinerary-option .io-modes .io-sep { color: var(--muted); font-size: 11px; }
.itinerary-option .io-main {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
  min-width: 0;
}
.itinerary-option .io-duration { font-weight: 600; }
.itinerary-option .io-time { color: var(--muted); font-size: 12px; }
.itinerary-option .io-fare { color: var(--accent); font-size: 12px; font-weight: 600; }
.itinerary-option .io-badge {
  font-size: 11px;
  color: var(--muted);
  white-space: nowrap;
}
.itinerary-option .io-badge-fastest {
  color: var(--accent);
  font-weight: 700;
}

.route-summary {
  background: var(--surface-elevated);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 13px 14px;
  font-size: 14px;
  box-shadow: var(--shadow-1);
}
.route-summary.hidden { display: none; }
.route-summary strong { font-size: 18px; letter-spacing: var(--tracking-tight); }

/* Route preview map — a small inline Leaflet map on the Directions results
   panel showing the route/itinerary before "Start Navigation" is tapped
   (mirrors Google Maps/Waze/Petal Maps). Distinct from #navMap (the
   full-screen overlay used during live turn-by-turn nav). Leaflet needs an
   explicit height on its container or it renders as a blank 0px box. */
.route-preview-map {
  height: 220px;
  border-radius: var(--radius-md);
  border: 1px solid var(--border);
  overflow: hidden;
  background: var(--panel-bg);
}
.route-preview-map.hidden { display: none; }
/* Same tile-mute treatment as .nav-map, for visual consistency between the
   preview map and the live nav map (see the comment above .nav-map .leaflet-tile-pane). */
.route-preview-map .leaflet-tile-pane {
  filter: grayscale(25%) saturate(1.2) brightness(1.08) contrast(0.92);
}

.ride-hailing-links.hidden { display: none; }
.ride-hailing-label {
  font-size: 11px;
  font-weight: 700;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  margin: 2px 2px 6px;
}
.ride-hailing-buttons {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}
.ride-hailing-btn {
  flex: 1 1 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-width: 70px;
  min-height: 40px;
  padding: 9px 8px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-elevated);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}
.ride-hailing-btn:hover { border-color: var(--accent); color: var(--accent); background: var(--accent-light); }
.ride-hailing-btn .rh-icon { font-size: 15px; }

.rain-banner {
  background: #eff6ff;
  border: 1px solid #bfdbfe;
  color: #1d4ed8;
  border-radius: var(--radius);
  padding: 10px 14px;
  font-size: 13px;
  font-weight: 600;
  margin-top: 8px;
}
.rain-banner.hidden { display: none; }

.dengue-banner {
  background: #fff7ed;
  border: 1px solid #fed7aa;
  color: #9a3412;
  border-radius: var(--radius);
  padding: 10px 14px;
  font-size: 13px;
  font-weight: 600;
  margin-top: 8px;
}
.dengue-banner.hidden { display: none; }

.flood-banner {
  background: #ecfeff;
  border: 1px solid #a5f3fc;
  color: #155e75;
  border-radius: var(--radius);
  padding: 10px 14px;
  font-size: 13px;
  font-weight: 600;
  margin-top: 8px;
}
.flood-banner.hidden { display: none; }

.flood-alert-marker { font-size: 20px; line-height: 1; filter: drop-shadow(0 1px 2px rgba(0,0,0,0.4)); }

.route-steps {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.route-steps li {
  padding: 9px 4px;
  font-size: 13px;
  border-bottom: 1px solid var(--border);
}
.route-steps li:last-child { border-bottom: none; }
.route-step-row, .route-steps li:not(.route-step) {
  display: flex;
  gap: 8px;
  align-items: flex-start;
}
.step-num {
  color: var(--muted);
  min-width: 18px;
  font-weight: 600;
}

/* Colored MRT/LRT line badge — background/text color are set inline per
   leg from the live GTFS feed (e.g. blue for Downtown Line, brown for
   Thomson-East Coast), so only layout lives here. */
.line-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.02em;
  border-radius: 4px;
  padding: 1px 5px;
  line-height: 1.5;
}
.itinerary-option .io-modes .line-badge {
  font-size: 10px;
  padding: 1px 4px;
}
.step-num-badge {
  min-width: 18px;
  flex-shrink: 0;
  margin-top: 1px;
}

.step-stops-row {
  margin-top: 6px;
  margin-left: 26px;
}
.stops-list-btn {
  border: 1px solid var(--border);
  background: var(--surface-elevated);
  border-radius: var(--radius-pill);
  padding: 6px 11px;
  min-height: 30px;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
}
.stops-list-btn:hover { background: var(--gray-100); }
.stops-list-btn.active {
  border-color: var(--accent);
  background: var(--accent-light);
  color: var(--accent);
}
.stops-list-panel {
  margin-top: 6px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-elevated);
  padding: 8px 10px 8px 26px;
  font-size: 12px;
  color: var(--label-primary);
  max-height: 260px;
  overflow-y: auto;
}
.stops-list-panel li { padding: 3px 0; }
.stops-list-panel .stop-tag {
  color: var(--muted);
  font-size: 11px;
  font-weight: 600;
}
.stops-list-panel.hidden { display: none; }

.step-wake-row {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 6px;
  margin-left: 26px;
}
.wake-btn {
  border: 1px solid var(--border);
  background: var(--surface-elevated);
  border-radius: var(--radius-pill);
  padding: 6px 11px;
  min-height: 30px;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
}
.wake-btn:hover { background: var(--gray-100); }
.wake-btn.active {
  border-color: var(--danger);
  background: var(--danger-tint);
  color: var(--danger);
}
.wake-status {
  font-size: 12px;
  color: var(--muted);
}

.step-arrivals-row {
  margin-top: 6px;
  margin-left: 26px;
}
.step-arrivals-btn-row {
  display: flex;
  align-items: center;
  gap: 8px;
}
.fav-quick-btn {
  border: none;
  background: none;
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  color: #d97706;
  padding: 4px;
}
.arrivals-btn {
  border: 1px solid var(--border);
  background: var(--surface-elevated);
  border-radius: var(--radius-pill);
  padding: 6px 11px;
  min-height: 30px;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
}
.arrivals-btn:hover { background: var(--gray-100); }
.arrivals-btn.active {
  border-color: var(--accent);
  background: var(--accent-light);
  color: var(--accent);
}
.arrivals-panel {
  margin-top: 6px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-elevated);
  padding: 7px 10px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.arrivals-panel.hidden { display: none; }
.arrivals-meta {
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 11px;
  color: var(--muted);
  padding-bottom: 4px;
  margin-bottom: 2px;
  border-bottom: 1px solid var(--border);
}
.arrivals-live-dot {
  color: #16a34a;
  font-size: 9px;
  animation: live-pulse 1.6s ease-in-out infinite;
}
@keyframes live-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.35; }
}
.arrivals-legend {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 10.5px;
  color: var(--muted);
  padding-bottom: 5px;
  margin-bottom: 2px;
  flex-wrap: wrap;
}
.arrivals-legend .load-dot { margin-left: 2px; }
.arrivals-legend span:not(.load-dot) { margin-right: 6px; }
.arrival-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 10px;
  font-size: 12.5px;
  padding: 3px 0;
}
.arrival-row:not(:last-child) { border-bottom: 1px solid var(--border); }
.arrival-service { font-weight: 700; min-width: 32px; }
.arrival-times {
  color: var(--muted);
  text-align: right;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  flex-wrap: wrap;
}
.arrival-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.load-dot {
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--border);
}
.load-dot.load-sea { background: #16a34a; }
.load-dot.load-sda { background: #d97706; }
.load-dot.load-lsd { background: #dc2626; }
.load-dot.load-unknown { background: var(--border); }

.bus-badge {
  font-size: 9px;
  font-weight: 700;
  color: var(--muted);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 0 3px;
  line-height: 1.4;
}
.wc-badge {
  border: none;
  font-size: 11px;
  padding: 0;
}

.driving-extra {
  background: var(--surface-elevated);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 12px;
  font-size: 12.5px;
  box-shadow: var(--shadow-1);
}
.driving-extra.hidden { display: none; }
.driving-extra-title {
  font-weight: 700;
  font-size: 12px;
  margin-bottom: 6px;
}
.driving-extra-row {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  padding: 3px 0;
  color: var(--muted);
}
.driving-extra-row:not(:last-child) { border-bottom: 1px solid var(--border); }
.driving-extra-lots { font-weight: 700; color: var(--ink); }
a.driving-extra-link-row {
  text-decoration: none;
  cursor: pointer;
}
a.driving-extra-link-row:hover { color: var(--accent); }
a.driving-extra-link-row:hover .driving-extra-lots { color: var(--accent); }
.driving-extra-note {
  margin-top: 4px;
  font-size: 11px;
  color: var(--muted);
}
.driving-extra-note a { color: var(--accent); }
.driving-extra-link {
  display: block;
  text-align: center;
  margin-top: 8px;
  text-decoration: none;
}
.traffic-dot {
  display: inline-block;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  margin-right: 4px;
  vertical-align: middle;
}
.traffic-dot-red { background: #dc2626; }
.traffic-dot-amber { background: #f59e0b; }
.arrivals-error {
  font-size: 12px;
  color: var(--muted);
  padding: 3px 0;
}

.fav-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.fav-item {
  border: 1px solid var(--border);
  background: var(--surface-elevated);
  border-radius: var(--radius-md);
  padding: 12px;
  box-shadow: var(--shadow-1);
}
.fav-header-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 8px;
}
.fav-label { font-size: 13.5px; }
.fav-code { color: var(--muted); font-weight: 400; }
.fav-remove-btn {
  border: none;
  background: none;
  color: var(--muted);
  cursor: pointer;
  font-size: 13px;
  padding: 2px 4px;
  flex-shrink: 0;
}
.fav-remove-btn:hover { color: var(--danger); }
.fav-item .arrivals-panel { margin-left: 0; }
#favEmptyHint.hidden { display: none; }

.wake-alert {
  position: fixed;
  left: 50%;
  bottom: max(20px, env(safe-area-inset-bottom));
  transform: translateX(-50%);
  z-index: 2100;
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--danger);
  color: white;
  padding: 13px 16px;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-3);
  max-width: min(92vw, 420px);
  animation: wake-pulse 1s ease-in-out infinite, toast-in var(--duration-base) var(--ease-spring);
}
.wake-alert.hidden { display: none; }
.wake-alert-text { font-size: 14px; font-weight: 600; }
.wake-alert .pill-btn {
  background: white;
  color: var(--danger);
  border-color: white;
  flex-shrink: 0;
}

@keyframes wake-pulse {
  0%, 100% { box-shadow: 0 2px 10px rgba(0,0,0,0.08); }
  50% { box-shadow: 0 2px 24px rgba(220,38,38,0.6); }
}

.install-banner {
  position: fixed;
  left: 50%;
  bottom: max(20px, env(safe-area-inset-bottom));
  transform: translateX(-50%);
  z-index: 2100;
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--material-dark);
  backdrop-filter: var(--material-blur-light);
  -webkit-backdrop-filter: var(--material-blur-light);
  color: white;
  padding: 13px 16px;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-3);
  max-width: min(92vw, 420px);
  flex-wrap: wrap;
  animation: toast-in var(--duration-base) var(--ease-spring);
}
.install-banner.hidden { display: none; }
.install-banner-text { font-size: 13.5px; font-weight: 600; }
.install-banner-actions { display: flex; gap: 8px; flex-shrink: 0; margin-left: auto; }
.install-banner .pill-btn.ghost { color: rgba(255,255,255,0.7); border-color: rgba(255,255,255,0.3); }
.install-banner .pill-btn.ghost:hover { color: white; border-color: white; }

.share-footer {
  margin: 8px 16px 16px;
  padding: 11px;
  min-height: 44px;
  border: 1px dashed var(--border);
  border-radius: var(--radius-md);
  background: none;
  color: var(--muted);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  text-align: center;
}
.share-footer:hover {
  border-color: var(--accent);
  color: var(--accent);
  background: var(--accent-light);
}

.support-footer {
  display: block;
  margin: 8px 16px 16px;
  padding: 11px;
  min-height: 44px;
  border: 1px solid #ffdd00;
  border-radius: var(--radius-md);
  background: #fff9db;
  color: #7a5b00;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  text-align: center;
  text-decoration: none;
}
.support-footer:hover {
  background: #ffdd00;
  color: #1a1a1a;
  border-color: #e6c700;
}

.credits-footer {
  margin: 0 16px 16px;
  padding: 12px 10px 4px;
  text-align: center;
}
.credits-author {
  margin: 0 0 2px;
  font-size: 12px;
  font-weight: 700;
  color: var(--muted);
}
.credits-author a {
  color: var(--accent);
  text-decoration: none;
}
.credits-author a:hover { text-decoration: underline; }
.credits-label {
  margin: 0 0 8px;
  font-size: 11px;
  color: var(--muted);
  opacity: 0.85;
}
/* "More tools by me" is tucked behind a native <details> disclosure so it
   stays out of the way by default — a discreet text toggle rather than a
   permanently-visible row of links. */
.more-tools { margin-top: 2px; }
.more-tools-toggle {
  list-style: none;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 11px;
  font-weight: 600;
  color: var(--muted);
  opacity: 0.75;
  cursor: pointer;
  user-select: none;
  padding: 2px 4px;
}
.more-tools-toggle:hover { opacity: 1; color: var(--accent); }
.more-tools-toggle::-webkit-details-marker { display: none; }
.more-tools-toggle::marker { content: ''; }
.more-tools-toggle::after {
  content: '▾';
  font-size: 9px;
  transition: transform 0.2s ease;
}
.more-tools[open] .more-tools-toggle::after { transform: rotate(-180deg); }
.more-tools .credits-links { margin-top: 8px; }

.credits-links {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 6px 10px;
}
.credits-links li {
  margin: 0;
}
.credits-links a {
  font-size: 12px;
  color: var(--accent);
  text-decoration: none;
}
.credits-links a:hover {
  text-decoration: underline;
}

.toast {
  position: fixed;
  bottom: max(20px, env(safe-area-inset-bottom));
  left: 50%;
  transform: translateX(-50%);
  background: var(--material-dark);
  backdrop-filter: var(--material-blur-light);
  -webkit-backdrop-filter: var(--material-blur-light);
  color: white;
  padding: 12px 18px;
  border-radius: var(--radius-lg);
  font-size: 13.5px;
  line-height: 1.4;
  max-width: min(92vw, 420px);
  z-index: 2000;
  box-shadow: var(--shadow-3);
  animation: toast-in var(--duration-base) var(--ease-spring);
}
.toast.hidden { display: none; }

@keyframes toast-in {
  from { transform: translate(-50%, 12px); opacity: 0; }
  to { transform: translate(-50%, 0); opacity: 1; }
}

.nav-start-btn.hidden { display: none; }

.nav-map-overlay {
  position: fixed;
  inset: 0;
  z-index: 2900; /* below .nav-banner (3000) so the instruction strip sits on top */
  background: var(--panel-bg);
  animation: sheet-backdrop-in var(--duration-base) var(--ease-snappy);
}
.nav-map-overlay.hidden { display: none; }
.nav-map {
  width: 100%;
  height: 100%;
  transform-origin: 50% 50%;
  transition: transform 0.35s ease-out;
}
/* Mutes the default OSM raster palette into something closer to a designed
   basemap (softer greys, less saturated roads/land-use fills) without
   swapping tile providers — every alternative with that cleaner look
   (CARTO, the newer Esri basemap service) now gates raster tiles behind a
   free-signup API key, which isn't worth the extra setup step just for a
   nicer palette. Only the tile layer is filtered, not markers/route lines,
   so the live puck and traffic overlay stay fully saturated. */
.nav-map .leaflet-tile-pane {
  filter: grayscale(25%) saturate(1.2) brightness(1.08) contrast(0.92);
}

/* A live-position "puck" with a heading arrow — reads more like "you are
   here, facing this way" on a driving map than a plain dot. */
.nav-live-puck {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--accent);
  border: 3px solid white;
  box-shadow: 0 0 0 2px var(--accent), 0 2px 8px rgba(0,0,0,0.45);
  display: flex;
  align-items: center;
  justify-content: center;
}
.nav-live-puck-arrow {
  width: 0;
  height: 0;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-bottom: 9px solid white;
  transition: transform 0.25s ease;
}

/* Start (A) and destination (B) markers — plain, not counter-rotated
   against the map's course-up spin like the puck arrow is. A pin's anchor
   point has to stay exactly on its coordinate, and counter-rotating it
   around its own center would visibly drag the tip off that spot; leaving
   it be means the glyph can end up tilted mid-turn, which is an acceptable
   tradeoff next to a pin that drifts off its actual location. */
.nav-start-marker {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: #16a34a;
  border: 3px solid white;
  box-shadow: 0 0 0 2px #16a34a, 0 2px 6px rgba(0,0,0,0.4);
}
.nav-dest-marker {
  font-size: 26px;
  line-height: 1;
  filter: drop-shadow(0 2px 3px rgba(0,0,0,0.45));
}

.nav-speed-badge {
  position: absolute;
  left: 14px;
  bottom: 24px;
  z-index: 2901;
  width: 58px;
  height: 58px;
  border-radius: 50%;
  background: var(--material-dark);
  backdrop-filter: var(--material-blur-light);
  -webkit-backdrop-filter: var(--material-blur-light);
  border: 3px solid #fff;
  color: white;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  box-shadow: var(--shadow-2);
}
.nav-speed-badge.hidden { display: none; }
.nav-speed-badge #navSpeedValue { font-size: 19px; font-weight: 700; line-height: 1; }
.nav-speed-badge .nav-speed-unit { font-size: 8px; color: rgba(255,255,255,0.7); margin-top: 1px; }

/* True-north indicator — sits outside the rotated map container, so its own
   needle rotates to whatever angle the map's course-up rotation put true
   north at (0 = up, when the map is shown north-up / not currently
   following). Lets you tell which way is actually north while the map
   itself is spun to match your direction of travel. */
.nav-compass {
  position: absolute;
  right: 14px;
  top: 84px;
  z-index: 2901;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: rgba(255,255,255,0.94);
  box-shadow: 0 2px 8px rgba(0,0,0,0.25);
  display: flex;
  align-items: center;
  justify-content: center;
}
.nav-compass.hidden { display: none; }
.nav-compass-needle {
  display: flex;
  flex-direction: column;
  align-items: center;
  font-size: 10px;
  font-weight: 700;
  color: var(--danger);
  line-height: 1;
  transition: transform 0.35s ease-out;
}
.nav-compass-tri { font-size: 9px; margin-bottom: 1px; }

.nav-recenter-btn {
  position: absolute;
  right: 14px;
  bottom: 24px;
  z-index: 2901;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: none;
  background: var(--material-thick);
  backdrop-filter: var(--material-blur-light);
  -webkit-backdrop-filter: var(--material-blur-light);
  box-shadow: var(--shadow-2);
  font-size: 18px;
  color: var(--label-primary);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}
.nav-recenter-btn svg { width: 20px; height: 20px; }

.nav-bottom-sheet {
  position: absolute;
  left: 50%;
  bottom: 24px;
  transform: translateX(-50%);
  z-index: 2901;
  background: var(--material-thick);
  backdrop-filter: var(--material-blur-light);
  -webkit-backdrop-filter: var(--material-blur-light);
  border-radius: var(--radius-pill);
  padding: 9px 22px;
  box-shadow: var(--shadow-2);
  display: flex;
  align-items: baseline;
  gap: 10px;
  white-space: nowrap;
}
.nav-bottom-sheet.hidden { display: none; }
.nav-bottom-eta { font-size: 17px; font-weight: 700; color: var(--ink); }
.nav-bottom-meta { font-size: 13px; color: var(--muted); display: flex; align-items: baseline; gap: 6px; }
.nav-bottom-dot { opacity: 0.6; }

.nav-banner {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 3000;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  padding-top: max(14px, env(safe-area-inset-top));
  background: var(--material-dark);
  backdrop-filter: var(--material-blur);
  -webkit-backdrop-filter: var(--material-blur);
  color: white;
  box-shadow: var(--shadow-3);
  border-radius: 0 0 var(--radius-lg) var(--radius-lg);
}
.nav-banner.hidden { display: none; }
.nav-banner-icon {
  font-size: 24px;
  flex-shrink: 0;
  width: 42px;
  height: 42px;
  border-radius: 50%;
  background: rgba(255,255,255,0.12);
  display: flex;
  align-items: center;
  justify-content: center;
}
.nav-banner-main { flex: 1; min-width: 0; }
.nav-banner-distance { font-size: 19px; font-weight: 700; letter-spacing: -0.2px; }
.nav-banner-instruction {
  font-size: 12.5px;
  color: rgba(255,255,255,0.75);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-top: 1px;
}
.nav-banner-btn {
  border: none;
  background: rgba(255,255,255,0.15);
  color: white;
  border-radius: 50%;
  width: 36px;
  height: 36px;
  min-width: 36px;
  font-size: 14px;
  cursor: pointer;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}
.nav-banner-btn svg { width: 16px; height: 16px; }
.nav-banner-btn:hover { background: rgba(255,255,255,0.25); }
.nav-banner-stop { background: rgba(220,38,38,0.85); }
.nav-banner-stop:hover { background: rgba(220,38,38,1); }

.route-steps li.nav-current-step {
  background: var(--accent-light);
  border-radius: var(--radius-sm);
  margin: 0 -4px;
  padding-left: 8px;
  padding-right: 4px;
}

.whatsapp-float {
  position: fixed;
  right: 20px;
  bottom: max(20px, env(safe-area-inset-bottom));
  z-index: 1900;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: #25D366;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: var(--shadow-2);
  text-decoration: none;
  transition: transform var(--duration-fast) var(--ease-snappy), box-shadow var(--duration-fast) var(--ease-snappy);
}
.whatsapp-float:hover {
  transform: scale(1.06);
  box-shadow: var(--shadow-3);
}
.whatsapp-float:active {
  transform: scale(0.94);
}
.whatsapp-float svg { width: 28px; height: 28px; fill: white; }

@media (max-width: 720px) {
  #sidebar { max-width: none; }
  .whatsapp-float { right: 16px; bottom: 16px; width: 50px; height: 50px; }
  .whatsapp-float svg { width: 25px; height: 25px; }
  .brand-tagline { display: none; }
  /* Cap the weather pill on phones so it can't eat the whole topbar row —
     the 5 icon/lang buttons after it don't shrink, so without a cap here
     the flag+name next to it got squeezed to nothing (see .brand above). */
  .weather-widget { max-width: 34vw; }
}

/* =========================================================================
   DARK-MODE THEME TOGGLE — a pill-shaped switch in the topbar (styled after
   the reference's clock-side switch), not just an icon button, so the
   control itself reads as an explicit on/off toggle rather than an action
   button. Lives in #topbar's .topbar-actions, after the other icon buttons.
   ========================================================================= */
.theme-toggle {
  border: none;
  background: none;
  padding: 0;
  cursor: pointer;
  flex-shrink: 0;
  display: flex;
  align-items: center;
}
.theme-toggle-track {
  position: relative;
  width: 48px;
  height: 28px;
  border-radius: var(--radius-pill);
  background: var(--surface-fill-strong);
  border: 1px solid var(--separator);
  padding: 2px;
  box-sizing: border-box;
  transition: background var(--duration-base) var(--ease-snappy);
}
.theme-toggle-thumb {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: #fff;
  color: #d97706;
  box-shadow: var(--shadow-1);
  display: flex;
  align-items: center;
  justify-content: center;
  transform: translateX(0);
  transition: transform var(--duration-base) var(--ease-snappy), background var(--duration-base) var(--ease-snappy), color var(--duration-base) var(--ease-snappy);
}
.theme-toggle-thumb svg { width: 14px; height: 14px; }
.theme-toggle-thumb .theme-icon-moon { display: none; }
[data-theme="dark"] .theme-toggle-track { background: rgba(255, 255, 255, 0.1); }
[data-theme="dark"] .theme-toggle-thumb {
  transform: translateX(20px);
  background: #1c1c1e;
  color: #9ec6ff;
}
[data-theme="dark"] .theme-toggle-thumb .theme-icon-sun { display: none; }
[data-theme="dark"] .theme-toggle-thumb .theme-icon-moon { display: block; }

/* =========================================================================
   LIVE / HERO NUMBER — a small reusable pair (value + unit) used on
   Waypoint's own live-countdown surfaces (bus arrivals, below). In light
   mode this stays a modest inline extension of the existing type scale; in
   dark mode it becomes the reference's oversized stacked digit + label.
   ========================================================================= */
.hero-number {
  display: inline-flex;
  align-items: baseline;
  gap: 3px;
}
.hero-number-unit {
  font-size: 0.62em;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  opacity: 0.75;
}

/* "LIVE" pill — the reference's blue status badge. Plain inline text in
   light mode (matches the existing .arrivals-meta "Live · updated…" line);
   becomes a solid pill only in dark mode. */
.live-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 10px;
  font-weight: 700;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* =========================================================================
   DARK-MODE OVERRIDES for hard-coded (non-token) colors and for the
   specific live-data surfaces called out in the design brief: bus arrivals
   (Bus Arrival Time tab + the Favourites/Directions arrivals panels) and
   the live weather readout. Everything else re-themes automatically from
   the token block near the top of this file.
   ========================================================================= */

/* ---- Alert/status banners: translucent-on-black instead of pastel-on-white,
   keeping each banner's hue identity (red/amber/blue/cyan) ---- */
[data-theme="dark"] .train-alert-banner {
  background: rgba(255, 105, 97, 0.14);
  border-bottom-color: rgba(255, 105, 97, 0.35);
  color: #ffb4ae;
}
[data-theme="dark"] .train-alert-dismiss { color: #ffb4ae; }
[data-theme="dark"] .offline-banner {
  background: rgba(255, 179, 64, 0.14);
  border-bottom-color: rgba(255, 179, 64, 0.35);
  color: #ffcf8a;
}
[data-theme="dark"] .rain-banner {
  background: rgba(59, 130, 246, 0.14);
  border-color: rgba(59, 130, 246, 0.35);
  color: #9ec6ff;
}
[data-theme="dark"] .dengue-banner {
  background: rgba(255, 179, 64, 0.14);
  border-color: rgba(255, 179, 64, 0.35);
  color: #ffcf8a;
}
[data-theme="dark"] .flood-banner {
  background: rgba(56, 189, 248, 0.14);
  border-color: rgba(56, 189, 248, 0.35);
  color: #9adcf5;
}
[data-theme="dark"] .attraction-food-tip {
  background: rgba(255, 179, 64, 0.12);
  border-color: rgba(255, 179, 64, 0.3);
  color: var(--label-primary);
}
[data-theme="dark"] .attraction-guide-card {
  background: rgba(255, 255, 255, 0.04);
  border-color: var(--border);
}
[data-theme="dark"] .attraction-guide-verified { color: #4ade80; }

/* ---- Bus Arrival Time tab: "Nearby" section + each stop's card go from
   filled/shadowed to outlined, per the reference's card treatment. ---- */
[data-theme="dark"] .nearby-arrivals-section {
  background: transparent;
  border: 1px solid var(--separator);
}
[data-theme="dark"] .nearby-stop-card {
  background: transparent;
  border: 1px solid var(--separator);
  box-shadow: none;
}
[data-theme="dark"] .nearby-service-no { color: var(--label-primary); }

/* The hero countdown itself: stacked oversized digit + small "MIN" label,
   white by default, green when the bus/train is arriving right now (the
   reference's "0 MIN" treatment) instead of always-blue. */
[data-theme="dark"] .nearby-service-primary {
  flex-direction: column;
  align-items: flex-end;
  gap: 0;
  color: var(--label-primary);
}
[data-theme="dark"] .nearby-live-icon { display: none; } /* the big digit itself is now the "this is live" signal */
[data-theme="dark"] .nearby-service-primary .hero-number {
  flex-direction: column;
  align-items: flex-end;
  gap: 0;
}
[data-theme="dark"] .nearby-service-primary .hero-number-value {
  font-size: 34px;
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.02em;
}
[data-theme="dark"] .nearby-service-primary .hero-number-unit {
  margin-top: 2px;
  font-size: 11px;
}
[data-theme="dark"] .nearby-service-primary.arrival-now { color: var(--success); }

/* Favourites/Directions arrivals panel: outlined card + a real "LIVE" pill,
   and each service's chip goes green once it's arriving right now. */
[data-theme="dark"] .arrivals-panel { background: transparent; border-color: var(--separator); }
[data-theme="dark"] .live-badge {
  background: var(--accent);
  color: #fff;
  border-radius: var(--radius-pill);
  padding: 2px 8px;
  font-size: 9.5px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
[data-theme="dark"] .live-badge .arrivals-live-dot { display: none; } /* the pill itself is the live signal now */
[data-theme="dark"] .arrival-chip.arrival-now { color: var(--success); font-weight: 700; }

/* ---- Live weather readout (temperature/humidity/wind sheet): same
   outlined-cell + hero-number treatment as the bus arrivals above. ---- */
[data-theme="dark"] .weather-panel-grid > div {
  background: transparent;
  border: 1px solid var(--separator);
}
[data-theme="dark"] .weather-panel-label {
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: 9.5px;
}
[data-theme="dark"] .weather-panel-value {
  font-size: 21px;
  font-weight: 800;
  letter-spacing: -0.01em;
}

/* ---------- Split Bill tab (see splitbill.js) ---------- */
.sb-section { display: flex; flex-direction: column; gap: 8px; margin-bottom: 14px; }
.sb-section.hidden { display: none; }
.sb-section-title { font-size: 12px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; color: var(--label-secondary); }
.sb-empty { margin: 0; }

.sb-input {
  width: 100%; min-height: 44px; padding: 10px 12px;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  font-size: 15px; background: var(--surface-secondary); color: var(--label-primary);
  font-family: inherit;
}
.sb-input::placeholder { color: var(--label-tertiary); }
.sb-input:focus { outline: none; background: var(--surface-elevated); border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-tint-weak); }
.sb-input.sb-readonly { color: var(--label-secondary); background: var(--surface-fill); }
select.sb-input { appearance: auto; }

.sb-inline-form { display: flex; gap: 8px; align-items: center; }
.sb-inline-form .pill-btn { flex-shrink: 0; min-height: 44px; }

.sb-people { display: flex; flex-wrap: wrap; gap: 6px; }
.sb-person-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 4px 4px 4px; border: 1px solid var(--border); border-radius: var(--radius-pill);
  background: var(--surface-elevated); font-size: 14px; font-weight: 600; color: var(--ink);
}
.sb-person-name { max-width: 9em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sb-avatar {
  flex-shrink: 0; width: 26px; height: 26px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 700; color: #fff;
  background: hsl(var(--sb-hue, 220), 62%, 48%);
}
.sb-chip-x {
  flex-shrink: 0; width: 28px; height: 28px; border: none; border-radius: 50%;
  background: none; color: var(--label-tertiary); font-size: 13px; cursor: pointer;
}
.sb-chip-x:hover { background: var(--surface-fill); color: var(--danger); }

.sb-expenses { display: flex; flex-direction: column; gap: 6px; }
.sb-expense {
  display: flex; align-items: center; gap: 10px; padding: 10px 6px 10px 12px;
  border: 1px solid var(--border); border-radius: var(--radius-md);
  background: var(--surface-elevated); cursor: pointer;
}
.sb-expense:hover { border-color: var(--accent); }
.sb-expense-main { flex: 1; min-width: 0; }
.sb-expense-desc { font-weight: 600; font-size: 14.5px; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sb-expense-meta { font-size: 12.5px; color: var(--label-secondary); margin-top: 2px; }
.sb-expense-amt { font-weight: 700; font-size: 15px; color: var(--ink); font-variant-numeric: tabular-nums; }

.sb-expense-form {
  display: flex; flex-direction: column; gap: 10px; padding: 12px;
  border: 1px solid var(--accent); border-radius: var(--radius-md); background: var(--surface-elevated);
}
.sb-expense-form.hidden, .nearby-btn.hidden { display: none; }
.sb-row { display: flex; gap: 8px; align-items: flex-end; }
.sb-row > * { flex: 1; min-width: 0; }
.sb-amount-wrap { position: relative; display: flex; align-items: center; }
.sb-amount-wrap .sb-currency {
  position: absolute; left: 12px; font-size: 14px; font-weight: 600; color: var(--label-secondary); pointer-events: none;
}
.sb-amount-wrap .sb-amount { padding-left: 38px; font-variant-numeric: tabular-nums; }
.sb-select-wrap { display: flex; flex-direction: column; gap: 3px; }
.sb-mini-label { font-size: 11.5px; font-weight: 600; color: var(--label-secondary); }
.sb-toggles { align-items: center; flex-wrap: wrap; }
.sb-toggles > * { flex: 0 0 auto; }
.sb-check { display: inline-flex; align-items: center; gap: 6px; font-size: 14px; color: var(--ink); cursor: pointer; }
.sb-check input { width: 18px; height: 18px; accent-color: var(--accent); }

.sb-seg { display: flex; padding: 3px; gap: 3px; border-radius: var(--radius-sm); background: var(--surface-fill); }
.sb-seg-btn {
  flex: 1; min-height: 36px; border: none; border-radius: 8px; background: none;
  font-size: 13px; font-weight: 600; color: var(--label-secondary); cursor: pointer;
}
.sb-seg-btn.active { background: var(--surface-elevated); color: var(--ink); box-shadow: var(--shadow-1); }

.sb-split-people { display: flex; flex-direction: column; gap: 4px; }
.sb-split-row { display: flex; align-items: center; gap: 10px; min-height: 44px; padding: 0 4px; cursor: pointer; }
.sb-split-row input[type="checkbox"] { width: 18px; height: 18px; accent-color: var(--accent); }
.sb-split-name { flex: 1; min-width: 0; font-size: 14.5px; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sb-amount-small { width: 120px; flex: 0 0 120px; }
.sb-amount-small .sb-input { min-height: 38px; padding-top: 6px; padding-bottom: 6px; }
.sb-form-actions { justify-content: flex-end; }
.sb-form-actions > * { flex: 0 0 auto; }

.sb-summary { display: flex; flex-direction: column; gap: 4px; }
.sb-total-row {
  display: flex; justify-content: space-between; align-items: baseline;
  padding: 10px 12px; border-radius: var(--radius-sm); background: var(--accent-light);
  color: var(--accent); font-size: 14px; font-weight: 600;
}
.sb-total-row strong { font-size: 18px; font-variant-numeric: tabular-nums; }
.sb-balance { display: flex; align-items: center; gap: 10px; padding: 8px 4px; border-bottom: 1px solid var(--separator); }
.sb-balance:last-child { border-bottom: none; }
.sb-balance-main { flex: 1; min-width: 0; }
.sb-balance-name { font-weight: 600; font-size: 14.5px; color: var(--ink); }
.sb-balance-meta { font-size: 12px; color: var(--label-secondary); font-variant-numeric: tabular-nums; }
.sb-net { font-size: 12.5px; font-weight: 700; padding: 4px 8px; border-radius: var(--radius-pill); white-space: nowrap; }
.sb-net.pos { color: var(--success); background: rgba(22, 163, 74, 0.12); }
.sb-net.neg { color: var(--danger); background: rgba(220, 38, 38, 0.1); }
.sb-net.zero { color: var(--label-secondary); background: var(--surface-fill); }

.sb-transfers { display: flex; flex-direction: column; gap: 6px; margin-top: 4px; }
.sb-transfer {
  display: flex; align-items: center; gap: 10px; padding: 10px 8px 10px 12px;
  border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--surface-elevated);
}
.sb-transfer.done { opacity: 0.55; }
.sb-transfer.done .sb-transfer-amt { text-decoration: line-through; }
.sb-transfer-text { flex: 1; min-width: 0; font-size: 14px; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sb-arrow { color: var(--label-tertiary); margin: 0 4px; }
.sb-transfer-amt { font-weight: 700; font-size: 15px; color: var(--ink); font-variant-numeric: tabular-nums; }
.sb-paid-btn { flex-shrink: 0; padding: 6px 10px; min-height: 32px; font-size: 12px; }
.sb-settled { text-align: center; padding: 12px; font-weight: 700; color: var(--success); }
.sb-left { margin: 0; text-align: right; }
.sb-reset { align-self: center; }
.sb-reset.armed { color: var(--danger); }

/* Split Bill — receipt scan + item-by-item split */
.sb-add-row { display: flex; gap: 8px; }
.sb-add-row > .pill-btn { flex: 1; min-height: 44px; }
.sb-add-row.hidden, .sb-items-box.hidden, .sb-scan-status.hidden, .sb-split-people.hidden { display: none; }
#sbSplitHint { white-space: pre-line; }
.sb-seg-btn { padding: 0 4px; }

.sb-items-box { display: flex; flex-direction: column; gap: 8px; }
.sb-scan-btn {
  display: flex; align-items: center; justify-content: center; min-height: 44px;
  border-style: dashed; border-color: var(--accent); color: var(--accent); background: var(--accent-light);
}
.sb-items-box.scanning .sb-scan-btn { opacity: 0.5; pointer-events: none; }
.sb-scan-status { display: flex; flex-direction: column; gap: 6px; font-size: 12.5px; color: var(--label-secondary); }
.sb-progress { height: 6px; border-radius: 3px; background: var(--surface-fill); overflow: hidden; }
.sb-progress span { display: block; height: 100%; width: 0; background: var(--accent); transition: width 0.25s ease; }

.sb-items { display: flex; flex-direction: column; gap: 8px; }
.sb-item { display: flex; align-items: center; gap: 6px; }
.sb-item .sb-item-name { flex: 1; min-width: 0; min-height: 38px; padding: 6px 10px; }
.sb-item .sb-amount-small { width: 104px; flex: 0 0 104px; }
.sb-add-item { align-self: flex-start; }

.sb-scan-row { display: flex; gap: 8px; }
.sb-scan-row .sb-scan-btn { flex: 1; min-width: 0; }
.sb-scan-btn.sb-scan-gallery { border-style: solid; border-color: var(--border); background: var(--surface-elevated); color: var(--ink); }

/* ---------- Waypoint Lens (camera → what is this + history) ---------- */
.lens-btn {
  position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  width: 34px; height: 34px; border: none; border-radius: 50%;
  background: none; color: var(--accent); cursor: pointer;
  display: flex; align-items: center; justify-content: center; padding: 0;
}
.lens-btn.hidden { display: none; }
.lens-btn svg { width: 22px; height: 22px; }
.lens-btn:hover { background: var(--accent-light); }
.lens-btn.is-new::after {
  content: ''; position: absolute; top: 5px; right: 5px; width: 8px; height: 8px;
  border-radius: 50%; background: var(--danger); box-shadow: 0 0 0 2px var(--surface-secondary);
}
.search-box.has-lens input { padding-right: 76px; }
.search-box.has-lens .clear-btn { right: 44px; }

.lens-card { background: var(--surface-elevated); text-align: left; max-height: 88vh; display: flex; flex-direction: column; padding-top: 26px; }
.lens-head { display: flex; gap: 12px; align-items: center; padding-right: 36px; margin-bottom: 10px; }
.lens-photo { width: 72px; height: 72px; flex: 0 0 72px; object-fit: cover; border-radius: var(--radius-sm); background: var(--surface-fill); }
.lens-head-text { min-width: 0; }
.lens-kicker { font-size: 11.5px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; color: var(--accent); }
.lens-title { margin: 2px 0 0; font-size: 19px; line-height: 1.25; font-weight: 700; color: var(--ink); letter-spacing: var(--tracking-tight); }
.lens-local { font-size: 14px; color: var(--label-secondary); margin-top: 2px; }
.lens-panel.loading .lens-title { color: var(--label-secondary); font-weight: 600; font-size: 16px; }

.lens-body { overflow-y: auto; flex: 1 1 auto; min-height: 0; font-size: 14.5px; line-height: 1.5; color: var(--ink); padding-bottom: 6px; }
.lens-body p { margin: 0 0 10px; }
.lens-body h3 { margin: 14px 0 6px; font-size: 12px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; color: var(--label-secondary); }
.lens-summary { font-size: 15.5px; }
.lens-badge { display: inline-block; margin-bottom: 8px; padding: 3px 9px; border-radius: var(--radius-pill); font-size: 12px; font-weight: 700; color: var(--warning); background: rgba(217, 119, 6, 0.12); }
.lens-texts { display: flex; flex-direction: column; gap: 6px; }
.lens-text-row { padding: 8px 10px; border-radius: var(--radius-sm); background: var(--surface-secondary); border: 1px solid var(--border); }
.lens-orig { font-size: 13px; color: var(--label-secondary); }
.lens-trans { font-weight: 600; }
.lens-tip { margin-top: 12px; padding: 10px 12px; border-radius: var(--radius-sm); background: var(--accent-light); }
.lens-note { margin-top: 12px !important; font-size: 11.5px; color: var(--label-tertiary); }
.lens-error { color: var(--label-secondary); }

.lens-skeleton { display: flex; flex-direction: column; gap: 10px; padding: 6px 0 14px; }
.lens-skeleton span { display: block; height: 12px; border-radius: 6px; background: var(--surface-fill); animation: lens-pulse 1.2s ease-in-out infinite; }
.lens-skeleton span:nth-child(1) { width: 92%; }
.lens-skeleton span:nth-child(2) { width: 78%; animation-delay: 0.15s; }
.lens-skeleton span:nth-child(3) { width: 85%; animation-delay: 0.3s; }
.lens-skeleton span:nth-child(4) { width: 55%; animation-delay: 0.45s; }
@keyframes lens-pulse { 0%, 100% { opacity: 0.45; } 50% { opacity: 1; } }

.lens-controls { border-top: 1px solid var(--separator); padding-top: 10px; display: flex; flex-direction: column; gap: 8px; }
.lens-lang { display: flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 600; color: var(--label-secondary); }
.lens-lang select { flex: 1; min-height: 38px; padding: 6px 10px; }
.lens-actions { display: flex; flex-wrap: wrap; gap: 6px; }
.lens-actions .pill-btn { flex: 1 1 auto; }
.lens-actions .pill-btn.hidden { display: none; }
.lens-actions .pill-btn:disabled { opacity: 0.5; }
body.lens-open { overflow: hidden; }

/* Lens call-to-action under the search bar */
.lens-cta {
  display: flex; align-items: center; gap: 6px; width: 100%; margin-top: 10px; padding: 11px 12px;
  border: 1px solid var(--accent-tint-strong); border-radius: var(--radius-md);
  background: linear-gradient(135deg, var(--accent-light), var(--surface-elevated));
  color: var(--ink);
}
.lens-cta.hidden { display: none; }
.lens-cta:hover { border-color: var(--accent); }
.lens-cta-main {
  display: flex; align-items: center; gap: 12px; flex: 1; min-width: 0;
  border: none; background: none; padding: 0; margin: 0; text-align: left; cursor: pointer; color: inherit; font: inherit;
}
.lens-cta-icon {
  flex: 0 0 40px; width: 40px; height: 40px; border-radius: 12px; background: var(--accent);
  display: flex; align-items: center; justify-content: center; font-size: 20px;
}
.lens-cta-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.lens-cta-title { font-size: 15px; font-weight: 700; color: var(--ink); }
.lens-cta-sub { font-size: 12.5px; line-height: 1.35; color: var(--label-secondary); }
.lens-cta-arrow { font-size: 24px; line-height: 1; color: var(--accent); }
.lens-cta-gallery {
  flex: 0 0 36px; width: 36px; height: 36px; border: none; border-radius: 50%;
  background: none; color: var(--accent); cursor: pointer;
  display: flex; align-items: center; justify-content: center; padding: 0;
}
.lens-cta-gallery svg { width: 19px; height: 19px; }
.lens-cta-gallery:hover { background: rgba(0,0,0,0.06); }
