/* ===========================================================================
 * PZ Map — "Liquid Glass" UI tokens (frosted-glass panels, Inter font,
 * letter-spacing).
 *
 * The theme (light/dark) is switched via a class on <body> (theme-light /
 * theme-dark, see web/js/app.js -> applyThemeClass()/setTheme()) and only
 * changes the glass/text/ink-rgb/label/switch-track variables — the "dark
 * glass" of the bottom markers pill (dark- variables) does NOT depend on the
 * theme (it's always dark).
 *
 * Section 4 (cells) in app.js keeps a separate JS THEME{} palette for
 * Leaflet's canvas layers (buildings, streets, water, forest) — Leaflet
 * path styles don't understand var(), so they need a parallel JS palette.
 * ======================================================================== */

/* Self-hosted Inter (variable font, weights 100-900) — see web/vendor/inter/.
   No CDN/Google Fonts request; font-display:swap avoids a render-blocking wait. */
@font-face {
  font-family: "Inter";
  src: url("../vendor/inter/InterVariable.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

:root {
  /* Color-emoji fonts are appended explicitly: with a self-hosted webfont
     first in the stack, Windows Chrome otherwise resolves emoji codepoints
     against plain "Segoe UI" (monochrome placeholder glyphs) before ever
     reaching the system color-emoji font. */
  --font-family: "Inter", -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI",
    "Segoe UI Emoji", "Apple Color Emoji", "Noto Color Emoji", sans-serif;
  --font-emoji: "Segoe UI Emoji", "Apple Color Emoji", "Noto Color Emoji", sans-serif;

  /* Liquid Glass — light theme (default). Edge: a thin dark hairline
     outline on the outside, a white glow — inset on top. The background is cool gray. */
  --glass-bg: rgba(247, 248, 250, 0.62);
  --glass-edge: rgba(15, 20, 30, 0.09);
  --glass-blur: blur(36px) saturate(1.5) brightness(1.05);
  --glass-shadow:
    inset 0 1px 0 rgba(255,255,255,.5),
    inset 0 0 12px rgba(255,255,255,.22),
    0 1px 1px rgba(10,14,20,.05),
    0 8px 24px rgba(10,14,20,.13),
    0 24px 64px rgba(10,14,20,.10);
  /* Compact shadow for small pills (chips): the panel-scale 24px/64px layers
     look wrong on a 42px pill and their extents (88px down, 64px sideways)
     never fit the scroll container's padding — see .chips. */
  --chip-shadow:
    inset 0 1px 0 rgba(255,255,255,.5),
    inset 0 0 12px rgba(255,255,255,.22),
    0 1px 2px rgba(10,14,20,.10),
    0 6px 16px rgba(10,14,20,.16);

  /* dark glass — bottom markers pill, always dark (both themes) */
  --dark-bg: rgba(18, 18, 21, 0.78);
  --dark-edge: rgba(255, 255, 255, 0.12);
  --dark-blur: blur(24px) saturate(1.5);
  --dark-shadow: inset 0 1px 0 rgba(255,255,255,.08), 0 8px 28px rgba(0,0,0,.35);
  --dark-text: rgba(240, 240, 245, 0.92);
  --dark-dim: rgba(240, 240, 245, 0.52);

  --text: #17181a;
  --text-dim: rgba(23,24,26,.55);
  --ink-rgb: 23,24,26;           /* for rgba(var(--ink-rgb), alpha), so ink-tinted colors stay themeable */

  --accent: #007aff;
  --accent-dark: #0a84ff;
  --accent-fg: #ffffff;
  --uncat: #6b7280;

  --input-bg: rgba(120, 120, 128, 0.08);
  --btn-border: rgba(0, 0, 0, 0.08);
  --switch-track: rgba(0, 0, 0, .14);

  --badge-spoiler-bg: #b6b6bb;
  --badge-spoiler-fg: #ffffff;
  --pin-color: #ff3b30;

  /* #compass background: glassy white in the light theme (dark theme keeps
     a faint ink tint, set in body.theme-dark below). */
  --compass-bg: rgba(255, 255, 255, .65);

  --label-color: #37373c;
  --label-halo: 0 0 4px #fff, 0 0 4px #fff, 0 0 9px rgba(255,255,255,.85);
  --street-label-color: #6B6B6B;
  --street-label-halo: 0 1px 2px rgba(255,255,255,.95), 0 -1px 2px rgba(255,255,255,.95), 1px 0 2px rgba(255,255,255,.95), -1px 0 2px rgba(255,255,255,.95);

  --bg: #F4F2EC;

  font-family: var(--font-family);
  font-optical-sizing: auto;
}

body.theme-dark {
  --bg: #1C1C1E;

  --glass-bg: rgba(32, 33, 38, 0.60);
  --glass-edge: rgba(255, 255, 255, 0.10);
  --glass-blur: blur(36px) saturate(1.5) brightness(1.05);
  --glass-shadow:
    inset 0 1px 0 rgba(255,255,255,.07),
    inset 0 0 12px rgba(255,255,255,.03),
    0 1px 1px rgba(0,0,0,.3),
    0 8px 24px rgba(0,0,0,.4),
    0 24px 64px rgba(0,0,0,.3);
  --chip-shadow:
    inset 0 1px 0 rgba(255,255,255,.07),
    inset 0 0 12px rgba(255,255,255,.03),
    0 1px 2px rgba(0,0,0,.35),
    0 6px 16px rgba(0,0,0,.42);

  --text: rgba(240, 240, 245, 0.92);
  --text-dim: rgba(240, 240, 245, 0.52);
  --ink-rgb: 240,240,245;

  --accent: #0a84ff;

  --input-bg: rgba(120, 120, 128, 0.18);
  --btn-border: rgba(255, 255, 255, 0.10);
  --switch-track: rgba(255, 255, 255, .18);

  --badge-spoiler-bg: #48484A;
  --badge-spoiler-fg: #ffffff;
  --pin-color: #ff453a;

  --compass-bg: rgba(var(--ink-rgb), .04);

  --label-color: rgba(235,235,245,0.92);
  --label-halo: 0 0 4px #000, 0 0 4px #000, 0 0 9px rgba(0,0,0,.85);
  --street-label-color: rgba(235,235,245,0.68);
  --street-label-halo: 0 1px 2px rgba(0,0,0,.9), 0 -1px 2px rgba(0,0,0,.9), 1px 0 2px rgba(0,0,0,.9), -1px 0 2px rgba(0,0,0,.9);
}

* { margin: 0; padding: 0; box-sizing: border-box; }

html, body {
  width: 100%;
  height: 100%;
  overflow: hidden;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-family);
  font-weight: 450;
  font-size: 14px;
  line-height: 1.3;
  letter-spacing: -0.012em;
  -webkit-font-smoothing: antialiased;
}

#map {
  position: absolute;
  inset: 0;
  background: var(--bg);
}

