/* ---------- эффекты заклинаний на фишках боя ----------
   Иконки и анимации — те же, что на странице «Анимации заклинаний». Эффект живёт 0,6 с при ×1
   (делится на скорость боя через --spd), то есть укладывается в ход (TURN_MS = 900). */
.sfx{position:absolute;left:0;top:0;width:var(--cell);height:var(--cell);display:grid;place-items:center;pointer-events:none;z-index:42;animation:sfxLife calc(.6s / var(--spd,1)) ease-out both}
.sfx>div{width:90%;height:90%}
.sfx svg{width:100%;height:100%;overflow:visible;display:block}
.sfx svg .p{transform-box:fill-box;transform-origin:center;animation-duration:calc(.6s / var(--spd,1));animation-fill-mode:both;animation-timing-function:cubic-bezier(.3,.7,.3,1)}
@keyframes sfxLife{0%{opacity:0}8%{opacity:1}80%{opacity:1}100%{opacity:0}}
@media (prefers-reduced-motion: reduce){.sfx{display:none}}
@keyframes burst{0%,38%{transform:scale(.2);opacity:0}48%{opacity:1}100%{transform:scale(1.7);opacity:0}}
@keyframes twinkle{0%,25%{transform:scale(0)}45%{transform:scale(1.3) rotate(45deg)}70%{transform:scale(.8) rotate(90deg)}100%{transform:scale(0) rotate(120deg)}}
.sfx .tw{animation-name:twinkle}
.sfx .tw2{animation-name:twinkle;animation-delay:calc(.06s / var(--spd,1))}

/* Магическая сфера: сгущается, кольца бегут по орбите, ударная волна */
.sfx .sp-orb{animation-name:spOrb}
@keyframes spOrb{0%{transform:scale(0) rotate(-120deg)}30%{transform:scale(1.15) rotate(0)}42%{transform:scale(.92)}54%{transform:scale(1.06)}68%,100%{transform:none}}
.sfx .sp-halo{animation-name:spHalo}
@keyframes spHalo{0%{transform:scale(.2);opacity:0}30%{transform:scale(1);opacity:1}45%{transform:scale(1.18)}65%,100%{transform:none;opacity:1}}
.sfx .sp-ring{animation-name:spRing;animation-timing-function:linear}
@keyframes spRing{0%{stroke-dashoffset:0;opacity:0}20%{opacity:1}100%{stroke-dashoffset:-120;opacity:1}}
.sfx .sp-ring.b{animation-name:spRing2}
@keyframes spRing2{0%{stroke-dashoffset:0;opacity:0}20%{opacity:1}100%{stroke-dashoffset:120;opacity:1}}
.sfx .sp-wave{animation-name:burst}

/* Удар тьмы: сгусток пустоты влетает, сжимается, выбрасывает осколки */
.sfx .dk-orb{animation-name:dkOrb;animation-timing-function:cubic-bezier(.6,0,.4,1)}
@keyframes dkOrb{0%{transform:scale(.3);opacity:0}20%{opacity:1}32%{transform:scale(1.1)}42%{transform:scale(.78)}52%{transform:scale(1.18)}66%,100%{transform:none}}
.sfx .dk-trail{animation-name:dkTrail;animation-timing-function:cubic-bezier(.6,0,.4,1)}
@keyframes dkTrail{0%{transform:translate(26px,-26px);opacity:0}10%{opacity:.9}32%{transform:none;opacity:.6}42%,100%{opacity:0}}
.sfx .dk-swirl{animation-name:dkSwirl;animation-timing-function:linear}
@keyframes dkSwirl{0%{transform:rotate(0)}100%{transform:rotate(-300deg)}}
.sfx .dk-sh{animation-name:dkSh}
@keyframes dkSh{0%,44%{transform:translate(0,0) scale(.3);opacity:0}52%{opacity:1}100%{transform:translate(var(--dx),var(--dy)) scale(1);opacity:0}}

/* Лечение и Регенерация маны */
.sfx .hl-cross{animation-name:hlCross}
@keyframes hlCross{0%{transform:scale(.3)}30%{transform:scale(1.18)}45%{transform:none}80%{transform:none}100%{transform:translateY(-10px)}}
.sfx .hl-arrow{animation-name:hlArrow}
@keyframes hlArrow{0%,20%{transform:translateY(12px);opacity:0}45%{opacity:1}100%{transform:translateY(-10px);opacity:0}}
.sfx .mn-cross{animation-name:mnCross;animation-timing-function:cubic-bezier(.2,.6,.3,1)}
@keyframes mnCross{0%{transform:scale(.3) rotate(-270deg)}45%{transform:scale(1.15) rotate(15deg)}58%{transform:rotate(0)}82%{transform:none}100%{transform:translateY(-10px)}}

