:root {
  --color-bg: #f4f6f7;
  --color-surface: #ffffff;
  --color-border: #e2e6e8;
  --color-text: #1c2b2f;
  --color-text-muted: #5c6f74;
  --color-primary: #0b5566;
  --color-primary-dark: #073c48;
  --color-accent: #e08a3e;
  --color-danger: #c0392b;
  --color-success: #2f8f5b;
  --color-photo-bg: #e8e4dc;
  --color-tag-bg: #eef1f1;
  --color-warning-bg: #fbe4e2;
  --color-warning-text: #b3261e;

  --group-dining: #e08a3e;
  --group-grocery: #2f8f5b;
  --group-emergency: #c0392b;
  --group-attraction: #6a5acd;
  --group-shopping: #4a6a75;
  --group-event: #c2185b;
  --group-worship: #8a6d3b;
  --group-cma_meeting: #1f9d8f;
  --group-fallback: #555555;
  --map-cluster: #0b5566;

  --radius: 10px;
  --shadow-sm: 0 1px 3px rgba(15, 40, 46, 0.08);
  --shadow-md: 0 4px 16px rgba(15, 40, 46, 0.12);

  color-scheme: light;
  font-size: 16px;
}

html[data-theme="dark"] {
  --color-bg: #0f1719;
  --color-surface: #1a2428;
  --color-border: #2f3f45;
  --color-text: #e8eef0;
  --color-text-muted: #9aadb4;
  --color-primary: #5eb4c4;
  --color-primary-dark: #0a4554;
  --color-accent: #e09a55;
  --color-danger: #e06a5c;
  --color-success: #4caf7a;
  --color-photo-bg: #243035;
  --color-tag-bg: #243035;
  --color-warning-bg: #3a2220;
  --color-warning-text: #f0a39c;

  /* Darker map node fills so they sit quieter on the dark basemap */
  --group-dining: #8a5424;
  --group-grocery: #1d5a3a;
  --group-emergency: #7a241c;
  --group-attraction: #3f357a;
  --group-shopping: #2e4248;
  --group-event: #7a1040;
  --group-worship: #564428;
  --group-cma_meeting: #14665c;
  --group-fallback: #3a4448;
  --map-cluster: #0a3d4a;

  --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.35);
  --shadow-md: 0 4px 16px rgba(0, 0, 0, 0.45);

  color-scheme: dark;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  background: var(--color-bg);
  color: var(--color-text);
  -webkit-font-smoothing: antialiased;
}

a {
  color: var(--color-primary);
}

/* ---------- Header ---------- */

header.app-header {
  background: linear-gradient(135deg, #073c48, #0b5566);
  color: #fff;
  padding: 0.9rem 1rem 0.7rem;
  position: sticky;
  top: 0;
  z-index: 30;
  box-shadow: var(--shadow-md);
}

html[data-theme="dark"] header.app-header {
  background: linear-gradient(135deg, #041f26, #0a3d4a);
}

.app-header .title-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  flex-wrap: nowrap;
}

.theme-toggle {
  flex: none;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: 1.5px solid rgba(255, 255, 255, 0.35);
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  padding: 0;
  transition: background 0.15s ease, border-color 0.15s ease;
}

.theme-toggle:hover {
  background: rgba(255, 255, 255, 0.22);
  border-color: rgba(255, 255, 255, 0.55);
}

.theme-toggle .theme-icon-sun {
  display: none;
}

html[data-theme="dark"] .theme-toggle .theme-icon-moon {
  display: none;
}

html[data-theme="dark"] .theme-toggle .theme-icon-sun {
  display: block;
}

.app-header h1 {
  font-size: 1.15rem;
  margin: 0;
  font-weight: 700;
  letter-spacing: 0.01em;
}

.app-header .venue-line {
  font-size: 0.78rem;
  opacity: 0.85;
  margin: 0.15rem 0 0;
}

@media (max-width: 640px) {
  .app-header .venue-line {
    display: none;
  }
}

/* ---------- Filter bar ---------- */

.filter-bar {
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
  padding: 0.75rem 1rem;
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

.filter-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  align-items: center;
}

/* The top row (search, tab pill, filter toggle) needs to fit on a single
   line even on a small phone — no wrapping, and if it's still too tight,
   scroll horizontally rather than break onto a second line. */
.top-controls-row {
  flex-wrap: nowrap;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  padding-bottom: 1px;
}

.top-controls-row::-webkit-scrollbar {
  display: none;
}

/* ---------- Filters toggle + collapsible panel ---------- */

.filter-toggle-btn {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.42rem 0.75rem;
  border-radius: 999px;
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  color: var(--color-text);
  font-size: 0.78rem;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
  position: relative;
}

.filter-toggle-btn:hover {
  border-color: var(--color-primary);
  color: var(--color-primary);
}

.filter-toggle-btn.active {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: #fff;
}

.filter-toggle-btn.has-active-filters::after {
  content: "";
  position: absolute;
  top: 1px;
  right: 1px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--color-accent);
  border: 1.5px solid var(--color-surface);
}

