/* Motion: it says what changed, then stops (a game settles, a Rating moves, a sheet opens),
   plus press feedback on controls. Nothing animates on load: a page is simply there. All of it is off under prefers-reduced-motion. */

@keyframes spin { to { transform: rotate(360deg); } }
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }
@keyframes sheen { to { transform: translateX(100%); } }
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes pop-in { from { opacity: 0; transform: scale(.96); } to { opacity: 1; transform: none; } }
@keyframes sheet-in { from { transform: translateY(24px); opacity: .6; } to { transform: none; opacity: 1; } }
@keyframes toast-countdown { from { transform: scaleX(1); } to { transform: scaleX(0); } }
@keyframes toast-in { from { opacity: 0; transform: translateX(24px) scale(.96); } to { opacity: 1; transform: translateX(var(--toast-x, 0px)); } }
@keyframes toast-out { from { opacity: var(--toast-opacity, 1); transform: translateX(var(--toast-x, 0px)); } to { opacity: 0; transform: translateX(calc(var(--toast-x, 0px) + 24px)) scale(.96); } }
@keyframes toast-out-down { from { opacity: var(--toast-opacity, 1); transform: translateX(var(--toast-x, 0px)); } to { opacity: 0; transform: translateX(var(--toast-x, 0px)) translateY(16px) scale(.96); } }
@keyframes toast-in-up { from { opacity: 0; transform: translateY(16px) scale(.96); } to { opacity: 1; transform: translateX(var(--toast-x, 0px)); } }

/* A reveal: the stage lifts in, the floodlights switch on (a flicker, then steady), the object lands and the words rise. */
@keyframes reveal-stage-in { from { opacity: 0; transform: scale(.98); } to { opacity: 1; transform: none; } }
@keyframes reveal-stage-out { from { opacity: 1; transform: none; } to { opacity: 0; transform: scale(.98); } }
@keyframes beam-on { 0% { opacity: 0; } 14% { opacity: .9; } 22% { opacity: .25; } 34% { opacity: 1; } 100% { opacity: 1; } }
@keyframes reveal-rise { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }
@keyframes medal-drop { 0% { opacity: 0; transform: translateY(-32px) scale(1.3) rotate(-8deg); } 60% { opacity: 1; } 100% { opacity: 1; transform: none; } }
@keyframes halo-breathe { 0%, 100% { opacity: .75; transform: scale(1); } 50% { opacity: 1; transform: scale(1.06); } }

/* A game settles: the result tiles flip over to the final score and the points pill pops in */
@keyframes flip { from { transform: perspective(240px) rotateX(-90deg); opacity: 0; } to { transform: perspective(240px) rotateX(0); opacity: 1; } }
@keyframes pts-pop { 0% { transform: scale(.5); opacity: 0; } 70% { transform: scale(1.12); opacity: 1; } 100% { transform: none; } }
.is-settling .score-tile { transform-origin: 50% 50%; animation: flip 520ms var(--ease-flip) both; animation-delay: calc(var(--i, 0) * 110ms); }
.is-settling .points-pill { animation: pts-pop var(--dur-slow) var(--ease-pop) 520ms both; }
.is-settling .delta { animation: delta-in var(--dur-slow) var(--ease-out) 700ms both; }

/* A Rating moves: the plate counts to the new number (script) and the change slides in beside it */
@keyframes delta-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.plate.is-counting { box-shadow: var(--shadow-plate), 0 0 0 2px var(--accent); }
.delta.is-new { animation: delta-in var(--dur-slow) var(--ease-out) 500ms both; }

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