:root {
  --bg: #f4f5f7;
  --fg: #1a1a1a;
  --muted: #5f6670;
  --line: #d6dbe3;
  --row-alt: #f7f7f7;
  --card: #ffffff;
  --brand: #ff5722;
  --red: #d32f2f;
  --orange: #f57c00;
  --blue: #1976d2;
  --flat: #555;
  --green: #2e7d32;
  --tab-h: 84px; /* reserved bottom space so content clears the floating nav pill */
  --active-header-h: 0px;
  --surge-controls-h: 0px;
  --surge-free-h: 0px;
  --trap-ad-h: 0px;
  --bottom-clearance: calc(72px + env(safe-area-inset-bottom));
  --nav-bottom: 28px;
  --app-h: 100dvh;
  font-size: 17px;
}
@media (display-mode: standalone) {
  :root {
    --app-h: calc(100dvh + env(safe-area-inset-bottom));
    --nav-bottom: 28px;
  }
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html, body { margin: 0; padding: 0; width: 100%; min-height: 100%; background: var(--bg); overflow-x: hidden; overflow-y: auto; }
body {
  font-family: -apple-system, "PingFang HK", "Microsoft JhengHei", "Segoe UI", Roboto, sans-serif;
  background: var(--bg);
  color: var(--fg);
  overscroll-behavior-y: contain;
  min-height: 100vh;
  min-height: var(--app-h);
}
@media (display-mode: standalone) {
  html, body {
    height: 100%;
    overflow: hidden;
  }
}

#app {
  max-width: 520px;
  width: 100%;
  margin: 0 auto;
  height: 100vh;
  height: var(--app-h);
  position: relative;
  overflow: hidden;
}
.auth-boot, .login-screen {
  min-height: 100dvh;
  padding: calc(22px + env(safe-area-inset-top)) 18px calc(22px + env(safe-area-inset-bottom));
  display: flex;
  align-items: center;
  justify-content: center;
  background: #0c0d10;
  color: #f5f5f5;
}
.login-screen {
  position: fixed;
  inset: 0;
  z-index: 1200;
  background: rgba(0,0,0,.62);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
}
.auth-boot {
  position: fixed;
  inset: 0;
  z-index: 1300;
  flex-direction: column;
  gap: 14px;
}
body.auth-loading #app { visibility: hidden; }
/* Crawlable SPA fallback: hidden by default; shown only while the app shell has not
   booted (auth-loading present). No-JS / timed-out renderers keep auth-loading and so
   see real content + links instead of a blank app. JS users have auth-loading removed at
   boot (behind the splash), so they never see this. */
/* Real content section, in normal document flow BELOW the app. Base state = VISIBLE so
   every browser visitor AND a JS-rendering crawler (Googlebot renders JS) sees real
   content, not a blank app shell. Installed PWA (standalone) hides it so day-to-day
   drivers see the app unchanged. Same HTML for everyone — visibility varies only by
   display-mode (like responsive CSS), so this is not cloaking. */
#seoLanding {
  display: block;
  background: #0c0d10;
  color: #e9eaee;
  font: 16px/1.7 -apple-system, system-ui, "PingFang HK", "Microsoft JhengHei", sans-serif;
  -webkit-text-size-adjust: 100%;
}
/* The section stays display:block (in the rendered DOM, so a JS-rendering crawler still
   indexes the content) but the app fills the viewport and body overflow:hidden clips this
   section off-screen — real users just see the app, no dark content bleeding at the bottom.
   Installed PWA (standalone) removes it entirely. */
