:root {
  --bg: #FAFAFA;
  --surface: #FFFFFF;
  --ink: #16181D;
  --muted: #6B7280;
  --border: #E7E7EA;
  --accent: #2563EB;
  --accent-weak: #EFF3FE;

  /* Darkened from the original #059669/#D97706/#DC2626 — those failed WCAG AA
     (4.5:1) as small badge text on their own tinted backgrounds and as the
     white numerals on solid marker pins. These clear 4.5:1 in both contexts. */
  --free: #047857;
  --free-bg: #E7F5EF;
  --few: #A34E08;
  --few-bg: #FBF0DF;
  --none: #B91C1C;
  --none-bg: #FBEAEA;
  /* Distinct hue (violet, not the red used for "no free places") — a closure
     notice is a different axis from vacancy status: a facility can show
     "brak wolnych miejsc" while still open, or show free places while not
     accepting new enrollment. Contrast-checked the same way as free/few/none
     (see their comment above): 7.1:1 white-on-solid, 6.0:1 text-on-bg. */
  --closed: #6D28D9;
  --closed-bg: #F1E9FE;

  --font-body: "Inter", -apple-system, "Segoe UI", sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, monospace;

  --radius-sm: 6px;
  --radius-md: 10px;
}

* { box-sizing: border-box; }

[hidden] { display: none !important; }

html, body {
  margin: 0;
  height: 100%;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  -webkit-font-smoothing: antialiased;
}

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

/* ---------- Top bar ---------- */

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding: 16px 28px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  flex-wrap: wrap;
}

.brand {
  display: flex;
  align-items: center;
  gap: 12px;
}

.brand-mark {
  width: 10px;
  height: 10px;
  border-radius: 3px;
  background: var(--accent);
  flex: none;
}

.brand-text h1 {
  font-weight: 600;
  font-size: 17px;
  margin: 0;
  letter-spacing: -0.01em;
}

.brand-text p {
  margin: 2px 0 0;
  font-size: 13px;
  color: var(--muted);
}

.topbar-stats {
  display: flex;
  gap: 32px;
}

.stat {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  min-width: 80px;
}

.stat-value {
  font-family: var(--font-mono);
  font-weight: 600;
  font-size: 19px;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.stat-updated .stat-value {
  font-size: 13px;
  font-weight: 500;
  color: var(--muted);
}

.stat-label {
  font-size: 11px;
  color: var(--muted);
  letter-spacing: 0.01em;
  text-align: right;
}

/* ---------- Layout ---------- */

/* `.app-shell` (body) makes the topbar an auto-sized flex item and `.layout`
   fill exactly what's left — `.layout` no longer has to guess the topbar's
   height via a hardcoded `calc(100vh - 66px)`, which broke on mobile where
   the topbar wraps to two lines (~150px, not 66px): see the mobile block
   below for what that bug looked like. */
.app-shell {
  display: flex;
  flex-direction: column;
}

.layout {
  display: flex;
  flex: 1;
  min-height: 0; /* let children's own scroll/height rules apply instead of growing past the flex parent */
}

.sidebar {
  width: 300px;
  flex: none;
  overflow-y: auto;
  border-right: 1px solid var(--border);
  background: var(--surface);
  padding: 20px;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.panel { display: flex; flex-direction: column; gap: 7px; }

.field-label {
  font-size: 12px;
  font-weight: 500;
  color: var(--muted);
}

input[type="text"], select {
  font-family: var(--font-body);
  font-size: 14px;
  padding: 9px 11px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--ink);
}

input[type="text"]::placeholder { color: #A3A6AC; }

.search-box { position: relative; }

.search-suggestions {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  z-index: 20;
  margin: 0;
  padding: 4px;
  list-style: none;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
  max-height: 280px;
  overflow-y: auto;
}

.search-suggestion {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  padding: 7px 9px;
  border-radius: 5px;
  cursor: pointer;
}

.search-suggestion:hover, .search-suggestion.active {
  background: var(--bg);
}

.search-suggestion-name {
  font-size: 13px;
  font-weight: 500;
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.search-suggestion-address {
  font-size: 11px;
  color: var(--muted);
  white-space: nowrap;
}

input[type="text"]:focus, select:focus, .toggle input:focus-visible + span {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
  border-color: var(--accent);
}

.toggle {
  display: flex;
  align-items: center;
  gap: 9px;
  font-size: 14px;
  cursor: pointer;
}

.toggle input { accent-color: var(--accent); width: 15px; height: 15px; }

/* Floating Leaflet control (bottomleft), not a sidebar panel — see
   addLegendControl() in app.js. Leaflet gives the control corner container
   its own stacking/positioning; this just styles the box itself, matching
   the popup wrapper's surface/shadow language. */
.map-legend-control {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: 0 2px 8px rgba(22, 24, 29, 0.15);
  padding: 7px 10px;
  font-size: 13px;
}

.map-legend summary {
  font-weight: 500;
  color: var(--ink);
  font-size: 13px;
}

.map-legend .legend-rows {
  margin-top: 8px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.legend-row {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  padding: 3px 0;
}

.dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex: none;
}

.dot-free { background: var(--free); }
.dot-few { background: var(--few); }
.dot-none { background: var(--none); }
.dot-closure { background: var(--closed); }
.dot-new { background: var(--accent); }

/* ---------- Nearest-on-foot search (sidebar + map) ---------- */

.nearby-btn {
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 500;
  padding: 9px 11px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--ink);
  cursor: pointer;
  text-align: left;
}

.nearby-btn:hover { border-color: var(--accent); }

.nearby-btn.active {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}

.nearby-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.nearby-clear {
  border: none;
  background: none;
  color: var(--muted);
  font-size: 13px;
  line-height: 1;
  cursor: pointer;
  padding: 2px 4px;
}

.nearby-clear:hover { color: var(--ink); }

.nearby-results {
  margin-top: 8px;
}

.nearby-status {
  font-size: 12px;
  color: var(--muted);
  margin: 6px 0;
}

#nearbyList {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-top: 6px;
}

.nearby-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px;
  width: 100%;
  padding: 6px 8px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}

