/* Map shell sizing — fills viewport below header on desktop, fixed-ish on
   mobile. min-height keeps the box from collapsing when the parent uses
   `flex-direction: column` (mobile), where `flex-1` would otherwise treat
   `flex-basis: 0%` as the resolved height. */
.map-shell {
  height: clamp(520px, calc(100vh - 180px), 1000px);
  min-height: clamp(520px, calc(100vh - 180px), 1000px);
}

/* Fullscreen — the JS lifts .map-shell out of the page and reparents it
   to <body>, so a plain `position: fixed` covers the viewport with no
   risk of an ancestor's transform/filter trapping it inside the page
   layout. The placeholder left behind keeps the surrounding cards from
   collapsing while the shell is away. */
.map-shell--fullscreen {
  /* !important is necessary because Tailwind's `relative` utility class
     (applied inline on the .map-shell element) is loaded after this file
     in the cascade and would otherwise win. */
  position: fixed !important;
  inset: 0 !important;
  top: 0 !important;
  left: 0 !important;
  z-index: 9999;
  width: 100vw !important;
  height: 100dvh !important;
  min-height: 100dvh !important;
  max-height: 100dvh !important;
  border-radius: 0 !important;
  border: 0 !important;
  margin: 0 !important;
  background: #09090b;
}
.map-shell-placeholder {
  height: clamp(520px, calc(100vh - 180px), 1000px);
  min-height: clamp(520px, calc(100vh - 180px), 1000px);
  flex: 1;
}
@media (max-width: 640px) {
  .map-shell-placeholder {
    height: clamp(644px, 95svh, 946px);
    min-height: clamp(644px, 95svh, 946px);
  }
}
/* Lock the underlying page so it can't scroll behind the fullscreen map.
   `overscroll-behavior: contain` stops iOS rubber-band from pulling the
   page underneath into view. */
body.map-is-fullscreen {
  overflow: hidden;
  overscroll-behavior: contain;
}
/* Mobile: map takes ~80% of the small viewport so it's the primary surface;
   content below is reachable with a short scroll. svh handles iOS dynamic
   toolbars correctly. */
@media (max-width: 640px) {
  .map-shell {
    height: clamp(644px, 95svh, 946px);
    min-height: clamp(644px, 95svh, 946px);
  }
}
/* Leaflet's container is `w-full h-full`, but percentage height won't
   resolve reliably against a flex-1 parent whose effective height comes from
   min-height/clamp. Pin it to the parent's box with absolute positioning so
   the map always fills the shell at every viewport size. */
.map-shell > #leaflet-map {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

/* Zones-in-view rail — mobile stacking */
.zones-rail--collapsed .zones-content {
  display: none;
}

/* Desktop: rail is absolutely positioned at the right edge of the map row.
   It always sits at the right of the row; the MAP SHELL's margin-right
   adjusts to make room. So expanding the rail shrinks the map (and
   collapsing it grows the map back). Both transitions share the same
   320ms timing so they move in lockstep. */
@media (min-width: 1024px) {
  .map-row {
    overflow: visible;
  }
  .map-row > .map-shell {
    /* Default: rail is expanded → reserve 280px + 12px gap. */
    margin-right: calc(280px + 0.75rem);
    transition: margin-right 320ms cubic-bezier(0.4, 0, 0.2, 1);
  }
  /* When the rail is collapsed, the map reclaims the space. Uses :has()
     so the parent reacts to the rail's class without any JS coupling. */
  .map-row:has(.zones-rail.zones-rail--collapsed) > .map-shell {
    margin-right: calc(44px + 0.75rem);
  }
  .zones-rail {
    position: absolute;
    top: 0;
    right: 0;
    width: 280px;
    height: clamp(520px, calc(100vh - 180px), 1000px);
    transition: width 320ms cubic-bezier(0.4, 0, 0.2, 1),
                padding 320ms cubic-bezier(0.4, 0, 0.2, 1);
    will-change: width;
    overflow: hidden;
    z-index: 410;
  }
  .zones-rail.zones-rail--collapsed {
    width: 44px;
    padding: 8px 4px;
  }

  /* Toggle button fills full height with chevron centered when collapsed. */
  .zones-rail--collapsed > #zones-toggle {
    flex: 1;
    width: 100%;
    justify-content: center;
    align-items: center;
  }
  .zones-rail--collapsed > #zones-toggle > div {
    display: none;
  }
}
.zones-chevron {
  transition: transform 200ms ease;
  color: rgba(255, 255, 255, 0.55);
}
/* Side-panel semantics: rail expands to the right.
   Collapsed → "▷" points right (direction of expansion),
   expanded → "◁" points left (direction of collapse). */
