/* =========================================================
   ANIMEHUB · animations.css
   All @keyframes + scroll-reveal + reduced-motion handling
   ========================================================= */

@keyframes gridDrift { from { transform: translate(0,0); } to { transform: translate(42px, 42px); } }

@keyframes floatParticle {
  0%   { transform: translateY(0) translateX(0); opacity: 0; }
  10%  { opacity: .8; }
  90%  { opacity: .6; }
  100% { transform: translateY(-120vh) translateX(20px); opacity: 0; }
}

@keyframes logoReveal {
  0%   { opacity: 0; letter-spacing: 10px; filter: blur(6px); }
  100% { opacity: 1; letter-spacing: 1px; filter: blur(0); }
}

@keyframes pulseGlow {
  0%, 100% { text-shadow: 0 0 18px var(--purple-glow), 0 0 46px var(--purple-glow-soft); }
  50%      { text-shadow: 0 0 30px var(--red-glow), 0 0 60px var(--purple-glow); }
}

@keyframes fadeFlicker { 0%, 100% { opacity: .55; } 50% { opacity: 1; } }

@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }

@keyframes fadeUp {
  from { opacity: 0; transform: translateY(26px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }

@keyframes scaleIn {
  from { opacity: 0; transform: scale(.94); }
  to   { opacity: 1; transform: scale(1); }
}

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

@keyframes spin { to { transform: rotate(360deg); } }

@keyframes borderGlowPulse {
  0%, 100% { box-shadow: 0 0 0 0 var(--purple-glow-soft); }
  50%      { box-shadow: 0 0 24px 2px var(--purple-glow-soft); }
}

@keyframes slideInRight { from { opacity: 0; transform: translateX(24px); } to { opacity: 1; transform: translateX(0); } }

/* Scroll reveal base state — JS toggles .is-visible via IntersectionObserver */
.reveal { opacity: 0; transform: translateY(28px); transition: opacity .7s var(--ease), transform .7s var(--ease); }
.reveal.is-visible { opacity: 1; transform: translateY(0); }
.reveal-delay-1 { transition-delay: .08s; }
.reveal-delay-2 { transition-delay: .16s; }
.reveal-delay-3 { transition-delay: .24s; }

.floating { animation: floatY 4.5s ease-in-out infinite; }
.spin { animation: spin 1s linear infinite; }
.fade-in { animation: fadeIn .5s var(--ease) both; }
.fade-up { animation: fadeUp .6s var(--ease) both; }
.scale-in { animation: scaleIn .4s var(--ease) both; }
.glow-pulse { animation: borderGlowPulse 2.8s ease-in-out infinite; }

/* Unconditional mount-in animation for dynamically injected cards/tiles.
   Deliberately NOT scroll-triggered: cards living inside a horizontally
   scrolling row never "intersect" the viewport once they sit past the
   first screenful, so an IntersectionObserver-based reveal would leave
   them invisible forever. A simple one-shot animation on insert avoids
   that trap entirely and looks identical either way. */
.anime-card, .character-card, .genre-tile, .screenshot-gallery img {
  animation: fadeUp .5s var(--ease) both;
}

/* Page transition veil between route changes (vanilla multi-page site) */
#page-veil {
  position: fixed; inset: 0; background: var(--black); z-index: 1100;
  transform: translateY(100%); transition: transform .5s var(--ease);
  pointer-events: none;
}
#page-veil.leaving { transform: translateY(0); }

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

/* ============ GENRE CINEMATIC OPENING — keyframes ============ */
/* Action: two blades sliding in from opposite corners to clash center-screen */
@keyframes bladeInLeft  { 0% { transform: translate(-60vw,-40vh) rotate(45deg) scale(.6); opacity:0; } 60% { opacity:1; } 100% { transform: translate(0,0) rotate(45deg) scale(1); opacity:1; } }
@keyframes bladeInRight { 0% { transform: translate(60vw,40vh) rotate(45deg) scale(.6); opacity:0; } 60% { opacity:1; } 100% { transform: translate(0,0) rotate(45deg) scale(1); opacity:1; } }
@keyframes sparkBurst { 0% { transform: translate(0,0) scale(0); opacity: 1; } 100% { transform: translate(var(--sx), var(--sy)) scale(1); opacity: 0; } }
@keyframes flashPulse { 0%, 100% { opacity: 0; } 50% { opacity: .85; } }

/* Fantasy: magic circle scaling/rotating in with runes fading around it */
@keyframes circleAppear { 0% { transform: scale(.2) rotate(-90deg); opacity: 0; } 70% { opacity: 1; } 100% { transform: scale(1) rotate(40deg); opacity: .9; } }
@keyframes runeFade { 0%, 20% { opacity: 0; transform: scale(.5); } 60% { opacity: 1; transform: scale(1.1); } 100% { opacity: 0; transform: scale(1); } }
@keyframes swirlPulse { 0%, 100% { opacity: .35; transform: scale(1); } 50% { opacity: .7; transform: scale(1.15); } }

/* Romance: floating hearts */
@keyframes heartFloat { 0% { transform: translateY(20vh) scale(.4); opacity: 0; } 25% { opacity: 1; } 100% { transform: translateY(-30vh) scale(1.1); opacity: 0; } }

/* Horror: drifting fog + shadow sweep */
@keyframes fogDrift { 0% { transform: translateX(-10%) scale(1); opacity: 0; } 30% { opacity: .55; } 100% { transform: translateX(10%) scale(1.15); opacity: .35; } }
@keyframes shadowSweep { 0% { transform: translateX(-100%); } 100% { transform: translateX(100%); } }

/* Sci-Fi: HUD corners + scanline */
@keyframes hudCornerIn { 0% { opacity: 0; transform: scale(.7); } 100% { opacity: 1; transform: scale(1); } }
@keyframes scanlineSweep { 0% { transform: translateY(-100%); opacity: 0; } 15% { opacity: 1; } 100% { transform: translateY(100vh); opacity: 0; } }

/* Generic genre fallback: soft thematic glow pulse */
@keyframes genericGlowIn { 0% { transform: scale(.3); opacity: 0; } 60% { opacity: .9; } 100% { transform: scale(1.3); opacity: 0; } }
