/* ===== All @keyframes ===== */

/* Shake word stage on wrong answer */
@keyframes shake {
  0%,100% { transform: translateX(-50%); }
  20% { transform: translateX(calc(-50% - 14px)); }
  40% { transform: translateX(calc(-50% + 14px)); }
  60% { transform: translateX(calc(-50% - 9px)); }
  80% { transform: translateX(calc(-50% + 9px)); }
}

/* Sign pop-in */
@keyframes bIn {
  0% { transform: scale(.4); opacity: 0; }
  60% { transform: scale(1.08); opacity: 1; }
  100% { transform: scale(1); }
}

/* Final word golden pulse */
@keyframes finalPulse {
  from { box-shadow: inset 0 2px 0 rgba(255,255,255,.08),inset 0 -3px 0 rgba(0,0,0,.6),0 0 26px rgba(255,215,0,.6),0 10px 26px rgba(0,0,0,.55); }
  to { box-shadow: inset 0 2px 0 rgba(255,255,255,.08),inset 0 -3px 0 rgba(0,0,0,.6),0 0 54px rgba(255,215,0,.95),0 10px 26px rgba(0,0,0,.55); }
}

/* Slot burst */
@keyframes slotBurst {
  0% { transform: translateY(0) scale(1); opacity: 1; }
  100% { transform: translateY(-26px) scale(1.7) rotate(40deg); opacity: 0; }
}

/* Timer number pulse */
@keyframes numPulse {
  from { transform: scale(1); }
  to { transform: scale(1.22); }
}

/* Combo fire */
@keyframes comboFire {
  from { transform: scale(1); }
  to { transform: scale(1.12); }
}

/* Character bob */
@keyframes charBob {
  from { transform: translateY(0); }
  to { transform: translateY(-3px); }
}

/* Board tilt */
@keyframes boardTilt {
  from { transform: rotate(-5deg); }
  to { transform: rotate(5deg); }
}

/* Glide bob */
@keyframes glideBob {
  from { transform: translateY(0) rotate(-3deg); }
  to { transform: translateY(-14px) rotate(3deg); }
}

/* Jet bob */
@keyframes jetBob {
  from { transform: translateY(0); }
  to { transform: translateY(-5px); }
}

/* Jump */
@keyframes charJump {
  0% { transform: translateY(0); }
  38% { transform: translateY(-120px) rotate(-4deg); }
  62% { transform: translateY(-120px); }
  100% { transform: translateY(0); }
}

/* Fly */
@keyframes charFly {
  0% { transform: translateY(0); }
  16% { transform: translateY(-22vh); }
  55% { transform: translateY(-24vh); }
  80% { transform: translateY(-21vh); }
  100% { transform: translateY(0); }
}

/* Flip */
@keyframes charFlip {
  0% { transform: translateY(0) rotate(0); }
  32% { transform: translateY(-92px) rotate(-190deg); }
  64% { transform: translateY(-70px) rotate(-330deg); }
  100% { transform: translateY(0) rotate(-360deg); }
}

/* Double jump */
@keyframes charDjump {
  0% { transform: translateY(0); }
  24% { transform: translateY(-78px); }
  46% { transform: translateY(0); }
  64% { transform: translateY(-48px); }
  100% { transform: translateY(0); }
}

/* Die */
@keyframes charDie {
  0% { transform: translateY(0); }
  18% { transform: translateY(-110px); }
  100% { transform: translateY(62vh) rotate(720deg); opacity: .9; }
}

/* Dragon companion patrols around its fixed gameplay anchor. */
@keyframes dragonEscortFlight {
  0%,100% { transform: translate3d(0,4px,0) rotate(-2deg) scale(.98); }
  16% { transform: translate3d(20px,-15px,0) rotate(.8deg) scale(1.015); }
  32% { transform: translate3d(52px,-6px,0) rotate(2.8deg) scale(1.045); }
  47% { transform: translate3d(37px,15px,0) rotate(-1.4deg) scale(.985); }
  63% { transform: translate3d(7px,20px,0) rotate(-3deg) scale(.95); }
  79% { transform: translate3d(29px,-13px,0) rotate(1deg) scale(1.01); }
  91% { transform: translate3d(58px,-25px,0) rotate(3.5deg) scale(1.055); }
}