.zones-rail--collapsed .zones-chevron {
  transform: rotate(-90deg);
}
.zones-rail:not(.zones-rail--collapsed) .zones-chevron {
  transform: rotate(90deg);
}
/* On mobile the rail stacks below the map, so up/down chevrons read better. */
@media (max-width: 1023px) {
  .zones-rail--collapsed .zones-chevron {
    transform: none;
  }
  .zones-rail:not(.zones-rail--collapsed) .zones-chevron {
    transform: rotate(180deg);
  }
}
#zones-toggle:hover .zones-chevron {
  color: rgba(255, 255, 255, 0.95);
}

/* Leaflet base overrides for dark theme */
.leaflet-container {
  background: #0a0a0a;
  font-family: 'Geist', ui-sans-serif, system-ui, sans-serif;
  outline: none;
}

.leaflet-control-attribution {
  background: rgba(0, 0, 0, 0.7) !important;
  color: rgba(255, 255, 255, 0.4) !important;
  border-radius: 6px;
  font-size: 10px !important;
  padding: 2px 6px !important;
  backdrop-filter: blur(6px);
}
.leaflet-control-attribution a {
  color: rgba(255, 255, 255, 0.55) !important;
  text-decoration: none;
}
.leaflet-control-attribution a:hover {
  color: rgba(255, 255, 255, 0.8) !important;
}

/* Zoom buttons - dark themed */
.leaflet-bar {
  border: 1px solid rgba(255, 255, 255, 0.08) !important;
  border-radius: 12px !important;
  overflow: hidden;
  background: rgba(0, 0, 0, 0.8);
  backdrop-filter: blur(8px);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05) !important;
}
.leaflet-bar a,
.leaflet-bar a:hover {
  background: transparent !important;
  color: rgba(255, 255, 255, 0.7) !important;
  border: none !important;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06) !important;
  width: 32px !important;
  height: 32px !important;
  line-height: 32px !important;
  font-size: 16px !important;
  font-weight: 500;
  transition: background 150ms, color 150ms;
}
.leaflet-bar a:last-child {
  border-bottom: none !important;
}
.leaflet-bar a:hover {
  background: rgba(255, 255, 255, 0.05) !important;
  color: #fff !important;
}
.leaflet-bar a.leaflet-disabled {
  color: rgba(255, 255, 255, 0.2) !important;
}

.leaflet-top.leaflet-left {
  margin-top: 160px;
  margin-left: 12px;
}
@media (min-width: 640px) {
  .leaflet-top.leaflet-left {
    margin-top: 160px;
    margin-left: 16px;
  }
}

/* Custom zone markers — divIcon-based pulse */
.zone-marker {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  pointer-events: auto;
}
.zone-marker__dot {
  position: relative;
  width: 12px;
  height: 12px;
  border-radius: 9999px;
  box-shadow:
    0 0 0 2px rgba(0, 0, 0, 0.6),
    0 0 0 4px rgba(255, 255, 255, 0.06),
    0 4px 10px rgba(0, 0, 0, 0.5);
}
.zone-marker__dot--active {
  background: #34d399;
  box-shadow:
    0 0 0 2px rgba(0, 0, 0, 0.6),
    0 0 0 4px rgba(52, 211, 153, 0.18),
    0 4px 10px rgba(16, 185, 129, 0.5);
}
.zone-marker__dot--active::after {
  content: '';
  position: absolute;
  inset: -2px;
  border-radius: 9999px;
  background: rgba(52, 211, 153, 0.35);
  animation: zone-ping 1.8s cubic-bezier(0, 0, 0.2, 1) infinite;
  z-index: -1;
}
.zone-marker__dot--inactive {
  background: #71717a;
  box-shadow:
    0 0 0 2px rgba(0, 0, 0, 0.6),
    0 0 0 4px rgba(113, 113, 122, 0.18),
    0 4px 10px rgba(0, 0, 0, 0.5);
}
.zone-marker__dot--premium {
  background: #fbbf24;
  box-shadow:
    0 0 0 2px rgba(0, 0, 0, 0.6),
    0 0 0 4px rgba(251, 191, 36, 0.20),
    0 4px 10px rgba(245, 158, 11, 0.5);
}
.zone-marker__dot--premium::after {
  content: '';
  position: absolute;
  inset: -2px;
  border-radius: 9999px;
  background: rgba(251, 191, 36, 0.35);
  animation: zone-ping 1.8s cubic-bezier(0, 0, 0.2, 1) infinite;
  z-index: -1;
}
.zone-marker--selected .zone-marker__dot {
  width: 16px;
  height: 16px;
  box-shadow:
    0 0 0 3px rgba(0, 0, 0, 0.7),
    0 0 0 6px rgba(255, 255, 255, 0.25),
    0 6px 14px rgba(0, 0, 0, 0.6);
}

