/* =====================================================================
 * GameFeel - shared animation/game-feel polish for the 7 ShitcoinBTC games
 * (spaceship, catcher, slots, tap, miner, lordle, lottery)
 *
 * Dependency-free. 60fps on phones: transform/opacity only, no layout
 * reads inside animation frames, pooled canvas confetti.
 * ===================================================================== */

/* ---------- modal / panel entrances ---------- */
@keyframes gfZoomIn {
  from { opacity: 0; transform: translate(-50%, -50%) scale(.86); }
  to   { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}
.gf-enter { animation: gfZoomIn .28s cubic-bezier(.2, 1.4, .4, 1) both; }
@keyframes gfZoomInC {
  from { opacity: 0; transform: scale(.86); }
  to   { opacity: 1; transform: scale(1); }
}
.gf-enter-c { animation: gfZoomInC .3s cubic-bezier(.2, 1.4, .4, 1) both; }

/* ---------- countdown digit punch ---------- */
@keyframes gfCountPop {
  0%   { opacity: 0; transform: translate(-50%, -50%) scale(2.1); }
  40%  { opacity: 1; transform: translate(-50%, -50%) scale(1); }
  100% { opacity: 1; transform: translate(-50%, -50%) scale(.96); }
}
.gf-countpop { animation: gfCountPop .62s cubic-bezier(.2, 1.2, .35, 1) both; }

/* ---------- generic scale pop (combo badges, buttons, chips) ---------- */
@keyframes gfPop {
  0%   { transform: scale(.6); }
  55%  { transform: scale(1.18); }
  100% { transform: scale(1); }
}
.gf-pop { animation: gfPop .3s cubic-bezier(.2, 1.4, .4, 1) both; }

/* ---------- shake (invalid input, heat alarm) ---------- */
@keyframes gfShakeX {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-9px); }
  40% { transform: translateX(8px); }
  60% { transform: translateX(-6px); }
  80% { transform: translateX(5px); }
}
.gf-shake { animation: gfShakeX .38s ease both; }

/* ---------- win bounce (lordle row, tier bars) ---------- */
@keyframes gfWinBounce {
  0%, 100% { transform: translateY(0); }
  30% { transform: translateY(-14px); }
  55% { transform: translateY(0); }
  75% { transform: translateY(-7px); }
}
.gf-bounce { animation: gfWinBounce .55s ease both; }

/* ---------- float-up text (+1 tap floaters, share pings) ---------- */
.gf-float-wrap { position: absolute; inset: 0; overflow: hidden; pointer-events: none; }
.gf-floater {
  position: absolute; font-weight: bold; color: #ffdf5e;
  font-size: 22px; pointer-events: none; white-space: nowrap;
  text-shadow: 0 2px 6px #000;
  animation: gfFloatUp .7s ease-out forwards;
}
@keyframes gfFloatUp {
  from { opacity: 1; transform: translate(-50%, -50%) scale(1); }
  to   { opacity: 0; transform: translate(-50%, -160%) scale(1.25); }
}

/* ---------- tap ripple ring ---------- */
.gf-ripple {
  position: absolute; border-radius: 50%; pointer-events: none;
  border: 3px solid rgba(242, 169, 0, .85);
  animation: gfRipple .45s ease-out forwards;
}
@keyframes gfRipple {
  from { opacity: .9; transform: translate(-50%, -50%) scale(.3); }
  to   { opacity: 0; transform: translate(-50%, -50%) scale(1.6); }
}

/* ---------- full screen flash (crash / big win) ---------- */
#gf-flash {
  position: fixed; inset: 0; z-index: 200; pointer-events: none;
  opacity: 0; background: #fff;
  transition: opacity .28s ease-out;
}
#gf-flash.on { opacity: .55; transition: opacity .05s ease-out; }

/* ---------- pooled canvas confetti ---------- */
#gf-confetti {
  position: fixed; inset: 0; z-index: 150; pointer-events: none;
}

/* ---------- inline button spinner ---------- */
.gf-spin {
  display: inline-block; width: 1em; height: 1em; margin-right: .5em;
  border: 2px solid rgba(20, 16, 10, .3); border-top-color: currentColor;
  border-radius: 50%; vertical-align: -.12em;
  animation: gfSpin .7s linear infinite;
}
@keyframes gfSpin { to { transform: rotate(360deg); } }
button.gf-busy { opacity: .72; }

/* ---------- loading dots (inline text, e.g. "Checking...") ---------- */
.gf-dots::after { content: ''; animation: gfDots 1.1s steps(4) infinite; }
@keyframes gfDots { 0% { content: ''; } 25% { content: '.'; } 50% { content: '..'; } 75% { content: '...'; } }

/* ---------- jackpot / hero glow ---------- */
@keyframes gfGlow {
  0%, 100% { box-shadow: 0 0 18px rgba(245, 130, 11, .25); }
  50%      { box-shadow: 0 0 44px rgba(245, 130, 11, .6); }
}
.gf-glow { animation: gfGlow 1.6s ease-in-out infinite; }

/* ---------- timer danger pulse (last 10 seconds) ---------- */
@keyframes gfDanger {
  0%, 100% { filter: brightness(1); }
  50%      { filter: brightness(1.7); }
}
.gf-danger { animation: gfDanger .5s ease-in-out infinite; }

/* ---------- lordle 3D tile flip ---------- */
.gf-tile { transform-style: preserve-3d; backface-visibility: hidden; }
@keyframes gfFlipIn {
  0%   { transform: rotateX(0); }
  50%  { transform: rotateX(-90deg); }
  100% { transform: rotateX(0); }
}
.gf-flip { animation: gfFlipIn .5s ease-in-out both; }

/* ---------- feed item slide-in ---------- */
@keyframes gfSlideIn {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}
.gf-slidein { animation: gfSlideIn .25s ease-out both; }

/* ---------- progress bar win state shimmer ---------- */
@keyframes gfShimmer {
  from { background-position: -200px 0; }
  to   { background-position: 200px 0; }
}
.gf-shimmer {
  background-image: linear-gradient(100deg, transparent 30%, rgba(255, 255, 255, .35) 50%, transparent 70%) !important;
  background-size: 200px 100%; background-repeat: no-repeat;
  animation: gfShimmer 1.4s linear infinite;
}

/* ---------- spin-button press ---------- */
.gf-press:active { transform: scale(.93); }
.gf-press { transition: transform .08s ease; }

/* ---------- respect reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  .gf-enter, .gf-enter-c, .gf-pop, .gf-shake, .gf-bounce,
  .gf-floater, .gf-ripple, .gf-flip, .gf-slidein, .gf-countpop {
    animation: none !important;
  }
  .gf-glow, .gf-danger, .gf-shimmer, .gf-spin { animation-duration: 3s; }
}
