/* ======================================================================
   ParkPuls.MS · stylesheet
   ----------------------------------------------------------------------
   Two-pane app shell (top bar · Parkfinder rail · map / Statistik) for the
   live Parkleitsystem map of Münster. Bright, transit-poster aesthetic:
   blue-tinted paper background, white cards with soft drop shadows, cyan +
   coral accents. Shares the visual identity and design tokens with the
   sibling project BusPuls.MS.
   Fonts: IBM Plex Sans Condensed (display), DM Sans (UI), Space Grotesk (figures).
   Note: ~1,900 lines of unused inherited BusPuls component CSS were removed
   2026-06; this file now contains only rules the current markup uses.
   ====================================================================== */

:root {
  /* Type stack — --serif token is now condensed grotesque, not a serif.
     Name kept for backward-compat with existing var(--serif) references. */
  --serif: 'IBM Plex Sans Condensed', 'Inter', system-ui, -apple-system, "Segoe UI", sans-serif;
  --sans:  'DM Sans', system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
  /* Figures / metrics font. Name kept as --mono for back-compat; it is now a
     proportional display face (Space Grotesk) used with tabular figures. */
  --mono:  'Space Grotesk', 'DM Sans', system-ui, sans-serif;

  /* Paper / ink — soft blue-tinted off-white canvas */
  --paper:       #eef4fa;             /* light-blue tinted off-white */
  --paper-deep:  #dde8f2;             /* slightly deeper, used behind tiles */
  --surface:     #ffffff;
  --surface-2:   #f4f8fc;
  --ink:         #14202c;             /* deep blue-tinged primary text */
  --ink-2:       #3a4a5c;             /* secondary text */
  --muted:       #5e6c7d;             /* aligned with BusPuls/Home for WCAG AA (≥4.5:1 on paper & white) */
  --dim:         #b3c0cd;
  --hairline:    rgba(20, 40, 64, 0.10);
  --hairline-2:  rgba(20, 40, 64, 0.06);
  --hl:          rgba(20, 40, 64, 0.045);
  --hl-hover:    rgba(20, 40, 64, 0.07);

  /* Brand — Stadtwerke cyan, shared with the ParkPuls.MS / BusPuls.MS mark */
  --brand:       #00B4F0;
  --brand-2:     #0091C2;
  --brand-soft:  #e1f7fe;
  --brand-line:  rgba(0, 180, 240, 0.32);

  /* Accent — coral, used by the heart/pulse in the mark and by .MS in the wordmark */
  --accent:      #FF4757;
  --accent-soft: #ffe9eb;
  --accent-line: rgba(255, 71, 87, 0.32);

  /* Signal palette (legible on white) */
  --good:        #15803d;
  --good-soft:   #dcfce7;
  --warn:        #b45309;
  --warn-soft:   #fef0c7;
  --bad:         #c2410c;
  --bad-soft:    #fee4cf;
  --crit:        #b91c1c;
  --crit-soft:   #fee2e2;
  --info:        #1d4ed8;
  --info-soft:   #dbeafe;
  --leicht:      #ca8a04;          /* golden yellow — Leichte Verzögerungen */
  --leicht-soft: #fef9c3;
  --early:       #1d4ed8;

  --radius-s:  8px;
  --radius:    12px;
  --radius-l:  18px;

  --shadow-sm: 0 1px 2px rgba(20,40,64,0.06), 0 1px 1px rgba(20,40,64,0.04);
  --shadow-md: 0 4px 18px rgba(20,40,64,0.08), 0 2px 4px rgba(20,40,64,0.05);
  --shadow-lg: 0 12px 36px rgba(20,40,64,0.12), 0 4px 12px rgba(20,40,64,0.07);

  --topbar-h: 82px;
  --drawer-bottom: 82px;             /* updated in JS via ResizeObserver */
  --footer-h: 28px;                  /* single-line strip; bumped automatically when wrapped on narrow viewports */

  /* Chart.js grid lines (read from JS via getComputedStyle) */
  --chart-grid: rgba(20, 40, 64, 0.06);
}

html { color-scheme: light; }
html[data-theme="dark"] { color-scheme: dark; }

/* =====================================================================
   Dark theme — token overrides only; component rules stay untouched.
   Activated by html[data-theme="dark"], set pre-paint by an inline
   script in index.html (system preference + manual toggle, persisted).
   ===================================================================== */
html[data-theme="dark"] {
  --paper:       #0d141d;
  --paper-deep:  #0a1018;
  --surface:     #151f2b;
  --surface-2:   #1a2634;
  --ink:         #e9eff6;
  --ink-2:       #b9c6d4;
  --muted:       #8295a8;
  --dim:         #4a5d70;
  --hairline:    rgba(255, 255, 255, 0.10);
  --hairline-2:  rgba(255, 255, 255, 0.06);
  --hl:          rgba(255, 255, 255, 0.055);
  --hl-hover:    rgba(255, 255, 255, 0.09);

  --brand-soft:  rgba(0, 180, 240, 0.16);
  --brand-line:  rgba(0, 180, 240, 0.40);
  --accent-soft: rgba(255, 71, 87, 0.16);
  --accent-line: rgba(255, 71, 87, 0.40);

  /* Signal palette brightened for legibility on dark surfaces */
  --good:        #4ade80;
  --good-soft:   rgba(74, 222, 128, 0.14);
  --warn:        #fbbf24;
  --warn-soft:   rgba(251, 191, 36, 0.13);
  --bad:         #fb923c;
  --bad-soft:    rgba(251, 146, 60, 0.14);
  --crit:        #f87171;
  --crit-soft:   rgba(248, 113, 113, 0.14);
  --info:        #60a5fa;
  --info-soft:   rgba(96, 165, 250, 0.15);
  --leicht:      #facc15;
  --leicht-soft: rgba(250, 204, 21, 0.12);

  --chart-grid:  rgba(255, 255, 255, 0.06);

  --shadow-sm: 0 1px 2px rgba(0,0,0,0.35), 0 1px 1px rgba(0,0,0,0.25);
  --shadow-md: 0 4px 18px rgba(0,0,0,0.45), 0 2px 4px rgba(0,0,0,0.30);
  --shadow-lg: 0 12px 36px rgba(0,0,0,0.55), 0 4px 12px rgba(0,0,0,0.35);
}

/* Dark-mode follow-ups for spots whose light values don't invert cleanly */
html[data-theme="dark"] .gp-status { color: #0a1018; }          /* brightened signal bg needs dark text */
html[data-theme="dark"] .gp-status.gp-off { color: var(--ink); }
html[data-theme="dark"] #status-pill.tone-leicht { color: var(--leicht); }
html[data-theme="dark"] .garage-label { color: var(--ink); text-shadow: 0 1px 2px var(--paper), 0 0 2px var(--paper); }
html[data-theme="dark"] .garage-label.leaflet-tooltip { background: rgba(21, 31, 43, 0.92); color: var(--ink); }

* { box-sizing: border-box; }
html, body {
  margin: 0; height: 100%;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 14px;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
button { font-family: inherit; }
button, [role="button"] { -webkit-tap-highlight-color: transparent; }
:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; border-radius: 4px; }

a { color: var(--brand-2); text-decoration: none; }
a:hover { text-decoration: underline; }

/* Metric figures: Space Grotesk is proportional, so request tabular (fixed-width)
   numerals everywhere numbers are displayed, to keep columns and live-updating
   values from shifting. */
.pstat .ps-v, .gc-free .gc-n, .dt-num, .gp-free strong,
.pp-pill .pp-n, .dt-sub, .hchart-val {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

#map {
  position: absolute;
  inset: var(--drawer-bottom) 0 var(--footer-h) 0;
  background: var(--paper-deep);
  transition: inset .35s cubic-bezier(.2,.7,.2,1);
}

/* ===== Leaflet integration ===== */
.leaflet-container { font-family: var(--sans); background: var(--paper-deep); }
.leaflet-control-zoom a, .leaflet-control-layers-toggle {
  background: var(--surface) !important;
  color: var(--ink-2) !important;
  border: 1px solid var(--hairline) !important;
  box-shadow: var(--shadow-sm) !important;
}
.leaflet-control-zoom a { font-weight: 600; }
.leaflet-control-zoom a:hover { background: var(--brand-soft) !important; color: var(--brand-2) !important; }
.leaflet-control-layers {
  border-radius: var(--radius) !important;
  border: 1px solid var(--hairline) !important;
  box-shadow: var(--shadow-md) !important;
  background: var(--surface) !important;
  color: var(--ink) !important;
  padding: 6px 8px !important;
}
.leaflet-control-layers-expanded { padding: 10px 12px !important; }
.leaflet-control-attribution {
  background: color-mix(in srgb, var(--surface) 80%, transparent) !important;
  color: var(--ink-2) !important;
  font-size: 10.5px;
  border-radius: 6px 0 0 0;
  backdrop-filter: blur(6px);
}
.leaflet-control-attribution a { color: var(--brand-2) !important; }
.leaflet-top.leaflet-left {
  top: calc(var(--drawer-bottom) + 12px);
  left: 14px;
  transition: top .35s cubic-bezier(.2,.7,.2,1);
}
/* Lift Leaflet attribution snug above the site footer */
.leaflet-bottom.leaflet-right { right: 0 !important; }
.leaflet-bottom              { bottom: var(--footer-h) !important; }
.leaflet-bottom .leaflet-control { margin-bottom: 0 !important; }

/* ===== Topbar (header bar) ===== */
#topbar {
  position: fixed;
  z-index: 800;
  top: 0; left: 0; right: 0;
  height: var(--topbar-h);
  background: rgba(252, 254, 255, 0.92);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
          backdrop-filter: saturate(180%) blur(14px);
  border-bottom: 1px solid var(--hairline);
  display: flex; align-items: center;
  padding: 0 24px;
  gap: 28px;
}

#brand { display: flex; align-items: center; gap: 12px; flex: 0 0 auto; min-width: 0; }
#brand h1 {
  font-family: var(--serif);
  font-size: 23px;
  font-weight: 600;          /* Plex Condensed 600 ≈ visual weight of old DM Serif 400 */
  margin: 0;
  letter-spacing: 0.1px;
  color: var(--brand);       /* cyan, matches the wordmark in the locked lockup */
}