@keyframes dragonDarkPatrol {
  0%,100% { transform: translate3d(4px,5px,0) rotate(-2.4deg) scale(.98); }
  19% { transform: translate3d(62px,-28px,0) rotate(4deg) scale(1.06); }
  38% { transform: translate3d(25px,-17px,0) rotate(-2deg) scale(.98); }
  58% { transform: translate3d(74px,12px,0) rotate(-4.2deg) scale(1.04); }
  77% { transform: translate3d(34px,-9px,0) rotate(1.4deg) scale(.97); }
  89% { transform: translate3d(12px,-23px,0) rotate(-2deg) scale(1.015); }
}

@keyframes dragonTransformOrbit {
  0%,100% { transform: translate3d(8px,3px,0) rotate(-2deg) scale(.98); }
  25% { transform: translate3d(43px,-26px,0) rotate(4deg) scale(1.06); }
  50% { transform: translate3d(72px,1px,0) rotate(-3deg) scale(1.11); }
  75% { transform: translate3d(31px,21px,0) rotate(3deg) scale(1.03); }
}

@keyframes swordEscortFlight {
  0%,100% { transform: translate3d(6px,2px,0) rotate(-3deg) scale(.96); }
  17% { transform: translate3d(70px,-25px,0) rotate(2.5deg) scale(1.04); }
  34% { transform: translate3d(40px,-12px,0) rotate(-1deg) scale(.98); }
  50% { transform: translate3d(96px,10px,0) rotate(4.5deg) scale(1.09); }
  65% { transform: translate3d(55px,-31px,0) rotate(-4deg) scale(.99); }
  82% { transform: translate3d(17px,-4px,0) rotate(1deg) scale(.95); }
}

/* An occasional independent burst: the visual rig travels while #brick stays fixed. */
@keyframes dragonForwardRush {
  0% { transform: translate3d(12px,0,0) rotate(-1deg) scale(.99); filter: brightness(1); }
  8% { transform: translate3d(-24px,7px,0) rotate(-4deg) scale(.94); filter: brightness(.94); }
  18% { transform: translate3d(46px,-11px,0) rotate(1deg) scale(1.02); filter: brightness(1.18); }
  39% { transform: translate3d(clamp(180px,52vw,780px),-38px,0) rotate(4.5deg) scale(1.1); filter: brightness(1.62) saturate(1.25); }
  48% { transform: translate3d(clamp(214px,calc(52vw + 34px),814px),-31px,0) rotate(2deg) scale(1.06); filter: brightness(1.36); }
  58% { transform: translate3d(clamp(168px,calc(52vw - 12px),768px),-20px,0) rotate(-1deg) scale(1.03); filter: brightness(1.2); }
  76% { transform: translate3d(58px,13px,0) rotate(-3deg) scale(.97); filter: brightness(1.06); }
  89% { transform: translate3d(-13px,-8px,0) rotate(1.5deg) scale(.96); filter: brightness(1); }
  100% { transform: translate3d(0,4px,0) rotate(-2deg) scale(.98); filter: brightness(1); }
}

@keyframes swordForwardRush {
  0% { transform: translate3d(7px,1px,0) rotate(-3deg) scale(.96); filter: brightness(1); }
  7% { transform: translate3d(-32px,8px,0) rotate(-6deg) scale(.89); filter: brightness(.92); }
  17% { transform: translate3d(76px,-14px,0) rotate(1deg) scale(1.03); filter: brightness(1.35); }
  34% { transform: translate3d(clamp(210px,58vw,860px),-46px,0) rotate(6deg) scale(1.15); filter: brightness(2.05) saturate(1.45); }
  43% { transform: translate3d(clamp(268px,calc(58vw + 58px),918px),-37px,0) rotate(3deg) scale(1.08); filter: brightness(1.62); }
  54% { transform: translate3d(clamp(190px,calc(58vw - 20px),840px),-23px,0) rotate(-2deg) scale(1.04); filter: brightness(1.34); }
  73% { transform: translate3d(78px,14px,0) rotate(-5deg) scale(.94); filter: brightness(1.12); }
  87% { transform: translate3d(-17px,-9px,0) rotate(2deg) scale(.92); filter: brightness(1); }
  100% { transform: translate3d(6px,2px,0) rotate(-3deg) scale(.96); filter: brightness(1); }
}