/* Дожди */
.sfx .rain{animation-name:rain;animation-timing-function:cubic-bezier(.55,0,1,.6);animation-duration:calc(.24s / var(--spd,1))!important}
@keyframes rain{0%{transform:translate(17px,-34px);opacity:0}20%{opacity:1}88%{opacity:1}100%{transform:translate(-1px,2px);opacity:0}}
.sfx .mt{animation-name:rain;animation-timing-function:cubic-bezier(.6,0,1,.5);animation-duration:calc(.22s / var(--spd,1))!important}
.sfx .msp{animation-name:mspark;animation-duration:calc(.24s / var(--spd,1))!important}
@keyframes mspark{0%{transform:scale(.2);opacity:0}30%{opacity:1;transform:scale(1.2)}100%{transform:scale(.6);opacity:0}}
.sfx .r2{animation-delay:calc(.07s / var(--spd,1))}.sfx .r3{animation-delay:calc(.14s / var(--spd,1))}.sfx .r4{animation-delay:calc(.05s / var(--spd,1))}.sfx .r5{animation-delay:calc(.12s / var(--spd,1))}
.sfx .s1{animation-delay:calc(.2s / var(--spd,1))}.sfx .s2{animation-delay:calc(.27s / var(--spd,1))}.sfx .s3{animation-delay:calc(.34s / var(--spd,1))}.sfx .s4{animation-delay:calc(.25s / var(--spd,1))}.sfx .s5{animation-delay:calc(.32s / var(--spd,1))}

/* Угнетение: одна тяжёлая стрела вбивается вниз */
.sfx .dn-arrow{animation-name:dnArrow;animation-timing-function:cubic-bezier(.7,0,.9,.4)}
@keyframes dnArrow{0%{transform:translateY(-26px) scaleY(1.3);opacity:0}12%{opacity:1}30%{transform:translateY(3px) scaleY(.84)}40%{transform:scaleY(1.06)}50%,100%{transform:none}}
.sfx .dn-crack{animation-name:dnCrack;animation-timing-function:ease-out}
@keyframes dnCrack{0%,28%{stroke-dashoffset:30;opacity:1}45%{stroke-dashoffset:0}85%{opacity:1}100%{stroke-dashoffset:0;opacity:0}}
.sfx .dn-drip{animation-name:dnDrip;animation-timing-function:ease-in}
@keyframes dnDrip{0%,38%{transform:translateY(-3px) scaleY(.3);opacity:0}48%{opacity:1;transform:none}100%{transform:translateY(10px) scaleY(1.4);opacity:0}}
.sfx .dn-vein{animation-name:dnVein}
@keyframes dnVein{0%,30%{opacity:.2}40%{opacity:1}55%{opacity:.5}70%{opacity:1}100%{opacity:.8}}

/* Слепота: капля летит, шлёпается кляксой, брызги, потёки */
.sfx .ink-drop{animation-name:inkDrop;animation-timing-function:cubic-bezier(.6,0,.9,.5)}
@keyframes inkDrop{0%{transform:translate(-22px,-26px) scale(.6);opacity:0}10%{opacity:1}28%{transform:none;opacity:1}32%,100%{transform:scale(1.6);opacity:0}}
.sfx .ink-splat{animation-name:inkSplat;animation-timing-function:cubic-bezier(.2,1.5,.4,1)}
@keyframes inkSplat{0%,26%{transform:scale(.15);opacity:0}30%{opacity:1}46%{transform:scale(1.06,.96)}58%,100%{transform:none;opacity:1}}
.sfx .ink-dot{animation-name:inkDot;animation-timing-function:cubic-bezier(.2,.8,.4,1)}
@keyframes inkDot{0%,27%{transform:translate(calc(var(--dx) * -3),calc(var(--dy) * -3)) scale(.2);opacity:0}34%{opacity:1}55%,100%{transform:none;opacity:1}}
.sfx .ink-drip{animation-name:inkDrip;animation-timing-function:ease-in;transform-origin:top}
@keyframes inkDrip{0%,32%{transform:scaleY(0);opacity:0}38%{opacity:1}78%,100%{transform:scaleY(1);opacity:1}}