@keyframes pulse-good {
  0%   { box-shadow: 0 0 0 0   rgba(21,128,61,0.55); }
  60%  { box-shadow: 0 0 0 7px rgba(21,128,61,0); }
  100% { box-shadow: 0 0 0 0   rgba(21,128,61,0); }
}

/* Trend arrow — coloured badge centred vertically on the right edge.
   Hidden when stable; green pill = improving, red pill = worsening. */
.kpi-trend {
  position: absolute;
  right: 9px;
  top: 50%;
  transform: translateY(-50%);
  display: flex; align-items: center; justify-content: center;
  width: 20px; height: 20px;
  border-radius: 5px;
  opacity: 0;
  transition: opacity .35s;
  pointer-events: none;
}
.kpi-trend.trend-good,
.kpi-trend.trend-bad  { opacity: 1; }
.kpi-trend.trend-good { color: var(--good); background: var(--good-soft); }
.kpi-trend.trend-bad  { color: var(--crit); background: var(--crit-soft); }
.kpi-trend svg { width: 12px; height: 12px; display: block; }






/* Merged status pill: dot + system-health label + hover-revealed timestamp.
   The pill takes a tone class (.tone-good / warn / bad / info) that paints
   both the dot and the soft background. Network-state classes (.err on dot
   for fetch failure, .load on dot during the very first poll) override
   the dot color but keep the pill quietly neutral. */
#status-pill {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 6px 14px 6px 11px;
  border-radius: 999px;
  border: 1px solid var(--hairline);
  background: var(--surface);
  font-family: var(--sans);
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-2);
  cursor: default;
  box-shadow: var(--shadow-sm);
  transition: background .25s, border-color .25s, color .25s;
  /* div replaces former button – suppress default outline in favour of
     the :focus-visible rule below, which already shows a brand outline */
  outline: none;
}
#status-pill:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; border-radius: 999px; }
#status-pill.tone-good { background: var(--good-soft); border-color: rgba(21,128,61,0.25);  color: var(--good); }
#status-pill.tone-warn { background: var(--warn-soft); border-color: rgba(180,83,9,0.25);   color: var(--warn); }
#status-pill.tone-bad  { background: var(--crit-soft); border-color: rgba(185,28,28,0.25);  color: var(--crit); }
#status-pill.tone-info  { background: var(--info-soft);   border-color: rgba(29,78,216,0.25);  color: var(--info); }
#status-pill.tone-leicht{ background: var(--leicht-soft); border-color: rgba(202,138,4,0.25); color: var(--leicht); }
#status-pill.tone-off  { background: var(--surface-2); border-color: var(--hairline);       color: var(--muted); }

#status-pill .dot {
  width: 9px; height: 9px; border-radius: 50%;
  background: var(--good);
  box-shadow: 0 0 0 0 rgba(21,128,61,0.45);
  animation: pulse-good 2s infinite;
}
#status-pill.tone-warn .dot { background: var(--warn); animation: pulse-warn 2.4s ease-out infinite; }
#status-pill.tone-bad  .dot { background: var(--crit); animation: none; }
#status-pill.tone-info   .dot { background: var(--info); }
#status-pill.tone-leicht .dot { background: var(--leicht); }
#status-pill.tone-off  .dot { background: var(--muted); animation: none; box-shadow: none; }
#status-pill .dot.err  { background: var(--crit); animation: none; }
#status-pill .dot.load { background: var(--warn); animation: pulse-warn 1.2s infinite; }
@keyframes pulse-warn {
  0%   { box-shadow: 0 0 0 0   rgba(180,83,9,0.45); }
  70%  { box-shadow: 0 0 0 7px rgba(180,83,9,0); }
  100% { box-shadow: 0 0 0 0   rgba(180,83,9,0); }
}

/* Status pill: inline expansion reveals the last-update timestamp on hover/
   focus (no JS layout math, pure CSS max-width transition). The reasons for
   the current verdict live in the separate #reasonsCard below the chrome. */
#status-pill .last-update-wrap {
  display: inline-flex; align-items: center; gap: 6px;
  max-width: 0;
  opacity: 0;
  overflow: hidden;
  white-space: nowrap;
  transition: max-width .25s ease, opacity .2s ease;
  font-weight: 500;
  color: currentColor;
}
#status-pill .last-update-wrap .sep { opacity: 0.5; }
#status-pill:hover .last-update-wrap,
#status-pill:focus-within .last-update-wrap { max-width: 240px; opacity: 0.85; margin-left: 2px; }

/* Floating reasons card – snug against the chrome's bottom edge at the
   top-right corner. The Leaflet zoom moved to top-left so this can have
   the corner. Visible only when the verdict is non-Reibungsloser Betrieb (and
   only when the user hasn't dismissed it for the current verdict). */
#reasonsCard {
  position: fixed;
  z-index: 700;
  top: calc(var(--drawer-bottom) + 8px);
  right: 14px;
  width: 280px;
  max-width: calc(100vw - 28px);
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-left: 3px solid var(--muted);
  border-radius: var(--radius);
  box-shadow: var(--shadow-md);
  padding: 11px 14px 13px 13px;
  transition: top .35s cubic-bezier(.2,.7,.2,1), border-color .25s ease;
  font-family: var(--sans);
}
#reasonsCard[hidden] { display: none; }
#reasonsCard.tone-info   { border-left-color: var(--info); }
#reasonsCard.tone-leicht { border-left-color: var(--leicht); }
#reasonsCard.tone-warn { border-left-color: var(--warn); }
#reasonsCard.tone-bad  { border-left-color: var(--crit); }
#reasonsCard.tone-off  { border-left-color: var(--muted); }
.reasons-card-title {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 8px 0;
  padding-right: 22px;       /* clear the X button */
}
.reasons-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.reasons-list li {
  padding-left: 14px;
  position: relative;
  font-size: 12.5px;
  line-height: 1.4;
  color: var(--ink);
}
.reasons-list li::before {
  content: "•";
  position: absolute;
  left: 2px;
  top: 0;
  color: var(--muted);
}
#reasonsClose {
  position: absolute;
  top: 7px;
  right: 7px;
  width: 22px;
  height: 22px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 0;
  border-radius: 6px;
  color: var(--muted);
  cursor: pointer;
  padding: 0;
  transition: background .12s ease, color .12s ease;
}
#reasonsClose:hover, #reasonsClose:focus-visible {
  background: var(--hl);
  color: var(--ink);
  outline: none;
}
#reasonsClose svg { width: 12px; height: 12px; }

@media (max-width: 560px){
  #reasonsCard {
    width: auto;
    left: 14px;
    right: 14px;
    top: calc(var(--drawer-bottom) + 8px);
  }
}



@media (max-width: 700px){
  #drawerTabs { grid-column: 1 / -1; justify-self: start; }
}



/* ---- Statistics drawer tabs --------------------------------------------- */
.drawer-tabs {
  display: flex;
  gap: 6px;
  justify-self: center;
}
.dtab {
  padding: 5px 15px;
  border-radius: 20px;
  border: 1.5px solid var(--brand);
  background: transparent;
  color: var(--brand);
  font: 600 12px/1.2 var(--sans);
  cursor: pointer;
  transition: background .15s, color .15s;
  white-space: nowrap;
}
.dtab.is-active {
  background: var(--brand);
  color: #fff;
}
.dtab:hover:not(.is-active) { background: var(--brand-soft); }
.dtab:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }

/* ---- Drawer panes -------------------------------------------------------- */
.drawer-pane         { display: none; }
.drawer-pane.is-active { display: block; }

/* ---- History chart grid -------------------------------------------------- */
.hist-charts {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 14px;
  align-items: stretch;
}
.hchart-card {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  padding: 14px 16px 12px;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.hchart-card h3 {
  font-family: var(--sans);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  margin: 0;
  color: var(--muted);
  display: flex;
  align-items: center;
  gap: 8px;
}
.hchart-card h3 .hc-dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
}
.hchart-wrap {
  position: relative;
  height: 150px;
  flex-shrink: 0;
}
.hchart-foot {
  display: flex;
  align-items: baseline;
  gap: 3px;
}
.hchart-val {
  font: 700 22px/1 var(--sans);
  color: var(--ink);
}
.hchart-suffix {
  font: 500 13px/1 var(--sans);
  color: var(--muted);
  margin-left: 3px;
}
.hchart-since {
  grid-column: 1 / -1;
  font: 400 11px var(--sans);
  color: var(--muted);
  font-style: italic;
  text-align: center;
  padding-top: 2px;
}@media (max-width: 900px){
  .hist-charts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}@media (max-width: 540px){
  .hist-charts { grid-template-columns: 1fr; }
}


















.segmented {
  display: flex;
  background: var(--paper-deep);
  border: 1px solid var(--hairline);
  border-radius: 10px;
  padding: 3px;
  gap: 2px;
}
.segmented label {
  flex: 1;
  text-align: center;
  padding: 7px 3px;
  border-radius: 7px;
  font-size: 11.5px;
  font-weight: 600;
  color: var(--ink-2);
  cursor: pointer;
  transition: background .15s ease, color .15s ease;
  user-select: none;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}
.segmented input { display: none; }
.segmented label:hover { color: var(--brand-2); }
.segmented label.active {
  background: var(--surface);
  color: var(--brand-2);
  box-shadow: 0 1px 2px rgba(0,0,0,0.06), inset 0 0 0 1px var(--brand-line);
}

.btn {
  flex: 1;
  padding: 7px 10px;
  background: var(--paper-deep);
  border: 1px solid var(--hairline);
  border-radius: 8px;
  color: var(--ink-2);
  cursor: pointer;
  font-size: 12px;
  font-weight: 600;
  transition: all .15s ease;
}
.btn:hover {
  border-color: var(--brand-line);
  color: var(--brand-2);
  background: var(--brand-soft);
}




/* Legend rows now live inside the controls panel's Legende section */
#legend-body-inner {
  display: flex; flex-direction: column; gap: 6px;
}
.legend-row {
  display: flex; align-items: center; gap: 8px;
  font-size: 11.5px;
  color: var(--ink-2);
}
.legend-row .sw {
  display: inline-block; width: 10px; height: 10px; border-radius: 3px;
  flex-shrink: 0;
}



.leaflet-marker-icon { background: transparent; border: none; }