@media (display-mode: standalone) {
  #seoLanding { display: none; }
}
#seoLanding .seo-landing-inner {
  max-width: 680px;
  margin: 0 auto;
  padding: calc(28px + env(safe-area-inset-top)) 20px calc(28px + env(safe-area-inset-bottom));
}
#seoLanding .seo-mark { font-weight: 800; letter-spacing: .5px; color: #ff7a4d; }
#seoLanding h1 { font-size: 26px; margin: 6px 0 12px; }
#seoLanding h2 { font-size: 19px; margin: 26px 0 10px; color: #ff7a4d; }
#seoLanding p { margin: 0 0 12px; }
#seoLanding .seo-table { width: 100%; border-collapse: collapse; margin: 10px 0 6px; font-size: 14px; }
#seoLanding .seo-table th, #seoLanding .seo-table td { text-align: left; padding: 8px 10px; border-bottom: 1px solid #23252b; vertical-align: top; }
#seoLanding .seo-table th { color: #c7cad1; font-weight: 700; background: #15171c; }
#seoLanding .seo-table td { color: #d7dae0; }
#seoLanding .seo-table a { color: #ff7a4d; }
#seoLanding .seo-feats { margin: 14px 0; padding-left: 18px; }
#seoLanding .seo-feats li { margin: 4px 0; }
#seoLanding .seo-links { display: flex; flex-wrap: wrap; gap: 10px 16px; margin: 18px 0; }
#seoLanding .seo-links a { color: #ff7a4d; text-decoration: none; }
#seoLanding .seo-links a:hover { text-decoration: underline; }
#seoLanding .seo-note { color: #9aa0aa; font-size: 13px; margin-top: 18px; }
.auth-boot-mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 96px;
  min-height: 54px;
  padding: 0 18px;
  border-radius: 16px;
  background: var(--brand);
  color: #fff;
  font-size: 1.1rem;
  font-weight: 950;
  letter-spacing: 0;
  box-shadow: 0 14px 34px rgba(255,87,34,.28);
}
.auth-spinner {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: 3px solid rgba(255,255,255,.16);
  border-top-color: var(--brand);
  animation: se-spin .9s linear infinite;
}
.auth-boot-title {
  font-size: 1.15rem;
  font-weight: 800;
  color: rgba(255,255,255,.88);
}
.auth-boot-sub {
  margin-top: -6px;
  color: rgba(255,255,255,.58);
  font-size: .82rem;
  font-weight: 750;
}
.login-panel {
  position: relative;
  width: 100%;
  max-width: 420px;
  padding: 30px 22px 24px;
  border: 1px solid rgba(255,255,255,.12);
  border-radius: 22px;
  background: #0c0d10;
  box-shadow: 0 24px 70px rgba(0,0,0,.42);
}
.login-close {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 44px;
  height: 44px;
  border: 1px solid rgba(255,255,255,.14);
  border-radius: 50%;
  background: rgba(255,255,255,.08);
  color: #fff;
  font: inherit;
  font-size: 1.05rem;
  font-weight: 900;
  cursor: pointer;
}
.login-mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 76px;
  min-height: 44px;
  padding: 0 14px;
  border-radius: 12px;
  background: var(--brand);
  color: #fff;
  font-weight: 900;
  letter-spacing: 0;
}
.login-panel h1 {
  margin: 24px 0 22px;
  font-size: 2.15rem;
  line-height: 1.08;
  letter-spacing: 0;
}
.login-field {
  display: block;
  margin: 14px 0;
}
.login-field > span:first-child {
  display: block;
  margin-bottom: 7px;
  color: rgba(255,255,255,.68);
  font-size: .82rem;
  font-weight: 800;
}
.login-field input {
  width: 100%;
  min-height: 52px;
  border: 1px solid rgba(255,255,255,.14);
  border-radius: 12px;
  background: rgba(255,255,255,.08);
  color: #fff;
  font: inherit;
  font-size: 1.08rem;
  padding: 12px 14px;
}
.login-field input:focus {
  outline: none;
  border-color: var(--brand);
  background: rgba(255,255,255,.11);
}
.code-wrap {
  display: flex;
  align-items: center;
  gap: 8px;
}
.code-wrap input { flex: 1; }
.code-eye {
  flex: 0 0 52px;
  width: 52px;
  height: 52px;
  border: 1px solid rgba(255,255,255,.14);
  border-radius: 12px;
  background: rgba(255,255,255,.08);
  color: #fff;
  font: inherit;
  cursor: pointer;
}
.login-submit {
  width: 100%;
  min-height: 54px;
  border: none;
  border-radius: 14px;
  margin-top: 10px;
  background: var(--brand);
  color: #fff;
  font: inherit;
  font-size: 1.05rem;
  font-weight: 900;
  cursor: pointer;
}
.login-submit:disabled {
  opacity: .62;
  cursor: wait;
}
.login-error {
  min-height: 22px;
  margin: 12px 0 0;
  color: #ffb4a3;
  font-size: .9rem;
  font-weight: 700;
  line-height: 1.4;
}
.login-devices {
  margin-top: 14px;
  padding: 12px;
  border: 1px solid rgba(255,255,255,.12);
  border-radius: 14px;
  background: rgba(255,255,255,.06);
}
.login-devices-title {
  color: #fff;
  font-size: .9rem;
  font-weight: 900;
  line-height: 1.35;
}
.login-devices-list {
  display: grid;
  gap: 9px;
  margin-top: 10px;
}
.login-device-row, .profile-device-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.login-device-row {
  padding-top: 9px;
  border-top: 1px solid rgba(255,255,255,.1);
}
.device-label {
  font-size: .9rem;
  font-weight: 900;
  line-height: 1.3;
}
.login-device-row .device-label { color: #fff; }
.device-seen {
  margin-top: 3px;
  color: var(--muted);
  font-size: .74rem;
  font-weight: 700;
  line-height: 1.3;
}
.login-device-row .device-seen { color: rgba(255,255,255,.58); }
.device-remove-btn, .device-logout-btn {
  flex: 0 0 auto;
  min-width: 64px;
  min-height: 44px;
  border-radius: 22px;
  font: inherit;
  font-size: .86rem;
  font-weight: 900;
  cursor: pointer;
  padding: 9px 14px;
}
.device-remove-btn {
  border: 1px solid rgba(255,255,255,.16);
  background: #fff;
  color: var(--red);
}
.device-remove-btn:disabled, .device-logout-btn:disabled, .profile-devices-refresh:disabled {
  opacity: .62;
  cursor: wait;
}
.login-help {
  margin: 12px 0 0;
  color: rgba(255,255,255,.64);
  font-size: .84rem;
  line-height: 1.55;
}
.login-help a {
  color: #ffab91;
  font-weight: 800;
}
.login-price-card {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 16px;
  padding: 13px;
  border: 1px solid rgba(255,255,255,.12);
  border-radius: 14px;
  background: rgba(255,255,255,.06);
}
.login-price-card > div {
  min-width: 0;
  flex: 1;
}
.login-price-card b,
.login-price-card span {
  display: block;
}
.login-price-card b {
  color: #fff;
  font-size: .94rem;
  line-height: 1.2;
}
.login-price-card span {
  margin-top: 4px;
  color: rgba(255,255,255,.66);
  font-size: .78rem;
  font-weight: 700;
  line-height: 1.35;
}
.login-price-card button {
  flex: 0 0 auto;
  min-height: 42px;
  border: 0;
  border-radius: 12px;
  padding: 0 13px;
  background: #fff;
  color: #111;
  font: inherit;
  font-size: .86rem;
  font-weight: 900;
  cursor: pointer;
}
body.auth-login #g63mBell, body.auth-loading #g63mBell { display: none; }
/* Wide screens (desktop / tablet browser): frame the mobile app as a centered card
   so it reads as intentional, not a column stranded in empty space. Phone stays
   edge-to-edge. The floating nav already centres on the viewport, over the card. */
@media (min-width: 600px) {
  body { background: #c9ccd2; }
  [data-theme="dark"] body { background: #050505; }
  #app { background: var(--bg); box-shadow: 0 0 0 1px rgba(0,0,0,.06), 0 24px 70px rgba(0,0,0,.16); }
}

.view {
  height: var(--app-h);
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-y: contain;
  padding: var(--active-header-h) 0 var(--bottom-clearance);
}
.hidden { display: none !important; }

/* ---- surge top bar ---- */
.topbar {
  display: flex; align-items: center; justify-content: space-between;
  padding: 13px 18px 12px;
  position: static; background: var(--card);
  border-bottom: 1px solid var(--line);
}
/* the demand strip sits above and already clears the notch; only add safe-area to the
   topbar if the strip is somehow hidden, so the title never sits under the Dynamic Island */
#demandStrip[hidden] + .topbar { padding-top: calc(13px + env(safe-area-inset-top)); }
.topbar-title { font-size: 1.15rem; font-weight: 800; letter-spacing: -.02em; }
.topbar-sub { font-size: .72rem; font-weight: 600; color: var(--muted); margin-left: 6px; }
.refresh-row .sort-btn {
  flex-direction: row; gap: 6px; align-items: center; flex: none; white-space: nowrap;
  background: var(--card); color: var(--fg);
  border: 1.5px solid var(--brand); border-radius: 20px;
  padding: 10px; font-size: .9rem; font-weight: 800; min-height: 46px;
  box-shadow: 0 1px 4px rgba(0,0,0,.08); transition: transform .08s ease;
}
.refresh-row .sort-btn:active { transform: scale(.96); background: var(--row-alt); }
.refresh-row .sort-btn .sort-lbl { display: none; }
.refresh-row .sort-btn #prodPrimary { color: var(--brand); font-weight: 800; }
.refresh-row .sort-btn .chevron { color: var(--brand); font-size: 1rem; font-weight: 700; }
.col-region { font-size: 0.95rem; }
.col-mult { text-align: center; }
.col-dist { text-align: right; color: var(--muted); }
.sort-btn {
  border: none; background: none; font: inherit; font-weight: 600;
  color: var(--blue); cursor: pointer; padding: 0; text-align: center;
  display: flex; flex-direction: column; align-items: center; line-height: 1.15;
}
.sort-btn .chevron { color: var(--blue); font-size: 0.9rem; }

.refresh-row {
  display: flex; flex-wrap: nowrap; justify-content: space-between; align-items: center; gap: 8px;
  padding: 8px 14px; color: var(--muted); font-size: 0.85rem;
  position: fixed;
  top: var(--surge-header-h, 0px);
  left: 50%;
  width: 100%;
  max-width: 520px;
  transform: translateX(-50%);
  z-index: 1090;
  background: var(--bg);
  border-bottom: 1px solid rgba(214,219,227,.72);
}
/* 列表 / 地圖 / 預測 / 駕駛 segmented control */
.view-toggle { display: inline-flex; background: var(--row-alt); border: 1px solid var(--line); border-radius: 20px; padding: 3px; min-width: 0; }
.vt-btn { border: none; background: none; font: inherit; font-weight: 700; font-size: .98rem; color: var(--muted);
  padding: 12px 9px; border-radius: 18px; cursor: pointer; transition: background .15s, color .15s; white-space: nowrap; min-height: 46px; }
.view-toggle.is-wide { flex: 1; }
.view-toggle.is-wide .vt-btn { flex: 1; }
/* Narrow phones (<=384px): shrink the toggle + sort so the row never wraps to two lines. */
@media (max-width: 384px) {
  .refresh-row { gap: 6px; padding: 8px 10px; }
  .vt-btn { padding: 11px 9px; font-size: .9rem; }
  .refresh-row .sort-btn { font-size: .82rem; }
}
.vt-btn.active { background: var(--brand); color: #fff; box-shadow: 0 2px 6px rgba(255,87,34,.35); }
/* dvh (not vh) so mobile URL-bar doesn't push the map under the tab bar */
/* z-index: 0 makes this a stacking context so Leaflet's high-z panes (~700) stay
   contained and never render over the fixed tabbar (which sits above at z-index 1000). */
.surge-map { position: relative; z-index: 0; height: calc(var(--app-h) - var(--active-header-h) - var(--surge-controls-h) - var(--bottom-clearance) - 18px);
  min-height: 430px; margin: 4px 10px 0;
  border-radius: 18px; overflow: hidden; border: 1px solid var(--line); }
/* MAP VIEW = fixed full-screen map. Lock the page (no scroll) and drop the doubled
   bottom spacing so the map sits flush above the nav with nothing to scroll past. */
body.surge-map-on #view-surge { overflow: hidden; padding-bottom: 0; }
body.surge-map-on .surge-map { margin-bottom: 0; }
body.trap-map-on #view-traps { overflow: hidden; padding-bottom: 0; }
/* live-car map: container bg blends loading tiles (no white flash) */
.surge-map .leaflet-container { background: #e9eaec; }
[data-theme="dark"] .surge-map .leaflet-container { background: #101216; }
.premium-gate {
  position: relative;
  min-height: 360px;
  margin-bottom: calc(var(--tab-h) + env(safe-area-inset-bottom));
  overflow: hidden;
}
.premium-teaser {
  display: grid;
  gap: 10px;
  padding: 4px 0 0;
  filter: blur(6px);
  pointer-events: none;
  user-select: none;
}
.premium-map-teaser {
  position: absolute;
  inset: 0;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
  gap: 12px;
  padding: 18px;
  background:
    linear-gradient(90deg, transparent 48%, rgba(255,87,34,.18) 49%, rgba(255,87,34,.18) 51%, transparent 52%),
    linear-gradient(0deg, transparent 48%, rgba(25,118,210,.12) 49%, rgba(25,118,210,.12) 51%, transparent 52%),
    var(--row-alt);
  filter: blur(6px);
  pointer-events: none;
}
.premium-map-teaser span {
  width: 38px;
  height: 38px;
  border-radius: 50%;
  align-self: center;
  justify-self: center;
  background: var(--brand);
  opacity: .72;
  box-shadow: 0 0 0 9px rgba(255,87,34,.14);
}
.premium-map-teaser span:nth-child(2n) { background: var(--blue); box-shadow: 0 0 0 8px rgba(25,118,210,.13); }
.premium-map-teaser span:nth-child(3n) { background: var(--green); box-shadow: 0 0 0 7px rgba(46,125,50,.13); }
.premium-lock-overlay {
  position: absolute;
  inset: 0;
  z-index: 620;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 22px;
  text-align: center;
  background: rgba(244,245,247,.48);
}
[data-theme="dark"] .premium-lock-overlay { background: rgba(10,10,12,.54); }
.premium-lock-title {
  max-width: 280px;
  padding: 12px 16px;
  border-radius: 16px;
  background: rgba(12,13,16,.86);
  color: #fff;
  font-size: 1.08rem;
  font-weight: 900;
  line-height: 1.35;
  box-shadow: 0 10px 28px rgba(0,0,0,.24);
}
.premium-lock-btn {
  min-height: 46px;
  min-width: 112px;
  border: none;
  border-radius: 23px;
  background: var(--brand);
  color: #fff;
  font: inherit;
  font-weight: 900;
  cursor: pointer;
  padding: 12px 20px;
  box-shadow: 0 6px 18px rgba(255,87,34,.35);
}
/* car markers: outer = Leaflet-positioned; inner .car-rot = heading rotation */
.car-ico { background: none !important; border: none !important; width: 24px; height: 24px; }
.car-rot { width: 24px; height: 24px; transform-origin: 50% 50%; will-change: transform; transition: transform .45s linear; }
.car-rot svg { display: block; }
.user-pin-buoy {
  background: transparent !important;
  border: 0 !important;
}
.nav-puck {
  position: relative;
  width: 54px;
  height: 54px;
  transform-origin: 50% 50%;
  filter: drop-shadow(0 5px 12px rgba(15,23,42,.32));
}
.nav-puck-rot {
  position: absolute;
  inset: 0;
  transform-origin: 50% 50%;
  transition: transform .18s linear;
  will-change: transform;
}
.nav-puck-rot svg { display: block; }
/* Radiating GPS pulse behind the location dot (does not rotate with heading). */
.nav-puck-pulse {
  position: absolute; left: 50%; top: 50%; width: 22px; height: 22px; margin: -11px 0 0 -11px;
  border-radius: 50%; background: rgba(26,115,232,.40); pointer-events: none; z-index: 0;
  animation: navPuckPulse 1.8s ease-out infinite;
}
.nav-puck-rot { z-index: 1; }
@keyframes navPuckPulse {
  0%   { transform: scale(.5); opacity: .75; }
  70%  { transform: scale(2.6); opacity: 0; }
  100% { transform: scale(2.6); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) { .nav-puck-pulse { animation: none; opacity: 0; } }
.nav-puck-dot {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: #1a73e8;
  border: 3px solid #fff;
  box-shadow: 0 0 0 2px rgba(26,115,232,.2), 0 2px 7px rgba(15,23,42,.28);
  transform: translate(-50%, -50%);
}
.pin-buoy-inner {
  position: relative;
  width: 58px;
  height: 58px;
  transform-origin: 50% 50%;
  filter: drop-shadow(0 0 12px rgba(255,87,34,.36));
}
.intel-heading-arrow {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 28px;
  height: 36px;
  z-index: 6;
  transform-origin: 50% 50%;
  transition: transform .22s linear;
  filter: drop-shadow(0 4px 8px rgba(30,34,45,.28));
}
.intel-heading-arrow svg { display: block; }
.pin-buoy-inner::before,
.pin-buoy-inner::after {
  content: "";
  position: absolute;
  inset: 10px;
  border-radius: 50%;
  border: 1px solid rgba(255,87,34,.62);
  animation: intelPing 1.9s ease-out infinite;
}
.pin-buoy-inner::after {
  inset: 4px;
  border-color: rgba(45,156,219,.42);
  animation-delay: .45s;
}
.intel-pin-core {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 32%, #fff 0 13%, #ffdfd3 14% 28%, #ff5722 29% 64%, #b91812 65% 100%);
  box-shadow: 0 0 0 2px rgba(255,255,255,.92), 0 0 20px rgba(255,87,34,.88);
  transform: translate(-50%, -50%);
  z-index: 3;
}
.intel-pin-sweep {
  position: absolute;
  inset: 7px;
  border-radius: 50%;
  background: conic-gradient(from 0deg, rgba(102,255,112,0) 0 72%, rgba(102,255,112,.46) 82%, rgba(102,255,112,0) 92% 100%);
  animation: intelSweep 2.4s linear infinite;
  opacity: .78;
  z-index: 1;
}
.intel-pin-ring {
  position: absolute;
  inset: 11px;
  border-radius: 50%;
  border: 1px dashed rgba(255,255,255,.82);
  box-shadow: inset 0 0 12px rgba(45,156,219,.32);
  animation: intelRing 5.5s linear infinite;
  z-index: 2;
}
.intel-pin-corner {
  position: absolute;
  width: 12px;
  height: 12px;
  border-color: rgba(255,255,255,.88);
  z-index: 4;
}
.intel-pin-corner.tl { left: 7px; top: 7px; border-left: 2px solid; border-top: 2px solid; }
.intel-pin-corner.tr { right: 7px; top: 7px; border-right: 2px solid; border-top: 2px solid; }
.intel-pin-corner.bl { left: 7px; bottom: 7px; border-left: 2px solid; border-bottom: 2px solid; }
.intel-pin-corner.br { right: 7px; bottom: 7px; border-right: 2px solid; border-bottom: 2px solid; }
@keyframes intelPing {
  0% { transform: scale(.58); opacity: .95; }
  72%, 100% { transform: scale(1.55); opacity: 0; }
}
@keyframes intelSweep {
  to { transform: rotate(360deg); }
}
@keyframes intelRing {
  to { transform: rotate(-360deg); }
}
@media (prefers-reduced-motion: reduce) {
  .pin-buoy-inner::before,
  .pin-buoy-inner::after,
  .intel-pin-sweep,
  .intel-pin-ring { animation: none; }
}
/* recenter FAB */
/* Waze-style dark basemap: brighten dim dark_all tiles so roads + street names read while driving */
.map-dark-boost .leaflet-tile-pane { filter: brightness(1.14) contrast(1.2) saturate(1.05); }
/* MapLibre GL driver pin: pulsing GPS ring (transform+opacity only — safe over WebGL on iOS). */
.gl-arrow-pulse {
  position: absolute; left: 50%; top: 50%; width: 30px; height: 30px; margin: -15px 0 0 -15px;
  border-radius: 50%; background: rgba(26,115,232,.45); pointer-events: none; z-index: 0;
  animation: glArrowPulse 1.5s ease-out infinite;
}
@keyframes glArrowPulse {
  0%   { transform: scale(.55); opacity: .6; }
  70%  { transform: scale(2.7); opacity: 0; }
  100% { transform: scale(2.7); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) { .gl-arrow-pulse { animation: none; opacity: 0; } }
.gl-arrow-rot { z-index: 1; }
.map-recenter { position: absolute; right: 16px; bottom: 96px; z-index: 600; width: 48px; height: 48px;
  border-radius: 50%; border: none; background: var(--card); color: var(--brand);
  box-shadow: 0 8px 22px rgba(20,24,40,.20); font-size: 24px; cursor: pointer;
  display: flex; align-items: center; justify-content: center; transition: background .15s, color .15s; }
/* Following is paused (user panned / dragged the pin): solid brand fill invites a tap to resume live GPS. */
.map-recenter.paused { background: var(--brand); color: #fff; animation: recenter-pulse 1.8s ease-in-out infinite; }
@keyframes recenter-pulse {
  0%, 100% { box-shadow: 0 2px 10px rgba(0,0,0,.28); }
  50% { box-shadow: 0 2px 10px rgba(0,0,0,.28), 0 0 0 6px rgba(255,87,34,.22); }
}
.trap-report-fabs {
  position: absolute; left: 50%; bottom: 30px; transform: translateX(-50%); z-index: 610;
  display: flex; gap: 22px; align-items: center; max-width: calc(100% - 20px);
}
/* White buttons identified by a coloured BORDER (police blue / camera red) so the multicolour
   police van sits on its natural white background instead of clashing with a solid fill. */
.trap-report-fab {
  min-width: 116px; min-height: 54px; border-radius: 27px;
  background: #fff; color: #1c2533; border: 3px solid #cdd3dd; box-shadow: 0 8px 22px rgba(20,24,40,.22);
  font: inherit; font-size: 1.02rem; font-weight: 850; white-space: nowrap; word-break: keep-all;
  cursor: pointer; display: inline-flex; align-items: center; justify-content: center; gap: 7px; padding: 10px 20px;
}
/* Same-size boxed report buttons: icon + caption, BOTTOM-aligned so the two captions line up.
   Both are white boxes (police = blue border, camera = red border) of identical size. */
.trap-report-fab.trf-icononly {
  width: 92px; height: 82px; min-width: 0; min-height: 0; padding: 8px 4px 9px;
  flex-direction: column; gap: 4px; justify-content: flex-end; align-items: center;
  background: #fff; border: 1px solid rgba(15,23,42,.08); border-radius: 18px;
  /* strong elevation so the white card lifts off the light-grey map instead of blending in */
  box-shadow: 0 10px 24px rgba(15,23,42,.30), 0 2px 6px rgba(15,23,42,.20);
}
/* Coloured glow that lifts each card AND colour-codes it: police = blue, camera = red. */
.trap-report-fab.trf-police.trf-icononly { box-shadow: 0 8px 22px rgba(31,111,224,.50), 0 2px 7px rgba(15,23,42,.22); }
.trap-report-fab.trf-cam.trf-icononly { box-shadow: 0 8px 22px rgba(224,36,36,.46), 0 2px 7px rgba(15,23,42,.22); }
.trap-report-fab.trf-cam.trf-icononly .trf-camimg { height: 40px; width: auto; }
.trf-cap { font-size: .74rem; font-weight: 850; line-height: 1; white-space: nowrap; }
.trap-report-fab.trf-police .trf-cap { color: #173a78; }
.trap-report-fab.trf-cam .trf-cap { color: #d61f1f; }
.trap-report-fab .trf-ic { flex: none; }
.trap-report-fab:active { transform: scale(.96); }
[data-theme="dark"] .trap-report-fab { box-shadow: 0 4px 16px rgba(0,0,0,.42); }
/* Surge colour legend, top-left of the map — tells the driver what the circle colours mean. */
/* keep the demand-strip text clear of the fixed notification bell */
.demand-strip { padding-right: 56px; }
/* Map controls live inside the map; the map itself already clears the floating nav. */
.surge-map .map-recenter { bottom: 96px; }
.trap-full-map .map-recenter { bottom: 96px; }
.surge-map .leaflet-bottom { bottom: 8px; }
.trap-full-map .leaflet-bottom { bottom: 8px; }
.map-legend { position: absolute; left: 10px; top: 10px; z-index: 500;
  display: flex; gap: 12px; align-items: center; padding: 7px 11px; border-radius: 12px;
  background: var(--card); box-shadow: 0 2px 10px rgba(0,0,0,.18);
  font-size: .68rem; font-weight: 700; color: var(--fg); pointer-events: none; }
.map-legend span { display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; }
.map-legend i { width: 10px; height: 10px; border-radius: 50%; border: 1.5px solid #fff; box-shadow: 0 0 0 1px rgba(0,0,0,.08); }
.map-legend.surge-scale-legend {
  flex-direction: column; align-items: stretch; gap: 5px; min-width: 138px; padding: 8px 10px;
  border-radius: 14px; background: rgba(255,255,255,.92); color: #172033;
  box-shadow: 0 8px 22px rgba(15,23,42,.22), 0 0 0 1px rgba(255,255,255,.72);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
}
.surge-scale-title { font-size: .68rem; font-weight: 900; line-height: 1; }
.surge-scale-bar {
  height: 9px; border-radius: 999px;
  background: linear-gradient(90deg, #ffb52e 0%, #ff9412 32%, #ff6a16 55%, #ff2d1c 78%, #e3102a 100%);
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.55), 0 1px 3px rgba(15,23,42,.22);
}
.surge-scale-bar.demand { background: linear-gradient(90deg, #ffb52e 0%, #ff5a1f 58%, #e3102a 100%); }
.surge-scale-labels { display: flex; justify-content: space-between; align-items: center; gap: 16px; }
.surge-scale-labels em { font-style: normal; font-size: .62rem; font-weight: 850; line-height: 1; color: inherit; }
/* 加乘地圖 = dark "heat" overview: dark canvas + glowing graduated surge bubbles (divIcon, not SVG). */
.surge-map.surge-heat-map { background: #273241; }
/* Medium slate, NOT near-black: low contrast lifts the inverted blacks to grey (brightness can't lift pure black). */
.surge-heat-map .leaflet-tile-pane { filter: invert(1) hue-rotate(190deg) brightness(1.18) contrast(0.55) saturate(0.6); }
/* Kill the native leaflet-rotate compass/pitch control (top-left ▲▼); legend + FABs are direct children, unaffected. */
.surge-heat-map .leaflet-control-container { display: none !important; }
.surge-heat-map .map-legend { background: rgba(16,18,24,.82); color: #fff; box-shadow: 0 2px 12px rgba(0,0,0,.45); }
.surge-heat-map .map-legend.surge-scale-legend { background: rgba(16,18,24,.86); color: #fff; box-shadow: 0 8px 22px rgba(0,0,0,.46), 0 0 0 1px rgba(255,255,255,.14); }
.surge-heat-ico { background: none !important; border: 0 !important; }
/* Heatmap marker = soft diffusing glow halo (overlaps blend into a heat cloud) + crisp core chip. */
.shb { position: relative; z-index: var(--shb-z, 1); display: flex; align-items: center; justify-content: center; isolation: isolate; overflow: visible; }
.shb-glow { position: absolute; z-index: 0; inset: -36%; border-radius: 50%; pointer-events: none;
  background: radial-gradient(circle, var(--heat) 0%, var(--heat) 30%, rgba(0,0,0,0) 70%);
  opacity: .34; filter: blur(4px); animation: shbPulse 2.8s ease-in-out infinite; }
.shb-core { position: relative; display: flex; align-items: center; justify-content: center;
  z-index: 2; width: auto; height: 25px; min-width: 38px; padding: 0 9px; border-radius: 999px;
  color: var(--chip-fg, #17120d); background: var(--heat); border: 2px solid rgba(255,255,255,.96);
  box-shadow: 0 5px 14px rgba(15,23,42,.36), 0 1px 3px rgba(15,23,42,.28), 0 0 0 1px rgba(15,23,42,.16);
  transform: translateZ(0); }
.shb-core b { font-size: .78rem; font-weight: 950; letter-spacing: 0; line-height: 1; font-variant-numeric: tabular-nums; text-shadow: var(--chip-shadow, none); }
.shb.hot .shb-glow { opacity: .44; animation-duration: 1.9s; }
@keyframes shbPulse { 0%,100% { transform: scale(.96); opacity: .28; } 50% { transform: scale(1.12); opacity: .46; } }
@media (prefers-reduced-motion: reduce) { .shb-glow { animation: none; } }

/* ---- Speed HUD (beta) — overlays the 快相 map ---- */
.speed-hud {
  position: fixed; left: 50%; transform: translateX(-50%);
  top: calc(var(--active-header-h, 0px) + var(--trap-ad-h, 0px) + 10px); z-index: 620;
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  padding: 8px 10px; border-radius: 15px; background: rgba(18,20,26,.88); backdrop-filter: blur(6px);
  box-shadow: 0 4px 18px rgba(0,0,0,.4); color: #fff; pointer-events: none;
}
.speed-hud.hidden { display: none; }
.sh-row { display: flex; align-items: center; gap: 10px; }
.sh-speed { display: flex; flex-direction: column; align-items: center; line-height: 1; min-width: 50px; }
.sh-speed b { font-size: 1.9rem; font-weight: 900; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.sh-speed span { font-size: .6rem; font-weight: 700; opacity: .7; margin-top: 2px; }
.speed-hud.over .sh-speed b { color: #ff5a4d; }
.speed-hud.warn .sh-speed b { color: #ffb02e; }
/* HK-style round speed-limit sign: red ring, white face, black number */
.sh-limit { width: 52px; height: 52px; border-radius: 50%; background: #fff; border: 5px solid #d81f27;
  display: flex; flex-direction: column; align-items: center; justify-content: center; }
.sh-limit b { color: #111; font-size: 1.25rem; font-weight: 900; line-height: 1; font-variant-numeric: tabular-nums; }
.sh-limit.est { border-color: #b9863a; } /* fallback/default 50 = amber ring so driver knows it's estimated */
.sh-meta { max-width: 150px; font-size: .56rem; line-height: 1.2; opacity: .72; font-weight: 600; }

/* ---- Global overspeed Edge Lighting (any tab) ---- */
.overspeed-flash { position: fixed; inset: 0; z-index: 1900; pointer-events: none; }
.overspeed-flash.hidden { display: none; }
/* Edge Lighting: hot inner rim plus soft red-magenta bloom, fading before the readable centre. */
.overspeed-flash::before {
  content: ''; position: absolute;
  inset:
    calc(env(safe-area-inset-top, 0px) + 2px)
    calc(env(safe-area-inset-right, 0px) + 2px)
    calc(env(safe-area-inset-bottom, 0px) + 2px)
    calc(env(safe-area-inset-left, 0px) + 2px);
  opacity: .78;
  box-shadow:
    inset 0 0 0 1px rgba(255,248,250,.98),
    inset 0 0 0 4px #ff2a55,
    inset 0 0 16px rgba(255,255,255,.78),
    inset 0 0 34px rgba(255,42,85,.88),
    inset 0 0 86px rgba(255,0,51,.58);
  animation: osfGrow 1.3s ease-in-out infinite alternate;
}
.speed-hud { z-index: 1950; } /* keep speed + limit legible above the edge glow */
.osf-banner {
  position: absolute; left: 50%; transform: translateX(-50%);
  top: calc(env(safe-area-inset-top, 0px) + 12px); z-index: 1;
  background: #d81f27; color: #fff; font-weight: 900; font-size: .95rem; letter-spacing: .01em;
  padding: 8px 16px; border-radius: 999px; box-shadow: 0 4px 20px rgba(216,31,39,.7);
  white-space: nowrap; font-variant-numeric: tabular-nums;
}
@keyframes osfGrow {
  from {
    opacity: .58;
    box-shadow:
      inset 0 0 0 1px rgba(255,248,250,.9),
      inset 0 0 0 3px #ff2a55,
      inset 0 0 12px rgba(255,255,255,.55),
      inset 0 0 26px rgba(255,42,85,.68),
      inset 0 0 68px rgba(255,0,51,.42);
  }
  to {
    opacity: .96;
    box-shadow:
      inset 0 0 0 2px rgba(255,248,250,1),
      inset 0 0 0 5px #ff0033,
      inset 0 0 20px rgba(255,255,255,.88),
      inset 0 0 46px rgba(255,42,85,.95),
      inset 0 0 116px rgba(255,0,51,.66);
  }
}
@media (prefers-reduced-motion: reduce) { .overspeed-flash::before { animation: none; opacity: .72; } }

.title-multiplier { font-weight: 700; color: var(--fg); font-size: 1rem; }
.refresh-status #countdown { font-weight: 700; color: var(--brand); }
.drive-toggle {
  border: 1.5px solid var(--brand); background: var(--card); color: var(--brand);
  font: inherit; font-weight: 800; font-size: 0.95rem; padding: 9px 16px;
  border-radius: 22px; cursor: pointer; min-height: 44px;
}
.drive-toggle.on { background: var(--brand); color: #fff; box-shadow: 0 3px 10px rgba(255,87,34,.4); }
.locate-btn {
  border: 1px solid var(--line); background: var(--row-alt); color: var(--fg);
  font: inherit; font-weight: 700; font-size: 1rem; padding: 11px 16px;
  border-radius: 22px; cursor: pointer; min-height: 46px;
}

/* demand index strip (weather correlate) */
.demand-strip {
  display: flex; align-items: center; gap: 12px; padding: 10px 14px;
  font-size: 0.92rem; font-weight: 600; border-bottom: 1px solid var(--line);
  position: sticky; top: 0; z-index: 7;
}
.demand-strip .dm-i b { font-size: 1.05rem; }
.demand-strip .dm-t { color: var(--muted); margin-left: auto; font-weight: 500; font-size: 0.82rem; }
/* active HKO warning chips (typhoon / rainstorm / thunderstorm / hot / special) */
.demand-strip .dm-warn { display: flex; flex-wrap: wrap; gap: 6px; margin-left: auto; justify-content: flex-end; }
.demand-strip .dm-warn i { font-style: normal; font-weight: 800; font-size: .76rem; background: rgba(0,0,0,.07);
  border-radius: 8px; padding: 3px 8px; white-space: nowrap; }
.dl-hi .dm-warn i { background: rgba(211,47,47,.16); }
.dl-mh .dm-warn i { background: rgba(245,124,0,.16); }
.dl-hi { background: #fdecea; color: var(--red); }
.dl-mh { background: #fff3e0; color: var(--orange); }
.dl-mid { background: #fff8e1; color: #8a6d00; }
.dl-lo { background: #e8f5e9; color: var(--green); }

/* tabular numbers so values don't jump as they update */
.col-mult, .col-dist, .tn-toll, .pk-vac, .t-dist, .fl-time, .trap-dist, .trap-conf { font-variant-numeric: tabular-nums; }

/* ---- surge list (2026 cards · 6pui data) ---- */
.surge-list { list-style: none; margin: 0; padding: 8px 10px 8px; }
.free-all-banner {
  list-style: none;
  display: inline-flex;
  max-width: 100%;
  margin: 2px 0 8px;
  padding: 7px 10px;
  border: 1px solid rgba(255,87,34,.24);
  border-radius: 999px;
  background: rgba(255,87,34,.10);
  color: #8a3600;
  font-size: .78rem;
  font-weight: 850;
  line-height: 1.25;
}
.free-all-banner span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
[data-theme="dark"] .free-all-banner {
  background: rgba(255,123,82,.14);
  border-color: rgba(255,123,82,.30);
  color: #ffc46b;
}
.surge-row {
  list-style: none; position: relative;
  background: var(--card); border: 1px solid var(--line); border-radius: 18px;
  padding: 13px 15px; margin: 8px 0;
  box-shadow: 0 2px 8px rgba(20,20,40,.04);
  transition: transform .12s ease, box-shadow .15s ease, border-color .15s ease;
}
/* animate rows in only on the FIRST paint of the list, never on poll refreshes
   (re-animating every 15s shifts layout + janks the location picker) */
.surge-list.first-paint .surge-row { animation: rowIn .26s cubic-bezier(.22,.61,.36,1) both; }
.surge-row:active { transform: scale(.985); }
@keyframes rowIn { from { opacity: 0; transform: translateY(7px); } to { opacity: 1; transform: none; } }
.surge-row.is-warm { border-color: rgba(245,124,0,.30); box-shadow: 0 2px 10px rgba(245,124,0,.10); }
.surge-row.is-hot  { border-color: rgba(211,47,47,.35);  box-shadow: 0 2px 14px rgba(211,47,47,.14); }
[data-theme="dark"] .surge-row { box-shadow: none; }
/* Left accent bar: lets a driver scan the list and instantly spot where surge is,
   instead of reading every row. Flat (no-surge) rows have no bar, so they recede. */
.surge-row.is-warm::before, .surge-row.is-hot::before {
  content: ''; position: absolute; left: 0; top: 11px; bottom: 11px; width: 4px; border-radius: 0 4px 4px 0;
}
.surge-row.is-warm::before { background: var(--orange); }
.surge-row.is-hot::before  { background: var(--red); }

/* card row 1: area name + distance/ETA */
.sc-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; margin-bottom: 10px; }
.sc-name { font-size: 1.24rem; font-weight: 800; letter-spacing: -.02em; display: flex; align-items: center; min-width: 0; }
.sc-dist { color: var(--muted); font-size: .82rem; font-weight: 700; white-space: nowrap; flex: none; font-variant-numeric: tabular-nums; }

/* card row 2: big primary multiplier (left) + per-type car supply (right) */
.sc-body { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.sc-mult { display: flex; flex-direction: column; line-height: 1; flex: none; }
.sc-mult b { font-size: 2.05rem; font-weight: 900; letter-spacing: -.04em; font-variant-numeric: tabular-nums; }
.sc-mult i { font-style: normal; font-size: .68rem; font-weight: 700; color: var(--muted); margin-top: 5px; letter-spacing: .02em; }
/* multiplier number colour tracks surge level; flat/no-data recedes */
.sc-mult.sc0 b { color: var(--muted); font-weight: 800; font-size: 1.7rem; }
.sc-mult.sc1 b, .sc-mult.sc2 b { color: #b06f00; }
.sc-mult.sc3 b { color: var(--orange); }
.sc-mult.sc4 b, .sc-mult.sc5 b { color: var(--red); }

/* per-type car supply: one chip per car class, distinct colours */
.sc-cars { display: flex; gap: 7px; flex-wrap: wrap; justify-content: flex-end; flex: 1; }
.cc { display: inline-flex; flex-direction: column; align-items: center; min-width: 47px;
  background: var(--row-alt); border-radius: 12px; padding: 6px 9px; line-height: 1; }
.cc b { font-size: 1.12rem; font-weight: 850; font-variant-numeric: tabular-nums; }
.cc i { font-style: normal; font-size: .56rem; font-weight: 700; color: var(--muted); margin-top: 3px; letter-spacing: .03em; }
.cc-x b  { color: var(--green); }
.cc-c b  { color: #0d9488; }
.cc-xl b { color: var(--blue); }
.cc-bk b { color: var(--fg); }
.sc-cars-wait { color: var(--muted); font-size: .8rem; font-weight: 600; align-self: center; flex: none; }
[data-theme="dark"] .cc-x b { color: #66bb6a; }
[data-theme="dark"] .cc-bk b { color: #e8eaed; }

.live-dot { display: inline-block; width: 7px; height: 7px; border-radius: 50%; background: var(--green);
  margin-left: 7px; box-shadow: 0 0 0 0 rgba(46,125,50,.5); animation: livePulse 2s infinite; }
@keyframes livePulse { 0% { box-shadow: 0 0 0 0 rgba(46,125,50,.45); } 70% { box-shadow: 0 0 0 6px rgba(46,125,50,0); } 100% { box-shadow: 0 0 0 0 rgba(46,125,50,0); } }

/* ---- surge list table: 6pui-style aligned data grid ---- */
.surge-table-shell {
  list-style: none;
  position: relative;
  margin: 4px 0 0;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 12px;
  overflow: visible;
  box-shadow: 0 2px 10px rgba(20,20,40,.05);
}
.surge-table {
  display: grid;
  color: var(--fg);
  font-variant-numeric: tabular-nums;
}
.surge-th, .surge-tr {
  display: grid;
  grid-template-columns: minmax(72px, 1.25fr) minmax(47px, .58fr) minmax(50px, .62fr) minmax(115px, 1.45fr) minmax(50px, .68fr);
  column-gap: 3px;
  align-items: stretch;
}
.surge-th {
  position: sticky;
  top: 0;
  z-index: 900;
  min-height: 38px;
  background: #eef1f5;
  border-bottom: 1px solid #c6ccd6;
  color: #313741;
  font-size: .78rem;
  font-weight: 900;
}
/* Locked teaser is wrapped in .premium-gate (overflow:hidden = a sticky scroll box),
   which made the sticky header stick ~104px DOWN into the middle. The teaser is a fixed
   mock that never scrolls, so pin the header normally at the top. */
.surge-table.is-locked .surge-th { position: static !important; top: auto !important; }
.surge-th > div {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 0;
  padding: 8px 3px;
  white-space: nowrap;
}
.surge-th > div:first-child { justify-content: flex-start; padding-left: 9px; }
.surge-tr {
  min-height: 52px;
  border-bottom: 1px solid var(--line);
  background: var(--card);
  cursor: pointer;
}
.surge-tr:last-child { border-bottom: 0; }
.surge-tr:nth-child(odd) { background: #fafbfc; }
.surge-tr:active { transform: scale(.992); }
.surge-tr:focus-visible {
  outline: 3px solid rgba(255,87,34,.42);
  outline-offset: -3px;
}
.surge-current {
  min-height: 48px;
  background: #fff7ed !important;
  cursor: default;
}
.surge-current .st-area strong { color: #9a4b00; }
.st-cell {
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 7px 3px;
  border-right: 1px solid rgba(214,219,227,.74);
  line-height: 1.15;
}
.st-cell:last-child { border-right: 0; }
.st-area {
  align-items: flex-start;
  justify-content: center;
  flex-direction: column;
  padding-left: 9px;
  padding-right: 4px;
}
.st-area strong {
  display: block;
  max-width: 100%;
  color: var(--fg);
  font-size: .96rem;
  font-weight: 900;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.st-area small {
  display: block;
  max-width: 100%;
  margin-top: 3px;
  color: var(--muted);
  font-size: .68rem;
  font-weight: 800;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.st-num, .st-time {
  font-size: .9rem;
  font-weight: 900;
  white-space: nowrap;
}
.st-time {
  color: #4d5561;
  font-size: .76rem;
  font-weight: 850;
}
.st-mult {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 34px;
  border-radius: 7px;
  padding: 5px 2px;
  color: var(--fg);
}
.st-lvl0 { background: transparent; color: var(--fg); }
.st-lvl1, .st-lvl2 { background: #ffe8a3; color: #5f3b00; }
.st-lvl3 { background: #ffc46b; color: #542800; }
.st-lvl4, .st-lvl5 { background: #c62828; color: #fff; }
.st-cars {
  justify-content: flex-start;
  gap: clamp(5px, 1.8vw, 8px);
  color: #2f343a;
  font-size: .79rem;
  font-weight: 700;
  letter-spacing: 0;
  line-height: 1.18;
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
  white-space: nowrap;
}
.st-cars .st-car {
  display: inline-flex;
  align-items: baseline;
  gap: 2px;
  min-width: 0;
  color: inherit;
  letter-spacing: 0;
}
@media (max-width: 390px) {
  .st-cars { font-size: .73rem; gap: 5px; }
  .st-cars .st-car { gap: 1.5px; }
}
@media (forced-colors: active) {
  .st-cars .st-car b { color: CanvasText; }
}

/* ---- English layout: English labels run wider than Chinese, so rebalance the surge
   table (give Area room, tighten the number columns) and let long district names wrap to
   two lines instead of truncating ("Current Location", "Tai Po Market", "Sheung Shui"). ---- */
html[lang="en"] .surge-th,
html[lang="en"] .surge-tr {
  grid-template-columns: minmax(86px, 1.75fr) minmax(34px, .46fr) minmax(36px, .48fr) minmax(90px, 1.02fr) minmax(38px, .5fr);
}
html[lang="en"] .st-area { padding-left: 8px; padding-right: 3px; }
html[lang="en"] .st-area strong {
  font-size: .82rem; line-height: 1.12; white-space: normal;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
html[lang="en"] .st-area small { font-size: .63rem; white-space: normal; }
html[lang="en"] .surge-th [role="columnheader"] { font-size: .66rem; line-height: 1.1; }
html[lang="en"] .st-cars { font-size: .71rem; gap: 4px; }
html[lang="en"] .st-num, html[lang="en"] .st-time { font-size: .82rem; }
/* List / Map / Drive toggle + Sort button are wider in English — keep the row on one line */
html[lang="en"] .refresh-row { gap: 6px; }
html[lang="en"] .vt-btn { padding: 11px 9px; font-size: .88rem; }
html[lang="en"] .refresh-row .sort-btn { padding: 9px 11px; font-size: .82rem; }

.st-hidden-cars {
  display: inline-flex;
  gap: 3px;
}
.st-cars .st-car b { color: var(--st-car-accent); font-weight: 800; letter-spacing: 0; margin-right: 0; opacity: 1; }
.st-cars .st-car-x  { --st-car-accent: #0f6f2d; }
.st-cars .st-car-c  { --st-car-accent: #00786f; }
.st-cars .st-car-b  { --st-car-accent: #8f5400; }
.st-cars .st-car-xl { --st-car-accent: #135db0; }
.surge-table.is-locked .st-private {
  user-select: none;
}
.surge-tr.is-row-locked .st-area { grid-column: 1; }
.surge-tr.is-row-locked .st-time { grid-column: 5; }
.st-locked-empty { min-height: 34px; }
.st-lock-cta {
  grid-column: 2 / 5;
  min-height: 34px;
  margin: 7px 3px;
  border: 1px solid rgba(255,87,34,.24);
  border-radius: 9px;
  background: rgba(255,248,245,.96);
  color: #8a3500;
  font-size: .72rem;
  font-weight: 900;
  white-space: normal;
  text-align: center;
  cursor: pointer;
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.55);
}
.st-lock-cta:active { transform: scale(.985); }
.st-lock-cta:focus-visible {
  outline: 3px solid rgba(255,87,34,.38);
  outline-offset: -2px;
}
.surge-table-gate {
  overflow: visible;
}
.surge-free-upgrade {
  margin: 8px 10px 10px;
  padding: 10px 12px;
  border: 1px solid rgba(255,87,34,.20);
  border-radius: 12px;
  background: rgba(255,248,245,.96);
  position: sticky;
  top: 6px;
  z-index: 950;
  box-shadow: 0 8px 22px rgba(20,20,40,.10);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 4px 10px;
  align-items: center;
}
.surge-free-upgrade b {
  font-size: .86rem;
}
.surge-free-upgrade span {
  grid-column: 1;
  color: var(--muted);
  font-size: .75rem;
  line-height: 1.35;
}
.surge-free-upgrade button {
  grid-column: 2;
  grid-row: 1 / span 2;
  border: 0;
  border-radius: 999px;
  background: var(--brand);
  color: #fff;
  padding: 8px 12px;
  font-weight: 900;
  white-space: nowrap;
}
[data-theme="dark"] .surge-free-upgrade {
  background: rgba(32,26,24,.96);
  border-color: rgba(255,123,82,.24);
}
.surge-list.first-paint .surge-tr {
  animation: rowIn .22s cubic-bezier(.22,.61,.36,1) both;
}
[data-theme="dark"] .surge-table-shell {
  box-shadow: none;
}
[data-theme="dark"] .surge-th {
  background: #20242b;
  border-bottom-color: #444a55;
  color: #eef1f5;
}
[data-theme="dark"] .surge-tr { background: var(--card); }
[data-theme="dark"] .surge-tr:nth-child(odd) { background: #181b21; }
[data-theme="dark"] .surge-current { background: #2a2118 !important; }
[data-theme="dark"] .surge-current .st-area strong { color: #ffc46b; }
[data-theme="dark"] .st-cell { border-right-color: rgba(59,64,74,.86); }
[data-theme="dark"] .st-time { color: #c9ced8; }
[data-theme="dark"] .st-lvl0 { color: #f0f0f0; }
[data-theme="dark"] .st-lvl1, [data-theme="dark"] .st-lvl2 { background: #624a13; color: #ffeab2; }
[data-theme="dark"] .st-lvl3 { background: #8a4a0f; color: #ffe0bd; }
[data-theme="dark"] .st-lvl4, [data-theme="dark"] .st-lvl5 { background: #b9231d; color: #fff; }
[data-theme="dark"] .st-cars { color: #d7dce3; }
[data-theme="dark"] .st-cars .st-car-x  { --st-car-accent: #74d77f; }
[data-theme="dark"] .st-cars .st-car-c  { --st-car-accent: #45d1c5; }
[data-theme="dark"] .st-cars .st-car-b  { --st-car-accent: #e8a64f; }
[data-theme="dark"] .st-cars .st-car-xl { --st-car-accent: #82b7ff; }
[data-theme="dark"] .st-lock-cta {
  background: rgba(38,30,25,.96);
  border-color: rgba(255,123,82,.30);
  color: #ffd1bb;
  box-shadow: none;
}
[data-theme="dark"] .surge-table-gate .premium-lock-overlay {
  background: rgba(10,10,12,.42);
}
@media (max-width: 390px) {
  .surge-list { padding-left: 6px; padding-right: 6px; }
  .surge-th, .surge-tr {
    grid-template-columns: minmax(68px, 1.18fr) minmax(45px, .54fr) minmax(48px, .58fr) minmax(108px, 1.35fr) minmax(47px, .62fr);
  }
  .st-area strong { font-size: .9rem; }
  .st-num { font-size: .84rem; }
  .st-cars { font-size: .72rem; gap: 2px; }
  .st-time { font-size: .7rem; }
}

/* live freshness badge (traffic header): green dot + update time, or grey "offline" */
.live-pill { display: inline-flex; align-items: center; gap: 5px; vertical-align: middle;
  font-size: .68rem; font-weight: 700; color: var(--green); background: rgba(46,125,50,.10);
  padding: 3px 9px 3px 7px; border-radius: 12px; margin-left: 8px; }
.live-pill .live-dot { margin-left: 0; }
.live-pill.stale { color: var(--muted); background: var(--row-alt); }
[data-theme="dark"] .live-pill { background: rgba(102,187,106,.14); color: #66bb6a; }

.m-red { color: var(--red); } .m-orange { color: var(--orange); } .m-blue { color: var(--blue); }
.m-green { color: var(--green); } .m-flat { color: var(--flat); }

/* per-type car chips inside the driving hero (centered, a touch larger) */
.drive-hero .dh-cars { justify-content: center; flex: none; margin-top: 12px; gap: 9px; }
.drive-hero .dh-cars .cc { min-width: 54px; padding: 8px 11px; }
.drive-hero .dh-cars .cc b { font-size: 1.28rem; }

/* explanatory footer notes / hints removed app-wide (clutter) — kept only the legal disclaimer */
.data-note, .modal-hint, .profile-auth-sub { display: none !important; }
#profileLocationShare .profile-auth-sub { display: block !important; }

/* One content-backed AdSense placement in the surge list view. */
.surge-publisher-context {
  margin: 10px 14px 0;
  padding: 12px 0 11px;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
.surge-publisher-context h2 {
  margin: 0 0 5px;
  font-size: 0.92rem;
  line-height: 1.3;
}
.surge-publisher-context p {
  margin: 0;
  color: var(--muted);
  font-size: 0.75rem;
  line-height: 1.55;
}
.surge-publisher-context p + p { margin-top: 5px; }
.reserve-slot { margin: 10px 14px 0; }
.reserve-slot[hidden], .reserve-slot.reserve-empty, body.auth-checking .reserve-slot { display: none !important; }
.reserve-slot.reserve-pending {
  display: block;
  min-height: 96px;
  overflow: hidden;
}
.reserve-slot.reserve-pending .reserve-shell,
.reserve-slot.reserve-pending .adsbygoogle {
  display: block;
  min-height: 96px !important;
}
.reserve-slot.reserve-preview {
  display: block !important;
  opacity: 1;
  height: auto !important;
  min-height: 0 !important;
  max-height: none !important;
  overflow: visible !important;
}
#view-surge > .reserve-slot {
  position: static !important;
  top: auto !important;
  z-index: 1;
  margin-top: 8px; padding: 0; background: var(--bg);
}
.reserve-shell {
  position: relative;
  overflow: hidden;
  min-height: 96px;
  border-radius: 12px;
  background: var(--card);
  box-shadow: 0 1px 2px rgba(20,24,40,.04);
}
.reserve-shell::before {
  content: "廣告";
  position: absolute;
  top: 6px;
  left: 8px;
  z-index: 1;
  color: rgba(95,102,112,.58);
  font-size: .56rem;
  font-weight: 800;
  letter-spacing: .08em;
}
.reserve-shell > .adsbygoogle {
  display: block !important;
  min-height: 96px;
  width: 100%;
}
.reserve-shell iframe { border: 0 !important; }
.reserve-shell:has(.adsbygoogle[data-ad-status="unfilled"]) { display: none; }
.reserve-box {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 96px;
  border-radius: 12px;
  border: 1px dashed #cdd4df;
  background:
    repeating-linear-gradient(135deg, rgba(255,87,34,.05) 0 10px, rgba(255,255,255,.24) 10px 20px),
    var(--card);
  color: var(--muted);
  font-size: .72rem;
  font-weight: 800;
  letter-spacing: .06em;
}
.ad-ph { display: flex; align-items: center; gap: 10px; min-height: 64px; padding: 12px 14px;
  background: var(--row-alt); border: 1px dashed var(--line); border-radius: 14px; flex-wrap: wrap; }
.ad-ph-tag { font-size: .6rem; font-weight: 800; letter-spacing: .08em; color: var(--muted);
  border: 1px solid var(--line); border-radius: 6px; padding: 2px 6px; background: var(--card); }
.ad-ph-txt { font-size: .82rem; font-weight: 600; color: var(--muted); flex: 1; }
.ad-ph-cta { border: none; background: var(--brand); color: #fff; font: inherit; font-weight: 800;
  font-size: .78rem; padding: 8px 14px; border-radius: 18px; cursor: pointer; white-space: nowrap; min-height: 36px; }
.ad-card { display: flex; align-items: center; gap: 10px; min-height: 64px; padding: 12px 14px;
  background: var(--card); border: 1px solid var(--line); border-radius: 14px; color: var(--fg);
  text-decoration: none; box-shadow: 0 1px 2px rgba(20,24,40,.04); }
.ad-card-main { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }
.ad-card-main b { font-size: .9rem; line-height: 1.25; color: var(--fg); }
.ad-card-main span, .ad-card-main small { color: var(--muted); font-size: .76rem; line-height: 1.35; }
.ad-card .ad-ph-cta { flex: 0 0 auto; display: inline-flex; align-items: center; min-height: 34px; }

/* empty / loading state: intentional centered card, not a blank board */
.surge-empty { list-style: none; display: flex; flex-direction: column; align-items: center; text-align: center;
  gap: 12px; padding: 48px 28px; margin: 18px 12px; background: var(--card);
  border: 1px solid var(--line); border-radius: 20px; }
.se-spinner { width: 34px; height: 34px; border-radius: 50%; border: 3px solid var(--line);
  border-top-color: var(--brand); animation: se-spin 0.9s linear infinite; }
@keyframes se-spin { to { transform: rotate(360deg); } }
.se-title { font-size: 1.08rem; font-weight: 800; color: var(--fg); letter-spacing: -.01em; }
.se-sub { font-size: .84rem; font-weight: 500; color: var(--muted); line-height: 1.55; max-width: 280px; }
@media (prefers-reduced-motion: reduce) { .se-spinner { animation: none; } }

/* ---- driving mode: single big "go here" target + runner-ups (glanceable in-car) ---- */
.drive-hero { list-style: none; display: flex; flex-direction: column; align-items: center; text-align: center;
  background: var(--card); border: 2px solid var(--brand); border-radius: 24px;
  margin: 14px 12px 10px; padding: 22px 16px 18px; cursor: pointer;
  box-shadow: 0 8px 26px rgba(255,87,34,.16); transition: transform .12s ease; }
.drive-hero:active { transform: scale(.985); }
.drive-hero .dh-tag { font-size: .84rem; font-weight: 800; color: var(--brand); letter-spacing: .03em; }
.drive-hero .dh-mult { font-size: 3.6rem; font-weight: 900; line-height: 1.02; letter-spacing: -.045em; margin: 4px 0 2px; color: var(--brand); }
.drive-hero .dh-area { font-size: 1.85rem; font-weight: 800; letter-spacing: -.02em; }
/* no surge → no multiplier headline; the area name IS the headline instead. */
.drive-hero.dh-flat .dh-area { font-size: 2.9rem; font-weight: 900; margin-top: 2px; letter-spacing: -.03em; }
.drive-hero.dh-flat .dh-tag { margin-bottom: 2px; }
.drive-hero .dh-meta { font-size: 1.02rem; font-weight: 700; color: var(--muted); margin-top: 5px; }
.drive-hero .dh-go { margin-top: 16px; background: var(--brand); color: #fff; font-weight: 800; font-size: 1.12rem;
  padding: 14px 22px; border-radius: 16px; width: 100%; max-width: 320px; }
/* hero colour tracks surge level */
.drive-hero.sc3 { border-color: var(--orange); box-shadow: 0 8px 26px rgba(245,124,0,.18); }
.drive-hero.sc3 .dh-mult, .drive-hero.sc3 .dh-tag { color: var(--orange); }
.drive-hero.sc3 .dh-go { background: var(--orange); }
.drive-hero.sc4, .drive-hero.sc5 { border-color: var(--red); box-shadow: 0 8px 28px rgba(211,47,47,.20); }
.drive-hero.sc4 .dh-mult, .drive-hero.sc5 .dh-mult,
.drive-hero.sc4 .dh-tag, .drive-hero.sc5 .dh-tag { color: var(--red); }
.drive-hero.sc4 .dh-go, .drive-hero.sc5 .dh-go { background: var(--red); }
/* no surge anywhere: neutral hero, brand CTA */
.drive-hero.sc0 { border-color: var(--line); box-shadow: 0 4px 16px rgba(0,0,0,.06); }
.drive-hero.sc0 .dh-mult { color: var(--fg); font-size: 2.6rem; }
.drive-hero.sc0 .dh-tag { color: var(--muted); }

.drive-rest-h { list-style: none; font-size: .8rem; font-weight: 800; color: var(--muted); padding: 12px 18px 4px; }
.drive-mini { list-style: none; display: flex; align-items: center; gap: 12px; background: var(--card);
  border: 1px solid var(--line); border-radius: 15px; margin: 7px 12px; padding: 15px 16px; cursor: pointer;
  transition: transform .12s ease; }
.drive-mini:active { transform: scale(.99); }
.drive-mini .dm-area { font-size: 1.18rem; font-weight: 800; flex: 1; min-width: 0; }
.drive-mini .dm-mult { font-size: 1.08rem; font-weight: 850; color: var(--orange); }
.drive-mini .dm-mult.dm-flat { color: var(--muted); font-weight: 700; }
.drive-mini .dm-dist { font-size: .94rem; font-weight: 700; color: var(--muted); white-space: nowrap; }

/* ---- skeleton loaders (shown while data loads) ---- */
.skel { position: relative; overflow: hidden; background: var(--card); border: 1px solid var(--line);
  border-radius: 16px; margin: 6px 8px; }
.skel-line { height: 12px; border-radius: 7px; background: var(--line); }
.skel-row { display: grid; grid-template-columns: 1.35fr 0.8fr 0.8fr 1.45fr 0.7fr; align-items: center; gap: 8px; padding: 16px 14px; border-bottom: 1px solid var(--line); }
.skel-row .sk-a { height: 16px; width: 60%; }
.skel-row .sk-b { height: 22px; width: 60%; margin: 0 auto; border-radius: 8px; }
.skel-tall { height: 64px; }
.skel-block { height: 180px; }
.skel-line, .skel-row > div, .skel-tall, .skel-block { background:
  linear-gradient(90deg, var(--line) 25%, var(--row-alt) 37%, var(--line) 63%);
  background-size: 400% 100%; animation: shimmer 1.3s ease-in-out infinite; border-radius: 8px; }
@keyframes shimmer { 0% { background-position: 100% 0; } 100% { background-position: -100% 0; } }
@media (prefers-reduced-motion: reduce) {
  .skel-line, .skel-row > div, .skel-tall, .skel-block, .surge-row, .live-dot { animation: none; }
  .view-enter, .view-swipe-in-left, .view-swipe-in-right, .view-swipe-out-left, .view-swipe-out-right { animation: none; }
}

/* ---- smooth interactions (2026) ---- */
.view-enter { animation: viewIn .26s cubic-bezier(.22,.61,.36,1) both; }
.view-swipe-layer {
  position: absolute;
  inset: 0;
  width: 100%;
  height: var(--app-h);
  background: var(--bg);
  z-index: 40;
  will-change: transform, opacity;
  pointer-events: none;
  box-shadow: 0 0 18px rgba(0,0,0,.08);
}
.view-swipe-in-left { animation: viewSwipeInFromRight .34s cubic-bezier(.22,.61,.36,1) both; }
.view-swipe-in-right { animation: viewSwipeInFromLeft .34s cubic-bezier(.22,.61,.36,1) both; }
.view-swipe-out-left { animation: viewSwipeOutToLeft .34s cubic-bezier(.22,.61,.36,1) both; }
.view-swipe-out-right { animation: viewSwipeOutToRight .34s cubic-bezier(.22,.61,.36,1) both; }
.view-swipe-in-left, .view-swipe-in-right { z-index: 42; }
.view-swipe-out-left, .view-swipe-out-right { z-index: 41; }
.view-swipe-layer > .simple-header,
.view-swipe-layer > .traffic-sticky,
.view-swipe-layer > .trap-sticky,
.view-swipe-layer > .surge-header {
  position: absolute;
  left: 0;
  transform: none;
  max-width: none;
}
@keyframes viewIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes viewSwipeInFromRight { from { transform: translateX(100%); } to { transform: translateX(0); } }
@keyframes viewSwipeInFromLeft { from { transform: translateX(-100%); } to { transform: translateX(0); } }
@keyframes viewSwipeOutToLeft { from { transform: translateX(0); opacity: 1; } to { transform: translateX(-32%); opacity: .86; } }
@keyframes viewSwipeOutToRight { from { transform: translateX(0); opacity: 1; } to { transform: translateX(32%); opacity: .86; } }
/* tactile press feedback on all controls */
button, .seg-btn, .tab, .nav-choice, .loc-pick, .journey-row, .parking-row, .toilet-row, .trap-row {
  transition: transform .12s ease, background .15s ease, color .15s ease, box-shadow .15s ease;
}
button:active, .seg-btn:active, .nav-choice:active, .loc-pick:active { transform: scale(.96); }
.tab:active { transform: none; }
.surge-row, .journey-row, .parking-row, .toilet-row, .trap-row, .cctv-cell { will-change: transform; }

/* ---- simple headers ---- */
.simple-header {
  padding: calc(16px + env(safe-area-inset-top)) 14px 16px; font-size: 1.15rem; font-weight: 700;
  border-bottom: 2px solid var(--line); background: var(--card);
  display: flex; align-items: center; gap: 10px;
}
.simple-header #g63mBell { margin-left: auto; }
.topbar #locateBtn { margin-left: auto; }
/* in the traffic tab the wrapper is sticky, so its header doesn't need the inset twice */
.traffic-sticky .simple-header { padding-top: calc(16px + env(safe-area-inset-top)); }
/* demand-strip sits BELOW the topbar (which already applies the notch inset), so it
   must NOT add safe-area-inset-top again — that double-dip created a big empty band. */
.demand-strip { padding-top: 8px !important; padding-bottom: 8px !important; }
.src-badge {
  font-size: 0.62rem; background: #eef3ff; color: var(--blue);
  padding: 2px 7px; border-radius: 10px; margin-left: 6px; font-weight: 600; vertical-align: middle;
}

/* ---- traffic segmented ---- */
/* one fixed block for the traffic tab header + segment bar (no gap/bleed).
   z-index above Leaflet panes (which go up to ~700) so maps never cover it. */
.view > .simple-header,
.traffic-sticky,
.trap-sticky,
.surge-header {
  position: fixed;
  top: 0;
  left: 50%;
  width: 100%;
  max-width: 520px;
  transform: translateX(-50%);
  z-index: 1100;
  background: var(--card);
}
.traffic-sticky { background: var(--card); }
.traffic-sticky .simple-header { position: static; border-bottom: none; }
.trap-sticky { background: var(--card); border-bottom: 1px solid var(--line); }
.trap-sticky .simple-header { position: static; border-bottom: none; }
.trap-mode-toggle {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 6px;
  margin: 0 14px 12px;
}
/* No-scroll grid: all segments visible at once (can't chase a sideways scroll while driving) */
.seg {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; padding: 4px 14px 12px;
  background: var(--card); border-bottom: 1px solid var(--line);
}
.seg-btn {
  border: 1px solid var(--line); background: var(--row-alt); color: var(--muted);
  font: inherit; font-weight: 700; padding: 12px 6px; border-radius: 14px; cursor: pointer; font-size: 0.95rem;
  text-align: center; white-space: nowrap; min-height: 48px; transition: background .15s, color .15s;
}
.seg-btn.active { background: var(--brand); color: #fff; border-color: var(--brand); box-shadow: 0 3px 10px rgba(255,87,34,.35); }

.parking-list, .news-list, .toilet-list, .trap-list { list-style: none; margin: 0; padding: 0; }
.parking-row {
  display: flex; justify-content: space-between; align-items: center; gap: 12px;
  padding: 15px 14px; border-bottom: 1px solid var(--line);
}
.pk-info { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.pk-name { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pk-sub { color: var(--muted); font-size: 0.78rem; }
.pk-actions { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.pk-vac {
  display: inline-flex; align-items: baseline; gap: 3px; white-space: nowrap;
  padding: 6px 10px; border-radius: 10px; font-variant-numeric: tabular-nums;
}
.pk-vac b { font-size: 1.05rem; font-weight: 900; line-height: 1; }
.pk-vac .pk-unit { font-size: .7rem; font-weight: 800; }
.pk-vac.v-ok { background: color-mix(in srgb, var(--green) 13%, transparent); color: var(--green); }
.pk-vac.v-low { background: color-mix(in srgb, var(--orange) 14%, transparent); color: var(--orange); }
.pk-vac.v-full { background: color-mix(in srgb, var(--red) 12%, transparent); color: var(--red); }
.pk-vac.v-unknown { background: var(--row-alt); color: var(--muted); }
.pk-nav {
  border: 1px solid var(--line); background: var(--row-alt); color: var(--blue);
  border-radius: 10px; min-height: 34px; padding: 0 10px; font-size: 0.78rem; font-weight: 850;
}
.v-ok { color: var(--green); }
.v-low { color: var(--orange); }
.v-full { color: var(--red); }
.v-unknown { color: var(--muted); }

.cctv-grid { display: grid; grid-template-columns: 1fr; gap: 12px; padding: 12px 14px; }
.cctv-cell { margin: 0; border-radius: 14px; overflow: hidden; background: #000; position: relative; box-shadow: 0 2px 10px rgba(0,0,0,.12); }
.cctv-cell img { width: 100%; height: 210px; object-fit: cover; display: block; }
.cctv-cell figcaption {
  position: absolute; bottom: 0; left: 0; right: 0; color: #fff;
  background: linear-gradient(transparent, rgba(0,0,0,.75));
  font-size: 1rem; padding: 26px 14px 10px; font-weight: 700;
}
.cctv-failed img { display: none; }
.cctv-failed::after {
  content: "📷 暫無畫面"; display: block; height: 210px; line-height: 210px;
  text-align: center; color: #999; background: #f0f0f0; font-size: 0.95rem;
}
.cctv-failed figcaption { color: #555; background: none; }

.news-row { padding: 13px 14px; border-bottom: 1px solid var(--line); font-size: 0.9rem; line-height: 1.5; }
.loading { padding: 20px 14px; color: var(--muted); text-align: center; }

/* ---- toilet ---- */
.toilet-row { padding: 14px; border-bottom: 1px solid var(--line); }
.t-main { display: flex; justify-content: space-between; align-items: baseline; }
.t-name { font-weight: 700; font-size: 1.05rem; }
.t-dist { color: var(--brand); font-weight: 700; font-size: 0.9rem; }
.t-sub { color: var(--muted); font-size: 0.8rem; margin-top: 3px; }
.t-tags { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; margin-top: 8px; }
.tg { font-size: 0.72rem; background: #f0f0f0; color: #555; padding: 3px 8px; border-radius: 8px; }
.tg-ok { background: #e8f5e9; color: var(--green); }
.t-nav { margin-left: auto; color: var(--blue); text-decoration: none; font-size: 0.82rem; font-weight: 600; }

/* ---- profile (2026) ---- */
.profile-card { text-align: center; padding: 26px 14px 16px; }
.avatar { font-size: 2.4rem; width: 78px; height: 78px; margin: 0 auto; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg, #ff7a45, #ff5722); box-shadow: 0 6px 18px rgba(255,87,34,.32); }
.profile-name { font-weight: 850; font-size: 1.4rem; margin-top: 12px; letter-spacing: -.02em; }
.profile-sub { color: var(--muted); font-size: 0.8rem; margin-top: 5px; }

.profile-auth-card, .profile-location-share, .profile-contact-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  margin: 12px 14px 0;
  padding: 14px;
  border: 1px solid var(--line);
  border-radius: 16px;
  background: var(--card);
  box-shadow: 0 2px 8px rgba(20,20,40,.04);
}
[data-theme="dark"] .profile-auth-card, [data-theme="dark"] .profile-location-share, [data-theme="dark"] .profile-contact-card { box-shadow: none; }
.profile-auth-title { font-weight: 900; font-size: .98rem; }
.profile-auth-sub { margin-top: 3px; color: var(--muted); font-size: .76rem; line-height: 1.35; font-weight: 700; }
.profile-auth-btn {
  flex: 0 0 auto;
  min-width: 86px;
  min-height: 44px;
  border: none;
  border-radius: 22px;
  background: var(--brand);
  color: #fff;
  font: inherit;
  font-weight: 900;
  cursor: pointer;
  padding: 10px 16px;
}
.profile-auth-card.is-logged-in .profile-auth-btn {
  background: var(--row-alt);
  color: var(--red);
  border: 1px solid var(--line);
}
.profile-location-share.is-on .profile-auth-btn {
  background: var(--row-alt);
  color: var(--red);
  border: 1px solid var(--line);
}
.profile-location-share.is-off .profile-auth-btn {
  background: var(--brand);
  color: #fff;
}
.profile-devices {
  margin: 12px 14px 0;
  padding: 14px;
  border: 1px solid var(--line);
  border-radius: 16px;
  background: var(--card);
  box-shadow: 0 2px 8px rgba(20,20,40,.04);
}
[data-theme="dark"] .profile-devices { box-shadow: none; }
.profile-devices-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 8px;
}
.profile-devices-head h2 {
  margin: 0;
  font-size: .98rem;
  font-weight: 900;
}
.profile-devices-refresh {
  min-height: 44px;
  border: 1px solid var(--line);
  border-radius: 22px;
  background: var(--row-alt);
  color: var(--fg);
  font: inherit;
  font-size: .8rem;
  font-weight: 900;
  cursor: pointer;
  padding: 8px 13px;
}
.profile-devices-list {
  display: grid;
  gap: 10px;
}
.profile-device-row {
  min-height: 54px;
  padding-top: 10px;
  border-top: 1px solid var(--line);
}
.profile-device-empty {
  color: var(--muted);
  font-size: .82rem;
  font-weight: 700;
  padding: 10px 0 2px;
}
.device-current {
  color: var(--green);
  font-size: .78rem;
}
.device-logout-btn {
  border: 1px solid var(--line);
  background: var(--row-alt);
  color: var(--red);
}

.stat-grid { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 10px; padding: 8px 14px 4px; }
.stat { background: var(--card); border: 1px solid var(--line); border-radius: 16px; padding: 16px 6px; text-align: center;
  box-shadow: 0 2px 8px rgba(20,20,40,.04); }
[data-theme="dark"] .stat { box-shadow: none; }
.stat-num { display: block; font-size: 1.7rem; font-weight: 850; color: var(--brand); letter-spacing: -.02em; }
.stat-label { font-size: 0.72rem; color: var(--muted); font-weight: 600; margin-top: 2px; }

.settings { padding: 14px; }
.setting-row { display: flex; justify-content: space-between; align-items: center; gap: 12px;
  background: var(--card); border: 1px solid var(--line); border-radius: 14px;
  padding: 14px 16px; margin-bottom: 10px; font-weight: 600; box-shadow: 0 1px 4px rgba(20,20,40,.03); }
[data-theme="dark"] .setting-row { box-shadow: none; }
/* custom dropdown — native chrome removed, brand chevron, tactile */
.setting-row select, .modal label select {
  -webkit-appearance: none; appearance: none; font: inherit; font-weight: 700;
  color: var(--fg); background: var(--row-alt); border: 1px solid var(--line);
  padding: 8px 30px 8px 12px; border-radius: 10px; cursor: pointer; min-height: 40px; text-align: right;
  min-width: 132px; max-width: 58%;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'><path d='M1 1l5 5 5-5' fill='none' stroke='%235f6670' stroke-width='2' stroke-linecap='round'/></svg>");
  background-repeat: no-repeat; background-position: right 13px center;
}
.setting-row select:focus, .modal label select:focus {
  outline: none;
  border-color: var(--line);
  background-color: var(--card);
  box-shadow: 0 0 0 3px rgba(255,87,34,.12);
}
.ghost-btn { background: var(--card); border: 1px solid var(--line); color: var(--red); font: inherit; font-weight: 700;
  padding: 14px 16px; border-radius: 14px; cursor: pointer; width: 100%; margin-top: 6px; }
.ghost-btn:active { background: var(--row-alt); }
.legal-links { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px 14px; padding: 2px 16px 0; }
.legal-links a, .legal-links button { color: var(--muted); font-family: inherit; font-size: 0.76rem; font-weight: 700; text-decoration: none; border: 0; background: transparent; padding: 0; cursor: pointer; }
.legal-links a:active, .legal-links button:active { color: var(--brand); }
.legal-note { color: var(--muted); font-size: 0.72rem; line-height: 1.6; padding: 14px 16px 0; text-align: center; }

.contact-sheet label,
.contact-field {
  display: block;
  margin-top: 12px;
}
.contact-sheet label > span,
.contact-field > span {
  display: block;
  font-size: .82rem;
  font-weight: 850;
  color: var(--muted);
  margin-bottom: 6px;
}
.contact-type-native {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}
.contact-type-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
}
.contact-type-btn {
  min-height: 44px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--row-alt);
  color: var(--fg);
  font: inherit;
  font-size: .9rem;
  font-weight: 850;
  line-height: 1.2;
  padding: 9px 8px;
  cursor: pointer;
  white-space: normal;
  word-break: keep-all;
}
.contact-type-btn.on {
  border-color: var(--brand);
  background: rgba(255,87,34,.12);
  color: var(--brand);
}
.contact-type-btn:active {
  transform: translateY(1px);
}
.contact-sheet textarea,
.contact-sheet input {
  width: 100%;
  resize: vertical;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--card);
  color: var(--fg);
  font: inherit;
  font-weight: 700;
  line-height: 1.45;
  padding: 11px 12px;
}
.contact-sheet textarea { min-height: 120px; }
.contact-sheet input { min-height: 44px; resize: none; }
.contact-sheet textarea:focus,
.contact-sheet input:focus {
  outline: none;
  border-color: var(--brand);
}

/* uber connect */
.uber-connect { margin: 16px 14px 0; padding: 14px; border: 1px solid var(--line); border-radius: 14px; background: var(--row-alt); }
.uc-title { font-weight: 800; font-size: 1rem; margin-bottom: 6px; }
.uc-hint { color: var(--muted); font-size: 0.74rem; line-height: 1.5; margin: 0 0 10px; }
.uc-status { font-weight: 700; font-size: 0.85rem; margin-bottom: 8px; }
.uber-connect textarea { width: 100%; font: inherit; font-size: 0.82rem; padding: 10px; border: 1px solid var(--line); border-radius: 10px; resize: vertical; background: var(--card); color: var(--fg); }
.uc-actions { display: flex; gap: 10px; margin-top: 10px; }
.uc-actions button { flex: 1; }

/* ---- FAB ---- */
.fab {
  position: fixed; right: 50%; transform: translateX(min(246px, 44vw));
  bottom: calc(var(--tab-h) + 16px + env(safe-area-inset-bottom));
  background: var(--brand); color: #fff; border: none; font: inherit; font-weight: 700;
  padding: 13px 18px; border-radius: 28px; box-shadow: 0 4px 14px rgba(255,87,34,.45);
  cursor: pointer; z-index: 20; font-size: 0.95rem;
}

/* ---- modal ---- */
.modal-backdrop {
  position: fixed; inset: 0; background: rgba(0,0,0,.5); z-index: 2000;
  display: flex; align-items: flex-end; justify-content: center;
}
.modal {
  background: var(--card); width: 100%; max-width: 520px; border-radius: 18px 18px 0 0;
  padding: 22px 18px calc(22px + env(safe-area-inset-bottom));
  animation: slideup .2s ease;
  max-height: 85vh; overflow-y: auto; -webkit-overflow-scrolling: touch;
}
@keyframes slideup { from { transform: translateY(100%); } to { transform: translateY(0); } }
.modal h2 { margin: 0 0 16px; font-size: 1.2rem; }
.modal label { display: block; font-size: 0.85rem; color: var(--muted); margin-bottom: 14px; }
.modal label select, .modal label input {
  display: block; width: 100%; font: inherit; color: var(--fg); margin-top: 6px;
  padding: 11px; border: 1px solid var(--line); border-radius: 10px;
}
.modal-actions { display: flex; gap: 10px; margin-top: 6px; }
.modal-actions button { flex: 1; }
.primary-btn { background: var(--brand); color: #fff; border: none; font: inherit; font-weight: 700; padding: 13px; border-radius: 10px; cursor: pointer; }
.modal-hint { color: var(--muted); font-size: 0.72rem; margin: 12px 0 0; line-height: 1.5; }
.location-consent-sheet p {
  margin: 0 0 10px;
  color: var(--muted);
  font-size: 0.86rem;
  line-height: 1.55;
}
.location-consent-sheet a { color: var(--brand); font-weight: 750; }
.location-consent-sheet .modal-actions { margin-top: 14px; }
#locationConsentModal {
  align-items: center;
  padding: max(16px, env(safe-area-inset-top)) 12px max(16px, env(safe-area-inset-bottom));
  overflow-y: auto;
}
.location-consent-sheet {
  border-radius: 14px;
  max-height: min(720px, calc(100dvh - 32px));
  padding-bottom: 22px;
}
.trap-report-sheet h2 { margin-bottom: 12px; }
.trap-note-label input {
  min-height: 48px; background: var(--row-alt);
}
.trap-type-grid {
  display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; margin: 10px 0 8px;
}
.trap-type-btn {
  min-height: 58px; border: 1px solid var(--line); border-radius: 14px;
  background: var(--row-alt); color: var(--fg); font: inherit; font-size: 1.08rem;
  font-weight: 850; cursor: pointer; white-space: nowrap; word-break: keep-all;
}
.trap-type-btn:active { background: var(--brand); color: #fff; }
.trap-type-btn:disabled {
  opacity: .58; cursor: wait; transform: none;
}
.trap-report-sheet.is-posting .ghost-btn {
  opacity: .58; pointer-events: none;
}
.driver-type-sheet h2 {
  margin-bottom: 14px;
}
.driver-type-choices {
  display: grid;
  gap: 10px;
}
.driver-type-choices button {
  min-height: 82px;
  padding: 13px 14px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--row-alt);
  color: var(--fg);
  font: inherit;
  text-align: left;
  cursor: pointer;
  display: grid;
  grid-template-columns: 54px 1fr;
  gap: 12px;
  align-items: center;
}
.dt-copy {
  min-width: 0;
}
.driver-type-choices .dt-copy b {
  display: block;
  font-size: 1rem;
  font-weight: 950;
  margin-bottom: 4px;
}
.driver-type-choices .dt-copy span {
  display: block;
  color: var(--muted);
  font-size: .8rem;
  line-height: 1.35;
  font-weight: 700;
}
.driver-type-choices button:active {
  border-color: rgba(255,87,34,.55);
  background: rgba(255,87,34,.10);
}
.dt-icon-pair { display: inline-flex; gap: 5px; flex: none; align-items: center; }
.dt-icon-pair .dt-icon { width: 40px; height: 40px; }
/* The Uber/taxi choice shows two icons, so let its icon column auto-size instead of the fixed 54px. */
.driver-type-choices button[data-driver-type-pick="uber"] { grid-template-columns: auto 1fr; }
.dt-icon {
  width: 54px;
  height: 44px;
  border-radius: 13px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  position: relative;
  overflow: hidden;
  flex: none;
}
.dt-car {
  background: linear-gradient(180deg, #eef3f7, #d8e1e8);
}
.dt-car::before {
  content: "";
  width: 34px;
  height: 16px;
  border-radius: 11px 11px 7px 7px;
  background: #2f3b48;
  box-shadow: inset 0 0 0 2px rgba(255,255,255,.18);
}
.dt-car::after {
  content: "";
  position: absolute;
  left: 13px;
  right: 13px;
  bottom: 9px;
  height: 6px;
  border-radius: 999px;
  background: radial-gradient(circle at 4px 3px, #111 0 3px, transparent 3.5px),
    radial-gradient(circle at calc(100% - 4px) 3px, #111 0 3px, transparent 3.5px);
}
.dt-uber {
  background: #050609;
  color: #fff;
  font-size: .78rem;
  font-style: normal;
  font-weight: 950;
  letter-spacing: 0;
}
.dt-taxi {
  background: linear-gradient(180deg, #f8fbff 0 48%, #e52727 49% 100%);
  border: 1px solid rgba(0,0,0,.10);
}
.dt-taxi::before {
  content: "TAXI";
  position: absolute;
  top: 5px;
  left: 8px;
  right: 8px;
  height: 15px;
  border-radius: 5px;
  background: #111;
  color: #fff;
  font-size: 8px;
  line-height: 15px;
  text-align: center;
  font-style: normal;
  font-weight: 950;
}
.dt-taxi::after {
  content: "";
  position: absolute;
  left: 12px;
  right: 12px;
  bottom: 7px;
  height: 7px;
  border-radius: 999px;
  background: radial-gradient(circle at 4px 4px, #111 0 3px, transparent 3.5px),
    radial-gradient(circle at calc(100% - 4px) 4px, #111 0 3px, transparent 3.5px);
}

/* ---- PWA update / install banner ---- */
.pwa-banner {
  position: fixed; left: 50%;
  bottom: calc(var(--tab-h) + env(safe-area-inset-bottom) + 12px);
  width: min(520px, calc(100vw - 24px));
  display: flex; align-items: center; gap: 10px;
  background: var(--fg); color: var(--bg);
  padding: 11px 12px 11px 16px; border-radius: 14px; z-index: 900;
  box-shadow: 0 8px 28px rgba(0,0,0,.28); font-size: 0.88rem;
  transform: translateX(-50%) translateY(-12px); opacity: 0; pointer-events: none;
  transition: transform .28s ease, opacity .28s ease;
}
.pwa-banner.show { transform: translateX(-50%) translateY(0); opacity: 1; pointer-events: auto; }
.pwa-banner-txt { flex: 1; line-height: 1.35; }
.pwa-banner-btn {
  flex: 0 0 auto; border: none; background: var(--brand); color: #fff;
  font: inherit; font-weight: 700; font-size: 0.85rem; padding: 8px 16px;
  border-radius: 20px; cursor: pointer; min-height: 40px;
}
.pwa-banner-x {
  flex: 0 0 auto; border: none; background: transparent; color: var(--bg);
  font-size: 0.95rem; cursor: pointer; opacity: .65; padding: 6px 4px;
}
.app-update-bar {
  position: fixed; left: 0; right: 0; top: 0;
  z-index: 4000; min-height: calc(44px + env(safe-area-inset-top));
  padding: calc(10px + env(safe-area-inset-top)) 16px 10px;
  border: 0; border-radius: 0; background: #ff5722; color: #fff;
  display: flex; align-items: center; justify-content: center; gap: 10px; flex-wrap: wrap;
  font: inherit; font-size: 0.9rem; font-weight: 800; text-align: center; cursor: pointer;
  box-shadow: 0 8px 26px rgba(0,0,0,.24);
  transform: translateY(-105%); opacity: 0;
  transition: transform .28s ease, opacity .28s ease;
}
.app-update-bar.show { transform: translateY(0); opacity: 1; }
.app-update-main { line-height: 1.25; }
.app-update-tap {
  line-height: 1.2; font-size: 0.74rem; font-weight: 900; opacity: .92;
  padding: 4px 8px; border-radius: 999px; background: rgba(255,255,255,.18);
}

/* ---- tab bar ---- */
/* IG-style floating bottom nav: dark glassy pill, detached from the edges, icons only.
   z-index 1000 keeps it above Leaflet map panes. */
.tabbar {
  position: fixed; left: 50%; transform: translateX(-50%);
  bottom: var(--nav-bottom);
  width: min(430px, calc(100% - 36px));
  display: flex; align-items: stretch; justify-content: space-between; gap: 0; z-index: 1000;
  padding: 6px 8px;
  background: rgba(8,12,16,.90);
  -webkit-backdrop-filter: saturate(170%) blur(22px); backdrop-filter: saturate(170%) blur(22px);
  border-radius: 30px;
  box-shadow: 0 14px 34px rgba(0,0,0,.34), inset 0 0 0 1px rgba(255,255,255,.06);
  border: 1px solid rgba(255,255,255,.12);
  transform-origin: 50% 100%;
  transition: opacity .22s ease;
}
body.hide-uber-tab .tab[data-tab="surge"] {
  display: none;
}
.tab {
  flex: 1 1 0; min-width: 0; height: 48px; border: none; background: none;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  cursor: pointer; border-radius: 14px; color: rgba(255,255,255,.62); position: relative;
  transition: background .18s ease, color .2s;
  touch-action: manipulation; pointer-events: auto;
}
.tab::before {
  content: "";
  position: absolute;
  inset: 5px 2px;
  border-radius: 20px;
  background: transparent;
  transition: background .18s ease, inset .22s cubic-bezier(.22,.61,.36,1), border-radius .22s ease;
}
.tab-icon { width: 21px; height: 21px; position: relative; z-index: 1; transition: width .22s cubic-bezier(.22,.61,.36,1), height .22s cubic-bezier(.22,.61,.36,1), transform .22s cubic-bezier(.22,1.2,.36,1); }
.tab-icon-airport { left: -1px; }
/* labels ALWAYS visible (icon + text) so the nav reads the same on every tab — older
   drivers shouldn't have to decode icon-only buttons. Driving mode just enlarges it. */
.tab-label { font-size: .6rem; font-weight: 700; line-height: 1; white-space: nowrap; letter-spacing: 0; position: relative; z-index: 1; }
.tab.active { color: #fff; }
.tab.active::before { background: rgba(255,255,255,.15); }
.tab.active .tab-label { color: var(--brand); }
.tab.active .tab-icon { transform: scale(1.16); }
.tab:active .tab-icon { transform: scale(.9); }
[data-theme="dark"] .tabbar { background: rgba(30,30,34,.82); }

/* ---- driving mode: huge glanceable rows, single product, top zones ---- */
/* keep the header consistent in driving mode (was hidden, which made the layout jump) */
body.driving .topbar { padding-top: calc(8px + env(safe-area-inset-top)); padding-bottom: 8px; }
body.driving .data-note, body.driving .crowd-tag { display: none; }
.surge-row.drive-row {
  grid-template-columns: 1.3fr 1fr 0.8fr;
  min-height: 96px; padding: 14px 16px; align-items: center;
}
.drive-row .col-region { font-size: 1.75rem; font-weight: 800; padding-left: 10px; }
.drive-row .col-mult { font-size: 3rem; font-weight: 900; line-height: 1; text-align: center; }
.drive-row .col-mult small { font-size: 1.1rem; font-weight: 700; margin-left: 2px; }
.drive-row .col-dist { font-size: 1.3rem; font-weight: 700; text-align: right; }
.drive-row .col-dist small { font-size: 0.8rem; color: var(--muted); margin-left: 2px; }
.drive-row .bar { width: 8px; }
/* driving = in-car: oversize the controls AND stack them full-width so 3 big mode
   buttons + the 排序 button never overflow the row (was causing horizontal scroll). */
/* driving mode stacks the full-width toggle + full-width 排序 onto two rows, so it must wrap
   (the base .refresh-row is nowrap to stop the compact controls wrapping on narrow phones). */
body.driving .refresh-row { padding: 12px 16px; gap: 10px; justify-content: center; flex-wrap: wrap; }
body.driving .view-toggle { display: flex; width: 100%; }
body.driving .vt-btn { flex: 1; font-size: 1.12rem; padding: 15px 8px; min-height: 56px; }
body.driving .refresh-row .sort-btn { flex: 1 1 100%; justify-content: center; font-size: 1.05rem; padding: 15px 16px; min-height: 56px; }
body.driving .map-legend { font-size: .82rem; padding: 9px 13px; }
/* driving mode applies to every tab: larger text + tap targets */
body.driving .tn-name, body.driving .t-name, body.driving .pk-name,
body.driving .fl-no { font-size: 1.25rem; }
body.driving .tn-toll { font-size: 1.7rem; }
body.driving .fl-time { font-size: 1.5rem; }
body.driving .tn-time, body.driving .t-dist, body.driving .pk-vac { font-size: 1.05rem; }
body.driving .seg-btn { font-size: 1.08rem; padding: 16px 6px; min-height: 56px; }
/* DRIVING MODE: SAME floating rounded nav, just scaled up for big in-car tap zones —
   keeps a consistent shape with normal mode (no jarring morph), and never shrinks on scroll. */
body.driving .tabbar {
  bottom: var(--nav-bottom);
  padding: 8px 6px; background: rgba(16,16,18,.94);
}
body.driving .tab { height: 62px; gap: 3px; }
body.driving .tab::before { inset: 6px 5px; border-radius: 24px; }
body.driving .tab-icon { width: 30px; height: 30px; }
body.driving .tab-label { font-size: .82rem; font-weight: 800; }
body.driving .tabbar.nav-min { transform: translateX(-50%) !important; opacity: 1 !important; pointer-events: auto !important; }
body.driving .simple-header { font-size: 1.35rem; }
body.driving .demand-strip { font-size: 1.05rem; padding: 14px 56px 14px 14px; }

/* ---- toast ---- */
.toast {
  position: fixed; bottom: calc(var(--tab-h) + 80px); left: 50%; transform: translateX(-50%);
  background: rgba(0,0,0,.85); color: #fff; padding: 11px 18px; border-radius: 22px;
  font-size: 0.88rem; z-index: 1100; max-width: 90%; text-align: center;
}

/* ---- tunnel list ---- */
.tunnel-list { list-style: none; margin: 0; padding: 0; }
.tunnel-row { padding: 14px; border-bottom: 1px solid var(--line); }
.tn-top { display: flex; justify-content: space-between; align-items: baseline; }
.tn-name { font-weight: 700; font-size: 1.05rem; }
.tn-toll { font-weight: 800; font-size: 1.35rem; }
/* two clean lines: [trend pill ........ 導航] then the 📍 distance·ETA full-width */
.tn-sub { display: flex; flex-direction: column; gap: 7px; margin-top: 8px; }
.tn-sub-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.tn-meta { color: var(--muted); font-size: 0.8rem; }
.tn-trend { font-size: 0.76rem; padding: 3px 11px; border-radius: 999px; font-weight: 700; white-space: nowrap; }
.tn-up { background: #fdecea; color: var(--red); }
.tn-down { background: #e8f5e9; color: var(--green); }
.tn-flatt { background: #f0f0f0; color: var(--muted); }
.tn-time { color: var(--blue); font-weight: 700; font-size: 0.84rem; }
.tn-nav { color: var(--blue); text-decoration: none; font-weight: 700; font-size: 0.84rem; white-space: nowrap; flex: none; }

/* ---- journey time ---- */
.journey-list { list-style: none; margin: 0; padding: 0; }
.journey-row { display: flex; justify-content: space-between; align-items: center; padding: 15px 14px; border-bottom: 1px solid var(--line); }
.jr-name { font-weight: 700; font-size: 1.05rem; }
.jr-time { color: var(--blue); font-weight: 600; font-variant-numeric: tabular-nums; }
.jr-time b { color: var(--fg); font-size: 1.05rem; }

/* ---- flight list ---- */
.airport-forecast-card {
  position: relative; z-index: 0;
  margin: 10px 16px 12px; padding: 15px 14px;
  border: 1px solid var(--line); border-radius: 14px; background: var(--card);
  box-shadow: 0 1px 4px rgba(0,0,0,.05);
}
.airport-subheader {
  margin: 16px 18px 8px; color: var(--muted);
  font-size: .82rem; font-weight: 850; letter-spacing: 0; line-height: 1.2;
}
#airportCarparkList {
  display: grid; grid-template-columns: 1fr 1fr; gap: 10px;
  padding: 8px 18px 12px; list-style: none; margin: 0;
}
.apk-chip { display: flex; flex-direction: column; gap: 8px; padding: 12px; background: var(--card); border: 1px solid var(--line); border-radius: 14px; }
.apk-chip .apk-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 6px; }
.apk-chip .apk-name {
  min-width: 0; font-weight: 800; font-size: 13.5px; line-height: 1.25; color: var(--fg);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.apk-chip .apk-code {
  flex-shrink: 0; font-size: 10.5px; font-weight: 900; letter-spacing: .02em;
  padding: 2px 7px; border-radius: 999px; background: var(--row-alt); color: var(--muted);
}
.apk-chip .apk-vac {
  display: flex; align-items: baseline; justify-content: center; gap: 4px;
  padding: 9px 6px; border-radius: 12px; font-variant-numeric: tabular-nums;
}
.apk-chip .apk-vac b { font-size: 22px; font-weight: 900; line-height: 1; }
.apk-chip .apk-vac .apk-unit { font-size: 11px; font-weight: 800; }
.apk-chip .apk-vac.v-ok { background: color-mix(in srgb, var(--green) 13%, transparent); color: var(--green); }
.apk-chip .apk-vac.v-low { background: color-mix(in srgb, var(--orange) 14%, transparent); color: var(--orange); }
.apk-chip .apk-vac.v-full { background: color-mix(in srgb, var(--red) 12%, transparent); color: var(--red); }
.apk-chip .apk-vac.v-unknown { background: var(--row-alt); color: var(--muted); }
.apk-chip .apk-bottom { display: flex; align-items: center; justify-content: space-between; gap: 6px; min-height: 22px; }
.apk-chip .apk-meta { min-width: 0; color: var(--muted); font-size: 10.5px; font-weight: 750; line-height: 1.2; }
.apk-chip .apk-nav {
  flex-shrink: 0; display: inline-flex; align-items: center; gap: 2px;
  padding: 5px 11px; border-radius: 999px; border: 1px solid var(--line);
  background: var(--row-alt); color: var(--blue); font-size: 11.5px; font-weight: 850; line-height: 1;
}
.af-title { font-size: 1.05rem; font-weight: 850; color: var(--fg); }
.af-kicker { margin-bottom: 8px; color: var(--muted); font-size: .74rem; font-weight: 800; line-height: 1.25; }
.af-verdict {
  display: inline-flex; align-items: center; max-width: 100%;
  padding: 8px 12px; border-radius: 12px;
  font-size: 1.16rem; font-weight: 900; line-height: 1.25;
}
.af-go .af-verdict { background: #e8f5e9; color: var(--green); }
.af-ok .af-verdict { background: #fff3e0; color: var(--orange); }
.af-avoid .af-verdict { background: #fdecea; color: var(--red); }
.af-quiet .af-verdict { background: var(--row-alt); color: var(--muted); }
.airport-forecast-card.af-locked { position: relative; overflow: hidden; min-height: 92px; }
.airport-forecast-card .premium-lock-overlay { z-index: 2; }

/* 需求預測 — GPS-local free preview + four-hour paid planner */
.demand-zones-card {
  margin: 10px 16px 12px; padding: 14px;
  border: 1px solid var(--line); border-radius: 16px; background: var(--card);
  box-shadow: 0 5px 18px rgba(15,23,42,.07);
}
.demand-zones-card.hidden { display: none; }
.dz-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 2px; }
.dz-sub { color: var(--muted); font-size: .74rem; font-weight: 650; line-height: 1.35; margin-bottom: 12px; }
.dz-title { font-size: 1.04rem; font-weight: 900; color: var(--fg); letter-spacing: -.015em; }
.dz-access {
  flex: 0 0 auto; padding: 3px 7px; border: 1px solid color-mix(in srgb, var(--orange) 36%, var(--line));
  border-radius: 999px; background: color-mix(in srgb, var(--orange) 9%, var(--card)); color: var(--orange);
  font-size: .59rem; font-weight: 900; letter-spacing: .045em; line-height: 1.2;
}
.dz-access.is-paid {
  border-color: color-mix(in srgb, var(--green) 38%, var(--line));
  background: color-mix(in srgb, var(--green) 9%, var(--card)); color: var(--green);
}
.dz-freshness {
  margin: 0 0 11px; padding: 9px 10px; border: 1px solid color-mix(in srgb, var(--green) 24%, var(--line));
  border-radius: 11px; background: color-mix(in srgb, var(--green) 6%, var(--card));
}
.dz-freshness-main { display: flex; align-items: center; gap: 6px; min-width: 0; }
.dz-freshness-main b { color: var(--fg); font-size: .69rem; font-weight: 900; }
.dz-freshness-main > span:last-child { margin-left: auto; color: var(--green); font-size: .62rem; font-weight: 850; white-space: nowrap; }
.dz-freshness-dot { width: 7px; height: 7px; flex: 0 0 auto; border-radius: 50%; background: var(--green); box-shadow: 0 0 0 3px color-mix(in srgb, var(--green) 13%, transparent); }
.dz-freshness-proof { margin: 4px 0 0 13px; color: var(--muted); font-size: .61rem; font-weight: 700; line-height: 1.35; }
.dz-freshness-warning { margin: 4px 0 0 13px; color: var(--orange); font-size: .61rem; font-weight: 850; }
.dz-freshness.is-stale { border-color: color-mix(in srgb, var(--orange) 35%, var(--line)); background: color-mix(in srgb, var(--orange) 7%, var(--card)); }
.dz-freshness.is-stale .dz-freshness-dot { background: var(--orange); box-shadow: 0 0 0 3px color-mix(in srgb, var(--orange) 13%, transparent); }
.dz-freshness.is-stale .dz-freshness-main > span:last-child { color: var(--orange); }
.dz-picker { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; gap: 10px; margin-bottom: 10px; }
.dz-picker > span { color: var(--muted); font-size: .72rem; font-weight: 850; }
.dz-zone-button {
  position: relative; display: flex; align-items: center; width: 100%; min-width: 0; min-height: 44px;
  padding: 0 38px 0 12px; border: 1px solid var(--line); border-radius: 10px;
  background: var(--row-alt); color: var(--fg); font: inherit; font-size: .85rem; font-weight: 800; cursor: pointer;
}
.dz-zone-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dz-select-chevron {
  position: absolute; top: 50%; right: 11px; width: 17px; height: 17px; transform: translateY(-50%);
  pointer-events: none; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round;
}
.dz-zone-button:active { border-color: var(--orange); background: color-mix(in srgb, var(--orange) 8%, var(--card)); }
.dz-zone-button:focus-visible { border-color: var(--orange); outline: 2px solid color-mix(in srgb, var(--orange) 24%, transparent); outline-offset: 1px; }
.dz-hours { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 5px; margin-bottom: 10px; }
.dz-hour {
  min-width: 0; min-height: 48px; padding: 6px 2px; border: 1px solid var(--line); border-radius: 10px;
  background: var(--row-alt); color: var(--fg); font: inherit; text-align: center;
}
.dz-hour span { display: block; font-size: .78rem; font-weight: 900; line-height: 1.1; white-space: nowrap; }
.dz-hour small { display: block; margin-top: 4px; color: var(--muted); font-size: .61rem; font-weight: 800; line-height: 1; }
.dz-hour.active { border-color: var(--orange); background: color-mix(in srgb, var(--orange) 10%, var(--card)); color: var(--orange); }
.dz-hour.locked { opacity: .52; cursor: pointer; }
.dz-hour:focus-visible, .dz-rank-row:focus-visible, .dz-upgrade:focus-visible, .dz-location-btn:focus-visible, .dz-nav:focus-visible {
  outline: 2px solid var(--orange); outline-offset: 2px;
}
.dz-hero {
  padding: 13px; border: 1px solid var(--line); border-radius: 13px;
  background: linear-gradient(145deg, color-mix(in srgb, var(--row-alt) 88%, transparent), var(--card));
}
.dz-hero-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.dz-hero-place { display: block; color: var(--fg); font-size: 1rem; font-weight: 900; }
.dz-hero-hour { display: block; margin-top: 2px; color: var(--muted); font-size: .7rem; font-weight: 750; }
.dz-trend { flex: 0 0 auto; color: var(--muted); font-size: .7rem; font-weight: 850; white-space: nowrap; }
.dz-hero-main { display: flex; align-items: baseline; gap: 9px; margin-top: 12px; }
.dz-tier-label { color: var(--muted); font-size: .76rem; font-weight: 800; }
.dz-hero-main strong { font-size: 2rem; line-height: 1; font-weight: 950; letter-spacing: -.04em; }
.dz-tier-blast .dz-hero-main strong, .dz-rank-tier.dz-tier-blast { color: #d92d20; }
.dz-tier-high .dz-hero-main strong, .dz-rank-tier.dz-tier-high { color: var(--orange); }
.dz-tier-mid .dz-hero-main strong, .dz-rank-tier.dz-tier-mid { color: #b7791f; }
.dz-tier-low .dz-hero-main strong, .dz-rank-tier.dz-tier-low { color: var(--muted); }
.dz-confidence { display: flex; justify-content: space-between; gap: 8px; margin-top: 10px; color: var(--muted); font-size: .69rem; font-weight: 750; }
.dz-preview-summary {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  margin-bottom: 10px; padding: 10px 12px; border: 1px solid var(--line); border-radius: 12px; background: var(--row-alt);
}
.dz-preview-summary > div:first-child { min-width: 0; }
.dz-preview-summary b { display: block; overflow: hidden; color: var(--fg); font-size: .9rem; font-weight: 900; text-overflow: ellipsis; white-space: nowrap; }
.dz-preview-summary small { display: block; margin-top: 3px; color: var(--muted); font-size: .63rem; font-weight: 750; }
.dz-preview-summary > div:last-child { display: flex; align-items: baseline; gap: 7px; flex: 0 0 auto; }
.dz-preview-summary span { color: var(--muted); font-size: .65rem; font-weight: 800; }
.dz-preview-summary strong { font-size: 1.45rem; font-weight: 950; line-height: 1; }
.dz-preview-summary.dz-tier-blast strong { color: #d92d20; }
.dz-preview-summary.dz-tier-high strong { color: var(--orange); }
.dz-preview-summary.dz-tier-mid strong { color: #b7791f; }
.dz-preview-summary.dz-tier-low strong { color: var(--muted); }
.dz-chart {
  margin-bottom: 10px; padding: 11px 11px 9px; border: 1px solid var(--line); border-radius: 13px;
  background: linear-gradient(180deg, color-mix(in srgb, var(--orange) 5%, var(--card)), var(--card));
}
.dz-chart-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.dz-chart-head b { color: var(--fg); font-size: .78rem; font-weight: 900; }
.dz-chart-head span {
  padding: 3px 7px; border-radius: 999px; background: color-mix(in srgb, var(--orange) 10%, var(--card));
  color: var(--orange); font-size: .61rem; font-weight: 900; white-space: nowrap;
}
.dz-chart-plot { display: block; width: 100%; height: 92px; margin-top: 5px; overflow: visible; }
.dz-chart-grid { fill: none; stroke: color-mix(in srgb, var(--line) 72%, transparent); stroke-width: 1; }
.dz-chart-area { fill: color-mix(in srgb, var(--orange) 15%, transparent); stroke: none; }
.dz-chart-line { fill: none; stroke: var(--orange); stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; }
.dz-chart-dot { fill: var(--card); stroke: var(--orange); stroke-width: 2.5; }
.dz-chart-dot.active { fill: var(--orange); stroke-width: 3; }
.dz-chart-labels { display: flex; align-items: center; justify-content: space-between; color: var(--muted); font-size: .59rem; font-weight: 800; }
.dz-chart-labels.is-paid { display: grid; grid-template-columns: repeat(4, 1fr); text-align: center; }
.dz-chart-note { margin-top: 5px; color: var(--muted); font-size: .59rem; font-weight: 700; text-align: center; }
.dz-nav {
  width: 100%; margin-top: 11px; padding: 9px 10px; border: 0; border-radius: 9px;
  background: color-mix(in srgb, var(--blue) 10%, var(--row-alt)); color: var(--blue);
  font: inherit; font-size: .76rem; font-weight: 850; cursor: pointer;
}
.dz-ranking { margin-top: 12px; }
.dz-ranking-title { margin-bottom: 6px; color: var(--muted); font-size: .7rem; font-weight: 850; }
.dz-ranking-list { display: grid; gap: 5px; }
.dz-rank-row {
  display: grid; grid-template-columns: 24px minmax(0, 1fr) auto; align-items: center; gap: 7px;
  width: 100%; min-height: 38px; padding: 7px 9px; border: 1px solid transparent; border-radius: 9px;
  background: var(--row-alt); color: var(--fg); font: inherit; text-align: left;
}
.dz-rank-row.active { border-color: color-mix(in srgb, var(--orange) 45%, var(--line)); }
.dz-rank-no { color: var(--muted); font-size: .7rem; font-weight: 900; }
.dz-rank-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: .82rem; font-weight: 800; }
.dz-rank-tier { font-size: .7rem; font-weight: 900; }
.dz-upgrade {
  display: flex; align-items: center; justify-content: space-between; gap: 8px; width: 100%; margin-top: 10px; padding: 11px;
  border: 1px solid color-mix(in srgb, var(--orange) 32%, var(--line)); border-radius: 11px;
  background: color-mix(in srgb, var(--orange) 7%, var(--card)); color: var(--fg); font: inherit; text-align: left;
}
.dz-upgrade span { font-size: .75rem; font-weight: 750; line-height: 1.3; }
.dz-upgrade b { flex: 0 0 auto; color: var(--orange); font-size: .7rem; font-weight: 900; }
.dz-location-body { display: flex; align-items: flex-start; gap: 11px; padding: 12px; border-radius: 12px; background: var(--row-alt); }
.dz-location-icon { flex: 0 0 auto; color: var(--orange); font-size: 1.65rem; font-weight: 400; line-height: 1; }
.dz-location-body b { color: var(--fg); font-size: .88rem; font-weight: 900; line-height: 1.3; }
.dz-location-body p { margin: 5px 0 0; color: var(--muted); font-size: .73rem; font-weight: 650; line-height: 1.4; }
.dz-location-btn {
  width: 100%; min-height: 42px; margin-top: 9px; border: 0; border-radius: 10px;
  background: var(--orange); color: #fff; font: inherit; font-size: .83rem; font-weight: 900;
}
.dz-stale { margin: -2px 0 8px; color: var(--orange); font-size: .69rem; font-weight: 800; }
.dz-tip { margin-top: 10px; color: var(--muted); font-size: .76rem; font-weight: 600; line-height: 1.4; }
.dz-road-caveat { display: block; margin-top: 4px; color: var(--orange); font-weight: 800; }
.demand-zones-card.dz-empty .dz-empty-text { color: var(--muted); font-size: .86rem; font-weight: 600; }
.transport-news-card {
  margin: 10px 16px 12px; padding: 12px 14px;
  border: 1px solid var(--line); border-radius: 14px; background: var(--card);
  box-shadow: 0 1px 4px rgba(0,0,0,.05);
}
.transport-news-card.hidden { display: none; }
.tnw-head { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.tnw-title { font-size: 1.02rem; font-weight: 850; color: var(--fg); }
.tnw-tabs { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; margin: 0 0 10px; }
.tnw-tab {
  min-height: 34px; border: 1px solid var(--line); border-radius: 9px;
  background: var(--row-alt); color: var(--muted);
  font-size: .82rem; line-height: 1.1; font-weight: 850;
}
.tnw-tab.active {
  border-color: color-mix(in srgb, var(--brand) 55%, var(--line));
  background: color-mix(in srgb, var(--brand) 14%, var(--card));
  color: var(--brand);
}
.tnw-sec { font-size: .74rem; font-weight: 850; letter-spacing: .02em; color: var(--muted); margin: 4px 0 6px; }
.tnw-sec-plan { margin-top: 12px; }
.tnw-live { list-style: none; margin: 0 0 2px; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.tnw-live-row {
  display: flex; align-items: baseline; gap: 7px;
  padding: 8px 10px; border-radius: 10px;
  background: color-mix(in srgb, var(--red) 8%, var(--row-alt));
}
.tnw-live-sev { flex-shrink: 0; font-size: .82rem; line-height: 1.35; }
.tnw-live-txt { flex: 1; min-width: 0; color: var(--fg); font-size: .84rem; font-weight: 700; line-height: 1.35; }
.tnw-live-when { flex-shrink: 0; color: var(--muted); font-size: .68rem; font-weight: 750; }
.tnw-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.tnw-row { padding: 10px 11px; border-radius: 11px; background: var(--row-alt); }
.tnw-row-head { display: flex; align-items: flex-start; gap: 8px; }
.tnw-row-head b { flex: 1; min-width: 0; color: var(--fg); font-size: .9rem; line-height: 1.35; font-weight: 850; }
.tnw-chip {
  flex: 0 0 auto; max-width: 104px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: #075985; background: #e0f2fe; border: 1px solid rgba(14,116,144,.16);
  border-radius: 999px; padding: 2px 8px; font-size: .68rem; line-height: 1.25; font-weight: 850;
}
.tnw-areas { margin-top: 4px; color: var(--blue); font-size: .76rem; line-height: 1.35; font-weight: 750; }
.tnw-period { margin-top: 4px; color: var(--fg); font-size: .78rem; line-height: 1.35; font-weight: 850; }
.tnw-detail { margin-top: 5px; color: var(--muted); font-size: .76rem; line-height: 1.4; font-weight: 600; }
.tnw-impact { margin-top: 5px; color: var(--fg); font-size: .8rem; line-height: 1.35; font-weight: 650; }
.tnw-source { display: inline-block; margin-top: 6px; color: var(--brand); font-size: .74rem; line-height: 1.25; font-weight: 850; text-decoration: none; }
.tnw-empty { padding: 10px 2px 2px; color: var(--muted); font-size: .84rem; font-weight: 750; line-height: 1.35; }
[data-theme="dark"] .tnw-chip { color: #bae6fd; background: #082f49; border-color: rgba(186,230,253,.18); }
.parking-beta-card {
  margin: 0 16px 12px; padding: 12px 14px;
  border: 1px solid var(--line); border-radius: 14px; background: var(--card);
  box-shadow: 0 1px 4px rgba(0,0,0,.05);
}
.parking-beta-card.hidden { display: none; }
.pk-section + .pk-section { margin-top: 11px; }
.pk-section-title {
  margin: 2px 0 6px; color: var(--muted); font-size: .76rem; line-height: 1.2; font-weight: 850;
}
.pk-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.pk-row {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 10px;
  min-height: 38px; padding: 8px 10px; border-radius: 10px; background: var(--row-alt); cursor: pointer;
}
.pk-row:focus-visible { outline: 2px solid var(--orange); outline-offset: 2px; }
.pk-name {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: var(--fg); font-size: .88rem; font-weight: 800;
}
.pk-meta {
  color: var(--muted); font-size: .76rem; font-weight: 750; white-space: nowrap; font-variant-numeric: tabular-nums;
}
.pk-empty { color: var(--muted); font-size: .86rem; font-weight: 650; line-height: 1.35; }
.af-locked-teaser { filter: blur(5px); opacity: .55; pointer-events: none; user-select: none; }
.af-reason { margin-top: 8px; color: var(--muted); font-size: .86rem; line-height: 1.45; font-weight: 600; }
.af-stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 7px; margin-top: 12px; }
.af-stats span {
  min-width: 0; padding: 7px 6px; border-radius: 10px; background: var(--row-alt);
  color: var(--muted); text-align: center; font-size: .68rem; font-weight: 800;
}
.af-stats b { display: block; color: var(--fg); font-size: 1.05rem; font-weight: 900; font-variant-numeric: tabular-nums; }
.af-stats i, .af-stats em { display: block; font-style: normal; }
.af-stats i { color: var(--muted); font-size: .66rem; margin-bottom: 2px; }
.af-stats em { color: var(--muted); font-size: .62rem; margin-top: 1px; }
.af-empty .af-empty-text { margin-top: 8px; color: var(--muted); font-size: .86rem; font-weight: 700; }
.flight-list { list-style: none; margin: 0; padding: 0; }
.flight-row { padding: 15px 14px; border-bottom: 1px solid var(--line); }
.flight-row.fl-landed { opacity: 0.55; }
.fl-top { display: flex; align-items: baseline; gap: 12px; }
.fl-time { font-size: 1.3rem; font-weight: 800; color: var(--brand); }
.fl-no { font-weight: 700; font-size: 1rem; }
.fl-mid { color: var(--fg); font-size: 0.9rem; margin-top: 4px; }
.fl-tags { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-top: 8px; }
.fl-hall { background: #eef3ff; color: var(--blue); font-size: 0.74rem; font-weight: 700; padding: 3px 9px; border-radius: 8px; }
.fl-bag { background: #fff3e0; color: var(--orange); font-size: 0.74rem; font-weight: 700; padding: 3px 9px; border-radius: 8px; }
.fl-status { color: var(--muted); font-size: 0.76rem; }
.fl-xl { background: #e8f5e9; color: var(--green); font-size: 0.74rem; font-weight: 800; padding: 3px 9px; border-radius: 8px; }
.fl-reg { background: #f0f0f0; color: #555; font-size: 0.74rem; font-weight: 700; padding: 3px 9px; border-radius: 8px; }
.fl-lcc { background: #fdecea; color: var(--red); font-size: 0.74rem; font-weight: 700; padding: 3px 9px; border-radius: 8px; }
.fl-ac { background: #ede7f6; color: #5e35b1; font-size: 0.74rem; font-weight: 700; padding: 3px 9px; border-radius: 8px; }
.flight-row.fl-long { border-left: 4px solid var(--green); }
[data-theme="dark"] .fl-ac { background: #2a2440; color: #b39ddb; }
[data-theme="dark"] .fl-hall { background: #1a2a44; }
[data-theme="dark"] .fl-bag { background: #3a2a14; }
[data-theme="dark"] .fl-xl { background: #16301a; }
[data-theme="dark"] .fl-reg { background: #2a2a2a; color: #bbb; }
[data-theme="dark"] .fl-lcc { background: #3a1d1a; }
[data-theme="dark"] .fl-ac { background: #2a2440; color: #b39ddb; }
[data-theme="dark"] .af-go .af-verdict { background: #16301a; }
[data-theme="dark"] .af-ok .af-verdict { background: #3a2a14; }
[data-theme="dark"] .af-avoid .af-verdict { background: #3a1d1a; }

/* card feel for list rows in the traffic tab */
.tunnel-row, .flight-row, .parking-row, .trap-row {
  margin: 8px 12px; border: 1px solid var(--line); border-radius: 14px;
  background: var(--card); box-shadow: 0 1px 4px rgba(0,0,0,.05); border-bottom: 1px solid var(--line);
}

/* ---- location picker ---- */
.loc-gps { width: 100%; font-size: 1.05rem; padding: 15px; margin-bottom: 4px; }
.loc-search-tools {
  position: sticky; top: 0; z-index: 3; display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 8px;
  margin: 4px 0 8px; padding: 2px 0 4px; background: var(--card);
}
.loc-search {
  width: 100%; min-width: 0; min-height: 48px; font: inherit; font-size: 1rem; padding: 12px 14px; margin: 0;
  border: 1px solid var(--line); border-radius: 12px; background: var(--row-alt); color: var(--fg);
}
.loc-search:focus { outline: none; border-color: var(--brand); background: var(--card); }
.loc-speech {
  width: 48px; min-height: 48px; border: 1px solid var(--line); border-radius: 12px;
  display: grid; place-items: center; background: var(--row-alt); color: var(--muted); font: inherit; cursor: pointer;
}
.loc-speech-icon { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }
.loc-speech:focus-visible { outline: 2px solid var(--orange); outline-offset: 2px; }
.loc-speech.is-listening { border-color: var(--orange); background: color-mix(in srgb, var(--orange) 12%, var(--card)); animation: loc-pulse 1s ease-in-out infinite; }
@keyframes loc-pulse { 50% { transform: scale(.94); } }
.loc-speech-status { min-height: 0; margin: -3px 2px 3px; color: var(--muted); font-size: .7rem; font-weight: 700; }
.loc-speech-status:empty { display: none; }
.loc-no-results { padding: 24px 8px; color: var(--muted); text-align: center; font-size: .86rem; font-weight: 750; }
.loc-region { margin-bottom: 6px; }
.loc-region-h { font-size: .78rem; font-weight: 800; color: var(--muted); letter-spacing: .04em; margin: 12px 2px 6px; }
.loc-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin: 0; }
.loc-pick {
  border: 1px solid var(--line); background: var(--row-alt); color: var(--fg);
  font: inherit; font-weight: 700; padding: 13px 4px; border-radius: 12px; cursor: pointer; min-height: 46px;
  transition: transform .1s ease, background .12s ease;
}
.loc-pick:active { background: var(--brand); color: #fff; transform: scale(.95); }

/* ---- nav chooser ---- */
.nav-choices { display: grid; gap: 8px; margin-bottom: 6px; }
.nav-choice {
  display: flex; align-items: center; gap: 12px; width: 100%; min-height: 54px;
  padding: 12px 15px; border: 1px solid var(--line); border-radius: 12px;
  background: var(--row-alt); color: var(--fg); font: inherit; font-weight: 600;
  cursor: pointer; text-decoration: none; line-height: 1.2;
}
.nav-choice .nc-icon-slot {
  flex: 0 0 26px; width: 26px; height: 26px; object-fit: contain;
  display: grid; place-items: center; font-size: 1.35rem; line-height: 1;
}
.nav-choice .nc-icon {
  width: 26px; height: 26px; object-fit: contain; display: block;
}
.nav-choice .nc-icon-google { width: 20px; height: 28px; }
.nav-choice .nc-icon-amap { width: 26px; height: 26px; border-radius: 6px; }

/* ---- news timestamp / severity ---- */
.news-row { display: flex; gap: 10px; align-items: flex-start; }
.news-row.news-hazard {
  border-left: 4px solid #0ea5e9;
  background: linear-gradient(90deg, rgba(14,165,233,.11), transparent 42%);
}
.news-sev { font-size: 1.05rem; line-height: 1.4; }
.news-body { flex: 1; }
.news-text { line-height: 1.5; }
.news-time { color: var(--muted); font-size: 0.72rem; }
.news-meta { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin-top: 6px; }
.news-place { color: var(--blue); font-weight: 600; font-size: 0.78rem; }
.news-mapbox { display: none; }
.news-mapbox.open {
  display: block; margin-top: 8px; height: 150px;
  border: 1px solid var(--line); border-radius: 12px; overflow: hidden;
  position: relative; z-index: 0; /* contain Leaflet's high-z panes in their own context */
}
.news-mapbox .leaflet-pane, .news-mapbox .leaflet-top, .news-mapbox .leaflet-control { z-index: 1 !important; }
.news-mapbox .leaflet-container { background: #eaeaea; font: inherit; }
.news-pin { font-size: 22px; line-height: 1; text-align: center; filter: drop-shadow(0 1px 1px rgba(0,0,0,.4)); }
.news-pin-water { font-size: 24px; filter: drop-shadow(0 1px 1px rgba(0,0,0,.45)) drop-shadow(0 0 8px rgba(14,165,233,.45)); }
[data-theme="dark"] .news-mapbox.open { filter: brightness(0.9); }
.news-demand { background: #fdecea; color: var(--red); font-size: 0.72rem; font-weight: 700; padding: 2px 8px; border-radius: 8px; }
[data-theme="dark"] .news-demand { background: #3a1d1a; }
.news-alert-chip {
  background: #e0f2fe; color: #075985; font-size: 0.72rem; font-weight: 800;
  padding: 2px 8px; border-radius: 8px; border: 1px solid rgba(14,116,144,.18);
}
[data-theme="dark"] .news-row.news-hazard {
  background: linear-gradient(90deg, rgba(14,165,233,.18), transparent 48%);
}
[data-theme="dark"] .news-alert-chip { background: #082f49; color: #bae6fd; border-color: rgba(186,230,253,.18); }
.sev-3 { color: var(--red); }
.sev-2 { color: var(--orange); }
.sev-1 { color: var(--blue); }

/* ---- speed-trap cards ---- */
.trap-full-map {
  position: relative;
  z-index: 0;
  height: calc(var(--app-h) - var(--active-header-h) - var(--trap-ad-h) - var(--bottom-clearance) - 18px);
  min-height: 0;
  margin: 4px 10px 0;
  border: 1px solid var(--line);
  border-radius: 18px;
  overflow: hidden;
  background: #e9eaec;
}
.trap-full-map .leaflet-container { background: #e9eaec; font: inherit; }
[data-theme="dark"] .trap-full-map,
[data-theme="dark"] .trap-full-map .leaflet-container { background: #101216; }
.trap-full-map .trap-report-fabs { bottom: 30px; }
.trap-full-map .map-legend { top: 10px; }
.trap-alert {
  position: fixed;
  left: 50%;
  bottom: calc(var(--bottom-clearance) + 12px);
  z-index: 1250;
  width: min(430px, calc(100% - 28px));
  transform: translateX(-50%);
  display: grid;
  grid-template-columns: 1fr;
  gap: 10px;
  align-items: center;
  padding: 14px;
  border-radius: 22px;
  background: rgba(17,20,24,.94);
  color: #fff;
  box-shadow: 0 14px 36px rgba(0,0,0,.34);
  -webkit-backdrop-filter: blur(18px) saturate(150%);
  backdrop-filter: blur(18px) saturate(150%);
}
.trap-alert-main { min-width: 0; }
.trap-alert-title { font-size: 1.08rem; font-weight: 950; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.trap-alert-meta { margin-top: 4px; color: rgba(255,255,255,.74); font-size: .82rem; font-weight: 800; }
.trap-alert-actions {
  display: grid;
  grid-template-columns: 1.25fr 1fr;
  gap: 10px;
}
.trap-alert-btn {
  border: none;
  border-radius: 18px;
  min-height: 58px;
  padding: 12px 14px;
  color: #fff;
  font: inherit;
  font-size: 1.02rem;
  font-weight: 950;
  white-space: nowrap;
  cursor: pointer;
  touch-action: manipulation;
}
.trap-alert-true { background: var(--brand); }
.trap-alert-false { background: rgba(255,255,255,.16); }
.trap-alert-timer {
  position: absolute;
  left: 14px;
  right: 14px;
  bottom: 5px;
  height: 2px;
  border-radius: 999px;
  background: rgba(255,255,255,.18);
  overflow: hidden;
}
.trap-alert-timer::before {
  content: "";
  display: block;
  height: 100%;
  background: var(--brand);
  animation: trapAlertTimer 12s linear forwards;
}
@keyframes trapAlertTimer { from { width: 100%; } to { width: 0; } }
.trap-row { padding: 13px 14px; }
.trap-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.trap-title { min-width: 0; font-size: 1.08rem; font-weight: 850; color: var(--fg); white-space: nowrap; word-break: keep-all; overflow: hidden; text-overflow: ellipsis; }
.trap-loc { white-space: normal; word-break: break-word; overflow: visible; text-overflow: clip; }
.trap-dist { flex: none; color: var(--muted); font-size: .82rem; font-weight: 800; white-space: nowrap; }
.trap-meta { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 8px; }
.trap-conf, .trap-time {
  display: inline-flex; align-items: center; min-height: 28px; padding: 4px 9px;
  border-radius: 9px; font-size: .72rem; font-weight: 800; white-space: nowrap; word-break: keep-all;
}
.trap-time { background: var(--row-alt); color: var(--muted); }
.trap-conf-low { background: #e8f5e9; color: var(--green); }
.trap-conf-mid { background: #fff3e0; color: var(--orange); }
.trap-conf-high { background: #fdecea; color: var(--red); }
[data-theme="dark"] .trap-conf-low { background: #16301a; color: #66bb6a; }
[data-theme="dark"] .trap-conf-mid { background: #3a2a14; }
[data-theme="dark"] .trap-conf-high { background: #3a1d1a; }
.trap-mapbox { display: block; margin-top: 9px; height: 150px; border: 1px solid var(--line); border-radius: 12px; overflow: hidden; position: relative; z-index: 0; }
.trap-mapbox .leaflet-pane, .trap-mapbox .leaflet-top, .trap-mapbox .leaflet-control { z-index: 1 !important; }
.trap-mapbox .leaflet-container { background: #eaeaea; font: inherit; }
[data-theme="dark"] .trap-mapbox { filter: brightness(0.9); }
.trap-pin { font-size: 22px; line-height: 1; text-align: center; filter: drop-shadow(0 1px 1px rgba(0,0,0,.4)); }
.trap-map-pin {
  width: 24px; height: 24px; border-radius: 50%; background: var(--trap-col, var(--brand));
  color: #fff; display: flex; align-items: center; justify-content: center; font-size: 14px;
  border: 2px solid #fff; box-shadow: 0 2px 8px rgba(0,0,0,.28);
}
/* Police (警察) report uses the HK police-van image instead of an emoji glyph. */
.trap-ico-img { height: 1.15em; width: auto; vertical-align: -0.22em; }
.trap-pin img.trap-ico-img { height: auto; }
/* On the white FAB the van sits on its natural white bg — just a soft shadow, no outline. */
/* Van (transparent padding trimmed) fills the police button width. */
.trap-report-fab .trf-van { width: 66px; height: auto; object-fit: contain; filter: drop-shadow(0 1px 2px rgba(0,0,0,.25)); }
/* On the MAP, contain the van in a clean circular badge (like the camera pin) so it
   reads as a marker, scales with the map, and matches the other pins instead of a
   big floating image. */
/* Rounded-rect badge sized to the van's landscape shape (a circle clips it). */
.trap-map-pin-police {
  width: auto; height: auto; padding: 2px 4px; border-radius: 9px;
  background: #fff; border: 1.5px solid #1668e3;
  box-shadow: 0 2px 7px rgba(0,0,0,.42);
  display: inline-flex; align-items: center; justify-content: center; overflow: visible;
}
.trap-map-pin-police img.trap-ico-img {
  display: block; width: 28px; height: auto; vertical-align: middle; filter: none;
}
.trap-empty { list-style: none; margin: 18px 12px; padding: 34px 24px; border: 1px solid var(--line); border-radius: 18px; background: var(--card); color: var(--muted); text-align: center; font-weight: 800; line-height: 1.45; }

/* ---- dark theme (opt-in; light is default) ---- */
[data-theme="dark"] {
  --bg: #0c0d10; --fg: #f0f0f0; --line: #3b404a; --row-alt: #1c1c1c; --muted: #bec4ce; --card: #15171c;
}
[data-theme="dark"] .seg-btn { background: #1c1c1c; }
[data-theme="dark"] .tabbar,
[data-theme="dark"] .modal,
[data-theme="dark"] .stat,
[data-theme="dark"] .nav-choice { background: #1c1c1c; }
[data-theme="dark"] .src-badge { background: #1a2a44; }
[data-theme="dark"] .tg { background: #2a2a2a; color: #bbb; }
[data-theme="dark"] .cctv-failed::after { background: #222; }
[data-theme="dark"] .tn-up { background: #3a1d1a; }
[data-theme="dark"] .tn-down { background: #16301a; }
[data-theme="dark"] .tn-flatt { background: #2a2a2a; }

/* always reserve room for the fixed notification bell so the demand-strip content never sits under it */
#demandStrip { padding-right: 62px !important; }

/* current-location row highlight (您在此) */
.surge-tr.is-here { background: rgba(255,87,34,.10); box-shadow: inset 3px 0 0 var(--brand); }
[data-theme="dark"] .surge-tr.is-here { background: rgba(255,87,34,.18); }
.here-tag { display: inline-block; margin-left: 6px; font-size: .58rem; font-weight: 800; color: #fff; background: var(--brand); border-radius: 6px; padding: 1px 6px; vertical-align: middle; letter-spacing: .02em; }

.nc-icon { width: 26px; height: 26px; object-fit: contain; flex: 0 0 auto; }

/* Surge header: topbar (white, holds the bell) on top, demand strip below — one fixed
   unit so the notification bell always sits on white, never on the coloured strip. */
.surge-header { background: var(--card); }
.surge-header .topbar { position: static; padding-top: calc(13px + env(safe-area-inset-top)); padding-right: 14px; }
.surge-header .demand-strip { position: static; top: auto; z-index: auto; }
#demandStrip { padding-right: 14px !important; }
.surge-table:not(.is-locked) .surge-th {
  position: sticky !important;
  top: 0 !important;
  z-index: 930;
}
