/* =============================================================
   ANIMATIONS.CSS — All keyframes and animation utilities.
   Glow pulses, coin bursts, win celebrations, shimmer effects.
   ============================================================= */

/* -----------------------------------------------------------
   JACKPOT COUNTER — makes the number flicker like a neon sign
   ----------------------------------------------------------- */
@keyframes jackpotPulse {
  0%, 90%, 100% { opacity: 1; text-shadow: 0 0 10px var(--gold-glow), 0 0 30px rgba(245,166,35,0.4); }
  92%           { opacity: 0.7; text-shadow: none; }
  94%           { opacity: 1; text-shadow: 0 0 6px var(--gold-glow); }
  96%           { opacity: 0.8; }
  98%           { opacity: 1; }
}

/* Number tick animation — digit pops when updated */
@keyframes digitTick {
  0%   { transform: scaleY(1); }
  30%  { transform: scaleY(1.15); color: var(--gold-bright); }
  60%  { transform: scaleY(0.95); }
  100% { transform: scaleY(1); }
}

/* -----------------------------------------------------------
   GLOW PULSE — repeating glow on cards and borders
   ----------------------------------------------------------- */
@keyframes glowPulseTeal {
  0%, 100% { box-shadow: 0 0 10px var(--teal-glow), 0 0 20px rgba(0,196,167,0.15); }
  50%      { box-shadow: 0 0 20px var(--teal-glow), 0 0 45px rgba(0,196,167,0.35), 0 0 60px rgba(0,196,167,0.1); }
}

@keyframes glowPulseGold {
  0%, 100% { box-shadow: 0 0 10px var(--gold-glow), 0 0 20px rgba(245,166,35,0.15); }
  50%      { box-shadow: 0 0 22px var(--gold-glow), 0 0 50px rgba(245,166,35,0.35), 0 0 70px rgba(245,166,35,0.1); }
}

@keyframes glowPulseCrimson {
  0%, 100% { box-shadow: 0 0 10px var(--crimson-glow); }
  50%      { box-shadow: 0 0 22px var(--crimson-glow), 0 0 50px rgba(220,28,46,0.3); }
}

/* -----------------------------------------------------------
   SHIMMER — sliding highlight across tier cards
   ----------------------------------------------------------- */
@keyframes shimmer {
  0%   { transform: translateX(-100%) skewX(-15deg); }
  100% { transform: translateX(250%) skewX(-15deg); }
}

/* -----------------------------------------------------------
   COIN BURST — individual coins fly outward from win center
   ----------------------------------------------------------- */
@keyframes coinFly {
  0%   { transform: translate(0, 0) scale(0) rotate(0deg);   opacity: 1; }
  60%  { opacity: 1; }
  100% { transform: translate(var(--tx), var(--ty)) scale(1) rotate(var(--rot)); opacity: 0; }
}

/* The coin elements themselves bounce and spin */
@keyframes coinSpin {
  0%   { transform: rotateY(0deg); }
  100% { transform: rotateY(360deg); }
}

/* -----------------------------------------------------------
   WIN CELEBRATION — the big win banner pops in
   ----------------------------------------------------------- */
@keyframes winBannerIn {
  0%   { transform: scale(0.3) rotate(-5deg); opacity: 0; }
  60%  { transform: scale(1.12) rotate(2deg); opacity: 1; }
  80%  { transform: scale(0.96) rotate(-1deg); }
  100% { transform: scale(1) rotate(0deg); opacity: 1; }
}

/* Screen flash on win */
@keyframes flashGold {
  0%   { background: transparent; }
  15%  { background: rgba(245,166,35,0.25); }
  30%  { background: transparent; }
  45%  { background: rgba(245,166,35,0.15); }
  60%  { background: transparent; }
  100% { background: transparent; }
}

/* -----------------------------------------------------------
   LOSE STATE — card shakes side to side
   ----------------------------------------------------------- */
@keyframes shakeX {
  0%, 100% { transform: translateX(0); }
  15%      { transform: translateX(-8px); }
  30%      { transform: translateX(7px); }
  45%      { transform: translateX(-6px); }
  60%      { transform: translateX(5px); }
  75%      { transform: translateX(-3px); }
  90%      { transform: translateX(2px); }
}

/* -----------------------------------------------------------
   BUTTON PRESS RIPPLE — expands from tap point
   ----------------------------------------------------------- */
@keyframes ripple {
  0%   { transform: scale(0);   opacity: 0.5; }
  100% { transform: scale(4);   opacity: 0; }
}

/* -----------------------------------------------------------
   ACTIVE PLAYER COUNTER — small pop when number changes
   ----------------------------------------------------------- */