.nearby-row:hover, .nearby-row.active { border-color: var(--accent); }

.nearby-name {
  font-size: 13px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.nearby-meta {
  flex: none;
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--muted);
  white-space: nowrap;
}

.origin-pin {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: #fff;
  border: 3px solid var(--accent);
  box-shadow: 0 1px 3px rgba(22, 24, 29, 0.35);
}

/* ---------- Per-district breakdown (sidebar) ---------- */

.district-stats-panel {
  border-bottom: 1px solid var(--border);
  padding-bottom: 14px;
}

.district-stats-list {
  display: flex;
  flex-direction: column;
  gap: 7px;
  margin-top: 4px;
  max-height: 220px;
  overflow-y: auto;
}

.district-stat-row {
  display: grid;
  grid-template-columns: 1fr auto;
  column-gap: 8px;
  row-gap: 4px;
  width: 100%;
  padding: 2px 0;
  border: none;
  background: none;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}

.district-stat-name {
  font-size: 12px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.district-stat-value {
  font-family: var(--font-mono);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  color: var(--muted);
}

.district-stat-bar {
  grid-column: 1 / -1;
  display: block;
  height: 4px;
  border-radius: 999px;
  background: var(--border);
  overflow: hidden;
}

.district-stat-bar span {
  display: block;
  height: 100%;
  background: var(--free);
  border-radius: 999px;
}

.district-stat-row:hover .district-stat-name { text-decoration: underline; }
.district-stat-row.active .district-stat-name { color: var(--accent); font-weight: 600; }

/* ---------- Sparklines (facility popup history + citywide trend) ---------- */

.trend-panel {
  border-bottom: 1px solid var(--border);
  padding-bottom: 14px;
}

.sparkline-wrap {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 4px;
}

.sparkline-range {
  display: flex;
  gap: 4px;
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--muted);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

/* ---------- Trend arrow (result badge + popup badge) ---------- */

.trend-arrow {
  display: inline-block;
  margin-left: 5px;
  font-weight: 700;
  font-size: 12px;
}

.trend-arrow.up { color: var(--free); }
.trend-arrow.down { color: var(--none); }

/* ---------- "What changed" feed (sidebar) ---------- */

.changes-panel {
  border-bottom: 1px solid var(--border);
  padding-bottom: 14px;
}

.changes-summary {
  display: flex;
  flex-direction: column;
  gap: 1px;
  margin-top: 6px;
  font-size: 12px;
}

.changes-summary-week {
  margin-top: 2px;
  opacity: 0.75;
}

.changes-summary-week .changes-summary-net {
  font-weight: 500;
}

.changes-summary-net {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}

.changes-summary-net.up { color: var(--free); }
.changes-summary-net.down { color: var(--none); }

.changes-summary-detail {
  color: var(--muted);
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}

.changes-list {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-top: 4px;
  padding-top: 8px;
  border-top: 1px solid var(--border);
}

.change-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px;
  padding: 4px 0;
  color: inherit;
  font-size: 12px;
}

