/* ═══════════════════════════════════════════════
   Little Adventure Town | animations
   Feedback animations use the individual transform properties
   (rotate / scale / translate) so they never fight with positioning
   transforms set from JavaScript.
   ═══════════════════════════════════════════════ */

@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes pop-in { from { opacity: 0; scale: .2; } 60% { scale: 1.25; } to { opacity: 1; scale: 1; } }
@keyframes spin { to { rotate: 360deg; } }
@keyframes floaty { 0%, 100% { translate: 0 0; } 50% { translate: 0 -3.5%; } }
@keyframes drift { from { translate: -12% 0; } to { translate: 12% 0; } }
@keyframes pulse { 0%, 100% { scale: 1; } 50% { scale: 1.09; } }
@keyframes slot-pulse { 0%, 100% { opacity: .55; } 50% { opacity: 1; } }
@keyframes flicker { from { transform: scale(1, 1) rotate(-2deg); } to { transform: scale(1.06, 1.12) rotate(2deg); } }
@keyframes waddle { from { rotate: -7deg; } to { rotate: 7deg; } }
@keyframes peek { 0%, 100% { transform: translateY(0); } 35%, 65% { transform: translateY(-34%); } }
@keyframes glimpse { 0%, 100% { opacity: 0; scale: .6; } 30%, 70% { opacity: .75; scale: 1; } }
@keyframes siren-a { 0%, 49% { opacity: 1; filter: drop-shadow(0 0 6px #ff4d4d); } 50%, 100% { opacity: .35; filter: none; } }
@keyframes siren-b { 0%, 49% { opacity: .35; filter: none; } 50%, 100% { opacity: 1; filter: drop-shadow(0 0 6px #4d8bff); } }

@keyframes wiggle {
  0%, 100% { rotate: 0deg; } 15% { rotate: -7deg; } 30% { rotate: 7deg; } 45% { rotate: -5deg; } 60% { rotate: 5deg; } 80% { rotate: -2deg; }
}
@keyframes bounce {
  0%, 100% { scale: 1 1; translate: 0 0; } 25% { scale: 1.08 .9; translate: 0 3%; } 50% { scale: .95 1.1; translate: 0 -10%; } 75% { scale: 1.04 .97; translate: 0 0; }
}
@keyframes pop { 0%, 100% { scale: 1; } 40% { scale: 1.22; } }
@keyframes jump {
  0%, 100% { translate: 0 0; scale: 1 1; } 12% { scale: 1.1 .88; } 40% { translate: 0 -26%; scale: .95 1.08; } 68% { translate: 0 0; scale: 1.08 .92; } 84% { translate: 0 -8%; scale: 1 1; }
}
@keyframes squish { 0%, 100% { scale: 1 1; } 45% { scale: 1.12 .82; } }
@keyframes spin-once { from { rotate: 0deg; } to { rotate: 360deg; } }
@keyframes hint {
  0%, 100% { filter: drop-shadow(0 0 0 rgba(255, 210, 63, 0)); scale: 1; }
  25%, 75% { filter: drop-shadow(0 0 14px #ffd23f) drop-shadow(0 0 6px #fff); scale: 1.07; }
  50% { filter: drop-shadow(0 0 6px #ffd23f); scale: 1.02; }
}
@keyframes attention { 0%, 100% { scale: 1; } 50% { scale: 1.05; } }

.fx-wiggle { animation: wiggle .6s ease-in-out !important; }
.fx-bounce { animation: bounce .65s ease-in-out !important; transform-origin: 50% 100%; }
.fx-pop { animation: pop .42s ease-out !important; }
.fx-jump { animation: jump .7s ease-in-out !important; transform-origin: 50% 100%; }
.fx-squish { animation: squish .26s ease-in-out !important; transform-origin: 50% 100%; }
.fx-spin { animation: spin-once .9s cubic-bezier(.3,1.3,.6,1) !important; }
.fx-hint { animation: hint 1.6s ease-in-out !important; }
.fx-attention { animation: attention .9s ease-in-out !important; }
.fx-glow { filter: drop-shadow(0 0 12px #ffd23f); }

.siren-on .siren-a { animation: siren-a .32s linear infinite; }
.siren-on .siren-b { animation: siren-b .32s linear infinite; }

/* People who ask their device for less motion get calmer idle animations.
   Feedback animations stay: they are short and carry meaning for the child. */
@media (prefers-reduced-motion: reduce) {
  .place, .tc, .title-name, .title-cloud, .town-sky .cloud, .sun-rays, .reward-rays, .reward-art, .tray-icon.turn-icon { animation: none !important; }
}
