/* ════════════════════════════════════════════════════════════════════
   cabana-globe.css — chrome for the Cabana world map.

   Loaded lazily by cabana-globe.js, so a page that never mounts a
   globe never fetches this.

   Two ideas run through the whole file:

   1. The map is the product; the chrome is glass laid over it. Every
      panel is translucent, blurred and shadowed rather than filled,
      so the world is never fully covered — you can always see where
      you are underneath the controls.

   2. Skins repaint the chrome too. God's Eye View re-renders the
      whole scene through a sensor, HUD included, and a light HUD
      floating over a Nightglass globe would read as two products
      stacked. So every colour below is a token, and `.cg-dark` swaps
      the token set rather than restyling the components.
   ════════════════════════════════════════════════════════════════════ */

.cg{
  --cg-ink:#08080F;
  --cg-ink-soft:#474A66;
  --cg-ink-faint:#8B8EAC;
  --cg-glass:rgba(252,252,254,.82);
  --cg-glass-solid:#FCFCFE;
  --cg-line:rgba(8,8,15,.09);
  --cg-line-2:rgba(8,8,15,.15);
  --cg-accent:#6D28FF;
  --cg-accent-2:#4F6DFF;
  --cg-live:#14B8A6;
  --cg-shadow:0 10px 40px rgba(8,8,15,.13),0 2px 10px rgba(8,8,15,.07);
  --cg-shadow-lift:0 22px 66px rgba(109,40,255,.17),0 8px 22px rgba(8,8,15,.11);
  --cg-r:16px;
  --cg-ease:cubic-bezier(.22,1,.36,1);
  --cg-spring:cubic-bezier(.34,1.4,.44,1);

  position:relative;
  width:100%;
  min-height:420px;
  overflow:hidden;
  border-radius:var(--cg-r);
  background:#EEF0F7;
  font-family:'Inter',system-ui,-apple-system,'Segoe UI',sans-serif;
  color:var(--cg-ink);
  isolation:isolate;
  contain:layout paint;
}

.cg.cg-dark{
  --cg-ink:#FCFCFE;
  --cg-ink-soft:#A9ACC8;
  --cg-ink-faint:#7A7D9B;
  --cg-glass:rgba(14,14,26,.76);
  --cg-glass-solid:#0D0D18;
  --cg-line:rgba(255,255,255,.11);
  --cg-line-2:rgba(255,255,255,.19);
  --cg-shadow:0 10px 40px rgba(0,0,0,.5),0 2px 10px rgba(0,0,0,.3);
  --cg-shadow-lift:0 22px 66px rgba(0,0,0,.6),0 8px 22px rgba(0,0,0,.4);
  background:#08080F;
}

/* ── The stage ─────────────────────────────────────────────────────
   The skin's CSS filter lands here, on the wrapper around the Leaflet
   container, rather than on the tile pane. Filtering the tile pane
   alone leaves Leaflet's own vector layers unfiltered, so a Noir map
   would keep full-colour arcs — the sensor has to be in front of
   everything the map draws, which is exactly where a real one sits.  */
.cg-stage{
  position:absolute;
  inset:0;
  transition:filter .55s var(--cg-ease);
  will-change:filter;
}
/* Leaflet is handed this element directly, so it adds
   `leaflet-container` to the SAME node — these must be compound, not
   descendant, or Leaflet's own `#ddd` container background wins and
   every skin sits on a grey plate instead of the page's own ground. */
.cg-stage.leaflet-container{
  width:100%;height:100%;
  background:transparent;
  font:inherit;
  outline:none;
}
.cg-stage .leaflet-control-attribution{
  font-size:9.5px;
  background:rgba(252,252,253,.8);
  color:#5A5C78;
  padding:2px 7px;
  border-radius:7px 0 0 0;
}
.cg-dark .cg-stage .leaflet-control-attribution{
  background:rgba(10,10,18,.8);color:#8B8EAC;
}
.cg-stage .leaflet-control-attribution a{color:inherit;}