/* Popups */
.leaflet-popup-content-wrapper {
  border-radius: var(--radius) !important;
  box-shadow: var(--shadow-lg) !important;
  background: var(--surface) !important;
  color: var(--ink) !important;
  border: 1px solid var(--hairline) !important;
}
.leaflet-popup-tip { background: var(--surface) !important; box-shadow: 0 2px 4px rgba(0,0,0,0.08) !important; }
.leaflet-popup-content { margin: 14px 16px !important; line-height: 1.4; font-family: var(--sans); }
.leaflet-popup-close-button {
  color: var(--muted) !important;
  font-size: 18px !important;
  padding: 6px 8px 0 0 !important;
}


@keyframes bdb-pulse {
  0%, 100% { background: var(--paper); }
  50%       { background: var(--crit-soft); }
}





@keyframes dep-pulse-orange {
  0%, 100% { box-shadow: 0 0 0 0   rgba(245, 158, 11, 0.35); }
  50%      { box-shadow: 0 0 0 4px rgba(245, 158, 11, 0); }
}
@keyframes dep-pulse-red {
  0%, 100% { box-shadow: 0 0 0 0   rgba(220, 38, 38, 0.40); }
  50%      { box-shadow: 0 0 0 5px rgba(220, 38, 38, 0); }
}

@keyframes dep-board-switch {
  0%, 100% { background: rgba(22, 163, 74, 1); }   /* filled  */
  50%      { background: rgba(22, 163, 74, 0); }   /* hollow  */
}


/* ===== Loading veil (first paint) ===== */
#loading-veil {
  position: fixed;
  inset: 0;
  z-index: 2000;
  display: flex; align-items: center; justify-content: center;
  background: var(--paper);
  transition: opacity .4s ease;
}
#loading-veil .veil-inner {
  display: flex; flex-direction: column; align-items: center; gap: 14px;
  text-align: center;
}
#loading-veil h2 {
  font-family: var(--serif);
  font-weight: 600;
  font-size: 28px;
  letter-spacing: 0.2px;
  color: var(--ink);
  margin: 0;
}
#loading-veil p {
  font-size: 12px;
  color: var(--muted);
  letter-spacing: 0.6px;
  text-transform: uppercase;
  margin: 0;
}
#loading-veil .veil-bar {
  width: 200px; height: 3px;
  background: var(--paper-deep);
  border-radius: 999px;
  overflow: hidden;
  position: relative;
}
#loading-veil .veil-bar::before {
  content: ""; position: absolute;
  top: 0; left: -40%;
  width: 40%; height: 100%;
  background: linear-gradient(90deg, transparent, var(--brand), transparent);
  animation: veil-slide 1.4s infinite;
}
@keyframes veil-slide { to { left: 100%; } }
#loading-veil.is-hidden { opacity: 0; pointer-events: none; }@media (max-width: 1100px){
  .hchart-wrap { height: 120px; }
  #brand h1 { font-size: 19px; }
}

/* Compress topbar at medium-narrow widths: tighten padding/gap and collapse
   the status pill to dot + background only. This frees ~140 px that the full
   "Reibungsloser Betrieb" label would otherwise consume, preventing KPI tiles
   from being squeezed into each other in the 660–820 px range. The ParkPuls
   chrome has no KPI strip, so the status label now stays visible — only the
   hover-reveal timestamp is dropped on touch widths. */@media (max-width: 820px){
  #topbar { padding: 0 16px; gap: 18px; }
  #status-pill .last-update-wrap { display: none; }
  #status-pill { padding: 6px 10px; }
}

/* Narrowest desktop – stack the topbar (brand on its own row, KPIs below) */@media (max-width: 560px){
  :root { --topbar-h: auto; }
  #topbar {
    flex-wrap: wrap;
    padding: 10px 12px;
    gap: 10px 12px;
  }
  #brand { width: 100%; }
  .hchart-wrap { height: 100px; }
  #map { top: 0; }
}

/* ===== Site footer (legal strip) =====
   A slim single-line strip pinned to the bottom of the viewport. Sources /
   API attributions live on the standalone /quellen.html page linked from
   here, so this strip carries only the © line, the legal links, and the
   short disclaimer. The map shrinks to leave space for it (#map uses
   --footer-h as its bottom inset); the Leaflet attribution row, the
   controls panel, and the Karten-Stil gear are all lifted by the same
   variable. Height is auto-measured in JS via ResizeObserver so it adapts
   when the line wraps on narrow viewports. */
#site-footer {
  position: fixed;
  z-index: 650;
  left: 0; right: 0; bottom: 0;
  background: rgba(252, 254, 255, 0.94);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
          backdrop-filter: saturate(180%) blur(14px);
  border-top: 1px solid var(--hairline);
  padding: 5px 18px 6px;
  font-family: var(--sans);
  font-size: 11px;
  color: var(--ink-2);
  line-height: 1.5;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
#site-footer a { color: var(--brand-2); text-decoration: none; }
#site-footer a:hover { text-decoration: underline; }
#site-footer .footer-row { display: inline; }
#site-footer .sep { color: var(--dim); padding: 0 6px; }
#site-footer .heart { color: #e11d48; }   /* signage rose, deliberately a touch warmer than --crit */
#site-footer .muted-note { color: var(--muted); }@media (max-width: 980px){
  /* Below ~980 px the single line can no longer fit – allow it to wrap and
     drop the right-hand disclaimer onto its own row to keep the line height
     small instead of stretching the strip. */
  #site-footer { white-space: normal; padding: 5px 12px 6px; font-size: 10.5px; }
  #site-footer .muted-note { display: block; margin-top: 1px; }
  #site-footer .sep:last-of-type { display: none; }
}@media (max-width: 540px){
  #site-footer { font-size: 10px; }
  #site-footer .sep { padding: 0 4px; }
}
/* Visually-hidden helper for screen-reader-only text (e.g. "Liebe" next to ♥) */
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }

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







/* (Legacy BusPuls @media 720px mobile block removed 2026-06-05 – it hid the map
   with no FAB to summon it and fought the redesign shell. Mobile is now defined
   in one coherent block at the end of this file.) */

/* =====================================================================
   ParkPuls.MS — parking-specific additions
   (garage popups, full-marker pulse, name labels, legend note, filter list)
   ===================================================================== */

/* Garage popup */
.garage-popup .leaflet-popup-content-wrapper {
  border-radius: 12px;
  box-shadow: var(--shadow-md);
}
.garage-popup .leaflet-popup-content { margin: 12px 14px; min-width: 190px; }
.gp-head {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  margin-bottom: 2px;
}
.gp-type {
  font-size: 10.5px; letter-spacing: 0.4px; text-transform: uppercase;
  color: var(--muted); font-weight: 600;
}
.gp-status {
  font-size: 10.5px; font-weight: 600; padding: 2px 8px; border-radius: 999px;
  color: #fff; background: var(--good);
}
.gp-status.gp-good { background: var(--good); }
.gp-status.gp-warn { background: var(--warn); }
.gp-status.gp-crit { background: var(--crit); }
.gp-status.gp-off  { background: var(--dim);  color: var(--ink); }
.gp-name {
  font-family: var(--sans); font-weight: 600; font-size: 15px;
  color: var(--ink); margin: 4px 0 8px;
}
.gp-free { font-size: 13px; color: var(--ink); }
.gp-free strong { font-family: var(--mono); font-size: 18px; font-weight: 600; }
.gp-free .gp-of { color: var(--muted); font-size: 12px; }
.gp-bar {
  height: 7px; border-radius: 4px; background: var(--hl);
  overflow: hidden; margin: 8px 0 4px;
}
.gp-bar-fill { height: 100%; border-radius: 4px; transition: width .3s ease; }
.gp-occ { font-size: 11.5px; color: var(--muted); }
/* No-live-data note in the map peek popup */
.gp-nodata { font-size: 12.5px; color: var(--muted); line-height: 1.4; margin: 2px 0 4px; }

@keyframes pp-marker-pulse {
  0%, 100% { stroke-opacity: 1; }
  50%      { stroke-opacity: 0.35; }
}

/* Permanent name labels (Leaflet tooltip) */
.garage-label.leaflet-tooltip {
  background: rgba(255,255,255,0.92);
  border: 1px solid var(--hairline);
  border-radius: 6px;
  box-shadow: var(--shadow-sm);
  font-family: var(--sans);
  font-size: 11px; font-weight: 600; color: var(--ink);
  padding: 2px 6px;
}
.garage-label.leaflet-tooltip::before { display: none; }

/* Legend note under the colour swatches */
.legend-note {
  margin-top: 8px; padding-top: 8px;
  border-top: 1px solid var(--hairline-2);
  font-size: 10.5px; color: var(--muted);
}


/* Feed-unreachable banner (shown only when the live fetch fails) */
#feed-error {
  position: fixed; left: 50%; bottom: 18px; transform: translateX(-50%);
  z-index: 2000; max-width: min(560px, 92vw);
  background: var(--surface); color: var(--ink-2);
  border: 1px solid var(--hairline); border-left: 3px solid var(--warn);
  border-radius: 12px; box-shadow: var(--shadow-md);
  padding: 12px 40px 12px 16px; font-size: 13px; line-height: 1.5;
}
#feed-error strong { color: var(--ink); }
#feed-error code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px;
  background: var(--hl); padding: 1px 5px; border-radius: 5px; }
#feed-error button {
  position: absolute; top: 8px; right: 10px;
  background: none; border: none; cursor: pointer;
  font-size: 14px; color: var(--muted); line-height: 1;
}
#feed-error button:hover { color: var(--ink); }


/* =============================================================================
   Redesign v2 layout — merged from the former redesign.css (2026-06-04).
   Loaded as part of style.css; these rules sit AFTER the base rules above so
   they override the legacy fixed-topbar / full-bleed-map layout.
   ============================================================================= */
/* =============================================================================
   ParkPuls.MS — redesign v2 (desktop-first)
   Loaded AFTER style.css. Defines the two-pane app shell (top bar · Parkfinder
   rail · map / Statistik) and overrides the legacy fixed-topbar / full-bleed-map
   layout. Reuses style.css for popup, charts, loading veil and status tones.
   ============================================================================= */

[hidden] { display: none !important; }

/* ---- App shell ------------------------------------------------------------ */
#app {
  display: grid;
  grid-template-rows: 56px minmax(0, 1fr) auto;
  height: 100vh;
  overflow: hidden;
}

/* ---- Top bar (override legacy position:fixed) ----------------------------- */
#topbar {
  position: static;
  height: 56px;
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 0 18px;
  background: var(--surface);
  border-bottom: 1px solid var(--hairline);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