@keyframes zone-ping {
  0%   { transform: scale(1);   opacity: 0.7; }
  80%  { transform: scale(2.2); opacity: 0;   }
  100% { transform: scale(2.2); opacity: 0;   }
}

/* Leaflet popup — dark themed */
.leaflet-popup-content-wrapper {
  background: rgba(9, 9, 11, 0.95) !important;
  color: #e5e5e5 !important;
  border: 1px solid rgba(255, 255, 255, 0.08) !important;
  border-radius: 16px !important;
  box-shadow:
    0 20px 50px rgba(0, 0, 0, 0.6),
    inset 0 1px 0 rgba(255, 255, 255, 0.06) !important;
  padding: 0 !important;
  backdrop-filter: blur(10px);
}
.leaflet-popup-content {
  margin: 0 !important;
  padding: 14px 16px 12px !important;
  font-family: 'Geist', sans-serif !important;
  line-height: 1.4 !important;
  width: 240px !important;
}
.leaflet-popup-tip {
  background: rgba(9, 9, 11, 0.95) !important;
  border: 1px solid rgba(255, 255, 255, 0.08);
  box-shadow: none !important;
}
.leaflet-popup-close-button {
  position: absolute !important;
  top: 10px !important;
  right: 10px !important;
  width: 22px !important;
  height: 22px !important;
  padding: 0 !important;
  border-radius: 6px !important;
  display: flex !important;
  align-items: center;
  justify-content: center;
  color: rgba(255, 255, 255, 0.45) !important;
  font-size: 16px !important;
  font-weight: 400 !important;
  line-height: 1 !important;
  text-decoration: none !important;
  background: transparent !important;
  transition: color 150ms, background 150ms;
}
.leaflet-popup-close-button:hover {
  color: #fff !important;
  background: rgba(255, 255, 255, 0.08) !important;
}
/* Reserve room on the right of the header so the code/label never slides
   under the absolute-positioned close button. */
.zone-popup__label,
.zone-popup__code {
  padding-right: 28px;
}

/* Popup content styling */
.zone-popup__label {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: rgba(255, 255, 255, 0.4);
  font-weight: 600;
  margin-bottom: 4px;
}
.zone-popup__code {
  font-family: 'Geist Mono', ui-monospace, monospace;
  font-size: 32px;
  font-weight: 700;
  color: #fff;
  letter-spacing: -0.02em;
  line-height: 1;
}
.zone-popup__neighborhood {
  font-size: 12px;
  color: rgba(255, 255, 255, 0.6);
  margin-top: 6px;
  margin-bottom: 10px;
}
.zone-popup__row {
  display: grid;
  grid-template-columns: 84px 1fr;
  align-items: center;
  gap: 12px;
  padding: 6px 0;
  border-top: 1px solid rgba(255, 255, 255, 0.06);
  font-size: 12px;
}
.zone-popup__row-label {
  color: rgba(255, 255, 255, 0.5);
}
.zone-popup__row-value {
  font-family: 'Geist Mono', monospace;
  color: #fff;
  font-weight: 600;
  text-align: left;
  justify-self: start;
}
.zone-popup__row-value--accent {
  color: #6ee7b7;
}
.zone-popup__row-value--muted {
  color: rgba(255, 255, 255, 0.5);
  font-weight: 500;
}
/* Warning toggle: the icon button lives inside .zone-popup__cta-row alongside
   Pay/Nav so all three buttons share the same height and visual weight. The
   body is a sibling outside the row; tapping the button toggles a class on
   the popup to show/hide it. */
