/* ============================================================
   BLUE ORCHID BEACH — motion layer ("Tide & Light")
   Start states exist only under html.motion, which the inline boot script sets and a
   failsafe removes if motion.js never reports in — so no JS, a blocked CDN, reduced
   motion and ?still=1 all render the finished page. Only transform and opacity animate.
   ============================================================ */

:root{
  --tide:cubic-bezier(.16,1,.3,1);   /* reveals, frames, arrivals */
  --swell:cubic-bezier(.7,0,.2,1);   /* two-way moves: curtains, swaps */
}

/* ---------- Lenis ---------- */
html.lenis,html.lenis body{height:auto}
.lenis.lenis-smooth{scroll-behavior:auto!important}
.lenis.lenis-smooth [data-lenis-prevent]{overscroll-behavior:contain}
.lenis.lenis-stopped{overflow:hidden}

/* ---------- Start states ----------
   Every element with a motion role waits transparent until motion.js plays it. Opacity,
   not visibility: unrevealed content stays in the tab order and in the accessibility
   tree, and anything that receives focus is revealed on the spot. */
.motion [data-m]{opacity:0}
/* A photo that arrived by page-transition morph is on screen from the first frame. */
.motion [data-m][data-arrived]{opacity:1!important}
/* Header photos are painted slightly enlarged and settle to 1 as the page arrives. */
.motion .hero__media,.motion .pagehead__media{transform:scale(1.16)}

/* ---------- Split text ----------
   Line masks get a little room below so Playfair's descenders aren't clipped. */
.m-line-mask{padding-bottom:.12em;margin-bottom:-.12em}

/* ---------- Kicker rule draws in (motion.js tweens --k from 0 to 1) ---------- */
.kicker::before{transform:scaleX(var(--k,1));transform-origin:right center}
.kicker.kicker--center::after{transform:scaleX(var(--k,1));transform-origin:left center}

/* ---------- Colour-block curtain ----------
   A page-coloured sheet leaves first, then a brand-colour block, uncovering the photo.
   The frame and its shadow never move; only the sheets translate. --c1 follows the
   time of day: lagoon in the morning, sunset gold mid-page, orchid at dusk. */
.curtain{position:absolute;inset:0;z-index:4;pointer-events:none;overflow:hidden;border-radius:inherit}
.curtain i{position:absolute;inset:0;background:var(--c1,var(--lagoon))}
.curtain i+i{background:var(--c2,var(--paper))}
.bg-paper2 .curtain i+i{--c2:var(--paper-2)}
.essence .curtain i+i{--c2:var(--foliage-deep)}
.essence .curtain i{--c1:var(--yellow)}

/* ---------- Day-cycle sky ---------- */
.motion .sky__l{will-change:opacity}

/* ---------- Nav: hides on the way down, returns on the way up ---------- */
.nav--hide{transform:translateY(-100%)}
body.menu-open .nav--hide{transform:none}
.nav__progress{position:absolute;left:0;right:0;bottom:0;height:2px;pointer-events:none;
  background:linear-gradient(90deg,var(--lagoon),var(--yellow-soft) 55%,var(--orchid));
  transform:scaleX(0);transform-origin:left center;opacity:0;transition:opacity var(--t) var(--ease)}
.nav.scrolled .nav__progress{opacity:1}
/* link labels roll up to a second copy on hover */
.roll{display:inline-flex;flex-direction:column;height:1.5em;line-height:1.5em;overflow:hidden;vertical-align:top}
.roll>span{display:block;transition:transform .55s var(--tide)}
.nav-links a:hover .roll>span,.nav-links a:focus-visible .roll>span{transform:translateY(-100%)}

/* ---------- Sun dial label rolls between times of day ---------- */
.motion .sundial__label{min-width:6.2em;text-align:left}

/* ---------- Cursor bubble (fine pointers, over photos that open the viewer) ---------- */
.cursor{position:fixed;left:0;top:0;z-index:1500;width:86px;height:86px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;pointer-events:none;
  background:rgba(168,67,101,.92);color:#fff;box-shadow:0 18px 40px -16px rgba(168,67,101,.7);
  font-family:"Playfair Display",Georgia,serif;font-style:italic;font-size:1rem;letter-spacing:.01em}