.change-row:hover .change-name { text-decoration: underline; }

.change-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.change-delta {
  flex: none;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.change-delta.up { color: var(--free); }
.change-delta.down { color: var(--none); }

.popup-photos {
  display: flex;
  gap: 4px;
  margin-top: 8px;
  overflow-x: auto;
}

.popup-photos img {
  width: 56px;
  height: 42px;
  object-fit: cover;
  border-radius: 4px;
  flex: none;
  display: block;
  border: 1px solid var(--border);
  background: linear-gradient(90deg, var(--border) 25%, var(--bg) 50%, var(--border) 75%);
  background-size: 200% 100%;
  animation: shimmer 1.4s ease-in-out infinite;
}

.popup-loading-skeleton {
  margin-top: 10px;
  padding-top: 8px;
  border-top: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.popup-history {
  margin-top: 10px;
  padding-top: 8px;
  border-top: 1px solid var(--border);
}

.popup-history-label {
  display: block;
  font-size: 11px;
  font-weight: 500;
  color: var(--muted);
  margin-bottom: 2px;
}

/* ---------- Feature tags (popup) + feature filter (sidebar) ---------- */

.popup-features {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-top: 8px;
}

.feature-tag {
  font-size: 11px;
  color: var(--muted);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 2px 8px;
}

.sidebar-details summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: center;
  gap: 5px;
}

.sidebar-details summary::-webkit-details-marker { display: none; }

.sidebar-details summary::before {
  content: "";
  width: 6px;
  height: 6px;
  border-right: 1.5px solid var(--muted);
  border-bottom: 1.5px solid var(--muted);
  transform: rotate(-45deg);
  transition: transform 0.15s ease;
  flex: none;
}

.sidebar-details[open] summary::before { transform: rotate(45deg); }

.feature-filters {
  display: flex;
  flex-direction: column;
  gap: 2px;
  max-height: 160px;
  overflow-y: auto;
  margin-top: 6px;
}

.feature-filter-item {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  padding: 3px 0;
  cursor: pointer;
}

.feature-filter-item input { accent-color: var(--accent); width: 14px; height: 14px; flex: none; }

/* ---------- Contact block (popup) ---------- */

.popup-contact {
  margin-top: 8px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.popup-contact-row {
  display: flex;
  gap: 6px;
  font-size: 12px;
}

.popup-contact-label {
  color: var(--muted);
  min-width: 62px;
  flex: none;
}

/* ---------- Sidebar footer ---------- */

.sidebar-footer {
  padding-top: 10px;
  border-top: 1px solid var(--border);
  font-size: 12px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.results-list {
  overflow-y: auto;
  max-height: 320px;
  display: flex;
  flex-direction: column;
  gap: 5px;
  margin-top: 6px;
}

.result-item {
  display: block;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  padding: 9px 10px;
  cursor: pointer;
  text-decoration: none;
  color: inherit;
  transition: background 0.12s ease, border-color 0.12s ease;
}

.result-item:hover {
  background: var(--bg);
  border-color: var(--border);
  text-decoration: none;
}

.result-name {
  font-weight: 500;
  font-size: 13px;
  color: var(--ink);
}

.result-address {
  font-size: 12px;
  color: var(--muted);
  margin-top: 1px;
}

.result-badge {
  display: inline-block;
  margin-top: 5px;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 600;
  padding: 2px 7px;
  border-radius: 4px;
}

/* Shared with .popup-badge below — same 3 status colors, same shape, just
   used in two different contexts (sidebar card vs. map popup). */
.result-badge.free, .popup-badge.free { color: var(--free); background: var(--free-bg); }
.result-badge.few, .popup-badge.few { color: var(--few); background: var(--few-bg); }
.result-badge.none, .popup-badge.none { color: var(--none); background: var(--none-bg); }
.result-badge.closure { color: var(--closed); background: var(--closed-bg); margin-left: 5px; }
.result-badge.new { color: var(--accent); background: var(--accent-weak); margin-left: 5px; }

/* ---------- Map ---------- */

.map-wrap {
  flex: 1;
  position: relative;
}

#map {
  width: 100%;
  height: 100%;
  background: var(--bg);
  /* Companion to initMap()'s tap:false (see map.js) — without this, some
     mobile browsers delay the native click ~300ms to watch for a
     double-tap-to-zoom gesture. If a popup's autoPan has already started
     moving the map by the time that delayed click lands, it can hit bare
     map instead of the marker/popup, triggering Leaflet's default
     click-on-map-closes-popup behavior — same "tap a pin, popup flashes
     and disappears" symptom tap:false alone didn't fully fix (reported
     again by user 2026-08-19 on a real phone after the first attempt). */
  touch-action: manipulation;
}

.map-empty {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(250, 250, 250, 0.92);
  font-size: 14px;
  color: var(--muted);
  z-index: 1000;
}

/* ---------- Loading state (first paint, before /api/data responds) ---------- */

.map-loading {
  display: none;
  position: absolute;
  inset: 0;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  background: var(--bg);
  color: var(--muted);
  font-size: 13px;
  z-index: 999;
}

body.is-loading .map-loading { display: flex; }

.map-loading-spinner {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 2.5px solid var(--border);
  border-top-color: var(--accent);
  animation: spin 0.8s linear infinite;
}

@keyframes spin { to { transform: rotate(360deg); } }

/* Generic shimmer skeleton — shared by topbar stats, popup "loading more"
   rows, and photo placeholders. One keyframe/gradient definition, applied
   via a couple of small utility classes so nothing here needs its own
   bespoke animation. */
@keyframes shimmer {
  0% { background-position: 150% 0; }
  100% { background-position: -50% 0; }
}

.skeleton-bar {
  display: block;
  height: 10px;
  border-radius: 4px;
  background: linear-gradient(90deg, var(--border) 25%, var(--bg) 50%, var(--border) 75%);
  background-size: 200% 100%;
  animation: shimmer 1.4s ease-in-out infinite;
}

.skeleton-thumb {
  flex: none;
  width: 56px;
  height: 42px;
  border-radius: 4px;
  background: linear-gradient(90deg, var(--border) 25%, var(--bg) 50%, var(--border) 75%);
  background-size: 200% 100%;
  animation: shimmer 1.4s ease-in-out infinite;
}

body.is-loading .stat-value {
  color: transparent;
  min-width: 40px;
  border-radius: 4px;
  background: linear-gradient(90deg, var(--border) 25%, var(--bg) 50%, var(--border) 75%);
  background-size: 200% 100%;
  animation: shimmer 1.4s ease-in-out infinite;
}

@media (prefers-reduced-motion: reduce) {
  .map-loading-spinner { animation: none; border-top-color: var(--border); }
  .skeleton-bar, .skeleton-thumb, body.is-loading .stat-value { animation: none; background: var(--border); }
}

/* Map marker: flat numbered pin, colored by vacancy status */

.zlobek-badge {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  border: 2px solid var(--surface);
  box-shadow: 0 1px 2px rgba(22, 24, 29, 0.18);
  color: #fff;
  font-family: var(--font-mono);
  font-weight: 600;
  font-size: 11px;
}

.zlobek-badge.free { background: var(--free); }
.zlobek-badge.few { background: var(--few); }
.zlobek-badge.none { background: var(--none); }

/* Small corner dot, not a full recolor — the free-places number underneath
   is still real (existing children keep their spot), it's the vacancy-status
   color that stays meaningful. The dot flags "not currently enrolling" as a
   separate fact layered on top. */
.zlobek-badge.has-closure::after {
  content: "";
  position: absolute;
  top: -2px;
  right: -2px;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--closed);
  border: 1.5px solid var(--surface);
}

/* Opposite corner from has-closure so a facility could in principle show
   both without the two dots overlapping (rare — newly added AND already
   ending — but not impossible). */
.zlobek-badge.is-new::before {
  content: "";
  position: absolute;
  top: -2px;
  left: -2px;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--accent);
  border: 1.5px solid var(--surface);
}