.filters-panel {
  display: none;
  flex-direction: column;
  gap: 0.5rem;
}

.filters-panel.open {
  display: flex;
}

.search-input {
  flex: 1 1 220px;
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  font-size: 0.9rem;
  background: var(--color-surface);
  color: var(--color-text);
}

/* type=search draws its own clear "x" in WebKit; we already have .search-clear-btn */
.search-input::-webkit-search-cancel-button,
.search-input::-webkit-search-decoration {
  -webkit-appearance: none;
  appearance: none;
  display: none;
}

select.filter-select {
  padding: 0.45rem 0.6rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  font-size: 0.85rem;
  background: var(--color-surface);
  color: var(--color-text);
}

/* ---------- Collapsible search widget ---------- */

.search-widget {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 0.3rem;
}

.search-icon-btn {
  flex: none;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  color: var(--color-text-muted);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  padding: 0;
}

.search-icon-btn:hover {
  border-color: var(--color-primary);
  color: var(--color-primary);
}

.search-widget .search-input {
  flex: 0 0 auto;
  width: 0;
  min-width: 0;
  padding: 0;
  border: none;
  opacity: 0;
  font-size: 0.85rem;
  transition: width 0.2s ease, opacity 0.15s ease, padding 0.2s ease;
}

.search-widget.expanded {
  flex: 1 1 160px;
}

.search-widget.expanded .search-input,
.search-widget.shrunk .search-input {
  opacity: 1;
  padding: 0.45rem 0.6rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
}

.search-widget.expanded .search-input {
  flex: 1 1 auto;
  width: 100%;
  min-width: 80px;
}

/* Shrunk: has a search term but lost focus — sized to just fit that text
   (width set inline in JS) instead of either the full expanded width or
   the fully-collapsed icon-only width. */
.search-widget.shrunk {
  flex: 0 0 auto;
}

.search-widget.shrunk .search-input {
  flex: 0 0 auto;
  min-width: 36px;
}

.search-clear-btn {
  display: none;
  flex: none;
  border: none;
  background: none;
  color: var(--color-text-muted);
  font-size: 0.75rem;
  cursor: pointer;
  padding: 0.3rem;
  line-height: 1;
}

.search-widget.expanded .search-clear-btn,
.search-widget.shrunk .search-clear-btn {
  display: inline-flex;
}

/* ---------- Top-level nav pill ---------- */

.tab-selector {
  position: relative;
  flex: 0 0 auto;
}

.tab-selector-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.42rem 0.7rem;
  border-radius: 999px;
  border: none;
  background: linear-gradient(135deg, var(--color-primary), var(--color-primary-dark));
  color: #fff;
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  cursor: pointer;
  white-space: nowrap;
}

.tab-selector-icon {
  font-size: 0.95em;
  line-height: 1;
}

.tab-selector-caret {
  font-size: 0.65rem;
  opacity: 0.85;
  transition: transform 0.18s ease;
}

.tab-selector.open .tab-selector-caret {
  transform: rotate(180deg);
}

.tab-selector-menu {
  /* Fixed (not absolute) because the pill lives inside .top-controls-row,
     which scrolls horizontally — an absolutely-positioned descendant would
     get clipped by that ancestor's scroll container instead of floating
     over the page. Position is computed in JS on open. */
  display: none;
  position: fixed;
  min-width: 210px;
  max-width: min(260px, 90vw);
  max-height: 340px;
  overflow-y: auto;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-md);
  z-index: 40;
  padding: 0.35rem;
}

.tab-selector.open .tab-selector-menu {
  display: block;
}

.tab-selector-option {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  width: 100%;
  padding: 0.55rem 0.65rem;
  border: none;
  background: none;
  border-radius: 8px;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--color-text);
  cursor: pointer;
  text-align: left;
}

.tab-selector-option:hover {
  background: var(--color-bg);
}

.tab-selector-option.active {
  background: var(--color-primary);
  color: #fff;
}

.tab-selector-option-icon {
  font-size: 0.95em;
  line-height: 1;
}

.chip {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.4rem 0.7rem;
  border-radius: 999px;
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  font-size: 0.8rem;
  cursor: pointer;
  color: var(--color-text-muted);
  user-select: none;
}