/* ---------- Buttons: a sheen crosses on hover ---------- */
.btn{position:relative;overflow:hidden;isolation:isolate}
.btn::after{content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:linear-gradient(105deg,transparent 32%,rgba(255,255,255,.26) 50%,transparent 68%);
  transform:translateX(-120%)}
.btn:hover::after{transform:translateX(120%);transition:transform .95s var(--tide)}

/* ---------- Footer night ---------- */
.motion .fireflies{display:block}
.fireflies i{position:absolute;left:var(--x);top:var(--y);width:4px;height:4px;border-radius:50%;
  background:#f6e58d;box-shadow:0 0 12px 3px rgba(246,229,141,.5);opacity:0;
  animation:firefly var(--t,9s) ease-in-out var(--d,0s) infinite;animation-play-state:paused}
.footer.is-inview .fireflies i{animation-play-state:running}
@keyframes firefly{
  0%{opacity:0;transform:translate(0,0) scale(.6)}
  20%{opacity:.85}
  50%{opacity:.3;transform:translate(var(--dx),var(--dy)) scale(1)}
  75%{opacity:.75}
  100%{opacity:0;transform:translate(calc(var(--dx) * 1.5),calc(var(--dy) * .35)) scale(.7)}
}

/* ---------- First-visit intro ----------
   Only on the first page of a session (html.intro-on). The orchid blooms, the stacked
   wordmark writes itself line by line, and the panel lifts into the page. The strips are
   static clip-paths; only the wipes inside them move. */
.intro{display:none}
.intro-on .intro{display:flex;position:fixed;inset:0;z-index:3000;align-items:center;justify-content:center;
  background:
    radial-gradient(62vw 62vw at 84% 6%, rgba(65,163,189,.24), transparent 60%),
    radial-gradient(50vw 50vw at 8% 94%, rgba(206,163,4,.16), transparent 60%),
    linear-gradient(160deg,var(--foliage),var(--foliage-deep))}
