/* nuclear-game-common.css
   Shared 80s-arcade animation toolkit for the nuclear game/demo/crossword pages.
   Pages keep their own layout + colors; this file only registers the shared
   custom properties and @keyframes so the same motions stay in sync everywhere.

   Orbit cards (ngOrbit) are parametrized per card via custom properties:
     --i                card index (0..n-1)
     --orbit-step       angle between cards          (default 36deg)
     --orbit-dist       orbit radius                 (default 132px)
     --orbit-tilt       rotateY wobble at the edges  (default -18deg, 0deg = flat)
     --orbit-fade       opacity at far side          (default .25, 1 = no fade)
     --orbit-fade-mid   opacity on the near side     (default .96)
     --orbit-min-scale / --orbit-max-scale           (default .82 / 1.05)
   --pulse-radius / --exit-offset are typed lengths so ngRadiusPulse and the
   decade exit/enter transitions can animate them (they default to 0px). */

@property --pulse-radius {
  syntax: '<length>';
  inherits: false;
  initial-value: 0px;
}

@property --exit-offset {
  syntax: '<length>';
  inherits: false;
  initial-value: 0px;
}

@keyframes ngOrbit {
  0% {
    opacity: var(--orbit-fade, .25);
    transform:
      rotateZ(calc(var(--i, 0) * var(--orbit-step, 36deg)))
      translateX(calc(var(--orbit-dist, 132px) + var(--pulse-radius, 0px) + var(--exit-offset, 0px)))
      rotateZ(calc(var(--i, 0) * var(--orbit-step, 36deg) * -1))
      rotateY(var(--orbit-tilt, -18deg))
      scale(var(--orbit-min-scale, .82));
  }
  18%, 72% {
    opacity: var(--orbit-fade-mid, .96);
  }
  50% {
    transform:
      rotateZ(calc(var(--i, 0) * var(--orbit-step, 36deg) + 180deg))
      translateX(calc(var(--orbit-dist, 132px) + var(--pulse-radius, 0px) + var(--exit-offset, 0px)))
      rotateZ(calc((var(--i, 0) * var(--orbit-step, 36deg) + 180deg) * -1))
      rotateY(calc(var(--orbit-tilt, -18deg) * -1))
      scale(var(--orbit-max-scale, 1.05));
  }
  100% {
    opacity: var(--orbit-fade, .25);
    transform:
      rotateZ(calc(var(--i, 0) * var(--orbit-step, 36deg) + 360deg))
      translateX(calc(var(--orbit-dist, 132px) + var(--pulse-radius, 0px) + var(--exit-offset, 0px)))
      rotateZ(calc((var(--i, 0) * var(--orbit-step, 36deg) + 360deg) * -1))
      rotateY(var(--orbit-tilt, -18deg))
      scale(var(--orbit-min-scale, .82));
  }
}

/* breathing orbit radius, pairs with ngOrbit on the same element */
@keyframes ngRadiusPulse {
  0%, 100% { --pulse-radius: 0px; }
  50% { --pulse-radius: 26px; }
}

/* full transform spin (halo dials, radar sweeps) */
@keyframes ngSpin {
  to { transform: rotate(360deg); }
}

/* rotate-property spin — composes with a static transform (tilted orbit rings) */
@keyframes ngRotate {
  to { rotate: 360deg; }
}

/* gentle scale breathing for reactor cores */
@keyframes ngCorePulse {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.05); }
}

/* endless grid floor; set --grid-scroll-x/--grid-scroll-y to the tile size */
@keyframes ngGridScroll {
  from { background-position: 0 0; }
  to { background-position: var(--grid-scroll-x, 0px) var(--grid-scroll-y, 42px); }
}

/* conic highlight sweeping across a panel (::before overlays) */
@keyframes ngSweepPanel {
  to { transform: rotate(378deg); }
}

/* reactor fleet card entrance + idle glow (stagger with --i) */
@keyframes ngFleetIn {
  from { opacity: 0; transform: translateY(14px) scale(.96); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}

@keyframes ngFleetPulse {
  0%, 100% {
    box-shadow: 0 0 8px rgba(0, 255, 136, .22), 0 0 2px rgba(0, 255, 136, .14);
    border-color: rgba(0, 255, 136, .4);
  }
  50% {
    box-shadow: 0 0 20px rgba(0, 255, 136, .52), 0 0 8px rgba(0, 255, 136, .26);
    border-color: rgba(0, 255, 136, .82);
  }
}

/* lyric chips raining down inside a clipped stage (--rot / --rot-end per chip) */
@keyframes ngLyricFall {
  to {
    top: 105%;
    transform: rotate(var(--rot-end, 0deg));
    opacity: 0;
  }
}

/* letter/cell pop-in with a small overshoot */
@keyframes ngPopIn {
  0% { transform: scale(.35); opacity: .2; }
  65% { transform: scale(1.18); opacity: 1; }
  100% { transform: scale(1); }
}

/* neon-sign flicker: steady glow with rare dips, 80s storefront style */
@keyframes ngNeonFlicker {
  0%, 6.5%, 7.5%, 44%, 45.4%, 100% { opacity: 1; }
  7%, 44.6% { opacity: .58; }
  7.2%, 45% { opacity: .84; }
}

/* classic attract-mode blink (PRESS PLAY / INSERT COIN) */
@keyframes ngBlink {
  0%, 55% { opacity: 1; }
  56%, 100% { opacity: 0; }
}

/* slow drifting color wash for relaxing overlays (reward screens) */
@keyframes ngAuroraDrift {
  from { transform: translate3d(-2%, -1%, 0) scale(1); }
  to { transform: translate3d(2%, 2%, 0) scale(1.08); }
}
