/* ═══════════════════════════════════════════════════
   MAP VIEW — NovaEstate
   ═══════════════════════════════════════════════════ */

/* ── Design tokens ── */
#map-view-overlay {
  --mv-gap-1: 4px;
  --mv-gap-2: 8px;
  --mv-gap-3: 12px;
  --mv-gap-4: 16px;
  --mv-gap-5: 20px;
  --mv-radius-sm: 8px;
  --mv-radius-md: 12px;
  --mv-radius-lg: 16px;
  --mv-radius-pill: 999px;
  --mv-btn-size: 40px;
  --mv-shadow-1: 0 2px 8px rgba(0,0,0,0.08);
  --mv-shadow-2: 0 4px 16px rgba(0,0,0,0.12);
  --mv-shadow-3: 0 10px 28px rgba(0,0,0,0.18);
  --mv-border: 1px solid #e5e5ea;
  --mv-accent: #0088FF;
  --mv-accent-hover: #0066DD;
  --mv-bg-card: #ffffff;
  --mv-bg-app: #f5f4f0;
  --mv-text: #111827;
  --mv-text-muted: #6b7280;
  /* z-index scale */
  --mv-z-base: 1;
  --mv-z-controls: 5;
  --mv-z-topbar: 10;
  --mv-z-tooltip: 20;
  --mv-z-overlay: 9999;
  --mv-z-panel: 10001;
  --mv-z-panel-content: 10010;
  --mv-z-modal: 99999;
}

/* ── Overlay ──
   Closed state must be inert — not just transparent. Several children inside
   the overlay (#mv-insets, .mv-inset-wrap, .mapboxgl-ctrl) explicitly set
   `pointer-events: auto`, which overrides the overlay's `pointer-events: none`
   and would otherwise leave the inset maps + Mapbox attribution clickable on
   the underlying search page after the user closes the map view. `visibility:
   hidden` makes the entire subtree unhittable regardless of pointer-events,
   and we delay it past the opacity transition so the close still animates. */
#map-view-overlay {
  position: fixed;
  inset: 0;
  z-index: var(--mv-z-overlay);
  display: flex;
  flex-direction: column;
  background: var(--mv-bg-app);
  opacity: 0;
  pointer-events: none;
  visibility: hidden;
  transition: opacity 0.3s ease, visibility 0s linear 0.3s;
}

#map-view-overlay.open {
  opacity: 1;
  pointer-events: all;
  visibility: visible;
  transition: opacity 0.3s ease, visibility 0s linear 0s;
}

/* ── Top Bar ── */
#map-view-topbar {
  height: 58px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 20px;
  background: white;
  border-bottom: 1px solid #e5e5ea;
  gap: 16px;
  z-index: 10;
}

#map-view-topbar .mv-logo {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 15px;
  font-weight: 600;
  color: #111;
}

#map-view-topbar .mv-logo img {
  height: 26px;
  width: auto;
}



#mv-close-btn {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: 1.5px solid #e5e5ea;
  background: white;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
  color: #374151;
  transition: background 0.15s, border-color 0.15s;
  flex-shrink: 0;
}

#mv-close-btn:hover {
  background: #f3f4f6;
  border-color: #d1d5db;
}

/* ── Search & Filters button ── */
#mv-filter-btn {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 16px;
  height: 36px;
  border-radius: 20px;
  border: 1.5px solid #e5e5ea;
  background: white;
  color: #374151;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s;
  position: relative;
  flex-shrink: 0;
  font-family: inherit;
}

#mv-filter-btn:hover {
  background: #f3f4f6;
  border-color: #d1d5db;
}

.mv-filter-badge {
  position: absolute;
  top: -6px;
  right: -6px;
  min-width: 18px;
  height: 18px;
  border-radius: 9px;
  background: #0088FF;
  color: white;
  font-size: 10px;
  font-weight: 700;
  align-items: center;
  justify-content: center;
  padding: 0 4px;
  border: 2px solid white;
}

/* ── Full-screen search panel ── */
#mv-search-panel {
  position: fixed;
  top: 58px;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 10001;
  display: flex;
  flex-direction: column;
}

/* Actual search form container — frosted glass, animates in/out */
#mv-sp-body {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px 24px 20px;
  background: rgba(255, 255, 255, 0.55);
  backdrop-filter: blur(28px);
  -webkit-backdrop-filter: blur(28px);
  border-bottom: 1px solid rgba(255,255,255,.28);
  flex-shrink: 0;
  overflow: visible;
  /* Opening animation: slide from top + fade */
  transform: translateY(-18px);
  opacity: 0;
  transition: transform 0.28s cubic-bezier(0.4, 0, 0.2, 1),
              opacity 0.22s ease;
}
#mv-search-panel.panel-open #mv-sp-body {
  transform: translateY(0);
  opacity: 1;
}

/* ── hp-search-wrap inside the map panel (desktop ≥ 1200px) ──────────────────
   Keep all of hp-search-wrap's own dark-glass styling untouched — the user
   wants the outer rectangle (#mv-sp-body) to be light, not the pill itself.
   We only need display/visibility for the exact-1200px boundary edge-case
   where the media-query hide rule coincides with the JS breakpoint. ───────── */
#mv-sp-body #hp-search-wrap {
  display: block !important;
  visibility: visible !important;
  position: relative;
  /* Zero the home page's `margin:0 auto` so it doesn't absorb the flex free
     space (which pushed the sibling Find button to the far right). #mv-sp-body's
     justify-content:center keeps the bar + button group centered with a tight
     gap. */
  margin: 0 !important;
}

/* The index page's Find button: a tall blue-gradient capsule with a white
   right-arrow, sitting BESIDE the dark search bar (gap on the left) and spanning
   the FULL bar height. JS lifts the button OUT of hp-search-wrap to be a flex
   sibling here; #mv-sp-body is already a centered flex row. The button click is
   already intercepted → _applyMvSearchFromPanel. */
#mv-sp-body > [data-rmv="find-btn"].mv-find-visible {
  display: flex !important;
  align-self: stretch;            /* full height of the flex line (= the search-bar height) */
  align-items: stretch;
  margin-left: 18px !important;   /* the gap (beats the element's inline margin-left:5px) */
  flex-shrink: 0;
  z-index: 5;
}
#mv-sp-body > [data-rmv="find-btn"].mv-find-visible > #searchBtn {
  /* !important beats the element's inline black/height/radius. */
  height: auto !important;
  align-self: stretch;     /* fill the wrapper → full bar height */
  width: 68px;
  min-width: 68px;
  display: flex !important;
  align-items: center;
  justify-content: center;
  padding: 0 !important;
  border-radius: 26px !important;
  background: linear-gradient(135deg, #4F8DF7 0%, #2563EB 100%) !important;
  background-color: transparent !important;   /* override inline background-color:black */
  color: #fff !important;
  box-shadow: 0 10px 30px rgba(45, 107, 240, 0.5), 0 1px 0 rgba(255, 255, 255, 0.3) inset;
  transition: filter 0.15s, transform 0.1s, box-shadow 0.15s;
}
#mv-sp-body > [data-rmv="find-btn"].mv-find-visible > #searchBtn:hover {
  filter: brightness(1.06);
  transform: translateY(-1px);
  box-shadow: 0 12px 34px rgba(45, 107, 240, 0.6), 0 1px 0 rgba(255, 255, 255, 0.34) inset;
}
#mv-sp-body > [data-rmv="find-btn"].mv-find-visible > #searchBtn i {
  margin: 0 !important;
  font-size: 26px;
}

/* Clickable backdrop below the search form — fades in with panel */
#mv-sp-backdrop {
  flex: 1;
  background: rgba(0,0,0,.45);
  cursor: pointer;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.28s ease;
}
#mv-search-panel.panel-open #mv-sp-backdrop {
  opacity: 1;
  pointer-events: auto;
}

