/* ==========================================================================
   PeakSeeker — Resort Globe hero
   Full-bleed 3D globe as the Discover page's opening view. Matches the
   existing dark navy / red PeakSeeker palette + Montserrat headers. Drop
   this file in alongside your other stylesheets — nothing here depends on
   Tailwind utility classes.
   ========================================================================== */

.rg-hero {
  --rg-navy: #0b1026;
  --rg-navy-2: #121a3a;
  --rg-card: #161f42;
  --rg-red: #e63946;
  --rg-red-2: #ff5b6a;
  --rg-ice: #bfe4ff;
  --rg-sun: #ffb454;
  --rg-stone: #c9ac78;
  --rg-text: #eef2ff;
  --rg-text-dim: #9aa4c7;
  --rg-border: rgba(255, 255, 255, 0.1);

  position: relative;
  width: 100%;
  height: 100vh;
  height: 100dvh;
  min-height: 560px;
  max-height: 980px;
  overflow: hidden;
  background: radial-gradient(120% 140% at 50% -10%, var(--rg-navy-2) 0%, var(--rg-navy) 55%, #05070f 100%);
  color: var(--rg-text);
  font-family: "Inter", system-ui, sans-serif;
}

/* rg-globe-viewport wraps the globe canvas plus everything scoped to it
   (loading/context-lost states, the tap popup, the pinch-to-zoom hint) — see
   the HTML comment in v2-explore.html for why. On desktop this is simply
   the old full-bleed absolute box behind the hero text, unchanged. On mobile
   (below) it becomes a normal in-flow block with its own fixed height. */
.rg-globe-viewport {
  position: absolute;
  inset: 0;
  z-index: 1;
}

.rg-globe-wrap {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: #05070f;
}

.rg-globe-wrap canvas { outline: none; }

.rg-globe-canvas {
  position: absolute;
  inset: 0;
  cursor: grab;
  /* A native, browser-level guarantee that doesn't depend on any three.js
     internals at all: it tells the browser's own gesture compositor that a
     single-finger VERTICAL drag on this element is a PAGE SCROLL, full stop,
     decided before any JS touchmove handler gets a chance to claim or
     preventDefault it. This is what actually keeps the page scrollable with
     one finger over the globe — resort-globe.js's OrbitControls setup lets a
     single finger rotate the globe (touches.ONE = ROTATE, its default) for
     mostly-HORIZONTAL drags, the one axis this rule doesn't reserve for
     native scroll; a two-finger gesture (pinch/pan-to-rotate) is a distinct
     gesture the browser recognizes separately and is unaffected either way. */
  touch-action: pan-y;
}

.rg-globe-canvas:active { cursor: grabbing; }

.rg-loading {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  gap: 10px;
  color: var(--rg-text-dim);
  font-size: 0.85rem;
  z-index: 8;
  transition: opacity 0.4s ease;
  pointer-events: none;
  background: var(--rg-navy);
}

.rg-loading .rg-spinner {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, 0.15);
  border-top-color: var(--rg-ice);
  animation: rg-spin 0.9s linear infinite;
}

@keyframes rg-spin {
  to { transform: rotate(360deg); }
}

/* ---- WebGL context-loss fallback ---- */
/* Hidden by default; resort-globe.js toggles .rg-visible on a real
   'webglcontextlost' event. A lost GPU context leaves the canvas frozen
   with no error of its own, so this swaps in an honest message + a manual
   reload (recovering the full three-globe scene in place isn't attempted —
   too much to safely rebuild for how rarely this actually fires) rather
   than leaving a dead, silently-broken hero. */
.rg-context-lost {
  position: absolute;
  inset: 0;
  z-index: 10;
  display: none;
  align-items: center;
  justify-content: center;
  background: var(--rg-navy);
  padding: 24px;
}

.rg-context-lost.rg-visible { display: flex; }

.rg-context-lost-inner {
  max-width: 360px;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
}

.rg-context-lost-inner p {
  color: var(--rg-text-dim);
  font-size: 0.85rem;
  line-height: 1.5;
  margin: 0;
}

.rg-context-lost-inner button {
  font-size: 0.78rem;
  font-weight: 700;
  color: var(--rg-text);
  background: rgba(255,255,255,0.08);
  border: 1px solid var(--rg-border);
  padding: 9px 18px;
  border-radius: 999px;
  cursor: pointer;
}