/* Cluster badge reuses the same shape/colors, just bigger (holds a summed
   total, sometimes 2-3 digits) and with a slightly heavier ring so it reads
   as "many pins collapsed here" rather than a single facility. */
.zlobek-badge.cluster {
  border-width: 3px;
  font-size: 13px;
}

.leaflet-popup-content-wrapper {
  font-family: var(--font-body);
  border-radius: var(--radius-md);
  box-shadow: 0 4px 16px rgba(22, 24, 29, 0.12);
}

.popup-name {
  font-weight: 600;
  font-size: 14px;
  margin: 0 0 2px;
}

.popup-address, .popup-district {
  font-size: 12px;
  color: var(--muted);
  margin: 0;
}

.popup-badge {
  display: inline-block;
  margin-top: 7px;
  font-family: var(--font-mono);
  font-weight: 600;
  font-size: 12px;
  padding: 3px 9px;
  border-radius: 5px;
}

.popup-updated {
  margin: 6px 0 0;
  font-size: 12px;
  color: var(--muted);
}

.closure-notice {
  margin: 8px 0 0;
  font-size: 12px;
  font-weight: 600;
  color: var(--closed);
  background: var(--closed-bg);
  padding: 6px 9px;
  border-radius: var(--radius-sm);
}

.new-facility-notice {
  margin: 8px 0 0;
  font-size: 12px;
  font-weight: 600;
  color: var(--accent);
  background: var(--accent-weak);
  padding: 6px 9px;
  border-radius: var(--radius-sm);
}