/* AI search container when moved into the map panel */
#mv-sp-body #ai_search_container {
  position: absolute;
  top: 100%;
  left: 24px;
  right: 24px;
  margin-top: 4px;
  z-index: 10010;
}
#mv-sp-body #ai_search_container.ai-open {
  transform: translateY(0) scale(1);
}
/* The page-level #ai_search_filed is dark-glass (sits over the dark hero on the
   search page). Inside the LIGHT map-panel search section it looked like a dark
   blob — restyle it to the panel's light theme so it matches the search bar it
   sits in. Higher specificity (#mv-sp-body …) beats the page rules. */
#mv-sp-body #ai_search_filed {
  background: rgba(255, 255, 255, 0.92);
  border: 1px solid rgba(0, 0, 0, 0.12);
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.14), 0 1px 0 rgba(0, 0, 0, 0.04) inset;
  color: #111;
}
#mv-sp-body #ai_search_filed #search_field_input { color: #111 !important; }
#mv-sp-body #ai_search_filed #search_field_input::placeholder { color: rgba(0, 0, 0, 0.45) !important; }
#mv-sp-body #ai_search_filed #ai_search_clear_btn { background: rgba(0, 0, 0, 0.06) !important; color: rgba(0, 0, 0, 0.55) !important; }
#mv-sp-body #ai_search_filed #ai_search_cancel_btn { background: rgba(0, 0, 0, 0.04) !important; color: rgba(0, 0, 0, 0.6) !important; border-color: rgba(0, 0, 0, 0.12) !important; }

/* ── Main body ── */
#map-view-body {
  flex: 1;
  display: flex;
  min-height: 0;
  overflow: hidden;
}

/* ── Left panel — estate list ── */
#mv-list-panel {
  width: 35%;
  min-width: 320px;
  max-width: 480px;
  display: flex;
  flex-direction: column;
  background: #fff;
  border-right: 1px solid #e5e5ea;
  overflow: hidden;
}

#mv-list-header {
  padding: 14px 16px 10px;
  flex-shrink: 0;
  border-bottom: 1px solid #eee;
}

#mv-list-header h3 {
  font-size: 14px;
  font-weight: 600;
  color: #111;
  margin: 0;
}

#mv-list-header p {
  font-size: 12px;
  color: #9ca3af;
  margin: 2px 0 0;
}

#mv-list-scroll {
  flex: 1;
  overflow-y: auto;
  padding: 10px 12px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

#mv-list-scroll::-webkit-scrollbar { width: 4px; }
#mv-list-scroll::-webkit-scrollbar-thumb { background: #d1d5db; border-radius: 2px; }

/* ── Estate mini card ── */
.mv-estate-card {
  flex-shrink: 0;    /* ✅ ADD — card never shrinks */
  flex-grow: 0;
  background: white;
  border-radius: 16px;
  overflow: hidden;
  border: 1.5px solid #e5e7eb;
  cursor: pointer;
  transition: border-color 0.15s, box-shadow 0.15s, transform 0.12s;
  display: flex;
  flex-direction: column;
}

.mv-estate-card:hover,
.mv-estate-card.highlighted {
  border-color: #0088FF;
  box-shadow: 0 4px 16px rgba(122, 123, 124, 0.12);
  transform: translateY(-1px);
  cursor: pointer;
}

.mv-estate-card.highlighted {
  box-shadow: 0 0 0 2px rgba(0,136,255,0.25), 0 4px 16px rgba(0,136,255,0.15);
}

/* "Pinned" card — the one that's currently drawing the privacy circle on
   the map. Slightly stronger blue ring than .highlighted so it reads as a
   selected state rather than a hover. */
.mv-estate-card.mv-card-active {
  border-color: #0088FF;
  box-shadow: 0 0 0 2px rgba(0, 136, 255, 0.45), 0 6px 20px rgba(0, 136, 255, 0.18);
}

/* "Open listing" pill on top of the card image — paired with the
   fullscreen button to its right. Slightly transparent until hover. */
.mv-card-open {
  opacity: 0.85;
  transition: opacity 0.15s, background 0.15s;
}
.mv-card-open:hover { opacity: 1; background: rgba(0, 0, 0, 0.7) !important; }

.mv-card-img {
  width: 100%;
  height: 140px;
  object-fit: cover;
  display: block;
  background: #e5e7eb;
}

.mv-card-body {
  padding: 10px 12px 12px;
}