.zone-popup__warning-btn {
  /* All-buttons base — also applied to .zone-popup__cta and .zone-popup__nav below. */
  display: flex;
  align-items: center;
  justify-content: center;
  height: 36px;
  width: 36px;
  padding: 0;
  border-radius: 10px;
  background: rgba(251, 191, 36, 0.10);
  border: 1px solid rgba(251, 191, 36, 0.30);
  color: #fcd34d;
  cursor: pointer;
  transition: background 150ms, border-color 150ms;
}
.zone-popup__warning-btn:hover {
  background: rgba(251, 191, 36, 0.18);
  border-color: rgba(251, 191, 36, 0.45);
}
.zone-popup__warning-btn svg {
  width: 14px;
  height: 14px;
}
.zone-popup__warning-btn--danger {
  background: rgba(239, 68, 68, 0.14);
  border-color: rgba(239, 68, 68, 0.40);
  color: #fecaca;
}
.zone-popup__warning-btn--danger:hover {
  background: rgba(239, 68, 68, 0.22);
  border-color: rgba(239, 68, 68, 0.55);
}
.zone-popup__warning-body {
  display: none;
  margin-top: 8px;
  padding: 8px 10px;
  border-radius: 8px;
  background: rgba(251, 191, 36, 0.08);
  border: 1px solid rgba(251, 191, 36, 0.25);
  color: #fcd34d;
  font-size: 11px;
  line-height: 1.4;
}
.zone-popup__warning-body--danger {
  background: rgba(239, 68, 68, 0.12);
  border-color: rgba(239, 68, 68, 0.35);
  color: #fecaca;
}
.zone-popup.show-warning .zone-popup__warning-body {
  display: block;
}

/* Mobile: tighten the popup so it doesn't dominate the smaller viewport. */
@media (max-width: 640px) {
  .leaflet-popup-content {
    padding: 11px 13px 10px !important;
    width: 210px !important;
  }
  .leaflet-popup-close-button {
    top: 8px !important;
    right: 8px !important;
    width: 20px !important;
    height: 20px !important;
    font-size: 14px !important;
  }
  .zone-popup__label,
  .zone-popup__code {
    padding-right: 24px;
  }
  .zone-popup__label {
    margin-bottom: 3px;
  }
  .zone-popup__code {
    font-size: 26px;
  }
  .zone-popup__neighborhood {
    font-size: 11px;
    margin-top: 4px;
    margin-bottom: 8px;
  }
  .zone-popup__row {
    grid-template-columns: 72px 1fr;
    gap: 10px;
    padding: 4px 0;
    font-size: 11px;
  }
  .zone-popup__warning-btn {
    width: 30px;
    height: 30px;
    border-radius: 8px;
  }
  .zone-popup__warning-btn svg {
    width: 12px;
    height: 12px;
  }
  .zone-popup__warning-body {
    margin-top: 6px;
    padding: 6px 8px;
    font-size: 10px;
  }
  .zone-popup__warning-list {
    font-size: 10px;
  }
  /* Rates-by-time table is hidden on mobile to keep the popup compact.
     Users still see the current rate in the "Right now" row above. */
  .zone-popup__rates {
    display: none;
  }
  /* Match button heights at 30px so warning/pay/nav line up cleanly. */
  .zone-popup__cta-row {
    grid-template-columns: 1fr 30px;
    gap: 6px;
    margin-top: 8px;
  }
  .zone-popup__cta-row--with-warning {
    grid-template-columns: 30px 1fr 30px;
  }
  .zone-popup__cta {
    height: 30px;
    padding: 0 10px;
    font-size: 11px;
  }
  /* Hide the trailing external-link arrow on mobile so "Pay zone XXXX"
     has enough room to render on one line inside the narrower column. */
  .zone-popup__cta > svg {
    display: none;
  }
  .zone-popup__nav {
    width: 30px;
    height: 30px;
    border-radius: 8px;
  }
  .zone-popup__nav svg {
    width: 14px;
    height: 14px;
  }
  .zone-popup .vehicle-badge + .zone-popup__row {
    margin-top: 8px;
  }
}