/* Iso mode: the basemap is a collage image, we keep the map background neutral
   regardless of the theme (the theme only touches the UI on top, not the render itself). */
body.mode-iso #map,
body.mode-iso .leaflet-container {
  background: #101114;
}

/* "+ Add" one-shot mode (state.addingMarker, app.js section 12a): the next
   left click places a marker, so the cursor hints at that instead of the
   usual grab/pointer. */
body.adding-marker #map,
body.adding-marker .leaflet-container {
  cursor: crosshair;
}

.leaflet-container {
  background: var(--bg);
  font-family: var(--font-family);
}

/* ---------------------------------------------------------------------- */
/* frost / frost-dark — base "glass" surfaces                             */
/* ---------------------------------------------------------------------- */
.frost {
  background: var(--glass-bg);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  border: 0.5px solid var(--glass-edge);
  box-shadow: var(--glass-shadow);
}
.frost-dark {
  background: var(--dark-bg);
  backdrop-filter: var(--dark-blur);
  -webkit-backdrop-filter: var(--dark-blur);
  border: 0.5px solid var(--dark-edge);
  box-shadow: var(--dark-shadow);
  color: var(--dark-text);
}
.lift { transition: transform .16s ease, box-shadow .16s ease, background .16s ease; }
.lift:hover { transform: translateY(-1px); }
.lift:active { transform: translateY(0) scale(.97); }

/* ===== Leaflet zoom control — recolored to match the glass, hidden into the bottom-right corner along with attribution ===== */
.leaflet-control-zoom { display: none; } /* we use our own ctrl-group (#zoom-in-btn/#zoom-out-btn) */
.leaflet-control-attribution {
  background: var(--glass-bg);
  color: var(--text-dim);
  font-size: 10.5px;
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
}
.leaflet-control-attribution a { color: var(--accent); }

/* ===== search ===== */
.search-card { position: absolute; top: 20px; left: 20px; width: 380px; z-index: 1050; border-radius: 18px; }
.search-row { position: relative; display: flex; align-items: center; gap: 11px; padding: 14px 18px; }
.search-row > svg:first-child { width: 17px; height: 17px; fill: rgba(var(--ink-rgb),.42); flex: 0 0 auto; }
.search-row input {
  border: 0; outline: 0; background: transparent; flex: 1; min-width: 0;
  font-family: inherit; font-weight: 450; font-size: 15px; line-height: 1.2; letter-spacing: -0.014em; color: var(--text);
}
.search-row input::placeholder { color: rgba(var(--ink-rgb),.38); }
.search-row kbd {
  font-family: inherit; font-weight: 500; font-size: 11px; line-height: 1; color: rgba(var(--ink-rgb),.4);
  background: rgba(var(--ink-rgb),.06); border-radius: 7px; padding: 5px 7px;
  border: 0.5px solid rgba(var(--ink-rgb),.07);
}
.search-row .clear-btn {
  display: none; width: 22px; height: 22px; border-radius: 50%; border: 0; cursor: pointer;
  background: rgba(var(--ink-rgb),.08); color: rgba(var(--ink-rgb),.5);
  align-items: center; justify-content: center; flex: 0 0 auto; padding: 0;
}
.search-row .clear-btn svg { width: 9px; height: 9px; fill: currentColor; }
.search-row .clear-btn:hover { background: rgba(var(--ink-rgb),.14); }
.search-card.has-query .clear-btn { display: flex; }
.search-card.has-query kbd { display: none; }