/* .popup-badge.{free,few,none} colors live above, combined with .result-badge's */

.popup-link {
  display: inline-block;
  margin-top: 8px;
  font-size: 12px;
}

/* ---------- Responsive ---------- */

@media (max-width: 700px) {
  .layout { flex-direction: column; }
  /* 40%/flex:1 of `.layout`'s own (already topbar-subtracted) height, not
     40vh/60vh of the full viewport — raw vh here previously ignored the
     topbar entirely, so on real phones (topbar wraps to ~150px, not the
     desktop's single-line ~66px) the sidebar+map combo added up to
     100vh + ~150px, pushing the bottom of the map below the fold. */
  .sidebar { width: 100%; max-height: 40%; }
  .map-wrap { flex: 1; min-height: 0; }
  .topbar-stats { gap: 18px; }

  /* Leaflet's default zoom buttons are ~30x30px — under the ~44px minimum
     recommended touch target, easy to miss on a phone. */
  .leaflet-control-zoom a {
    width: 40px !important;
    height: 40px !important;
    line-height: 40px !important;
    font-size: 18px !important;
  }
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; }
}

/* ---------- Facility page (SEO landing page, /zlobek/<id>) ---------- */

.brand-title {
  margin: 0;
  font-weight: 600;
  font-size: 17px;
  letter-spacing: -0.01em;
}

.brand-title a { color: var(--ink); }
.brand-title a:hover { color: var(--accent); text-decoration: none; }

.facility-page {
  max-width: 720px;
  margin: 0 auto;
  padding: 28px 20px 60px;
}

.breadcrumbs {
  display: flex;
  gap: 8px;
  font-size: 13px;
  color: var(--muted);
  margin-bottom: 18px;
}

.breadcrumbs span[aria-hidden] { color: var(--border); }

.facility-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 24px;
}

.facility-name {
  font-size: 24px;
  font-weight: 600;
  margin: 0 0 4px;
  letter-spacing: -0.01em;
}

.facility-address {
  font-style: normal;
  color: var(--muted);
  font-size: 14px;
  margin-bottom: 12px;
  display: block;
}