/* Desktop: mv-card-body-mobile acts like mv-card-body */
.mv-card-body-mobile {
  padding: 10px 12px 12px;
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.mv-card-price {
  font-size: 17px;
  font-weight: 700;
  color: #111;
  margin: 0 0 3px;
}

.mv-card-title {
  font-size: 13px;
  color: #374151;
  margin: 0 0 4px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.mv-card-location {
  font-size: 11px;
  color: #9ca3af;
  margin: 0 0 8px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.mv-card-features {
  display: flex;
  gap: 12px;
  align-items: center;
}

.mv-card-feat {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 12px;
  color: #6b7280;
}

.mv-card-feat img { width: 14px; height: 14px; }

.mv-card-feat i { font-size: 11px; color: #9ca3af; }

/* ── Load more in list ── */
#mv-list-load-more {
  margin: 8px 12px 14px;
  margin-bottom:8px;
  padding: 10px;
  border-radius: 12px;
  border: 1.5px solid #d1d5db;
  background: transparent;
  color: #6b7280;
  font-size: 13px;
  cursor: pointer;
  transition: border-color 0.15s, color 0.15s;
  flex-shrink: 0;
}

#mv-list-load-more:hover {
  border-color: #0088FF;
  color: #0088FF;
}

/* ── Selected-areas summary (desktop sidebar footer) ── */
.mv-geo-summary {
  flex-shrink: 0;
  border-top: 1px solid #ececec;
  background: #faf9f6;
  padding: 10px 12px;
  max-height: 38%;
  overflow-y: auto;
}
.mv-geosum-head {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: #9ca3af;
  margin-bottom: 8px;
}
.mv-geosum-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 9px;
  border-radius: 9px;
  background: #fff;
  border: 1px solid #eef0f3;
  margin-bottom: 6px;
}
.mv-geosum-row:last-child { margin-bottom: 0; }
.mv-geosum-info { display: flex; flex-direction: column; min-width: 0; flex: 1; line-height: 1.2; }
.mv-geosum-level { font-size: 9px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: #0088FF; }
.mv-geosum-name {
  font-size: 13px; font-weight: 600; color: #0f1e4b; cursor: pointer;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.mv-geosum-name:hover { text-decoration: underline; }
.mv-geosum-stats { display: flex; align-items: center; gap: 5px; font-size: 11px; color: #6b7280; white-space: nowrap; flex-shrink: 0; }
.mv-geosum-stats b { font-weight: 800; color: #0f1e4b; }
.mv-geosum-matched b { color: #0088FF; }
.mv-geosum-dot { color: #c5cad4; }
.mv-geosum-x {
  border: none; background: #f3f4f6; color: #9ca3af;
  width: 20px; height: 20px; border-radius: 50%; flex-shrink: 0; cursor: pointer;
  display: flex; align-items: center; justify-content: center; font-size: 10px;
  transition: background 0.12s, color 0.12s;
}
.mv-geosum-x:hover { background: #ef4444; color: #fff; }

/* ── Loading skeleton for list ── */
.mv-skeleton {
  background: white;
  border-radius: 16px;
  overflow: hidden;
  border: 1.5px solid #e5e7eb;
}

.mv-skeleton-img {
  width: 100%;
  height: 160px;
  background: linear-gradient(90deg, #f3f4f6 25%, #e5e7eb 50%, #f3f4f6 75%);
  background-size: 200% 100%;
  animation: mv-shimmer 1.4s infinite;
}

.mv-skeleton-body { padding: 10px 12px 12px; display: flex; flex-direction: column; gap: 6px; }
.mv-skeleton-line { height: 12px; border-radius: 6px; background: linear-gradient(90deg, #f3f4f6 25%, #e5e7eb 50%, #f3f4f6 75%); background-size: 200% 100%; animation: mv-shimmer 1.4s infinite; }
.mv-skeleton-price { height: 20px; width: 50%; border-radius: 6px; background: linear-gradient(90deg, #f3f4f6 25%, #e5e7eb 50%, #f3f4f6 75%); background-size: 200% 100%; animation: mv-shimmer 1.4s infinite; }
.mv-skeleton-line.w80 { width: 80%; }
.mv-skeleton-line.w55 { width: 55%; }
.mv-skeleton-feats { display: flex; gap: 8px; margin-top: 2px; }
.mv-skeleton-feat { height: 24px; width: 64px; border-radius: 20px; background: linear-gradient(90deg, #f3f4f6 25%, #e5e7eb 50%, #f3f4f6 75%); background-size: 200% 100%; animation: mv-shimmer 1.4s infinite; }

@keyframes mv-shimmer {
  0% { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

/* ── Map/List toggle — hidden on desktop, shown on mobile via media query ── */
#mv-mode-toggle {
  display: none;
}

/* ── Right panel — map ── */
#mv-map-panel {
  flex: 1;
  position: relative;
  min-width: 0;
}

#mv-mapbox {
  width: 100%;
  height: 100%;
}

/* ── Map controls overlay ── */
#mv-map-controls {
  position: absolute;
  top: 14px;
  right: 14px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  z-index: 5;
}

.mv-map-btn {
  width: 36px;
  height: 36px;
  border-radius: 10px;
  background: white;
  border: 1px solid #e5e5ea;
  box-shadow: 0 2px 8px rgba(0,0,0,0.08);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  font-size: 14px;
  color: #374151;
  transition: background 0.15s;
}

.mv-map-btn:hover { background: #f3f4f6; }

/* ── Zoom level badge ── */
#mv-zoom-badge {
  position: absolute;
  bottom: 14px;
  right: 14px;
  background: white;
  border: 1px solid #e5e5ea;
  border-radius: 20px;
  padding: 5px 12px;
  font-size: 12px;
  color: #6b7280;
  box-shadow: 0 2px 8px rgba(0,0,0,0.08);
  pointer-events: none;
  z-index: 5;
}

/* ── "Map not available yet — coming soon" overlay ──────────────
   Replaces the map canvas when the active country has no published
   tileset. Sits above the mapbox container with a soft gradient so it
   reads as an intentional empty state, not a render failure. */
#mv-map-unavailable {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: linear-gradient(135deg, #f3f7fc 0%, #e8eef7 100%);
  z-index: 50;
}
.mv-map-unavailable-card {
  max-width: 420px;
  text-align: center;
  background: #fff;
  border: 1px solid #e5e7eb;
  border-radius: 16px;
  padding: 32px 28px 26px;
  box-shadow: 0 10px 28px rgba(15, 23, 42, 0.08);
}
.mv-map-unavailable-icon {
  width: 56px;
  height: 56px;
  margin: 0 auto 16px;
  border-radius: 50%;
  background: rgba(0, 136, 255, 0.10);
  color: #0088ff;
  font-size: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.mv-map-unavailable-title {
  font-size: 18px;
  font-weight: 700;
  color: #111827;
  margin-bottom: 8px;
}
.mv-map-unavailable-body {
  font-size: 13.5px;
  color: #4b5563;
  line-height: 1.5;
  margin-bottom: 14px;
}
.mv-map-unavailable-country {
  display: inline-block;
  font-size: 13px;
  font-weight: 600;
  color: #0088ff;
  background: rgba(0, 136, 255, 0.08);
  padding: 4px 12px;
  border-radius: 999px;
  margin-bottom: 10px;
}
.mv-map-unavailable-country:empty { display: none; }
.mv-map-unavailable-tag {
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #6b7280;
}



/* Single estate pin */
.mv-pin {
  cursor: pointer;
  transition: transform 0.15s;
}

.mv-pin:hover { transform: scale(1.15) translateY(-2px); }

.mv-pin-inner {
  background: white;
  border: 2px solid #0088FF;
  border-radius: 20px;
  padding: 4px 8px;
  font-size: 12px;
  font-weight: 600;
  color: #0088FF;
  white-space: nowrap;
  box-shadow: 0 2px 10px rgba(0,136,255,0.2);
  display: flex;
  align-items: center;
  gap: 4px;
}

.mv-pin-inner::after {
  content: '';
  position: absolute;
  bottom: -7px;
  left: 50%;
  transform: translateX(-50%);
  width: 0;
  height: 0;
  border-left: 6px solid transparent;
  border-right: 6px solid transparent;
  border-top: 7px solid #0088FF;
}

.mv-pin.active .mv-pin-inner {
  background: #0088FF;
  color: white;
}

.mv-pin.active .mv-pin-inner::after {
  border-top-color: #0088FF;
}

/* ══════════════════════════════════════
   MAPBOX POPUP
══════════════════════════════════════ */

.mapboxgl-popup-content {
  padding: 0 !important;
  border-radius: 16px !important;
  overflow: hidden;
  box-shadow: 0 8px 30px rgba(0,0,0,0.15) !important;
  border: 1px solid #e5e7eb;
  width: 260px;
}

.mapboxgl-popup-close-button {
  font-size: 16px !important;
  color: white !important;
  background: rgba(0,0,0,0.4) !important;
  border-radius: 50% !important;
  width: 24px !important;
  height: 24px !important;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  top: 8px !important;
  right: 8px !important;
  line-height: 1 !important;
}

.mapboxgl-popup-tip { display: none !important; }

.mv-popup {
  font-family: inherit;
}

.mv-popup-img {
  width: 100%;
  height: 150px;
  object-fit: cover;
  display: block;
  background: #e5e7eb;
}

.mv-popup-body {
  padding: 12px 14px 14px;
}

.mv-popup-price {
  font-size: 18px;
  font-weight: 700;
  color: #111;
  margin: 0 0 3px;
}

.mv-popup-title {
  font-size: 13px;
  color: #374151;
  margin: 0 0 4px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.mv-popup-location {
  font-size: 11px;
  color: #9ca3af;
  margin: 0 0 10px;
  display: flex;
  align-items: center;
  gap: 4px;
}

.mv-popup-features {
  display: flex;
  gap: 14px;
  margin-bottom: 12px;
}

.mv-popup-feat {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 12px;
  color: #6b7280;
}

.mv-popup-feat img { width: 14px; height: 14px; }

.mv-popup-btn {
  display: block;
  width: 100%;
  padding: 9px;
  background: #0088FF;
  color: white;
  border: none;
  border-radius: 12px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  text-align: center;
  text-decoration: none;
  transition: background 0.15s;
}

.mv-popup-btn:hover { background: #0066DD; }

/* ══════════════════════════════════════
   ZOOM LEVEL INDICATOR
══════════════════════════════════════ */

#mv-level-indicator {
  position: absolute;
  top: 14px;
  left: 50%;
  transform: translateX(-50%);
  background: white;
  border: 1px solid #e5e5ea;
  border-radius: 20px;
  padding: 5px 14px;
  font-size: 12px;
  font-weight: 500;
  color: #374151;
  box-shadow: 0 2px 8px rgba(0,0,0,0.08);
  pointer-events: none;
  z-index: 5;
  display: flex;
  align-items: center;
  gap: 6px;
  transition: opacity 0.3s;
}

#mv-level-indicator i { font-size: 11px; color: #0088FF; }

/* The level switcher now shows the active level explicitly, so the legacy
   "Viewing X" pill is redundant on desktop. Keep the element in the DOM
   (other code reads/writes its text) but visually hide it. */
#mv-level-indicator { display: none !important; }

/* Floating "click to go deeper" hint — shown while viewing a non-leaf level
   (click-driven leveling: zoom no longer switches levels). */
#mv-drill-hint {
  position: absolute;
  bottom: 18px;
  left: 50%;
  transform: translateX(-50%) translateY(6px);
  background: rgba(255,255,255,0.96);
  border: 1px solid #e9d5ff;          /* light purple, matches the child highlight */
  border-radius: 20px;
  padding: 6px 14px;
  font-size: 12px;
  font-weight: 600;
  color: #6b21a8;                      /* purple-800 */
  box-shadow: 0 2px 10px rgba(0,0,0,0.10);
  pointer-events: none;
  z-index: 6;
  display: flex;
  align-items: center;
  gap: 7px;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.25s ease, transform 0.25s ease;
}
#mv-drill-hint.is-visible { opacity: 1; visibility: visible; transform: translateX(-50%) translateY(0); }
#mv-drill-hint i { font-size: 12px; color: #a855f7; }   /* light purple icon */

/* (The purple focus-and-context "Back" bar was removed per design — the
   focus-drill logic remains but renders no visible bar. See #mv-level-nav
   below for the new major-level dropdown that replaced the top-left controls.) */

/* ══════════════════════════════════════
   EMPTY STATE
══════════════════════════════════════ */

#mv-empty-state {
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 40px 20px;
  text-align: center;
  color: #9ca3af;
  gap: 10px;
}

#mv-empty-state i { font-size: 32px; color: #d1d5db; }
#mv-empty-state p { font-size: 13px; margin: 0; }

/* Mobile sheet elevated above map panel (z-index 10001) when opened from map view */
#mSheet.mv-sheet-elevated {
  z-index: 10002 !important;
}
#mDdHost.mv-dd-elevated {
  z-index: 10003 !important;
}

/* Filters modal must always appear above the elevated sheet */
#filters-modal.open {
  z-index: 10010 !important;
}

/* ══════════════════════════════════════
   SEARCH / MAP LOADER
══════════════════════════════════════ */
#search-loader {
  position: fixed;
  inset: 0;
  z-index: 10015;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.35);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s ease;
}
#search-loader.active {
  opacity: 1;
  pointer-events: auto;
}
#search-loader .sl-box {
  background: #fff;
  border-radius: 18px;
  padding: 28px 36px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  box-shadow: 0 12px 40px rgba(0,0,0,0.18);
  min-width: 160px;
}
#search-loader .sl-ring {
  width: 44px;
  height: 44px;
  border: 3.5px solid #e5e7eb;
  border-top-color: #0088FF;
  border-radius: 50%;
  animation: sl-spin 0.75s linear infinite;
}
@keyframes sl-spin { to { transform: rotate(360deg); } }
#search-loader .sl-text {
  font-size: 13px;
  font-weight: 600;
  color: #374151;
  font-family: Montserrat, sans-serif;
  letter-spacing: 0.01em;
}

/* ══════════════════════════════════════
   RESPONSIVE
══════════════════════════════════════ */

/* ═══════════════════════════════════════════════════════════
   MOBILE (≤768px) — Full-screen map + draggable bottom sheet
   ═══════════════════════════════════════════════════════════ */
@media (max-width: 768px) {

  /* Body: map fills entire area, list panel floats on top */
  #map-view-body {
    position: relative;
    flex-direction: column;
  }

  /* Map: always full height behind the sheet */
  #mv-map-panel {
    position: absolute;
    inset: 0;
    height: 100% !important;
  }

  /* List panel: modern bottom sheet — rounded, soft shadow, snappier states.
     Three snap points the user actually wants:
       collapsed: only the header bar peeks above the bottom (≈92px).
       half:      header + ~2 horizontal cards (≈210px) — much taller than the
                  old 130px so the user sees real content without expanding.
       full:      fills 88% of the viewport.
     Heights tuned for one-handed reach: tap on the header bar to expand, drag
     the whole header area (44px tall handle + h3 row) to fine-tune. */
  #mv-list-panel {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    width: 100%;
    max-width: none;
    height: 88%;
    border-right: none;
    border-top: none;
    border-radius: 22px 22px 0 0;
    box-shadow: 0 -8px 32px rgba(0,0,0,0.18), 0 -1px 0 rgba(0,0,0,0.04);
    z-index: 20;
    transform: translateY(calc(100% - 320px));
    transition: transform 0.34s cubic-bezier(0.32, 0.72, 0, 1);
    will-change: transform;
    overflow: hidden;
    background: #fff;
  }

  /* Snap states applied by JS */
  #mv-list-panel.mv-sheet-collapsed {
    transform: translateY(calc(100% - 92px));  /* only the header bar peeks */
  }
  #mv-list-panel.mv-sheet-half {
    /* Header (~92px) + ~228px for one full vertical card (240×~228 with
       4/3 image area) — bumped from 210px so the new vertical card layout
       isn't cut off mid-image. Half-state still shows roughly one card,
       but the full image and meta are visible instead of a tiny strip. */
    transform: translateY(calc(100% - 320px));
  }
  #mv-list-panel.mv-sheet-full {
    transform: translateY(0);                   /* fully expanded */
  }
  /* Disable transition during drag */
  #mv-list-panel.mv-sheet-dragging {
    transition: none;
  }

  /* Drag handle — the entire 44px strip is the tap/drag target. Far easier
     to grab than the old 22px pill. The visible bar inside is centred. */
  #mv-list-handle {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    height: 44px;
    background: #fff;
    border-radius: 22px 22px 0 0;
    cursor: grab;
    touch-action: none;
    user-select: none;
    -webkit-user-select: none;
    position: relative;
  }
  #mv-list-handle:active { cursor: grabbing; }
  .mv-list-handle-bar {
    display: block;
    width: 44px;
    height: 5px;
    background: #cbd5e0;
    border-radius: 3px;
    transition: background 0.15s, width 0.15s;
  }
  #mv-list-handle:hover .mv-list-handle-bar,
  #mv-list-panel.mv-sheet-collapsed .mv-list-handle-bar {
    background: #94a3b8;
    width: 56px;
  }
  /* The header text under the handle is ALSO part of the drag/tap zone
     (JS binds the same handlers) so the user gets a generous 70px-tall area. */
  #mv-list-header {
    cursor: pointer;
    touch-action: none;
    user-select: none;
    -webkit-user-select: none;
  }

  /* Lock the page underneath when the sheet is fully expanded — stops
     iOS rubber-banding from rocking the map behind. */
  html.mv-sheet-fullscreen,
  html.mv-sheet-fullscreen body {
    overflow: hidden;
    overscroll-behavior: none;
    touch-action: none;
  }

  /* Map/List toggle button — floats above the bottom sheet */
  #mv-mode-toggle {
    position: absolute;
    bottom: 142px; /* sits above the default half-open sheet */
    right: 14px;
    z-index: 21;
    display: flex;
    flex-direction: column;
    gap: 8px;
    pointer-events: auto;
  }
  .mv-toggle-btn {
    width: 42px;
    height: 42px;
    border-radius: 50%;
    border: none;
    background: #fff;
    box-shadow: 0 2px 10px rgba(0,0,0,0.18);
    color: #111;
    font-size: 15px;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background 0.15s, color 0.15s;
  }
  .mv-toggle-btn.active {
    background: #0088FF;
    color: #fff;
  }

  /* Compact header on mobile */
  #mv-list-header {
    padding: 10px 14px 8px;
  }

  /* Horizontal scroll for cards on mobile */
  #mv-list-scroll {
    flex-direction: row;
    overflow-x: auto;
    overflow-y: hidden;
    padding: 8px 12px 12px;
    gap: 10px;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
  }
  #mv-list-scroll::-webkit-scrollbar { display: none; }

  /* ── Mobile peek/half card — VERTICAL layout, same image proportions as
     the search-page property cards (image on top with aspect-ratio 4/3,
     body below). Previously the card was a 280×90 horizontal strip with
     a tiny 110×90 thumbnail — property photos got cropped weirdly because
     a 16:9 source can't fit a 1.22:1 box without aggressive top-clipping.
     Switching to vertical lets the photo render at its natural feel and
     matches what the user sees on the search-results listing. */
  .mv-estate-card {
    flex-direction: column;
    flex-shrink: 0;
    width: 240px;
    height: auto;
    scroll-snap-align: start;
    border-radius: 14px;
    overflow: hidden;
  }

  /* Image: full-width top with 4/3 aspect for the small peek-mode card
     (240px wide → ~180px tall image — neat). The `!important` overrides
     the 160px inline height that _buildMiniCard puts on the slider. */
  .mv-card-slider {
    width: 100%;
    min-width: unset;
    height: auto !important;
    aspect-ratio: 4 / 3;
    border-radius: 14px 14px 0 0;
    flex-shrink: 0;
  }

  /* Hide the inline prev/next arrows on touch viewports — the tap-halves
     gesture (left half of image = prev, right half = next) added in
     map_view.js _buildMiniCard makes them redundant clutter, and at
     24×24 they're too small to hit on a phone anyway. */
  .mv-card-prev,
  .mv-card-next {
    display: none !important;
  }

  /* Info area below the image */
  .mv-card-body-mobile {
    width: 100%;
    padding: 8px 10px 10px;
    display: flex;
    flex-direction: column;
    gap: 3px;
    overflow: hidden;
  }

  /* The slider's track + slides need to stretch to the new aspect-ratio
     parent — without this, height:100% on the slides resolves to 0 when
     the parent uses `height: auto` (only aspect-ratio gives it a height). */
  .mv-card-track,
  .mv-card-track > div {
    height: 100%;
  }

  /* Full-screen list mode: switch to a column-flow scrollable list.
     The card layout itself is already vertical (image-on-top + body) at
     all snap states — fullscreen just spans each card the full panel
     width and stacks them top-to-bottom. */
  #mv-list-scroll.mv-list-vertical {
    flex-direction: column;
    overflow-x: hidden;
    overflow-y: auto;
    scroll-snap-type: none;
  }
  #mv-list-scroll.mv-list-vertical .mv-estate-card {
    width: 100%;
  }
  /* Image height in fullscreen mode — match `.prop-card-img` from the
     search-results page (fixed 210px). At full mobile width the
     previously-applied `aspect-ratio: 4/3` produced a ~270px image
     that ate most of the visible sheet — looked stretched and pushed
     the title/price below the fold. Fixed 210px renders at the same
     proportions the user sees on the search-results listing. */
  #mv-list-scroll.mv-list-vertical .mv-card-slider {
    aspect-ratio: auto !important;
    height: 210px !important;
  }
  #mv-list-scroll.mv-list-vertical .mv-card-body-mobile {
    padding: 10px 12px 12px;
    gap: 4px;
  }

  /* Skeleton adapts to horizontal */
  .mv-skeleton { width: 260px; flex-shrink: 0; }
}