.rd-brand { display: flex; align-items: center; gap: 8px; }
.rd-mark { display: flex; align-items: center; }
.rd-mark img { height: 36px; width: auto; display: block; }
.rd-word { font-family: var(--serif); font-weight: 600; font-size: 22px; margin: 0; letter-spacing: .2px; color: var(--ink); }
.rd-sfx { color: var(--accent); }   /* coral .MS — matches Home/Bus/Zug and the ParkPuls card on the hub */
.rd-made { font-size: 12px; color: var(--muted); white-space: nowrap; }
.rd-made .heart { color: var(--accent); }
.rd-topbar-spacer { flex: 1; }
/* The "Made with ♥" tagline also lives in the footer; drop it from the top bar
   once the chrome gets tight so it never collides with the view switch / pill. */
@media (max-width: 1080px) { .rd-made { display: none; } }

.rd-viewswitch { display: flex; background: var(--hl); border-radius: 9px; padding: 3px; }
.rd-viewswitch button {
  border: 0; background: transparent; cursor: pointer;
  font-family: var(--sans); font-size: 13px; font-weight: 500; color: var(--muted);
  padding: 6px 16px; border-radius: 7px;
}
.rd-viewswitch button.is-active { background: var(--surface); color: var(--ink); box-shadow: var(--shadow-sm); }

/* Lage status pill (reuses #status-pill + tone-* from paintStatusPill) */
#topbar #status-pill {
  position: static; display: inline-flex; align-items: center; gap: 7px;
  padding: 6px 13px; border-radius: 999px; font-size: 13px; font-weight: 500;
  background: var(--hl); color: var(--ink-2); border: 1px solid var(--hairline); cursor: default;
}
#topbar #status-pill .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--muted); }
#topbar #status-pill .last-update-wrap { color: var(--muted); font-weight: 400; }
#status-pill.tone-good { background: var(--good-soft); color: var(--good); border-color: transparent; }
#status-pill.tone-good .dot { background: var(--good); }
#status-pill.tone-leicht { background: var(--leicht-soft); color: #8a6d00; border-color: transparent; }
#status-pill.tone-leicht .dot { background: var(--leicht); }
#status-pill.tone-warn { background: var(--warn-soft); color: var(--warn); border-color: transparent; }
#status-pill.tone-warn .dot { background: var(--warn); }
#status-pill.tone-bad { background: var(--crit-soft); color: var(--crit); border-color: transparent; }
#status-pill.tone-bad .dot { background: var(--crit); }
#status-pill.tone-off { background: var(--hl); color: var(--muted); }
#status-pill .dot.load { background: var(--brand); animation: pp-pulse 1.1s ease-in-out infinite; }
#status-pill .dot.err  { background: var(--crit); }
@keyframes pp-pulse { 0%,100% { opacity: 1; } 50% { opacity: .35; } }

/* ---- Two-pane shell ------------------------------------------------------- */
#shell { display: grid; grid-template-columns: 384px minmax(0, 1fr); min-height: 0; }
/* Statistik view: the rail is hidden, so collapse its track and let the
   Statistik panel use the full width instead of being trapped in 384px. */
#shell.stat-mode { grid-template-columns: minmax(0, 1fr); }

#rail {
  background: var(--surface); border-right: 1px solid var(--hairline);
  display: flex; flex-direction: column; min-height: 0; overflow: hidden;
}
#rail-list { display: flex; flex-direction: column; min-height: 0; flex: 1; }

/* City pulse — three equal KPI tiles (Freie Plätze · Ø Auslastung · Offene Häuser) */
.pulse { padding: 15px 16px 13px; border-bottom: 1px solid var(--hairline); }
.pulse-stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.pstat { position: relative; background: var(--hl); border-radius: 10px; padding: 10px 11px; }
.pstat .ps-v { display: block; font-family: var(--mono); font-weight: 700; font-size: 20px; line-height: 1.05; color: var(--ink); }
.pstat .ps-k { display: block; font-size: 11px; color: var(--muted); margin-top: 3px; }
/* The "Freie Plätze" tile is the headline number — slightly larger + tinted. */
.pstat-hero { background: var(--brand-soft); }
.pstat-hero .ps-v { font-size: 26px; color: var(--brand-2); }
.pstat-hero .ps-k { color: var(--brand-2); opacity: .85; }
.pstat-hero .kpi-trend { right: 8px; }
.pulse-dist { margin-top: 13px; }
.pd-head { font-size: 10px; font-weight: 700; letter-spacing: .6px; text-transform: uppercase; color: var(--muted); margin-bottom: 6px; }
.pd-bar { display: flex; height: 7px; border-radius: 4px; overflow: hidden; background: var(--hl); }
.pd-seg { height: 100%; transition: width .3s ease; }
.pd-seg.pd-low { background: var(--good); }
.pd-seg.pd-med { background: var(--leicht); }
.pd-seg.pd-hi  { background: var(--crit); }
.pd-legend { display: flex; gap: 14px; margin-top: 7px; font-size: 11.5px; color: var(--muted); }
.pd-legend b { color: var(--ink); font-weight: 500; }
.pd-sw { display: inline-block; width: 9px; height: 9px; border-radius: 50%; margin-right: 5px; vertical-align: -1px; }
.pd-sw.pd-low { background: var(--good); }
.pd-sw.pd-med { background: var(--leicht); }
.pd-sw.pd-hi  { background: var(--crit); }

/* Mobile-only city-pulse summary + filter-sheet trigger. Both are display:none
   here (desktop keeps the full tiles + inline find section as before); the
   ≤720px block below turns them on and defines the collapse/sheet behaviour. */
.pulse-compact, .filter-summary, .find-veil, .find-sheet-head { display: none; }