.chip.active {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: #fff;
}

.chip-group {
  display: flex;
  gap: 0.4rem;
  flex-wrap: wrap;
}

.dining-only-panel,
.diet-only-panel,
.rating-price-panel,
.meeting-only-panel {
  display: none;
}

.dining-only-panel.visible,
.diet-only-panel.visible,
.rating-price-panel.visible,
.meeting-only-panel.visible {
  display: flex;
}

.chip-icon {
  width: 14px;
  height: 14px;
  flex: none;
}

/* ---------- Restaurant type selector ---------- */

.type-selector {
  position: relative;
}

.type-selector-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.5rem 0.9rem;
  border-radius: 999px;
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--color-text);
  cursor: pointer;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.type-selector-btn:hover {
  border-color: var(--color-primary);
}

.type-selector.open .type-selector-btn {
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px rgba(11, 85, 102, 0.12);
}

.type-selector-icon {
  font-size: 1rem;
  line-height: 1;
}

.type-selector-caret {
  color: var(--color-text-muted);
  font-size: 0.7rem;
  transition: transform 0.18s ease;
}

.type-selector.open .type-selector-caret {
  transform: rotate(180deg);
}

.type-selector-menu {
  display: none;
  position: absolute;
  top: calc(100% + 0.4rem);
  left: 0;
  min-width: 250px;
  max-width: min(320px, 90vw);
  max-height: 320px;
  overflow-y: auto;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-md);
  z-index: 25;
  padding: 0.35rem;
}

.type-selector.open .type-selector-menu {
  display: block;
}

.type-selector-option {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  gap: 0.6rem;
  padding: 0.55rem 0.65rem;
  border: none;
  background: none;
  border-radius: 8px;
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--color-text);
  cursor: pointer;
  text-align: left;
}

.type-selector-option:hover {
  background: var(--color-bg);
}

.type-selector-option.active {
  background: var(--color-primary);
  color: #fff;
  font-weight: 700;
}

.type-selector-option-main {
  display: flex;
  align-items: center;
  gap: 0.45rem;
}

.type-selector-option-count {
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--color-text-muted);
}

.type-selector-option.active .type-selector-option-count {
  color: rgba(255, 255, 255, 0.85);
}

@media (max-width: 480px) {
  /* Deliberately not width: 100% here — the type selector shares its row
     with the breakfast/coffee/vegetarian/vegan chips on the Dining tab, so
     it stays sized to its content instead of pushing them onto their own
     row and eating extra vertical space. */
  .type-selector-menu {
    left: 0;
    right: 0;
    max-width: none;
  }
}

/* ---------- Layout ---------- */

main.layout {
  display: flex;
  flex-direction: column;
  gap: 0;
}

#map {
  height: 30vh;
  min-height: 200px;
  width: 100%;
  z-index: 1;
}

/* Leaflet's default pane is light gray — keep night mode black so tile
   swaps (and slow loads) don't flash a bright rectangle behind the map. */
html[data-theme="dark"] #map,
html[data-theme="dark"] #map .leaflet-container {
  background: #000;
}

.list-panel {
  padding: 0.75rem;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

@media (min-width: 900px) {
  main.layout {
    flex-direction: row;
    height: calc(100vh - 132px);
  }

  .list-panel {
    width: 46%;
    max-width: 560px;
    overflow-y: auto;
    height: 100%;
    order: 1;
  }

  #map {
    flex: 1;
    height: 100%;
    order: 2;
  }
}

/* ---------- Place cards ---------- */

.place-card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  padding: 0.85rem 0.95rem;
  box-shadow: var(--shadow-sm);
  cursor: pointer;
  transition: box-shadow 0.15s ease, transform 0.15s ease;
  position: relative;
  /* Do not use overflow:hidden here: the desktop list-panel is a column
     flex container with a fixed height, and overflow other than visible
     makes flex items' min-height collapse to 0 — so dozens of cards all
     shrink into clipped one-line bars. Clip photos on .place-photo instead. */
  flex-shrink: 0;
}

.place-card:hover,
.place-card.highlighted {
  box-shadow: var(--shadow-md);
  border-color: var(--color-primary);
}

/* Wide, short banner for Higher Power / Events photos. Negative margins
   pull the image edge-to-edge; border-radius on the top matches the card. */
.place-photo {
  margin: -0.85rem -0.95rem 0.7rem;
  height: 110px;
  overflow: hidden;
  background: var(--color-photo-bg);
  border-radius: var(--radius) var(--radius) 0 0;
}

