/* ============================================================
   The KOHO Air Hotel — Experiences map ("Cinematic Full-Bleed")
   Five zones — On Gili Air, In the Sea, At the hotel, On Lombok,
   Wellness — switched by a floating pill bar. All five show one
   large image edge to edge (Lombok's is a static satellite image).
   Frosted-glass pins sit directly on all five. Behaviour:
   assets/experience-map.js
   Palette + type inherited from assets/site.css — the same nine
   tokens and the same flat engraved-linework language already
   drawn for getting-here.html. No new colours.
   ============================================================ */

.expmap{position:relative}

/* ---------- progressive-enhancement fallback ---------- */
.expmap-fallback{list-style:none;margin:0;padding:0;
  display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:2px}
.expmap-fallback li{margin:0}
.expmap-fallback a{display:block;padding:16px 18px;background:var(--sand);
  border:1px solid transparent;transition:border-color .3s var(--ease)}
.expmap-fallback a:hover,.expmap-fallback a:focus-visible{border-color:var(--clay)}
.expmap-fallback .fb-zone{font-size:.6rem;letter-spacing:.24em;text-transform:uppercase;color:var(--clay-ink);display:block}
.expmap-fallback .fb-title{font-family:'Cormorant Garamond',Georgia,serif;font-size:1.2rem;line-height:1.15;display:block;margin-top:4px}
.expmap-fallback .fb-dur{font-size:.78rem;color:var(--soft);display:block;margin-top:4px}
.expmap.is-enhanced .expmap-fallback{display:none}

/* ---------- atlas shell ---------- */
.atlas{opacity:0;transition:opacity .6s var(--ease)}
.expmap.is-ready .atlas{opacity:1}

/* ---------- pill bar (zone switcher) ---------- */
.atlas-pills{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:14px}
.atlas-pill{
  appearance:none;border:1px solid var(--line);background:var(--bone);font-family:'Jost',sans-serif;
  display:flex;align-items:baseline;gap:8px;padding:10px 18px;border-radius:30px;cursor:pointer;
  color:var(--soft);transition:background .25s var(--ease),color .25s var(--ease),border-color .25s var(--ease);
}
.atlas-pill:hover{border-color:var(--clay)}
.atlas-pill:focus-visible{outline:2px solid var(--brass);outline-offset:2px}
.atlas-pill.is-active{background:var(--ink);color:var(--bone);border-color:var(--ink)}
.pl-num{font-family:'Cormorant Garamond',Georgia,serif;font-style:italic;font-size:.98rem;color:var(--clay)}
.atlas-pill.is-active .pl-num{color:var(--brass)}
.pl-name{font-size:.86rem;letter-spacing:.01em}
.pl-count{font-size:.6rem;font-variant-numeric:tabular-nums;color:var(--clay-ink);opacity:.85}
.atlas-pill.is-active .pl-count{color:rgba(250,247,241,.65)}

/* ---------- stage: the open zone ---------- */
.atlas-stage{position:relative;background:var(--ink);z-index:41;
  border:1px solid var(--line);box-shadow:0 30px 70px -40px rgba(21,42,46,.4);overflow:hidden}
.atlas-plate{display:none}
.atlas-plate.is-active{display:block}