.intro__inner{display:flex;flex-direction:column;align-items:center;gap:clamp(18px,3vw,30px)}
.intro__orchid{width:clamp(84px,9vw,118px);height:auto;overflow:visible}
.intro__orchid .petal{fill:url(#orchidPetal);opacity:0}
.intro__orchid .lip{fill:var(--orchid)}
.intro__orchid .column{fill:#FFF6DC}
.intro__mark{position:relative;width:min(330px,64vw);aspect-ratio:3045/2112}
.intro__band{position:absolute;inset:0;clip-path:inset(var(--top) 0 calc(100% - var(--top) - var(--h)) 0)}
.intro__wipe{position:absolute;inset:0;overflow:hidden;transform:translateX(-101%)}
.intro__hold{position:absolute;inset:0;transform:translateX(101%)}
.intro__hold img{width:100%;height:auto}

/* ---------- Page transitions: the next page rises like the tide ----------
   Cross-document view transitions (Chrome, Safari); other browsers navigate normally.
   The nav and sun dial stay put; going back reverses the direction. */
@media (prefers-reduced-motion:no-preference){
  @view-transition{navigation:auto}
}
.nav{view-transition-name:site-nav}
.sundial{view-transition-name:sundial}
::view-transition-old(root){animation:vt-sink .85s cubic-bezier(.7,0,.2,1) both}
::view-transition-new(root){animation:vt-rise 1s cubic-bezier(.16,1,.3,1) both;
  border-radius:28px 28px 0 0;box-shadow:0 -30px 80px -24px rgba(20,26,14,.42)}
html.vt-back::view-transition-old(root){animation-name:vt-sink-back}
html.vt-back::view-transition-new(root){animation-name:vt-rise-back;border-radius:0 0 28px 28px}
@keyframes vt-sink{to{transform:translateY(-5%) scale(.965);opacity:.3}}
@keyframes vt-rise{from{transform:translateY(100%)}}
@keyframes vt-sink-back{to{transform:translateY(5%) scale(.965);opacity:.3}}
@keyframes vt-rise-back{from{transform:translateY(-100%)}}
/* a home room card's photo flies into its suite */
::view-transition-group(room-media){animation-duration:.95s;animation-timing-function:cubic-bezier(.7,0,.2,1);overflow:clip;border-radius:24px}
::view-transition-old(room-media),::view-transition-new(room-media){height:100%;object-fit:cover}

/* ---------- Home: hero ---------- */
/* a soft sun glint drifts over the aerial (light, not a grade: screen blend, low opacity) */
.motion .hero__leak{display:block;position:absolute;inset:-25%;pointer-events:none;mix-blend-mode:screen;opacity:.55;
  background:radial-gradient(34% 30% at 64% 34%, rgba(255,221,160,.42), transparent 70%);
  animation:leak 24s ease-in-out infinite alternate}
@keyframes leak{from{transform:translate(-7%,-4%)}to{transform:translate(7%,5%)}}
.motion .hero__frame{will-change:transform}

/* ---------- Home: the vibe ---------- */
.motion .essence::before{animation:breathe 20s ease-in-out infinite alternate;will-change:transform}
@keyframes breathe{from{transform:scale(1) translate(0,0)}to{transform:scale(1.14) translate(-2.5%,2%)}}
.motion .essence .feature__media img[data-vibe-main]{transform:scale(1.12)} /* room for the drift */

/* ---------- Home: the Experience as three chapters (motion only) ----------
   JS picks the layout. .is-on (1024px and up): texts on the left, one sticky photo frame
   on the right. .is-stack (phones and tablets): the photo pins edge to edge across the top
   and the texts scroll up beneath it. Either way the features dissolve into one grid and
   each chapter wipes its photo up over the last. Without either class (no JS, reduced
   motion, short landscape screens) this is the ordinary stacked layout. */
.chapters__hud,.chapters__shade{display:none}
.chapters:is(.is-on,.is-stack) .feature{display:contents}
.chapters:is(.is-on,.is-stack) .feature__body{transition:opacity .8s var(--ease)}
.chapters:is(.is-on,.is-stack) .feature__body:not(.is-active){opacity:.26}
.chapters:is(.is-on,.is-stack) .feature__media,.chapters:is(.is-on,.is-stack) .chapters__hud{align-self:start;position:sticky;aspect-ratio:auto;order:0}
.chapters:is(.is-on,.is-stack) .feature__media.is-layer{box-shadow:none} /* one shadow for the stack */
.chapters:is(.is-on,.is-stack) .feature__media::after{display:none} /* one shared tint, on the HUD */
.chapters:is(.is-on,.is-stack) .feature:hover .feature__media img{transform:none}
.chapters:is(.is-on,.is-stack) .feature__media img{transition:none}
.chapters:is(.is-on,.is-stack) .chapters__shade{display:block;position:absolute;inset:0;z-index:1;background:#0d1208;opacity:0;pointer-events:none}
.chapters:is(.is-on,.is-stack) .feature__badge{z-index:2}
.chapters:is(.is-on,.is-stack) .chapters__hud{display:block;z-index:4;pointer-events:none;overflow:hidden}
.chapters__hud::before{content:"";position:absolute;inset:0;background:linear-gradient(120deg,rgba(168,67,101,.12),rgba(65,163,189,.06));mix-blend-mode:multiply}
.chapters__hud::after{content:"";position:absolute;inset:auto 0 0 0;height:40%;background:linear-gradient(0deg,rgba(13,18,8,.55),transparent)}
.chapters__count{position:absolute;left:30px;bottom:34px;z-index:1;display:flex;align-items:baseline;gap:10px;color:#fff;
  font-family:"Playfair Display",Georgia,serif;font-variant-numeric:lining-nums tabular-nums;text-shadow:0 2px 18px rgba(0,0,0,.35)}
.chapters__digits{display:block;height:1em;overflow:hidden;font-size:3rem;line-height:1}
.chapters__digits i{display:block;font-style:normal;height:1em}
.chapters__of{font-size:1rem;color:rgba(255,255,255,.72);letter-spacing:.06em}
.chapters__bar{position:absolute;left:30px;right:30px;bottom:22px;z-index:1;height:2px;background:rgba(255,255,255,.22);border-radius:2px;overflow:hidden}
.chapters__bar i{position:absolute;inset:0;background:var(--yellow-soft);transform:scaleX(0);transform-origin:left center}
@media (min-width:1024px){
  .chapters.is-on{grid-template-columns:.85fr 1.15fr;column-gap:clamp(48px,6vw,96px);row-gap:0;align-items:start}
  .chapters.is-on .feature__body{grid-column:1;grid-row:var(--row);min-height:84vh;display:flex;flex-direction:column;justify-content:center;align-items:flex-start;padding-block:6vh}
  .chapters.is-on .feature__media,.chapters.is-on .chapters__hud{grid-column:2;grid-row:1 / span 3;top:calc(50vh - min(32vh,310px));height:min(64vh,620px)}
  .chapters.is-on .chapters__hud{border-radius:var(--r-lg)}
}
@media (max-width:1023px){
  /* The stage spans every row so it can stay pinned while all three texts pass under it;
     the negative margins undo the container's 22px gutter so it runs edge to edge. */
  .chapters.is-stack{--stage:min(46vh,440px);grid-template-columns:minmax(0,1fr);grid-template-rows:var(--stage)}
  .chapters.is-stack .feature__media,.chapters.is-stack .chapters__hud{grid-column:1;grid-row:1 / span 4;top:0;height:var(--stage);margin-inline:-22px;border-radius:0;box-shadow:none}
  .chapters.is-stack .chapters__hud{box-shadow:0 24px 30px -24px rgba(20,26,14,.5)}
  .chapters.is-stack .feature__body{grid-column:1;grid-row:var(--row-m);min-height:calc(100vh - var(--stage) - 40px);
    display:flex;flex-direction:column;justify-content:center;align-items:flex-start;padding:10px 0 30px}
  .chapters.is-stack .feature__body:not(.is-active){opacity:.3}
  .chapters.is-stack .feature__badge{left:22px}
  .chapters.is-stack .chapters__count{left:22px;bottom:28px}
  .chapters.is-stack .chapters__digits{font-size:2.4rem}
  .chapters.is-stack .chapters__bar{left:22px;right:22px;bottom:16px}
}
/* Small viewport units keep the stage steady while a phone's toolbar slides in and out. */
@supports (height:1svh){
  @media (max-width:1023px){
    .chapters.is-stack{--stage:min(46svh,440px)}
    .chapters.is-stack .feature__body{min-height:calc(100svh - var(--stage) - 40px)}
  }
}

/* ---------- Odometer numbers (stats) ---------- */
.sr-only{position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
.odo{display:inline-flex;align-items:flex-start;font-variant-numeric:lining-nums tabular-nums}
.odo__col{display:inline-block;height:1.1em;overflow:hidden;line-height:1.1}
.odo__strip{display:block}
.odo__strip b{display:block;height:1.1em;font-weight:inherit}
.odo__ch{display:inline-block;line-height:1.1}

/* ---------- Room cards: a glare follows the pointer across the tilt ---------- */
.room-card__glare{position:absolute;inset:-50%;z-index:3;pointer-events:none;opacity:0;
  background:radial-gradient(circle at 50% 50%,rgba(255,255,255,.18),transparent 38%);transition:opacity .5s var(--ease)}
.room-card:hover .room-card__glare{opacity:1}

/* ---------- Home: the kinetic strip (JS drives it; CSS loop is the fallback) ---------- */
.marquee.is-live .marquee__row{animation:none}
.marquee.is-live{touch-action:pan-y;cursor:grab}
.marquee.is-dragging{cursor:grabbing}
.marquee.is-dragging .marquee__item{pointer-events:none}

/* ---------- Viewer: the photo flies from its thumbnail, so the figure itself holds still ---------- */
.motion-live .lightbox figure{transform:none;transition:none}
.lb-ghost{position:fixed;z-index:2100;margin:0;object-fit:cover;border-radius:var(--r);pointer-events:none;box-shadow:0 30px 80px -20px rgba(0,0,0,.6)}

/* ---------- Location: the karst mist drifts (a cinemagraph made of soft gradients) ---------- */
.fog{display:none}
.motion .fog{display:block;position:absolute;inset:0;z-index:1;overflow:hidden;pointer-events:none}
.fog i{position:absolute;left:0;top:4%;width:220%;height:58%;opacity:.36;
  background:
    radial-gradient(20% 46% at 14% 56%, rgba(255,255,255,.6), transparent 72%),
    radial-gradient(26% 52% at 42% 44%, rgba(255,255,255,.48), transparent 72%),
    radial-gradient(18% 40% at 70% 60%, rgba(255,255,255,.55), transparent 72%),
    radial-gradient(22% 50% at 92% 48%, rgba(255,255,255,.4), transparent 72%);
  background-size:50% 100%;background-repeat:repeat-x;
  animation:fog 90s linear infinite;animation-play-state:paused}
.fog i+i{top:20%;height:46%;opacity:.22;background-position:30% 0;animation-duration:140s;animation-direction:reverse}
.locrow__media.is-inview .fog i{animation-play-state:running}
@keyframes fog{from{transform:translateX(0)}to{transform:translateX(-50%)}}

/* ---------- Home CTA: a warm dusk glow that sinks as you pass ---------- */
.cta__glow{display:none}
.motion .cta__glow{display:block;position:absolute;inset:0;z-index:-1;pointer-events:none;mix-blend-mode:screen;
  background:radial-gradient(40% 48% at 74% 62%, rgba(255,190,112,.46), rgba(255,160,90,.1) 55%, transparent 72%)}

/* ---------- Inner pages ---------- */
/* the page-head photo reaches above the header so its scroll parallax never shows a gap */
.motion .pagehead__media{top:-12%}

/* ---------- Gallery filter: the active fill flows from the old pill into the new one ---------- */
.motion-live .filter{position:relative;overflow:hidden;isolation:isolate}
.motion-live .filter::before{content:"";position:absolute;inset:0;z-index:-1;background:var(--foliage);
  transform:scaleX(0);transform-origin:var(--from,left) center;transition:transform .6s var(--tide)}
.motion-live .filter.is-active{background:var(--card);border-color:var(--foliage);color:var(--cream)}
.motion-live .filter.is-active::before{transform:scaleX(1)}
.motion-live .masonry{position:relative}

/* ---------- Booking ---------- */
.motion-live .panel{animation:none} /* motion.js slides panels by direction instead */
.motion-live .stepper li.active .dot{animation:dotpop .7s var(--spring)}
@keyframes dotpop{0%{transform:scale(.7)}60%{transform:scale(1.14)}100%{transform:scale(1)}}
.ripple{position:absolute;z-index:-1;width:120px;height:120px;margin:-60px 0 0 -60px;border-radius:50%;pointer-events:none;background:rgba(168,67,101,.2)}
.summary dd.is-new,.summary .total b.is-new{animation:flash 1s var(--ease)}
@keyframes flash{0%{opacity:.35}100%{opacity:1}}
.confirm{position:relative}
.petal-burst{position:absolute;left:50%;top:44px;width:0;height:0;pointer-events:none;z-index:2}
.petal-burst i{position:absolute;left:-7px;top:-4px;width:14px;height:8px;border-radius:50% 50% 50% 50% / 60% 60% 40% 40%;background:var(--c,var(--yellow-soft))}

/* ---------- Mobile menu: links cascade in behind the sliding panel ---------- */
.motion .mobile-menu a{opacity:0;transform:translateY(26px);
  transition:opacity .45s var(--ease),transform .8s var(--tide),color var(--t) var(--ease),translate var(--t) var(--spring)}
.motion body.menu-open .mobile-menu a{opacity:1;transform:none}
.motion body.menu-open .mobile-menu a:nth-child(1){transition-delay:.16s}
.motion body.menu-open .mobile-menu a:nth-child(2){transition-delay:.22s}
.motion body.menu-open .mobile-menu a:nth-child(3){transition-delay:.28s}
.motion body.menu-open .mobile-menu a:nth-child(4){transition-delay:.34s}
.motion body.menu-open .mobile-menu a:nth-child(5){transition-delay:.42s}