/* ══════════════════════════════════════
   MINI CARD — IMAGE SLIDER
══════════════════════════════════════ */

.mv-card-slider {
  position: relative;
  height: 160px;
  overflow: hidden;
  flex-shrink: 0;
  background: #e5e7eb;
  border-radius: 14px 14px 0 0;
}

.mv-card-track {
  display: flex;
  height: 100%;
  transition: transform 0.3s ease;
  will-change: transform;
}

.mv-card-prev,
.mv-card-next {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  background: rgba(0,0,0,0.45);
  border: none;
  border-radius: 50%;
  width: 28px;
  height: 28px;
  color: white;
  font-size: 11px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: opacity 0.15s;
  z-index: 2;
}

.mv-card-prev { left: 6px; }
.mv-card-next { right: 6px; }

.mv-card-prev:hover,
.mv-card-next:hover {
  background: rgba(0,0,0,0.65);
}

.mv-card-fs {
  position: absolute;
  top: 7px;
  right: 7px;
  background: rgba(0,0,0,0.5);
  border: none;
  border-radius: 50%;
  width: 28px;
  height: 28px;
  color: white;
  font-size: 11px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 2;
  opacity: 0;
  transition: opacity 0.15s;
}

.mv-card-slider:hover .mv-card-fs {
  opacity: 1;
}

