/* Faro — mobile-first, no framework. Kept small for the 3G / <500KB budget.
   The visual system and every token below are documented in docs/DESIGN.md.
   Palette follows Google Material so the app reads as familiar and modern.
   Rule: components reference tokens; no raw hex outside the token blocks. */

/* ---- Tokens (light) --------------------------------------------------------------- */
:root {
  --surface: #ffffff;
  --surface-raised: #ffffff;
  --surface-sunken: #f1f3f4;
  --text: #202124;
  --muted: #5f6368;
  --border: #dadce0;
  --overlay: rgba(32, 33, 36, 0.5);

  --brand: #2563eb;
  --brand-fg: #ffffff;
  --official: #1967d2;
  --official-fg: #ffffff;

  /* Fixed marker/accent colours — deliberately NOT overridden in the dark blocks, so the FAB,
     the announcement chip and the map markers stay the SAME colour in light and dark (they sit
     on the map or carry their own fill, not the page background). */
  --report-red: #d93025;    /* report triangles + "Report a problem" FAB */
  --report-red-fg: #ffffff;
  --announce-blue: #2563eb;  /* announcement chip + announcement circle pins */
  --announce-blue-fg: #ffffff;
  --shelter-green: #1e9e4a;  /* shelter/resource square outline */
  --pin-bg: #f4f5f6;         /* pin fill — a light grey in BOTH themes so glyphs stay legible */
  --pin-fg: #202124;         /* pin glyph colour (monochrome-emoji fallback), dark in both themes */

  /* Emergency banner uses --report-red (see .banner) so it matches the "Report a problem"
     button exactly — one red across the app. Fixed in both themes: it's a safety signal. */

  --danger: #d33a4a;
  --danger-fg: #ffffff;
  --danger-soft-bg: #fdecee;
  --danger-soft-fg: #b3243b;
  --danger-glow: rgba(211, 58, 74, 0.45);
  --warning-bg: #fef7e0;
  --warning-fg: #a05100;
  --success: #1e8e3e;
  --success-bg: #e6f4ea;
  --success-fg: #137333;
  --info-bg: #e8f0fe;
  --info-fg: #1967d2;
  --review-bg: #f3e8fd;
  --review-fg: #8430ce;

  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;

  --radius-sm: 10px;
  --radius-md: 18px;
  --radius-pill: 999px;

  --text-xs: 0.72rem;
  --text-sm: 0.82rem;
  --text-base: 0.95rem;
  --text-md: 1.05rem;
  --text-lg: 1.25rem;
  --text-xl: 1.9rem;

  /* Material-style elevation: soft, grey-tinted, layered. */
  --shadow-sm: 0 1px 2px rgba(60, 64, 67, 0.3), 0 1px 3px 1px rgba(60, 64, 67, 0.12);
  --shadow-md: 0 1px 3px rgba(60, 64, 67, 0.3), 0 4px 8px 3px rgba(60, 64, 67, 0.13);
  --shadow-lg: 0 -1px 3px rgba(60, 64, 67, 0.1), 0 -6px 20px rgba(60, 64, 67, 0.2);
}

