/* =====================================================================
   Invitation engine v1 — shared by every invitation. No client details here.
   ===================================================================== */
@font-face{font-family:"Cormorant Garamond";font-style:italic;font-weight:500;font-display:swap;src:url(fonts/cormorant-garamond-latin-500-italic.woff2) format("woff2")}
@font-face{font-family:"Cormorant Garamond";font-style:normal;font-weight:600;font-display:swap;src:url(fonts/cormorant-garamond-latin-600-normal.woff2) format("woff2")}
@font-face{font-family:"Cormorant Garamond";font-style:italic;font-weight:600;font-display:swap;src:url(fonts/cormorant-garamond-latin-600-italic.woff2) format("woff2")}
@font-face{font-family:"Cormorant Garamond";font-style:normal;font-weight:700;font-display:swap;src:url(fonts/cormorant-garamond-latin-700-normal.woff2) format("woff2")}
@font-face{font-family:"Pinyon Script";font-style:normal;font-weight:400;font-display:swap;src:url(fonts/pinyon-script-latin-400-normal.woff2) format("woff2")}
@font-face{font-family:"Marcellus";font-style:normal;font-weight:400;font-display:swap;src:url(fonts/marcellus-latin-400-normal.woff2) format("woff2")}

:root{
  --ink:#8a1a3b; --gold:#c6952c; --page:#f4dfcc;
  --ease:cubic-bezier(.22,1,.36,1);
  --stageW:min(100vw, 560px);
  --serif:"Cormorant Garamond",Georgia,"Times New Roman",serif;
  --script:"Pinyon Script","Snell Roundhand","Apple Chancery",cursive;
  --caps:"Marcellus","Cormorant Garamond",Georgia,serif;
  --sans:system-ui,-apple-system,"Segoe UI",Roboto,"Noto Sans","Noto Sans Kannada","Noto Sans Devanagari","Noto Sans Telugu","Noto Sans Tamil",sans-serif;
}
*{box-sizing:border-box;margin:0;padding:0}
html{-webkit-text-size-adjust:100%}
body{font-family:var(--serif);color:var(--ink);background:var(--page);overflow-x:hidden;min-height:100vh;min-height:100dvh}
body.locked{overflow:hidden;height:100vh;height:100dvh}
img{display:block;-webkit-user-drag:none;user-select:none}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
.sr{position:absolute;width:1px;height:1px;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}

