/* ═══════════════════════════════════════════
   动画系统 v2.0
   ═══════════════════════════════════════════ */
@keyframes fadeIn { from{opacity:0} to{opacity:1} }
@keyframes fadeOut { from{opacity:1} to{opacity:0} }
@keyframes slideUp { from{opacity:0;transform:translateY(24px)} to{opacity:1;transform:translateY(0)} }
@keyframes slideDown { from{opacity:0;transform:translateY(-16px)} to{opacity:1;transform:translateY(0)} }
@keyframes scaleIn { from{opacity:0;transform:scale(.8)} to{opacity:1;transform:scale(1)} }
@keyframes modalSlideIn { from{opacity:0;transform:scale(.9) translateY(16px)} to{opacity:1;transform:scale(1) translateY(0)} }
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.3}}
@keyframes pulseRing{0%{box-shadow:0 0 0 0 rgba(91,79,207,.4)}70%{box-shadow:0 0 0 12px rgba(91,79,207,0)}100%{box-shadow:0 0 0 0 rgba(91,79,207,0)}}
@keyframes breathe{0%,100%{transform:scale(1)}50%{transform:scale(1.04)}}
@keyframes softGlow{0%,100%{filter:brightness(1) drop-shadow(0 0 4px rgba(255,215,0,.3))}50%{filter:brightness(1.15) drop-shadow(0 0 16px rgba(255,215,0,.6))}}
@keyframes toastIn{0%{opacity:0;transform:translateX(-50%) scale(.4) translateY(20px)}60%{transform:translateX(-50%) scale(1.06) translateY(-4px)}100%{opacity:1;transform:translateX(-50%) scale(1) translateY(0)}}
@keyframes toastOut{from{opacity:1;transform:translateX(-50%) scale(1)}to{opacity:0;transform:translateX(-50%) scale(.8) translateY(-10px)}}
.toast.removing{animation:toastOut .25s ease forwards}
@keyframes petFloat{0%,100%{transform:translateY(0) rotate(0deg)}25%{transform:translateY(-6px) rotate(-1deg)}75%{transform:translateY(-3px) rotate(1deg)}}
@keyframes evolveGlow{0%{box-shadow:0 0 8px rgba(255,107,157,.3),inset 0 0 8px rgba(255,215,0,.2)}25%{box-shadow:0 0 32px rgba(255,107,157,.7),0 0 64px rgba(255,215,0,.4),inset 0 0 16px rgba(255,215,0,.3)}50%{box-shadow:0 0 16px rgba(176,124,216,.5),0 0 48px rgba(93,173,226,.4),inset 0 0 12px rgba(255,215,0,.2)}75%{box-shadow:0 0 32px rgba(255,107,157,.7),0 0 64px rgba(255,215,0,.4),inset 0 0 16px rgba(255,215,0,.3)}100%{box-shadow:0 0 8px rgba(255,107,157,.3),inset 0 0 8px rgba(255,215,0,.2)}}
.pet-evolving{animation:evolveGlow .8s ease-in-out 4}
@keyframes chargeRight{0%{transform:translateX(0) scale(1)}40%{transform:translateX(60px) scale(1.25)}100%{transform:translateX(0) scale(1)}}
@keyframes chargeLeft{0%{transform:translateX(0) scale(1)}40%{transform:translateX(-60px) scale(1.25)}100%{transform:translateX(0) scale(1)}}
@keyframes hitShake{0%,100%{transform:translateX(0)}15%{transform:translateX(-10px) rotate(-3deg)}30%{transform:translateX(8px) rotate(2deg)}45%{transform:translateX(-6px) rotate(-1deg)}60%{transform:translateX(4px)}75%{transform:translateX(-2px)}}
@keyframes hitFlash{0%{filter:brightness(1)}30%{filter:brightness(2.5) saturate(0)}100%{filter:brightness(1)}}
@keyframes critBurst{0%{transform:scale(0);opacity:1}50%{transform:scale(2.5);opacity:.8}100%{transform:scale(3);opacity:0}}
@keyframes dmgFloat{0%{opacity:1;transform:translateY(0) scale(.5)}20%{opacity:1;transform:translateY(-20px) scale(1.3)}100%{opacity:0;transform:translateY(-70px) scale(1)}}
@keyframes dmgCritFloat{0%{opacity:1;transform:translateY(0) scale(.3) rotate(-10deg)}30%{opacity:1;transform:translateY(-30px) scale(1.8) rotate(5deg)}100%{opacity:0;transform:translateY(-90px) scale(1.2) rotate(0deg)}}
@keyframes monsterDefeat{0%{opacity:1;transform:scale(1) rotate(0)}30%{opacity:.7;transform:scale(1.1) rotate(15deg)}100%{opacity:0;transform:scale(.1) rotate(360deg) translateY(60px)}}
@keyframes victoryJump{0%,100%{transform:scale(1) translateY(0)}30%{transform:scale(1.3) translateY(-30px)}50%{transform:scale(.95) translateY(-5px)}70%{transform:scale(1.15) translateY(-18px)}90%{transform:scale(1.02) translateY(-2px)}}
@keyframes particleBurst{0%{transform:translate(0,0) scale(1);opacity:1}100%{transform:translate(var(--px),var(--py)) scale(0);opacity:0}}
@keyframes coinFly{0%{opacity:0;transform:translateY(20px) scale(.3)}40%{opacity:1;transform:translateY(-30px) scale(1.2)}100%{opacity:0;transform:translateY(-80px) scale(.6)}}
@keyframes confettiFall{0%{transform:translateY(-30px) rotate(0deg) scale(1);opacity:1}80%{opacity:.8}100%{transform:translateY(105vh) rotate(720deg) scale(.3);opacity:0}}
@keyframes shimmer{0%{transform:translateX(-100%)}100%{transform:translateX(200%)}}
@keyframes spin{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}
@keyframes bounceIn{0%{transform:scale(0)}50%{transform:scale(1.15)}70%{transform:scale(.95)}100%{transform:scale(1)}}
@keyframes costumeSnap{0%{transform:scale(1)}50%{transform:scale(1.15)}100%{transform:scale(1)}}
@keyframes checkinPop{0%{transform:scale(0)}60%{transform:scale(1.2)}100%{transform:scale(1)}}
@keyframes rankUp{0%{background:transparent}50%{background:rgba(240,192,64,.3)}100%{background:transparent}}
.page-enter{animation:slideUp .35s cubic-bezier(.4,0,.2,1)}