.mv-card-counter {
  position: absolute;
  bottom: 7px;
  right: 8px;
  background: rgba(0,0,0,0.55);
  color: white;
  border-radius: 10px;
  padding: 2px 7px;
  font-size: 10px;
  pointer-events: none;
  z-index: 2;
}

/* ══════════════════════════════════════
   LIGHTBOX
══════════════════════════════════════ */

#mv-lightbox {
  position: fixed;
  inset: 0;
  z-index: 99999;
  background: rgba(0,0,0,0.92);
  display: flex;
  align-items: center;
  justify-content: center;
}

/* ── Mapbox attribution: compact but visible (ToS compliance) ── */
#mv-mapbox .mapboxgl-ctrl-bottom-right {
  bottom: 0;
  right: 0;
  z-index: var(--mv-z-controls);
}
#mv-mapbox .mapboxgl-ctrl-attrib {
  background: rgba(255,255,255,0.78);
  font-size: 10px;
  padding: 0 6px;
  border-top-left-radius: var(--mv-radius-sm);
}
#mv-mapbox .mapboxgl-ctrl-attrib a { color: #6b7280; }
#mv-mapbox .mapboxgl-ctrl-logo {
  margin: 0 6px 4px 0;
  transform: scale(0.8);
  transform-origin: bottom right;
  opacity: 0.7;
}
/* Inset maps remain logo-free (their main map carries the attribution) */
.mv-inset-map .mapboxgl-ctrl-bottom-right,
.mv-inset-map .mapboxgl-ctrl-bottom-left { display: none !important; }

/* ══════════════════════════════════════
   INSET MAPS — Madeira / Açores
══════════════════════════════════════ */

#mv-insets {
  position: absolute;
  bottom: 40px;
  left: 10px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  z-index: 5;
  pointer-events: auto;
}

.mv-inset-wrap {
  position: relative;
  width: 150px;
  height: 95px;
  border-radius: 10px;
  overflow: hidden;
  border: 1.5px solid rgba(0, 136, 255, 0.35);
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.18);
  cursor: pointer;
  transition: border-color 0.15s, box-shadow 0.15s;
  background: #e8edf4;
}

.mv-inset-wrap:hover {
  border-color: rgba(0, 136, 255, 0.75);
  box-shadow: 0 4px 16px rgba(0, 136, 255, 0.2);
}

.mv-inset-map {
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.mv-inset-label {
  position: absolute;
  top: 5px;
  left: 6px;
  background: rgba(255, 255, 255, 0.88);
  color: #111;
  font-size: 10px;
  font-weight: 600;
  padding: 2px 7px;
  border-radius: 6px;
  pointer-events: none;
  line-height: 1.5;
  backdrop-filter: blur(2px);
}

@media (max-width: 768px) {
  #mv-insets {
    bottom: auto;
    top: 10px;
    left: 10px;
    flex-direction: row;
    gap: 4px;
  }
  .mv-inset-wrap {
    width: 72px;
    height: 48px;
    border-radius: 8px;
  }
  .mv-inset-label {
    font-size: 9px;
    padding: 1px 5px;
  }

  /* Push the level indicator right so it clears the two mini-maps
     (2 × 72px + 4px gap + 10px left offset = ~168px) */
  #mv-level-indicator {
    left: auto;
    right: 10px;
    transform: none;
  }
}

/* ══════════════════════════════════════
   v2 — UNIFIED CONTROLS, LAYERS, CHIPS
══════════════════════════════════════ */

/* Normalize all icon-buttons (zoom, locate, layer items) to the same size */
.mv-map-btn {
  width: var(--mv-btn-size);
  height: var(--mv-btn-size);
  border-radius: var(--mv-radius-md);
  background: var(--mv-bg-card);
  border: var(--mv-border);
  box-shadow: var(--mv-shadow-1);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  font-size: 14px;
  color: var(--mv-text);
  transition: background 0.15s, transform 0.12s, box-shadow 0.15s;
}
.mv-map-btn:hover {
  background: #f3f4f6;
  box-shadow: var(--mv-shadow-2);
  transform: translateY(-1px);
}
.mv-map-btn:active { transform: translateY(0); }
.mv-map-btn.active,
.mv-map-btn[aria-pressed="true"] {
  background: var(--mv-accent);
  border-color: var(--mv-accent);
  color: #fff;
}