/* Dark tokens live in one snippet applied two ways: via prefers-color-scheme (when the user
   hasn't overridden), and via [data-theme="dark"] (when they pick Dark). No build step means
   the block is duplicated rather than shared — keep the two copies in sync. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --surface: #292a2e;
    --surface-raised: #363739;
    --surface-sunken: #202124;
    --text: #e8eaed;
    --muted: #a6abb0;
    --border: #494c50;
    --overlay: rgba(0, 0, 0, 0.55);

    --brand: #8fabf7;
    --brand-fg: #202124;
    --official: #aecbfa;
    --official-fg: #202124;

    --danger: #f5959b;
    --danger-fg: #202124;
    --danger-soft-bg: #2d1a18;
    --danger-soft-fg: #f6aea9;
    --danger-glow: rgba(245, 149, 155, 0.45);
    --warning-bg: #3a2f14;
    --warning-fg: #fdd663;
    --success: #81c995;
    --success-bg: #1c2b1f;
    --success-fg: #a8dab5;
    --info-bg: #1a2a42;
    --info-fg: #8ab4f8;
    --review-bg: #2a1e37;
    --review-fg: #d7aefb;

    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.6), 0 1px 3px 1px rgba(0, 0, 0, 0.4);
    --shadow-md: 0 1px 3px rgba(0, 0, 0, 0.6), 0 4px 8px 3px rgba(0, 0, 0, 0.4);
    --shadow-lg: 0 -1px 3px rgba(0, 0, 0, 0.4), 0 -6px 20px rgba(0, 0, 0, 0.55);
  }
}
:root[data-theme="dark"] {
  --surface: #292a2e;
  --surface-raised: #363739;
  --surface-sunken: #202124;
  --text: #e8eaed;
  --muted: #a6abb0;
  --border: #494c50;
  --overlay: rgba(0, 0, 0, 0.55);

  --brand: #8fabf7;
  --brand-fg: #202124;
  --official: #aecbfa;
  --official-fg: #202124;

  --danger: #f5959b;
  --danger-fg: #202124;
  --danger-soft-bg: #2d1a18;
  --danger-soft-fg: #f6aea9;
  --danger-glow: rgba(245, 149, 155, 0.45);
  --warning-bg: #3a2f14;
  --warning-fg: #fdd663;
  --success: #81c995;
  --success-bg: #1c2b1f;
  --success-fg: #a8dab5;
  --info-bg: #1a2a42;
  --info-fg: #8ab4f8;
  --review-bg: #2a1e37;
  --review-fg: #d7aefb;

  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.6), 0 1px 3px 1px rgba(0, 0, 0, 0.4);
  --shadow-md: 0 1px 3px rgba(0, 0, 0, 0.6), 0 4px 8px 3px rgba(0, 0, 0, 0.4);
  --shadow-lg: 0 -1px 3px rgba(0, 0, 0, 0.4), 0 -6px 20px rgba(0, 0, 0, 0.55);
}

/* ---- Base ------------------------------------------------------------------------- */
* { box-sizing: border-box; }
html, body { height: 100%; margin: 0; }
body {
  display: flex;
  flex-direction: column;
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  color: var(--text);
  background: var(--surface);
}
.hidden { display: none !important; }

/* ---- Permanent disclaimer banner -------------------------------------------------- */
.banner {
  background: var(--report-red);   /* same red as the "Report a problem" button, for consistency */
  color: var(--report-red-fg);
  padding: var(--space-2) var(--space-3);
  font-size: 0.86rem;
  font-weight: 500;
  line-height: 1.35;
  text-align: center;
  letter-spacing: 0.1px;
  z-index: 1000;
}

/* ---- Map -------------------------------------------------------------------------- */
.map {
  flex: 1 1 auto;
  min-height: 0;
  position: relative;
}

/* Dark mode: lift the basemap a touch so it reads as a lighter dark, not near-black.
   Only the tile pane is affected — pins, circles and controls live in other panes, so their
   colours stay true. Never applied in Light mode. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .leaflet-tile-pane { filter: brightness(1.18) contrast(0.97); }
}
:root[data-theme="dark"] .leaflet-tile-pane { filter: brightness(1.18) contrast(0.97); }
/* Light: Stadia's light style paints water/parks very pale and its streets/buildings very faint.
   saturate() only touches coloured pixels (deepening water to blue and parks to green while
   leaving the neutral greys/whites of the ground alone); the small contrast() bump lifts the grey
   street and building lines so they read against the near-white ground. Scoped to mirror the dark
   rules so the two never both apply. */
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) .leaflet-tile-pane { filter: saturate(1.55) contrast(1.12); }
}
:root[data-theme="light"] .leaflet-tile-pane { filter: saturate(1.55) contrast(1.12); }

