@keyframes modalIn {
  from {
    opacity: 0;
    transform: translateY(22px) scale(0.98);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

@keyframes toastIn {
  from {
    opacity: 0;
    transform: translateY(-10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes rareShine {
  0%,
  100% {
    box-shadow: var(--shadow);
  }
  50% {
    box-shadow: 0 0 0 2px rgba(244, 197, 66, 0.38), 0 0 24px rgba(95, 212, 232, 0.28);
  }
}

@keyframes hamsterBounce {
  0%,
  100% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(-3px);
  }
}

@keyframes screenEnter {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes completedPulse {
  0%,
  100% {
    box-shadow: 0 0 0 0 rgba(106, 143, 78, 0.55);
  }
  60% {
    box-shadow: 0 0 0 6px rgba(106, 143, 78, 0);
  }
}

@keyframes progressShimmer {
  from {
    background-position: -200% center;
  }
  to {
    background-position: 200% center;
  }
}

@keyframes dummyShake {
  0%   { transform: translateX(0) rotate(0deg); }
  20%  { transform: translateX(-6px) rotate(-4deg); }
  45%  { transform: translateX(6px) rotate(3deg); }
  70%  { transform: translateX(-4px) rotate(-2deg); }
  100% { transform: translateX(0) rotate(0deg); }
}

@keyframes hamsterAttack {
  0%   { transform: translateX(0) scale(1) rotate(0deg); }
  25%  { transform: translateX(8px) scale(1.08) rotate(-5deg); }
  55%  { transform: translateX(16px) scale(1.13) rotate(-10deg); }
  78%  { transform: translateX(4px) scale(1.04) rotate(-3deg); }
  100% { transform: translateX(0) scale(1) rotate(0deg); }
}

@keyframes hamsterIdle {
  0%, 100% { transform: translateY(0) scale(1); }
  50%       { transform: translateY(-3px) scale(1.02); }
}

@keyframes popIn {
  from { transform: scale(0.6); opacity: 0; }
  to   { transform: scale(1);   opacity: 1; }
}

@keyframes floatUp {
  0%   { transform: translateY(0)    scale(1.1); opacity: 1; }
  60%  { transform: translateY(-20px) scale(1);   opacity: 1; }
  100% { transform: translateY(-40px) scale(0.85); opacity: 0; }
}

@keyframes tutorialCardIn {
  from {
    opacity: 0;
    transform: translateY(10px) scale(0.98);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

@keyframes tutorialTargetPulse {
  0%,
  100% {
    box-shadow: var(--shadow), 0 0 0 0 rgba(244, 197, 66, 0.42);
  }
  55% {
    box-shadow: var(--shadow), 0 0 0 8px rgba(244, 197, 66, 0);
  }
}

@keyframes readyActionPulse {
  0%,
  100% {
    filter: brightness(1);
    transform: translateY(0);
  }
  50% {
    filter: brightness(1.08);
    transform: translateY(-1px);
  }
}

@keyframes guideSweep {
  0%,
  42% {
    opacity: 0;
    transform: translateX(-65%);
  }
  52% {
    opacity: 1;
  }
  74%,
  100% {
    opacity: 0;
    transform: translateX(65%);
  }
}

@keyframes cardRise {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes resourcePop {
  0% { transform: scale(0.96); }
  100% { transform: scale(1); }
}

@keyframes navNudge {
  0%,
  100% { transform: translateY(0); }
  50% { transform: translateY(-2px); }
}

@keyframes hitFlash {
  0% { opacity: 0; transform: scaleX(0.2); }
  30% { opacity: 1; transform: scaleX(1); }
  100% { opacity: 0; transform: scaleX(1.2); }
}

@keyframes shinyTwinkle {
  0%,
  100% {
    box-shadow: inset 0 -3px 0 rgba(0, 0, 0, 0.14), 0 0 0 rgba(244, 197, 66, 0);
  }
  50% {
    box-shadow: inset 0 -3px 0 rgba(0, 0, 0, 0.14), 0 0 18px rgba(244, 197, 66, 0.42);
  }
}

@keyframes shinySweep {
  from {
    transform: translateX(-130%) skewX(-18deg);
  }
  to {
    transform: translateX(130%) skewX(-18deg);
  }
}

@keyframes routeSweep {
  from {
    transform: translateX(-110%);
    opacity: 0;
  }
  20%,
  70% {
    opacity: 1;
  }
  to {
    transform: translateX(110%);
    opacity: 0;
  }
}

@keyframes completedBounce {
  0%,
  100% {
    transform: translateY(0) rotate(0deg);
  }
  35% {
    transform: translateY(-2px) rotate(-1deg);
  }
  70% {
    transform: translateY(1px) rotate(1deg);
  }
}

@keyframes selectedZoneBreath {
  0%,
  100% {
    box-shadow: var(--shadow), 0 0 0 rgba(199, 137, 53, 0);
  }
  50% {
    box-shadow: var(--shadow), 0 0 20px rgba(199, 137, 53, 0.22);
  }
}

@keyframes gachaGlowOrbit {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

@keyframes prizePop {
  0% {
    transform: scale(0.96) rotate(-1deg);
  }
  50% {
    transform: scale(1.02) rotate(1deg);
  }
  100% {
    transform: scale(1) rotate(0deg);
  }
}

@keyframes gachaBoxIdle {
  0%,
  100% {
    transform: translateX(-50%) translateY(0) rotate(0deg);
  }
  50% {
    transform: translateX(-50%) translateY(-3px) rotate(-0.7deg);
  }
}

@keyframes gachaEnvelopeIdle {
  0%,
  100% {
    transform: translateX(-50%) translateY(4px) rotateZ(0deg);
  }
  35% {
    transform: translateX(-50%) translateY(-3px) rotateZ(-0.6deg);
  }
  70% {
    transform: translateX(-50%) translateY(1px) rotateZ(0.45deg);
  }
}

@keyframes gachaSealPulse {
  0%,
  100% {
    opacity: 0.42;
    transform: scale(0.92);
  }
  50% {
    opacity: 0.95;
    transform: scale(1.12);
  }
}

@keyframes gachaEnvelopeOpenShake {
  0% {
    transform: translateX(-50%) translateY(4px) rotateZ(0deg) scale(1);
  }
  18% {
    transform: translateX(-50%) translateY(0) rotateZ(-2deg) scale(1.03);
  }
  34% {
    transform: translateX(-50%) translateY(2px) rotateZ(2deg) scale(1.02);
  }
  52% {
    transform: translateX(-50%) translateY(-4px) rotateZ(-1deg) scale(1.04);
  }
  100% {
    transform: translateX(-50%) translateY(2px) rotateZ(0deg) scale(1);
  }
}

@keyframes gachaBoxOpenShake {
  0% {
    transform: translateX(-50%) translateY(0) rotate(0deg);
  }
  22% {
    transform: translateX(-50%) translateY(4px) rotate(-2deg);
  }
  46% {
    transform: translateX(-50%) translateY(-7px) rotate(2deg);
  }
  72% {
    transform: translateX(-50%) translateY(0) rotate(-1deg);
  }
  100% {
    transform: translateX(-50%) translateY(0) rotate(0deg);
  }
}

@keyframes gachaLidOpen {
  0% {
    transform: translateX(-50%) rotateX(0deg);
    filter: brightness(1);
  }
  45% {
    transform: translateX(-50%) rotateX(-34deg) translateY(-3px);
    filter: brightness(1.08);
  }
  100% {
    transform: translateX(-50%) rotateX(-68deg) translateY(-8px);
    filter: brightness(1.14);
  }
}

@keyframes gachaSealBurst {
  0% {
    transform: scale(1);
    box-shadow:
      inset 0 2px 0 rgba(255, 255, 255, 0.45),
      0 0 0 7px rgba(244, 197, 66, 0.14),
      0 0 18px rgba(244, 197, 66, 0.38);
  }
  42% {
    transform: scale(1.22);
    box-shadow:
      inset 0 2px 0 rgba(255, 255, 255, 0.6),
      0 0 0 14px rgba(244, 197, 66, 0.18),
      0 0 34px rgba(244, 197, 66, 0.78);
  }
  100% {
    opacity: 0.75;
    transform: scale(0.92);
  }
}

@keyframes gachaGlowBurst {
  0% {
    opacity: 0.16;
    transform: translateX(-50%) scale(0.66);
  }
  48% {
    opacity: 0.88;
    transform: translateX(-50%) scale(1.28);
  }
  100% {
    opacity: 0.46;
    transform: translateX(-50%) scale(1.06);
  }
}

@keyframes gachaRewardRise {
  0% {
    opacity: 0;
    transform: translateX(-50%) translateY(28px) scale(0.78) rotate(-7deg);
  }
  58% {
    opacity: 1;
    transform: translateX(-50%) translateY(-20px) scale(1.04) rotate(3deg);
  }
  100% {
    opacity: 1;
    transform: translateX(-50%) translateY(-12px) scale(1) rotate(0deg);
  }
}

@keyframes gachaRewardDrop {
  0% {
    opacity: 0;
    transform: translateX(-50%) translateY(-78px) scale(0.72) rotate(-8deg);
  }
  30% {
    opacity: 1;
    transform: translateX(-50%) translateY(10px) scale(1.04) rotate(4deg);
  }
  48% {
    transform: translateX(-50%) translateY(-8px) scale(0.98) rotate(-2deg);
  }
  68% {
    transform: translateX(-50%) translateY(2px) scale(1.01) rotate(1deg);
  }
  100% {
    opacity: 1;
    transform: translateX(-50%) translateY(0) scale(1) rotate(0deg);
  }
}

@keyframes gachaParticleBurst {
  0% {
    opacity: 0;
    transform: translate(-50%, 0) scale(0.4);
  }
  28% {
    opacity: 1;
  }
  100% {
    opacity: 0;
    transform: translate(calc(-50% + var(--tx)), var(--ty)) scale(0.96);
  }
}

@keyframes gachaLetterFly {
  0% {
    opacity: 0;
    transform: translateX(-50%) translateY(24px) scale(0.72) rotate(-8deg);
  }
  22% {
    opacity: 1;
  }
  68% {
    opacity: 1;
    transform: translateX(-50%) translateY(-72px) scale(1.08) rotate(5deg);
  }
  100% {
    opacity: 0;
    transform: translateX(-50%) translateY(-96px) scale(1.18) rotate(9deg);
  }
}

@keyframes gachaSparkBurst {
  0% {
    opacity: 0;
    transform: translateX(-50%) scale(0.65);
  }
  30% {
    opacity: 1;
  }
  100% {
    opacity: 0;
    transform: translateX(-50%) scale(1.35) translateY(-18px);
  }
}

@keyframes gachaBurstLightPulse {
  0% {
    opacity: 0;
    transform: translate(-50%, -50%) scale(0.65);
  }
  48% {
    opacity: 0.9;
    transform: translate(-50%, -50%) scale(1.22);
  }
  100% {
    opacity: 0.42;
    transform: translate(-50%, -50%) scale(1.02);
  }
}

@keyframes gachaSparkBurstBetter {
  0% {
    opacity: 0;
    transform: translate(-50%, -50%) scale(0.72);
  }
  32% {
    opacity: 1;
  }
  100% {
    opacity: 0;
    transform: translate(-50%, -58%) scale(1.35);
  }
}

.modal {
  animation: modalIn 180ms ease-out;
}

.status-strip span {
  animation: toastIn 160ms ease-out;
}

.screen {
  animation: var(--screen-enter-animation, screenEnter 200ms ease-out);
}

.guide-card,
.stack > .hamster-card,
.stack > .zone-card,
.stack > .quest-card,
.stack > .upgrade-card,
.stack > .inventory-card,
.gacha-result-card {
  animation: var(--card-enter-animation, cardRise 180ms ease-out both);
}

.stack > :nth-child(2),
.gacha-result-grid > :nth-child(2) {
  animation-delay: var(--card-enter-delay-2, 35ms);
}

.stack > :nth-child(3),
.gacha-result-grid > :nth-child(3) {
  animation-delay: var(--card-enter-delay-3, 70ms);
}

.stack > :nth-child(n+4),
.gacha-result-grid > :nth-child(n+4) {
  animation-delay: var(--card-enter-delay-many, 105ms);
}

.resource-chip strong {
  animation: resourcePop 160ms ease-out;
}

.resource-chip.resource-shiny,
.shiny-counter {
  animation: shinyTwinkle 2.6s ease-in-out infinite;
}

.nav-button.is-active .nav-icon {
  animation: navNudge 1.8s ease-in-out infinite;
}

.zone-card.is-active {
  animation: selectedZoneBreath 2.4s ease-in-out infinite;
}

.rarity-frame-rare,
.rarity-frame-epic,
.rarity-frame-legendary,
.rarity-frame-mythic {
  animation: rareShine 2.8s ease-in-out infinite;
}

.hamster-card:hover .hamster-portrait {
  animation: hamsterBounce 420ms ease-in-out;
}

/* Completed expedition — pulsing green badge */
.expedition-slot[data-status="completed"] .timer-badge {
  background: rgba(106, 143, 78, 0.22);
  color: var(--success);
  animation: completedPulse 1.4s ease-out infinite;
}

.expedition-slot[data-status="completed"] {
  animation: completedBounce 1.8s ease-in-out infinite;
}

/* Active expedition progress shimmer */
.expedition-slot[data-status="active"] .progress span {
  background: linear-gradient(
    90deg,
    var(--accent) 0%,
    var(--accent-2) 50%,
    var(--accent) 100%
  );
  background-size: 200% 100%;
  animation: progressShimmer 2.2s linear infinite;
}

.expedition-slot[data-status="active"]::after {
  animation: routeSweep 2.5s ease-in-out infinite;
}

.hero-gacha::after {
  animation: gachaGlowOrbit 16s linear infinite;
}

.gacha-result-card.is-prize {
  animation: prizePop 420ms ease-out both, rareShine 2.8s ease-in-out infinite;
}

.arena-stage.has-fighter {
  box-shadow: inset 0 -10px 24px rgba(63, 111, 106, 0.12);
}

.arena-stage.has-hit::before {
  content: "";
  position: absolute;
  left: 36%;
  right: 18%;
  top: 36%;
  height: 3px;
  border-radius: 999px;
  background: linear-gradient(90deg, transparent, rgba(244, 197, 66, 0.9), transparent);
  transform-origin: left center;
  animation: hitFlash 220ms ease-out both;
  pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
    transition-duration: 1ms !important;
  }
}