#mv-map-controls {
  gap: var(--mv-gap-2);
}
#mv-map-controls .mv-map-btn-group {
  display: flex;
  flex-direction: column;
  background: var(--mv-bg-card);
  border-radius: var(--mv-radius-md);
  box-shadow: var(--mv-shadow-1);
  border: var(--mv-border);
  overflow: hidden;
}
#mv-map-controls .mv-map-btn-group .mv-map-btn {
  border: none;
  border-radius: 0;
  box-shadow: none;
  background: transparent;
}
#mv-map-controls .mv-map-btn-group .mv-map-btn + .mv-map-btn {
  border-top: 1px solid #f0f0f3;
}
#mv-map-controls .mv-map-btn-group .mv-map-btn:hover {
  background: #f3f4f6;
  transform: none;
  box-shadow: none;
}

/* ── Level navigation row: major-level dropdown (left) + layer switcher (right) ──
   The row is absolutely positioned where the switcher used to sit (top, just left
   of the zoom/satellite controls); its two pills lay out left→right with a gap. */
#mv-level-nav {
  position: absolute;
  top: 14px;
  right: calc(14px + var(--mv-btn-size) + var(--mv-gap-3));
  display: inline-flex;
  align-items: center;
  gap: 8px;
  z-index: var(--mv-z-controls);
}

/* ── Layer switcher (segmented) ── */
#mv-layer-switcher {
  display: inline-flex;
  background: var(--mv-bg-card);
  border: var(--mv-border);
  border-radius: var(--mv-radius-pill);
  padding: 3px;
  box-shadow: var(--mv-shadow-1);
  overflow: hidden;
}

/* ── Major-level area dropdown (a modern pill matching the switcher) ── */
#mv-major-select-wrap {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 34px;
  padding: 0 10px 0 11px;
  background: var(--mv-bg-card);
  border: var(--mv-border);
  border-radius: var(--mv-radius-pill);
  box-shadow: var(--mv-shadow-1);
  color: var(--mv-text);
  transition: border-color 0.15s, box-shadow 0.15s;
}
#mv-major-select-wrap:hover { border-color: var(--mv-accent); }
#mv-major-select-wrap:focus-within {
  border-color: var(--mv-accent);
  box-shadow: 0 0 0 3px rgba(0,136,255,0.18);
}
#mv-major-select-wrap .mv-major-ico { font-size: 12px; color: var(--mv-accent); }
#mv-major-select-wrap .mv-major-caret {
  font-size: 10px;
  color: var(--mv-text-muted);
  pointer-events: none;
}
#mv-major-select {
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  border: none;
  outline: none;
  background: transparent;
  font-family: inherit;
  font-size: 12px;
  font-weight: 600;
  color: var(--mv-text);
  cursor: pointer;
  padding: 0 2px 0 0;
  max-width: 168px;
  text-overflow: ellipsis;
}
/* The placeholder (value="") reads as the muted level label ("State" / "District"). */
#mv-major-select:invalid,
#mv-major-select option[value=""] { color: var(--mv-text-muted); }
/* No areas known yet → dim + non-interactive (keeps the label visible). */
#mv-major-select-wrap.mv-major-empty {
  opacity: 0.55;
  pointer-events: none;
}
.mv-layer-btn {
  display: inline-flex;
  align-items: center;
  padding: 6px 14px;
  border: none;
  background: transparent;
  border-radius: var(--mv-radius-pill);
  font-size: 12px;
  font-weight: 500;
  color: var(--mv-text-muted);
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
  font-family: inherit;
  white-space: nowrap;
}
.mv-layer-btn:hover { color: var(--mv-text); }
.mv-layer-btn.active {
  background: var(--mv-accent);
  color: #fff;
  box-shadow: 0 1px 4px rgba(0,136,255,0.35);
}

/* ── Topbar "Center on country" button ──
   Replaces the old bottom "Clear {zone}" pill. Sits in the topbar
   between the filter button and the close button; visible only when
   exactly one country is selected. Mobile uses the standalone pill
   look; desktop+tablet groups it with #mv-filter-btn into a single
   segmented control via .mv-topbar-actions (rules below). */
#mv-recenter-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 0 14px;
  height: 36px;
  background: var(--mv-bg-card);
  border: 1.5px solid #e5e5ea;
  border-radius: var(--mv-radius-pill);
  font-size: 13px;
  font-weight: 500;
  color: #374151;
  cursor: pointer;
  font-family: inherit;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
  flex-shrink: 0;
}
#mv-recenter-btn:hover {
  background: #f3f4f6;
  border-color: #d1d5db;
}
#mv-recenter-btn i { font-size: 12px; color: #6b7280; }
.mv-recenter-label {
  white-space: nowrap;
}

/* ── Topbar action group — desktop + tablet ──
   Wraps More filters + Center as a single connected control bar on
   the right side of the topbar. The wrapper carries the border + bg;
   the inner buttons drop their own border + bg and share a hairline
   divider. The wrapper uses `margin-left: auto` to push itself + the
   close button to the right, leaving the logo on the far left.

   Mobile (≤768px): the wrapper is transparent and just provides a
   gap between the two buttons; each button still looks like a pill
   on its own.                                                       */
.mv-topbar-actions {
  display: flex;
  align-items: center;
  gap: 8px; /* mobile fallback: small gap between standalone pills */
}

@media (min-width: 769px) {
  .mv-topbar-actions {
    margin-left: auto;
    gap: 0;
    background: white;
    border: 1.5px solid #e5e5ea;
    border-radius: 20px;
    height: 36px;
    transition: border-color 0.15s;
  }
  .mv-topbar-actions:hover {
    border-color: #d1d5db;
  }
  /* Buttons inside the group lose their individual border + radius +
     bg so the wrapper's pill shape becomes the group's silhouette. */
  .mv-topbar-actions > #mv-filter-btn,
  .mv-topbar-actions > #mv-recenter-btn {
    border: none;
    border-radius: 0;
    background: transparent;
    height: 100%;
    padding: 0 14px;
  }
  .mv-topbar-actions > #mv-filter-btn:hover,
  .mv-topbar-actions > #mv-recenter-btn:hover {
    background: #f3f4f6;
    border-color: transparent;
  }
  /* Inner divider between the two buttons */
  .mv-topbar-actions > button + button {
    border-left: 1px solid #e5e5ea;
  }
  /* Round the outermost edges of the first/last visible button so
     hover bg matches the wrapper's rounded ends. */
  .mv-topbar-actions > #mv-filter-btn {
    border-top-left-radius: 18px;
    border-bottom-left-radius: 18px;
  }
  .mv-topbar-actions > #mv-recenter-btn {
    border-top-right-radius: 18px;
    border-bottom-right-radius: 18px;
  }
  /* When recenter is hidden (no country), filter button rounds on
     the right side too so the group still looks like a single pill. */
  .mv-topbar-actions:not(:has(#mv-recenter-btn:not([style*="display: none"]))) > #mv-filter-btn {
    border-radius: 18px;
  }
}

/* ── Country switcher pills (above the chip row) ──
   One pill per country with data. Active country is highlighted. Hidden
   when fewer than 2 countries are available — no point showing a row with
   one disabled-looking pill. */
#mv-country-pills {
  display: none;  /* JS toggles to flex when ≥2 countries are available */
  flex-wrap: nowrap;
  align-items: center;
  gap: 8px;
  padding: 8px var(--mv-gap-5);
  background: #fff;
  border-bottom: var(--mv-border);
  overflow-x: auto;
  scrollbar-width: none;
  flex-shrink: 0;
}
#mv-country-pills::-webkit-scrollbar { display: none; }
.mv-country-pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 14px 6px 8px;
  background: #f1f5fb;
  border: 1px solid #e5e7eb;
  border-radius: var(--mv-radius-pill);
  color: var(--mv-text);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
  flex-shrink: 0;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
}
/* Circled flag — matches search page (.search-cpill img): 18px round avatar */
.mv-country-pill-flag {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  object-fit: cover;
  flex-shrink: 0;
  display: block;
}
.mv-country-pill:hover {
  background: #e7eef9;
  border-color: rgba(0, 136, 255, 0.4);
}
.mv-country-pill.active {
  background: var(--mv-accent);
  border-color: var(--mv-accent);
  color: #fff;
  box-shadow: 0 1px 3px rgba(0, 136, 255, 0.25);
}
/* Disabled: country has no published map tileset yet. Inline opacity
   styling from the JS adds 0.5 — these declarations make sure no hover
   effect fires AND the pill is unfocusable. */