@keyframes dragonRushShockRing {
  0%,12% { opacity: 0; transform: translateX(-30px) scale(.28,.62); }
  20% { opacity: .92; transform: translateX(8px) scale(.72,.86); }
  37% { opacity: 1; transform: translateX(28px) scale(1.18,1.08); }
  52% { opacity: 0; transform: translateX(54px) scale(1.75,1.42); }
  100% { opacity: 0; transform: translateX(54px) scale(1.75,1.42); }
}

@keyframes dragonRushEnergyCone {
  0%,8% { opacity: 0; transform: translateX(46px) scaleX(.3); }
  18% { opacity: .82; transform: translateX(10px) scaleX(.72); }
  38% { opacity: .94; transform: translateX(-24px) scaleX(1.32); }
  56% { opacity: .42; transform: translateX(-42px) scaleX(1.7); }
  73%,100% { opacity: 0; transform: translateX(-68px) scaleX(1.9); }
}

@keyframes dragonWakeLine {
  0% { opacity: 0; transform: translateX(16px) scaleX(.2); }
  18% { opacity: .9; }
  72% { opacity: .42; }
  100% { opacity: 0; transform: translateX(-76px) scaleX(1.2); }
}

@keyframes dragonWakeArc {
  0%,100% { opacity: .15; scale: .72 .86; }
  42% { opacity: .75; scale: 1 .98; }
  70% { opacity: .32; scale: .9 1.05; }
}

@keyframes dragonWakeBreath {
  from { opacity: .38; transform: translateX(7px) scaleX(.92); }
  to { opacity: .72; transform: translateX(-3px) scaleX(1.06); }
}

@keyframes dragonAuraPulse {
  0%,100% { opacity: .52; transform: perspective(130px) rotateX(58deg) scale(.93); }
  50% { opacity: .96; transform: perspective(130px) rotateX(58deg) scale(1.07); }
}

@keyframes dragonTailParticle {
  0% { opacity: 0; transform: translate(10px,0) scale(.3); }
  12% { opacity: .95; }
  68% { opacity: .74; }
  100% { opacity: 0; transform: translate(var(--particle-dx),var(--particle-dy)) scale(.08); }
}

@keyframes dragonMagicParticle {
  0% { opacity: 0; transform: translate(0,10px) scale(.24) rotate(0); }
  17% { opacity: .95; }
  64% { opacity: .72; }
  100% { opacity: 0; transform: translate(var(--magic-dx),var(--magic-dy)) scale(.1) rotate(var(--magic-turn)); }
}

@keyframes dragonMagicBreath {
  0%,100% { opacity: .22; transform: scale(.94); }
  50% { opacity: .48; transform: scale(1.05); }
}

/* Dragon darts toward the answer impact, then returns to escort position. */
@keyframes dragonStrike {
  0% { transform: translate(0,0) scale(1); }
  18% { transform: translate(-8px,5px) scale(.98) rotate(-2deg); }
  48% { transform: translate(58px,-22px) scale(1.08) rotate(3deg); }
  100% { transform: translate(0,0) scale(1); }
}

@keyframes swordStrike {
  0% { transform: translate3d(0,0,0) scale(1); filter: brightness(1); }
  16% { transform: translate3d(-18px,7px,0) scale(.96) rotate(-3deg); }
  44% { transform: translate3d(115px,-25px,0) scale(1.08) rotate(4deg); filter: brightness(1.75); }
  65% { transform: translate3d(76px,-12px,0) scale(1.03) rotate(1deg); filter: brightness(1.3); }
  100% { transform: translate3d(0,0,0) scale(1); filter: brightness(1); }
}

/* Danger is carried by the dragon's motion instead of a glowing square. */
@keyframes dragonDangerPulse {
  0%,100% { transform: translateY(0) scale(1); filter: drop-shadow(0 0 5px rgba(255,45,35,.48)); }
  50% { transform: translateY(-5px) scale(1.055); filter: drop-shadow(0 0 15px rgba(255,45,35,.92)); }
}