/* Ослабление: клинок ломается */
.sfx .wk-tip{animation-name:wkTip;animation-timing-function:cubic-bezier(.5,0,.8,.6)}
@keyframes wkTip{0%,36%{transform:none;opacity:1}44%{transform:translate(1px,-3px) rotate(4deg)}100%{transform:translate(9px,18px) rotate(70deg);opacity:0}}
.sfx .wk-hilt{animation-name:wkHilt}
@keyframes wkHilt{0%,36%{transform:none}46%{transform:translateY(2px) rotate(-6deg)}60%,100%{transform:translateY(1px) rotate(-3deg)}}
.sfx .wk-spark{animation-name:wkSpark}
@keyframes wkSpark{0%,32%{transform:scale(.1);opacity:0}40%{transform:scale(1.3) rotate(20deg);opacity:1}70%,100%{transform:scale(.4) rotate(45deg);opacity:0}}
.sfx .wk-shake{animation-name:wkShake}
@keyframes wkShake{0%{transform:scale(.6);opacity:0}14%{transform:none;opacity:1}22%{transform:rotate(-3deg)}28%{transform:rotate(3deg)}34%{transform:rotate(-2deg)}40%,100%{transform:none}}

/* Проклятие: тяжёлый череп, глаза вспыхивают */
.sfx .cu-skull{animation-name:cuSkull;animation-timing-function:cubic-bezier(.7,0,.4,1)}
@keyframes cuSkull{0%{transform:scale(1.7);opacity:0}28%{transform:scale(.93);opacity:1}38%{transform:scale(1.04)}48%,100%{transform:none;opacity:1}}
.sfx .cu-eye{animation-name:cuEye}
@keyframes cuEye{0%,30%{transform:scale(.2);opacity:0}44%{transform:scale(1.7);opacity:1}56%{transform:scale(.9)}66%{transform:scale(1.2)}80%,100%{transform:none;opacity:1}}
.sfx .cu-aura{animation-name:cuAura}
@keyframes cuAura{0%,20%{transform:scale(.3);opacity:0}40%{transform:scale(1.15);opacity:1}60%{transform:scale(.95)}100%{transform:none;opacity:.9}}

/* Ужас */
.sfx .te-face{animation-name:teFace}
@keyframes teFace{0%{transform:scale(.4);opacity:0}25%{transform:scale(1.3);opacity:1}35%{transform:scale(1) translateX(-2px)}42%{transform:translateX(2px)}49%{transform:translateX(-2px)}56%{transform:translateX(1px)}64%,100%{transform:none}}

/* Вампиризм */
.sfx .vp-top{animation-name:vpTop;animation-timing-function:cubic-bezier(.8,0,.6,1.4)}
@keyframes vpTop{0%,22%{transform:translateY(-11px)}40%{transform:translateY(2px)}52%,100%{transform:none}}
.sfx .vp-bot{animation-name:vpBot;animation-timing-function:cubic-bezier(.8,0,.6,1.4)}
@keyframes vpBot{0%,22%{transform:translateY(11px)}40%{transform:translateY(-2px)}52%,100%{transform:none}}
.sfx .vp-drip{animation-name:vpDrip}
@keyframes vpDrip{0%,42%{transform:translateY(-4px) scale(.3);opacity:0}52%{opacity:1;transform:none}100%{transform:translateY(12px);opacity:0}}

/* Песни: нота подпрыгивает, предмет вспыхивает рядом */
.sfx .sg-note{animation-name:sgNote;animation-timing-function:ease-out}
@keyframes sgNote{0%{transform:translateY(10px) scale(.4);opacity:0}22%{transform:translateY(-4px) scale(1.1) rotate(-10deg);opacity:1}42%{transform:rotate(7deg)}60%{transform:translateY(-1px) rotate(-3deg)}78%,100%{transform:none}}
.sfx .sg-item{animation-name:sgItem;animation-timing-function:cubic-bezier(.3,1.6,.5,1)}
@keyframes sgItem{0%,18%{transform:scale(0);opacity:0}40%{transform:scale(1);opacity:1}100%{transform:none}}

/* Воскрешение: два крыла раскрываются в свете */
.sfx .rs-wr{animation-name:rsWr;animation-timing-function:cubic-bezier(.3,1.3,.5,1)}
@keyframes rsWr{0%{transform:rotate(70deg) scale(.5);opacity:0}38%{transform:rotate(-8deg) scale(1.04);opacity:1}54%{transform:rotate(3deg)}70%,100%{transform:none}}
.sfx .rs-wl{animation-name:rsWl;animation-timing-function:cubic-bezier(.3,1.3,.5,1)}
@keyframes rsWl{0%{transform:rotate(-70deg) scale(.5);opacity:0}38%{transform:rotate(8deg) scale(1.04);opacity:1}54%{transform:rotate(-3deg)}70%,100%{transform:none}}
.sfx .rs-light{animation-name:rsLight}
@keyframes rsLight{0%,20%{transform:scale(.2);opacity:0}45%{transform:scale(1.2);opacity:1}100%{transform:none;opacity:.85}}