/* The map controls (Leaflet zoom) get a Material treatment to match. */
.leaflet-bar {
  border: none !important;
  box-shadow: var(--shadow-sm) !important;
  border-radius: var(--radius-sm) !important;
  overflow: hidden;
}
.leaflet-bar a {
  background: var(--surface-raised) !important;
  color: var(--text) !important;
  border-color: var(--border) !important;
}
.leaflet-control-attribution {
  background: color-mix(in srgb, var(--surface-raised) 82%, transparent) !important;
  color: var(--muted) !important;
}
.leaflet-control-attribution a { color: var(--brand) !important; }

/* ---- Pins: SHAPE = kind, COLOR = status (docs/DESIGN.md §5) ------------------------ */
/* Reports = triangle (red active / neutral disputed) · resources = pink square ·
   announcements = blue circle. Reports are the smallest; the other two are larger so
   official posts and places stand out over the many citizen reports. A white/raised fill
   with a coloured outline and a category glyph in the middle across all three. */

/* Report = triangle (inline SVG so the outline is themeable), red outline, category glyph in the
   middle. The smallest of the three, but sized so the glyph is legible. Light-grey fill in both
   themes. The SVG is an absolute backdrop (z 0); the glyph is grid-centred above it (z 1) and
   nudged down into the wider lower half of the triangle. */
/* position:absolute is required — Leaflet transforms the marker to its lat/lng via translate3d,
   which only lands on the anchor point when the element is out of flow. With position:relative the
   translate stacked on top of the element's normal-flow offset, dropping the triangle ~14px below
   its circle (and by a per-marker amount), which is what made pins look off-centre when zooming. */
.report-pin { position: absolute; display: grid; place-items: center; width: 40px; height: 38px; filter: drop-shadow(var(--shadow-sm)); }
.report-pin .pin-shape { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; z-index: 0; }
.report-pin .pin-shape path { fill: var(--pin-bg); stroke: var(--report-red); stroke-width: 2.5; stroke-linejoin: round; }
.report-pin .pin-glyph { position: relative; z-index: 1; margin-top: 5px; font-size: 16px; line-height: 1; color: var(--pin-fg); }
/* Disputed = neutral outline + faded (fades, never deleted). Reads as inactive. */
.report-pin.is-disputed .pin-shape path { stroke: var(--muted); }
.report-pin.is-disputed { opacity: 0.65; }
/* Queued offline: dashed neutral outline, visibly "not sent yet". */
.report-pin.is-pending .pin-shape path { stroke: var(--muted); stroke-dasharray: 3 3; }
.report-pin.is-pending { opacity: 0.7; }

/* Resource = rounded square, green outline, larger than report triangles. */
.resource-pin {
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  font-size: 23px;
  color: var(--pin-fg);
  background: var(--pin-bg);
  border: 2.5px solid var(--shelter-green);
  border-radius: 11px;
  box-shadow: var(--shadow-sm);
}
.resource-pin.is-stale { border-color: var(--muted); opacity: 0.55; }

/* Announcement = circle, blue outline, larger than report triangles. */
.announcement-pin {
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  font-size: 23px;
  color: var(--pin-fg);
  background: var(--pin-bg);
  border: 2.5px solid var(--announce-blue);
  border-radius: 50%;
  box-shadow: var(--shadow-sm);
}

/* Approximate-location circle drawn around every report (reports are not GPS-exact).
   Red for active, neutral for disputed — matching the pin. Selected report's ring emphasised. */
.report-circle { stroke: var(--report-red); fill: var(--report-red); fill-opacity: 0.12; stroke-opacity: 0.6; stroke-width: 1.5; }
.report-circle.is-disputed { stroke: var(--muted); fill: var(--muted); }
.report-circle.is-selected { fill-opacity: 0.2; stroke-opacity: 0.85; stroke-width: 2.5; }