.rg-context-lost-inner button:hover { border-color: var(--rg-red); }

/* ---- hero overlay content (sits above the globe, transparent to drag) ---- */
.rg-hero-scrim {
  position: absolute;
  inset: 0;
  z-index: 4;
  pointer-events: none;
  background:
    linear-gradient(180deg, rgba(5,7,15,0.72) 0%, rgba(5,7,15,0.12) 32%, rgba(5,7,15,0.05) 62%, rgba(5,7,15,0.55) 100%);
}

.rg-hero-content {
  position: absolute;
  inset: 0;
  z-index: 5;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: 88px 20px 20px;
  pointer-events: none;
}

@media (min-width: 768px) {
  .rg-hero-content { padding: 104px 48px 28px; }
}

/* Mobile: earlier fixes here (trimming hero copy to one line, darkening the
   scrim) tried to make the overlaid text/buttons coexist with the globe
   underneath them, but the underlying problem was the overlay itself — text,
   two CTA buttons, a legend, zoom controls and a search box all sharing the
   exact same screen area as the globe, fighting the globe for taps and
   burying pins behind chrome that was only pointer-events:none where nothing
   was drawn. Given room isn't something you can win back via padding tweaks
   when everything's still stacked in the same box, this replaces the overlay
   with a real stacked layout on mobile: hero text/CTAs in normal document
   flow, THEN the globe as its own fixed-height block nothing else draws on
   top of, THEN the legend/zoom/search controls below that — see
   #rg-globe-viewport and the .rg-hero-content/.rg-hero-top/.rg-hero-bottom
   rules further down. Desktop is untouched: plenty of room there for the
   original overlay treatment. */
@media (max-width: 767px) {
  .rg-hero {
    height: auto;
    min-height: 0;
    max-height: none;
    overflow: visible;
    display: flex;
    flex-direction: column;
  }

  /* The globe's own dedicated slice of screen — no text or controls drawn
     on top of it any more, just the canvas and its popup/loading states.
     46vh keeps it a genuinely usable, tappable/draggable area on a typical
     phone (~330-420px tall) without pushing the legend/search row below the
     fold on shorter screens. */
  .rg-globe-viewport {
    position: relative;
    inset: auto;
    order: 2;
    flex: 0 0 auto;
    width: 100%;
    height: 46vh;
    min-height: 300px;
    max-height: 460px;
    border-top: 1px solid var(--rg-border);
    border-bottom: 1px solid var(--rg-border);
  }

  /* Nothing overlays the globe on mobile any more, so the scrim (whose only
     job was separating overlaid text from the globe behind it) has nothing
     left to do here — hide it rather than needlessly darken the globe. */
  .rg-hero-scrim { display: none; }

  /* .rg-hero-content used to be a single position:absolute box covering the
     whole hero, with .rg-hero-top/.rg-hero-bottom stacked inside it via
     flex + justify-content:space-between so they landed at the very top and
     very bottom of that box. display:contents removes .rg-hero-content's own
     box entirely (its old padding/position/flex rules are moot here) and
     promotes its two children to be direct flex items of .rg-hero itself,
     so they can be given their own order/spacing independent of one
     another — text above the globe, controls below it. */
  .rg-hero-content { display: contents; }

  .rg-hero-top {
    order: 1;
    position: relative;
    pointer-events: auto;
    padding: 28px 16px 18px;
  }

  .rg-hero-copy { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; margin-bottom: 12px; }

  .rg-hero-bottom {
    order: 3;
    position: relative;
    pointer-events: auto;
    padding: 14px 16px 28px;
  }
}

.rg-hero-top { max-width: 760px; }

.rg-hero-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--rg-red-2);
  margin-bottom: 6px;
}

.rg-hero-title {
  font-family: "Montserrat", sans-serif;
  font-weight: 900;
  line-height: 1.02;
  letter-spacing: -0.02em;
  font-size: clamp(2.2rem, 7vw, 4.6rem);
  color: #fff;
  text-shadow: 0 4px 30px rgba(0,0,0,0.55);
  margin: 0 0 10px;
}

.rg-hero-copy {
  font-size: clamp(0.85rem, 1.6vw, 1.05rem);
  color: rgba(238,242,255,0.86);
  max-width: 640px;
  text-shadow: 0 2px 16px rgba(0,0,0,0.5);
  margin: 0 0 18px;
}