/* Find controls */
.find { padding: 12px 16px 11px; border-bottom: 1px solid var(--hairline); display: flex; flex-direction: column; gap: 9px; }
.rd-search { display: flex; align-items: center; gap: 8px; background: var(--hl); border-radius: 9px; padding: 0 11px; height: 38px; }
.rd-search svg { flex: 0 0 auto; width: 16px; height: 16px; color: var(--muted); }
.rd-search input { border: 0; background: transparent; outline: none; width: 100%; font-family: var(--sans); font-size: 14px; color: var(--ink); }
.find-row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
#sortMode { flex: 1 1 150px; font-family: var(--sans); font-size: 13px; border: 1px solid var(--hairline); border-radius: 9px; padding: 8px 9px; background: var(--surface); color: var(--ink); cursor: pointer; }
.rd-chips { display: flex; gap: 6px; }
.rd-chip { font-family: var(--sans); font-size: 12px; font-weight: 500; border: 1px solid var(--hairline); background: var(--surface); color: var(--muted); border-radius: 999px; padding: 6px 11px; cursor: pointer; }
.rd-chip.is-active { background: var(--brand); border-color: var(--brand); color: #fff; }

/* ---- Destination search: row (input + geolocation button) ---- */
.rd-searchrow { display: flex; gap: 8px; align-items: center; }
.rd-searchrow .rd-search { flex: 1 1 auto; }
.rd-geo { flex: 0 0 auto; width: 38px; height: 38px; display: flex; align-items: center; justify-content: center;
  background: var(--hl); border: 0; border-radius: 9px; color: var(--muted); cursor: pointer;
  transition: background .15s ease, color .15s ease; }
.rd-geo svg { width: 18px; height: 18px; }
.rd-geo:hover { background: var(--brand-soft); color: var(--brand-2); }
.rd-geo:focus-visible { outline: none; box-shadow: inset 0 0 0 1.5px var(--brand-line); }
.rd-geo:disabled { cursor: default; opacity: .7; }
.rd-geo.is-loading svg { animation: rd-geo-spin .9s linear infinite; }
@keyframes rd-geo-spin { to { transform: rotate(360deg); } }

/* ---- Destination search: autocomplete dropdown ---- */
.rd-search { position: relative; }
.dest-results { position: absolute; top: calc(100% + 5px); left: 0; right: 0; z-index: 1200;
  background: var(--surface); border: 1px solid var(--hairline); border-radius: 10px;
  box-shadow: 0 8px 24px rgba(20,40,64,0.14); overflow: hidden; max-height: 320px; overflow-y: auto; }
.dr-item { display: flex; align-items: center; gap: 9px; width: 100%; text-align: left;
  background: transparent; border: 0; border-bottom: 1px solid var(--hairline); padding: 9px 11px; cursor: pointer; font-family: var(--sans); }
.dr-item:last-child { border-bottom: 0; }
.dr-item:hover, .dr-item.is-active { background: var(--hl); }
.dr-ico { flex: 0 0 auto; width: 16px; height: 16px; color: var(--muted); }
.dr-ico svg { width: 16px; height: 16px; }
.dr-text { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.dr-label { font-size: 13.5px; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dr-sub { font-size: 11.5px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dr-tag { flex: 0 0 auto; font-size: 10px; text-transform: uppercase; letter-spacing: .4px; color: var(--muted);
  background: var(--hl); border-radius: 5px; padding: 2px 6px; }

/* ---- Chosen destination chip ---- */
.dest-chip { display: flex; align-items: center; gap: 7px; background: var(--brand-soft); border: 1px solid var(--brand-line);
  color: var(--brand-2); border-radius: 9px; padding: 6px 10px; font-size: 12.5px; }
.dest-chip svg { flex: 0 0 auto; width: 14px; height: 14px; }
.dest-chip .dc-text { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--ink); }
.dest-chip .dc-text strong { color: var(--ink); }
.dc-clear { flex: 0 0 auto; border: 0; background: transparent; color: var(--muted); cursor: pointer; font-size: 13px; line-height: 1; padding: 2px 4px; border-radius: 5px; }
.dc-clear:hover { background: var(--hl); color: var(--ink); }
/* Leaflet divIcon reset for the destination pin (no default white box) */
.dest-pin { background: transparent !important; border: 0 !important; }

/* ---- Price planner (duration + arrival) ---- */
/* Price planner — duration stepper + quick presets, arrival toggle + 24h selects */
.planner { display: flex; flex-direction: column; gap: 13px; }
.pl-group { display: flex; flex-direction: column; gap: 7px; }
.pl-grp-head { display: flex; align-items: baseline; justify-content: space-between; }
.pl-grp-label { font-size: 12px; font-weight: 600; color: var(--muted); }
.pl-grp-val { font-family: var(--mono); font-weight: 700; font-size: 15px; color: var(--ink); font-variant-numeric: tabular-nums; }

/* Duration stepper:  −  [ 1 · 2 · 3 · 4 · Tag ]  +  */
.pl-stepper { display: flex; align-items: stretch; gap: 7px; }
.pl-step { flex: 0 0 auto; width: 34px; border: 1px solid var(--hairline); background: var(--surface); color: var(--ink);
  border-radius: 9px; font-size: 19px; font-weight: 600; line-height: 1; cursor: pointer;
  transition: background .15s ease, border-color .15s ease, color .15s ease, transform .12s ease; }
.pl-step:hover { background: var(--brand-soft); border-color: var(--brand-line); color: var(--brand-2); }
.pl-step:active { transform: scale(.94); }
.pl-presets { flex: 1 1 auto; display: grid; grid-template-columns: repeat(5, 1fr); gap: 5px; }
.pl-preset { font-family: var(--sans); font-size: 12px; font-weight: 500; border: 1px solid var(--hairline); background: var(--surface);
  color: var(--muted); border-radius: 8px; padding: 7px 0; cursor: pointer;
  transition: background .15s ease, color .15s ease, border-color .15s ease; }
.pl-preset:hover { border-color: var(--brand-line); color: var(--brand-2); }
.pl-preset.is-active { background: var(--brand); border-color: var(--brand); color: #fff; }

/* Arrival: Jetzt / Geplant segmented toggle + day & time selects */
.pl-arrival { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.pl-when { display: inline-flex; background: var(--hl); border-radius: 9px; padding: 3px; gap: 2px; }
.pl-when button { font-family: var(--sans); font-size: 12.5px; font-weight: 600; border: 0; background: transparent; color: var(--muted);
  border-radius: 7px; padding: 6px 14px; cursor: pointer; transition: background .15s ease, color .15s ease; }
.pl-when button.is-active { background: var(--surface); color: var(--brand-2); box-shadow: 0 1px 3px rgba(20,40,64,0.12); }
.pl-when-fields { display: flex; gap: 7px; }
.pl-when-fields[hidden] { display: none; }
#planDay, #planTime { font-family: var(--sans); font-size: 12.5px; border: 1px solid var(--hairline);
  border-radius: 8px; padding: 6px 8px; background: var(--surface); color: var(--ink); cursor: pointer; }
.pl-note { font-size: 11px; color: var(--muted); margin: 2px 0 0; line-height: 1.35; }
/* Muted qualifier in the detail Tarif row (e.g. "(gerundet)", closed-at-arrival) */
.dt-approx { color: var(--muted); font-weight: 400; font-size: .92em; }

/* List */
.list-meta { padding: 8px 16px; font-size: 12px; color: var(--muted); }
.list-wrap { flex: 1; overflow: auto; min-height: 0; }
/* Each list entry is a row: the card button (opens detail) + an optional
   mobile-only "locate on map" button beside it. The row carries the divider. */
.gc-row { display: flex; align-items: stretch; border-bottom: 1px solid var(--hairline-2); }
.gcard {
  flex: 1 1 auto; min-width: 0;
  display: flex; gap: 11px; align-items: center; text-align: left;
  padding: 11px 16px; border: 0;
  background: transparent; cursor: pointer; font-family: var(--sans);
}
.gcard:hover { background: var(--hl); }
.gcard.is-sel { background: var(--brand-soft); box-shadow: inset 3px 0 0 var(--brand); }
/* Tap-to-locate button — hidden on desktop (list-hover highlights instead). */
.gc-locate {
  display: none; flex: 0 0 auto; width: 50px; border: 0; border-left: 1px solid var(--hairline-2);
  background: transparent; color: var(--muted); cursor: pointer;
  align-items: center; justify-content: center; transition: color .15s ease, background .15s ease;
}
.gc-locate svg { width: 20px; height: 20px; }
.gc-locate:active { color: var(--brand-2); background: var(--hl); }
.gc-row.is-sel .gc-locate { color: var(--brand-2); }
.gc-dot { width: 11px; height: 11px; border-radius: 50%; flex: 0 0 auto; }
.gc-main { flex: 1; min-width: 0; }
.gc-name { display: block; font-weight: 500; font-size: 14px; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.gc-bar { display: block; height: 5px; border-radius: 3px; background: var(--hl); overflow: hidden; margin: 6px 0 5px; }
.gc-bar-f { display: block; height: 100%; border-radius: 3px; }
.gc-meta { display: flex; gap: 8px; flex-wrap: wrap; font-size: 11px; color: var(--muted); }
.gc-meta .b { background: var(--hl); border-radius: 5px; padding: 1px 6px; }
/* Closed houses: when they reopen (live schedule) — slightly emphasised */
.gc-meta .b.b-reopen { background: var(--info-soft); color: var(--info); font-weight: 500; }
/* Price estimate for the chosen duration — emphasised */
.gc-meta .b.b-price { background: var(--brand-soft); color: var(--brand-2); font-weight: 600; }
.gc-meta .b.b-price.b-closed { background: var(--hl); color: var(--dim); font-weight: 500; }
/* Open house with 0 free spaces — flagged "voll" (same meaning as the KPI) */
.gc-meta .b.b-full { background: var(--crit-soft); color: var(--crit); font-weight: 600; }
/* Facility type (Parkhaus / Parkplatz) — neutral outlined category chip */
.gc-meta .b.b-type { background: transparent; border: 1px solid var(--hairline); color: var(--muted); font-weight: 500; }
/* Untrusted sensor — honest "no live data" marker (muted, non-alarming) */
.gc-meta .b.b-nodata { background: var(--hl); color: var(--dim); font-weight: 500; border: 1px dashed var(--hairline); }
/* Distance to the chosen destination */
.gc-meta .b.b-dist { background: var(--info-soft); color: var(--info); font-weight: 500; }
/* E-Lade-Indikator — facility offers EV charging (GARAGE_INFO.ev) */
.gc-meta .b.b-ev { background: var(--good-soft); color: var(--good); font-weight: 600; }
.gc-free { flex: 0 0 auto; text-align: right; min-width: 54px; }
.gc-free .gc-n { display: block; font-family: var(--mono); font-weight: 700; font-size: 22px; line-height: 1; }
.gc-free .gc-l { display: block; font-size: 10px; color: var(--muted); }
.gcard.is-closed .gc-name { color: var(--muted); }

/* Detail */
#rail-detail { display: flex; flex-direction: column; min-height: 0; overflow: auto; }
.dt-top { padding: 13px 16px; border-bottom: 1px solid var(--hairline); }
.dt-back { display: inline-flex; align-items: center; gap: 6px; border: 0; background: transparent; color: var(--brand-2); font-family: var(--sans); font-size: 13px; font-weight: 500; cursor: pointer; padding: 0; margin-bottom: 10px; }
.dt-type { display: block; font-size: 10px; font-weight: 700; letter-spacing: 1.2px; text-transform: uppercase; color: var(--muted); margin-bottom: 3px; }
.dt-name { font-family: var(--serif); font-weight: 600; font-size: 22px; margin: 0; color: var(--ink); }
.dt-badge { display: inline-block; font-size: 11px; font-weight: 600; color: #fff; border-radius: 999px; padding: 2px 10px; margin-top: 7px; }
.dt-hero { display: flex; align-items: baseline; gap: 8px; padding: 14px 16px 8px; }
.dt-hero .dt-num { font-family: var(--mono); font-weight: 700; font-size: 30px; }
.dt-hero .dt-lbl { font-size: 13px; color: var(--muted); }
.dt-bar { height: 8px; border-radius: 5px; background: var(--hl); overflow: hidden; margin: 0 16px 8px; }
.dt-bar-fill { display: block; height: 100%; border-radius: 5px; }
.dt-sub { padding: 0 16px 14px; font-size: 12.5px; color: var(--muted); font-variant-numeric: tabular-nums; }
.dt-rows { padding: 0 16px; }
.dt-sec { font-size: 10px; font-weight: 700; letter-spacing: 1px; text-transform: uppercase; color: var(--muted); margin: 16px 0 0; }
.dt-rows .dt-sec:first-child { margin-top: 2px; }
.dt-row { display: flex; justify-content: space-between; gap: 14px; padding: 8px 0; border-top: 1px solid var(--hairline-2); font-size: 13px; }
.dt-sec + .dt-row { border-top: 0; }
.dt-row .k { color: var(--muted); flex: 0 0 auto; }
.dt-row .v { text-align: right; color: var(--ink); }
/* Live opening status (rendered inside a row value) */
.dt-open { display: block; font-weight: 600; color: var(--ink); }
.dt-open i { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 6px; background: var(--muted); vertical-align: 1px; }
.dt-open.good { color: var(--good); } .dt-open.good i { background: var(--good); }
.dt-open.warn { color: var(--warn); } .dt-open.warn i { background: var(--warn); }
.dt-open.off  { color: var(--muted); } .dt-open.off i { background: var(--dim); }
.dt-open-sub { display: block; font-size: 11.5px; font-weight: 400; color: var(--muted); margin-top: 2px; }
.dt-actions { padding: 14px 16px 18px; }
.dt-route { display: flex; gap: 8px; }
.dt-btn { flex: 1; text-align: center; border: 1px solid var(--hairline); border-radius: 9px; padding: 10px; font-family: var(--sans); font-weight: 500; font-size: 13px; color: var(--ink); background: var(--surface); text-decoration: none; }
.dt-btn:hover { background: var(--hl); text-decoration: none; }
.dt-btn.primary { background: var(--brand); border-color: var(--brand); color: #fff; }
.dt-link { display: block; text-align: center; margin-top: 10px; color: var(--brand-2); font-size: 12.5px; }

/* ---- Map area ------------------------------------------------------------- */
#mapwrap { position: relative; min-height: 0; }
#map { position: absolute; inset: 0; background: var(--paper-deep); transition: none; }
.leaflet-top.leaflet-left { top: 12px; left: 12px; }
.leaflet-bottom { bottom: 0 !important; }

/* Desktop: the wrapper + sheet are transparent (display:contents), so the two
   cards float over the map exactly as before; the mobile handle is hidden. */
#mapTools, .mt-sheet { display: contents; }
.mt-handle { display: none; }

.mapcard {
  position: absolute; z-index: 600; background: var(--surface);
  border: 1px solid var(--hairline); border-radius: var(--radius);
  box-shadow: var(--shadow-md); padding: 12px 13px; font-size: 12px;
}
#mapctl { top: 14px; right: 14px; width: 196px; }
.mc-title { margin: 0 0 7px; font-size: 11px; text-transform: uppercase; letter-spacing: .5px; color: var(--muted); font-weight: 600; }
#mapctl .segmented { margin-bottom: 11px; }
#mapctl .mc-title + .segmented { margin-bottom: 11px; }
#mapctl h3.mc-title:not(:first-child) { margin-top: 4px; }
.mc-toggle { display: flex; align-items: center; gap: 8px; padding: 3px 0; font-size: 12.5px; color: var(--ink-2); cursor: pointer; }
.mc-toggle input { accent-color: var(--brand); }

/* Segmented control (mirror of legacy .segmented, scoped to the map card) */
#mapctl .segmented { display: flex; background: var(--hl); border-radius: 8px; padding: 3px; }
#mapctl .segmented label {
  flex: 1; text-align: center; font-size: 12px; font-weight: 500; color: var(--muted);
  padding: 5px; border-radius: 6px; cursor: pointer; user-select: none;
}
#mapctl .segmented label[aria-selected="true"] { background: var(--surface); color: var(--ink); box-shadow: var(--shadow-sm); }

#legendCard { bottom: 18px; right: 14px; width: 190px; }
.lc-head {
  display: flex; justify-content: space-between; align-items: baseline; gap: 6px;
  width: 100%; margin-bottom: 7px; padding: 0; border: 0; background: none; cursor: pointer;
  font-family: var(--sans); font-size: 11px; text-transform: uppercase; letter-spacing: .5px;
  color: var(--muted); font-weight: 600;
}
.lc-head:hover { color: var(--ink-2); }
.lc-mode { color: var(--brand-2); margin-left: auto; }
.lc-chev { width: 13px; height: 13px; flex: 0 0 auto; align-self: center; color: var(--muted); transition: transform .2s ease; }
#legendCard.is-collapsed .lc-chev { transform: rotate(180deg); }
#legendCard.is-collapsed .lc-head { margin-bottom: 0; }
#legendCard.is-collapsed #legend-body-inner { display: none; }
.legend-row { display: flex; align-items: center; gap: 8px; margin: 3px 0; font-size: 12px; color: var(--ink-2); }
.legend-row .sw { width: 12px; height: 12px; border-radius: 50%; border: 2px solid var(--surface); box-shadow: 0 0 0 1px var(--hairline); flex: 0 0 auto; }
.legend-note { margin-top: 7px; font-size: 10.5px; color: var(--muted); }

/* ---- "P + free count" map pins -------------------------------------------- */
.pp-marker { background: transparent; border: 0; }

/* Pill pin (Parkhaus / Parkplatz): tip apex sits on the geographic point.
   --ox/--oy are small declutter offsets (set inline by JS) that fan apart
   pills which would otherwise hide each other in the dense centre. */
.pp-pill {
  position: absolute; left: 0; top: 0;
  transform: translate(calc(-50% + var(--ox, 0px)), calc(-100% - 6px + var(--oy, 0px)));
  display: flex; align-items: stretch; height: 24px;
  border: 2px solid #fff; box-shadow: 0 1px 4px rgba(20,40,64,0.35);
  background: var(--c); color: #fff; font-family: var(--mono);
  white-space: nowrap; cursor: pointer;
}
.pp-pill.pp-ph { border-radius: 9px; }   /* Parkhaus — rounded pin */
.pp-pill.pp-pp { border-radius: 3px; }   /* Parkplatz — squared tag */
.pp-pill .pp-p { display: flex; align-items: center; padding: 0 5px; background: rgba(255,255,255,0.26); font-weight: 700; font-size: 11px; }
.pp-pill.pp-ph .pp-p { border-radius: 7px 0 0 7px; }
.pp-pill.pp-pp .pp-p { border-radius: 1px 0 0 1px; }
/* Roof over the "P" — marks a Parkhaus (building) */
.pp-roof { position: absolute; left: 11px; top: -8px; transform: translateX(-50%); line-height: 0; pointer-events: none; }
.pp-roof .rf { fill: var(--c); }
.pp-roof .rs { fill: none; stroke: #fff; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.pp-pill .pp-n { display: flex; align-items: center; padding: 0 7px; font-weight: 700; font-size: 12.5px; letter-spacing: .2px; }
.pp-pill::after {                          /* downward tip */
  content: ""; position: absolute; left: 50%; bottom: -7px; transform: translateX(-50%);
  border: 6px solid transparent; border-top-color: var(--c);
}
.pp-pill.pp-full { animation: pp-pin-pulse 1.8s ease-in-out infinite; }
@keyframes pp-pin-pulse {
  0%, 100% { box-shadow: 0 1px 4px rgba(20,40,64,0.35), 0 0 0 0 rgba(220,38,38,0.55); }
  50%      { box-shadow: 0 1px 4px rgba(20,40,64,0.35), 0 0 0 7px rgba(220,38,38,0); }
}
.pp-pill.is-sel { outline: 2px solid var(--ink); outline-offset: 1px; box-shadow: 0 0 0 4px var(--brand-line), 0 1px 4px rgba(20,40,64,0.35); }
/* Highlighted from a list-card hover — lift, enlarge and ring the pin so the
   eye jumps straight to it on the map (must repeat the base translate). */
.pp-pill.is-hover { transform: translate(calc(-50% + var(--ox, 0px)), calc(-100% - 6px + var(--oy, 0px))) scale(1.16);
  box-shadow: 0 0 0 4px var(--brand-line), 0 6px 16px rgba(20,40,64,0.45); }

/* Dot (zoomed out, and closed houses) — centred on the point */
.pp-dot {
  position: absolute; left: 0; top: 0; transform: translate(-50%, -50%);
  width: 14px; height: 14px; border-radius: 50%;
  border: 2px solid #fff; background: var(--c); box-shadow: 0 1px 3px rgba(20,40,64,0.3); cursor: pointer;
}
.pp-dot.pp-closed { width: 12px; height: 12px; background: var(--surface); border: 2px solid var(--dim); box-shadow: none; }
/* Open but no trustworthy live data: a pale-green "P" pin (count omitted),
   reading as "open, park here — live count unknown". Dark-green glyph for
   legibility on the pale fill; clearly NOT the closed hollow dot. */
.pp-pill.pp-nodata { color: #14532d; }
.pp-pill.pp-nodata .pp-p { background: rgba(20,83,45,0.12); }
.pp-dot.is-sel { box-shadow: 0 0 0 4px var(--brand-line), 0 1px 3px rgba(20,40,64,0.3); }
.pp-dot.is-hover { transform: translate(-50%, -50%) scale(1.45); box-shadow: 0 0 0 4px var(--brand-line), 0 2px 6px rgba(20,40,64,0.4); }

/* Marker name labels (carried from legacy .garage-label) */
.garage-label { background: transparent; border: 0; box-shadow: none; font-weight: 600; font-size: 11px; color: var(--ink); text-shadow: 0 1px 2px #fff, 0 0 2px #fff; }
.garage-label::before { display: none; }

/* Popup "Alle Details" button */
.gp-more { margin-top: 9px; width: 100%; border: 0; background: var(--brand-soft); color: var(--brand-2); font-family: var(--sans); font-weight: 500; font-size: 12.5px; padding: 8px; border-radius: 8px; cursor: pointer; }
.gp-more:hover { background: var(--brand); color: #fff; }

/* ---- Statistik view ------------------------------------------------------- */
#statview { position: absolute; inset: 0; z-index: 500; background: var(--paper); overflow: auto; padding: 18px 22px 26px; }
.sv-head { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-bottom: 16px; flex-wrap: wrap; }
.sv-title { display: flex; flex-direction: column; }
.sv-eyebrow { font-size: 11px; text-transform: uppercase; letter-spacing: .6px; color: var(--muted); font-weight: 600; }
.sv-main { font-family: var(--serif); font-size: 18px; font-weight: 600; color: var(--ink); }
#statview .drawer-tabs { display: flex; gap: 4px; background: var(--hl); border-radius: 9px; padding: 3px; }
#statview .dtab { border: 0; background: transparent; cursor: pointer; font-family: var(--sans); font-size: 13px; font-weight: 500; color: var(--muted); padding: 7px 16px; border-radius: 7px; }
#statview .dtab:hover:not(.is-active) { color: var(--ink-2); }
#statview .dtab.is-active { background: var(--surface); color: var(--ink); box-shadow: var(--shadow-sm); }
#statview .drawer-pane { display: none; }
#statview .drawer-pane.is-active { display: block; }
#statview .hist-charts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
@media (max-width: 1100px){ #statview .hist-charts { grid-template-columns: 1fr; } }

/* Statistik empty / error state (shown until history data accrues) */
.sv-empty {
  grid-column: 1 / -1;
  max-width: 460px;
  margin: 40px auto;
  text-align: center;
  color: var(--muted);
}
.sv-empty svg { width: 40px; height: 40px; color: var(--brand); opacity: .8; margin-bottom: 10px; }
.sv-empty h4 { font-family: var(--serif); font-size: 17px; font-weight: 600; color: var(--ink); margin: 0 0 6px; }
.sv-empty p { font-size: 13px; line-height: 1.5; margin: 0; }

/* ---- Footer (override legacy position:fixed) ------------------------------ */
#site-footer { position: static; background: var(--surface); backdrop-filter: none; -webkit-backdrop-filter: none; z-index: auto; }

/* ---- Reasons card position (above the legend, bottom-left of map) --------- */
#reasonsCard { left: 400px; right: auto; bottom: 18px; }

/* Floating action button (map ⇄ list) — only used on the mobile layout below. */
.map-fab { display: none; }

/* =============================================================================
   Mobile / narrow-viewport layout (≤ 720 px) — list-first
   -----------------------------------------------------------------------------
   The Parkfinder rail becomes the full-screen primary surface. The map is a
   full-screen overlay summoned by a floating button; the Statistik view reuses
   that overlay (it renders inside #mapwrap). Desktop layout above is untouched.
   ============================================================================= */
@media (max-width: 720px) {

  /* Top bar: one compact row that fits a ~360 px phone. */
  #topbar { gap: 8px; padding: 0 11px; position: relative; z-index: 1300; flex-wrap: nowrap; }
  .rd-mark img { height: 26px; }
  .rd-word { font-size: 16px; }
  .rd-viewswitch { padding: 2px; }
  .rd-viewswitch button { padding: 6px 11px; font-size: 12px; }
  #topbar #status-pill { padding: 5px 9px; font-size: 12px; gap: 6px; min-width: 0; max-width: 42vw; }
  #topbar #status-pill .txt { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  #topbar #status-pill .last-update-wrap { display: none; }   /* reclaim width */

  /* Shell collapses to a single full-height cell holding the rail. */
  #shell { grid-template-columns: 1fr; grid-template-rows: minmax(0, 1fr); }
  #rail { border-right: 0; }
  .list-wrap { padding-bottom: 80px; }    /* clear the floating FAB */
  .gc-locate { display: inline-flex; }    /* touch: tap a row to locate its pin */

  /* ---- City-pulse: one-line summary, tap to reveal the distribution ----
     Replaces the 3-tile grid as the default state; #pcFree/#pcOcc/#pcOpen
     mirror the same live numbers (kept in sync by renderPulse in app.js). */
  .pulse { padding: 0; border-bottom: 0; }
  .pulse-compact {
    display: flex; align-items: center; gap: 7px; width: 100%;
    padding: 10px 16px; border: 0; border-bottom: 1px solid var(--hairline);
    background: var(--surface); cursor: pointer; text-align: left;
    font-family: var(--sans); color: var(--ink);
  }
  .pulse-compact .pc-n { font-family: var(--mono); font-weight: 700; font-size: 16px; color: var(--brand-2); flex: 0 0 auto; }
  .pulse-compact .pc-txt { flex: 1 1 auto; min-width: 0; font-size: 12px; color: var(--ink-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .pulse-compact .pc-chev { width: 13px; height: 13px; color: var(--muted); flex: 0 0 auto; transition: transform .2s ease; }
  .pulse-compact[aria-expanded="true"] .pc-chev { transform: rotate(180deg); }
  .pulse-detail {
    max-height: 0; overflow: hidden; background: var(--surface);
    border-bottom: 1px solid var(--hairline);
    transition: max-height .25s ease;
  }
  .pulse-detail.is-open { max-height: 220px; }
  .pulse-detail .pulse-stats { display: none; }   /* numbers already live in the compact row */
  .pulse-detail .pulse-dist { padding: 4px 16px 13px; margin-top: 0; }

  /* ---- Filter summary bar: collapsed trigger for the find/planner sheet --- */
  .filter-summary {
    display: flex; align-items: center; gap: 8px; width: 100%;
    padding: 10px 16px; border: 0; border-bottom: 1px solid var(--hairline);
    background: var(--surface-2); cursor: pointer; text-align: left;
    font-family: var(--sans);
  }
  .filter-summary .fs-ico { width: 15px; height: 15px; color: var(--brand-2); flex: 0 0 auto; }
  .filter-summary .fs-txt { flex: 1 1 auto; min-width: 0; font-size: 12px; font-weight: 500; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .filter-summary .fs-chev { width: 13px; height: 13px; color: var(--muted); flex: 0 0 auto; transition: transform .2s ease; }
  .filter-summary[aria-expanded="true"] .fs-chev { transform: rotate(180deg); }

  /* ---- Find section becomes a bottom sheet, opened by .filter-summary ---- */
  .find-veil {
    display: block; position: fixed; top: 56px; left: 0; right: 0; bottom: 0;
    z-index: 1350; background: rgba(13,20,29,.32); opacity: 0; pointer-events: none;
    transition: opacity .25s ease;
  }
  .find-veil.is-open { opacity: 1; pointer-events: auto; }
  #find {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 1360;
    max-height: 82vh; overflow-y: auto;
    background: var(--surface);
    border-radius: 16px 16px 0 0; box-shadow: var(--shadow-lg); border-bottom: 0;
    transform: translateY(101%);
    transition: transform .3s cubic-bezier(.2,.7,.2,1);
    padding-bottom: max(11px, env(safe-area-inset-bottom, 0px));
  }
  #find.is-open { transform: translateY(0); }
  .find-sheet-head { display: block; }
  .fsh-handle { display: block; width: 36px; height: 4px; border-radius: 99px; background: var(--dim); margin: 9px auto 2px; }
  .fsh-row { display: flex; align-items: center; justify-content: space-between; padding: 5px 2px 11px; border-bottom: 1px solid var(--hairline); margin-bottom: 2px; }
  .fsh-row h3 { font-family: var(--serif); font-size: 15px; font-weight: 600; margin: 0; color: var(--ink); }
  .fsh-close { border: 0; background: transparent; color: var(--brand-2); font-family: var(--sans); font-size: 12.5px; font-weight: 600; cursor: pointer; padding: 4px 2px; }

  /* Map + Statistik live in a full-screen overlay, slid up when summoned. */
  #mapwrap {
    position: fixed;
    top: 56px; left: 0; right: 0; bottom: 0;
    z-index: 1200;
    transform: translateY(101%);
    transition: transform .32s cubic-bezier(.2,.7,.2,1);
    box-shadow: 0 -10px 30px rgba(20,40,64,.20);
  }
  body.map-open #mapwrap,
  body.stat-view #mapwrap { transform: translateY(0); }

  /* Map controls become a collapsible bottom sheet (within the map overlay).
     A handle pill sits bottom-left (the FAB owns bottom-right); tapping it
     slides up a panel with the colour-mode + layers + legend. */
  #mapTools { display: block; }
  .mt-handle {
    display: inline-flex; align-items: center; gap: 7px;
    position: absolute; left: 14px; bottom: 16px; z-index: 1250;
    height: 44px; padding: 0 15px; margin: 0;
    border: 1px solid var(--hairline); border-radius: 999px; cursor: pointer;
    background: var(--surface); color: var(--ink);
    font-family: var(--sans); font-size: 13px; font-weight: 600;
    box-shadow: var(--shadow-md);
  }
  .mt-handle .mt-chev { width: 16px; height: 16px; color: var(--muted); transition: transform .25s ease; }
  #mapTools.open .mt-handle .mt-chev { transform: rotate(180deg); }

  .mt-sheet {
    display: none;
    position: absolute; left: 12px; right: 12px; bottom: 70px; z-index: 1240;
    max-height: 62%; overflow: auto;
    background: var(--surface); border: 1px solid var(--hairline);
    border-radius: 14px; box-shadow: var(--shadow-lg);
  }
  #mapTools.open .mt-sheet { display: block; }
  /* Cards become flush, stacked sections inside the sheet (override the
     desktop absolute positioning). */
  .mt-sheet #mapctl, .mt-sheet #legendCard {
    position: static; inset: auto; width: auto; margin: 0;
    border: 0; border-radius: 0; box-shadow: none;
  }
  .mt-sheet #legendCard { border-top: 1px solid var(--hairline-2); }

  /* No controls in the Statistik view. */
  body.stat-view #mapTools { display: none; }

  /* Floating action button: toggles the map overlay (Karte ⇄ Liste). */
  .map-fab {
    display: inline-flex; align-items: center; gap: 8px;
    position: fixed; right: 16px; bottom: 18px; z-index: 1300;
    height: 48px; padding: 0 18px 0 15px; margin: 0;
    border: 0; border-radius: 999px; cursor: pointer;
    background: var(--brand); color: #fff;
    font-family: var(--sans); font-size: 14px; font-weight: 600;
    box-shadow: 0 6px 18px rgba(0,180,240,.42), 0 2px 6px rgba(20,40,64,.18);
    transition: background .15s ease;
  }
  .map-fab:hover, .map-fab:focus-visible { background: var(--brand-2); outline: none; }
  .map-fab svg { width: 20px; height: 20px; }
  body.stat-view .map-fab { display: none; }   /* no map FAB while viewing trends */

  /* Status-reasons hint docks above the FAB, full width. */
  #reasonsCard {
    left: 12px; right: 12px; bottom: 78px; top: auto;
    width: auto; max-width: none;
  }

  /* Statistik view: edge-to-edge with a little breathing room. */
  #statview { padding: 16px 14px 24px; }
  .sv-head { gap: 10px 14px; }
}

/* Extra-narrow phones (e.g. 360 px): shave a few more pixels so nothing overflows. */
@media (max-width: 380px) {
  #topbar { gap: 6px; padding: 0 10px; }
  .rd-mark img { height: 24px; }
  .rd-word { font-size: 15px; }
  .rd-viewswitch button { padding: 5px 9px; font-size: 11.5px; }
  #topbar #status-pill { padding: 5px 8px; font-size: 11.5px; max-width: 38vw; }
}

/* =============================================================================
   UI polish layer (2026-06) — theme toggle, skeleton loading, micro-
   interactions, panel transitions, themed scrollbars, glass map cards.
   All motion is killed globally by the prefers-reduced-motion rule above.
   ============================================================================= */

/* ---- Theme toggle (top bar) ---- */
.rd-theme {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; flex: 0 0 auto;
  border: 1px solid var(--hairline); border-radius: 9px;
  background: var(--surface); color: var(--ink-2); cursor: pointer;
  transition: background .15s ease, color .15s ease, border-color .15s ease, transform .12s ease;
}
.rd-theme:hover { background: var(--hl); color: var(--brand-2); border-color: var(--brand-line); }
.rd-theme:active { transform: scale(.92); }
.rd-theme svg { width: 17px; height: 17px; display: block; }
.rd-theme .ico-moon { display: none; }
html[data-theme="dark"] .rd-theme .ico-sun  { display: none; }
html[data-theme="dark"] .rd-theme .ico-moon { display: block; }
html[data-theme="dark"] .rd-theme:hover { color: var(--brand); }

/* ---- Skeleton loading (shown until the first poll lands) ---- */
@keyframes sk-shimmer { from { background-position: 200% 0; } to { background-position: -200% 0; } }
.sk {
  border-radius: 6px;
  background: linear-gradient(90deg, var(--hl) 25%, var(--hl-hover) 50%, var(--hl) 75%);
  background-size: 200% 100%;
  animation: sk-shimmer 1.4s linear infinite;
}
.sk-card { display: flex; gap: 11px; align-items: center; padding: 14px 16px; border-bottom: 1px solid var(--hairline-2); }
.sk-dot  { width: 11px; height: 11px; border-radius: 50%; flex: 0 0 auto; }
.sk-main { flex: 1; display: flex; flex-direction: column; gap: 8px; }
.sk-line { height: 10px; }
.sk-line.w60 { width: 60%; }
.sk-line.w85 { width: 85%; }
.sk-num  { width: 44px; height: 26px; border-radius: 7px; flex: 0 0 auto; }

/* ---- Micro-interactions: list cards ---- */
.gcard { transition: background .15s ease; }
.gcard:active { background: var(--hl-hover); }
.gcard:hover .gc-name { color: var(--brand-2); }
.gcard .gc-bar-f { transition: width .45s cubic-bezier(.2,.7,.2,1), background-color .3s ease; }

/* ---- Chips, tabs, buttons: smooth + tactile ---- */
.rd-chip { transition: background .15s ease, color .15s ease, border-color .15s ease, transform .12s ease; }
.rd-chip:hover:not(.is-active) { border-color: var(--brand-line); color: var(--brand-2); }
.rd-chip:active { transform: scale(.95); }
.rd-viewswitch button { transition: background .18s ease, color .18s ease, box-shadow .18s ease; }
.dt-btn { transition: background .15s ease, border-color .15s ease, transform .12s ease; }
.dt-btn:active { transform: scale(.97); }
.dt-btn.primary:hover { background: var(--brand-2); border-color: var(--brand-2); }
.gp-more { transition: background .15s ease, color .15s ease; }
.dt-back { transition: color .15s ease; }
.dt-back:hover { color: var(--brand); }
#sortMode { transition: border-color .15s ease; }
#sortMode:hover { border-color: var(--brand-line); }
/* Inert while a destination is set (list is always sorted by distance then) */
#sortMode:disabled { opacity: .55; cursor: not-allowed; }
#sortMode:disabled:hover { border-color: var(--hairline); }
.rd-search { transition: box-shadow .15s ease; }
.rd-search:focus-within { box-shadow: inset 0 0 0 1.5px var(--brand-line); }
.pstat { transition: background .15s ease; }

/* ---- Panel / view transitions ---- */
@keyframes pp-fade-up  { from { opacity: 0; transform: translateY(8px); }  to { opacity: 1; transform: none; } }
@keyframes pp-slide-in { from { opacity: 0; transform: translateX(14px); } to { opacity: 1; transform: none; } }
#statview:not([hidden])    { animation: pp-fade-up  .28s cubic-bezier(.2,.7,.2,1); }
#rail-detail:not([hidden]) { animation: pp-slide-in .26s cubic-bezier(.2,.7,.2,1); }
#rail-list:not([hidden])   { animation: pp-fade-up  .22s cubic-bezier(.2,.7,.2,1); }

/* ---- Map pins: gentle lift on hover ---- */
.pp-pill { transition: transform .15s ease; }
.pp-pill:hover { transform: translate(calc(-50% + var(--ox, 0px)), calc(-100% - 6px + var(--oy, 0px))) scale(1.07); }

/* ---- Glass map cards (controls + legend float over the map) ---- */
.mapcard {
  background: color-mix(in srgb, var(--surface) 86%, transparent);
  -webkit-backdrop-filter: saturate(160%) blur(10px);
          backdrop-filter: saturate(160%) blur(10px);
}

/* ---- Narrow viewports: keep the chrome from widening the page ----
   #app's implicit grid column sizes to min-content, so an overflowing top
   bar silently widens the whole layout past the viewport. Clamp the track
   and shave the top-bar pieces so everything fits a 360–390 px phone with
   the theme toggle present. */
#app { grid-template-columns: minmax(0, 1fr); }

@media (max-width: 720px) {
  #topbar { gap: 6px; padding: 0 9px; }
  .rd-mark img { height: 24px; }
  .rd-word { font-size: 15px; }
  .rd-viewswitch button { padding: 6px 9px; font-size: 11.5px; }
  #topbar #status-pill { padding: 5px 8px; font-size: 11.5px; max-width: 34vw; flex-shrink: 1; }
  .rd-theme { width: 30px; height: 30px; border-radius: 8px; }
  .rd-theme svg { width: 15px; height: 15px; }
}
@media (max-width: 380px) {
  #topbar { gap: 5px; }
  .rd-word { font-size: 14px; }
  .rd-theme { width: 28px; height: 28px; }
}

/* =============================================================================
   2026-06-11 additions — review follow-ups
   ============================================================================= */

/* ---- Empty search state in the Parkfinder list (#6) ---- */
.list-empty {
  padding: 36px 22px;
  text-align: center;
  color: var(--muted);
}
.list-empty svg { width: 34px; height: 34px; color: var(--dim); margin-bottom: 8px; }
.list-empty h4 { font-family: var(--serif); font-size: 16px; font-weight: 600; color: var(--ink); margin: 0 0 5px; }
.list-empty p { font-size: 12.5px; line-height: 1.5; margin: 0 0 14px; }
.list-empty p strong { color: var(--ink-2); }
.list-empty-reset {
  border: 1px solid var(--hairline); border-radius: 999px; cursor: pointer;
  background: var(--surface); color: var(--brand-2);
  font-family: var(--sans); font-size: 12.5px; font-weight: 500; padding: 7px 14px;
  transition: background .15s ease, border-color .15s ease;
}
.list-empty-reset:hover { border-color: var(--brand-line); background: var(--brand-soft); }

/* ---- Detail sparkline: free spaces over the last 24 h (#14) ---- */
.dt-spark { padding: 12px 16px 4px; }
.dt-spark-head {
  font-size: 10.5px; font-weight: 600; letter-spacing: .5px; text-transform: uppercase;
  color: var(--muted); margin-bottom: 6px;
}
.dt-spark-sub { font-weight: 500; text-transform: none; letter-spacing: 0; opacity: .8; }
.dt-spark-wrap { position: relative; height: 84px; }
/* Best-arrival hint + 30-day history strip (detail drawer, 2026-07-16) */
.dt-best { margin: 8px 16px 0; padding: 8px 10px; border-radius: 8px;
  background: var(--surface-2, rgba(0,180,240,0.06)); font-size: 12.5px; color: var(--ink-2, #3a4a5c); }
.dt-best b { font-variant-numeric: tabular-nums; }
.dt-hist30 { padding: 12px 16px 4px; }
.dt-hist30-bars { display: flex; align-items: flex-end; gap: 2px; height: 56px; }
.dt-hist30-bars span { flex: 1; min-height: 2px; border-radius: 2px 2px 0 0; }
.dt-hist30-axis { display: flex; justify-content: space-between;
  font-size: 10.5px; color: var(--muted, #7a8a9b); margin-top: 2px; }
.dt-spark-empty { height: 84px; display: flex; align-items: center; justify-content: center;
  font-size: 12.5px; color: var(--muted); text-align: center; padding: 0 12px; }

/* ---- Prominent partial-data notice above the Statistik charts (#16) ---- */
.hchart-notice {
  grid-column: 1 / -1;
  padding: 11px 16px;
  background: var(--info-soft);
  border: 1px solid var(--hairline-2);
  border-left: 3px solid var(--info);
  border-radius: 10px;
  font-size: 13px; line-height: 1.5; color: var(--ink-2);
}
.hchart-notice strong { color: var(--ink); }

/* ---- Mobile refinements (#10) ----
   (#9's scroll-triggered KPI condensing was superseded by the always-compact
   .pulse-compact summary above — the pulse is collapsed by default now, so
   there's nothing left to condense on scroll.) */
@media (max-width: 720px) {
  /* #10 — keep footer links clear of the floating "Karte" button */
  #site-footer { padding-right: 112px; }
}

/* ---- Themed scrollbars (rail list, detail, Statistik, mobile sheet) ---- */
.list-wrap, #rail-detail, #statview, .mt-sheet { scrollbar-width: thin; scrollbar-color: var(--dim) transparent; }
.list-wrap::-webkit-scrollbar, #rail-detail::-webkit-scrollbar, #statview::-webkit-scrollbar, .mt-sheet::-webkit-scrollbar { width: 8px; }
.list-wrap::-webkit-scrollbar-thumb, #rail-detail::-webkit-scrollbar-thumb, #statview::-webkit-scrollbar-thumb, .mt-sheet::-webkit-scrollbar-thumb {
  background: var(--dim); border-radius: 99px; border: 2px solid transparent; background-clip: content-box;
}

/* ==========================================================================
   Footer-Standortverzeichnis als Drop-up-Panel [2026-07-07]
   Der Footer ist eine fixierte Ein-Zeilen-Leiste (nowrap/hidden). Das SEO-
   <details> expandierte IN der Leiste und wuchs über die Karte. Jetzt: die
   Summary bleibt ein Inline-Element in der Zeile, das geöffnete <nav> legt
   sich als eigenes Panel ÜBER die Leiste (absolute zum fixed Footer).
   Farben über Vars → folgt automatisch dem Dark-Theme.
   ========================================================================== */
#site-footer:has(#standorte-verzeichnis[open]) { overflow: visible; }
#standorte-verzeichnis { display: inline; }
#standorte-verzeichnis > summary {
  display: inline; cursor: pointer; list-style: none;
  color: var(--brand-2);
}
#standorte-verzeichnis > summary::-webkit-details-marker { display: none; }
#standorte-verzeichnis > summary::before { content: " · "; color: var(--dim); }
#standorte-verzeichnis > summary::after  { content: " ▴"; font-size: 8px; }
#standorte-verzeichnis[open] > summary::after { content: " ▾"; font-size: 8px; }
#standorte-verzeichnis > nav {
  position: absolute; left: 0; right: 0; bottom: 100%;
  background: var(--surface);
  border-top: 1px solid var(--hairline);
  box-shadow: 0 -10px 26px rgba(20, 40, 64, 0.14);
  padding: 12px 18px; line-height: 2.1;
  white-space: normal; text-align: center;
  max-height: 45vh; overflow-y: auto;
}

/* Nachschärfung [2026-07-07]: Durch die zusätzlichen Footer-Elemente ist die
   Ein-Zeilen-Leiste ~1150 px breit – unterhalb davon würde die nowrap/ellipsis-
   Regel (>980 px) die Verzeichnis-Summary unsichtbar abschneiden. Früher
   umbrechen statt clippen. */
@media (max-width: 1220px) {
  #site-footer { white-space: normal; }
}