/* ---- Map overlays: chip, Map button, legend, last-updated, empty ------------------ */
/* Announcement chip: top-centre pill, clearing the zoom control (left) and Map button (right). */
.announcement-chip {
  position: absolute;
  top: var(--space-2);
  left: 50%;
  transform: translateX(-50%);
  z-index: 600;
  max-width: calc(100% - 170px);
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-2) var(--space-3);
  background: var(--announce-blue); /* same blue in light and dark */
  color: var(--announce-blue-fg);
  border: none;
  border-radius: var(--radius-pill);
  font: inherit;
  font-size: var(--text-sm);
  font-weight: 600;
  line-height: 1.2;
  box-shadow: var(--shadow-md);
  cursor: pointer;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Nothing active: a quiet, non-interactive pill so it reads as status, not a call to action. */
.announcement-chip.is-empty {
  background: var(--surface-raised);
  color: var(--muted);
  font-weight: 500;
  box-shadow: var(--shadow-sm);
  cursor: default;
}

/* App version — tiny, muted, bottom-left corner. Sits above tiles, out of the way of the
   attribution (bottom-right) and the FAB (bottom-centre). Non-interactive. */
.app-version {
  position: absolute;
  left: var(--space-2);
  bottom: var(--space-1);
  z-index: 500;
  padding: 1px 6px;
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--surface-raised) 70%, transparent);
  color: var(--muted);
  font-size: 11px;
  line-height: 1.5;
  letter-spacing: 0.2px;
  pointer-events: none;
  user-select: none;
}

/* "Updated Nm ago" — small, muted, top-centre under the chip so the FAB never hides it. */
.last-updated {
  position: absolute;
  top: 46px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 500;
  padding: 2px var(--space-2);
  font-size: var(--text-xs);
  line-height: 1.4;
  color: var(--muted);
  background: color-mix(in srgb, var(--surface-raised) 88%, transparent);
  border-radius: var(--radius-pill);
  box-shadow: var(--shadow-sm);
  pointer-events: none;
  white-space: nowrap;
}

/* Map button (was "Key"): opens the map key + theme control. Top-right, Material pill. */
.legend-toggle {
  position: absolute;
  top: var(--space-2);
  right: var(--space-2);
  z-index: 600;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 40px;
  padding: var(--space-2) var(--space-3);
  background: var(--surface-raised);
  color: var(--text);
  border: none;
  border-radius: var(--radius-pill);
  font-size: var(--text-sm);
  font-weight: 600;
  box-shadow: var(--shadow-sm);
  cursor: pointer;
}
.legend-toggle svg { width: 16px; height: 16px; fill: currentColor; }

.legend-panel {
  position: absolute;
  top: 52px;
  right: var(--space-2);
  z-index: 600;
  width: 210px;
  max-width: calc(100% - 16px);
  padding: var(--space-3);
  background: var(--surface-raised);
  color: var(--text);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-md);
  font-size: var(--text-sm);
}
.legend-panel h2 { margin: 0 0 var(--space-2); font-size: var(--text-sm); }

/* Segmented theme control. */
.seg {
  display: flex;
  gap: 2px;
  padding: 3px;
  margin-bottom: var(--space-3);
  background: var(--surface-sunken);
  border-radius: var(--radius-pill);
}
.seg-btn {
  flex: 1 1 0;
  min-height: 32px;
  padding: 4px 6px;
  border: none;
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--muted);
  font: inherit;
  font-size: var(--text-xs);
  font-weight: 600;
  cursor: pointer;
}
.seg-btn.is-on { background: var(--surface-raised); color: var(--brand); box-shadow: var(--shadow-sm); }

.legend-row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: 6px;
  line-height: 1.3;
}
/* Legend swatches: filled mini-shapes that mirror the pins (shape = kind, colour = status). */
.legend-swatch {
  flex: 0 0 auto;
  width: 16px;
  height: 16px;
  border: none;
}
.legend-swatch.tri { background: var(--report-red); clip-path: polygon(50% 0, 100% 100%, 0 100%); }
.legend-swatch.tri.dis { background: var(--muted); }
.legend-swatch.sq { background: var(--shelter-green); border-radius: 4px; }
.legend-swatch.circle { background: var(--announce-blue); border-radius: 50%; }
.legend-foot {
  margin: var(--space-2) 0 0;
  padding-top: var(--space-2);
  border-top: 1px solid var(--border);
  font-size: var(--text-xs);
  color: var(--muted);
}
.legend-foot a { color: var(--brand); }

