/* =====================================================================
   ANIMASI PEMBUKA
   ---------------------------------------------------------------------
   Semua memakai kelas .opener pada tombolnya. Saat dibuka, JS
   menambahkan kelas .is-open (dan .is-armed / .is-blown untuk gaya
   yang butuh tahapan).
   ===================================================================== */

.opener-stage{
  margin:34px auto 30px;
  width:min(300px,74vw);
  perspective:1200px;
}
.opener{
  position:relative;width:100%;
  border:0;padding:0;background:none;cursor:pointer;
  transform-style:preserve-3d;
  transition:transform .45s cubic-bezier(.2,.8,.25,1),filter .4s;
}
.opener:hover{transform:translateY(-6px) scale(1.02)}
.opener:focus-visible{outline:3px solid var(--accent);outline-offset:10px;border-radius:14px}
.opener:disabled{cursor:default}
.opener.is-locked{filter:grayscale(.3) brightness(.97);opacity:.9}
.opener.is-locked:hover{transform:none}

.op-lock{
  position:absolute;left:50%;top:50%;translate:-50% -50%;z-index:20;
  width:52px;height:52px;border-radius:50%;
  display:grid;place-items:center;font-size:1.35rem;
  background:color-mix(in srgb,var(--card) 88%,transparent);
  border:1px solid var(--line);
  box-shadow:var(--shadow-md);
}

/* Petunjuk kecil di bawah objek */
.ck-hint,.bl-hint{
  position:absolute;left:50%;bottom:-30px;translate:-50% 0;
  white-space:nowrap;font-family:var(--sans);font-size:.76rem;font-weight:600;
  color:var(--ink-soft);opacity:.9;transition:opacity .3s;
}
.opener.is-open .ck-hint,
.opener.is-open .bl-hint{opacity:0}

/* =========================================================
   1 · AMPLOP SURAT
   ========================================================= */
.opener[data-opener="envelope"]{aspect-ratio:1.5/1;filter:drop-shadow(0 18px 34px rgba(120,50,75,.26))}
/* Segel lilin sudah berupa cakram 52px di titik yang sama dengan badge
   gembok, dan saat terkunci isinya memang 🔒. Badge-nya dilepas supaya
   tidak ada dua cakram bertumpuk yang menyisakan halo aksen di tepinya. */
.opener[data-opener="envelope"] .op-lock{display:none}