.mv-country-pill.disabled,
.mv-country-pill:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  pointer-events: none;
}
.mv-country-pill.disabled:hover {
  /* Match the resting state colors — no hover lift on disabled pills */
  background: #f1f5fb;
  border-color: #e5e7eb;
}

/* ── Surface-click popup (multi-select with checkbox confirm) ────────
   Mapbox-native Popup anchored to the SURFACE centroid (follows the
   map as you pan/zoom). Wrapped in .mv-surface-popup-wrapper so we
   can override the default chrome and use our own card design. */
.mv-surface-popup-wrapper .mapboxgl-popup-content {
  padding: 0;
  background: transparent;
  box-shadow: none;
  border-radius: 0;
  /* Shrink-wrap the pill. Without this the content block stays ~240px wide
     while the pill is ~175px, leaving a big transparent box to the right of
     the pill (the "what's that in the pill" empty area). */
  width: max-content;
  max-width: none;
}
.mv-surface-popup-wrapper .mapboxgl-popup-tip {
  /* Hide Mapbox's default arrow — the card's own shadow is enough */
  display: none;
}
.mv-surface-popup-wrapper {
  font-family: 'Montserrat', sans-serif;
  z-index: 10000;
  /* OPACITY-ONLY fade. Must NOT animate `transform` here: Mapbox positions the
     popup via `transform: translate(...)` on THIS element, so a transform
     keyframe overrides it and the pill flashes at the top-left origin before
     snapping to the anchor. The little scale-in lives on the inner pill. */
  animation: mvSurfacePopupFade 120ms ease-out;
  max-width: 240px !important;
}
@keyframes mvSurfacePopupFade {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes mvSurfacePillIn {
  from { transform: translateY(3px) scale(0.97); }
  to   { transform: none; }
}
/* ── Standalone surface pill ────────────────────────────────────────
   No card, no name line — JUST the segmented pill, floating at the
   surface centroid, shown on hover (transient) or click (pinned):
       [ {total} total | {matching} matching | ☑ ]
   The surface is identified by the hover highlight + on-map label; the
   name rides along as a native title tooltip. */
.mv-surface-pill {
  display: inline-flex;
  align-items: stretch;
  height: 38px;
  border: 1px solid rgba(15, 30, 75, 0.08);
  border-radius: 10px;
  overflow: hidden;
  background: #fff;
  box-shadow:
    0 1px 2px rgba(0, 0, 0, 0.05),
    0 8px 20px rgba(15, 30, 75, 0.16);
  transform-origin: top center;
  animation: mvSurfacePillIn 130ms ease-out;
}
.mv-surface-pill-seg {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 0 12px;
  line-height: 1;
  color: #0f1e4b;
}
/* hairline dividers — the "|" between the cells */
.mv-surface-pill-seg + .mv-surface-pill-seg,
.mv-surface-pill-check {
  border-left: 1px solid rgba(15, 30, 75, 0.08);
}
.mv-surface-pill-seg b { font-size: 14px; font-weight: 800; }
.mv-surface-pill-seg i {
  font-size: 8.5px;
  font-style: normal;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: #9aa3b2;
  margin-top: 2px;
}
.mv-surface-pill-matching b { color: #0088FF; }
.mv-surface-pill-matching i { color: #0088FF; opacity: 0.65; }
.mv-surface-pill-check {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 12px;
  cursor: pointer;
  transition: background 0.12s;
}
.mv-surface-pill-check:hover { background: #f3f8ff; }
.mv-surface-pill-check input[type="checkbox"] {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
  pointer-events: none;
}
.mv-surface-pill-checkmark {
  flex-shrink: 0;
  width: 17px;
  height: 17px;
  border: 2px solid #cdd4df;
  border-radius: 5px;
  background: #fff;
  position: relative;
  transition: background 0.15s, border-color 0.15s;
}
.mv-surface-pill-check input[type="checkbox"]:checked + .mv-surface-pill-checkmark {
  background: #0088FF;
  border-color: #0088FF;
}
.mv-surface-pill-check input[type="checkbox"]:checked + .mv-surface-pill-checkmark::after {
  content: "";
  position: absolute;
  left: 5px;
  top: 1px;
  width: 4px;
  height: 9px;
  border: solid #fff;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
.mv-surface-pill-check input[type="checkbox"]:focus-visible + .mv-surface-pill-checkmark {
  box-shadow: 0 0 0 3px rgba(0, 136, 255, 0.25);
}
.mv-surface-pill-check:hover .mv-surface-pill-checkmark {
  border-color: #0088FF;
}

/* ── Transient toast ─────────────────────────────────────────────────
   Replaces the old docked surface bar. Selection now happens via the
   checkbox on each surface's map label; the only thing the bottom of the
   map still needs is a brief, non-interactive notice (e.g. "Municipality
   not mapped here."). Bottom-centred, fades in/out, never blocks clicks. */
.mv-toast {
  position: absolute;
  left: 50%;
  bottom: 18px;
  transform: translateX(-50%) translateY(6px);
  max-width: calc(100% - 32px);
  padding: 8px 16px;
  background: rgba(15, 30, 75, 0.92);
  color: #fff;
  font-family: 'Montserrat', sans-serif;
  font-size: 12.5px;
  font-weight: 600;
  line-height: 1.3;
  border-radius: 10px;
  box-shadow: 0 6px 20px rgba(15, 30, 75, 0.28);
  z-index: 7;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.18s ease, transform 0.18s ease;
}
.mv-toast.is-visible { opacity: 1; transform: translateX(-50%) translateY(0); }
@media (max-width: 768px) {
  .mv-toast { bottom: 102px; max-width: calc(100% - 24px); white-space: normal; text-align: center; }
}

/* ── Active-filter chip row ── */
#mv-chip-row {
  display: none;
  flex-wrap: nowrap;
  align-items: center;
  gap: var(--mv-gap-2);
  padding: 8px var(--mv-gap-5);
  background: #faf9f6;
  border-bottom: var(--mv-border);
  overflow-x: auto;
  scrollbar-width: none;
  flex-shrink: 0;
}
#mv-chip-row.visible { display: flex; }
#mv-chip-row::-webkit-scrollbar { display: none; }
.mv-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 8px 5px 12px;
  background: #fff;
  border: var(--mv-border);
  border-radius: var(--mv-radius-pill);
  font-size: 12px;
  font-weight: 500;
  color: var(--mv-text);
  cursor: default;
  white-space: nowrap;
  flex-shrink: 0;
}
/* Non-removable chip (the country pill): no × on the right, so the
   right-padding reserved for it would push the label left of centre. Use
   symmetric padding + no internal gap so the label is centred. */
.mv-chip.mv-chip-static {
  padding: 5px 12px;
  gap: 0;
}

/* Group block: header label + its chips travel together; sets are visually
   separated by a thin divider so the user can read each set as a unit. */
.mv-chip-group {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
  padding-right: var(--mv-gap-3);
  margin-right: var(--mv-gap-2);
  border-right: 1px dashed #d1d5db;
}
.mv-chip-group:last-of-type {
  border-right: none;
  padding-right: 0;
  margin-right: 0;
}
.mv-chip-group-label {
  font-size: 10px;
  font-weight: 700;
  color: var(--mv-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  white-space: nowrap;
  margin-right: 2px;
}

/* Per-category accent so each set has a distinct background tint (location
   blue, type green, price orange, beds purple, ai pink). No icons — the set
   header label tells the user which type each pill is. */
.mv-chip[data-cat="countries"],
.mv-chip[data-cat="communities"],
.mv-chip[data-cat="districts"],
.mv-chip[data-cat="comarcas"],
.mv-chip[data-cat="counties"],
.mv-chip[data-cat="towns"],
.mv-chip[data-cat="zones"],
.mv-chip[data-cat="sp_zonas"],
.mv-chip[data-cat="intermediate_regions"] {
  background: #eef5ff;
  border-color: #cfe2ff;
  color: #1e3a8a;
}

/* Clickable geo chip — hover lift + slight border darken signals the
   text is interactive (centres the map on this surface; the × is the
   only "remove" affordance). */
.mv-chip-clickable .mv-chip-text {
  cursor: pointer;
  transition: color 0.12s ease;
}
.mv-chip-clickable:hover {
  border-color: #93c5fd;
  background: #e0ecff;
}
.mv-chip-clickable .mv-chip-text:hover {
  text-decoration: underline;
}
.mv-chip[data-cat="estate_types"],
.mv-chip[data-cat="sub_estate_types"] {
  background: #ecfdf5;
  border-color: #bbf7d0;
  color: #065f46;
}
.mv-chip[data-cat="price"] {
  background: #fff7ed;
  border-color: #fed7aa;
  color: #9a3412;
}
.mv-chip[data-cat="beds"] {
  background: #faf5ff;
  border-color: #e9d5ff;
  color: #5b21b6;
}
.mv-chip[data-cat="ai"] {
  background: #fdf2f8;
  border-color: #fbcfe8;
  color: #9d174d;
}
.mv-chip-x {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: #f3f4f6;
  color: var(--mv-text-muted);
  border: none;
  font-size: 9px;
  cursor: pointer;
  padding: 0;
  transition: background 0.12s, color 0.12s;
}
.mv-chip-x:hover { background: #ef4444; color: #fff; }
.mv-chip-clear-all {
  border: none;
  background: transparent;
  color: var(--mv-text-muted);
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  padding: 5px 8px;
  margin-left: auto;
  white-space: nowrap;
  flex-shrink: 0;
}
.mv-chip-clear-all:hover { color: #ef4444; text-decoration: underline; }

/* ── Filled-dropdown indicator: small accent dot (issue 1) ──
   Toggled by _mvUpdateDropdownFilledStates() in map_view.js. Scoped under the
   map-view search panel so it doesn't bleed into the regular search page.
   Pinned to the top-right corner of each dropdown so it doesn't push the
   button's icon/label out of place.
   Three responsive variants need it:
     desktop ≥1200px → .dropdown / .dropbtn      (hp-search-wrap)
     tablet  736–1199 → .ts-dd                    (tSearch)
     mobile  ≤735     → .ms-row                   (mSheet rows)
   `--mv-accent` only resolves inside #map-view-overlay; mobile mSheet is a
   sibling under <body>, so the dot has to use the literal #0088FF — using
   the variable there resolved to transparent and rendered as a hollow ring
   (just the box-shadow halo with no fill). */
#mv-sp-body .dropdown,
#mv-sp-body .ts-dd { position: relative; }
#mv-sp-body .dropdown.mv-has-value > .dropbtn::before,
#mv-sp-body .ts-dd.mv-has-value::before,
#mSheet .ms-row.mv-has-value::before {
  content: "";
  position: absolute;
  top: -2px;
  right: -2px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #0088FF;
  box-shadow: 0 0 0 2px rgba(0, 136, 255, 0.18);
  pointer-events: none;
  z-index: 5;
}
/* Mobile mSheet rows are flex columns — anchor the dot to the row's right
   edge with a small inset so it nests inside the rounded card. */
#mSheet .ms-row { position: relative; }
#mSheet .ms-row.mv-has-value::before {
  top: 8px;
  right: 8px;
}

/* ── Result count badge on filter button ── */
.mv-result-count {
  display: inline-flex;
  align-items: center;
  margin-left: 6px;
  padding: 1px 7px;
  background: rgba(0,136,255,0.12);
  color: var(--mv-accent);
  border-radius: var(--mv-radius-pill);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.2px;
}
.mv-result-count.empty { display: none; }

/* ── Polished inset cards ── */
.mv-inset-wrap {
  border-radius: var(--mv-radius-md);
  border: var(--mv-border);
  box-shadow: var(--mv-shadow-2);
  background: #f1f5fb;
  transition: transform 0.15s, box-shadow 0.15s, border-color 0.15s;
}
.mv-inset-wrap:hover {
  transform: translateY(-2px);
  border-color: rgba(0, 136, 255, 0.6);
  box-shadow: var(--mv-shadow-3);
}
.mv-inset-wrap[data-id="mainland"] {
  border-color: rgba(0, 136, 255, 0.55);
  box-shadow: 0 4px 18px rgba(0, 136, 255, 0.18);
}
.mv-inset-wrap[data-id="mainland"]::after {
  content: '\f060';
  font-family: 'Font Awesome 6 Free';
  font-weight: 900;
  position: absolute;
  bottom: 5px;
  right: 6px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--mv-accent);
  color: #fff;
  font-size: 9px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 1px 4px rgba(0,136,255,0.4);
}
.mv-inset-wrap.mv-hidden { display: none !important; }

/* ── Mobile adjustments for new controls ── */
@media (max-width: 768px) {
  /* The whole level-nav row (dropdown + switcher) positions in the top-right and
     is capped to the viewport; the switcher scrolls horizontally within the
     space left by the compact dropdown. */
  #mv-level-nav {
    top: 8px;
    right: 8px;
    max-width: calc(100vw - 16px);
    gap: 6px;
  }
  #mv-layer-switcher {
    padding: 2px;
    min-width: 0;
    overflow-x: auto;
    scrollbar-width: none;
  }
  #mv-layer-switcher::-webkit-scrollbar { display: none; }
  /* Icons were removed, so the text label IS the button on mobile too —
     keep it visible (the bar scrolls horizontally if it runs long). */
  .mv-layer-btn { padding: 5px 10px; font-size: 11px; }
  #mv-major-select-wrap { height: 32px; flex: 0 0 auto; padding: 0 8px 0 9px; }
  #mv-major-select { max-width: 92px; font-size: 11px; }
  #mv-map-controls {
    top: 56px;
    right: 8px;
  }
  #mv-chip-row { padding: 6px 12px; }
}