.map-empty {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 550;
  max-width: 80%;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-3) var(--space-3) var(--space-4);
  background: var(--surface-raised);
  color: var(--muted);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-sm);
  font-size: var(--text-base);
  text-align: center;
  pointer-events: auto;
}
.map-empty-text { flex: 1; }
.map-empty-close {
  flex: none;
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  padding: 0;
  border: 0;
  border-radius: var(--radius-pill);
  background: var(--surface-sunken);
  color: var(--muted);
  font-size: 13px;
  line-height: 1;
  cursor: pointer;
}
.map-empty-close:hover { background: var(--border); color: var(--text); }
/* The shimmer placeholder has no children and shouldn't reserve the flex gap. */
.map-empty.is-loading { display: block; }
.map-empty.is-loading {
  color: transparent;
  background:
    linear-gradient(90deg, var(--surface-sunken) 25%, var(--border) 37%, var(--surface-sunken) 63%);
  background-size: 400% 100%;
  animation: faro-shimmer 1.4s ease infinite;
  min-width: 180px;
  min-height: 44px;
}
@keyframes faro-shimmer {
  0% { background-position: 100% 0; }
  100% { background-position: 0 0; }
}

/* ---- Floating action button ------------------------------------------------------- */
.fab {
  position: fixed;
  left: 50%;
  bottom: var(--space-4);
  transform: translateX(-50%);
  z-index: 1000;
  min-height: 52px;
  background: var(--report-red); /* red, matching the report triangles on the map */
  color: var(--report-red-fg);
  border: none;
  border-radius: var(--radius-pill);
  padding: var(--space-3) var(--space-5);
  font-size: 1rem;
  font-weight: 600;
  box-shadow: var(--shadow-md);
  cursor: pointer;
}

/* ---- Bottom-sheet panel + scrim --------------------------------------------------- */
.scrim {
  position: fixed;
  inset: 0;
  z-index: 1000;
  background: var(--overlay);
}
.panel {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 1001;
  background: var(--surface-raised);
  color: var(--text);
  border-top-left-radius: var(--radius-md);
  border-top-right-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  max-height: 80vh;
  overflow-y: auto;
}
.sheet-handle {
  width: 36px;
  height: 4px;
  margin: var(--space-2) auto 0;
  border-radius: var(--radius-pill);
  background: var(--border);
}
.sheet-close {
  position: absolute;
  top: var(--space-2);
  right: var(--space-2);
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  background: transparent;
  border: none;
  border-radius: 50%;
  color: var(--muted);
  font-size: 1.1rem;
  cursor: pointer;
}
.panel-body { padding: var(--space-3) var(--space-4) calc(var(--space-4) + env(safe-area-inset-bottom)); }

.panel-title { margin: 0 0 var(--space-3); padding-right: var(--space-6); font-size: var(--text-md); font-weight: 600; }
.panel-title.danger { color: var(--danger); }

.prompt { margin: 0 0 var(--space-4); font-size: var(--text-base); line-height: 1.4; }

.anon-note {
  margin: 0 0 var(--space-4);
  padding: var(--space-2) var(--space-3);
  background: var(--surface-sunken);
  border-radius: var(--radius-sm);
  color: var(--muted);
  font-size: var(--text-sm);
  line-height: 1.4;
}

.row { display: flex; gap: var(--space-2); flex-wrap: wrap; }

/* ---- Buttons (Material: pill, filled primary, tonal secondary) -------------------- */
.btn {
  flex: 1 1 auto;
  min-width: 8rem;
  min-height: 44px;
  padding: var(--space-3) var(--space-4);
  font-size: 1rem;
  font-weight: 500;
  border: none;
  border-radius: var(--radius-pill);
  background: var(--surface-sunken);
  color: var(--text);
  text-align: center;
  text-decoration: none;
  cursor: pointer;
}
.btn-primary { background: var(--brand); color: var(--brand-fg); }
.btn-danger { background: var(--danger); color: var(--danger-fg); }
.btn:disabled { opacity: 0.5; cursor: default; }
.btn-share { flex: 0 0 auto; min-width: 0; }