/* Urgent timer flutter. */
@keyframes dragonUrgent {
  0%,100% { transform: translate(0,0); }
  50% { transform: translate(2px,-1px) rotate(-1deg); }
}

/* Coin fly */
@keyframes coinFlyA {
  0% { transform: translate(0,0) scale(1); opacity: 1; }
  20% { transform: translate(0,-72px) scale(1.2); opacity: 1; }
  100% { transform: translate(var(--fx,0px),var(--fy,-120px)) scale(.35); opacity: .85; }
}

/* Coin drop (missed) */
@keyframes coinDropA {
  0% { transform: translate(0,0); }
  34% { transform: translate(9px,var(--gy,200px)); }
  52% { transform: translate(15px,calc(var(--gy,200px) - 44px)); }
  72% { transform: translate(21px,var(--gy,200px)); }
  86% { transform: translate(25px,calc(var(--gy,200px) - 16px)); }
  100% { transform: translate(28px,var(--gy,200px)); opacity: 0; }
}

/* Dust puff */
@keyframes dustPuff {
  0% { transform: translate(0,0) scale(1); opacity: .8; }
  100% { transform: translate(-26px,-14px) scale(2.4); opacity: 0; }
}

/* Flame */
@keyframes flameGo {
  0% { transform: translate(0,0) scale(1); opacity: .95; }
  100% { transform: translate(var(--dx,0px),28px) scale(.3); opacity: 0; }
}

/* Qt-Gaming animated WebP overlays */
@keyframes qtImpactFade {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(.58); }
  12% { opacity: 1; transform: translate(-50%, -50%) scale(1); }
  78% { opacity: 1; }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(1.12); }
}

@keyframes qtBombFade {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(.48); }
  10% { opacity: 1; }
  76% { opacity: 1; transform: translate(-50%, -50%) scale(1.05); }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(1.18); }
}

@keyframes qtEvolutionBombFade {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(.34) rotate(-12deg); }
  12% { opacity: 1; transform: translate(-50%, -50%) scale(.92) rotate(4deg); }
  34% { transform: translate(-50%, -50%) scale(1.08) rotate(-3deg); }
  76% { opacity: 1; transform: translate(-50%, -50%) scale(1.02) rotate(7deg); }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(1.24) rotate(18deg); }
}

@keyframes qtFireFly {
  0% { opacity: 0; transform: translate(-50%, -50%) translate(0, 0) scale(.62); }
  12% { opacity: 1; }
  72% { opacity: 1; }
  100% { opacity: 0; transform: translate(-50%, -50%) translate(var(--dx), var(--dy)) scale(1); }
}

/* UFO */
@keyframes ufoFly {
  0% { transform: translate(-60px,0); }
  50% { transform: translate(50vw,-14px); }
  100% { transform: translate(calc(100vw + 60px),4px); }
}
@keyframes ufoFlyB {
  0% { transform: translate(-60px,0); }
  34% { transform: translate(38vw,-10px); }
  58% { transform: translate(38vw,-10px); }
  100% { transform: translate(calc(100vw + 60px),6px); }
}

/* Beam */
@keyframes beamOn {
  0% { opacity: 0; }
  12% { opacity: 1; }
  80% { opacity: 1; }
  100% { opacity: 0; }
}

/* Cow abduction */
@keyframes cowUp {
  0% { transform: translateY(0) rotate(0); opacity: 1; }
  70% { opacity: 1; }
  100% { transform: translateY(var(--rise,-200px)) rotate(25deg); opacity: 0; }
}

/* Knight bubble */
@keyframes bubIn {
  0% { opacity: 0; transform: translateY(8px) scale(.6); }
  15% { opacity: 1; transform: translateY(0) scale(1); }
  78% { opacity: 1; }
  100% { opacity: 0; transform: translateY(-12px); }
}

/* Ghost float */
@keyframes ghostUp {
  0% { transform: translateY(0); opacity: 0; }
  12% { opacity: .72; }
  100% { transform: translateY(-170px); opacity: 0; }
}

/* Score pop */
@keyframes scorePop {
  0% { transform: scale(1); }
  40% { transform: scale(1.35) rotate(-3deg); }
  100% { transform: scale(1); }
}