.suggest {
  position: absolute; top: calc(100% + 8px); left: 0; right: 0;
  border-radius: 16px; overflow: hidden; z-index: 1051;
  max-height: 320px; overflow-y: auto;
}
.suggest.hidden { display: none; }
.sug-section-label {
  padding: 9px 16px 4px; font-weight: 600; font-size: 10.5px; line-height: 1;
  text-transform: uppercase; letter-spacing: .06em; color: var(--text-dim);
}
.sug-row {
  display: flex; align-items: center; gap: 11px; padding: 9px 16px; cursor: pointer;
  font-weight: 500; font-size: 13.5px; line-height: 1.2; letter-spacing: -0.01em; color: var(--text);
}
.sug-row:hover, .sug-row.active { background: rgba(var(--ink-rgb),.06); }
.sug-row .sug-icon {
  width: 24px; height: 24px; border-radius: 50%; display: grid; place-items: center; flex: 0 0 auto;
  background: rgba(var(--ink-rgb),.08);
}
.sug-row .sug-icon svg { width: 11px; height: 11px; fill: var(--text-dim); }
.sug-row .sug-icon.cat { box-shadow: inset 0 -1px 2px rgba(0,0,0,.14), 0 1px 2px rgba(0,0,0,.10); }
.sug-row .sug-icon.cat svg { width: 12px; height: 12px; fill: #fff; }
.sug-row .sug-sub { margin-left: auto; font-weight: 450; font-size: 11.5px; color: var(--text-dim); font-variant-numeric: tabular-nums; }
.sug-empty { padding: 16px; text-align: center; font-weight: 450; font-size: 12.5px; color: var(--text-dim); }

/* ===== category chips ===== */
.chips {
  /* Padding is the shadow gutter: --chip-shadow extents are 10px up, 22px
     down, 16px sideways, so 12/20/26 fits with margin; the position offsets
     compensate so the chips render at the same visual spot. */
  position: absolute; top: 74px; left: 0; right: 68px; z-index: 1045;
  display: flex; gap: 10px; overflow-x: auto; padding: 12px 20px 26px;
  scrollbar-width: none;
  /* No mask-image here for the edge fade: a mask on the container forces the
     browser to composite all children (including their backdrop-filter
     frost) into a single layer, silently killing the frost blur on .chip.
     Per-chip opacity fade instead (updateChipsEdgeFade() in app.js). */
}
.chips::-webkit-scrollbar { display: none; }
.chip {
  display: flex; align-items: center; gap: 8px; flex: 0 0 auto;
  height: 42px; padding: 0 16px 0 8px; border-radius: 99px; cursor: pointer;
  font-family: inherit; font-weight: 500; font-size: 14px; line-height: 1; letter-spacing: -0.01em; color: var(--text);
  user-select: none; border: 0;
  transition: opacity .08s linear;
  /* Pill-scale shadow overriding the panel-scale .frost one (see --chip-shadow). */
  box-shadow: var(--chip-shadow);
}
.chip.chip-all { padding: 0 18px; }
.chip .mini {
  width: 28px; height: 28px; border-radius: 50%; display: grid; place-items: center; flex: 0 0 auto;
  box-shadow: inset 0 -1px 2px rgba(0,0,0,.14), 0 1px 2px rgba(0,0,0,.10);
}
.chip .mini svg { width: 13px; height: 13px; fill: #fff; }
/* Chip label: visible in the enabled state, in the disabled state the chip
   collapses down to an icon circle (max-width -> 0, gap is compensated via margin). */
.chip .lbl {
  max-width: 180px; overflow: hidden; white-space: nowrap; line-height: 1.25;
  transition: max-width .22s ease, opacity .16s ease, margin-left .22s ease;
}
.chip.off { background: rgba(var(--ink-rgb),.06); color: var(--text-dim); padding: 0 8px; }
.chip.off .lbl { max-width: 0; opacity: 0; margin-left: -8px; }
.chip.off .mini { filter: grayscale(1); opacity: .55; }
/* Compact mode ("Chips without labels" toggle in the "Layers" panel):
   labels are removed from ALL chips, the enabled state is shown by the circle's color
   (colored = on, gray = off). The "All" chip is text-only — we don't collapse it. */
.chips.compact .chip:not(.chip-all) { padding: 0 8px; }
.chips.compact .chip:not(.chip-all) .lbl { max-width: 0; opacity: 0; margin-left: -8px; }
/* "Search" toggle in the "Layers" panel: hides the search card; the chip row
   moves up to take its place. */
body.search-hidden .search-card { display: none; }
body.search-hidden .chips { top: 4px; }
/* "Category chips" toggle: fully hides the chip row. */
body.chips-hidden .chips { display: none; }
.chips.locked .chip { opacity: .45; pointer-events: none; }

/* ===== right stack ===== */
.ctrl-stack { position: absolute; right: 20px; top: 20px; display: flex; flex-direction: column; gap: 12px; z-index: 1040; }
.ctrl-group { border-radius: 16px; overflow: hidden; display: flex; flex-direction: column; }
.ctrl-btn {
  width: 46px; height: 46px; display: grid; place-items: center; border: 0; background: transparent; cursor: pointer;
  color: #46464b; font-family: inherit;
}
body.theme-dark .ctrl-btn { color: rgba(240,240,245,.78); }
.ctrl-btn + .ctrl-btn { border-top: 0.5px solid rgba(var(--ink-rgb),.08); }
.ctrl-btn svg { width: 18px; height: 18px; fill: currentColor; }
.ctrl-btn:hover:not(:disabled) { background: rgba(var(--ink-rgb),.05); }
.ctrl-btn.seg-on { color: var(--accent); }
.ctrl-btn:disabled { opacity: .35; cursor: not-allowed; }

/* ===== floor selector (third group of the right stack) ===== */
.floor-btn { font-size: 12px; height: 34px; }
.floor-value {
  padding: 3px 0; text-align: center; font-weight: 650; font-size: 13px; line-height: 1;
  color: var(--text); font-variant-numeric: tabular-nums;
}
#floor-selector.disabled { opacity: .45; }

/* ===== "Layers" dropdown panel ===== */
.layers-panel {
  position: absolute; top: 20px; right: 76px; width: 250px; z-index: 1041;
  border-radius: 16px; padding: 6px; z-index: 1055;
  opacity: 1; transition: opacity .18s ease, translate .18s ease;
}
.layers-panel.hidden { opacity: 0; translate: 6px 0; pointer-events: none; }
.layer-row {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 10px 10px; border-radius: 11px; cursor: pointer;
  font-weight: 500; font-size: 13px; line-height: 1.2; letter-spacing: -0.008em; color: var(--text);
}
.layer-row:hover { background: rgba(var(--ink-rgb),.05); }
.layer-actions { display: flex; gap: 8px; padding: 6px 8px 6px; }
.layer-actions button {
  flex: 1; height: 30px; border: 0; border-radius: 9px; cursor: pointer; font-family: inherit;
  background: rgba(var(--ink-rgb),.06); color: var(--text);
  font-weight: 500; font-size: 11.5px; line-height: 1; letter-spacing: -0.008em;
}
.layer-actions button:hover { background: rgba(var(--ink-rgb),.1); }

/* ===== language switcher (bottom of the "Layers" panel) ===== */
.layer-lang-row {
  display: flex; gap: 8px; padding: 8px 8px 6px; margin-top: 4px;
  border-top: 0.5px solid rgba(var(--ink-rgb),.08);
}
.lang-pill {
  flex: 1; height: 30px; border: 0; border-radius: 9px; cursor: pointer; font-family: inherit;
  background: rgba(var(--ink-rgb),.06); color: var(--text-dim);
  font-weight: 500; font-size: 11.5px; line-height: 1; letter-spacing: -0.008em;
  transition: background .15s ease, color .15s ease;
}
.lang-pill:hover { background: rgba(var(--ink-rgb),.1); }
.lang-pill.active { background: var(--accent); color: var(--accent-fg); }

/* ===== "About" row (bottom of the "Layers" panel, below the language pills).
   The divider reuses the exact same border-top/margin-top recipe as
   .layer-lang-row above, so both dividers look identical. ===== */
.layer-about-row {
  padding-top: 4px; margin-top: 4px;
  border-top: 0.5px solid rgba(var(--ink-rgb),.08);
}
.layer-about-row .layer-row { justify-content: space-between; }
.about-chev { width: 10px; height: 10px; fill: var(--text-dim); transform: rotate(-90deg); flex: 0 0 auto; }

/* iOS-style toggle (used both in the layers panel and the markers panel) */
.switch { position: relative; width: 36px; height: 21px; border-radius: 99px; background: var(--switch-track); transition: background .18s ease; flex: 0 0 auto; }
.switch::after {
  content: ''; position: absolute; top: 2px; left: 2px; width: 17px; height: 17px; border-radius: 50%;
  background: #fff; box-shadow: 0 1px 3px rgba(0,0,0,.35); transition: left .18s ease;
}
.switch.on { background: #30d158; }
.switch.on::after { left: 17px; }

/* ===== status ===== */
.status-pill {
  position: absolute; left: 20px; bottom: 18px;
  padding: 8px 15px; border-radius: 99px; font-weight: 450; font-size: 12px; line-height: 1;
  color: var(--text-dim); z-index: 1040; white-space: nowrap; font-variant-numeric: tabular-nums;
}
.status-pill b { color: var(--text); font-weight: 600; }

.iso-disclaimer {
  position: absolute; right: 12px; bottom: 24px; z-index: 1030;
  padding: 3px 8px; font-weight: 450; font-size: 10.5px; color: var(--text-dim);
  cursor: help; white-space: nowrap;
}

/* ===== permanent attribution line (bottom-right corner, below the iso
   disclaimer — always visible in both modes/themes, deliberately smaller
   and quieter than the disclaimer above it). Only the <a> links are
   interactive (pointer-events), so hovering/clicking the plain-text parts
   passes straight through to the map underneath; link clicks also stop
   propagation (see initAttribution() in app.js) so they never trigger a
   map click/drag. ===== */
.map-attribution {
  position: absolute; right: 12px; bottom: 4px; z-index: 1029;
  padding: 2px 4px; font-weight: 450; font-size: 9.5px; line-height: 1.4;
  color: var(--text-dim); opacity: .6; white-space: nowrap;
  pointer-events: none;
}
.map-attribution a {
  color: var(--text-dim); text-decoration: none; pointer-events: auto;
}
.map-attribution a:hover { text-decoration: underline; }

/* ===== shared-point pin: a beacon with pulsing rings.
   Must look RADICALLY different from regular markers. ===== */
.pin-beacon { position: relative; width: 56px; height: 56px; display: block; pointer-events: none; }
.pin-core {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  width: 30px; height: 30px; border-radius: 50%;
  background: #FF3B30; border: 3px solid #fff;
  display: grid; place-items: center;
  box-shadow: 0 2px 6px rgba(0,0,0,.35), 0 8px 22px rgba(255,59,48,.45);
}
.pin-core svg { width: 13px; height: 13px; fill: #fff; }
.pin-wave {
  position: absolute; left: 50%; top: 50%; width: 30px; height: 30px;
  margin: -15px 0 0 -15px; border-radius: 50%;
  border: 2px solid rgba(255, 59, 48, .75);
  animation: pin-pulse 1.8s ease-out infinite;
}
.pin-wave.w2 { animation-delay: .9s; }
@keyframes pin-pulse {
  0%   { transform: scale(.7); opacity: .9; }
  100% { transform: scale(2.4); opacity: 0; }
}

/* ===== compass legend for directions (bottom-right corner, above the status pill).
   Unobtrusive: semi-transparent, non-interactive. In isometric, the cardinal directions
   sit at the real angles of the projection (north — up and to the right). ===== */
#compass {
  /* Sits above the corner text stack: attribution (bottom 4) and the iso
     disclaimer (bottom 24) — keep clear of both. */
  position: absolute; right: 14px; bottom: 52px; z-index: 1030;
  width: 48px; height: 48px; border-radius: 50%;
  background: var(--compass-bg);
  border: 0.5px solid rgba(var(--ink-rgb), .10);
  opacity: .75; pointer-events: none;
}
#compass .pt {
  position: absolute; transform: translate(-50%, -50%);
  font-weight: 600; font-size: 9px; line-height: 1; color: var(--text-dim);
  letter-spacing: 0;
}
#compass .pt.n { color: #e0524d; font-weight: 700; }
/* Two-letter labels (uk locale) are a bit smaller than one-letter ones (en locale: N/E/S/W),
   to fit within the same 48px circle without overflowing. */
#compass .pt.sm { font-size: 8px; }
#compass .dot {
  position: absolute; left: 50%; top: 50%; width: 3px; height: 3px;
  margin: -1.5px 0 0 -1.5px; border-radius: 50%; background: rgba(var(--ink-rgb), .3);
}

/* ===== POI on the map (Leaflet divIcon — className is set directly on .poi-badge,
   positioning is done by Leaflet itself, here there are only visual tokens) ===== */
.poi-badge {
  width: 26px; height: 26px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
  border: 2.5px solid #fff;
  box-shadow: inset 0 -2px 3px rgba(0,0,0,.16), 0 2px 4px rgba(0,0,0,.18), 0 6px 16px rgba(0,0,0,.18);
  pointer-events: auto;
}
.poi-badge svg { width: 13px; height: 13px; fill: #fff; }
.poi-badge.spoiler { background: var(--badge-spoiler-bg); color: var(--badge-spoiler-fg); font-weight: 700; font-size: 13px; }
.poi-badge.custom { background: rgba(28,28,32,.92); font-size: 13px; font-family: var(--font-emoji); }

/* Inline Ukrainian flag (SVG): emoji flags don't render on Windows, so the
   flag is drawn as two rects — crisp everywhere, aligns with the text line. */
.ua-flag { width: 15px; height: 10px; border-radius: 2px; vertical-align: -1px; display: inline-block; }
.poi-badge.pin svg { fill: var(--pin-color); }

.town-label {
  font-weight: 650; font-size: 12px; line-height: 1; letter-spacing: .07em; color: var(--label-color);
  text-shadow: var(--label-halo);
  pointer-events: none; text-transform: uppercase; white-space: nowrap;
}

.street-label { pointer-events: none; white-space: nowrap; }
.street-label span {
  display: inline-block; font-weight: 500; font-size: 10px; color: var(--street-label-color);
  text-shadow: var(--street-label-halo); letter-spacing: 0.02em;
}

/* ===== Leaflet popups — glass ===== */
.leaflet-popup-content-wrapper {
  background: var(--glass-bg);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  border: 0.5px solid var(--glass-edge);
  box-shadow: var(--glass-shadow);
  color: var(--text);
  border-radius: 16px;
}
.leaflet-popup-tip {
  background: var(--glass-bg);
  border: 0.5px solid var(--glass-edge);
}
.leaflet-popup-content {
  margin: 12px 14px;
  font-family: inherit; font-weight: 450; font-size: 13px; line-height: 1.35;
}
.popup-title {
  font-weight: 650; font-size: 13.5px; line-height: 1.25; letter-spacing: -0.01em;
  margin-bottom: 7px; color: var(--text); padding-right: 26px;
}
.popup-rooms {
  list-style: none; margin: 0; padding: 0; max-height: 220px; overflow-y: auto;
}
.popup-rooms li {
  padding: 3px 0; font-weight: 450; font-size: 12.5px; border-bottom: 0.5px dotted rgba(var(--ink-rgb),.14);
}
.popup-empty { color: var(--text-dim); font-weight: 450; font-size: 12.5px; font-style: italic; }
.leaflet-container a.leaflet-popup-close-button {
  top: 8px; right: 8px; width: 24px; height: 24px; padding: 0;
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%; color: var(--text-dim); font-family: inherit;
  font-size: 15px; line-height: 1; font-weight: 500;
  transition: background .15s ease, color .15s ease;
}
.leaflet-container a.leaflet-popup-close-button:hover {
  background: rgba(var(--ink-rgb), .08); color: var(--text);
}

.popup-actions { display: flex; gap: 7px; margin-top: 9px; flex-wrap: wrap; }
.popup-actions button {
  background: rgba(var(--ink-rgb),.06); border: 0.5px solid var(--btn-border); color: var(--text);
  border-radius: 10px; padding: 6px 10px; cursor: pointer; font-family: inherit;
  font-weight: 500; font-size: 12px; line-height: 1;
}
.popup-actions button:hover { background: rgba(0,122,255,.14); border-color: var(--accent); }

.marker-form input, .marker-form select {
  width: 100%; margin-bottom: 7px; background: var(--input-bg); border: 0.5px solid var(--btn-border);
  color: var(--text); border-radius: 10px; padding: 6px 8px; font-family: inherit; font-weight: 450; font-size: 12.5px;
}
/* Emoji picker options must resolve to the color-emoji font. */
.marker-form select, .marker-form select option { font-family: var(--font-emoji); }

/* ===================================================================== */
/* Markers menu (bottom pill + expandable card, dark glass)               */
/* ===================================================================== */
#mk-pill {
  position: absolute; bottom: 20px; left: 50%; transform: translateX(-50%);
  display: flex; align-items: center; gap: 9px;
  height: 42px; padding: 0 18px 0 14px; border-radius: 99px; cursor: pointer; z-index: 1060;
  font-family: inherit; font-weight: 500; font-size: 14px; line-height: 1; user-select: none;
}
#mk-pill svg:first-child { width: 15px; height: 15px; fill: var(--accent-dark); }
#mk-pill .cnt { color: var(--dark-dim); font-variant-numeric: tabular-nums; }
#mk-pill .chev { width: 11px; height: 11px; fill: var(--dark-dim); transition: transform .22s ease; }
#mk-pill.open .chev { transform: rotate(180deg); }

#mk-panel {
  position: absolute; bottom: 74px; left: 50%; translate: -50% 0;
  width: 360px; border-radius: 20px; z-index: 1059; overflow: hidden;
  opacity: 1; transition: opacity .2s ease, translate .22s ease;
}
#mk-panel.hidden { opacity: 0; translate: -50% 10px; pointer-events: none; }