.env-body{
  position:absolute;inset:0;border-radius:12px;
  background:linear-gradient(160deg,#fffaf7,#fdeae2 60%,#f9dcd3);
  border:1px solid rgba(201,106,127,.22);
}
.env-pocket{
  position:absolute;inset:0;border-radius:12px;overflow:hidden;z-index:3;
  background:linear-gradient(160deg,#fdf1ec,#f7ddd4);
  clip-path:polygon(0 22%,50% 62%,100% 22%,100% 100%,0 100%);
  border:1px solid rgba(201,106,127,.16);
}
.env-flap{
  position:absolute;left:0;right:0;top:0;height:62%;z-index:5;
  background:linear-gradient(175deg,#fbe4dc,#f3cdc2);
  clip-path:polygon(0 0,100% 0,50% 100%);
  transform-origin:top center;transform:rotateX(0deg);
  transition:transform .85s cubic-bezier(.6,-.2,.3,1.4),z-index 0s .42s;
  border-top:1px solid rgba(201,106,127,.2);
}
.env-letter{
  position:absolute;left:8%;right:8%;top:12%;z-index:4;
  height:74%;border-radius:8px;background:#fffdfb;
  box-shadow:0 6px 22px rgba(120,50,75,.16);
  display:grid;place-items:center;
  transform:translateY(18%) scale(.96);opacity:0;
  transition:transform .8s cubic-bezier(.2,.9,.2,1) .35s,opacity .5s .35s;
}
.env-letter span{font-family:var(--script);font-size:1.9rem;color:var(--accent)}
.env-seal{
  position:absolute;left:50%;top:52%;z-index:6;translate:-50% -50%;
  width:52px;height:52px;border-radius:50%;
  background:radial-gradient(circle at 35% 30%,color-mix(in srgb,var(--accent) 62%,#fff),var(--accent));
  color:#fff;display:grid;place-items:center;font-size:1.3rem;
  box-shadow:0 6px 16px rgba(150,50,80,.35),inset 0 -3px 8px rgba(0,0,0,.15);
  transition:opacity .35s,transform .5s;
}
.opener[data-opener="envelope"].is-open .env-flap{transform:rotateX(-172deg);z-index:1}
.opener[data-opener="envelope"].is-open .env-seal{opacity:0;transform:scale(.4) rotate(60deg)}
.opener[data-opener="envelope"].is-open .env-letter{transform:translateY(-24%) scale(1);opacity:1}

/* =========================================================
   2 · KOTAK KADO
   ========================================================= */
.opener[data-opener="giftbox"]{aspect-ratio:1/1;filter:drop-shadow(0 20px 32px rgba(120,50,75,.24))}

.gb-glow{
  position:absolute;left:50%;top:42%;translate:-50% -50%;
  width:80%;aspect-ratio:1;border-radius:50%;
  background:radial-gradient(circle,color-mix(in srgb,var(--accent2) 60%,transparent),transparent 65%);
  opacity:0;transition:opacity .6s .25s;
}
.opener[data-opener="giftbox"].is-open .gb-glow{opacity:.85}

.gb-base{
  position:absolute;left:8%;right:8%;bottom:6%;height:52%;z-index:3;
  border-radius:8px 8px 12px 12px;
  background:linear-gradient(165deg,color-mix(in srgb,var(--accent) 72%,#fff) 0%,var(--accent) 55%,color-mix(in srgb,var(--accent) 82%,#000) 100%);
  box-shadow:inset 0 -10px 22px rgba(0,0,0,.16);
  overflow:hidden;
}
.gb-ribbon-v{
  position:absolute;left:50%;top:0;bottom:0;width:17%;translate:-50% 0;
  background:linear-gradient(90deg,color-mix(in srgb,var(--accent2) 70%,#fff),var(--accent2),color-mix(in srgb,var(--accent2) 80%,#000));
}
.gb-content{
  position:absolute;left:50%;top:34%;translate:-50% 0;z-index:2;
  width:44%;aspect-ratio:1;border-radius:14px;
  background:color-mix(in srgb,var(--card) 96%,transparent);
  display:grid;place-items:center;font-size:1.7rem;
  box-shadow:0 8px 20px rgba(0,0,0,.18);
  opacity:0;transition:transform .85s cubic-bezier(.2,.9,.2,1) .28s,opacity .5s .28s;
}
.opener[data-opener="giftbox"].is-open .gb-content{opacity:1;transform:translateY(-56%) scale(1.05)}

.gb-lid{
  position:absolute;left:2%;right:2%;top:26%;height:22%;z-index:6;
  border-radius:8px;
  background:linear-gradient(170deg,color-mix(in srgb,var(--accent) 62%,#fff),var(--accent) 70%);
  box-shadow:0 6px 14px rgba(0,0,0,.18);
  transition:transform .9s cubic-bezier(.4,-.25,.3,1.35),opacity .5s .35s;
}
.gb-lid-ribbon{
  position:absolute;left:50%;top:0;bottom:0;width:15%;translate:-50% 0;
  background:linear-gradient(90deg,color-mix(in srgb,var(--accent2) 70%,#fff),var(--accent2));
}
.gb-bow{position:absolute;left:50%;top:-46%;translate:-50% 0;width:60%;height:52%}
.gb-bow i{position:absolute;top:14%;width:42%;height:78%;background:var(--accent2);box-shadow:inset 0 -3px 8px rgba(0,0,0,.18)}
.gb-bow-l{left:0;border-radius:60% 20% 50% 50% / 70% 40% 60% 55%;transform:rotate(-14deg)}
.gb-bow-r{right:0;border-radius:20% 60% 50% 50% / 40% 70% 55% 60%;transform:rotate(14deg)}
.gb-bow-c{
  left:50%!important;top:34%!important;translate:-50% 0;
  width:24%!important;height:34%!important;border-radius:50%;
  background:color-mix(in srgb,var(--accent2) 80%,#000)!important;
}
.opener[data-opener="giftbox"].is-open .gb-lid{transform:translateY(-135%) rotate(-16deg);opacity:0}

.gb-burst{position:absolute;left:50%;top:38%;translate:-50% -50%;width:0;height:0;z-index:8}
.gb-burst i{
  position:absolute;width:9px;height:14px;border-radius:2px;
  background:var(--accent2);opacity:0;
}
.gb-burst i:nth-child(2n){background:var(--accent)}
.gb-burst i:nth-child(3n){background:#fff;width:7px;height:7px;border-radius:50%}
.opener[data-opener="giftbox"].is-open .gb-burst i{animation:gbFly .95s cubic-bezier(.2,.8,.3,1) .3s both}
.gb-burst i:nth-child(1){--dx:-120px;--dy:-90px}
.gb-burst i:nth-child(2){--dx:-70px;--dy:-140px}
.gb-burst i:nth-child(3){--dx:0px;--dy:-160px}
.gb-burst i:nth-child(4){--dx:70px;--dy:-140px}
.gb-burst i:nth-child(5){--dx:120px;--dy:-90px}
.gb-burst i:nth-child(6){--dx:145px;--dy:-25px}
.gb-burst i:nth-child(7){--dx:-145px;--dy:-25px}
.gb-burst i:nth-child(8){--dx:-95px;--dy:40px}
.gb-burst i:nth-child(9){--dx:95px;--dy:40px}
.gb-burst i:nth-child(10){--dx:10px;--dy:-200px}
@keyframes gbFly{
  0%{opacity:1;transform:translate(0,0) rotate(0) scale(.4)}
  70%{opacity:1}
  100%{opacity:0;transform:translate(var(--dx),var(--dy)) rotate(320deg) scale(1)}
}

/* =========================================================
   3 · KUE + TIUP LILIN
   ========================================================= */
.opener[data-opener="cake"]{aspect-ratio:1.12/1;filter:drop-shadow(0 18px 30px rgba(120,50,75,.22))}

.ck-plate{
  position:absolute;left:2%;right:2%;bottom:3%;height:9%;z-index:1;
  border-radius:50%;
  background:linear-gradient(180deg,#fdfbfa,#e6dcdf);
  box-shadow:0 6px 14px rgba(0,0,0,.14);
}
.ck-tier-2{
  position:absolute;left:11%;right:11%;bottom:9%;height:26%;z-index:3;
  border-radius:8px 8px 14px 14px;
  background:linear-gradient(170deg,color-mix(in srgb,var(--accent) 55%,#fff),color-mix(in srgb,var(--accent) 88%,#000));
  box-shadow:inset 0 -8px 18px rgba(0,0,0,.14);
}
.ck-tier-1{
  position:absolute;left:23%;right:23%;bottom:33%;height:22%;z-index:4;
  border-radius:8px 8px 10px 10px;
  background:linear-gradient(170deg,color-mix(in srgb,var(--accent) 45%,#fff),color-mix(in srgb,var(--accent) 78%,#000));
  box-shadow:inset 0 -6px 14px rgba(0,0,0,.12);
}
.ck-top{
  position:absolute;left:21%;right:21%;bottom:53%;height:8%;z-index:5;
  border-radius:50%;
  background:linear-gradient(180deg,#fffdfc,color-mix(in srgb,var(--accent2) 40%,#fff));
  box-shadow:0 3px 8px rgba(0,0,0,.1);
}
.ck-drip{position:absolute;left:21%;right:21%;bottom:49%;height:9%;z-index:6;display:flex;justify-content:space-between}
.ck-drip i{
  width:9%;border-radius:0 0 60% 60%;
  background:linear-gradient(180deg,#fffdfc,color-mix(in srgb,var(--accent2) 46%,#fff));
}
.ck-drip i:nth-child(2n){height:74%}
.ck-drip i:nth-child(2n+1){height:100%}

.ck-candles{
  position:absolute;left:50%;bottom:58%;translate:-50% 0;z-index:7;
  width:46%;height:26%;display:flex;justify-content:space-between;align-items:flex-end;
}
.ck-candle{position:relative;width:12%;height:78%;border-radius:3px;
  background:repeating-linear-gradient(135deg,#fff 0 5px,color-mix(in srgb,var(--accent2) 55%,#fff) 5px 10px);
  box-shadow:inset -2px 0 3px rgba(0,0,0,.1);
}
.ck-candle:nth-child(2){height:100%}
.ck-wick{position:absolute;left:50%;top:-14%;translate:-50% 0;width:2px;height:14%;background:#5a4436;border-radius:2px}
.ck-flame{
  position:absolute;left:50%;top:-72%;translate:-50% 0;
  width:190%;aspect-ratio:.62;
  border-radius:50% 50% 46% 46% / 68% 68% 34% 34%;
  background:radial-gradient(ellipse at 50% 74%,#fff9d0 0%,#ffd75e 34%,#ff9c3d 68%,rgba(255,120,40,.25) 100%);
  /* filter:blur(.4px) dihapus: 0,4px tidak terlihat, tapi memaksa
     lapisan filter per nyala api — di dalam induk yang sudah
     ber-drop-shadow, jadi tiap frame flicker meraster ulang kuenya. */
  box-shadow:0 0 16px 5px rgba(255,180,70,.55);
  transform-origin:50% 100%;
  animation:flicker 1.5s ease-in-out infinite alternate;
  transition:transform .5s cubic-bezier(.4,0,.2,1),opacity .45s;
}
.ck-candle:nth-child(2) .ck-flame{animation-delay:-.5s}
.ck-candle:nth-child(3) .ck-flame{animation-delay:-1s}
@keyframes flicker{
  0%  {transform:scale(1)      rotate(-2deg)}
  50% {transform:scaleY(1.12) scaleX(.94) rotate(2deg)}
  100%{transform:scale(1.04)  rotate(-1deg)}
}
.ck-smoke{
  position:absolute;left:50%;top:-64%;translate:-50% 0;
  width:60%;aspect-ratio:.5;border-radius:50%;
  background:radial-gradient(circle,rgba(190,190,190,.75),transparent 68%);
  opacity:0;
}

/* Lilin padam */
.opener[data-opener="cake"].is-blown .ck-flame{
  animation:none;opacity:0;transform:scaleY(.1) scaleX(.7);
}
.opener[data-opener="cake"].is-blown .ck-smoke{
  animation:smokeUp 1.4s ease-out calc(var(--i) * .08s) both;
}
@keyframes smokeUp{
  0%  {opacity:.75;transform:translateY(0) scale(.5)}
  100%{opacity:0;  transform:translateY(-190%) scale(2.1)}
}
/* Getaran halus saat mikrofon menangkap tiupan */
.opener[data-opener="cake"].is-blowing .ck-flame{
  animation:blowBend .32s ease-in-out infinite alternate;
}
@keyframes blowBend{
  from{transform:rotate(-16deg) scaleY(.86)}
  to  {transform:rotate(18deg)  scaleY(.7)}
}

/* =========================================================
   4 · BALON PECAH
   ========================================================= */
.opener[data-opener="balloon"]{aspect-ratio:.82/1;filter:drop-shadow(0 16px 26px rgba(120,50,75,.2))}
/* Balonnya tidak mengisi penuh kotak tombol: tingginya 66% dan mulai
   dari 4%, jadi pusatnya di 34%. Tanpa ini gemboknya menempel di tepi
   bawah balon, bukan di tengahnya. */
.opener[data-opener="balloon"] .op-lock{top:34%}

.bl-body{
  position:absolute;left:50%;top:4%;translate:-50% 0;
  width:66%;aspect-ratio:.82;
  border-radius:50% 50% 50% 50% / 56% 56% 44% 44%;
  background:
    radial-gradient(circle at 32% 26%,color-mix(in srgb,var(--accent) 30%,#fff) 0%,var(--accent) 46%,color-mix(in srgb,var(--accent) 76%,#000) 100%);
  box-shadow:inset -10px -14px 26px rgba(0,0,0,.18);
  transform-origin:50% 100%;
  animation:blFloat 3.4s ease-in-out infinite alternate;
  transition:transform .3s cubic-bezier(.34,1.56,.64,1),opacity .18s;
}
@keyframes blFloat{
  from{transform:translateY(0)    rotate(-2deg)}
  to  {transform:translateY(-8px) rotate(2deg)}
}
.bl-shine{
  position:absolute;left:22%;top:16%;width:26%;height:20%;border-radius:50%;
  background:linear-gradient(140deg,rgba(255,255,255,.85),rgba(255,255,255,0));
  filter:blur(1px);
}
.bl-knot{
  position:absolute;left:50%;top:calc(4% + 78%);translate:-50% 0;
  width:0;height:0;z-index:2;
  border-left:9px solid transparent;border-right:9px solid transparent;
  border-top:13px solid color-mix(in srgb,var(--accent) 82%,#000);
}
.bl-string{
  position:absolute;left:50%;top:calc(4% + 83%);
  width:26%;height:26%;
  border-left:2px solid color-mix(in srgb,var(--ink-soft) 75%,transparent);
  border-bottom-left-radius:80% 100%;
  transform:translateX(-4px);
}
/* Tahap mengembang */
.opener[data-opener="balloon"].stage-1 .bl-body{animation:none;transform:scale(1.09)}
.opener[data-opener="balloon"].stage-2 .bl-body{animation:none;transform:scale(1.2)}
.opener[data-opener="balloon"].is-open .bl-body{opacity:0;transform:scale(1.45)}
.opener[data-opener="balloon"].is-open .bl-knot,
.opener[data-opener="balloon"].is-open .bl-string{opacity:0;transition:opacity .2s}

.bl-pop{position:absolute;left:50%;top:42%;translate:-50% -50%;width:0;height:0;z-index:5}
.bl-pop i{
  position:absolute;width:12px;height:16px;opacity:0;
  background:var(--accent);
  clip-path:polygon(50% 0,100% 62%,58% 100%,0 70%);
}
.bl-pop i:nth-child(2n){background:var(--accent2)}
.bl-pop i:nth-child(3n){background:#fff}
.opener[data-opener="balloon"].is-open .bl-pop i{animation:blShard .8s cubic-bezier(.15,.8,.3,1) both}
.bl-pop i:nth-child(1){--dx:-130px;--dy:-70px}
.bl-pop i:nth-child(2){--dx:-90px;--dy:-125px}
.bl-pop i:nth-child(3){--dx:-30px;--dy:-150px}
.bl-pop i:nth-child(4){--dx:35px;--dy:-148px}
.bl-pop i:nth-child(5){--dx:95px;--dy:-120px}
.bl-pop i:nth-child(6){--dx:135px;--dy:-62px}
.bl-pop i:nth-child(7){--dx:145px;--dy:15px}
.bl-pop i:nth-child(8){--dx:105px;--dy:80px}
.bl-pop i:nth-child(9){--dx:15px;--dy:120px}
.bl-pop i:nth-child(10){--dx:-80px;--dy:95px}
.bl-pop i:nth-child(11){--dx:-140px;--dy:25px}
.bl-pop i:nth-child(12){--dx:0px;--dy:-190px}
@keyframes blShard{
  0%  {opacity:1;transform:translate(0,0) rotate(0) scale(.5)}
  100%{opacity:0;transform:translate(var(--dx),var(--dy)) rotate(420deg) scale(1.1)}
}

/* =========================================================
   5 · GORDEN PANGGUNG
   ========================================================= */
.opener[data-opener="curtain"]{aspect-ratio:1.34/1;filter:drop-shadow(0 18px 30px rgba(60,20,35,.3))}

.cu-stage{
  position:absolute;inset:6% 4% 4%;border-radius:8px;overflow:hidden;
  background:linear-gradient(180deg,#2a1420,#150a11);
  display:grid;place-items:center;
}
.cu-glow{
  position:absolute;left:50%;top:58%;translate:-50% -50%;
  width:70%;aspect-ratio:1;border-radius:50%;
  background:radial-gradient(circle,color-mix(in srgb,var(--accent2) 70%,transparent),transparent 66%);
  opacity:.35;transition:opacity .7s .3s;
}
.cu-star{position:relative;font-size:2rem;z-index:2;transition:transform .7s .35s,opacity .5s .35s;transform:scale(.7);opacity:.7}
.opener[data-opener="curtain"].is-open .cu-glow{opacity:.95}
.opener[data-opener="curtain"].is-open .cu-star{transform:scale(1.25);opacity:1}

.cu-panel{
  position:absolute;top:6%;bottom:4%;width:50%;z-index:4;
  display:flex;
  background:linear-gradient(180deg,color-mix(in srgb,var(--accent) 86%,#000),color-mix(in srgb,var(--accent) 62%,#000));
  transition:transform 1.05s cubic-bezier(.55,0,.2,1);
  box-shadow:0 0 26px rgba(0,0,0,.4);
}
.cu-panel i{flex:1;border-right:1px solid rgba(0,0,0,.18);
  background:linear-gradient(90deg,rgba(255,255,255,.16),transparent 62%,rgba(0,0,0,.22));}
.cu-left{left:4%;border-radius:6px 0 0 6px}
.cu-right{right:4%;border-radius:0 6px 6px 0}
.opener[data-opener="curtain"].is-open .cu-left{transform:translateX(-102%) scaleX(.55)}
.opener[data-opener="curtain"].is-open .cu-right{transform:translateX(102%) scaleX(.55)}

.cu-rod{
  position:absolute;left:0;right:0;top:3%;height:4%;z-index:6;border-radius:99px;
  background:linear-gradient(180deg,#e8c98a,#a8823f);
  box-shadow:0 3px 8px rgba(0,0,0,.3);
}
.cu-valance{
  position:absolute;left:2%;right:2%;top:6%;height:13%;z-index:5;
  background:linear-gradient(180deg,color-mix(in srgb,var(--accent) 90%,#000),color-mix(in srgb,var(--accent) 70%,#000));
  border-radius:0 0 50% 50% / 0 0 100% 100%;
  box-shadow:0 6px 14px rgba(0,0,0,.32);
}

/* =========================================================
   6 · BUNGA MEKAR
   ========================================================= */
.opener[data-opener="bloom"]{aspect-ratio:.92/1;filter:drop-shadow(0 16px 26px rgba(60,80,40,.22))}
/* Bunganya berpusat di 34% kotak tombol, bukan di tengahnya. */
.opener[data-opener="bloom"] .op-lock{top:34%}

.bm-stem{
  position:absolute;left:50%;bottom:0;translate:-50% 0;
  width:6px;height:38%;border-radius:99px;
  background:linear-gradient(180deg,#7fa85f,#4d7a3a);
}
.bm-leaf{
  position:absolute;bottom:9%;width:26%;height:12%;
  background:linear-gradient(140deg,#8fbb6a,#4d7a3a);
  border-radius:50% 0 50% 50%;
}
.bm-leaf-l{left:28%;transform:rotate(18deg) scaleX(-1);transform-origin:100% 50%}
.bm-leaf-r{right:28%;transform:rotate(-18deg);transform-origin:0 50%}

.bm-flower{
  position:absolute;left:50%;top:34%;translate:-50% -50%;
  width:92%;aspect-ratio:1;
}
.bm-sepal{position:absolute;left:50%;top:50%;translate:-50% -50%;width:100%;height:100%}
.bm-sepal i{
  position:absolute;left:50%;bottom:44%;margin-left:-4%;
  width:9%;height:26%;border-radius:50% 50% 40% 40%;
  background:linear-gradient(180deg,#6f9c50,#4d7a3a);
  transform-origin:50% 100%;
}
.bm-sepal i:nth-child(1){transform:rotate(-32deg)}
.bm-sepal i:nth-child(2){transform:rotate(0deg)}
.bm-sepal i:nth-child(3){transform:rotate(32deg)}

.bm-petal{
  position:absolute;left:50%;bottom:50%;margin-left:-13%;
  width:26%;height:42%;
  border-radius:50% 50% 42% 42% / 62% 62% 38% 38%;
  background:linear-gradient(180deg,color-mix(in srgb,var(--accent) 32%,#fff),var(--accent));
  transform-origin:50% 100%;
  transform:rotate(var(--a)) scale(.66,.46);
  box-shadow:inset 0 -6px 12px rgba(0,0,0,.08);
  transition:transform .8s cubic-bezier(.34,1.4,.5,1) calc(var(--i) * 65ms);
}
.bm-petal-in{
  width:19%;height:30%;margin-left:-9.5%;
  background:linear-gradient(180deg,#fff,color-mix(in srgb,var(--accent2) 62%,#fff));
  z-index:3;
  transition-delay:calc(var(--i) * 65ms + 180ms);
}
.bm-core{
  position:absolute;left:50%;top:50%;translate:-50% -50%;z-index:4;
  width:22%;aspect-ratio:1;border-radius:50%;
  background:radial-gradient(circle at 38% 34%,#ffe9a0,color-mix(in srgb,var(--accent2) 78%,#000));
  box-shadow:inset 0 -3px 8px rgba(0,0,0,.2);
  display:grid;place-items:center;font-size:.9rem;
  transform:scale(.78);
  transition:transform .7s cubic-bezier(.34,1.5,.5,1) .42s;
}
.opener[data-opener="bloom"].is-open .bm-petal{transform:rotate(var(--a)) scale(1,1)}
.opener[data-opener="bloom"].is-open .bm-core{transform:scale(1)}
.opener[data-opener="bloom"].is-open .bm-sepal i:nth-child(1){transform:rotate(-52deg)}
.opener[data-opener="bloom"].is-open .bm-sepal i:nth-child(3){transform:rotate(52deg)}
.bm-sepal i{transition:transform .7s cubic-bezier(.34,1.4,.5,1)}

/* =========================================================
   7 · TOPI TOGA
   ---------------------------------------------------------
   Papannya persegi yang diputar 45 derajat lalu dipipihkan
   setengah. Urutan transform-nya sengaja `scaleY() rotate()`,
   bukan sebaliknya: transform dibaca dari kanan ke kiri, jadi
   yang ditulis paling kiri yang berlaku terakhir di layar.
   Dibalik, yang terpipihkan adalah perseginya sebelum diputar,
   dan hasilnya belah ketupat tegak, bukan bidang datar.
   ========================================================= */
.opener[data-opener="toga"]{aspect-ratio:1.15/1;filter:drop-shadow(0 16px 28px rgba(40,30,70,.3))}
/* Topinya duduk di paruh atas kotak tombol, jadi gemboknya ikut naik. */
.opener[data-opener="toga"] .op-lock{top:37%}

/* Satu bungkus untuk seluruh topi: yang melayang saat dilempar
   adalah benda utuh, bukan lima keping yang harus disamakan
   waktunya satu per satu. */
.tg-cap{position:absolute;inset:0}

.tg-crown{
  position:absolute;left:50%;top:40%;translate:-50% 0;z-index:1;
  width:37%;height:27%;
  border-radius:10% 10% 44% 44% / 12% 12% 64% 64%;
  background:linear-gradient(170deg,
    color-mix(in srgb,var(--accent) 32%,#000),
    color-mix(in srgb,var(--accent) 18%,#000));
}
.tg-board{
  position:absolute;left:50%;top:34%;translate:-50% -50%;z-index:2;
  width:58%;aspect-ratio:1;border-radius:7%;
  background:linear-gradient(135deg,
    color-mix(in srgb,var(--accent) 88%,#000),
    color-mix(in srgb,var(--accent) 48%,#000));
  box-shadow:0 4px 10px rgba(0,0,0,.22);
  transform:scaleY(.5) rotate(45deg);
}
.tg-btn{
  position:absolute;left:50%;top:34%;translate:-50% -50%;z-index:3;
  width:8%;aspect-ratio:1;border-radius:50%;
  background:var(--accent2);box-shadow:0 1px 3px rgba(0,0,0,.35);
}
.tg-cord{
  position:absolute;left:50%;top:34%;translate:0 -50%;z-index:3;
  width:39%;height:2px;border-radius:2px;
  background:color-mix(in srgb,var(--accent2) 88%,#000);
}
.tg-tassel{
  position:absolute;left:88%;top:34%;translate:-50% 0;z-index:3;
  width:9%;height:40%;
  transform-origin:50% 0;
  animation:tgSway 3.2s ease-in-out infinite alternate;
}
.tg-tassel::before{           /* tali dari sudut papan ke simpul */
  content:"";position:absolute;left:50%;top:0;translate:-50% 0;
  width:2px;height:34%;border-radius:2px;
  background:color-mix(in srgb,var(--accent2) 88%,#000);
}
.tg-tassel i{                 /* jumbainya, benang demi benang */
  position:absolute;left:50%;top:30%;translate:-50% 0;
  width:100%;height:70%;border-radius:30% 30% 22% 22%;
  background:
    linear-gradient(180deg,color-mix(in srgb,var(--accent2) 60%,#fff) 0 16%,transparent 16%),
    repeating-linear-gradient(90deg,
      var(--accent2) 0 2px,
      color-mix(in srgb,var(--accent2) 62%,#000) 2px 4px);
}
@keyframes tgSway{
  from{transform:rotate(-7deg)}
  to  {transform:rotate(6deg)}
}

/* Dilempar: sedikit menekuk dulu, baru naik sambil berputar. */
.opener[data-opener="toga"].is-open .tg-cap{
  animation:tgToss 1s cubic-bezier(.3,.7,.35,1) forwards;
}
@keyframes tgToss{
  0%  {transform:translateY(0)     rotate(0deg)}
  16% {transform:translateY(6%)    rotate(-4deg)}
  100%{transform:translateY(-165%) rotate(-26deg);opacity:0}
}
.opener[data-opener="toga"].is-open .tg-tassel{
  animation:tgFly .9s ease-out forwards;
}
@keyframes tgFly{
  from{transform:rotate(6deg)}
  to  {transform:rotate(-54deg)}
}

/* =========================================================
   Hormati "kurangi gerakan"
   ========================================================= */
@media (prefers-reduced-motion:reduce){
  .ck-flame,.bl-body,.tg-tassel{animation:none}
  .opener,.opener *{transition-duration:.01ms!important}
  .gb-burst i,.bl-pop i,.ck-smoke{animation:none!important;opacity:0!important}
}

/* =========================================================
   8 · KOTAK CINCIN
   ---------------------------------------------------------
   Kotaknya sengaja KECIL di tengah panggung persegi, bukan
   selebar panggungnya. Kotak cincin sungguhan memang benda
   kecil, dan proporsi itulah yang membedakannya dari kotak
   kado — kalau dilebarkan, yang terbaca cuma "kotak".
   Ruang di atasnya dipakai cincin untuk naik.
   ========================================================= */
.opener[data-opener="ring"]{aspect-ratio:1/1;filter:drop-shadow(0 16px 30px rgba(120,50,75,.24))}

.rg-glow{
  position:absolute;left:50%;top:40%;translate:-50% -50%;z-index:0;
  width:70%;aspect-ratio:1;border-radius:50%;opacity:0;
  background:radial-gradient(circle,
    color-mix(in srgb,var(--accent2) 50%,transparent) 0%,
    transparent 66%);
  transition:opacity .5s;
}
.opener[data-opener="ring"].is-open .rg-glow{opacity:1}

.rg-base{
  position:absolute;left:27%;right:27%;top:52%;height:34%;z-index:3;
  border-radius:3px 3px 9px 9px;
  background:linear-gradient(168deg,
    color-mix(in srgb,var(--accent) 40%,#2a1b22),
    color-mix(in srgb,var(--accent) 20%,#170e12));
  box-shadow:0 10px 20px rgba(0,0,0,.3), inset 0 1px 0 rgba(255,255,255,.16);
}
/* Belahan beludru tempat cincin berdiri. Tersembunyi selama kotaknya
   tertutup: isi kotak yang terlihat sebelum tutupnya dibuka membuat
   seluruh bendanya berhenti terbaca sebagai kotak. */
.rg-slot{
  position:absolute;left:50%;top:13%;translate:-50% 0;
  width:36%;height:22%;border-radius:99px;opacity:0;
  background:color-mix(in srgb,var(--accent) 14%,#0f080b);
  box-shadow:inset 0 2px 4px rgba(0,0,0,.55);
  transition:opacity .3s .28s;
}
.opener[data-opener="ring"].is-open .rg-slot{opacity:1}

.rg-ring{
  position:absolute;left:50%;top:40%;translate:-50% 0;z-index:2;
  width:23%;aspect-ratio:1;
}
.rg-band{
  position:absolute;inset:0;border-radius:50%;
  background:linear-gradient(150deg,
    color-mix(in srgb,var(--accent2) 72%,#fff),
    var(--accent2) 55%,
    color-mix(in srgb,var(--accent2) 66%,#3a2028));
  /* Lubang di tengah dibuat dengan mask, bukan border. Lebar border
     tidak menerima persen, jadi cincin yang ikut mengecil di layar
     sempit hanya bisa dibentuk begini. Lubangnya juga harus benar-benar
     tembus: cincin melayang di atas kotak, dan lubang yang ditambal
     warna akan salah warna begitu ia naik. */
  -webkit-mask:radial-gradient(circle,transparent 0 56%,#000 60% 100%);
  mask:radial-gradient(circle,transparent 0 56%,#000 60% 100%);
  filter:drop-shadow(0 2px 4px rgba(0,0,0,.35));
}
.rg-stone{
  position:absolute;left:50%;top:-24%;translate:-50% 0;
  width:44%;aspect-ratio:1;border-radius:20% 50% 20% 50%;
  rotate:45deg;
  background:linear-gradient(140deg,#fff,color-mix(in srgb,var(--accent2) 40%,#fff) 55%,#fff);
  box-shadow:0 0 12px color-mix(in srgb,var(--accent2) 75%,transparent);
}

/* Tutupnya menumpang 2% di atas alas. Celah setipis apa pun di antara
   keduanya terbaca sebagai kotak retak, bukan kotak tertutup. */
.rg-lid{
  position:absolute;left:25.5%;right:25.5%;top:22%;height:32%;z-index:4;
  transform-origin:50% 100%;
  border-radius:10px 10px 3px 3px;
  background:linear-gradient(168deg,
    color-mix(in srgb,var(--accent) 56%,#2a1b22),
    color-mix(in srgb,var(--accent) 30%,#1a1015) 62%,
    color-mix(in srgb,var(--accent) 44%,#241519));
  box-shadow:0 6px 14px rgba(0,0,0,.3), inset 0 2px 0 rgba(255,255,255,.22);
  transition:transform .75s cubic-bezier(.3,.8,.3,1);
}
/* Garis engsel: satu sorot tipis di tepi bawah tutup. Tanpa itu tutup
   dan alas terbaca sebagai satu balok yang kebetulan bergaris. */
.rg-lid::after{
  content:"";position:absolute;left:6%;right:6%;bottom:0;height:2px;
  border-radius:2px;background:color-mix(in srgb,var(--accent2) 70%,transparent);
  opacity:.65;
}
/* Sisi dalam beludru. Tanpa lapis kedua ini, tutup yang berputar ke
   belakang terbaca sebagai kotak yang terbelah, bukan yang dibuka. */
.rg-lid-in{
  position:absolute;inset:8% 8% 12%;border-radius:7px;
  background:linear-gradient(180deg,
    color-mix(in srgb,var(--accent) 30%,#fdf3f0),
    color-mix(in srgb,var(--accent) 50%,#e9cfc9));
  opacity:0;transition:opacity .4s .3s;
}
.opener[data-opener="ring"].is-open .rg-lid{transform:rotateX(-122deg)}
.opener[data-opener="ring"].is-open .rg-lid-in{opacity:1}
.opener[data-opener="ring"].is-open .rg-ring{
  animation:rgRise 1s cubic-bezier(.25,.9,.3,1) .2s forwards;
}
@keyframes rgRise{
  0%  {transform:translate(-50%,0)    scale(1)}
  60% {transform:translate(-50%,-72%) scale(1.22)}
  100%{transform:translate(-50%,-62%) scale(1.16)}
}

.rg-spark{position:absolute;inset:0;z-index:5;pointer-events:none}
.rg-spark i{
  position:absolute;left:50%;top:34%;
  width:5%;aspect-ratio:1;border-radius:50%;opacity:0;
  background:#fff;box-shadow:0 0 8px color-mix(in srgb,var(--accent2) 80%,transparent);
}
.opener[data-opener="ring"].is-open .rg-spark i{
  animation:rgSpark .9s ease-out forwards;
}
.rg-spark i:nth-child(1){--dx:-140%;--dy:-90%;animation-delay:.44s}
.rg-spark i:nth-child(2){--dx:130%;--dy:-110%;animation-delay:.52s}
.rg-spark i:nth-child(3){--dx:-90%;--dy:-170%;animation-delay:.6s}
.rg-spark i:nth-child(4){--dx:95%;--dy:-40%;animation-delay:.48s}
.rg-spark i:nth-child(5){--dx:-30%;--dy:-190%;animation-delay:.64s}
.rg-spark i:nth-child(6){--dx:40%;--dy:-150%;animation-delay:.56s}
@keyframes rgSpark{
  0%  {opacity:0;transform:translate(-50%,-50%) scale(.2)}
  30% {opacity:1;transform:translate(calc(-50% + var(--dx) * .5),calc(-50% + var(--dy) * .5)) scale(1)}
  100%{opacity:0;transform:translate(calc(-50% + var(--dx)),calc(-50% + var(--dy))) scale(.3)}
}

/* =========================================================
   9 · KERETA BAYI
   ========================================================= */
.opener[data-opener="baby"]{aspect-ratio:1.3/1;filter:drop-shadow(0 16px 30px rgba(120,50,75,.22))}

.bb-kereta{position:absolute;inset:0}

/* Keranjangnya setengah lingkaran di bawah: itu bentuk yang paling
   cepat dikenali, dan bagian atasnya sengaja rata supaya kanopi
   punya garis untuk berporos. */
.bb-body{
  position:absolute;left:16%;right:22%;top:44%;height:30%;z-index:2;
  border-radius:8% 8% 52% 52% / 8% 8% 96% 96%;
  background:linear-gradient(170deg,
    color-mix(in srgb,var(--accent) 78%,#fff) 0%,
    var(--accent) 70%);
  box-shadow:inset 0 -6px 12px rgba(0,0,0,.14);
}
/* Porosnya di sudut kanan bawah, tempat kanopi bertemu rangka.
   Dulu porosnya di kiri dan kanopinya DIPUTAR sampai keluar dari
   panggung, terbaca sebagai potongan oranye yang tercecer di tepi
   kartu. Kanopi sungguhan tidak berputar, ia melipat: menyusut ke
   arah pangkalnya, lipatan demi lipatan. */
.bb-hood{
  position:absolute;left:16%;width:44%;top:16%;height:28%;z-index:3;
  transform-origin:100% 100%;
  transition:transform .7s cubic-bezier(.3,.8,.3,1);
}
.bb-hood i{
  position:absolute;inset:0;
  border-radius:96% 8% 0 0 / 98% 10% 0 0;
  background:linear-gradient(150deg,
    color-mix(in srgb,var(--accent2) 86%,#fff),
    var(--accent2));
  box-shadow:inset -3px 3px 8px rgba(255,255,255,.35);
}
/* Gagangnya turun sampai MASUK ke bibir keranjang. Batang yang
   berhenti di udara sebelum menyentuh apa pun terbaca sebagai garis
   yang tercecer, bukan sebagai pegangan. */
.bb-handle{
  position:absolute;right:21%;top:20%;width:17%;height:29%;z-index:1;
  border-top:4px solid color-mix(in srgb,var(--accent) 45%,#3a2028);
  border-right:4px solid color-mix(in srgb,var(--accent) 45%,#3a2028);
  border-radius:0 46% 0 0;
}
.bb-wheel{
  position:absolute;bottom:8%;z-index:4;aspect-ratio:1;border-radius:50%;
  background:radial-gradient(circle,
    #fff 0 22%,
    color-mix(in srgb,var(--accent) 40%,#2c1a20) 24% 100%);
  box-shadow:0 3px 7px rgba(0,0,0,.26);
}
.bb-wheel-b{left:22%;width:17%}     /* belakang, lebih besar */
.bb-wheel-d{left:52%;width:12%;bottom:10%}   /* depan */

.opener[data-opener="baby"].is-open .bb-hood{transform:scaleX(.13)}
/* Keretanya berjalan pergi ke kanan, bukan memudar di tempat: benda
   beroda yang menghilang tanpa bergerak terbaca seperti gambar yang
   gagal dimuat. */
.opener[data-opener="baby"].is-open .bb-kereta{
  animation:bbJalan .95s cubic-bezier(.4,.1,.7,1) .25s forwards;
}
@keyframes bbJalan{
  0%  {transform:translateX(0)    rotate(0deg);opacity:1}
  22% {transform:translateX(-5%)  rotate(-1.5deg)}
  100%{transform:translateX(118%) rotate(2deg);opacity:0}
}
.opener[data-opener="baby"].is-open .bb-wheel{
  animation:bbPutar .95s linear .25s forwards;
}
@keyframes bbPutar{ to{ rotate:540deg } }

.bb-spark{position:absolute;inset:0;z-index:5;pointer-events:none}
.bb-spark i{
  position:absolute;left:34%;top:34%;
  width:5%;aspect-ratio:1;border-radius:50%;opacity:0;
  background:#fff;box-shadow:0 0 7px color-mix(in srgb,var(--accent2) 75%,transparent);
}
.opener[data-opener="baby"].is-open .bb-spark i{animation:rgSpark .85s ease-out forwards}
.bb-spark i:nth-child(1){--dx:-60%;--dy:-130%;animation-delay:.3s}
.bb-spark i:nth-child(2){--dx:70%;--dy:-100%;animation-delay:.38s}
.bb-spark i:nth-child(3){--dx:10%;--dy:-170%;animation-delay:.46s}
.bb-spark i:nth-child(4){--dx:-110%;--dy:-70%;animation-delay:.34s}
.bb-spark i:nth-child(5){--dx:120%;--dy:-160%;animation-delay:.42s}

@media (prefers-reduced-motion:reduce){
  .opener[data-opener="ring"].is-open .rg-ring,
  .opener[data-opener="baby"].is-open .bb-kereta,
  .opener[data-opener="baby"].is-open .bb-wheel,
  .rg-spark i,.bb-spark i{animation:none}
  .rg-lid,.bb-hood{transition-duration:.2s}
}