/* ===== Mobile layout polish (geo panel PR) — appended last so these win ===== */
@media (max-width: 768px) {
  /* (2.2) Compact topbar: shrink the logo + make the action buttons icon-only
     so logo + filters + center + close fit on a ~360px phone without smashing. */
  #map-view-topbar { height: 52px; padding: 0 10px; gap: 8px; }
  .mv-logo img { height: 19px; }
  .mv-topbar-actions { gap: 6px; }
  #mv-filter-btn { padding: 0 11px; height: 34px; gap: 5px; }
  #mv-filter-btn > span[data-i18n="search.more_filters"] { display: none; }
  #mv-recenter-btn { padding: 0; width: 34px; height: 34px; justify-content: center; gap: 0; }
  #mv-recenter-btn .mv-recenter-label { display: none; }
  #mv-close-btn { width: 34px; height: 34px; }

  /* (2.1) Insets move from the top (where they crowded the layer switcher) to
     the BOTTOM-left, above the collapsed sheet. */
  #mv-insets {
    top: auto; bottom: 156px; left: 8px;
    flex-direction: row; gap: 6px;
  }

  /* (2.4) The toast floats ABOVE the sheet so its notice clears the peek. */
  .mv-toast { bottom: 102px; z-index: 26; }

  /* The desktop "Selected areas" panel is redundant on mobile (chips cover it). */
  .mv-geo-summary { display: none !important; }

  /* (2.3) When the sheet is pulled up (half/full) the map is mostly hidden —
     fade out the map-overlay controls instead of letting them smash against the
     sheet's top edge. They return when the sheet is collapsed. */
  #map-view-overlay.mv-sheet-up #mv-insets,
  #map-view-overlay.mv-sheet-up #mv-level-nav,
  #map-view-overlay.mv-sheet-up #mv-map-controls,
  #map-view-overlay.mv-sheet-up #mv-zoom-badge,
  #map-view-overlay.mv-sheet-up .mv-toast {
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.2s ease;
  }
}