.mk-head { display: flex; align-items: center; justify-content: space-between; padding: 16px 18px 8px; }
.mk-head h3 { font-weight: 650; font-size: 15px; line-height: 1; letter-spacing: -0.015em; }
.mk-toggle { display: flex; align-items: center; gap: 8px; font-weight: 450; font-size: 12.5px; color: var(--dark-dim); cursor: pointer; }

#mk-list { max-height: 300px; overflow-y: auto; padding: 4px 8px; }
.mk-row { display: flex; align-items: center; gap: 11px; padding: 7px 10px; border-radius: 12px; cursor: pointer; }
.mk-row:hover { background: rgba(255,255,255,.07); }
.mk-row .em-badge {
  width: 30px; height: 30px; border-radius: 50%; flex: 0 0 auto;
  display: grid; place-items: center; font-size: 15px;
  background: rgba(255,255,255,.10); border: 0.5px solid rgba(255,255,255,.10);
  font-family: var(--font-emoji);
}
.mk-row .t { display: flex; flex-direction: column; gap: 3px; flex: 1; min-width: 0; }
.mk-row .t b {
  font-weight: 550; font-size: 13.5px; line-height: 1.25; letter-spacing: -0.01em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.mk-row .t i {
  font-weight: 450; font-size: 11.5px; line-height: 1.25; font-style: normal;
  color: var(--dark-dim); font-variant-numeric: tabular-nums;
}
.mk-row .del {
  width: 26px; height: 26px; border-radius: 50%; border: 0; cursor: pointer; flex: 0 0 auto;
  display: grid; place-items: center; background: transparent; color: var(--dark-dim);
  opacity: 0; transition: opacity .15s ease, background .15s ease;
}
.mk-row:hover .del { opacity: 1; }
.mk-row .del:hover { background: rgba(255,69,58,.22); color: #ff6961; }
.mk-row .del svg { width: 12px; height: 12px; fill: currentColor; }

.mk-empty { padding: 22px 18px 26px; text-align: center; color: var(--dark-dim); font-weight: 450; font-size: 13px; }

.mk-actions { display: flex; gap: 8px; padding: 10px 12px 14px; border-top: 0.5px solid rgba(255,255,255,.08); }
.mk-actions button {
  flex: 1; height: 34px; border: 0; border-radius: 10px; cursor: pointer;
  background: rgba(255,255,255,.10); color: var(--dark-text);
  font-family: inherit; font-weight: 500; font-size: 12.5px; line-height: 1; letter-spacing: -0.01em;
  transition: background .15s ease;
}
.mk-actions button:hover { background: rgba(255,255,255,.17); }
.mk-actions button.primary { background: var(--accent-dark); color: #fff; }
.mk-actions button.primary:hover { background: #2a93ff; }

/* ===== toast ===== */
.toast {
  position: absolute; bottom: 74px; left: 50%; transform: translate(-50%, 0);
  padding: 10px 18px; border-radius: 99px; z-index: 1070;
  font-family: inherit; font-weight: 500; font-size: 13px; line-height: 1; white-space: nowrap;
  opacity: 0; transition: opacity .25s ease, transform .25s ease; pointer-events: none;
}
.toast.show { opacity: 1; transform: translate(-50%, -4px); }

/* ===================================================================== */
/* "About" modal — dark overlay + centered glass card, opened from the    */
/* "About this map" row at the bottom of the "Layers" panel (see          */
/* initAboutModal() in app.js). Closes via the ✕ button, an overlay       */
/* click, or Escape.                                                      */
/* ===================================================================== */
.about-overlay {
  position: fixed; inset: 0; z-index: 1090;
  background: rgba(0, 0, 0, .45);
  display: flex; align-items: center; justify-content: center;
  padding: 20px;
  opacity: 1; transition: opacity .18s ease;
}
.about-overlay.hidden { opacity: 0; pointer-events: none; }
.about-modal {
  position: relative; width: 100%; max-width: 360px; max-height: calc(100vh - 40px);
  overflow-y: auto; border-radius: 20px; padding: 26px 24px 22px;
  transform: scale(1); transition: transform .18s ease;
}
.about-overlay.hidden .about-modal { transform: scale(.96); }
.about-close {
  position: absolute; top: 12px; right: 12px; width: 26px; height: 26px; border-radius: 50%;
  border: 0; cursor: pointer; background: rgba(var(--ink-rgb),.08); color: var(--text-dim);
  display: grid; place-items: center; padding: 0;
}
.about-close:hover { background: rgba(var(--ink-rgb),.14); color: var(--text); }
.about-close svg { width: 10px; height: 10px; fill: currentColor; }
.about-title { font-weight: 700; font-size: 19px; line-height: 1.2; letter-spacing: -0.015em; color: var(--text); padding-right: 20px; }
.about-tagline { margin-top: 2px; font-weight: 500; font-size: 12.5px; color: var(--text-dim); }
.about-notice { margin-top: 14px; font-weight: 450; font-size: 12.5px; line-height: 1.4; color: var(--text-dim); }
.about-links { list-style: none; margin: 14px 0 0; padding: 0; display: flex; flex-direction: column; gap: 7px; }
.about-links a { color: var(--accent); font-weight: 500; font-size: 13px; text-decoration: none; }
.about-links a:hover { text-decoration: underline; }
.about-links .about-made { font-weight: 450; font-size: 12.5px; color: var(--text-dim); }
.about-section { margin-top: 16px; padding-top: 12px; border-top: 0.5px solid rgba(var(--ink-rgb),.08); }
.about-section h3 {
  font-weight: 650; font-size: 10.5px; line-height: 1; text-transform: uppercase;
  letter-spacing: .06em; color: var(--text-dim); margin-bottom: 6px;
}
.about-section p { font-weight: 450; font-size: 12.5px; line-height: 1.5; color: var(--text); }
.about-section p + p { margin-top: 2px; }

/* ===== onboarding: short first-visit tour, see ONBOARDING_STEPS in app.js.
   The overlay and callout — position:fixed, the coordinates are set by JS
   (positionOnboardingOverlay()/positionOnboardingCallout()) via the target
   element's getBoundingClientRect(), since e.g. #layers-btn sits inside
   .ctrl-group with overflow:hidden — the pulsing rings there would be
   clipped. pointer-events:none on both the overlay and the callout — they
   don't block clicks on the map/target (the skip button opts back into
   pointer-events so it stays clickable). Placement variants (place-left/
   place-top/place-center) cover the three ONBOARDING_STEPS entries. ===== */
.onboarding-overlay {
  position: fixed; pointer-events: none; z-index: 1041;
}
.onboarding-overlay.hidden { display: none; }
.onboarding-wave {
  position: absolute; inset: 0; border-radius: 50%;
  border: 2px solid var(--accent);
  animation: onboarding-pulse 1.8s ease-out infinite;
}
.onboarding-wave.w2 { animation-delay: .9s; }
@keyframes onboarding-pulse {
  0%   { transform: scale(.85); opacity: .9; }
  100% { transform: scale(2.3); opacity: 0; }
}

.onboarding-callout {
  position: fixed; z-index: 1042; max-width: 230px;
  padding: 11px 15px; border-radius: 12px;
  font-weight: 500; font-size: 12.5px; line-height: 1.35;
  opacity: 0;
  transition: opacity .25s ease, transform .25s ease;
  pointer-events: none;
}
.onboarding-callout.hidden { display: none; }
.onboarding-callout.show { opacity: 1; }

/* placement: callout to the left of the target (target sits at top-right, e.g. #layers-btn) */
.onboarding-callout.place-left { transform: translateY(-50%) translateX(8px); }
.onboarding-callout.place-left.show { transform: translateY(-50%) translateX(0); }
/* placement: callout above the target, centered on it (e.g. #mk-pill) */
.onboarding-callout.place-top { transform: translateX(-50%) translateY(8px); }
.onboarding-callout.place-top.show { transform: translateX(-50%) translateY(0); }
/* placement: no target (the final step) — a centered plaque */
.onboarding-callout.place-center { transform: translate(-50%, -50%) scale(.96); }
.onboarding-callout.place-center.show { transform: translate(-50%, -50%) scale(1); }

.onboarding-step {
  font-weight: 650; font-size: 10.5px; letter-spacing: .04em; text-transform: uppercase;
  color: var(--dark-dim); margin-bottom: 3px; padding-right: 16px;
}
.onboarding-text { padding-right: 16px; }
.onboarding-skip {
  position: absolute; top: 6px; right: 6px; width: 18px; height: 18px;
  border: 0; border-radius: 50%; cursor: pointer; padding: 0;
  display: grid; place-items: center; pointer-events: auto;
  background: rgba(255,255,255,.10); color: var(--dark-dim);
  font-family: inherit; font-size: 10px; line-height: 1;
}
.onboarding-skip:hover { background: rgba(255,255,255,.18); color: var(--dark-text); }

.onboarding-arrow { position: absolute; width: 0; height: 0; }
.onboarding-arrow.hidden { display: none; }
.onboarding-arrow.arrow-right {
  top: 50%; right: -8px; margin-top: -6px;
  border-top: 6px solid transparent;
  border-bottom: 6px solid transparent;
  border-left: 8px solid var(--dark-bg);
}
.onboarding-arrow.arrow-down {
  left: 50%; bottom: -8px; margin-left: -6px;
  border-left: 6px solid transparent;
  border-right: 6px solid transparent;
  border-top: 8px solid var(--dark-bg);
}
