/* ══════════ fx-pack.css — ชุดอนิเมชั่นรอบสี่ ══════════
   ทุกชิ้นอยู่บน #fxp-layer (fixed, ไม่รับการแตะ) ยกเว้นคลาสที่ติดกับ element เดิมโดยตรง
   (fxp-no สั่นปุ่ม, fxp-poisoned ฟองพิษ, fxp-bump ตัวนับหยก) ซึ่งแตะแค่ transform/pseudo */
#fxp-layer{position:fixed;inset:0;pointer-events:none;z-index:215;overflow:hidden}
.fxp{position:fixed;pointer-events:none;will-change:transform,opacity}

/* 2 · กลืนโอสถ */
.fxp-pill .p{position:absolute;left:-7px;top:-7px;width:14px;height:14px;border-radius:50%;
  background:radial-gradient(circle at 36% 30%,#fff1c9,#e0a23c 55%,#9c5a16);box-shadow:0 0 10px rgba(240,180,80,.6);opacity:0}
.fxp-pill.go .p{animation:fxpPill .8s cubic-bezier(.55,0,.9,.6) forwards}
@keyframes fxpPill{0%{opacity:0;transform:translate(0,120px) scale(1.2)}15%{opacity:1}
  85%{opacity:1;transform:translate(0,2px) scale(.7)}100%{opacity:0;transform:translate(0,0) scale(.3)}}
.fxp-pill .w{position:absolute;left:-16px;top:-16px;width:32px;height:32px;border-radius:50%;
  border:2px solid rgba(255,202,106,.85);opacity:0}
.fxp-pill.go .w{animation:fxpPillW .7s .68s ease-out forwards}
@keyframes fxpPillW{from{opacity:.9;transform:scale(.3)}to{opacity:0;transform:scale(3.2)}}

/* 3 · เหรียญหยกพุ่งเข้าตัวนับ */
.fxp-coin{width:11px;height:11px;margin:-5px 0 0 -5px;border-radius:50%;
  background:radial-gradient(circle at 35% 30%,#d9f3e2,#6fa587 60%,#3f6b54);box-shadow:0 0 6px rgba(127,183,154,.55);opacity:0}
.fxp-coin.go{animation:fxpCoin .85s cubic-bezier(.45,0,.2,1) forwards}
@keyframes fxpCoin{0%{opacity:0;transform:translate(0,0) scale(.6)}12%{opacity:1;transform:translate(calc(var(--mx)*.3),-18px) scale(1)}
  100%{opacity:.2;transform:translate(var(--dx),var(--dy)) scale(.45)}}
.fxp-bump{animation:fxpBump .45s cubic-bezier(.3,1.6,.4,1)}
@keyframes fxpBump{0%{transform:scale(1)}40%{transform:scale(1.22);color:#d9f3e2}100%{transform:scale(1)}}

/* 4 · แสงวิ่งผ่านแถวศิษย์ */
.fxp-sweep{border-radius:12px;overflow:hidden}
.fxp-sweep i{position:absolute;inset:0;background:linear-gradient(105deg,transparent 30%,rgba(233,187,97,.38) 50%,transparent 70%);
  transform:translateX(-120%)}
.fxp-sweep.go i{animation:fxpSweep 1.1s cubic-bezier(.4,0,.2,1) forwards}
@keyframes fxpSweep{to{transform:translateX(130%)}}

/* 5 · ตราประทับ */
.fxp-stamp b{position:absolute;left:-19px;top:-19px;width:38px;height:38px;border-radius:6px;background:#8f2723;
  color:#ffe0d6;display:grid;place-items:center;font:800 18px "Songti SC",SimSun,serif;opacity:0;
  box-shadow:0 2px 8px rgba(0,0,0,.5)}
.fxp-stamp.go b{animation:fxpStamp 1.2s cubic-bezier(.3,1.5,.4,1) forwards}
@keyframes fxpStamp{0%{opacity:0;transform:scale(2.4) rotate(-20deg)}30%{opacity:1;transform:scale(1) rotate(-9deg)}
  80%{opacity:1;transform:scale(1) rotate(-9deg)}100%{opacity:0;transform:scale(1.05) rotate(-9deg)}}

/* 6 · อัญมณีหมุนลงช่อง */
.fxp-gem .g{position:absolute;left:-7px;top:-7px;width:14px;height:14px;
  background:radial-gradient(circle at 35% 30%,#e6f4ff,#5d93c9 60%,#2c5580);opacity:0}
.fxp-gem.go .g{animation:fxpGem .75s cubic-bezier(.3,.9,.3,1) forwards}
@keyframes fxpGem{0%{opacity:1;transform:translateY(-44px) rotate(45deg) scale(1.4)}
  100%{opacity:0;transform:translateY(0) rotate(405deg) scale(.9)}}
.fxp-gem .ring{position:absolute;left:-14px;top:-14px;width:28px;height:28px;border-radius:50%;border:2px solid #8fd3e8;opacity:0}
.fxp-gem.go .ring{animation:fxpGemR .55s .66s ease-out forwards}
@keyframes fxpGemR{from{opacity:.9;transform:scale(.4)}to{opacity:0;transform:scale(2.8)}}

/* 16 · ปราณล้นที่ปลายแถบ */
.fxp-over i{position:absolute;left:-9px;top:-9px;width:18px;height:18px;border-radius:50%;
  background:radial-gradient(circle,rgba(120,215,240,.9),rgba(84,198,224,0) 70%);opacity:0}
.fxp-over.go i{animation:fxpOver .85s ease-out forwards}
.fxp-over.go i:nth-child(2){animation-delay:.18s}
@keyframes fxpOver{from{opacity:1;transform:translateX(0) scale(.5)}to{opacity:0;transform:translateX(18px) scale(2.2)}}

/* 19 · เกราะแตกเป็นอนูละเอียด
   สามจังหวะ: โดมเกราะสว่างวาบ → รอยร้าววิ่งทั่วโดม → โดมหาย เศษแก้วกระจายเป็นเส้นโค้งตกลงตามแรงโน้มถ่วง
   เศษแต่ละชิ้นมีขนาด มุม ความเร็ว และการหมุนต่างกัน จึงไม่ดูเป็นลวดลายซ้ำ */
.fxp-shatter .dome{position:absolute;left:calc(var(--w) / -2);top:calc(var(--w) / -2);width:var(--w);height:var(--w);
  border-radius:50%;border:1.5px solid rgba(147,197,253,.95);
  background:radial-gradient(circle at 40% 35%,rgba(191,219,254,.38),rgba(96,165,250,.14) 55%,rgba(59,130,246,.05) 70%);
  box-shadow:0 0 18px rgba(96,165,250,.55),inset 0 0 14px rgba(191,219,254,.35)}
.fxp-shatter.go .dome{animation:fxpDome .42s cubic-bezier(.3,0,.6,1) forwards}
@keyframes fxpDome{0%{opacity:.25;transform:scale(.92)}30%{opacity:1;transform:scale(1.04)}
  70%{opacity:.9;transform:scale(1)}100%{opacity:0;transform:scale(1.18)}}
.fxp-shatter .crack{position:absolute;left:calc(var(--w) / -2);top:calc(var(--w) / -2);width:var(--w);height:var(--w);border-radius:50%;
  background:
    linear-gradient(28deg,transparent 48.6%,rgba(236,244,255,.95) 49.6%,transparent 50.6%),
    linear-gradient(-52deg,transparent 48.6%,rgba(236,244,255,.85) 49.6%,transparent 50.6%),
    linear-gradient(96deg,transparent 48.8%,rgba(236,244,255,.75) 49.6%,transparent 50.4%),
    linear-gradient(151deg,transparent 48.8%,rgba(236,244,255,.7) 49.6%,transparent 50.4%);
  opacity:0;clip-path:circle(0% at 50% 50%)}
.fxp-shatter.go .crack{animation:fxpCrack .34s .08s cubic-bezier(.2,.8,.3,1) forwards}
@keyframes fxpCrack{0%{opacity:1;clip-path:circle(0% at 50% 50%)}80%{opacity:1;clip-path:circle(52% at 50% 50%)}
  100%{opacity:0;clip-path:circle(55% at 50% 50%)}}
.fxp-shatter .sh{position:absolute;left:0;top:0;opacity:0;
  background:linear-gradient(135deg,rgba(236,244,255,.98),rgba(147,197,253,.85) 45%,rgba(59,130,246,.7));
  clip-path:polygon(50% 0,100% 38%,78% 100%,14% 86%,0 30%);
  box-shadow:0 0 4px rgba(147,197,253,.7)}
.fxp-shatter.go .sh{animation-name:fxpShard;animation-timing-function:cubic-bezier(.22,.6,.36,1);animation-fill-mode:forwards;
  animation-delay:.32s}
@keyframes fxpShard{
  0%{opacity:1;transform:translate(0,0) rotate(0) scale(1)}
  35%{opacity:1;transform:translate(var(--x1),var(--y1)) rotate(calc(var(--r) * .4)) scale(1)}
  100%{opacity:0;transform:translate(var(--x2),var(--y2)) rotate(var(--r)) scale(.55)}}
.fxp-shatter .gl{position:absolute;left:-2px;top:-2px;width:4px;height:4px;border-radius:50%;background:#f4f9ff;
  box-shadow:0 0 6px 2px rgba(191,219,254,.8);opacity:0}
.fxp-shatter.go .gl{animation:fxpGlint .5s ease-out forwards}
@keyframes fxpGlint{0%{opacity:0;transform:translate(0,0) scale(.3)}30%{opacity:1;transform:translate(calc(var(--gx) * .5),calc(var(--gy) * .5)) scale(1.1)}
  100%{opacity:0;transform:translate(var(--gx),var(--gy)) scale(.2)}}

/* 20 · ป้ายตำแหน่งเลื่อน */
.fxp-rank{overflow:hidden;border-radius:8px;background:var(--surface-panel,#1a1a1a)}
.fxp-rank span{position:absolute;inset:0;display:grid;place-items:center;font-size:12px;font-weight:800}
.fxp-rank .o{color:#8a8478}
.fxp-rank .n{color:#e9bb61;transform:translateY(100%)}
.fxp-rank.go .o{animation:fxpRkO .6s .15s cubic-bezier(.4,0,.2,1) forwards}
.fxp-rank.go .n{animation:fxpRkN .6s .15s cubic-bezier(.4,0,.2,1) forwards,fxpRkFade .4s 1s forwards}
@keyframes fxpRkO{to{transform:translateY(-100%)}}
@keyframes fxpRkN{to{transform:translateY(0)}}
@keyframes fxpRkFade{to{opacity:0}}
.fxp-rank.go{animation:fxpRkBg .4s 1s forwards}
@keyframes fxpRkBg{to{opacity:0}}

/* 21 · เมฆลอยหลังภูเขาในหน้าหลัก */
.ho-stage::before,.ho-stage::after{content:"";position:absolute;z-index:-2;pointer-events:none;
  width:120px;height:18px;border-radius:40px;
  background:radial-gradient(ellipse at 50% 60%,rgba(214,220,210,.13),rgba(214,220,210,0) 70%);
  filter:blur(1px)}
.ho-stage::before{top:106px;left:-130px;animation:fxpCloud 38s linear infinite}
.ho-stage::after{top:132px;left:-130px;width:88px;height:14px;animation:fxpCloud 52s linear infinite;animation-delay:-24s}
@keyframes fxpCloud{from{transform:translateX(0)}to{transform:translateX(calc(100vw + 260px))}}

/* 24 · ปฏิเสธแบบสั่น */
.fxp-no{animation:fxpNo .4s cubic-bezier(.36,.07,.19,.97)}
@keyframes fxpNo{10%,90%{transform:translateX(-1px)}20%,80%{transform:translateX(2px)}
  30%,50%,70%{transform:translateX(-4px)}40%,60%{transform:translateX(4px)}}

/* 25 · คลื่นจากจุดที่แตะ */
.fxp-ripclip{overflow:hidden}
.fxp-ripclip i{position:absolute;width:var(--s);height:var(--s);margin:calc(var(--s) / -2) 0 0 calc(var(--s) / -2);
  border-radius:50%;background:radial-gradient(circle,rgba(255,244,214,.26),rgba(255,244,214,0) 65%);
  transform:scale(0);animation:fxpRip .6s cubic-bezier(.2,.7,.3,1) forwards}
@keyframes fxpRip{0%{transform:scale(0);opacity:1}100%{transform:scale(1);opacity:0}}

/* 26 · สองชิ้นหลอมเป็นหนึ่ง */
.fxp-fuse i{position:absolute;opacity:0}
.fxp-fuse .a,.fxp-fuse .b{left:-13px;top:-13px;width:26px;height:26px;border-radius:7px;
  background:linear-gradient(145deg,#6a6480,#2e2b3c);border:1px solid #7a7490}
.fxp-fuse.go .a{animation:fxpFuseA .6s cubic-bezier(.5,0,.8,.5) forwards}
.fxp-fuse.go .b{animation:fxpFuseB .6s cubic-bezier(.5,0,.8,.5) forwards}
@keyframes fxpFuseA{0%{opacity:1;transform:translateX(-58px) rotate(-12deg)}100%{opacity:0;transform:translateX(0) rotate(0)}}
@keyframes fxpFuseB{0%{opacity:1;transform:translateX(58px) rotate(12deg)}100%{opacity:0;transform:translateX(0) rotate(0)}}
.fxp-fuse .n{left:-17px;top:-17px;width:34px;height:34px;border-radius:9px;
  background:linear-gradient(145deg,#f3d58a,#b8862e);box-shadow:0 0 18px rgba(233,187,97,.6)}
.fxp-fuse.go .n{animation:fxpFuseN 1s .55s cubic-bezier(.3,1.5,.4,1) forwards}
@keyframes fxpFuseN{0%{opacity:0;transform:scale(.3)}35%{opacity:1;transform:scale(1.08)}75%{opacity:1;transform:scale(1)}100%{opacity:0;transform:scale(1)}}
.fxp-fuse .ring{left:-20px;top:-20px;width:40px;height:40px;border-radius:50%;border:2px solid #e9bb61}
.fxp-fuse.go .ring{animation:fxpFuseR .6s .55s ease-out forwards}
@keyframes fxpFuseR{from{opacity:.9;transform:scale(.4)}to{opacity:0;transform:scale(3)}}

/* 27 · ฟองพิษจากกล่องบนเวที */
.fxp-poisoned::after{content:"";position:absolute;left:18%;right:18%;bottom:30%;height:60%;pointer-events:none;
  background:
    radial-gradient(circle,rgba(132,204,22,.55) 0 2.2px,transparent 3px) 12% 100%/12px 12px no-repeat,
    radial-gradient(circle,rgba(132,204,22,.5) 0 1.6px,transparent 2.4px) 58% 100%/10px 10px no-repeat,
    radial-gradient(circle,rgba(132,204,22,.45) 0 2px,transparent 2.8px) 86% 100%/12px 12px no-repeat;
  animation:fxpBub 1.9s ease-in infinite;opacity:.9}
@keyframes fxpBub{0%{background-position:12% 100%,58% 100%,86% 100%;opacity:0}
  15%{opacity:.9}100%{background-position:18% 0%,52% 10%,80% 0%;opacity:0}}

/* 28 · สแกนกระเป๋าตอนเรียง */
.fxp-scan{overflow:hidden;border-radius:10px}
.fxp-scan i{position:absolute;left:0;right:0;height:26px;top:-26px;
  background:linear-gradient(180deg,transparent,rgba(233,187,97,.18) 60%,rgba(233,187,97,.7) 96%,transparent)}
.fxp-scan.go i{animation:fxpScan .95s cubic-bezier(.4,0,.2,1) forwards}
@keyframes fxpScan{to{top:100%}}

/* 29 · ดอกบัวบาน */
.fxp-lotus i{position:absolute;left:-7px;top:-34px;width:14px;height:34px;transform-origin:50% 100%;
  border-radius:50% 50% 50% 50%/65% 65% 35% 35%;
  background:linear-gradient(180deg,#fbe1ec,#d98fb2 70%,#b86b92);opacity:0}
.fxp-lotus i.in{height:26px;top:-26px;background:linear-gradient(180deg,#fff2f7,#eab2cb)}
.fxp-lotus.go i{animation:fxpPetal 1.9s cubic-bezier(.3,1.2,.4,1) forwards}
@keyframes fxpPetal{0%{opacity:0;transform:rotate(var(--a)) scaleY(.1)}
  35%{opacity:1;transform:rotate(var(--a)) scaleY(1)}75%{opacity:1;transform:rotate(var(--a)) scaleY(1)}
  100%{opacity:0;transform:rotate(var(--a)) scaleY(1) translateY(-6px)}}
.fxp-lotus b{position:absolute;left:-7px;top:-7px;width:14px;height:14px;border-radius:50%;
  background:radial-gradient(circle,#fff3cf,#e9bb61);box-shadow:0 0 16px rgba(233,187,97,.7);opacity:0}
.fxp-lotus.go b{animation:fxpCore 1.9s .4s ease-out forwards}
@keyframes fxpCore{0%{opacity:0;transform:scale(.3)}30%{opacity:1;transform:scale(1.2)}80%{opacity:1}100%{opacity:0;transform:scale(1)}}

@media (prefers-reduced-motion:reduce){
  #fxp-layer{display:none}
  .ho-stage::before,.ho-stage::after,.fxp-poisoned::after{animation:none;display:none}
  .fxp-no,.fxp-bump{animation:none}
}