/* Detail-card restriction banner */
.detail-warning {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin-top: 12px;
  padding: 10px 12px;
  border-radius: 10px;
  background: rgba(239, 68, 68, 0.10);
  border: 1px solid rgba(239, 68, 68, 0.30);
  color: #fecaca;
}
.detail-warning svg {
  flex-shrink: 0;
  margin-top: 1px;
  color: #fca5a5;
}
.detail-warning__title {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.01em;
  color: #fee2e2;
}
.detail-warning__sub {
  font-size: 11px;
  line-height: 1.4;
  margin-top: 2px;
  color: rgba(254, 202, 202, 0.85);
}
.detail-warning__list {
  margin: 4px 0 0;
  padding-left: 16px;
  font-size: 11px;
  line-height: 1.5;
  color: rgba(254, 202, 202, 0.85);
}
.detail-warning--info {
  background: rgba(251, 191, 36, 0.10);
  border-color: rgba(251, 191, 36, 0.30);
  color: #fde68a;
}
.detail-warning--info svg { color: #fcd34d; }
.detail-warning--info .detail-warning__title { color: #fef3c7; }
.detail-warning--info .detail-warning__list { color: rgba(253, 230, 138, 0.85); }

/* Popup amber list (same colour as parent .zone-popup__warning) */
.zone-popup__warning-list {
  margin: 4px 0 0;
  padding-left: 16px;
  font-size: 11px;
  line-height: 1.45;
}
/* CTA row: Pay zone (flex 1fr) + Nav button (square). When the zone has a
   restriction, a square warning button is added as the first column, giving
   a 3-button visual set that shares the same height. */
.zone-popup__cta-row {
  display: grid;
  grid-template-columns: 1fr 36px;
  gap: 6px;
  margin-top: 10px;
}
.zone-popup__cta-row--with-warning {
  grid-template-columns: 36px 1fr 36px;
}
.zone-popup__cta {
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  height: 36px;
  padding: 0 12px;
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.10);
  border-radius: 10px;
  color: #fff;
  font-size: 12px;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
  transition: background 150ms, border-color 150ms;
}
.zone-popup__cta:hover {
  background: rgba(255, 255, 255, 0.14);
  border-color: rgba(255, 255, 255, 0.18);
}
.zone-popup__nav {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.10);
  border-radius: 10px;
  color: #fff;
  text-decoration: none;
  transition: background 150ms, border-color 150ms;
}
.zone-popup__nav:hover {
  background: rgba(255, 255, 255, 0.14);
  border-color: rgba(255, 255, 255, 0.18);
}


/* Same ratio in the detail card under the map */
.detail-cta-row {
  display: grid;
  grid-template-columns: 1fr 0.3fr;
  gap: 8px;
  margin-top: 16px;
}
.detail-pay,
.detail-nav { min-width: 0; }

/* Vehicle-type badge — used in the popup header and detail card. Colour
   reads from `--vehicle-color` so the same CSS works for any type variant. */