.rg-hero-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  pointer-events: auto;
}

.rg-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-weight: 700;
  font-size: 0.85rem;
  padding: 12px 20px;
  border-radius: 14px;
  border: none;
  cursor: pointer;
  text-decoration: none;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
  box-shadow: 0 8px 24px rgba(0,0,0,0.35);
}

.rg-btn:hover { transform: translateY(-1px); }
.rg-btn:active { transform: scale(0.97); }

.rg-btn-primary { background: linear-gradient(135deg, #1a2a6c, #001255); color: #fff; }
.rg-btn-accent { background: linear-gradient(135deg, #ff5b3d, #b51c00); color: #fff; }

/* ---- bottom row: legend + zoom tier + jump search ---- */
.rg-hero-bottom {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  pointer-events: none;
}

@media (max-width: 767px) {
  .rg-hero-bottom { flex-direction: column; align-items: stretch; gap: 10px; }
  .rg-legend { order: 2; overflow-x: auto; flex-wrap: nowrap; padding-bottom: 2px; }
  .rg-legend span { flex: 0 0 auto; }
  .rg-zoom-tier-wrap { order: 1; justify-content: flex-end; }
  #rg-zoom-tier { display: none; }
  .rg-reset-view { display: inline-flex; }
  .rg-jump { order: 3; max-width: none; }
}

.rg-legend {
  display: flex;
  gap: 14px;
  font-size: 0.76rem;
  color: var(--rg-text-dim);
  flex-wrap: wrap;
  pointer-events: auto;
}

.rg-legend span {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: rgba(5,7,15,0.55);
  backdrop-filter: blur(6px);
  padding: 5px 10px 5px 8px;
  border-radius: 999px;
  border: 1px solid var(--rg-border);
}

.rg-legend i {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  display: inline-block;
}

.rg-legend .snowy i { background: var(--rg-ice); box-shadow: 0 0 8px var(--rg-ice); }
.rg-legend .warm i { background: var(--rg-sun); box-shadow: 0 0 8px var(--rg-sun); }
.rg-legend .neutral i { background: #7d8bb8; }
.rg-legend .summit i { background: var(--rg-stone); }

.rg-zoom-tier-wrap {
  display: flex;
  align-items: center;
  gap: 8px;
  pointer-events: auto;
}

#rg-zoom-tier {
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--rg-text-dim);
  background: rgba(5,7,15,0.55);
  backdrop-filter: blur(6px);
  border: 1px solid var(--rg-border);
  padding: 6px 12px;
  border-radius: 999px;
  white-space: nowrap;
}

.rg-reset-view {
  font-size: 0.72rem;
  font-weight: 700;
  color: var(--rg-text);
  background: rgba(5,7,15,0.55);
  backdrop-filter: blur(6px);
  border: 1px solid var(--rg-border);
  padding: 6px 12px;
  border-radius: 999px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  opacity: 0;
  transform: translateY(4px) scale(0.95);
  pointer-events: none;
  transition: opacity 0.2s ease, transform 0.2s ease;
}

.rg-reset-view.rg-visible {
  opacity: 1;
  transform: translateY(0) scale(1);
  pointer-events: auto;
}

.rg-reset-view:hover { border-color: var(--rg-red); }

/* ---- jump-to-resort search ---- */
.rg-jump {
  position: relative;
  pointer-events: auto;
  width: 100%;
  max-width: 320px;
}

.rg-jump-input-wrap {
  display: flex;
  align-items: center;
  gap: 8px;
  background: rgba(12,17,40,0.72);
  backdrop-filter: blur(10px);
  border: 1px solid var(--rg-border);
  border-radius: 14px;
  padding: 10px 14px;
}

.rg-jump-input-wrap .material-symbols-outlined {
  color: var(--rg-text-dim);
  font-size: 18px;
}

.rg-jump input {
  flex: 1;
  background: transparent;
  border: none;
  outline: none;
  color: var(--rg-text);
  font-size: 0.85rem;
  font-family: inherit;
}

.rg-jump input::placeholder { color: var(--rg-text-dim); }

.rg-jump-dropdown {
  position: absolute;
  left: 0;
  right: 0;
  bottom: calc(100% + 8px);
  background: rgba(12,17,40,0.96);
  backdrop-filter: blur(10px);
  border: 1px solid var(--rg-border);
  border-radius: 14px;
  padding: 6px;
  max-height: 260px;
  overflow-y: auto;
  display: none;
  flex-direction: column;
  gap: 4px;
  box-shadow: 0 20px 40px rgba(0,0,0,0.5);
}

.rg-jump-dropdown.rg-open { display: flex; }

/* ---- scroll-vs-zoom hint pill (fades in briefly the first time a plain
   scroll gets caught and redirected to page-scroll instead of globe-zoom;
   toggled via JS adding/removing .rg-visible) ---- */
.rg-scroll-hint {
  position: absolute;
  left: 50%;
  bottom: 130px;
  transform: translateX(-50%) translateY(6px);
  z-index: 6;
  max-width: min(86vw, 360px);
  text-align: center;
  font-size: 0.76rem;
  font-weight: 600;
  line-height: 1.35;
  color: var(--rg-text);
  background: rgba(5,7,15,0.78);
  backdrop-filter: blur(8px);
  border: 1px solid var(--rg-border);
  padding: 8px 16px;
  border-radius: 16px;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.25s ease, transform 0.25s ease;
}

.rg-scroll-hint.rg-visible {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

@media (max-width: 767px) {
  /* Relative to #rg-globe-viewport now (its own ~46vh box), not the whole
     hero, so this just needs to clear the bottom edge of that box — not the
     legend/search row any more, since that row lives below the viewport in
     normal flow instead of overlaying it. */
  .rg-scroll-hint { bottom: 14px; }
}

/* ---- scroll cue ---- */
.rg-scroll-cue {
  position: absolute;
  left: 50%;
  bottom: 14px;
  transform: translateX(-50%);
  z-index: 5;
  color: rgba(238,242,255,0.7);
  pointer-events: auto;
  animation: rg-bob 2s ease-in-out infinite;
  text-decoration: none;
}

.rg-scroll-cue .material-symbols-outlined { font-size: 26px; }

@keyframes rg-bob {
  0%, 100% { transform: translateX(-50%) translateY(0); }
  50% { transform: translateX(-50%) translateY(6px); }
}

/* ---- pin markers ----
   badge (icon) + stem + ground shadow, so a pin reads as actually planted
   on the terrain rather than a flat dot floating in space — matters once
   you're deep-zoomed into satellite tiles, where pins now stay visible. */
.rg-pin {
  position: relative;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: center;
  transform: translate(-50%, -100%);
  /* THE globe-wide "pins/clusters don't respond to taps or clicks at all"
     bug: the marker library wraps every .rg-pin/.rg-cluster in its own
     per-item positioning div with pointer-events: none (deliberately, so
     the whole html-elements layer doesn't block drag-to-rotate on the
     canvas beneath it) — and nothing here was ever re-enabling pointer
     events on the actual marker. pointer-events inherits, so with no rule
     setting it back to auto, .rg-pin/.rg-cluster themselves were computed
     pointer-events: none, meaning the browser never dispatched a click,
     mouse, or touch event to them in the first place — wireActivation()'s
     listeners below were correctly wired but structurally unreachable.
     This is why prior verification (synthetic dispatchEvent() calls in a
     test script) looked fine: dispatchEvent() invokes a target's listeners
     directly and skips hit-testing/pointer-events entirely, so it couldn't
     catch this. A real tap or click, which does go through hit-testing,
     always fell through to whatever was underneath (the canvas, or page
     chrome sitting above it) instead of reaching the pin. */
  pointer-events: auto;
  /* Same reasoning as .rg-globe-canvas's touch-action rule above — a pin's
     own generous hit-slop (see .rg-pin::before below) means a scroll swipe
     that merely passes near a pin, not just squarely on the bare canvas, is
     just as likely to land here first at "jam packed" world-view density.
     Without this, that swipe would be a normal DOM touchmove this element
     could (depending on any ancestor's JS) end up swallowing instead of
     handing to the browser's native scroll. */
  touch-action: pan-y;
  /* z-index alone only ranks siblings within a stacking context — .rg-pin
     already forms one via its own `transform`, so without this the inner
     .rg-pin-marker's hover z-index only wins against ITS OWN stem/shadow,
     not against a neighboring pin's marker. Bumping .rg-pin's own z-index on
     hover/focus is what actually lifts a pin above a nearby one in a dense
     cluster (Chamonix/Zermatt-style close pins) instead of staying tucked
     behind it. */
  z-index: 1;
  outline: none;
}

.rg-pin:hover,
.rg-pin:focus-within { z-index: 20; }

/* Invisible hit-slop: the visible badge got bumped up from a fiddly 20px dot
   to a more legible size (users reported pins were "nuts small" once
   zoomed in), but a sphere you're also trying to drag-rotate still benefits
   from a hit zone bigger than the badge itself, especially on touch. A
   pseudo-element hit zone widens what's clickable without changing what's
   drawn; clicks on it still dispatch to .rg-pin itself (pseudo-elements
   aren't separate DOM nodes for event purposes). */
.rg-pin::before {
  content: "";
  position: absolute;
  inset: -16px -20px;
  z-index: 0;
}

.rg-pin-marker {
  display: flex;
  flex-direction: column;
  align-items: center;
  transition: transform 0.18s cubic-bezier(0.34, 1.56, 0.64, 1);
  animation: rg-pin-drop 0.55s cubic-bezier(0.34, 1.56, 0.64, 1) both;
}

.rg-pin:hover .rg-pin-marker,
.rg-pin:focus-within .rg-pin-marker { transform: scale(1.28) translateY(-2px); }

/* Keyboard focus: pins are now tabindex="0" + Enter/Space-activatable (were
   click-only). :focus-within already covers the hover-equivalent scale/label
   reveal above; this adds a visible ring on the badge itself so keyboard
   navigation has a real focus indicator instead of relying on the subtle
   scale-up alone. */
.rg-pin:focus-visible .rg-pin-badge {
  outline: 2px solid #fff;
  outline-offset: 3px;
}

@keyframes rg-pin-drop {
  from { opacity: 0; transform: translateY(-16px) scale(0.35); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}

.rg-pin-badge {
  position: relative;
  /* Was a fixed 20px — read as "nuts small" once zoomed in on the globe,
     since this is a flat screen-space CSS size that doesn't grow as you fly
     closer to the terrain underneath it. Bumped ~50% larger; var()'d like
     .rg-cluster-badge in case a per-zoom-tier size ever wants tuning later. */
  width: var(--rg-pin-size, 30px);
  height: var(--rg-pin-size, 30px);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 2px solid rgba(255, 255, 255, 0.85);
  box-sizing: border-box;
}

.rg-pin-badge .rg-icon-fallback,
.rg-popup-stat .rg-icon-fallback {
  line-height: 1;
  position: relative;
  z-index: 1;
}

.rg-pin-badge .rg-icon-fallback { font-size: 15px; display: inline-block; filter: drop-shadow(0 1px 1px rgba(0,0,0,0.35)); }

.rg-pin-halo {
  position: absolute;
  inset: -7px;
  border-radius: 50%;
  pointer-events: none;
}

.rg-pin-stem {
  width: 3px;
  height: 13px;
  background: linear-gradient(rgba(255,255,255,0.75), rgba(255,255,255,0.05));
  margin-top: -1px;
}

.rg-pin-shadow {
  width: 13px;
  height: 4px;
  border-radius: 50%;
  background: rgba(0,0,0,0.45);
  filter: blur(1px);
  margin-top: -1px;
}

.rg-pin.rg-snowy .rg-pin-badge {
  background: radial-gradient(circle at 35% 30%, #d6f1ff, #7fd4ff 70%);
  box-shadow: 0 0 12px 2px rgba(127, 212, 255, 0.7), 0 2px 6px rgba(0,0,0,0.35);
}

.rg-pin.rg-snowy .rg-pin-halo {
  border: 1.5px solid rgba(191, 228, 255, 0.6);
  animation: rg-ping 2.4s cubic-bezier(0,0,0.2,1) infinite;
  will-change: transform, opacity;
}

@keyframes rg-ping {
  0% { transform: scale(0.7); opacity: 0.85; }
  75%, 100% { transform: scale(1.9); opacity: 0; }
}

.rg-pin.rg-warm .rg-pin-badge {
  background: radial-gradient(circle at 35% 30%, #ffe0b0, #ff9d4d 70%);
  box-shadow: 0 0 12px 2px rgba(255, 180, 84, 0.6), 0 2px 6px rgba(0,0,0,0.35);
}

.rg-pin.rg-warm .rg-pin-halo {
  border: 1.5px solid rgba(255, 180, 84, 0.45);
  animation: rg-ping 4.2s cubic-bezier(0,0,0.2,1) infinite;
  will-change: transform, opacity;
}

.rg-pin.rg-neutral .rg-pin-badge {
  background: radial-gradient(circle at 35% 30%, #a9b3d8, #55628f 70%);
  box-shadow: 0 0 8px 1px rgba(125, 139, 184, 0.45), 0 2px 6px rgba(0,0,0,0.35);
}

.rg-pin.rg-pending .rg-pin-badge {
  background: rgba(255, 255, 255, 0.18);
  border-color: rgba(255,255,255,0.4);
  animation: rg-pulse 1.4s ease-in-out infinite;
  will-change: opacity;
}

/* Summits: a landmark, not a live-conditions reading — stone/bronze rather
   than any of the three weather hues, and no pulsing halo (a "live" pulse on
   data that never updates would be misleading, same reasoning as "neutral"
   getting no halo either). */
.rg-pin.rg-summit .rg-pin-badge {
  background: radial-gradient(circle at 35% 30%, #ece0c8, var(--rg-stone) 70%);
  box-shadow: 0 0 8px 1px rgba(201, 172, 120, 0.45), 0 2px 6px rgba(0,0,0,0.35);
}

@keyframes rg-pulse {
  0%, 100% { opacity: 0.5; }
  50% { opacity: 1; }
}

.rg-pin-label {
  position: absolute;
  bottom: calc(100% + 6px);
  left: 50%;
  transform: translate(-50%, 4px);
  font-size: 11px;
  font-weight: 700;
  color: var(--rg-text);
  background: rgba(5, 7, 15, 0.9);
  border: 1px solid var(--rg-border);
  padding: 3px 8px;
  border-radius: 7px;
  white-space: nowrap;
  opacity: 0;
  transition: opacity 0.15s ease, transform 0.15s ease;
  pointer-events: none;
  z-index: 8;
}

.rg-pin:hover .rg-pin-label,
.rg-pin:focus-within .rg-pin-label { opacity: 1; transform: translate(-50%, 0); }

/* ---- world-view cluster markers ----------------------------------------
   Stand in for a group of nearby pins at "world" zoom tier (see
   buildClusters/buildClusterEl in resort-globe.js) — bigger and far easier
   to tap than the individual 20px pin badges they replace, which is the
   point: up to 222 pins piled up at the default view were both unreadable
   and a real pain to hit precisely, worse on a phone. Deliberately its own
   treatment (not any of the snowy/warm/neutral/summit pin colors) so a
   cluster never reads as "a resort with weather" — it's a zoom-in
   affordance, not a 5th weather category. Originally a glowing red — swapped
   for a calm navy/frosted-glass treatment (matching the popup card's own
   surface color) after real-world feedback that a cluster of red circles
   read as an alert/warning state rather than a neutral "zoom in for more"
   affordance, especially with several of them on screen at once. */
.rg-cluster {
  position: absolute;
  cursor: pointer;
  transform: translate(-50%, -50%);
  z-index: 2;
  outline: none;
  /* Same fix as .rg-pin above, same reason — see that comment. */
  pointer-events: auto;
  /* Same reasoning as .rg-globe-canvas/.rg-pin's touch-action rules — a
     swipe-to-scroll gesture is, if anything, MORE likely to start on a
     cluster badge than a lone pin, since clusters are the larger targets by
     design (see buildClusterEl's sqrt(count) sizing). */
  touch-action: pan-y;
}

.rg-cluster:hover,
.rg-cluster:focus-within { z-index: 21; }

.rg-cluster::before {
  content: "";
  position: absolute;
  inset: -10px;
  z-index: 0;
}

.rg-cluster-badge {
  position: relative;
  width: var(--rg-cluster-size, 40px);
  height: var(--rg-cluster-size, 40px);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: radial-gradient(circle at 35% 30%, rgba(255,255,255,0.18), rgba(18,26,58,0.82) 70%);
  border: 2px solid rgba(255, 255, 255, 0.55);
  box-shadow: 0 3px 14px rgba(0,0,0,0.45);
  backdrop-filter: blur(4px);
  transition: transform 0.18s cubic-bezier(0.34, 1.56, 0.64, 1);
  animation: rg-pin-drop 0.55s cubic-bezier(0.34, 1.56, 0.64, 1) both;
}

.rg-cluster:hover .rg-cluster-badge,
.rg-cluster:focus-within .rg-cluster-badge { transform: scale(1.1); }

.rg-cluster:focus-visible .rg-cluster-badge {
  outline: 2px solid #fff;
  outline-offset: 3px;
}

.rg-cluster-count {
  font-weight: 800;
  font-size: 13px;
  color: #fff;
  text-shadow: 0 1px 3px rgba(0,0,0,0.5);
}

/* popup card on pin/row click */
.rg-popup {
  position: absolute;
  top: 88px;
  right: 20px;
  width: min(320px, calc(100% - 40px));
  background: rgba(12, 17, 40, 0.92);
  backdrop-filter: blur(10px);
  border: 1px solid var(--rg-border);
  border-radius: 16px;
  padding: 16px 18px;
  z-index: 6;
  transform: translateY(-8px);
  opacity: 0;
  pointer-events: none;
  transition: transform 0.2s ease, opacity 0.2s ease;
  box-shadow: 0 20px 50px rgba(0,0,0,0.5);
}

@media (min-width: 768px) {
  .rg-popup { top: 110px; right: 48px; }
}

@media (max-width: 767px) {
  /* Relative to #rg-globe-viewport's own shorter box now, not the full
     hero — 88px was sized to clear the eyebrow/title text that used to sit
     above the globe in the same box; that text lives in its own block above
     the viewport now, so the popup can sit much closer to the top of its
     own smaller box. */
  .rg-popup { top: 16px; right: 16px; }
}

.rg-popup.rg-open {
  transform: translateY(0);
  opacity: 1;
  pointer-events: auto;
}

.rg-popup .rg-popup-kind {
  display: block;
  font-size: 0.65rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--rg-text-dim);
  margin-bottom: 4px;
}

.rg-popup h3 {
  margin: 0 0 2px;
  font-family: "Montserrat", sans-serif;
  font-size: 1.05rem;
  padding-right: 14px;
}

.rg-popup .rg-popup-meta {
  font-size: 0.8rem;
  color: var(--rg-text-dim);
  margin-bottom: 8px;
}

.rg-popup .rg-popup-stat {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 0.9rem;
  font-weight: 600;
}

.rg-popup a.rg-popup-link {
  display: inline-block;
  margin-top: 10px;
  font-size: 0.8rem;
  color: var(--rg-red-2);
  text-decoration: none;
  font-weight: 600;
}

.rg-popup a.rg-popup-link:hover { text-decoration: underline; }

.rg-popup-close {
  position: absolute;
  top: 10px;
  right: 12px;
  background: none;
  border: none;
  color: var(--rg-text-dim);
  cursor: pointer;
  font-size: 14px;
}

/* ---- jump-search result rows (reused inside the dropdown) ---- */
.rg-list-row {
  background: rgba(255,255,255,0.03);
  border: 1px solid transparent;
  border-radius: 10px;
  padding: 9px 10px;
  display: flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
}

.rg-list-row:hover { border-color: var(--rg-red); background: rgba(255,255,255,0.06); }

.rg-list-row .rg-list-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
}

.rg-list-row.rg-snowy .rg-list-dot { background: var(--rg-ice); box-shadow: 0 0 6px var(--rg-ice); }
.rg-list-row.rg-warm .rg-list-dot { background: var(--rg-sun); box-shadow: 0 0 6px var(--rg-sun); }
.rg-list-row.rg-neutral .rg-list-dot { background: #7d8bb8; }
.rg-list-row.rg-pending .rg-list-dot { background: rgba(255,255,255,0.25); }
.rg-list-row.rg-summit .rg-list-dot { background: var(--rg-stone); }

.rg-list-row .rg-list-name {
  font-weight: 600;
  font-size: 0.84rem;
}

.rg-list-row .rg-list-kind {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 5px;
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--rg-stone);
  background: rgba(201, 172, 120, 0.16);
  border-radius: 4px;
  vertical-align: 1px;
}

.rg-list-row .rg-list-meta {
  font-size: 0.73rem;
  color: var(--rg-text-dim);
}

.rg-list-empty {
  text-align: center;
  color: var(--rg-text-dim);
  padding: 16px 0;
  font-size: 0.82rem;
}