/* ---- Category chooser grid -------------------------------------------------------- */
.cat-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-2);
  margin-bottom: var(--space-4);
}
.cat {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 48px;
  padding: var(--space-3);
  font-size: var(--text-base);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-raised);
  color: var(--text);
  cursor: pointer;
  text-align: left;
}
.cat-symbol { font-size: 1.2rem; line-height: 1; }

/* ---- Inputs ----------------------------------------------------------------------- */
.desc-label { display: block; margin-bottom: var(--space-1); font-size: var(--text-base); }
.desc {
  width: 100%;
  padding: var(--space-3);
  font: inherit;
  color: var(--text);
  background: var(--surface-sunken);
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  margin-bottom: var(--space-4);
  resize: vertical;
}
.desc:focus { outline: none; border-color: var(--brand); background: var(--surface-raised); }
.desc::placeholder { color: var(--muted); }

/* ---- Toasts ----------------------------------------------------------------------- */
.toast {
  position: fixed;
  left: 50%;
  bottom: 5rem;
  transform: translateX(-50%);
  z-index: 1002;
  max-width: 90vw;
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-sm);
  color: #fff;
  font-size: var(--text-base);
  text-align: center;
  box-shadow: var(--shadow-md);
}
.toast-ok { background: var(--success); }
.toast-error { background: var(--danger); }

/* ---- Boot fallback (colours pinned so it survives even if tokens never resolve) --- */
.boot-fallback {
  display: flex;
  flex-direction: column;
  justify-content: center;
  height: 100%;
  padding: var(--space-5);
  text-align: center;
  background: #ffffff;
  color: #1a1a1a;
  font-size: var(--text-base);
  line-height: 1.5;
}
.boot-fallback p { margin: 0 0 var(--space-2); }
.boot-fallback-title { font-size: var(--text-md); font-weight: 600; }
.boot-fallback-hint { font-size: var(--text-sm); color: #666; }
.boot-fallback a { color: #d93025; }

/* ---- Contact + address lines ------------------------------------------------------ */
.contact-line { margin: var(--space-1) 0 0; font-size: 0.88rem; line-height: 1.4; color: var(--text); }
.contact-line a { color: var(--brand); text-decoration: none; }

/* ---- Announcement list items ------------------------------------------------------ */
.announcement {
  padding: var(--space-3);
  margin-bottom: var(--space-2);
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}
.announcement.is-expired { opacity: 0.55; }
.announcement.is-resource { border-left: 3px solid var(--success); }
.announcement-title { margin: 0 0 var(--space-1); font-size: 1rem; }
.announcement-body { margin: 0 0 var(--space-1); font-size: 0.92rem; line-height: 1.4; }

/* ---- Report detail sheet ---------------------------------------------------------- */
.detail-head { margin-bottom: var(--space-2); }
.detail-meta {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  flex-wrap: wrap;
  margin-top: calc(-1 * var(--space-1));
}
.detail-time { font-size: 0.8rem; color: var(--muted); }
.detail-desc { margin: var(--space-2) 0 var(--space-4); font-size: var(--text-base); line-height: 1.4; }

.badge {
  display: inline-block;
  padding: 0.15rem var(--space-2);
  border-radius: var(--radius-pill);
  font-size: var(--text-xs);
  font-weight: 600;
}
.badge-active { background: var(--info-bg); color: var(--info-fg); }
.badge-disputed { background: var(--surface-sunken); color: var(--muted); }
.badge-resolved { background: var(--success-bg); color: var(--success-fg); }
.badge-stale { background: var(--warning-bg); color: var(--warning-fg); }
.badge-flagged { background: var(--review-bg); color: var(--review-fg); }

.vote-btn { font-size: var(--text-base); }
.hint { margin: var(--space-2) 0 0; font-size: var(--text-sm); color: var(--muted); }

.section-title { margin: var(--space-5) 0 var(--space-2); font-size: var(--text-base); }
.comment-list { list-style: none; margin: 0 0 var(--space-3); padding: 0; }
.comment { padding: var(--space-2); margin-bottom: var(--space-1); background: var(--surface-sunken); border-radius: var(--radius-sm); }
.comment-body { margin: 0 0 var(--space-1); font-size: 0.9rem; line-height: 1.35; word-break: break-word; }
.comment-time { font-size: var(--text-xs); color: var(--muted); }

.error-text { margin: var(--space-2) 0 0; font-size: var(--text-sm); color: var(--danger); }
.error-box {
  margin: var(--space-3) 0 0;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--danger);
  border-left-width: 4px;
  border-radius: 6px;
  background: var(--danger-soft-bg);
  color: var(--danger-soft-fg);
  font-size: 0.88rem;
  line-height: 1.4;
}

/* ---- Landing page (mifaro.net apex) ----------------------------------------------- */
.landing {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-6) var(--space-5);
  max-width: 34rem;
  margin: 0 auto;
  text-align: center;
  overflow-y: auto;
}
.landing-title { margin: var(--space-2) 0 0; font-size: var(--text-xl); color: var(--official); }
.landing-tagline { margin: 0; font-size: 1rem; line-height: 1.5; color: var(--muted); }
.landing-choose { margin: var(--space-5) 0 var(--space-1); font-size: 1rem; color: var(--muted); font-weight: 600; }
.landing-cities { display: flex; flex-direction: column; gap: var(--space-2); width: 100%; max-width: 22rem; }
.landing .landing-city {
  display: block;
  min-height: 44px;
  padding: var(--space-3) var(--space-4);
  background: var(--brand);
  color: var(--brand-fg);
  border-radius: var(--radius-sm);
  font-size: var(--text-md);
  font-weight: 600;
  text-decoration: none;
  box-shadow: var(--shadow-sm);
}