.place-photo img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center center;
}

.place-card .card-top {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 0.5rem;
}

.place-card h3 {
  margin: 0;
  font-size: 1rem;
  font-weight: 700;
  line-height: 1.25;
}

.group-dot {
  display: inline-block;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  margin-right: 0.4rem;
  flex: none;
}

.fav-btn {
  border: none;
  background: none;
  font-size: 1.25rem;
  cursor: pointer;
  color: #c7ccce;
  line-height: 1;
  padding: 0;
}

.fav-btn.active {
  color: var(--color-accent);
}

.card-meta {
  margin-top: 0.3rem;
  font-size: 0.8rem;
  color: var(--color-text-muted);
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem 0.6rem;
  align-items: center;
}

.badge {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0.15rem 0.5rem;
  border-radius: 999px;
  font-size: 0.72rem;
  font-weight: 600;
  white-space: nowrap;
}

.badge-walk { background: #e3f3ee; color: #1d7a5a; }
.badge-transit { background: #e6eef7; color: #2b5f9e; }
.badge-car { background: #fdece3; color: #b5541f; }
.badge-ferry { background: #ece6f7; color: #5b3fa0; }
.badge-online { background: #e0f3f1; color: #157a6e; }
.badge-open { background: #e3f3ee; color: #1d7a5a; }
.badge-closed { background: #f6e6e6; color: #a33; }
.badge-soon { background: #fdf1d9; color: #92600a; }
.badge-unknown { background: #eee; color: #888; }
.badge-muted { background: var(--color-tag-bg); color: var(--color-text-muted); }
.badge-michelin { background: #2a2a2a; color: #e8c04a; letter-spacing: 0.5px; }
.badge-advance-tickets { background: var(--color-warning-bg); color: var(--color-warning-text); font-weight: 700; }

html[data-theme="dark"] .badge-walk { background: #1a3d32; color: #6dcea8; }
html[data-theme="dark"] .badge-transit { background: #1c2f45; color: #7eb0e8; }
html[data-theme="dark"] .badge-car { background: #3a2a1c; color: #e0a06a; }
html[data-theme="dark"] .badge-ferry { background: #2a2340; color: #b49ae8; }
html[data-theme="dark"] .badge-online { background: #1a3a36; color: #6dcdc0; }
html[data-theme="dark"] .badge-open { background: #1a3d32; color: #6dcea8; }
html[data-theme="dark"] .badge-closed { background: #3a2222; color: #e08888; }
html[data-theme="dark"] .badge-soon { background: #3a3018; color: #e0c06a; }
html[data-theme="dark"] .badge-unknown { background: #2a3236; color: #9aadb4; }

.card-tags {
  margin-top: 0.45rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
}

.tag {
  font-size: 0.7rem;
  padding: 0.15rem 0.5rem;
  border-radius: 6px;
  background: var(--color-tag-bg);
  color: var(--color-text-muted);
}

.card-services {
  margin-top: 0.45rem;
  font-size: 0.85rem;
  line-height: 1.35;
  color: var(--color-text);
}

.card-notes {
  margin-top: 0.45rem;
  font-size: 0.82rem;
  color: var(--color-text-muted);
}

.card-detail {
  margin-top: 0.6rem;
  padding-top: 0.6rem;
  border-top: 1px solid var(--color-border);
  font-size: 0.82rem;
  display: none;
  flex-direction: column;
  gap: 0.35rem;
}

.card-detail.visible {
  display: flex;
}

.detail-row {
  line-height: 1.4;
}

.stars {
  color: var(--color-accent);
  letter-spacing: 1px;
}

.detail-note {
  font-size: 0.76rem;
  color: var(--color-text-muted);
  font-style: italic;
}

.hours-status-soon {
  color: #92600a;
  font-weight: 700;
}

html[data-theme="dark"] .hours-status-soon {
  color: #e0c06a;
}

.detail-warning {
  color: var(--color-warning-text);
  font-weight: 700;
  font-style: normal;
  background: var(--color-warning-bg);
  border-radius: 6px;
  padding: 0.4rem 0.55rem;
}

.card-detail a.map-link {
  color: var(--color-primary);
  font-weight: 600;
  text-decoration: none;
}

.hours-table {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.15rem 0.6rem;
  font-size: 0.78rem;
  color: var(--color-text-muted);
}

.hours-table .today {
  color: var(--color-text);
  font-weight: 700;
}

.empty-state {
  text-align: center;
  padding: 2.5rem 1rem;
  color: var(--color-text-muted);
}

.place-dot {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  border: 2px solid #fff;
  background: var(--group-fallback);
  filter: drop-shadow(0 1px 3px rgba(15, 40, 46, 0.55));
}

.place-dot--dining { background: var(--group-dining); }
.place-dot--grocery { background: var(--group-grocery); }
.place-dot--emergency { background: var(--group-emergency); }
.place-dot--attraction { background: var(--group-attraction); }
.place-dot--shopping { background: var(--group-shopping); }
.place-dot--event { background: var(--group-event); }
.place-dot--worship { background: var(--group-worship); }
.place-dot--cma_meeting { background: var(--group-cma_meeting); }

/* Clustered destinations: a bigger dot with a count, replacing individual
   dots that are too close together to tell apart at the current zoom. */
.cluster-dot {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--map-cluster);
  color: #fff;
  font-weight: 700;
  font-size: 0.78rem;
  border: 2px solid #fff;
  filter: drop-shadow(0 1px 3px rgba(15, 40, 46, 0.55));
}

html[data-theme="dark"] .place-dot,
html[data-theme="dark"] .cluster-dot {
  border-color: #6b767a;
}

.leaflet-popup-content {
  font-size: 0.85rem;
}

.leaflet-popup-content b {
  font-size: 0.92rem;
}

html[data-theme="dark"] .leaflet-popup-content-wrapper,
html[data-theme="dark"] .leaflet-popup-tip {
  background: var(--color-surface);
  color: var(--color-text);
  box-shadow: var(--shadow-md);
}

html[data-theme="dark"] .leaflet-container a.leaflet-popup-close-button {
  color: var(--color-text-muted);
}

html[data-theme="dark"] .leaflet-control-attribution {
  background: rgba(26, 36, 40, 0.85);
  color: var(--color-text-muted);
}

html[data-theme="dark"] .leaflet-control-attribution a {
  color: var(--color-primary);
}

html[data-theme="dark"] .leaflet-bar a {
  background: var(--color-surface);
  color: var(--color-text);
  border-bottom-color: var(--color-border);
}

html[data-theme="dark"] .leaflet-bar a:hover {
  background: var(--color-bg);
}

/* Stacked layout only: map pin → short popup → "View details" → list entry.
   Hidden on side-by-side where tapping a pin already selects the card. */
.popup-view-details {
  display: none;
  margin-top: 0.55rem;
  width: 100%;
  padding: 0.45rem 0.65rem;
  border: none;
  border-radius: 8px;
  background: var(--color-primary);
  color: #fff;
  font: inherit;
  font-size: 0.82rem;
  font-weight: 600;
  cursor: pointer;
}

@media (max-width: 899px) {
  .popup-view-details {
    display: block;
  }
}

/* ---------- Venue marker ---------- */

.venue-marker-wrap {
  position: relative;
  width: 46px;
  height: 58px;
}

.venue-marker-badge {
  width: 46px;
  height: 46px;
  border-radius: 12px;
  background: var(--color-primary);
  border: 3px solid #fff;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
  display: flex;
  align-items: center;
  justify-content: center;
}

.venue-marker-badge span {
  color: #fff;
  font-weight: 800;
  font-size: 0.82rem;
  letter-spacing: 0.03em;
}

.venue-marker-point {
  position: absolute;
  left: 50%;
  bottom: 4px;
  transform: translateX(-50%);
  width: 0;
  height: 0;
  border-left: 8px solid transparent;
  border-right: 8px solid transparent;
  border-top: 10px solid var(--color-primary);
}

/* ---------- User location ---------- */

.user-location-dot {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: #2b7de9;
  border: 3px solid #fff;
  box-shadow: 0 0 0 1px rgba(43, 125, 233, 0.4), 0 1px 4px rgba(0, 0, 0, 0.35);
  position: relative;
}

.user-location-pulse {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 36px;
  height: 36px;
  margin: -18px 0 0 -18px;
  border-radius: 50%;
  background: rgba(43, 125, 233, 0.28);
  animation: user-location-pulse 2s ease-out infinite;
}

@keyframes user-location-pulse {
  0% {
    transform: scale(0.4);
    opacity: 0.9;
  }
  70% {
    transform: scale(1);
    opacity: 0;
  }
  100% {
    opacity: 0;
  }
}

.locate-control {
  background: var(--color-surface);
}

.locate-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  font-size: 1.15rem;
  color: var(--color-primary);
  text-decoration: none;
  line-height: 1;
}

.locate-btn:hover {
  background: var(--color-bg);
}

footer.app-footer {
  text-align: center;
  font-size: 0.72rem;
  color: var(--color-text-muted);
  padding: 1rem;
}