.vehicle-badge {
  --vehicle-color: rgba(255, 255, 255, 0.7);
  display: inline-flex;
  align-items: center;
  gap: 6px;
  /* Default margins for the detail card (neighborhood above has no
     margin-bottom and the rate chip below uses mt-3 = 12 px). The popup
     overrides these because the popup's neighborhood already supplies its
     own margin-bottom. */
  margin: 12px 0 0;
  padding: 4px 8px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--vehicle-color) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--vehicle-color) 35%, transparent);
  color: var(--vehicle-color);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.01em;
}
.vehicle-badge svg { width: 13px; height: 13px; }
.vehicle-badge i  { font-size: 12px; line-height: 1; }
.vehicle-badge--motorcycle    { --vehicle-color: #c4b5fd; }
.vehicle-badge--accessibility { --vehicle-color: #93c5fd; }
.vehicle-badge--ev            { --vehicle-color: #67e8f9; }
.vehicle-badge--compact {
  /* Popup context: neighborhood above already supplies the top gap via its
     own margin-bottom, so reset the default margin-top. */
  margin: 0;
  padding: 3px 7px;
  font-size: 10px;
}
.vehicle-badge--compact svg { width: 11px; height: 11px; }
.vehicle-badge--compact i { font-size: 10px; }

/* Match the 10 px above the badge (nbhd margin-bottom: 10) with an equal
   gap below it so the badge is centred between neighborhood and the row. */
.zone-popup .vehicle-badge + .zone-popup__row {
  margin-top: 10px;
}

/* Filter toolbar (the card that holds "When" + "Show") */
.filter-toolbar {
  backdrop-filter: blur(6px);
}
.filter-group__label {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  color: rgba(255, 255, 255, 0.42);
  font-weight: 700;
  margin-bottom: 8px;
}
.filter-group__rows {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
@media (max-width: 640px) {
  .filter-group__label {
    font-size: 9px;
    letter-spacing: 0.16em;
    margin-bottom: 5px;
  }
  .filter-group__rows { gap: 6px; }
  .filter-divider { margin: 8px 0; }
}
.filter-group__hour-row {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}
.filter-group__hour-row[hidden] {
  display: none;
}
.filter-group__sublabel {
  font-size: 9px;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  color: rgba(255, 255, 255, 0.4);
  font-weight: 700;
  flex-shrink: 0;
}
.filter-group--show {
  flex: 0 0 auto;
}
/* Divider — thin horizontal line on mobile, vertical separator on desktop */
.filter-divider {
  margin: 12px 0;
  height: 1px;
  background: rgba(255, 255, 255, 0.06);
}
@media (min-width: 1024px) {
  .filter-divider {
    margin: 0;
    width: 1px;
    height: auto;
    align-self: stretch;
    background: rgba(255, 255, 255, 0.06);
  }
}

/* Drag-to-scroll containers — hour picker, day picker, vehicle filter.
   The cursor flips between grab/grabbing so users know it can be dragged.
   The right-edge fade hints at off-screen content. */
.drag-scroll {
  cursor: grab;
  user-select: none;
  touch-action: pan-x;
  -webkit-overflow-scrolling: touch;
  scroll-behavior: smooth;
}
.drag-scroll--active {
  cursor: grabbing;
  scroll-behavior: auto;
}
.drag-scroll > * {
  /* Prevent native HTML5 drag from interfering with the custom drag */
  -webkit-user-drag: none;
}

/* Vehicle-filter pill — toggleable; greyed/struck-through when off */
.vehicle-pill svg { width: 12px; height: 12px; }
.vehicle-pill i  { font-size: 11px; line-height: 1; }

/* Legend dots */
.legend-dot {
  width: 10px;
  height: 10px;
  border-radius: 9999px;
  display: inline-block;
  flex-shrink: 0;
}
.legend-dot--active {
  background: #34d399;
  box-shadow: 0 0 0 2px rgba(52, 211, 153, 0.18);
}
.legend-dot--inactive {
  background: #71717a;
  box-shadow: 0 0 0 2px rgba(113, 113, 122, 0.18);
}
.legend-dot--premium {
  background: #fbbf24;
  box-shadow: 0 0 0 2px rgba(251, 191, 36, 0.20);
}
.legend-dot--fav {
  background: #ec4899;
  box-shadow: 0 0 0 2px #ffffff inset, 0 0 0 2px rgba(236, 72, 153, 0.35);
}

/* Mobile-only collapsible legend. The chip stays small so the map shows
   through. Tapping reveals the full key. */
.legend-card__toggle {
  cursor: pointer;
  background: transparent;
  border: 0;
  color: inherit;
  width: 100%;
}
.legend-card__toggle .legend-card__chev {
  transition: transform 180ms ease;
}
.legend-card[data-legend-open="true"] .legend-card__chev {
  transform: rotate(180deg);
}
@media (max-width: 640px) {
  /* Collapsed: only the toggle is visible. */
  .legend-card:not([data-legend-open="true"]) .legend-card__body {
    display: none;
  }
  /* Expanded: drop the body padding back to compact mobile sizing. */
  .legend-card[data-legend-open="true"] .legend-card__body {
    padding: 6px 10px 10px;
    border-top: 1px solid rgba(255, 255, 255, 0.06);
  }
  .legend-card__toggle { padding: 6px 10px; }
}

/* =====================================================================
   Favorite-zone map markers — DOM/SVG pins layered on top of the canvas
   circles. Pink fill, white star, white ring, drop-shadow glow, and a
   gentle pulsing halo so saved zones are unmistakable on the map.
   ===================================================================== */
.fav-marker {
  /* Leaflet sets these inline (width/height/position) but the inner
     visuals are ours to lay out. */
  pointer-events: auto;
  background: transparent !important;
  border: 0 !important;
}
.fav-marker__pin {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 15px;
  height: 15px;
  margin: -7.5px 0 0 -7.5px;
  border-radius: 9999px;
  background: #ec4899;
  border: 0;
  box-shadow:
    0 0 0 2.5px #ffffff inset,
    0 0 0 3px rgba(236, 72, 153, 0.35),
    0 0 9px rgba(236, 72, 153, 0.55);
  z-index: 2;
  transition: transform 120ms ease;
}
.fav-marker:hover .fav-marker__pin {
  transform: scale(1.1);
}
.fav-marker--selected .fav-marker__pin {
  background: #db2777;
  transform: scale(1.12);
  box-shadow:
    0 0 0 2.5px #ffffff inset,
    0 0 0 5px rgba(236, 72, 153, 0.45),
    0 0 14px 4px rgba(236, 72, 153, 0.7),
    0 0 22px 6px rgba(236, 72, 153, 0.35);
}
.fav-marker__pin svg { display: none; }
/* Pulse removed for a quieter on-map presence. */
.fav-marker__pulse { display: none; }

/* Custom scroll for zone list */
.custom-scroll::-webkit-scrollbar {
  width: 6px;
}
.custom-scroll::-webkit-scrollbar-track {
  background: transparent;
}
.custom-scroll::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.08);
  border-radius: 9999px;
}
.custom-scroll::-webkit-scrollbar-thumb:hover {
  background: rgba(255, 255, 255, 0.16);
}

/* Rate table — used in popup and detail panel */
.rate-grid {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.rate-row {
  display: grid;
  grid-template-columns: 64px 1fr 1fr;
  gap: 6px;
  align-items: stretch;
}
.rate-row__label {
  display: flex;
  align-items: center;
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: rgba(255, 255, 255, 0.45);
  font-weight: 600;
}
.rate-cell {
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 8px;
  padding: 6px 8px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.rate-cell__time {
  font-size: 9px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: rgba(255, 255, 255, 0.40);
  font-weight: 600;
}
.rate-cell__price {
  font-family: 'Geist Mono', monospace;
  font-size: 13px;
  font-weight: 700;
  color: rgba(255, 255, 255, 0.92);
  letter-spacing: -0.01em;
}
.rate-cell--active {
  background: rgba(16, 185, 129, 0.10);
  border-color: rgba(16, 185, 129, 0.30);
  box-shadow: 0 0 0 1px rgba(16, 185, 129, 0.10) inset;
}
.rate-cell--active .rate-cell__time {
  color: rgba(110, 231, 183, 0.7);
}
.rate-cell--active .rate-cell__price {
  color: #6ee7b7;
}

.rate-grid--compact .rate-cell {
  padding: 4px 6px;
}
.rate-grid--compact .rate-cell__price {
  font-size: 12px;
}

/* Popup-specific rate section — the .zone-popup__row above already
   contributes its own padding-bottom and bottom border, so we don't need
   an additional margin/padding/border here. */
.zone-popup__rates {
  margin-top: 6px;
}
.zone-popup__rates-title {
  font-size: 9px;
  text-transform: uppercase;
  letter-spacing: 0.10em;
  color: rgba(255, 255, 255, 0.40);
  font-weight: 600;
  margin-bottom: 6px;
}

/* Neighborhood cluster bubbles (shown at low zoom) */
.cluster-bubble {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  border-radius: 9999px;
  background: rgba(9, 9, 11, 0.88);
  border: 2px solid rgba(255, 255, 255, 0.18);
  backdrop-filter: blur(8px);
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.55), inset 0 1px 0 rgba(255, 255, 255, 0.08);
  cursor: pointer;
  transition: transform 120ms, border-color 120ms;
  text-align: center;
  padding: 4px;
}
.cluster-bubble:hover {
  transform: scale(1.07);
  border-color: rgba(255, 255, 255, 0.35);
}
.cluster-bubble__count {
  font-family: 'Geist Mono', monospace;
  font-size: 15px;
  font-weight: 700;
  color: #fff;
  line-height: 1;
}
.cluster-bubble__name {
  font-size: 7px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: rgba(255, 255, 255, 0.45);
  font-weight: 600;
  margin-top: 2px;
  max-width: 56px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Zone code label chip (divIcon at high zoom) */
.zone-label {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 22px;
  border-radius: 6px;
  background: rgba(9, 9, 11, 0.85);
  border: 1.5px solid var(--zone-color, rgba(255,255,255,0.2));
  font-family: 'Geist Mono', monospace;
  font-size: 10px;
  font-weight: 700;
  color: #fff;
  letter-spacing: 0.02em;
  white-space: nowrap;
  cursor: pointer;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.5);
  transition: transform 120ms, border-color 120ms;
}
.zone-label:hover {
  transform: scale(1.08);
  border-color: #fff;
}

/* Zone chip in list */
.zone-chip {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.06);
  cursor: pointer;
  transition: background 150ms, border-color 150ms, transform 100ms;
  text-align: left;
  width: 100%;
}
.zone-chip:hover {
  background: rgba(255, 255, 255, 0.06);
  border-color: rgba(255, 255, 255, 0.12);
}
.zone-chip:active {
  transform: scale(0.985);
}
.zone-chip__dot {
  flex-shrink: 0;
  width: 6px;
  height: 6px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.25);
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.06);
}
.zone-chip[data-tier="active"] .zone-chip__dot {
  background: #34d399;
  box-shadow: 0 0 8px rgba(52, 211, 153, 0.45);
}
.zone-chip[data-tier="premium"] .zone-chip__dot {
  background: #fbbf24;
  box-shadow: 0 0 8px rgba(251, 191, 36, 0.45);
}
.zone-chip__main {
  display: flex;
  flex-direction: column;
  min-width: 0;
  flex: 1;
}
.zone-chip__sub {
  display: none;
  font-size: 10px;
  color: rgba(255, 255, 255, 0.40);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-top: 1px;
}
.zone-chip__code {
  font-family: 'Geist Mono', monospace;
  font-size: 13px;
  font-weight: 700;
  color: #fff;
  letter-spacing: -0.01em;
}
.zone-chip__rate {
  font-family: 'Geist Mono', monospace;
  font-size: 11px;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.55);
  margin-left: auto;
  flex-shrink: 0;
  text-align: right;
}
.zone-chip[data-tier="active"] .zone-chip__rate {
  color: #6ee7b7;
}
.zone-chip[data-tier="premium"] .zone-chip__rate {
  color: #fcd34d;
}
.zone-chip--selected {
  background: rgba(255, 255, 255, 0.08);
  border-color: rgba(255, 255, 255, 0.20);
}
.zone-chip--selected .zone-chip__code {
  color: #fff;
}