/* Вампиризм: глаза, вспышка, пасть */
.sfx .vp-eyes{animation-name:vpEyes}
@keyframes vpEyes{0%{opacity:0;transform:scaleY(.2)}20%{opacity:1;transform:none}70%{opacity:1}100%{opacity:0}}
.sfx .vp-cav{animation-name:vpCav;animation-timing-function:cubic-bezier(.8,0,.6,1.4)}
@keyframes vpCav{0%,22%{transform:scaleY(1.9)}40%{transform:scaleY(.25)}52%,100%{transform:scaleY(.3)}}
.sfx .vp-flash{animation-name:vpFlash}
@keyframes vpFlash{0%,36%{transform:scale(.4);opacity:0}46%{transform:scale(1.05);opacity:1}100%{transform:scale(1.2);opacity:0}}
/* Призыв скелета: могила шевелится, костяная рука выбирается наружу */
.sfx .sk-hand{animation-name:skHand;animation-timing-function:cubic-bezier(.3,1.25,.5,1)}
@keyframes skHand{0%,12%{transform:translateY(30px)}52%{transform:translateY(-2px)}64%{transform:rotate(-4deg)}78%{transform:rotate(3deg)}100%{transform:none}}
.sfx .sk-mound{animation-name:skMound}
@keyframes skMound{0%{transform:scale(.7);opacity:0}10%{transform:none;opacity:1}16%{transform:translateX(-1.5px)}22%{transform:translateX(1.5px)}28%{transform:translate(-1px,-1px)}34%{transform:translateY(-2px) scaleY(1.06)}44%,100%{transform:none}}
.sfx .sk-dirt{animation-name:skDirt;animation-timing-function:cubic-bezier(.2,.8,.5,1)}
@keyframes skDirt{0%,26%{transform:translate(0,0) scale(.4);opacity:0}32%{opacity:1}70%{transform:translate(var(--dx),var(--dy)) scale(1)}100%{transform:translate(var(--dx),calc(var(--dy) + 9px)) scale(.8);opacity:0}}
.sfx .sk-glow{animation-name:skGlow}
@keyframes skGlow{0%,20%{transform:scale(.3);opacity:0}40%{transform:scale(1.1);opacity:1}100%{transform:scale(1.2);opacity:0}}

/* Огненный шар */
.sfx .fb-ball{animation-name:fbBall;animation-timing-function:ease-in-out}
@keyframes fbBall{0%{transform:scale(.3);opacity:0}18%{opacity:1}30%{transform:scale(1.12)}38%{transform:scale(.82);opacity:1}48%,100%{transform:scale(1.5);opacity:0}}
.sfx .fb-boom{animation-name:fbBoom;animation-timing-function:ease-out}
@keyframes fbBoom{0%,38%{transform:scale(.2);opacity:0}52%{transform:scale(1.05);opacity:1}75%{opacity:.85}100%{transform:scale(1.3);opacity:0}}
/* Огненный дождь: три метеора, малые взрывы, большой взрыв в конце */
.sfx .fr-big{animation-name:frBig;animation-delay:calc(.3s / var(--spd,1));animation-duration:calc(.3s / var(--spd,1))!important;animation-timing-function:ease-out}
@keyframes frBig{0%{transform:scale(.25);opacity:0}25%{transform:scale(1.05);opacity:1}60%{opacity:.9}100%{transform:scale(1.3);opacity:0}}
/* Проклятие: печать впечатывается, щит раскалывается */
.sfx .cs-seal{animation-name:csSeal;animation-timing-function:cubic-bezier(.6,0,.4,1)}
@keyframes csSeal{0%{transform:scale(1.6) rotate(-40deg);opacity:0}30%{transform:scale(.94) rotate(0);opacity:1}40%{transform:scale(1.03)}50%,100%{transform:none;opacity:1}}
.sfx .cs-runes{animation-name:csRunes;animation-timing-function:linear}
@keyframes csRunes{0%{transform:rotate(0)}100%{transform:rotate(120deg)}}
.sfx .cs-shL{animation-name:csShL}.sfx .cs-shR{animation-name:csShR}
@keyframes csShL{0%,20%{transform:scale(.4);opacity:0}32%{transform:none;opacity:1}46%{transform:none}100%{transform:translate(5px,4px) rotate(14deg);opacity:.85}}
@keyframes csShR{0%,20%{transform:scale(.4);opacity:0}32%{transform:none;opacity:1}46%{transform:none}100%{transform:translate(-5px,4px) rotate(-14deg);opacity:.85}}
.sfx .cs-flash{animation-name:wkSpark;animation-delay:calc(.08s / var(--spd,1))}

