/* ===== Map ===== */
.map-wrap{max-width:1280px; margin:0 auto; padding:56px 32px 80px}
.map-head .page-sub{margin-bottom:0}
.map-head{
  display:flex; align-items:flex-end; justify-content:space-between; gap:24px;
  flex-wrap:wrap; margin-bottom:24px;
}
.map-stat{display:flex; align-items:baseline; gap:8px}
.map-stat-num{font-family:var(--serif); font-size:34px; font-weight:600; color:var(--navy)}
.map-stat-lbl{font-size:11px; letter-spacing:.14em; text-transform:uppercase; color:var(--mute)}

.map-layout{display:grid; grid-template-columns:1fr 300px; gap:20px; align-items:start}

.map-canvas{
  position:relative; width:100%; aspect-ratio:1000/620; overflow:hidden;
  background:radial-gradient(120% 100% at 50% 0%, #2A3B4D 0%, #1E2B38 55%, #16202B 100%);
  border-radius:10px; border:1px solid var(--navy3);
  box-shadow:inset 0 0 80px rgba(0,0,0,.45), 0 18px 40px rgba(26,37,48,.18);
}
.map-world{
  position:absolute; inset:0; width:100%; height:100%; display:block;
  fill:#33475C; stroke:#465D75; stroke-width:.6; stroke-linejoin:round;
  vector-effect:non-scaling-stroke;
}
.map-grid{
  position:absolute; inset:0; pointer-events:none; opacity:.5;
  background-image:
    linear-gradient(rgba(197,160,89,.07) 1px, transparent 1px),
    linear-gradient(90deg, rgba(197,160,89,.07) 1px, transparent 1px);
  background-size:8.333% 12.5%;
}
.map-legend{
  position:absolute; left:16px; bottom:14px; display:flex; align-items:center; gap:8px;
  font-size:10.5px; letter-spacing:.06em; color:rgba(249,248,244,.55); pointer-events:none;
}
.map-legend-dot{width:8px; height:8px; border-radius:50%; background:var(--gold); flex:none}

/* --- Pins --- */
.map-pin{
  position:absolute; width:34px; height:34px; margin:-17px 0 0 -17px; z-index:4;
  display:flex; align-items:center; justify-content:center; cursor:pointer;
  border-radius:50%; outline-offset:3px;
}
.map-pin-dot{
  width:13px; height:13px; border-radius:50%; background:var(--gold);
  border:2px solid rgba(255,255,255,.9); box-shadow:0 2px 8px rgba(0,0,0,.5);
  transition:transform .18s ease, background .18s ease;
}
.map-pin-pulse{
  position:absolute; width:13px; height:13px; border-radius:50%;
  box-shadow:0 0 0 0 rgba(197,160,89,.55); animation:pinPulse 2.6s ease-out infinite;
}
@keyframes pinPulse{
  0%{box-shadow:0 0 0 0 rgba(197,160,89,.5)}
  70%{box-shadow:0 0 0 15px rgba(197,160,89,0)}
  100%{box-shadow:0 0 0 0 rgba(197,160,89,0)}
}
.map-pin:hover, .map-pin:focus-visible, .map-pin.is-active{z-index:6}
.map-pin:hover .map-pin-dot,
.map-pin:focus-visible .map-pin-dot,
.map-pin.is-active .map-pin-dot{transform:scale(1.5); background:#fff}
.map-pin:hover .map-pin-pulse,
.map-pin.is-active .map-pin-pulse{animation:none}

/* --- Hover label --- */
.map-label{
  position:absolute; transform:translate(-50%, calc(-100% - 22px));
  background:var(--navy); color:#fff; padding:8px 12px; border-radius:6px;
  white-space:nowrap; pointer-events:none; z-index:5;
  border:1px solid var(--navy3); box-shadow:0 10px 24px rgba(0,0,0,.4);
  display:flex; flex-direction:column; gap:2px;
  opacity:0; transition:opacity .15s ease, transform .15s ease;
}
.map-label::after{
  content:""; position:absolute; left:50%; bottom:-5px; width:9px; height:9px;
  margin-left:-4.5px; background:var(--navy); border-right:1px solid var(--navy3);
  border-bottom:1px solid var(--navy3); transform:rotate(45deg);
}
.map-label.is-visible{opacity:1; transform:translate(-50%, calc(-100% - 16px))}
.map-label-name{font-size:12.5px; font-weight:600}
.map-label-meta{font-size:10.5px; color:var(--gold-light); letter-spacing:.04em}

/* --- Side list --- */
.map-list{
  background:var(--white); border:1px solid var(--line); border-radius:10px;
  overflow:hidden; max-height:calc(100vw * 0.44); overflow-y:auto;
}
.map-list-head{
  font-size:10.5px; letter-spacing:.16em; text-transform:uppercase; color:var(--mute);
  font-weight:700; padding:14px 16px; border-bottom:1px solid var(--line); background:var(--cream);
  position:sticky; top:0;
}
.map-list-item{
  display:flex; align-items:center; justify-content:space-between; gap:10px;
  padding:13px 16px; border-bottom:1px solid #F0EDE6; cursor:pointer;
  transition:background .15s ease, box-shadow .15s ease;
}
.map-list-item:last-child{border-bottom:0}
.map-list-item:hover, .map-list-item:focus-visible, .map-list-item.is-active{
  background:var(--cream); box-shadow:inset 3px 0 0 var(--gold);
}
.map-list-main{display:flex; flex-direction:column; gap:3px; min-width:0}
.map-list-name{font-size:13px; font-weight:600; color:var(--ink)}
.map-list-loc{font-size:11px; color:var(--mute)}
.map-list-rating{font-size:12px; font-weight:600; color:var(--gold-dark); flex:none}

@media (max-width:900px){
  .map-layout{grid-template-columns:1fr}
  .map-list{max-height:340px}
  .map-wrap{padding:40px 20px}
}

@media (prefers-reduced-motion:reduce){
  .map-pin-pulse{animation:none}
  .map-label{transition:none}
}


/* --- Region filters --- */
.map-regions{
  display:flex; flex-wrap:wrap; gap:8px; margin:0 0 14px;
}
.map-region{
  display:inline-flex; align-items:center; gap:7px;
  padding:7px 13px; border:1px solid var(--line); border-radius:999px;
  background:var(--white); color:var(--ink); text-decoration:none;
  font-size:12.5px; line-height:1; white-space:nowrap;
  transition:border-color .15s, background .15s;
}
.map-region:hover{border-color:var(--gold)}
.map-region.is-active{border-color:var(--gold); background:rgba(191,155,90,.12); font-weight:600}
.map-region-badge{
  display:inline-flex; align-items:center; justify-content:center;
  min-width:20px; height:20px; padding:0 6px; border-radius:999px;
  background:var(--gold); color:#fff; font-size:11px; font-weight:700;
}
.map-region.is-active .map-region-badge{background:var(--navy, #1A2530)}

/* Hidden by a region filter — not display:none, so the pin keeps its place in
   the layout and animates back rather than jumping. */
.map-pin.is-filtered,
.map-list-item.is-filtered{display:none}

.map-list-head-sub{margin-top:14px; opacity:.75}
.map-list-item.is-unmapped{opacity:.62}

/* --- Cluster markers --- */
/* A numbered disc where several spas sit too close to tell apart. Sized by
   its digit count so a three-figure group does not spill out of the circle. */
.map-cluster{
  position:absolute; z-index:5; transform:translate(-50%,-50%);
  display:flex; align-items:center; justify-content:center;
  min-width:26px; height:26px; padding:0 7px;
  border-radius:999px; border:2px solid #fff;
  background:var(--gold); color:#fff; text-decoration:none;
  font-size:12px; font-weight:700; line-height:1;
  box-shadow:0 2px 8px rgba(0,0,0,.35);
  transition:transform .15s;
}
.map-cluster:hover,
.map-cluster:focus-visible{transform:translate(-50%,-50%) scale(1.15); z-index:7}
.map-cluster-num{pointer-events:none}
.map-cluster.is-filtered{display:none}

/* --- The live (Leaflet) map --- */
/* Sits on top of the server-rendered SVG and only becomes visible once the
   upgrade has actually succeeded, so a Leaflet that fails to load or throws
   leaves the static map exactly as it was. */
.map-live{position:absolute; inset:0; z-index:8; display:none}
.map-canvas.is-live .map-live{display:block}
/* The SVG, its pins and its cluster markers step aside together — but stay in
   the DOM, since .is-live is only added after the live map is built. */
.map-canvas.is-live .map-world,
.map-canvas.is-live .map-pin,
.map-canvas.is-live .map-label,
.map-canvas.is-live .map-cluster,
.map-canvas.is-live .map-legend{display:none}

/* Leaflet paints its own background; without this the dark canvas shows
   through the tile seams while they load. */
.map-live .leaflet-container{
  width:100%; height:100%; background:#EAF0F4;
  font:inherit;
}
.map-live-name{font-weight:600; color:var(--ink); text-decoration:none}
.map-live-name:hover{text-decoration:underline}
.map-live-meta{margin-top:3px; font-size:12px; color:var(--sub)}

/* "Use my location" — Leaflet's own bar styling, with a busy and a denied
   state so a press that goes nowhere still reads as having been received. */
.map-locate a{
  font-size:16px; line-height:30px; text-align:center;
  color:var(--ink); text-decoration:none;
}
.map-locate.is-busy a{opacity:.45; cursor:progress}
.map-locate.is-denied a{color:var(--bad-fg, #A6362F)}