@keyframes playerCountPop {
  0%   { transform: scale(1); }
  40%  { transform: scale(1.2); color: var(--teal-light); }
  100% { transform: scale(1); }
}

/* -----------------------------------------------------------
   SCRATCH TILE REVEAL — tile fades in when fully scratched
   ----------------------------------------------------------- */
@keyframes tileReveal {
  0%   { transform: scale(0.85); filter: blur(4px); opacity: 0; }
  60%  { transform: scale(1.08); filter: blur(0); opacity: 1; }
  100% { transform: scale(1); }
}

/* Match glow — a winning symbol pulses */
@keyframes matchGlow {
  0%, 100% { box-shadow: 0 0 6px var(--gold-glow); background: rgba(245,166,35,0.08); }
  50%      { box-shadow: 0 0 20px var(--gold-glow), 0 0 40px rgba(245,166,35,0.4); background: rgba(245,166,35,0.18); }
}

/* Per-tile flash — a brief gold pulse when a tile first crosses ~60% scratched.
   Inset glow + tint so it reads through the parts of the foil the player has
   already scratched off, WITHOUT the foil being cleared there. */
@keyframes tileFlash {
  0%   { box-shadow: inset 0 0 0 rgba(245,166,35,0);     border-color: var(--gold);           background: rgba(245,166,35,0); }
  35%  { box-shadow: inset 0 0 30px rgba(245,166,35,0.9); border-color: var(--gold);           background: rgba(245,166,35,0.38); }
  100% { box-shadow: inset 0 0 0 rgba(245,166,35,0);     border-color: rgba(0,196,167,0.2);   background: rgba(245,166,35,0); }
}

/* -----------------------------------------------------------
   BOTTOM NAV — active tab indicator slide
   ----------------------------------------------------------- */
@keyframes navTabIn {
  0%   { transform: scaleX(0); }
  100% { transform: scaleX(1); }
}

/* -----------------------------------------------------------
   LOGO — gentle floating animation
   ----------------------------------------------------------- */
@keyframes logoFloat {
  0%, 100% { transform: translateY(0px); }
  50%      { transform: translateY(-6px); }
}

/* -----------------------------------------------------------
   SCREEN ENTRANCE — slides up when switching screens
   ----------------------------------------------------------- */
@keyframes screenSlideUp {
  0%   { transform: translateY(20px); opacity: 0; }
  100% { transform: translateY(0);    opacity: 1; }
}

/* ===========================================================
   NAV REDESIGN — STAGE 2: cross-screen slide between game screens
   Only applied (via JS) when both ends are in {home, play, power-play,
   jackpot-strike}. Both screens go position:absolute so they overlap and
   cross-animate over the persistent #app-bg. These rules live in animations.css
   (loaded last) so the 2-class selectors override `.screen.active`'s
   screenSlideUp at equal specificity.
   =========================================================== */

/* Both transitioning screens overlap, filling the app stack. */
.screen.screen--leaving-down,
.screen.screen--entering-up {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}

/* OUTGOING — gravity: starts slow, ACCELERATES downward under the nav + slight
   fade. ease-IN curve. Sits below the incoming. */
.screen.screen--leaving-down {
  z-index: 1;
  animation: navFallDown 0.32s cubic-bezier(0.4, 0.0, 1, 1) both;
}

/* INCOMING — the hero: rises from below with a SUBTLE overshoot, then settles.
   Sits above the outgoing. */
.screen.screen--entering-up {
  z-index: 2;
  animation: navRiseUp 0.42s cubic-bezier(0.34, 1.56, 0.64, 1) both;
}

/* After an animated entry, hold the screen still — stops `.active`'s
   screenSlideUp from re-firing the instant `entering-up` is removed. Cleared at
   the start of the next navigateTo so instant navs animate normally again. */
.screen.screen--settled {
  animation: none;
}

/* Gravity drop — accelerate away, vanish under the bottom nav. */
@keyframes navFallDown {
  0%   { transform: translateY(0);    opacity: 1; }
  100% { transform: translateY(100%); opacity: 0.85; }
}

/* Rise + settle — the overshoot is carried by the cubic-bezier above. */
@keyframes navRiseUp {
  0%   { transform: translateY(100%); }
  100% { transform: translateY(0); }
}

/* Persistent background parallax — lags the panels: smaller travel (~10px),
   lazier ease, drifts out and eases back. Preserves the centring translateX. */
.app-bg--parallax {
  animation: navBgParallax 0.40s ease-out both;
}
@keyframes navBgParallax {
  0%   { transform: translateX(-50%) translateY(0); }
  45%  { transform: translateX(-50%) translateY(10px); }
  100% { transform: translateX(-50%) translateY(0); }
}