/* Жертва: капля падает, плющится, брызги */
.sfx .sc-drop{animation-name:scDrop;animation-timing-function:cubic-bezier(.55,0,.9,.5)}
@keyframes scDrop{0%{transform:translateY(-22px) scale(.7);opacity:0}12%{opacity:1}34%{transform:none}42%{transform:scale(1.15,.8) translateY(4px);opacity:1}50%,100%{transform:scale(1.3,.4) translateY(14px);opacity:0}}
.sfx .sc-splat{animation-name:scSplat;animation-timing-function:cubic-bezier(.2,1.4,.4,1)}
@keyframes scSplat{0%,38%{transform:scale(.1);opacity:0}44%{opacity:1}60%,100%{transform:none;opacity:1}}
.sfx .sc-dot{animation-name:scDot;animation-timing-function:cubic-bezier(.2,.8,.4,1)}
@keyframes scDot{0%,38%{transform:translate(0,0) scale(.3);opacity:0}46%{opacity:1}75%{transform:translate(var(--dx),var(--dy)) scale(1)}100%{transform:translate(var(--dx),calc(var(--dy) + 8px));opacity:0}}
/* Костяная стрела: замах, удар, трещина, осколки */
.sfx .bn-bone{animation-name:bnBone;animation-timing-function:cubic-bezier(.7,0,.6,1.3)}
@keyframes bnBone{0%{transform:rotate(-75deg);opacity:0}12%{opacity:1}34%{transform:rotate(8deg)}44%{transform:rotate(-4deg)}54%,100%{transform:none}}
.sfx .bn-hit{animation-name:wkSpark;animation-delay:calc(.04s / var(--spd,1))}
.sfx .bn-crack{animation-name:bnCrack}
@keyframes bnCrack{0%,34%{opacity:0}40%,100%{opacity:1}}
.sfx .bn-chip{animation-name:scDot}
/* Паутина: нити разбегаются от центра, кольца прорисовываются, сеть вздрагивает */
.sfx .wb-rays{animation-name:wbRays;animation-timing-function:ease-out}
@keyframes wbRays{0%{stroke-dashoffset:26}35%,100%{stroke-dashoffset:0}}
.sfx .wb-ring{animation-name:wbRing;animation-timing-function:ease-out}
@keyframes wbRing{0%,15%{stroke-dashoffset:var(--l,160);opacity:0}20%{opacity:1}55%,100%{stroke-dashoffset:0;opacity:1}}
.sfx .wb-net{animation-name:wbNet}
@keyframes wbNet{0%,50%{transform:scale(1.15)}60%{transform:scale(.94)}72%{transform:scale(1.03)}84%,100%{transform:none}}
.sfx .wb-hit{animation-name:wkSpark}
/* Цепная молния: вспышка, на каждой следующей цели меньше и позже */
.sfx .cl-glow{animation-name:clGlow}
@keyframes clGlow{0%{transform:scale(.2);opacity:0}15%{transform:scale(1.15);opacity:1}30%{opacity:.5}42%{opacity:1}60%{transform:none;opacity:.8}100%{transform:scale(.9);opacity:0}}
.sfx .cl-star{animation-name:clStar;animation-timing-function:ease-out}
@keyframes clStar{0%{transform:scale(.1) rotate(-20deg);opacity:0}14%{transform:scale(1.2);opacity:1}26%{transform:scale(.85) rotate(8deg);opacity:.6}38%{transform:scale(1.05);opacity:1}100%{transform:scale(.7) rotate(15deg);opacity:0}}
.sfx .cl-arcs{animation-name:clArcs;animation-timing-function:steps(1)}
@keyframes clArcs{0%{opacity:0}12%{opacity:1}22%{opacity:0}30%{opacity:1;transform:rotate(25deg)}44%{opacity:0}52%{opacity:.8;transform:rotate(-15deg)}70%,100%{opacity:0}}
.sfx .cl-core{animation-name:clCore}
@keyframes clCore{0%{transform:scale(0)}12%{transform:scale(1.4)}40%{transform:scale(.8)}100%{transform:scale(.3);opacity:0}}