.cg-vignette{
  position:absolute;inset:0;
  pointer-events:none;
  z-index:3;
  transition:background .55s var(--cg-ease);
}
.cg-arc-canvas{
  position:absolute;top:0;left:0;
  pointer-events:none;
  transition:opacity .4s var(--cg-ease);
}

/* ── Boot ───────────────────────────────────────────────────────────
   A world map is a heavy thing to ask for, and a grey rectangle while
   it arrives reads as broken. The orb is the same gradient the pins
   use, so the wait already looks like the product.                   */
.cg-boot{
  position:absolute;inset:0;z-index:900;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:16px;background:#EEF0F7;color:var(--cg-ink-faint);
  font-size:13px;font-weight:600;text-align:center;padding:24px;
}
.cg-dark .cg-boot{background:#08080F;}
.cg-boot-orb{
  width:46px;height:46px;border-radius:50%;
  background:conic-gradient(from 0deg,#6D28FF,#4F6DFF,#4EE0C8,#F5B12E,#6D28FF);
  animation:cgSpin 2.4s linear infinite,cgBreathe 2.4s ease-in-out infinite;
  filter:blur(.4px);
}
.cg-boot-t{font-size:13.5px;}
.cg-boot-s{font-size:12.5px;font-weight:500;max-width:34ch;line-height:1.6;}
.cg-boot-s a{color:var(--cg-accent);font-weight:650;}
@keyframes cgSpin{to{transform:rotate(360deg);}}
@keyframes cgBreathe{0%,100%{opacity:.72;}50%{opacity:1;}}

/* ── Pins ───────────────────────────────────────────────────────────
   The pin is one button carrying a dot and a label. The allocator
   decides whether the label paints and which side of the dot it sits
   on; it writes --lx/--ly and a data-anchor, and everything below is
   the consequence. Keeping placement in two custom properties means
   a re-allocation is a compositor-only change.                       */
.cg-pin-wrap{background:none;border:0;}

.cg-pin{
  position:absolute;
  left:0;top:0;
  transform:translate(-50%,-50%);
  background:none;border:0;padding:0;margin:0;
  cursor:pointer;
  display:block;
  line-height:0;
  -webkit-tap-highlight-color:transparent;
}
.cg-pin:focus-visible{outline:none;}
.cg-pin:focus-visible .cg-dot{
  box-shadow:0 0 0 3px var(--cg-glass-solid),0 0 0 5.5px var(--cg-accent);
}

.cg-dot{
  display:block;
  width:9px;height:9px;border-radius:50%;
  background:linear-gradient(140deg,#4F6DFF,#6D28FF);
  border:2px solid var(--cg-glass-solid);
  box-shadow:0 2px 8px rgba(79,109,255,.42);
  transition:width .22s var(--cg-spring),height .22s var(--cg-spring),
             box-shadow .22s var(--cg-ease),background .3s var(--cg-ease);
}
.cg-pin-country .cg-dot{width:11px;height:11px;}
.cg-pin-continent .cg-dot{
  width:15px;height:15px;
  background:linear-gradient(140deg,#6D28FF,#F5B12E);
  box-shadow:0 3px 14px rgba(109,40,255,.5);
}
.cg-pin-district .cg-dot{
  width:7px;height:7px;
  background:linear-gradient(140deg,#8B5CF6,#C3AEFA);
}
.cg-pin.hot .cg-dot{
  width:14px;height:14px;
  box-shadow:0 3px 16px rgba(109,40,255,.6);
}
.cg-pin.on .cg-dot{
  width:16px;height:16px;
  background:linear-gradient(140deg,#F5B12E,#FF6A3C);
  box-shadow:0 0 0 5px rgba(245,177,46,.22),0 4px 18px rgba(245,177,46,.5);
}

/* The selected pin gets a sonar ping — one ring, slow, so it reads as
   "you are here" rather than as an alert. */
.cg-pin.on::after{
  content:'';
  position:absolute;left:50%;top:50%;
  width:16px;height:16px;margin:-8px 0 0 -8px;
  border-radius:50%;
  border:1.5px solid #F5B12E;
  animation:cgPing 2.1s var(--cg-ease) infinite;
  pointer-events:none;
}
@keyframes cgPing{
  0%{transform:scale(1);opacity:.85;}
  70%{transform:scale(3.4);opacity:0;}
  100%{transform:scale(3.4);opacity:0;}
}

/* ── Labels ────────────────────────────────────────────────────────
   Hidden by default: a label paints only when the allocator gave it a
   slot. `visibility` rather than `display` keeps the element
   measurable, which the allocator needs — it reads offsetWidth to
   size the collision box, and a display:none element measures zero.  */
.cg-label{
  position:absolute;
  left:50%;top:50%;
  transform:translate(calc(-50% + var(--lx,0px)),calc(-50% + var(--ly,0px)));
  visibility:hidden;opacity:0;
  pointer-events:none;
  white-space:nowrap;
  line-height:1;
  transition:opacity .26s var(--cg-ease);
}
.cg-pin.has-label .cg-label{visibility:visible;opacity:1;}

.cg-label-in{
  display:inline-block;
  padding:3.5px 8px;
  border-radius:100px;
  font-size:11.5px;
  font-weight:650;
  letter-spacing:-.012em;
  color:var(--cg-ink);
  background:var(--cg-glass);
  -webkit-backdrop-filter:blur(9px) saturate(1.3);
  backdrop-filter:blur(9px) saturate(1.3);
  border:1px solid var(--cg-line);
  box-shadow:0 2px 9px rgba(8,8,15,.1);
  transition:background .2s var(--cg-ease),color .2s var(--cg-ease),
             transform .2s var(--cg-spring);
}
.cg-pin-continent .cg-label-in{
  font-size:12.5px;font-weight:750;
  text-transform:uppercase;letter-spacing:.07em;
}
.cg-pin-country .cg-label-in{font-weight:700;}
.cg-pin-district .cg-label-in{font-size:10.5px;font-weight:600;opacity:.92;}

.cg-pin[data-anchor="r"] .cg-label{transform:translate(var(--lx),-50%);}
.cg-pin[data-anchor="l"] .cg-label{transform:translate(calc(-100% + var(--lx)),-50%);}
.cg-pin[data-anchor="t"] .cg-label,
.cg-pin[data-anchor="b"] .cg-label{transform:translate(-50%,calc(-50% + var(--ly)));}

.cg-pin.hot .cg-label-in{
  transform:scale(1.06);
  border-color:var(--cg-line-2);
  box-shadow:0 4px 16px rgba(109,40,255,.2);
}
.cg-pin.on .cg-label-in{
  background:linear-gradient(135deg,#F5B12E,#FF6A3C);
  color:#1A0E00;
  border-color:transparent;
  font-weight:750;
  box-shadow:0 5px 20px rgba(245,177,46,.42);
}

/* ── HUD ───────────────────────────────────────────────────────────
   Ported from the God's Eye View LOCATION readout: two lines, always
   present, always answering "where am I". The pulse is the only thing
   on the panel that moves, which is what makes it read as live.      */
.cg-hud{
  position:absolute;top:14px;left:14px;z-index:640;
  display:flex;align-items:center;gap:11px;
  padding:9px 15px 9px 11px;
  border-radius:100px;
  background:var(--cg-glass);
  -webkit-backdrop-filter:blur(16px) saturate(1.5);
  backdrop-filter:blur(16px) saturate(1.5);
  border:1px solid var(--cg-line);
  box-shadow:var(--cg-shadow);
  max-width:min(46%,380px);
  transition:opacity .3s var(--cg-ease),transform .3s var(--cg-ease);
}
.cg-hud.cg-off{opacity:0;transform:translateY(-8px);pointer-events:none;}

.cg-hud-mark{
  position:relative;flex:0 0 auto;
  width:26px;height:26px;border-radius:50%;
  background:linear-gradient(140deg,#4F6DFF,#6D28FF);
  display:grid;place-items:center;
}
.cg-hud-pulse{
  width:7px;height:7px;border-radius:50%;background:#fff;
  box-shadow:0 0 0 0 rgba(255,255,255,.8);
  animation:cgPulse 2.3s var(--cg-ease) infinite;
}
@keyframes cgPulse{
  0%{box-shadow:0 0 0 0 rgba(255,255,255,.75);}
  70%{box-shadow:0 0 0 9px rgba(255,255,255,0);}
  100%{box-shadow:0 0 0 0 rgba(255,255,255,0);}
}
.cg-hud-text{min-width:0;}
.cg-hud-1{
  font-family:'Geist','Inter',system-ui,sans-serif;
  font-size:14px;font-weight:680;letter-spacing:-.024em;
  line-height:1.2;color:var(--cg-ink);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.cg-hud-2{
  font-size:11px;font-weight:550;color:var(--cg-ink-faint);
  line-height:1.35;margin-top:1px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.cg-hud-stat{
  flex:0 0 auto;padding-left:11px;margin-left:2px;
  border-left:1px solid var(--cg-line);
  font-family:'Geist','Inter',ui-monospace,monospace;
  font-size:10.5px;font-weight:650;color:var(--cg-ink-soft);
  font-feature-settings:'tnum' 1;
  white-space:nowrap;
}

/* ── Skin rail ─────────────────────────────────────────────────────
   The optics are a control the guest holds, so they live at the top
   of the frame rather than in a settings drawer. On narrow screens
   the names drop and the swatches remain: the choice stays available,
   the explanation moves to the tooltip.                              */
.cg-skins{
  position:absolute;top:14px;right:14px;z-index:640;
  display:flex;gap:3px;padding:4px;
  border-radius:100px;
  background:var(--cg-glass);
  -webkit-backdrop-filter:blur(16px) saturate(1.5);
  backdrop-filter:blur(16px) saturate(1.5);
  border:1px solid var(--cg-line);
  box-shadow:var(--cg-shadow);
}
.cg-skin{
  display:inline-flex;align-items:center;gap:6px;
  padding:6px 11px 6px 8px;border:0;border-radius:100px;
  background:transparent;cursor:pointer;
  font:inherit;font-size:11.5px;font-weight:620;
  color:var(--cg-ink-soft);
  letter-spacing:-.01em;
  transition:background .2s var(--cg-ease),color .2s var(--cg-ease);
}
.cg-skin:hover{background:rgba(109,40,255,.08);color:var(--cg-ink);}
.cg-skin.on{background:var(--cg-ink);color:var(--cg-glass-solid);}
.cg-dark .cg-skin.on{background:var(--cg-glass-solid);color:#08080F;}
.cg-swatch{
  width:11px;height:11px;border-radius:50%;flex:0 0 auto;
  border:1.5px solid rgba(255,255,255,.7);
  box-shadow:0 1px 4px rgba(8,8,15,.28);
}

/* ── Category filters ─────────────────────────────────────────────── */
.cg-filters{
  position:absolute;left:50%;bottom:16px;z-index:640;
  transform:translateX(-50%);
  display:flex;gap:5px;padding:5px;
  border-radius:100px;
  background:var(--cg-glass);
  -webkit-backdrop-filter:blur(16px) saturate(1.5);
  backdrop-filter:blur(16px) saturate(1.5);
  border:1px solid var(--cg-line);
  box-shadow:var(--cg-shadow);
  max-width:calc(100% - 28px);
  overflow-x:auto;
  scrollbar-width:none;
}
.cg-filters::-webkit-scrollbar{display:none;}
.cg-chip{
  display:inline-flex;align-items:center;gap:6px;
  padding:7px 12px;border:0;border-radius:100px;
  background:transparent;cursor:pointer;white-space:nowrap;
  font:inherit;font-size:12px;font-weight:620;
  color:var(--cg-ink-soft);letter-spacing:-.012em;
  transition:background .2s var(--cg-ease),color .2s var(--cg-ease),
             transform .18s var(--cg-spring);
}
.cg-chip:hover{background:rgba(109,40,255,.08);color:var(--cg-ink);}
.cg-chip.on{
  background:linear-gradient(135deg,#6D28FF,#4F6DFF);
  color:#fff;
  box-shadow:0 4px 14px rgba(109,40,255,.34);
}
.cg-chip:active{transform:scale(.96);}
.cg-chip-i{font-size:13px;line-height:1;}
.cg-chip-n{
  font-family:'Geist','Inter',ui-monospace,monospace;
  font-size:10px;font-weight:700;
  padding:2px 5px;border-radius:100px;
  background:rgba(8,8,15,.07);
  font-feature-settings:'tnum' 1;
}
.cg-chip.on .cg-chip-n{background:rgba(255,255,255,.22);}
.cg-dark .cg-chip-n{background:rgba(255,255,255,.1);}

/* ── Tours ─────────────────────────────────────────────────────────
   A shot list, presented as a shot list. Each button is one of the
   recipes in cabana-globe.js, and pressing it hands the camera over
   until the guest takes it back.                                     */
.cg-tours{
  position:absolute;left:14px;top:74px;z-index:635;
  width:216px;max-height:calc(100% - 170px);
  display:flex;flex-direction:column;
  padding:11px;
  border-radius:18px;
  background:var(--cg-glass);
  -webkit-backdrop-filter:blur(16px) saturate(1.5);
  backdrop-filter:blur(16px) saturate(1.5);
  border:1px solid var(--cg-line);
  box-shadow:var(--cg-shadow);
  transition:opacity .3s var(--cg-ease),transform .3s var(--cg-ease);
}
.cg-tours-h{
  font-size:10px;font-weight:750;letter-spacing:.11em;
  text-transform:uppercase;color:var(--cg-ink-faint);
  padding:2px 4px 9px;
}
.cg-tours-list{
  display:flex;flex-direction:column;gap:3px;
  overflow-y:auto;scrollbar-width:thin;
  margin:-2px;padding:2px;
}
.cg-tour{
  display:grid;
  grid-template-columns:22px 1fr;
  grid-template-areas:'i t' 'i b' 'i n';
  gap:0 9px;
  padding:9px 10px;border:0;border-radius:12px;
  background:transparent;cursor:pointer;text-align:left;
  font:inherit;color:var(--cg-ink);
  transition:background .2s var(--cg-ease);
}
.cg-tour:hover{background:rgba(109,40,255,.08);}
.cg-tour.on{
  background:linear-gradient(135deg,rgba(109,40,255,.16),rgba(79,109,255,.1));
  box-shadow:inset 0 0 0 1px rgba(109,40,255,.3);
}
.cg-tour-i{grid-area:i;font-size:16px;line-height:1.1;align-self:start;}
.cg-tour-t{
  grid-area:t;
  font-family:'Geist','Inter',system-ui,sans-serif;
  font-size:12.5px;font-weight:660;letter-spacing:-.022em;
}
.cg-tour-b{
  grid-area:b;font-size:11px;font-weight:500;line-height:1.42;
  color:var(--cg-ink-faint);margin-top:2px;
}
.cg-tour-n{
  grid-area:n;font-size:9.5px;font-weight:700;letter-spacing:.06em;
  text-transform:uppercase;color:var(--cg-accent);margin-top:5px;
}
.cg-tour.on .cg-tour-n::after{content:' · playing';}

/* While a tour is running the rest of the chrome steps back, so the
   guest is watching the world rather than a toolbar. */
.cg-touring .cg-filters,
.cg-touring .cg-skins{opacity:.35;transform:translateY(4px);}
.cg-touring .cg-filters{transform:translateX(-50%) translateY(4px);}
.cg-touring .cg-filters:hover,
.cg-touring .cg-skins:hover{opacity:1;transform:none;}
.cg-touring .cg-filters:hover{transform:translateX(-50%);}
.cg-filters,.cg-skins{transition:opacity .4s var(--cg-ease),transform .4s var(--cg-ease);}

/* ── Place card ────────────────────────────────────────────────────
   Everything Cabana knows about one place, and every real page that
   backs it. It is a panel on desktop and a bottom sheet on phones —
   the same content, laid out for the hand holding it.                */
.cg-card{
  position:absolute;top:14px;right:14px;z-index:660;
  width:330px;max-width:calc(100% - 28px);
  max-height:calc(100% - 96px);
  overflow-y:auto;overscroll-behavior:contain;
  padding:18px 18px 20px;
  border-radius:20px;
  background:var(--cg-glass-solid);
  border:1px solid var(--cg-line);
  box-shadow:var(--cg-shadow-lift);
  animation:cgCardIn .42s var(--cg-ease);
  scrollbar-width:thin;
}
@keyframes cgCardIn{
  from{opacity:0;transform:translateY(-10px) scale(.97);}
  to{opacity:1;transform:none;}
}
/* The card and the skin rail want the same corner. The card wins —
   it is the thing the guest just asked for — and the rail slides
   under the HUD rather than being hidden, so the optics stay
   reachable while reading a place. */
.cg-carded .cg-skins{top:auto;bottom:70px;right:14px;}

.cg-card-x{
  position:absolute;top:12px;right:12px;
  width:26px;height:26px;border:0;border-radius:50%;
  background:rgba(8,8,15,.06);color:var(--cg-ink-soft);
  font-size:17px;line-height:1;cursor:pointer;
  transition:background .18s var(--cg-ease),color .18s var(--cg-ease);
}
.cg-card-x:hover{background:rgba(8,8,15,.12);color:var(--cg-ink);}
.cg-dark .cg-card-x{background:rgba(255,255,255,.08);}

.cg-card-eyebrow{
  font-size:10px;font-weight:750;letter-spacing:.11em;
  text-transform:uppercase;color:var(--cg-ink-faint);
  padding-right:30px;
}
.cg-up{
  border:0;background:none;padding:0;cursor:pointer;
  font:inherit;font-size:10px;font-weight:750;letter-spacing:.11em;
  text-transform:uppercase;color:var(--cg-accent);
  text-decoration:underline;text-underline-offset:2px;
}
.cg-card-h{
  font-family:'Geist','Inter',system-ui,sans-serif;
  font-size:23px;font-weight:660;letter-spacing:-.035em;
  line-height:1.14;margin:7px 0 0;color:var(--cg-ink);
}
.cg-card-draw{
  font-size:12.8px;line-height:1.58;color:var(--cg-ink-soft);
  margin:9px 0 0;
}

.cg-facts{
  display:flex;flex-direction:column;gap:1px;
  margin:15px 0 0;border-radius:12px;overflow:hidden;
  background:var(--cg-line);
}
.cg-fact{
  display:flex;flex-direction:column;gap:2px;
  padding:9px 12px;background:var(--cg-glass-solid);
}
.cg-fact b{
  font-family:'Geist','Inter',ui-monospace,monospace;
  font-size:12.5px;font-weight:700;letter-spacing:-.02em;
  color:var(--cg-ink);font-feature-settings:'tnum' 1;
}
.cg-fact span{font-size:11.5px;line-height:1.5;color:var(--cg-ink-faint);}
/* Live inventory is the one fact on the card that comes from the
   database rather than the catalogue. It gets the only colour. */
.cg-fact-live{
  background:linear-gradient(135deg,rgba(78,224,200,.14),rgba(20,184,166,.07));
}
.cg-fact-live b{color:var(--cg-live);}

.cg-hi{
  list-style:none;margin:14px 0 0;padding:0;
  display:flex;flex-wrap:wrap;gap:5px;
}
.cg-hi li{
  font-size:11px;font-weight:600;padding:4.5px 9px;
  border-radius:100px;background:rgba(109,40,255,.08);
  color:var(--cg-accent);letter-spacing:-.01em;
}
.cg-dark .cg-hi li{background:rgba(139,92,246,.16);color:#C3AEFA;}

.cg-gos{display:flex;flex-direction:column;gap:5px;margin:16px 0 0;}
.cg-go{
  display:grid;
  grid-template-columns:24px 1fr 14px;
  align-items:center;gap:9px;
  padding:11px 13px;border-radius:13px;
  background:rgba(8,8,15,.04);
  color:var(--cg-ink);text-decoration:none;
  font-size:12.8px;font-weight:640;letter-spacing:-.014em;
  transition:background .2s var(--cg-ease),transform .2s var(--cg-spring);
}
.cg-dark .cg-go{background:rgba(255,255,255,.06);}
.cg-go:hover{
  background:linear-gradient(135deg,#6D28FF,#4F6DFF);
  color:#fff;transform:translateX(3px);
}
.cg-go-i{font-size:15px;line-height:1;}
.cg-go-x{font-size:13px;opacity:.45;transition:opacity .2s var(--cg-ease);}
.cg-go:hover .cg-go-x{opacity:1;}

.cg-kids-h{
  font-size:10px;font-weight:750;letter-spacing:.11em;
  text-transform:uppercase;color:var(--cg-ink-faint);margin:17px 0 8px;
}
.cg-kids{display:flex;flex-wrap:wrap;gap:5px;}
.cg-kid{
  border:1px solid var(--cg-line-2);border-radius:100px;
  background:transparent;cursor:pointer;
  padding:5.5px 11px;font:inherit;font-size:11.5px;font-weight:620;
  color:var(--cg-ink-soft);letter-spacing:-.012em;
  display:inline-flex;align-items:center;gap:5px;
  transition:border-color .2s var(--cg-ease),color .2s var(--cg-ease),
             background .2s var(--cg-ease);
}
.cg-kid:hover{
  border-color:var(--cg-accent);color:var(--cg-accent);
  background:rgba(109,40,255,.06);
}
.cg-kid i{
  width:5px;height:5px;border-radius:50%;background:var(--cg-live);
  box-shadow:0 0 0 2px rgba(20,184,166,.2);
}

/* ── Controls ─────────────────────────────────────────────────────── */
.cg-controls{
  position:absolute;right:14px;bottom:16px;z-index:640;
  display:flex;flex-direction:column;gap:3px;padding:4px;
  border-radius:100px;
  background:var(--cg-glass);
  -webkit-backdrop-filter:blur(16px) saturate(1.5);
  backdrop-filter:blur(16px) saturate(1.5);
  border:1px solid var(--cg-line);
  box-shadow:var(--cg-shadow);
}
.cg-ctl{
  width:32px;height:32px;border:0;border-radius:50%;
  background:transparent;cursor:pointer;
  font-size:14px;line-height:1;color:var(--cg-ink-soft);
  display:grid;place-items:center;
  transition:background .18s var(--cg-ease),color .18s var(--cg-ease),
             transform .18s var(--cg-spring);
}
.cg-ctl:hover{background:rgba(109,40,255,.1);color:var(--cg-accent);}
.cg-ctl:active{transform:scale(.9);}
.cg-ctl-on{color:var(--cg-accent);background:rgba(109,40,255,.1);}
.cg-ctl.cg-ok{background:rgba(20,184,166,.16);color:var(--cg-live);}
.cg-ctl.cg-warn{background:rgba(245,177,46,.18);color:#D98E0B;}

/* ── Narrow screens ────────────────────────────────────────────────
   Below 860px the tour rail becomes a horizontal scroller docked
   above the filters, and the card becomes a bottom sheet. Nothing is
   removed — a phone gets the whole map, laid out for a thumb.        */
@media (max-width:860px){
  .cg{min-height:520px;border-radius:14px;}

  .cg-hud{max-width:calc(100% - 28px);}
  .cg-hud-stat{display:none;}

  .cg-skins{
    top:auto;bottom:calc(env(safe-area-inset-bottom,0px) + 118px);
    left:14px;right:14px;
    overflow-x:auto;scrollbar-width:none;justify-content:flex-start;
  }
  .cg-skins::-webkit-scrollbar{display:none;}
  .cg-carded .cg-skins{display:none;}
  .cg-skin-name{display:none;}
  .cg-skin{padding:7px 9px;}

  .cg-tours{
    left:14px;right:14px;width:auto;top:auto;
    bottom:calc(env(safe-area-inset-bottom,0px) + 168px);
    max-height:none;padding:9px;
  }
  .cg-tours-h{display:none;}
  .cg-tours-list{
    flex-direction:row;overflow-x:auto;gap:6px;
    scrollbar-width:none;
  }
  .cg-tours-list::-webkit-scrollbar{display:none;}
  .cg-tour{
    flex:0 0 auto;width:154px;
    grid-template-columns:1fr;
    grid-template-areas:'i' 't' 'n';
    padding:8px 10px;
  }
  .cg-tour-b{display:none;}

  .cg-filters{
    left:14px;right:14px;transform:none;max-width:none;
    bottom:calc(env(safe-area-inset-bottom,0px) + 62px);
    justify-content:flex-start;
  }
  .cg-touring .cg-filters{transform:translateY(4px);}
  .cg-touring .cg-filters:hover{transform:none;}

  .cg-controls{
    flex-direction:row;
    right:14px;bottom:calc(env(safe-area-inset-bottom,0px) + 14px);
  }

  .cg-card{
    top:auto;left:0;right:0;bottom:0;
    width:auto;max-width:none;
    max-height:74%;
    border-radius:22px 22px 0 0;
    padding:20px 18px calc(env(safe-area-inset-bottom,0px) + 22px);
    animation:cgSheetIn .4s var(--cg-ease);
  }
  @keyframes cgSheetIn{
    from{transform:translateY(100%);}
    to{transform:none;}
  }
  /* With the sheet up, the rails underneath it are unreachable and
     would only show through the gap. */
  .cg-carded .cg-tours,
  .cg-carded .cg-filters{opacity:0;pointer-events:none;}
}

@media (max-width:520px){
  .cg-hud{padding:7px 13px 7px 9px;gap:9px;}
  .cg-hud-1{font-size:13px;}
  .cg-hud-mark{width:22px;height:22px;}
}

/* ── Reduced motion ────────────────────────────────────────────────
   The camera already honours this in JS — durations collapse to zero
   and the idle drift never starts. What is left here is the ambient
   motion, which has no equivalent switch: the ping, the pulse and the
   boot orb are stilled, and every transition is cut to a blink so the
   interface still acknowledges a click.                              */
@media (prefers-reduced-motion:reduce){
  .cg *,.cg *::before,.cg *::after{
    animation-duration:.01ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.06s !important;
  }
  .cg-boot-orb{animation:cgBreathe 2s ease-in-out infinite !important;}
}

/* ── Print ─────────────────────────────────────────────────────────
   A printed map is a reference, not an interface. The chrome goes and
   the world stays.                                                   */
@media print{
  .cg-skins,.cg-tours,.cg-filters,.cg-controls,.cg-card-x{display:none !important;}
  .cg{border:1px solid #ccc;break-inside:avoid;}
}
