/* Saloni & Praful — garden invite
   Scenes: hill road → envelope → card → (zoom through) garden tree hub → gold frames → event scenes → engagement gallery
   Layout rule: a painting is NEVER cropped. Every painted layer lives in a .pbox (937×1679 portrait canvas):
     · phones (taller than the canvas) → full-bleed, canvas pinned to the bottom, its top edge mirrored + softened above
     · tablets / laptops (wider)        → canvas at full height, centred, a mirrored + blurred continuation at the sides
   ------------------------------------------------------------------ */
:root{
  --script:'Alex Brush',cursive;
  --sans:'Jost',system-ui,sans-serif;
  --serif:'Cormorant Garamond',Georgia,serif;
  --hindi:'Tiro Devanagari Hindi',serif;

  --paper:#f5f0e6;
  --paper-2:#f7f3eb;
  --ink:#5c5651;
  --ink-2:#7a736c;
  --rose:#8e4a5c;
  --gold:#b8923e;
  --wine:#9a2a35;

  --vh:100dvh;
  --pr:.5581;                    /* portrait canvas 937/1679 */
  --zoom:1.5s;                   /* frame zoom duration */
  --ease:cubic-bezier(.65,0,.35,1);
}
*{box-sizing:border-box;margin:0;padding:0}
html,body{height:100%;height:100dvh;background:#efe7da;overflow:hidden;-webkit-text-size-adjust:100%;overscroll-behavior:none}
body{font-family:var(--sans);color:var(--ink);-webkit-font-smoothing:antialiased;touch-action:manipulation}
button{font:inherit;color:inherit;cursor:pointer;background:none;border:0}
img{display:block;user-select:none;-webkit-user-drag:none}
img[hidden]{display:none}

/* ================= BACKDROP (visible around the frame on tablets / laptops) ================= */
.backdrop{position:fixed; inset:0; overflow:hidden; background:#86b6df url(../img/intro/sky.webp) center/cover no-repeat; pointer-events:none}
.backdrop::after{content:""; position:absolute; inset:0; background:radial-gradient(ellipse at 50% 55%, rgba(0,0,0,0) 40%, rgba(20,40,70,.32) 100%)}
.backdrop__cloud{position:absolute; opacity:.85}
.backdrop__cloud--1{width:34vw; left:-6vw; top:8vh; animation:bdrift 70s linear infinite}
.backdrop__cloud--2{width:26vw; left:60vw; top:-4vh; animation:bdrift 90s linear infinite reverse}
.backdrop__cloud--3{width:30vw; left:30vw; top:62vh; opacity:.6; animation:bdrift 110s linear infinite}
@keyframes bdrift{from{transform:translateX(-12vw)}to{transform:translateX(100vw)}}

/* ================= STAGE ================= */
.stage{
  position:fixed; inset:0; margin:auto;
  width:100%; height:var(--vh); height:100dvh;
  overflow:clip; container-type:size;
  background:#efe7da;
  transition:opacity .9s ease;
  outline:none; -webkit-tap-highlight-color:transparent;
  --u:1cqw;                      /* paper unit: envelope + card sizes scale with this */
  --env-top:9.5cqh;
  --cardw:min(88cqw, 46cqh);
}
.stage.is-loading{opacity:0}
.stage.is-loading .scene *,.stage.is-loading .clouds *{animation-play-state:paused}
.stage.is-intro,.stage.is-card,.stage.is-scene{cursor:pointer}

.sky{position:absolute; inset:0; background:#86b6df url(../img/intro/sky.webp) center top/cover no-repeat}

/* ================= THE PORTRAIT CANVAS BOX ================= */
.pbox{position:absolute; left:50%; bottom:0; width:100cqw; aspect-ratio:937/1679; transform:translateX(-50%)}
.pbox > img.land,.garden__art,.event__art,.gallery__art{position:absolute; inset:0; width:100%; height:100%; object-fit:cover}

/* extensions: the painting mirrored outward, sharp at the seam, melting into blur */
.ext{position:absolute; pointer-events:none}
.ext img{position:absolute; inset:0; width:100%; height:100%}
.ext__blur{filter:blur(18px) brightness(.86) saturate(.92)}
.ext--top{left:0; width:100%; bottom:calc(100% - 1.5px); height:100%}
.ext--top img{transform:scaleY(-1)}
.ext--top .ext__blur{-webkit-mask-image:linear-gradient(to bottom, rgba(0,0,0,0) 0, #000 16cqh); mask-image:linear-gradient(to bottom, rgba(0,0,0,0) 0, #000 16cqh)}
.ext--left{top:0; height:100%; right:100%; width:100%}
.ext--right{top:0; height:100%; left:100%; width:100%}
.ext--left img,.ext--right img{transform:scaleX(-1)}
.ext--left .ext__blur{-webkit-mask-image:linear-gradient(to right, rgba(0,0,0,0) .5cqw, #000 8cqw); mask-image:linear-gradient(to right, rgba(0,0,0,0) .5cqw, #000 8cqw)}
.ext--right .ext__blur{-webkit-mask-image:linear-gradient(to left, rgba(0,0,0,0) .5cqw, #000 8cqw); mask-image:linear-gradient(to left, rgba(0,0,0,0) .5cqw, #000 8cqw)}
.vignette{position:absolute; inset:0; pointer-events:none; display:none;
  background:linear-gradient(to right, rgba(20,40,70,.28), rgba(20,40,70,0) 18%, rgba(20,40,70,0) 82%, rgba(20,40,70,.28)),
             linear-gradient(to bottom, rgba(20,40,70,.18), rgba(20,40,70,0) 22%)}

/* wider than the canvas (tablets, laptops): canvas at full height, centred, sides continue softly */
@media (min-aspect-ratio:5581/10000){
  .stage{--u:.6cqh; --env-top:11cqh}
  .pbox{bottom:auto; top:0; width:auto; height:100cqh; aspect-ratio:937/1679;
    box-shadow:0 0 clamp(24px, 4cqw, 70px) rgba(10,25,45,.45), 0 0 0 1px rgba(255,255,255,.18)}
  .pbox .ext--top{display:none}
  .pbox .ext--left,.pbox .ext--right{width:100cqw}
  .pbox .ext--left .ext__sharp,.pbox .ext--right .ext__sharp{display:none}
  .pbox .ext--left .ext__blur,.pbox .ext--right .ext__blur{-webkit-mask-image:none; mask-image:none;
    filter:blur(26px) brightness(.78) saturate(.9); transform:scaleX(-1.08)}
  .vignette{display:block}
  .clouds{left:50%; width:calc(100cqh * .5581); transform:translateX(-50%); overflow:hidden}
}
@media (min-aspect-ratio:5581/10000) and (max-aspect-ratio:62/100){
  .pbox{box-shadow:none}
  .vignette{display:none}
}
@media (max-aspect-ratio:5581/10000){
  .pbox .ext--left,.pbox .ext--right{display:none}
  .vignette{display:block; opacity:.6}
}

/* garden, event & gallery cover the screen on phones so no flat-sky band shows at the top/bottom */
@media (max-aspect-ratio:5581/10000){
  .scene--p,.garden__box,.event__box,.gallery__box{
    bottom:auto; top:0; aspect-ratio:auto;
    width:calc(100cqh * 937 / 1679); height:100cqh;
  }
  .intro .ext,.garden .ext,.event .ext,.gallery .ext{display:none}
}

/* ================= LAYER VISIBILITY BY STATE ================= */
.intro,.garden,.event,.gallery{position:absolute; inset:0}
.intro,.paper{transition:opacity .9s ease}
.garden{opacity:0; pointer-events:none; transition:opacity 1s ease}
.event{opacity:0; pointer-events:none; transition:opacity .7s ease}
.gallery{opacity:0; pointer-events:none; transition:opacity 1s ease}

.is-hub .intro,.is-zoomin .intro,.is-scene .intro,.is-zoomout .intro,.is-gallery .intro,
.is-hub .paper,.is-zoomin .paper,.is-scene .paper,.is-zoomout .paper,.is-gallery .paper{opacity:0; pointer-events:none; visibility:hidden; transition:opacity .9s ease, visibility 0s .9s}
.is-through .garden,.is-hub .garden,.is-zoomin .garden,.is-zoomout .garden{opacity:1}
.is-hub .garden,.is-zoomout .garden{pointer-events:auto}
.is-zoomin .event,.is-scene .event{opacity:1}
.is-scene .event{pointer-events:auto}
.is-gallery .gallery{opacity:1; pointer-events:auto}
.is-scene .garden{opacity:0; transition:none}
.is-zoomout .garden{transition:none}   /* garden snaps visible behind the fading scene so the reverse shows no dip */

/* ================= SCENE 1 · hill road ================= */
.scenery{position:absolute; inset:0}
.intro::after{content:""; position:absolute; inset:0; z-index:1; pointer-events:none; opacity:0; transition:opacity .9s ease;
  background:rgba(18,30,46,.3); backdrop-filter:blur(2px); -webkit-backdrop-filter:blur(2px)}
.is-open .intro::after,.is-card .intro::after,.is-through .intro::after{opacity:1}
.land{position:absolute; inset:0; width:100%; height:100%}

.clouds{position:absolute; inset:0; pointer-events:none}
.cloud{position:absolute; opacity:.9; filter:saturate(.9)}
.cloud--a{width:calc(60 * var(--u)); left:-8%; top:-1cqh; animation:drift 46s ease-in-out infinite alternate}
.cloud--b{width:calc(46 * var(--u)); left:52%; top:9cqh; opacity:.75; animation:drift 58s ease-in-out infinite alternate-reverse}
.cloud--c{width:calc(36 * var(--u)); left:58%; top:24cqh; opacity:.7; animation:drift 40s ease-in-out infinite alternate}
@keyframes drift{from{transform:translateX(-2.5%)}to{transform:translateX(2.5%)}}

.flock{display:none}   /* the new hill-road painting has its own flock of birds */
@keyframes flockDrift{from{transform:translate(-2%,3%)}to{transform:translate(16%,-5%)}}
.bird{position:absolute; transform-origin:50% 60%; animation:flap .46s ease-in-out infinite alternate}
@keyframes flap{from{transform:scaleY(1) translateY(0)}to{transform:scaleY(.42) translateY(2%)}}

.car{position:absolute; transform:translate(-50%,-50%); left:51%; top:89%; width:32%;
  filter:drop-shadow(0 .3cqw .5cqw rgba(0,0,0,.25));
  animation:drive 8s cubic-bezier(.3,.05,.6,1) forwards}
@keyframes drive{
  0%  {left:51%; top:89%;   width:32%}
  28% {left:61%; top:83%;   width:24%}
  52% {left:66%; top:77.5%; width:16.5%}
  76% {left:57%; top:70%;   width:11%}
  100%{left:53%; top:61.5%; width:7.5%}
}

/* ================= PAPER LAYER (envelope + card) ================= */
.paper{position:absolute; inset:0}

.env-wrap{position:absolute; inset:0; z-index:5; transition:opacity .9s ease, transform 1.2s cubic-bezier(.4,0,.6,1); pointer-events:none}
.stage:not(.is-intro):not(.is-open) .env-wrap{opacity:0; transform:translateY(6%) scale(.94)}
.env{
  position:absolute; left:calc(50% - 48 * var(--u)); top:var(--env-top); width:calc(96 * var(--u)); aspect-ratio:1.778;
  transform-origin:50% 50%; backface-visibility:hidden;
  animation:envIn 1.1s cubic-bezier(.2,.7,.2,1) both, envFloat 6s ease-in-out 1.1s infinite;
}
.env__face{position:absolute; inset:0; width:100%; height:100%; object-fit:contain;
  filter:drop-shadow(0 calc(1 * var(--u)) calc(2.2 * var(--u)) rgba(30,40,60,.32))}
@keyframes envIn{from{opacity:0; transform:rotate(-7deg) translateY(-10%) scale(1.12)}to{opacity:1; transform:rotate(-7deg) translateY(0) scale(1)}}
@keyframes envFloat{0%,100%{transform:rotate(-7deg) translateY(0)}50%{transform:rotate(-6.3deg) translateY(-1.4%)}}
.is-open .env{animation:envOpenShake .6s ease both}
@keyframes envOpenShake{0%,100%{transform:rotate(-7deg)}25%{transform:rotate(-8.2deg) translateY(.6%)}60%{transform:rotate(-6deg) translateY(-.4%)}}

.env__paper{position:absolute; inset:0; background:var(--paper); border-radius:calc(.6 * var(--u));
  box-shadow:0 calc(1.2 * var(--u)) calc(3 * var(--u)) rgba(30,40,60,.28), 0 calc(.3 * var(--u)) calc(.6 * var(--u)) rgba(30,40,60,.15), inset 0 0 0 1px rgba(255,255,255,.6)}
.env__paper::before{content:""; position:absolute; inset:0; border-radius:inherit; filter:url(#crumple); background:#fff; mix-blend-mode:multiply; opacity:.9; pointer-events:none}
.env__paper::after{content:""; position:absolute; inset:0; border-radius:inherit; filter:url(#grain); background:#fff; mix-blend-mode:multiply; opacity:.8; pointer-events:none}
.env__flapline{position:absolute; left:0; right:0; top:0; height:48%;
  background:linear-gradient(to bottom, rgba(0,0,0,.035), rgba(0,0,0,0) 60%);
  clip-path:polygon(0 0,100% 0,50% 100%); opacity:.9}

.crest{position:absolute; left:7%; top:15%; width:30%; aspect-ratio:120/130}
.crest__svg{width:100%; height:100%; overflow:visible}
.crest__letter{font-family:var(--script); font-size:56px; fill:var(--gold)}
.crest__letter--2{fill:var(--rose); font-size:50px}
.crest__img{position:absolute; inset:0; width:100%; height:100%; object-fit:contain}
.crest.has-img .crest__svg{display:none}
.crest.has-img{top:12%; width:33%; aspect-ratio:240/260}

.env__text{position:absolute; left:40%; top:36%; width:55%; text-align:center; transform:rotate(-3deg)}
.env__names{font-family:var(--script); color:var(--rose); font-size:calc(6.9 * var(--u)); line-height:1; white-space:nowrap}
.env__names span{font-size:.72em; color:var(--gold); margin:0 .12em}
.env__line{font-family:var(--sans); font-weight:400; font-size:calc(2.05 * var(--u)); letter-spacing:.2em; text-transform:uppercase; color:var(--ink-2); margin-top:calc(1.1 * var(--u))}
.env__line sup{font-size:.6em; letter-spacing:0; vertical-align:top; position:relative; top:.15em}
.env__line--venue:empty{display:none}

.postmark{position:absolute; left:52%; top:6%; width:32%; transform:rotate(-8deg); opacity:.7; mix-blend-mode:multiply}
.seal{position:absolute; filter:drop-shadow(0 calc(.4 * var(--u)) calc(.5 * var(--u)) rgba(60,10,15,.35))}
.seal--env{left:55%; top:-6%; width:13%}

.stamp{position:absolute; background:#fff}
.stamp--env{right:3.5%; top:4%; width:14%; aspect-ratio:.82; transform:rotate(3deg)}
.stamp__pic{position:absolute; inset:9%; background:url(../img/intro/landscape.webp) 55% 62%/300% no-repeat; outline:1px solid rgba(0,0,0,.1); outline-offset:-1px}
.stamp__pic::after{content:""; position:absolute; inset:0; box-shadow:inset 0 0 0 calc(.4 * var(--u)) #fff, inset 0 0 0 calc(.55 * var(--u)) rgba(0,0,0,.08)}
.stamp__edge{position:absolute; background:#fff}
.stamp__edge--t,.stamp__edge--b{left:0; right:0; height:calc(.9 * var(--u));
  background:radial-gradient(circle at calc(.9 * var(--u)) 50%, transparent calc(.42 * var(--u)), #fff calc(.5 * var(--u))) 0 0/calc(1.8 * var(--u)) 100%}
.stamp__edge--t{top:calc(-.45 * var(--u))} .stamp__edge--b{bottom:calc(-.45 * var(--u))}
.stamp__edge--l,.stamp__edge--r{top:0; bottom:0; width:calc(.9 * var(--u));
  background:radial-gradient(circle at 50% calc(.9 * var(--u)), transparent calc(.42 * var(--u)), #fff calc(.5 * var(--u))) 0 0/100% calc(1.8 * var(--u))}
.stamp__edge--l{left:calc(-.45 * var(--u))} .stamp__edge--r{right:calc(-.45 * var(--u))}

/* ---- the card ---- */
.card{
  position:absolute; left:50%; top:50%;
  width:min(90cqw, 52cqh); aspect-ratio:.5625;
  transform-origin:50% 50%; z-index:6; opacity:0;
  transform:translate(-50%,-50%) scale(.82);
  transition:transform 1.5s cubic-bezier(.19,.73,.22,1), opacity 1.1s cubic-bezier(.3,.6,.3,1);
  will-change:transform, opacity; backface-visibility:hidden;
}
.card__face{position:absolute; inset:0; width:100%; height:100%; object-fit:fill; display:block;
  filter:drop-shadow(0 1.4cqw 3cqw rgba(28,30,48,.3))}
.is-open .card,.is-card .card{opacity:1; transform:translate(-50%,-50%) scale(1)}   /* one continuous bloom — no mid-transition restart */
.is-open .env-wrap{opacity:0; transform:scale(1.08)}   /* envelope dissolves as the card blooms in */
/* card reveal is handled by .is-open / .is-card above; the zoom-through is below */
.card__paper{position:absolute; inset:calc(.75 * var(--u)); background:var(--paper-2); overflow:clip;
  box-shadow:0 calc(.8 * var(--u)) calc(2.5 * var(--u)) rgba(30,40,60,.25)}
.card__paper::after{content:""; position:absolute; inset:0; background:#fff; mix-blend-mode:multiply; opacity:.05; pointer-events:none}
.is-card .card__paper{box-shadow:none}

.card__edge{position:absolute; z-index:2}
.card__edge--t,.card__edge--b{left:0; right:0; height:calc(1.5 * var(--u));
  background:radial-gradient(circle at calc(1.5 * var(--u)) 50%, transparent calc(.58 * var(--u)), var(--paper-2) calc(.7 * var(--u))) 0 0/calc(3 * var(--u)) 100%}
.card__edge--t{top:calc(-.75 * var(--u))} .card__edge--b{bottom:calc(-.75 * var(--u))}
.card__edge--l,.card__edge--r{top:0; bottom:0; width:calc(1.5 * var(--u));
  background:radial-gradient(circle at 50% calc(1.5 * var(--u)), transparent calc(.58 * var(--u)), var(--paper-2) calc(.7 * var(--u))) 0 0/100% calc(3 * var(--u))}
.card__edge--l{left:calc(-.75 * var(--u))} .card__edge--r{right:calc(-.75 * var(--u))}

.stamp--card{right:6%; top:3.5%; width:17%; aspect-ratio:.85; transform:rotate(2deg); z-index:3}
.seal--card{right:4%; top:11%; width:11%; z-index:4}

.card__body{position:absolute; inset:0; padding:9% 9% 6%; text-align:center; display:flex; flex-direction:column; align-items:center; justify-content:center; z-index:3;
  container-type:inline-size}
.ganesh{width:16cqw; height:16cqw; display:grid; place-items:center; margin-bottom:.5cqw}
.ganesh__om{font-family:var(--hindi); font-size:11.5cqw; color:var(--gold); line-height:1}
.ganesh img{width:100%; height:100%; object-fit:contain}
.card__shree{font-family:var(--hindi); font-size:4cqw; color:var(--gold); letter-spacing:.05em; margin-bottom:7cqw}
.card__request{font-weight:300; font-size:4.6cqw; line-height:1.55; color:var(--ink); max-width:30ch; margin-bottom:5.6cqw}
.card__name{font-family:var(--script); font-weight:400; font-size:19.5cqw; line-height:1; color:var(--rose)}
.card__parents{font-weight:300; font-size:4.15cqw; line-height:1.6; color:var(--ink-2); letter-spacing:.04em; margin:2cqw 0 4.2cqw}
.card__with{font-family:var(--script); font-size:9.2cqw; color:var(--ink-2); line-height:1; margin:1cqw 0 2cqw}
.card__dates{font-family:var(--sans); font-weight:400; font-size:4cqw; letter-spacing:.22em; text-transform:uppercase; color:var(--rose); margin-top:4cqw}
.card__dates span{font-family:var(--serif); font-weight:500; font-size:1.35em; letter-spacing:0}

.card__body{display:none}
.stamp--card,.seal--card{opacity:0; transition:opacity .6s ease .35s}
.is-card .card__body{display:flex; animation:cardBodyIn .6s ease .3s both}
.is-card .stamp--card,.is-card .seal--card{opacity:1}
@keyframes cardBodyIn{from{opacity:0}to{opacity:1}}

/* the garden seen through the card (zoom-through) */
.card__window{position:absolute; inset:0; width:100%; height:100%; object-fit:cover; object-position:50% 40%; opacity:0; z-index:1; transition:opacity .6s ease}
.stage:not(.is-intro):not(.is-open):not(.is-card) .card__window{opacity:1}
.stage:not(.is-intro):not(.is-open):not(.is-card) .card__body,.stage:not(.is-intro):not(.is-open):not(.is-card) .stamp--card,.stage:not(.is-intro):not(.is-open):not(.is-card) .seal--card{opacity:0; transition:opacity .4s ease}
.stage:not(.is-intro):not(.is-open):not(.is-card) .card{transition:transform 1.9s cubic-bezier(.5,0,.5,1), opacity .9s ease .55s; transform:translate(-50%,-50%) scale(1.75); opacity:0}
.stage:not(.is-intro):not(.is-open):not(.is-card) .card__edge{opacity:0; transition:opacity .4s ease .5s}
.is-through .garden__box{animation:gardenIn 2.2s cubic-bezier(.5,0,.5,1) both}
@keyframes gardenIn{from{transform:translateX(-50%) scale(1.3)}to{transform:translateX(-50%) scale(1)}}

/* ================= THE GARDEN HUB ================= */
.garden__box{container-type:size; transform-origin:50% 50%; backface-visibility:hidden}
.is-zoomin .garden__box,.is-zoomout .garden__box{transition:transform var(--zoom) var(--ease); will-change:transform}
.garden .ext,.garden .leaves{transition:opacity .35s ease}
.is-zoomin .garden .ext,.is-zoomout .garden .ext,
.is-zoomin .leaves,.is-zoomout .leaves{opacity:0}
.is-zoomin .frame__swing,.is-zoomout .frame__swing{animation:none !important}
.is-zoomin .frame__gold,.is-zoomout .frame__gold{filter:none}

/* gold frames hanging from the branches */
.frames{position:absolute; inset:0}
.frame{position:absolute; width:calc(13cqw * var(--fw, .866)); height:calc(13cqw * var(--fh, 1.155)); transform:translate(-50%,-50%); cursor:pointer; -webkit-tap-highlight-color:transparent}
.frame__swing{position:absolute; inset:0; transform-origin:50% -47%; animation:swing 5.2s ease-in-out infinite alternate}
.frame:nth-child(2n) .frame__swing{animation-duration:6.1s; animation-delay:-2s}
.frame:nth-child(3n) .frame__swing{animation-duration:4.6s; animation-delay:-1.2s}
.frame:nth-child(5n) .frame__swing{animation-duration:5.8s; animation-delay:-3.1s}
@keyframes swing{from{transform:rotate(-2.2deg)}to{transform:rotate(2.2deg)}}
.frame__rope{position:absolute; left:50%; bottom:100%; width:.45cqw; height:47%; transform:translateX(-50%);
  background:linear-gradient(to right, #8a6a44, #c8a878 45%, #7a5a38); border-radius:1px; opacity:.95}
.frame__rope::before{content:""; position:absolute; left:-80%; right:-80%; top:-.4cqw; height:.9cqw; border-radius:50%; background:#6f5134; opacity:.8}
.frame__thumb{position:absolute; left:11.33%; top:8.5%; width:77.34%; height:83%; object-fit:cover; background:#dfe8d0}
.frame__gold{position:absolute; inset:0; width:100%; height:100%; object-fit:contain; pointer-events:none; filter:drop-shadow(0 .5cqw .9cqw rgba(30,25,10,.45))}
.frame__label{position:absolute; left:50%; top:103%; transform:translateX(-50%); white-space:nowrap; font-family:var(--script); font-size:2.9cqw; color:#fff; text-shadow:0 1px 6px rgba(20,30,10,.7); opacity:0; transition:opacity .4s ease; pointer-events:none}
.frame:hover .frame__label,.frame:focus-visible .frame__label{opacity:1}
.frame.is-active .frame__label{opacity:0 !important}
.frame.is-active .frame__swing{animation:none}
.frame.is-active .frame__thumb{box-shadow:0 0 0 .5cqw rgba(255,245,200,.5)}
@media (hover:hover){ .frame:hover .frame__swing{animation-play-state:paused} .frame:hover .frame__gold{filter:drop-shadow(0 .9cqw 1.4cqw rgba(30,25,10,.55))} }
.frame__btn{position:absolute; inset:-15% -10%; border-radius:4px}
.frame:focus-visible{outline:2px solid #fff; outline-offset:4px}

/* a few falling leaves */
.leaves{position:absolute; inset:0; pointer-events:none; overflow:clip}
.leaves i{position:absolute; top:-3%; width:1.3cqw; height:.8cqw; border-radius:60% 10%; background:#8fbf5e; opacity:0; animation:leaf 11s linear infinite}
.leaves i:nth-child(1){left:18%; animation-delay:0s; background:#9ac66a}
.leaves i:nth-child(2){left:36%; animation-delay:-3.2s}
.leaves i:nth-child(3){left:52%; animation-delay:-6.1s; background:#c6e39a}
.leaves i:nth-child(4){left:66%; animation-delay:-1.4s}
.leaves i:nth-child(5){left:80%; animation-delay:-8.3s; background:#6f9f4a}
.leaves i:nth-child(6){left:28%; animation-delay:-4.7s}
@keyframes leaf{0%{transform:translate(0,0) rotate(0); opacity:0}8%{opacity:.9}50%{transform:translate(4cqw,48cqh) rotate(200deg)}100%{transform:translate(-3cqw,104cqh) rotate(400deg); opacity:.7}}

/* ================= AN EVENT SCENE ================= */
.event__box{container-type:size; transform-origin:50% 50%; backface-visibility:hidden; will-change:transform}
.is-zoomin .event{transition:opacity .8s ease .55s}
.is-zoomin .event__box{animation:sceneIn var(--zoom) var(--ease) both}
@keyframes sceneIn{from{transform:translateX(-50%) scale(1.12)}to{transform:translateX(-50%) scale(1)}}
/* closing a scene is the exact reverse of opening it: the scene fades OUT (revealing the garden
   zooming back out so the frame shrinks into place), mirroring the fade-IN over the zoom-in */
.is-zoomout .event{opacity:0; transition:opacity .8s ease}
.is-zoomout .event__box{animation:sceneOut var(--zoom) var(--ease) both}
@keyframes sceneOut{from{transform:translateX(-50%) scale(1)}to{transform:translateX(-50%) scale(1.12)}}

/* the paper card with title / date / time */
.ecard{position:absolute; left:50%; top:2.5%; width:58cqw; z-index:3; opacity:0; transform:translate(-50%,-6%);
  transition:opacity .7s ease, transform .9s cubic-bezier(.2,.7,.2,1)}
.is-scene .ecard.is-in{opacity:1; transform:translate(-50%,0)}
/* drop the card to the bottom (above the nav) for scenes where the couple's faces sit high */
.ecard--bottom{top:auto; bottom:11%; transform:translate(-50%,6%)}
.ecard__img{width:100%; height:auto; display:block; filter:drop-shadow(0 1cqw 2cqw rgba(30,25,20,.3))}
.ecard__paper{position:relative; padding:3cqw 5.5cqw 4cqw; text-align:center; color:var(--ink); background:rgba(252,249,244,.94);
  -webkit-mask:linear-gradient(#000,#000) 0 0/100% calc(100% - 3.2cqw) no-repeat,
               radial-gradient(circle at 50% 0, #000 1.55cqw, transparent 1.7cqw) 0 100%/5cqw 3.2cqw repeat-x,
               radial-gradient(circle at 50% 0, #000 1.1cqw, transparent 1.25cqw) 2.5cqw 100%/5cqw 2.4cqw repeat-x,
               radial-gradient(circle at 50% 0, #000 .8cqw, transparent .95cqw) 1.2cqw 100%/3.4cqw 3.2cqw repeat-x;
          mask:linear-gradient(#000,#000) 0 0/100% calc(100% - 3.2cqw) no-repeat,
               radial-gradient(circle at 50% 0, #000 1.55cqw, transparent 1.7cqw) 0 100%/5cqw 3.2cqw repeat-x,
               radial-gradient(circle at 50% 0, #000 1.1cqw, transparent 1.25cqw) 2.5cqw 100%/5cqw 2.4cqw repeat-x,
               radial-gradient(circle at 50% 0, #000 .8cqw, transparent .95cqw) 1.2cqw 100%/3.4cqw 3.2cqw repeat-x;
  filter:drop-shadow(0 1.2cqw 2.4cqw rgba(30,30,40,.28))}
.ecard__paper::after{content:""; position:absolute; inset:0; filter:url(#grain); background:#fff; mix-blend-mode:multiply; opacity:.7; pointer-events:none}
.ecard__paper > *{position:relative; z-index:1}
.ecard__title{font-family:var(--script); font-weight:400; font-size:7.8cqw; line-height:1; color:var(--ec); margin-bottom:.4cqw}
.ecard__date{font-family:var(--serif); font-weight:500; font-size:6.6cqw; line-height:.9; color:var(--ec); letter-spacing:-.01em}
.ecard__date sup{font-size:.38em; vertical-align:top; position:relative; top:.5em; margin-left:.1em; letter-spacing:.02em}
.ecard__month{font-family:var(--sans); font-weight:400; font-size:2.6cqw; letter-spacing:.32em; text-transform:uppercase; color:var(--ink); margin-top:.3cqw}
.ecard__orn{width:11cqw; height:auto; margin:.7cqw auto .6cqw; color:var(--ec); opacity:.8; display:block}
.ecard__time{font-family:var(--sans); font-weight:400; font-size:2.9cqw; letter-spacing:.26em; color:var(--ink)}
.ecard__venue,.ecard__attire{font-family:var(--sans); font-weight:300; font-size:2.5cqw; letter-spacing:.2em; text-transform:uppercase; color:var(--ink-2); margin-top:.9cqw}
.ecard__venue:empty,.ecard__attire:empty,.ecard__tag:empty{display:none}
.ecard__tag{font-family:var(--serif); font-style:italic; font-size:3cqw; color:var(--ink-2); margin-top:.7cqw}

/* ambient effects over a scene */
.fx{position:absolute; inset:0; pointer-events:none; overflow:clip}
.fx i{position:absolute; display:block}
.fx--petals i,.fx--confetti i{top:-4%; width:1.6cqw; height:1.1cqw; border-radius:70% 20% 70% 20%; background:var(--petal,#f3a6b8); opacity:0; animation:petal var(--d,9s) linear var(--delay,0s) infinite}
.fx--confetti i{border-radius:20%; width:1.1cqw; height:1.1cqw}
@keyframes petal{0%{transform:translate(0,0) rotate(0deg); opacity:0}6%{opacity:.95}50%{transform:translate(var(--sx,4cqw),50cqh) rotate(220deg)}100%{transform:translate(calc(var(--sx,4cqw) * -1),106cqh) rotate(420deg); opacity:.75}}
.fx--glow::before{content:""; position:absolute; left:0; right:0; bottom:0; height:46%; background:radial-gradient(ellipse at 50% 100%, rgba(255,200,120,.32), rgba(255,200,120,0) 68%); animation:breathe 3.6s ease-in-out infinite alternate}
@keyframes breathe{from{opacity:.75}to{opacity:1}}
.fx--sparkle i{width:.9cqw; height:.9cqw; border-radius:50%; background:#fff6cf; box-shadow:0 0 .9cqw .3cqw rgba(255,235,170,.9); opacity:0; animation:twinkle var(--d,3s) ease-in-out var(--delay,0s) infinite}
@keyframes twinkle{0%,100%{opacity:0; transform:scale(.5)}50%{opacity:.95; transform:scale(1.1)}}
.fx--sun::before{content:""; position:absolute; inset:0; background:radial-gradient(ellipse at 30% 12%, rgba(255,236,190,.4), rgba(255,236,190,0) 55%); animation:breathe 5s ease-in-out infinite alternate}

/* ================= THE GALLERY ================= */
.gallery__box{container-type:size}
.gallery__inner{position:absolute; inset:0; overflow:auto; overscroll-behavior:contain; scrollbar-width:none; padding:16cqw 6cqw 10cqw; display:flex; flex-direction:column; align-items:center; gap:4cqw}
.gallery__inner::-webkit-scrollbar{display:none}
.gallery__head{text-align:center; color:#fff; text-shadow:0 1px 10px rgba(40,30,10,.55); opacity:0; transform:translateY(-10px); transition:opacity .8s ease .3s, transform .8s ease .3s}
.gallery__eyebrow{font-family:var(--sans); font-weight:300; font-size:3cqw; letter-spacing:.28em; text-transform:uppercase; opacity:.9}
.gallery__title{font-family:var(--script); font-weight:400; font-size:15cqw; line-height:1; margin-top:1cqw}
.is-gallery .gallery__head{opacity:1; transform:none}

.photos{display:grid; grid-template-columns:repeat(3, 1fr); gap:4cqw 3.4cqw; width:100%; max-width:88cqw}
.photo{position:relative; aspect-ratio:.86; background:#fff; padding:2.2cqw 2.2cqw 6.5cqw; box-shadow:0 1.2cqw 2.6cqw rgba(40,30,10,.35); cursor:pointer; border:0; text-align:left;
  transform:rotate(var(--r,0deg)) translateY(10px); opacity:0; transition:opacity .7s ease var(--dl,0s), transform .7s cubic-bezier(.2,.7,.2,1) var(--dl,0s)}
.is-gallery .photo{opacity:1; transform:rotate(var(--r,0deg)) translateY(0)}
.photo:nth-child(3n+1){--r:-2.4deg} .photo:nth-child(3n+2){--r:1.6deg} .photo:nth-child(3n){--r:-1.1deg}
.photo:nth-child(2){--dl:.1s} .photo:nth-child(3){--dl:.2s} .photo:nth-child(4){--dl:.3s} .photo:nth-child(5){--dl:.4s} .photo:nth-child(6){--dl:.5s} .photo:nth-child(n+7){--dl:.6s}
.photo::before{content:""; position:absolute; left:50%; top:-1.6cqw; width:3.4cqw; height:2.6cqw; transform:translateX(-50%); background:linear-gradient(#d9b98a,#b48b58); border-radius:2px; box-shadow:0 1px 2px rgba(0,0,0,.3)}
.photo__img{position:absolute; inset:2.2cqw 2.2cqw 6.5cqw; width:auto; height:auto; object-fit:cover; background:#e9e2d2}
.photo__ph{position:absolute; inset:2.2cqw 2.2cqw 6.5cqw; display:grid; place-items:center; background:linear-gradient(160deg,#f6ecdc,#e3d2b5); color:#a88c5e}
.photo__ph svg{width:34%; height:auto; opacity:.7}
.photo__cap{position:absolute; left:0; right:0; bottom:1.4cqw; text-align:center; font-family:var(--script); font-size:3.6cqw; color:#7a6a55; line-height:1}
@media (hover:hover){ .photo:hover{transform:rotate(0) translateY(-4px) scale(1.03); z-index:2} }
.gallery__end{text-align:center; color:#fff; text-shadow:0 1px 10px rgba(40,30,10,.6); margin-top:2cqw; opacity:0; transition:opacity .8s ease .8s}
.is-gallery .gallery__end{opacity:1}
.gallery__names{font-family:var(--script); font-size:11cqw; line-height:1}
.gallery__names span{font-size:.7em; opacity:.85}
.gallery__dates{font-family:var(--sans); font-size:3.1cqw; letter-spacing:.3em; margin-top:1.4cqw}
.gallery__note{font-family:var(--serif); font-style:italic; font-size:3.9cqw; margin-top:1.6cqw; opacity:.95}
.gallery__btn{display:inline-block; margin-top:3.2cqw; padding:2.2cqw 5cqw; border-radius:999px; font-family:var(--sans); font-size:2.9cqw; letter-spacing:.24em; text-transform:uppercase; color:#fff; text-decoration:none; text-shadow:none;
  background:rgba(142,74,92,.85); box-shadow:0 .8cqw 2cqw rgba(60,20,30,.35); backdrop-filter:blur(4px)}
.gallery__btn:hover{background:rgba(142,74,92,1)}

/* ================= UI ================= */
.hint{position:absolute; left:50%; bottom:max(5%, env(safe-area-inset-bottom, 0px) + 4%); transform:translateX(-50%); z-index:20;
  font-size:.72rem; letter-spacing:.3em; text-transform:uppercase; color:#fff; padding:.7rem 1.2rem; white-space:nowrap;
  border-radius:999px; background:rgba(40,60,80,.35); backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px);
  opacity:0; transition:opacity .6s ease; pointer-events:none; animation:pulse 2.4s ease-in-out infinite}
.is-intro.is-ready .hint,.is-hub.is-ready .hint{opacity:1; pointer-events:auto}
.is-hub .hint{bottom:auto; top:max(4%, env(safe-area-inset-top, 0px) + 3%); animation:none}
@keyframes pulse{0%,100%{transform:translateX(-50%) scale(1)}50%{transform:translateX(-50%) scale(1.05)}}

.nav{position:absolute; left:50%; bottom:max(2.5%, env(safe-area-inset-bottom, 0px) + 2%); transform:translateX(-50%); z-index:20;
  display:flex; align-items:center; gap:.5rem; padding:.35rem; border-radius:999px;
  background:rgba(40,60,80,.32); backdrop-filter:blur(8px); -webkit-backdrop-filter:blur(8px);
  opacity:0; pointer-events:none; transition:opacity .5s ease}
.is-hub .nav,.is-scene .nav,.is-gallery .nav{opacity:1; pointer-events:auto}
.nav__btn{width:2.5rem; height:2.5rem; border-radius:50%; color:#fff; display:grid; place-items:center; transition:background .25s ease}
.nav__btn svg{width:1.25rem; height:1.25rem}
.nav__btn:hover{background:rgba(255,255,255,.18)}
.nav__btn--tree{background:rgba(255,255,255,.14)}
.nav__btn--tree svg{width:1.3rem; height:1.3rem}
.nav__dots{position:absolute; left:50%; top:100%; transform:translateX(-50%); margin-top:.3rem; display:flex; gap:.15rem}
.nav__dot{width:1.05rem; height:1.05rem; display:grid; place-items:center; -webkit-tap-highlight-color:transparent}
.nav__dot::before{content:""; width:.34rem; height:.34rem; border-radius:50%; background:rgba(255,255,255,.5); transition:all .3s ease}
.nav__dot.is-on::before{background:#fff; width:.9rem; border-radius:.2rem}
.nav__dot.is-gal::before{background:rgba(255,220,160,.6)}
.nav__dot.is-gal.is-on::before{background:#ffd79a}
@media (hover:hover){ .nav__dot:hover::before{background:#fff; transform:scale(1.15)} }

.replay{position:absolute; right:3%; bottom:max(2.5%, env(safe-area-inset-bottom, 0px) + 2%); width:2.4rem; height:2.4rem; border-radius:50%; z-index:20;
  background:rgba(40,60,80,.35); color:#fff; backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px);
  display:grid; place-items:center; opacity:0; transition:opacity .5s ease; pointer-events:none}
.replay svg{width:1.1rem; height:1.1rem}
.is-card .replay,.is-gallery .replay{opacity:.85; pointer-events:auto}

/* background-music toggle (top-right, mirrors the replay button) */
.music{position:absolute; right:3%; top:max(3%, env(safe-area-inset-top, 0px) + 2%); width:2.4rem; height:2.4rem; border-radius:50%; z-index:30;
  background:rgba(40,60,80,.35); color:#fff; backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px);
  display:grid; place-items:center; opacity:0; transition:opacity .5s ease, transform .25s ease; pointer-events:none}
.stage.is-ready .music{opacity:.85; pointer-events:auto}
.music:hover{transform:scale(1.06)}
.music svg{width:1.2rem; height:1.2rem}
.music__off{display:none}
.music.is-muted .music__on{display:none}
.music.is-muted .music__off{display:block}

/* lightbox */
.lightbox{position:absolute; inset:0; z-index:40; background:rgba(20,16,12,.92); display:grid; place-items:center; opacity:0; pointer-events:none; transition:opacity .35s ease}
.lightbox.is-open{opacity:1; pointer-events:auto}
.lightbox__img{max-width:92%; max-height:84%; object-fit:contain; box-shadow:0 20px 60px rgba(0,0,0,.6); border:6px solid #fff}
.lightbox__cap{position:absolute; left:0; right:0; bottom:max(5%, env(safe-area-inset-bottom, 0px) + 4%); text-align:center; color:#fff; font-family:var(--script); font-size:1.6rem}
.lightbox__close{position:absolute; top:max(3%, env(safe-area-inset-top, 0px) + 2%); right:4%; width:2.4rem; height:2.4rem; border-radius:50%; background:rgba(255,255,255,.15); color:#fff; font-size:1.5rem; line-height:1}

/* phone held sideways: the composition is portrait only */
.rotate{position:fixed; inset:0; z-index:50; display:none; place-items:center; text-align:center; color:#fff;
  background:#86b6df url(../img/intro/sky.webp) center/cover no-repeat; font-size:.8rem; letter-spacing:.2em; text-transform:uppercase}
.rotate svg{width:3.2rem; height:3.2rem; margin:0 auto .9rem; animation:tilt 2.4s ease-in-out infinite; display:block}
.rotate p{text-shadow:0 1px 8px rgba(20,40,70,.5)}
@keyframes tilt{0%,100%{transform:rotate(0)}50%{transform:rotate(-90deg)}}
@media (orientation:landscape) and (max-height:520px) and (pointer:coarse){ .rotate{display:grid} .stage{visibility:hidden} }

/* debug / verification hook: ?state=card&t=3000 pins a state with no transitions */
.no-anim, .no-anim *{transition:none !important}

@media (prefers-reduced-motion:reduce){
  .cloud,.flock,.bird,.car,.env,.hint,.backdrop__cloud,.frame__swing,.leaves i,.fx i,.fx::before{animation:none !important}
  .card,.env,.env-wrap,.scenery,.sky,.clouds,.ext,.garden__box,.event__box{transition:none !important; animation:none !important}
}