/* plain invitation: what a guest gets if scripts are blocked or fail. The engine hides it once the artwork is up. */
.plain{position:relative;z-index:2;max-width:30rem;margin:0 auto;padding:12vh 1.5rem 4rem;text-align:center;font-size:1.25rem;line-height:1.45}
.plain h1{font-family:var(--script);font-weight:400;font-size:3rem;line-height:1.1;margin:.4em 0}
.plain p{margin:.7em 0}
.plain .k{font-family:var(--caps);font-size:.8rem;letter-spacing:.3em;text-transform:uppercase;color:#8a6a24}
.plain a{display:inline-block;margin:.4em .3em;padding:.6em 1.4em;border-radius:999px;background:var(--ink);color:#fff8ee;text-decoration:none;font-weight:600}

/* ambient page colour, so any side margin on a wide screen matches the artwork */
.ambient{position:fixed;inset:0;z-index:0;pointer-events:none;
  background:radial-gradient(90% 60% at 50% 20%,rgba(255,250,242,.7),transparent 70%),linear-gradient(180deg,#fbeee0 0%,#f5ddc9 50%,#f7e2cf 100%)}
.invite{position:relative;z-index:1}
.world{position:relative;width:var(--stageW);margin:0 auto}
@media (min-width:561px){.world{box-shadow:0 0 90px rgba(120,70,40,.22)}}

/* ---------- sections: one plate each, width 100%, natural height ---------- */
.sec{position:relative;width:100%;isolation:isolate;aspect-ratio:var(--w)/var(--h);
  /* overlap the previous section by --lap % of this plate's height; the join is cross-faded by the top mask below */
  margin-top:calc(var(--lap,0) * var(--h) / var(--w) * -1%)}
.sec:first-child{margin-top:0}
.sec.cropped{overflow-x:clip}
/* the canvas is the plate's own pixel space; a cropped section shows a window of it */
.cv{position:absolute;top:0;height:100%;left:var(--cvx,0%);width:var(--cvw,100%);container-type:inline-size}
.sec .ref{position:absolute;inset:0;width:100%;height:100%;z-index:1}
.sec + .sec .ref{
  -webkit-mask-image:linear-gradient(180deg,transparent 0,#000 var(--fade,5%));
          mask-image:linear-gradient(180deg,transparent 0,#000 var(--fade,5%))}

/* anything placed in plate pixels: --x --y --bw (--bh) against --W --H */
.ov,.hit,.tblock,.slot,.envcut{position:absolute;left:calc(var(--x)/var(--W)*100%);top:calc(var(--y)/var(--H)*100%);width:calc(var(--bw)/var(--W)*100%)}
.hit,.tblock,.slot,.envcut{height:calc(var(--bh)/var(--H)*100%)}

.ov{z-index:5;pointer-events:none;overflow:visible}
.ov img{width:100%;height:auto;object-fit:contain}
.sway{transform-origin:50% 0;animation:sway var(--t,6s) ease-in-out infinite;animation-delay:var(--d,0s)}
@keyframes sway{0%,100%{transform:rotate(-2.4deg)}50%{transform:rotate(2.4deg)}}
.sway.lantern{animation-name:swayl}
/* small lights that come and go · cloth that lifts in a breeze */
.twinkle{animation:twinkle var(--t,3.2s) ease-in-out infinite;animation-delay:var(--d,0s)}
@keyframes twinkle{0%,100%{opacity:.15;transform:scale(.7)}50%{opacity:1;transform:scale(1)}}
.waft{transform-origin:0 0;animation:waft var(--t,9s) ease-in-out infinite;animation-delay:var(--d,0s)}
@keyframes waft{0%,100%{transform:rotate(-1.2deg) translateY(0)}50%{transform:rotate(1.4deg) translateY(1.5%)}}
@keyframes swayl{0%,100%{transform:rotate(-1.6deg)}50%{transform:rotate(1.6deg)}}
.lantern-light{position:absolute;left:50%;top:44%;width:150%;aspect-ratio:1;transform:translate(-50%,-50%);border-radius:50%;pointer-events:none;
  background:radial-gradient(circle,rgba(255,214,140,.45) 0,rgba(255,190,110,.18) 35%,rgba(255,180,100,0) 70%);
  animation:breath var(--t,4.5s) ease-in-out infinite}
@keyframes breath{0%,100%{opacity:.55}50%{opacity:1}}
/* motion only runs while its section is near the screen */
.sec .sway,.sec .lantern-light,.sec .petal,.sec .twinkle,.sec .waft{animation-play-state:paused}
.sec.vis .sway,.sec.vis .lantern-light,.sec.vis .petal,.sec.vis .twinkle,.sec.vis .waft{animation-play-state:running}
.sec.vis .sway{will-change:transform}

/* sparse petals, confined to a band (never over the wording) */
.petals{position:absolute;left:0;right:0;top:calc(var(--y0)*1%);height:calc((var(--y1) - var(--y0))*1%);overflow:hidden;pointer-events:none;z-index:6;container-type:size}
.petal{position:absolute;top:-8%;left:var(--px);width:calc(var(--s)*1%);aspect-ratio:1/1.3;opacity:0;
  background:radial-gradient(ellipse at 35% 30%,#ffd6de 0,#f28aa3 45%,#c9365f 100%);
  border-radius:60% 40% 60% 40%/50% 60% 40% 50%;
  animation:fall var(--t) linear infinite;animation-delay:var(--d)}
.petal.p2{background:radial-gradient(ellipse at 35% 30%,#f2a1b0 0,#c8365a 50%,#7e1236 100%)}
.petal.p3{background:radial-gradient(ellipse at 35% 30%,#fff2f4 0,#f7c4d0 50%,#e58aa5 100%)}
@keyframes fall{0%{transform:translate3d(0,0,0) rotate(0);opacity:0}8%{opacity:.85}50%{transform:translate3d(var(--dx),55cqh,0) rotate(150deg)}92%{opacity:.7}100%{transform:translate3d(calc(var(--dx)*-.5),112cqh,0) rotate(320deg);opacity:0}}
.petals-fixed{position:fixed;inset:0;z-index:900;pointer-events:none;overflow:hidden;container-type:size;opacity:0;transition:opacity 1.2s ease}
body:not(.locked) .petals-fixed{opacity:1}
.petals-fixed .petal{animation-play-state:running;width:calc(var(--s)*0.55%)}
body.away .petals-fixed .petal{animation-play-state:paused}

/* ---------- reveal: pieces of the finished plate, and the live wording, rise into view ---------- */
.tblock{z-index:3;pointer-events:none;background-repeat:no-repeat}
.tblock,.slot.rise,.ov.rise{opacity:0;transform:translate3d(0,18px,0);transition:opacity 1s var(--ease),transform 1.1s var(--ease);transition-delay:var(--delay,0s)}
.tblock.in,.slot.rise.in,.ov.rise.in{opacity:1;transform:none}
/* a soft glow behind a piece the couple added (an emblem, a deity) */
.ov.halo::before{content:"";position:absolute;left:50%;top:48%;width:170%;aspect-ratio:1;transform:translate(-50%,-50%);border-radius:50%;
  background:radial-gradient(circle,rgba(255,226,160,.5) 0,rgba(255,214,140,.2) 38%,rgba(255,210,130,0) 68%)}
.ov.halo img{position:relative}

/* live wording: real text, set in the plate's pixel space (1cqw = 1% of the plate's width) */
.slot{z-index:4;display:flex;flex-direction:column;justify-content:center;align-items:center;text-align:center;pointer-events:none;
  font-family:var(--serif);color:var(--ink);font-size:calc(var(--fs)/var(--W)*100cqw*var(--fit,1));line-height:var(--lh,1.12);font-kerning:normal;font-variant-numeric:lining-nums}
.slot .ln{display:block;white-space:nowrap}
.slot.left{align-items:flex-start;text-align:left}
.slot.top{justify-content:flex-start}
.slot.script{font-family:var(--script);line-height:1.15;-webkit-text-stroke:.016em currentColor}
.slot.script .ln{padding:0 .12em}
.slot.sans{font-family:var(--sans)}
.slot.caps{font-family:var(--caps);text-transform:uppercase}
.slot.caps .ln{text-indent:.3em}
.slot.flat{text-shadow:0 0 .35em #fff,0 0 .7em rgba(255,255,255,.9)}

/* functional areas drawn exactly over the painted buttons */
.hit{z-index:20;display:block;border-radius:6%;-webkit-tap-highlight-color:transparent;cursor:pointer;outline:none}
.hit.round{border-radius:999px}
.hit.round::after{content:"";position:absolute;inset:-9px -6px}   /* painted buttons are slim: the touch area is taller than the paint */
.hit:focus-visible,.mute:focus-visible,.entrance:focus-visible{outline:3px solid var(--ink);outline-offset:3px;box-shadow:0 0 0 6px rgba(255,255,255,.9)}
.entrance:focus-visible{outline-offset:-6px}

/* tiny mute toggle; the ring is small but the touch area is a full 44px */
.mute{position:fixed;right:max(7px,calc(env(safe-area-inset-right) + 5px));bottom:max(7px,calc(env(safe-area-inset-bottom) + 5px));z-index:1500;
  width:44px;height:44px;border-radius:50%;display:flex;align-items:center;justify-content:center;-webkit-tap-highlight-color:transparent;opacity:.88;transition:opacity .2s}
.mute::before{content:"";position:absolute;inset:5px;border-radius:50%;background:rgba(255,248,238,.86);border:1px solid rgba(198,149,44,.7);box-shadow:0 2px 8px rgba(110,60,40,.18)}
.mute:hover{opacity:1}
.mute[hidden]{display:none}
.mute svg{position:relative;width:17px;height:17px;fill:var(--ink);stroke:var(--ink);stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}
.mute svg .w{fill:none}
.mute svg.off{display:none}
.mute.is-muted svg.on{display:none}
.mute.is-muted svg.off{display:block}

.toast{position:fixed;left:50%;bottom:max(24px,calc(env(safe-area-inset-bottom) + 18px));transform:translate(-50%,16px);z-index:2000;max-width:calc(100vw - 32px);
  background:linear-gradient(180deg,#9c1d44,#7a1233);color:#fff8ee;border:1px solid #e2c06a;border-radius:999px;padding:.55em 1.3em;
  font-size:15px;font-weight:600;letter-spacing:.02em;opacity:0;pointer-events:none;transition:opacity .3s,transform .3s var(--ease);box-shadow:0 8px 22px rgba(110,20,50,.3)}
.toast.on{opacity:1;transform:translate(-50%,0)}

/* ---------- envelope: closed artwork + the open artwork's card ---------- */
.copy{position:absolute;inset:0;background-size:100% 100%;pointer-events:none}
.envcut{background-size:100% 100%;pointer-events:none}
.env .pocket{position:absolute;left:0;right:0;top:var(--pocketTop);height:var(--pocket0);overflow:hidden;z-index:4;pointer-events:none;
  transition:height 1.1s cubic-bezier(.4,0,.2,1) .35s}
.env.open .pocket{height:var(--pocket1)}
/* the card keeps the section's size inside the pocket; its offsets are % of its own height */
.env .pocket .cardwrap{position:absolute;left:0;top:0;width:100%;aspect-ratio:var(--W)/var(--H);
  transform:translateY(calc(var(--cardStart) - var(--pocketTop)));
  transition:transform 1.25s cubic-bezier(.3,.5,.2,1) .5s}
.env.open .pocket .cardwrap{transform:translateY(calc(-1 * var(--pocketTop)))}
.env .envmove{position:absolute;inset:0;z-index:5;pointer-events:none;transition:transform 1.1s cubic-bezier(.4,0,.2,1) .35s}
.env.open .envmove{transform:translateY(var(--glide))}
.env .seal{transform-origin:var(--sealX) var(--sealY);transition:transform .22s cubic-bezier(.3,1.5,.5,1)}
.env .seal.press{transform:scale(.93)}
.env .seal.release{transform:scale(1.04)}
.env .cardbtn{z-index:6;opacity:0;transform:translateY(calc(var(--btnShift) - 1.2%));transition:opacity .5s ease 1.55s,transform .6s var(--ease) 1.55s}
.env.open .cardbtn{opacity:1;transform:translateY(var(--btnShift))}
.env.open .hit.env-hit{display:none}
.env .hit.date-btn{display:none}
.env.open .hit.date-btn{display:block}
.env.open .tblock{opacity:0;transition:opacity .35s ease .2s}

/* ---------- entrance (door) ---------- */
.entrance{position:fixed;inset:0;z-index:1000;overflow:hidden;background:var(--theme,#f3dcc8);display:flex;align-items:center;justify-content:center;cursor:pointer;
  -webkit-tap-highlight-color:transparent;opacity:0;transition:opacity .7s ease}
.entrance.ready{opacity:1}
.entrance.gone{display:none}
.door-stage{position:absolute;left:50%;top:50%;width:var(--dw);height:var(--dh);transform:translate(-50%,-50%) scale(var(--cam,1));
  transition:transform 2.7s cubic-bezier(.4,0,.2,1);will-change:transform}
.door-base{position:absolute;inset:0;width:100%;height:100%}
.pendant{position:absolute;z-index:3;left:calc(var(--px)/var(--W)*100%);top:calc(var(--py)/var(--H)*100%);width:calc(var(--pw)/var(--W)*100%);height:auto}
.doorway{position:absolute;left:calc(var(--dx)/var(--W)*100%);top:calc(var(--dy)/var(--H)*100%);width:calc(var(--dwid)/var(--W)*100%);height:calc(var(--dhei)/var(--H)*100%);
  z-index:2;perspective:1300px;perspective-origin:50% 45%}
.light{position:absolute;left:-0.5%;right:-0.5%;top:-0.3%;bottom:-1%;overflow:hidden;
  background:radial-gradient(60% 45% at 50% 55%,#fffdf6 0,#fff4e2 40%,#f7dfc4 100%);opacity:0;transition:opacity .9s ease}
.light::after{content:"";position:absolute;inset:-30%;background:radial-gradient(circle at 50% 55%,rgba(255,255,255,1) 0,rgba(255,250,235,.8) 25%,rgba(255,240,215,0) 60%);
  transform:scale(.4);opacity:0;transition:transform 2.2s cubic-bezier(.3,0,.2,1),opacity 1.6s ease}
.doors{position:absolute;inset:0;transform-style:preserve-3d}
.leaf{position:absolute;top:0;height:100%;width:50%;transform-style:preserve-3d;transition:transform 2.1s cubic-bezier(.55,.05,.35,1) .12s;will-change:transform}
.leaf img{width:100%;height:100%;object-fit:fill}
.leaf::after{content:"";position:absolute;inset:0;background:linear-gradient(90deg,rgba(0,0,0,0),rgba(0,0,0,.28));opacity:0;transition:opacity 1.6s ease}
.leaf.l{left:0;transform-origin:0 50%}
.leaf.r{right:0;transform-origin:100% 50%}
.leaf.r::after{background:linear-gradient(270deg,rgba(0,0,0,0),rgba(0,0,0,.35))}
.seam-flash{position:absolute;z-index:4;left:calc(var(--dx)/var(--W)*100% + var(--dwid)/var(--W)*50% - 1.5%);top:calc(var(--dy)/var(--H)*100%);width:3%;height:calc(var(--dhei)/var(--H)*100%);
  background:radial-gradient(50% 50% at 50% 50%,rgba(255,250,230,.95),rgba(255,250,230,0));opacity:0;pointer-events:none}
.entrance.opening .seam-flash{animation:seam .5s ease-out 1}
@keyframes seam{0%{opacity:0}30%{opacity:1}100%{opacity:0}}
/* the free edges recede: the doors swing inward, away from the guest */
.entrance.opening .leaf.l{transform:rotateY(96deg)}
.entrance.opening .leaf.r{transform:rotateY(-96deg)}
.entrance.opening .leaf::after{opacity:1}
.entrance.opening .light{opacity:1;transition-delay:.1s}
.entrance.opening .light::after{transform:scale(1.9);opacity:1}
.entrance.opening .tap-hint{opacity:0}
.entrance.opening .door-stage{--cam:1.12}
.veil{position:fixed;inset:0;z-index:1100;pointer-events:none;opacity:0;background:radial-gradient(70% 60% at 50% 50%,#fffdf8 0,#fff7ea 45%,#fbeed9 100%);transition:opacity .9s ease}
.veil.on{opacity:1;transition:opacity 1.1s ease .9s}
.veil.off{opacity:0;transition:opacity 1.3s ease}
.tap-hint{position:absolute;left:0;right:0;bottom:max(4.5vh,calc(env(safe-area-inset-bottom) + 3vh));z-index:1010;display:flex;flex-direction:column;align-items:center;gap:10px;pointer-events:none;transition:opacity .4s}
.tap-text{font-family:var(--caps);text-transform:uppercase;font-size:clamp(12px,3.4vw,15px);letter-spacing:.34em;text-indent:.34em;color:#5c4318;text-shadow:0 0 10px rgba(255,255,255,.95),0 0 22px rgba(255,255,255,.8);animation:hint 2.6s ease-in-out infinite}
.tap-ring{width:14px;height:14px;border-radius:50%;border:1.5px solid #a8843a;position:relative}
.tap-ring::after{content:"";position:absolute;inset:-6px;border-radius:50%;border:1px solid rgba(168,132,58,.85);animation:tring 2.6s ease-out infinite}
@keyframes hint{0%,100%{opacity:.75}50%{opacity:1}}
@keyframes tring{0%{transform:scale(.6);opacity:1}100%{transform:scale(2.2);opacity:0}}

/* ---------- entrance (envelope) ---------- */
.env-entrance{flex-direction:column;gap:clamp(18px,4.5vh,44px);
  background:radial-gradient(80% 55% at 50% 45%,#fffaf5 0,rgba(255,250,245,0) 70%),var(--theme,#fbeae3)}
.ecorner{position:absolute;width:min(calc(var(--cw)*1vw),calc(var(--cw)*.62vh));height:auto;pointer-events:none}
.ecorner.tl{left:-2%;top:-1.5%}
.ecorner.tr{right:-2%;top:-1.5%}
.ecorner.bl{left:-2%;bottom:-1.5%}
.ecorner.br{right:-2%;bottom:-1.5%}
.ehead{position:relative;font-family:var(--caps);text-transform:uppercase;font-size:clamp(13px,3.6vw,17px);letter-spacing:.34em;text-indent:.34em;color:var(--gold);transition:opacity .5s ease}
.envl{position:relative;width:min(74vw,38vh,400px);aspect-ratio:var(--ar);filter:drop-shadow(0 18px 22px rgba(92,22,40,.28));
  transition:transform 2.6s cubic-bezier(.3,0,.2,1);animation:envfloat 5s ease-in-out infinite}
@keyframes envfloat{0%,100%{translate:0 0}50%{translate:0 -1.2%}}
.envl img{position:absolute;left:0;width:100%;height:auto}
.eback,.efront{top:0;opacity:0;transition:opacity .45s ease .22s}
.eclosed{bottom:0;transition:opacity .45s ease .22s,transform .2s cubic-bezier(.3,1.5,.5,1)}
.efront{z-index:3}
.eclosed{z-index:4}
/* the card lives in a window that ends at the envelope's lower edge, so it is never seen below it */
.ecardwrap{position:absolute;left:0;right:0;top:-70%;bottom:1%;overflow:hidden;z-index:2;opacity:0;transition:opacity .3s ease .4s}
.ecard{position:absolute;left:11%;right:11%;top:68%;aspect-ratio:1/1.12;border-radius:2.5%;container-type:inline-size;
  display:flex;flex-direction:column;align-items:center;justify-content:flex-start;padding-top:13cqw;gap:1.5cqw;text-align:center;color:var(--ink);
  background:linear-gradient(180deg,#fffaf3,#fbeadf);border:1px solid rgba(190,140,60,.55);box-shadow:inset 0 0 0 1.6cqw #fffaf3,inset 0 0 0 1.9cqw rgba(190,140,60,.5);
  transition:transform 1.5s cubic-bezier(.3,.6,.2,1) .62s}
.ecard .k{font-family:var(--caps);text-transform:uppercase;font-size:4.4cqw;letter-spacing:.3em;text-indent:.3em;color:var(--gold);margin-bottom:3cqw}
.ecard .n{font-family:var(--script);font-size:15cqw;line-height:1.05;white-space:nowrap}
.ecard .a{font-family:var(--script);font-size:9cqw;line-height:.9;color:var(--gold)}
.env-entrance.opening .eclosed{opacity:0;transform:scale(.985)}
.env-entrance.opening .eback,.env-entrance.opening .efront,.env-entrance.opening .ecardwrap{opacity:1}
.env-entrance.opening .ecard{transform:translateY(-62%)}
.env-entrance.opening .envl{transform:translateY(9%) scale(1.06);animation:none}
.env-entrance.opening .ehead{opacity:0}
.env-entrance .tap-hint{position:relative;left:auto;right:auto;bottom:auto;flex-direction:column-reverse}

/* ---------- entrance (flaps): the artwork whole, its four flaps drawn apart ---------- */
.flap-entrance{background:var(--theme,#3d0c1a)}
.fsoft{position:absolute;inset:-6%;background-size:cover;background-position:50% 50%;transition:opacity .7s ease .35s}
.fstage{position:relative;aspect-ratio:var(--ar);width:min(100vw,calc(100vh * var(--far)));width:min(100vw,calc(100dvh * var(--far)))}
.flap,.fseal{position:absolute;inset:0;background-size:100% 100%}
/* where the artwork ends short of the screen, it melts into the soft copy behind it */
@media (max-aspect-ratio:57/100){.flap,.fseal{-webkit-mask-image:linear-gradient(180deg,transparent 0,#000 5%,#000 95%,transparent 100%);mask-image:linear-gradient(180deg,transparent 0,#000 5%,#000 95%,transparent 100%)}}
@media (min-aspect-ratio:58/100){.flap,.fseal{-webkit-mask-image:linear-gradient(90deg,transparent 0,#000 5%,#000 95%,transparent 100%);mask-image:linear-gradient(90deg,transparent 0,#000 5%,#000 95%,transparent 100%)}}
.flap{transition:transform 1.9s cubic-bezier(.62,.02,.3,1) .42s,opacity .8s ease 1.5s;will-change:transform}
.fseal{transform-origin:var(--sx) var(--sy);transition:transform .2s cubic-bezier(.3,1.5,.5,1);animation:sealbreath 3.2s ease-in-out infinite}
@keyframes sealbreath{0%,100%{filter:brightness(1)}50%{filter:brightness(1.09)}}
.fring{position:absolute;left:var(--sx);top:var(--sy);width:34%;aspect-ratio:1;border-radius:50%;border:1.5px solid rgba(255,226,170,.75);transform:translate(-50%,-50%) scale(.85);opacity:0;pointer-events:none;animation:fring 3.2s ease-out infinite}
@keyframes fring{0%{opacity:.8;transform:translate(-50%,-50%) scale(.85)}70%,100%{opacity:0;transform:translate(-50%,-50%) scale(1.3)}}
.flap-entrance .tap-text{color:#fbe9c6;text-shadow:0 1px 3px rgba(30,0,8,.9),0 0 14px rgba(30,0,8,.8)}
.flap-entrance.opening{background:transparent;pointer-events:none}
.flap-entrance.opening .fsoft{opacity:0}
.flap-entrance.opening .fseal{animation:sealgo .42s ease-in forwards}
@keyframes sealgo{0%{transform:scale(1)}40%{transform:scale(.93)}75%{transform:scale(1.04);opacity:1}100%{transform:scale(1.04);opacity:0}}
.flap-entrance.opening .fring{animation:none;opacity:0}
.flap-entrance.opening .flap.top{transform:translateY(-104%)}
.flap-entrance.opening .flap.bottom{transform:translateY(104%)}
.flap-entrance.opening .flap.left{transform:translateX(-104%)}
.flap-entrance.opening .flap.right{transform:translateX(104%)}
.flap-entrance.opening .flap{opacity:0}
body.parting .veil{display:none}

/* ---------- a cover the guest wipes away ---------- */
.scratch{position:absolute;left:calc(var(--x)/var(--W)*100%);top:calc(var(--y)/var(--H)*100%);width:calc(var(--bw)/var(--W)*100%);height:calc(var(--bh)/var(--H)*100%);
  z-index:25;touch-action:pan-y;cursor:pointer;-webkit-tap-highlight-color:transparent;transition:opacity .8s ease,transform .8s ease;outline:none}
.scratch.gone{opacity:0;transform:scale(1.02);pointer-events:none}
.scratch:focus-visible{outline:2px solid rgba(255,226,170,.9);outline-offset:-4px}
/* what lies under the cover stays out of reach, and unread, until it is revealed */
.sec.covered .slot,.sec.covered .hit{visibility:hidden}

/* ---------- reduced motion ---------- */
@media (prefers-reduced-motion:reduce){
  .sway,.lantern-light,.petal,.tap-text,.tap-ring::after,.twinkle,.waft,.envl,.fseal,.fring{animation:none!important}
  .flap{transition-duration:1s}
  .tblock,.slot.rise,.ov.rise{opacity:1;transform:none;transition:none}
  .petals-fixed{display:none}
  .lantern-light{opacity:.7}
  .leaf{transition-duration:1.2s}.door-stage{transition-duration:1.4s}
}