.facility-badge { font-size: 14px; padding: 4px 12px; }

.facility-map-link {
  display: inline-block;
  margin-left: 10px;
  font-size: 13px;
}

.facility-updated {
  margin: 8px 0 0;
  font-size: 12px;
  color: var(--muted);
}

.occupancy {
  margin-top: 14px;
  max-width: 320px;
}

.occupancy-bar {
  height: 6px;
  border-radius: 999px;
  background: var(--border);
  overflow: hidden;
}

.occupancy-fill {
  height: 100%;
  background: var(--accent);
  border-radius: 999px;
}

.occupancy-label {
  display: block;
  margin-top: 6px;
  font-size: 12px;
  color: var(--muted);
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}

.facility-features { margin-top: 16px; }

.photo-gallery {
  margin-top: 16px;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
  gap: 8px;
}

.photo-gallery img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: var(--radius-sm);
  display: block;
  border: 1px solid var(--border);
  /* Shimmers through until the image itself has decoded and painted over it —
     these load from nabor.pcss.pl, not our own static/, so worth a visible
     placeholder rather than a blank box on a slow connection. Pure CSS, no
     onload JS needed: the background just stops being visible once the <img>
     content covers it. */
  background: linear-gradient(90deg, var(--border) 25%, var(--bg) 50%, var(--border) 75%);
  background-size: 200% 100%;
  animation: shimmer 1.4s ease-in-out infinite;
}

/* ---------- Lightbox (shared: map popup + facility gallery, lightbox.js) ---------- */

.lightbox-overlay {
  position: fixed;
  inset: 0;
  background: rgba(10, 10, 12, 0.88);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 48px 20px;
  z-index: 10000;
}

.lightbox-img {
  max-width: 100%;
  max-height: 80vh;
  border-radius: var(--radius-sm);
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
}

.lightbox-caption {
  color: #fff;
  font-size: 13px;
  margin: 0;
  text-align: center;
}

.lightbox-close {
  position: absolute;
  top: 14px;
  right: 18px;
  background: none;
  border: none;
  color: #fff;
  font-size: 26px;
  line-height: 1;
  cursor: pointer;
  padding: 10px;
}

.facility-contact {
  margin: 20px 0 0;
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 8px 16px;
}

.facility-contact dt {
  color: var(--muted);
  font-size: 13px;
}

.facility-contact dd {
  margin: 0;
  font-size: 13px;
}

/* `max-content` on the dt column never wraps by definition — fine for short
   labels like "Kierownik", but "Godziny przyjmowania kierownika" (32 chars)
   forces the column past what a phone screen has room for, overflowing the
   whole page horizontally (measured live: 468px scrollWidth on a 375px
   viewport). Stack dt above dd instead of trying to cap the column width —
   any future long label is safe this way, not just today's. */
@media (max-width: 700px) {
  .facility-contact {
    grid-template-columns: 1fr;
    gap: 0;
  }
  .facility-contact dt {
    margin-top: 10px;
  }
  .facility-contact dt:first-child {
    margin-top: 0;
  }
}

.facility-links {
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid var(--border);
  display: flex;
  gap: 20px;
  font-size: 13px;
}

.history-section {
  margin-top: 28px;
}

.history-section h2 {
  font-size: 15px;
  font-weight: 600;
  margin: 0 0 10px;
}

.history-table {
  width: 100%;
  border-collapse: collapse;
  margin-top: 14px;
  font-size: 13px;
}

.history-table th {
  text-align: left;
  color: var(--muted);
  font-weight: 500;
  padding: 6px 8px;
  border-bottom: 1px solid var(--border);
}

.history-table td {
  padding: 6px 8px;
  border-bottom: 1px solid var(--border);
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}

.history-run-count {
  color: var(--muted);
  font-size: 12px;
}

/* ---------- 404 page ---------- */

.error-page {
  max-width: 480px;
  margin: 12vh auto 0;
  padding: 0 20px;
  text-align: center;
}

.error-page h1 { font-size: 22px; margin-bottom: 8px; }
.error-page p { color: var(--muted); margin-bottom: 20px; }