/* ── STAGE 2b: HOME-content staggered cascade ────────────────────────────────
   When the HOME screen is involved in an animated transition, it does NOT move
   as one block — its container holds still (animation:none) and absolutely
   overlaps the game screen, while its child elements cascade individually
   (per-element animation-delay set in JS). Game screens keep moving as one unit
   (the .screen--leaving-down/.entering-up rules above). */
.screen.screen--home-leaving,
.screen.screen--home-entering,
.screen.screen--play-leaving,
.screen.screen--play-entering,
.screen.screen--pp-entering {
  position: absolute;
  inset: 0;
  animation: none;   /* the screen block is still; its children/layers animate */
}
.screen.screen--home-leaving,
.screen.screen--play-leaving  { z-index: 1; }
.screen.screen--home-entering,
.screen.screen--play-entering,
.screen.screen--pp-entering { z-index: 2; }

/* Power Play ENTRY cascade keyframes (applied INLINE per element by
   _applyPpStagger). Real RISE + OVERSHOOT motion — matches the Scratch Rush frame
   cascade feel (springy "settle into place"). Each settles to the element's
   CURRENT (hand-tuned) position; transform/opacity only, never layout properties.
   Two variants:
     ppChromeIn     — chrome RISES + fades (signs/bank/wallet/panel/play; no base
                      transform → a plain translateY is safe).
     ppRiseCentered — RISE + fade for layers that center via translateX(-50%)
                      (.pp-bg, .pp-track). The X-centering is kept in EVERY keyframe
                      so the board rises but never shifts sideways. */
@keyframes ppChromeIn {
  0%   { opacity: 0; transform: translateY(22px); }
  100% { opacity: 1; transform: translateY(0); }
}
@keyframes ppRiseCentered {
  0%   { opacity: 0; transform: translateX(-50%) translateY(24px); }
  100% { opacity: 1; transform: translateX(-50%) translateY(0); }
}
/* (v138: the Power Play die is now a SPRITE SHEET — power-play.js steps
   background-position frame by frame, so the old CSS 3D `ppDieTumble`
   keyframe was removed along with the .pp-die cube.) */

/* Per-element home cascade keyframes — same easings as the block slide (applied
   INLINE per element by _applyHomeStagger so they override the tier cards'
   `animation:none` + the panels' idle glows). Travel is a viewport fraction (not
   the element's own height) so each piece visibly drops away / rises in. */
@keyframes homeStaggerOut {
  0%   { transform: translateY(0);    opacity: 1; }
  100% { transform: translateY(60vh); opacity: 0; }
}
@keyframes homeStaggerIn {
  0%   { transform: translateY(60vh); opacity: 0; }
  100% { transform: translateY(0);    opacity: 1; }
}

/* Reduced-motion is handled in navigateTo() (always instant — no slide, no
   stagger). This media query is a CSS backstop for the block slide / parallax. */
@media (prefers-reduced-motion: reduce) {
  .screen.screen--leaving-down,
  .screen.screen--entering-up,
  .app-bg--parallax {
    animation-duration: 0.01s;
  }
}

/* -----------------------------------------------------------
   TOAST NOTIFICATION — slides in from top
   ----------------------------------------------------------- */
@keyframes toastIn {
  0%   { transform: translateY(-100%); opacity: 0; }
  100% { transform: translateY(0);     opacity: 1; }
}
@keyframes toastOut {
  0%   { transform: translateY(0);     opacity: 1; }
  100% { transform: translateY(-120%); opacity: 0; }
}

/* -----------------------------------------------------------
   COMING SOON BADGE — slow pulsing lock
   ----------------------------------------------------------- */
@keyframes lockPulse {
  0%, 100% { transform: scale(1);    opacity: 0.7; }
  50%      { transform: scale(1.12); opacity: 1; }
}


/* ── Lucky Reel entrance (v152) ───────────────────────────────────────────────
   The cabinet arrives as ONE unit: scale + opacity only, so no box changes and
   the no-scroll fit established in v148 cannot be disturbed mid-flight. A short
   overshoot lands it with weight; it is over inside --lr-enter-ms so the SPIN
   button is live immediately, with no trailing flourish to sit through. */
@keyframes mgaLrMachineIn {
  0%   { opacity: 0; transform: scale(var(--lr-enter-from, 0.86)); }
  62%  { opacity: 1; transform: scale(var(--lr-enter-overshoot, 1.028)); }
  100% { opacity: 1; transform: scale(1); }
}
/* The dim fades over the same period — opacity only. */
@keyframes mgaLrScrimIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* prefers-reduced-motion: appear directly, no movement at all. */
@media (prefers-reduced-motion: reduce) {
  .mga-lr-machine--art,
  .mini-game-modal--bare::before { animation: none !important; }
}