/* ---- Officials console (official.html only) --------------------------------------- */
.official-page { background: var(--surface-sunken); }
.banner-official { background: var(--official); color: var(--official-fg); }
.console {
  flex: 1 1 auto;
  width: 100%;
  max-width: 42rem;
  margin: 0 auto;
  padding: var(--space-4) var(--space-4) var(--space-6);
  overflow-y: auto;
}
/* Top bar: title + who's signed in on the left, sign-out on the right. */
.console-topbar {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}
.console-topbar .btn { flex: 0 0 auto; min-width: 0; }
.console-h1 { margin: 0; font-size: var(--text-lg); font-weight: 600; }
.console-sub { margin: 2px 0 0; font-size: var(--text-sm); color: var(--muted); }
.console-foot { margin: var(--space-2) 0 0; font-size: var(--text-sm); color: var(--muted); text-align: center; }

/* Each area of the console is a card, so sections read as distinct at a glance. */
.card {
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: var(--space-4);
  margin-bottom: var(--space-4);
  box-shadow: var(--shadow-sm);
}
.card-title { margin: 0 0 var(--space-1); font-size: var(--text-md); font-weight: 600; }
.card-hint { margin: 0 0 var(--space-3); font-size: var(--text-sm); color: var(--muted); line-height: 1.4; }
.card .desc { margin-bottom: 0; }

/* A labelled field: label above its input, consistent spacing. */
.field { margin-bottom: var(--space-3); }
.field:last-of-type { margin-bottom: 0; }
.field-label { display: block; margin-bottom: 6px; font-size: var(--text-sm); font-weight: 600; color: var(--text); }

.list-title { margin: var(--space-2) 0 var(--space-3); font-size: var(--text-md); font-weight: 600; }
.anchor-label { display: flex; align-items: center; gap: var(--space-2); margin: 0 0 var(--space-2); font-size: var(--text-sm); }
.picker-map { height: 220px; border: 1px solid var(--border); border-radius: var(--radius-sm); margin-bottom: var(--space-1); }

/* ---- Motion preference ------------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  .map-empty.is-loading { animation: none; }
}