/* ---------- photo-mode zones (Gili Air, Hotel, Lombok, Wellness) ---------- */
.em-hero{position:relative;aspect-ratio:var(--em-ar,16/9);background:#0c2126 center/cover no-repeat;overflow:hidden}
.em-hero-grad{position:absolute;inset:0;
  background:linear-gradient(180deg,rgba(8,20,23,.1) 0%,rgba(8,20,23,0) 32%,rgba(8,20,23,0) 55%,rgba(8,20,23,.72) 100%);
  pointer-events:none}
.em-hero-title{position:absolute;left:34px;bottom:26px;right:34px;display:flex;justify-content:space-between;align-items:flex-end;gap:20px;pointer-events:none}
.em-hero-title .k{font-size:.62rem;letter-spacing:.28em;text-transform:uppercase;color:rgba(250,247,241,.72);display:block}
.em-hero-title h3{font-family:'Cormorant Garamond',Georgia,serif;font-style:italic;font-weight:500;
  font-size:clamp(1.5rem,3vw,2.2rem);color:#FAF7F1;margin:6px 0 0}
.em-hero-title .hint{font-size:.74rem;color:rgba(250,247,241,.65);max-width:34ch;text-align:right}
@media (max-width:640px){.em-hero-title .hint{display:none}}

.em-pin{position:absolute;transform:translate(-16px,-50%);display:flex;align-items:center;gap:9px;
  cursor:pointer;text-decoration:none;background:none;border:0;padding:0;font-family:inherit}
.em-pin .ring{width:32px;height:32px;border-radius:50%;flex:none;
  background:rgba(21,42,46,.34);border:1px solid rgba(250,247,241,.55);backdrop-filter:blur(4px);
  display:flex;align-items:center;justify-content:center;transition:transform .2s var(--ease),background .2s var(--ease)}
.em-pin .ring::after{content:'';width:7px;height:7px;border-radius:50%;background:#FAF7F1}
.em-pin[data-cat="gili"] .ring::after{background:var(--clay)}
.em-pin[data-cat="hotel"] .ring::after{background:var(--sea)}
.em-pin[data-cat="lombok"] .ring::after{background:var(--azure)}
.em-pin[data-cat="wellness"] .ring::after{background:var(--plum)}
.em-pin .cap{background:rgba(21,42,46,.55);backdrop-filter:blur(4px);color:#FAF7F1;
  font-size:.72rem;padding:7px 13px;border-radius:20px;white-space:nowrap;
  border:1px solid rgba(250,247,241,.2);transition:background .2s var(--ease),color .2s var(--ease)}
.em-pin:hover,.em-pin:focus-visible{outline:none}
.em-pin:hover .ring,.em-pin:focus-visible .ring{transform:scale(1.12);background:var(--brass)}
.em-pin:hover .cap,.em-pin:focus-visible .cap{background:#FAF7F1;color:var(--ink);border-color:#FAF7F1}
@media (max-width:640px){.em-pin .cap{font-size:.66rem;padding:6px 10px}.em-pin .ring{width:26px;height:26px}}

/* ============================================================
   ON LOMBOK — a static real satellite photo (pulled once from Esri's
   MapServer export endpoint, no live tiles/pan/zoom/third-party JS
   any more), using the exact same .em-hero/.em-pin structure as Gili
   Air/Hotel/Wellness — real lat/lng convert to % via lombokXY() in
   the JS instead of hand-placed points. Landmark pins (Mataram, Kuta,
   the airport) are real geography, not experiences — not clickable,
   so they're deliberately styled as plain map labels (a small solid
   dot + bare text, no frosted-glass ring/pill, no hover reaction)
   rather than the real pins' "button" look, which previously differed
   from a real pin only by the dot's colour — easy to miss at a glance,
   and hovering one still lit up brass and turned the caption into a
   white pill exactly like a clickable pin.
   ============================================================ */
.em-pin.is-landmark{cursor:default}
.em-pin.is-landmark .ring{width:8px;height:8px;background:transparent;border:none;backdrop-filter:none}
.em-pin.is-landmark .ring::after{width:100%;height:100%;background:var(--clay-ink)}
.em-pin.is-landmark .cap{background:none;backdrop-filter:none;border:none;padding:0;
  color:rgba(250,247,241,.8);text-shadow:0 1px 4px rgba(3,20,28,.75);font-size:.68rem}
.em-pin.is-landmark:hover .ring,.em-pin.is-landmark:focus-visible .ring{transform:none;background:transparent}
.em-pin.is-landmark:hover .cap,.em-pin.is-landmark:focus-visible .cap{background:none;color:rgba(250,247,241,.8);border-color:transparent}

/* ============================================================
   IN THE SEA — ambient + wildlife motion (staged for review;
   linked from experience-map.js's addWaterMotion(), water zone
   only — every other zone's hero is untouched). Skipped entirely
   under prefers-reduced-motion at the JS level, so that case is
   exactly today's static hero, no CSS override needed here.
   Stacking: wl-layer (bg atmosphere + wildlife) sits BELOW
   .em-hero-grad so the same vignette darkens both the real photo
   and the moving crops identically; .em-pin sits above everything
   so all 7 pins stay fully clickable.
   ============================================================ */
.em-hero-grad{z-index:2}
.em-pin{z-index:3}
.atlas-plate[data-plate="water"] .wl-layer{position:absolute;inset:0;z-index:1;overflow:hidden;pointer-events:none}

/* ---- ambient: light-ray drift ---- */
.wl-ray{position:absolute;left:-10%;right:-10%;top:0;height:70%;opacity:.4;filter:blur(10px);
  mix-blend-mode:screen;transform-origin:top center;
  background:repeating-linear-gradient(95deg,rgba(255,255,255,.3) 0px,rgba(255,255,255,.3) 14px,rgba(255,255,255,0) 14px,rgba(255,255,255,0) 80px);
  animation:wlRayDrift 19s ease-in-out infinite}
.wl-ray.r2{opacity:.28;filter:blur(18px);
  background:repeating-linear-gradient(84deg,rgba(255,255,255,.32) 0px,rgba(255,255,255,.32) 26px,rgba(255,255,255,0) 26px,rgba(255,255,255,0) 130px);
  animation:wlRayDrift2 24s ease-in-out infinite}
@keyframes wlRayDrift{0%,100%{transform:translateX(-3%) skewX(-9deg)}50%{transform:translateX(3%) skewX(-5deg)}}
@keyframes wlRayDrift2{0%,100%{transform:translateX(2%) skewX(7deg)}50%{transform:translateX(-2%) skewX(11deg)}}

/* ---- ambient: surface glint ---- */
.wl-glint{position:absolute;left:-20%;width:140%;top:1%;height:22px;opacity:.6;filter:blur(4px);mix-blend-mode:screen;
  background:repeating-linear-gradient(90deg,rgba(255,255,255,0) 0px,rgba(255,255,255,.55) 44px,rgba(255,255,255,0) 96px,rgba(255,255,255,.32) 150px,rgba(255,255,255,0) 210px);
  animation:wlSwell 27s linear infinite}
@keyframes wlSwell{0%{transform:translateX(0)}100%{transform:translateX(-50%)}}

/* ---- ambient: rising particles ---- */
.wl-particles{position:absolute;inset:-10% 0 0;opacity:.45;
  background-image:radial-gradient(circle,rgba(255,255,255,.85) 1px,transparent 1.6px),radial-gradient(circle,rgba(255,255,255,.55) 1px,transparent 1.8px);
  background-size:160px 160px,90px 90px;
  animation:wlRise 30s linear infinite}
@keyframes wlRise{0%{transform:translate3d(0,-8%,0)}100%{transform:translate3d(-2%,92%,0)}}

/* ---- wildlife: masked crops of the same hero photo, swaying in place ---- */
.wl-life{position:absolute;
  -webkit-mask-image:radial-gradient(ellipse 60% 60% at 50% 50%,#000 40%,transparent 78%);
  mask-image:radial-gradient(ellipse 60% 60% at 50% 50%,#000 40%,transparent 78%)}
.wl-life img{width:100%;height:100%;object-fit:cover;display:block}

.wl-surfer{left:24.18%;top:0%;width:21.2%;height:27.38%;animation:wlSurferDrift 9s ease-in-out infinite}
.wl-turtle{left:31.62%;top:32.21%;width:10.42%;height:21.74%;animation:wlTurtleSwim 13s ease-in-out infinite}
.wl-statues{left:3.35%;top:32.21%;width:17.86%;height:30.6%}
.wl-manta{left:67.71%;top:21.74%;width:10.42%;height:32.21%;animation:wlMantaGlide 16s ease-in-out infinite}
.wl-hammerhead{left:50.22%;top:57.97%;width:17.49%;height:31.4%;animation:wlSharkCruise 22s ease-in-out infinite}
.wl-wreck{left:31.25%;top:60.39%;width:14.51%;height:27.38%}
/* statues and wreck stay still — stone and metal, not swimming life */

@keyframes wlTurtleSwim{0%,100%{transform:translate(-8px,4px) rotate(-2deg)}50%{transform:translate(8px,-4px) rotate(2deg)}}
@keyframes wlMantaGlide{0%,100%{transform:translateX(-10px) rotate(-2deg)}50%{transform:translateX(10px) rotate(2deg)}}
@keyframes wlSharkCruise{0%,100%{transform:translateX(-14px)}50%{transform:translateX(14px)}}
@keyframes wlSurferDrift{0%,100%{transform:translateY(0)}50%{transform:translateY(4px)}}

/* ---- pins: idle breathing, sitewide (Idea 05 — not water-only any more); hover/focus still wins with the existing static scale ---- */
@keyframes wlBreathe{0%,100%{transform:scale(1)}50%{transform:scale(1.06)}}
.em-pin .ring{animation:wlBreathe 4s ease-in-out infinite}
.em-pin:hover .ring,.em-pin:focus-visible .ring{animation:none}

/* ============================================================
   ON GILI AIR — motion (staged for review; linked from
   experience-map.js's addGiliMotion(), gili zone only — every
   other zone's hero is untouched). Skipped entirely under
   prefers-reduced-motion at the JS level, same as the water
   zone's motion.
   Stacking: gm-layer sits below .em-hero-grad (same vignette
   darkens the photo and every layer alike) and below .em-pin
   (both z-indexed globally above, see the ".em-hero-grad"/
   ".em-pin" rules earlier in this file).
   ============================================================ */
.gm-layer{position:absolute;inset:0;z-index:1;overflow:hidden;pointer-events:none}

/* ---- Ken Burns: slow zoom/pan on the same aerial photo ---- */
.gm-photo{position:absolute;inset:-6%;background:center/cover no-repeat;
  animation:gmKenBurns 34s ease-in-out infinite alternate}
@keyframes gmKenBurns{0%{transform:scale(1) translate(0,0)}100%{transform:scale(1.08) translate(-1.5%,-1%)}}

/* ---- drifting cloud-shadow blobs ---- */
.gm-cloud{position:absolute;top:-10%;width:38%;height:55%;border-radius:50%;
  background:radial-gradient(ellipse,rgba(10,30,40,.16),rgba(10,30,40,0) 70%);
  mix-blend-mode:multiply;filter:blur(18px)}
.gm-cloud.c1{left:-10%;animation:gmCloudDrift1 46s linear infinite}
.gm-cloud.c2{left:40%;top:0;width:30%;height:45%;animation:gmCloudDrift2 60s linear infinite}
@keyframes gmCloudDrift1{0%{transform:translateX(0)}100%{transform:translateX(160%)}}
@keyframes gmCloudDrift2{0%{transform:translateX(0)}100%{transform:translateX(140%)}}

/* ---- reef shimmer, confined to the reef band around the pinned island ---- */
.gm-reef{position:absolute;left:50%;top:38%;width:52%;height:48%;opacity:.5;
  -webkit-mask-image:radial-gradient(ellipse 60% 55% at 60% 55%,#000 35%,transparent 75%);
  mask-image:radial-gradient(ellipse 60% 55% at 60% 55%,#000 35%,transparent 75%);
  background-image:radial-gradient(circle,rgba(255,255,255,.8) 1px,transparent 1.6px);
  background-size:60px 60px;mix-blend-mode:screen;
  animation:gmReefShimmer 10s ease-in-out infinite}
@keyframes gmReefShimmer{0%,100%{opacity:.35}50%{opacity:.6}}

/* ============================================================
   ON LOMBOK — motion (staged for review; linked from
   experience-map.js's addLombokMotion(), called from inside
   buildLombok() rather than the shared ZONES.forEach branch,
   since Lombok uses its own build function). Same stacking as
   every other zone's motion layer.
   ============================================================ */
.lm-layer{position:absolute;inset:0;z-index:1;overflow:hidden;pointer-events:none}

/* ---- Ken Burns: slow zoom/pan on the same satellite photo ---- */
.lm-photo{position:absolute;inset:-6%;background:center/cover no-repeat;
  animation:lmKenBurns 40s ease-in-out infinite alternate}
@keyframes lmKenBurns{0%{transform:scale(1) translate(0,0)}100%{transform:scale(1.06) translate(-1%,1%)}}

/* ---- drifting cloud cover — screen-blended white, not the dark aerial-shadow blobs Gili Air uses ---- */
.lm-cloud{position:absolute;top:-15%;width:34%;height:60%;border-radius:50%;
  background:radial-gradient(ellipse,rgba(255,255,255,.22),rgba(255,255,255,0) 70%);
  mix-blend-mode:screen;filter:blur(20px)}
.lm-cloud.c1{left:-12%;animation:lmCloudDrift1 58s linear infinite}
.lm-cloud.c2{left:45%;top:10%;width:26%;height:46%;animation:lmCloudDrift2 72s linear infinite}
@keyframes lmCloudDrift1{0%{transform:translateX(0)}100%{transform:translateX(170%)}}
@keyframes lmCloudDrift2{0%{transform:translateX(0)}100%{transform:translateX(150%)}}

/* ---------- dev-only edit-mode panel (?edit=1) ---------- */
.em-editpanel{position:fixed;bottom:16px;right:16px;z-index:999;width:260px;
  background:var(--ink);color:var(--bone);font-family:Jost,sans-serif;font-size:.72rem;
  padding:12px 14px;border-radius:8px;box-shadow:0 12px 30px -12px rgba(0,0,0,.5)}
.em-editpanel b{display:block;margin-bottom:6px;font-weight:500}
.em-editpanel pre{margin:0 0 8px;white-space:pre-wrap;font-size:.68rem;line-height:1.5;
  max-height:220px;overflow-y:auto;font-family:ui-monospace,Menlo,monospace}
.em-editpanel button{appearance:none;border:1px solid var(--bone);background:none;color:var(--bone);
  font-family:inherit;font-size:.68rem;padding:5px 10px;border-radius:20px;cursor:pointer}
.em-editpanel button:hover{background:var(--bone);color:var(--ink)}

/* ---------- reduced motion ---------- */
@media (prefers-reduced-motion:reduce){
  .expmap *{transition-duration:.001ms!important}
}