/* Floating text */
@keyframes ftUp {
  0% { opacity: 0; transform: translate(-50%,0) scale(.55); }
  14% { opacity: 1; transform: translate(-50%,-8px) scale(1.18); }
  30% { transform: translate(-50%,-14px) scale(1); }
  100% { opacity: 0; transform: translate(-50%,-64px) scale(.96); }
}

/* Big text */
@keyframes fbFloatBig {
  0% { opacity: 0; transform: translateX(-50%) scale(.4); }
  18% { opacity: 1; transform: translateX(-50%) scale(1.15); }
  30% { transform: translateX(-50%) scale(1); }
  100% { opacity: 0; transform: translateX(-50%) translateY(-30px) scale(1.05); }
}

/* Vignette danger pulse */
@keyframes vgPulse {
  0%,100% { opacity: .3; }
  50% { opacity: .85; }
}

/* Title card */
@keyframes tcIn {
  0% { opacity: 0; transform: scale(2.6); filter: blur(10px); }
  16% { opacity: 1; transform: scale(1); filter: blur(0); }
  76% { opacity: 1; transform: scale(1); }
  100% { opacity: 0; transform: scale(.9); }
}

/* READY pop */
@keyframes rdyPop {
  0% { transform: scale(.3); opacity: 0; }
  60% { transform: scale(1.14); }
  100% { transform: scale(1); opacity: 1; }
}

/* Fade in */
@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

/* Caret blink */
@keyframes blink {
  50% { opacity: 0; }
}

/* Review card flip */
@keyframes cardFlip {
  0% { transform: rotateY(88deg); opacity: .3; }
  100% { transform: rotateY(0); opacity: 1; }
}

/* Logo float */
@keyframes logoFloat {
  0%,100% { transform: translateY(0); }
  50% { transform: translateY(-10px); }
}

/* Distance milestone pop */
@keyframes milePop {
  0% { transform: scale(1); }
  30% { transform: scale(1.4) rotate(-2deg); }
  60% { transform: scale(.96); }
  100% { transform: scale(1); }
}

/* v8 new animations */
@keyframes daolangSweep {
  0% { transform: translateX(-100%); opacity: 1; }
  50% { opacity: 1; }
  100% { transform: translateX(100%); opacity: 0; }
}

@keyframes vortexExpand {
  0% { width: 0; height: 0; opacity: 1; }
  100% { width: 200vmax; height: 200vmax; opacity: 0; }
}

@keyframes edgeFrost {
  0% { border-color: rgba(140,200,255,.5); box-shadow: inset 0 0 60px rgba(100,180,255,.3); }
  100% { border-color: rgba(140,200,255,0); box-shadow: inset 0 0 60px rgba(100,180,255,0); }
}

@keyframes coinRainFall {
  0% { transform: translateY(0) rotate(0deg); opacity: 1; }
  80% { opacity: 1; }
  100% { transform: translateY(105vh) rotate(720deg); opacity: 0; }
}

@keyframes frozenTimer {
  to { background-position: 20px 0; }
}

@keyframes skillReady {
  0%, 100% { box-shadow: 0 0 8px rgba(255,215,0,.18); }
  50% { box-shadow: 0 0 16px rgba(255,215,0,.48); }
}

@keyframes abyssCloudDrift {
  from { transform: translate(-2px, 1px); }
  to { transform: translate(3px, -2px); }
}

@keyframes wordSlash {
  0% { opacity: 0; transform: translateX(-18%) rotate(-8deg) scaleX(.08); }
  25% { opacity: 1; }
  65% { opacity: 1; transform: translateX(0) rotate(-8deg) scaleX(1); }
  100% { opacity: 0; transform: translateX(12%) rotate(-8deg) scaleX(1); }
}

@keyframes slashLabel {
  0%, 20% { opacity: 0; transform: scale(.7); }
  45%, 70% { opacity: 1; transform: scale(1); }
  100% { opacity: 0; transform: scale(1.08); }
}

@keyframes skippedWord {
  0% { opacity: 1; transform: translateX(0); }
  55% { opacity: .25; transform: translateX(7px); }
  100% { opacity: 0; transform: translateX(18px); }
}