/* Special-vehicle chips — colour the dot, the rate label and the border so
   the rail picks up the same palette as the map markers + filter pills.
   The rate-tier rules above are overridden by these (later, same specificity)
   only for the chip's own dot + rate; backgrounds stay subtle. */
.zone-chip--motorcycle    { border-color: rgba(167, 139, 250, 0.30); }
.zone-chip--motorcycle .zone-chip__dot,
.zone-chip[data-vehicle="motorcycle"] .zone-chip__dot {
  background: #a78bfa;
  box-shadow: 0 0 8px rgba(167, 139, 250, 0.55);
}
.zone-chip--motorcycle .zone-chip__rate,
.zone-chip[data-vehicle="motorcycle"] .zone-chip__rate {
  color: #c4b5fd;
}

.zone-chip--accessibility { border-color: rgba(96, 165, 250, 0.30); }
.zone-chip--accessibility .zone-chip__dot,
.zone-chip[data-vehicle="accessibility"] .zone-chip__dot {
  background: #60a5fa;
  box-shadow: 0 0 8px rgba(96, 165, 250, 0.55);
}
.zone-chip--accessibility .zone-chip__rate,
.zone-chip[data-vehicle="accessibility"] .zone-chip__rate {
  color: #93c5fd;
}

.zone-chip--ev            { border-color: rgba(34, 211, 238, 0.30); }
.zone-chip--ev .zone-chip__dot,
.zone-chip[data-vehicle="ev"] .zone-chip__dot {
  background: #22d3ee;
  box-shadow: 0 0 8px rgba(34, 211, 238, 0.55);
}
.zone-chip--ev .zone-chip__rate,
.zone-chip[data-vehicle="ev"] .zone-chip__rate {
  color: #67e8f9;
}

/* Vertical-rail layout on desktop: list rows with sub-line */
@media (min-width: 1024px) {
  .zone-chip {
    padding: 8px 10px;
  }
  .zone-chip__sub {
    display: block;
  }
  .zone-chip__rate {
    font-size: 12px;
  }
}

/* Sticky header inside the scroll container */
.zones-rail #zone-list {
  scroll-padding-top: 4px;
}
