/* ============================================================
   ROYAL HEIST — animations: keyframes and transient state
   classes applied by fx.js / the resolution director
   ============================================================ */

/* ---------- generic keyframes ---------- */
@keyframes heartPulse {
  0%, 100% { opacity: 0.55; }
  50% { opacity: 1; }
}

@keyframes dealIn {
  from { transform: translateY(60px) rotate(4deg); opacity: 0; }
  to   { transform: translateY(0) rotate(0); opacity: 1; }
}
.tcard.dealing { animation: dealIn 0.3s cubic-bezier(0.22, 1, 0.36, 1) backwards; }

@keyframes shake {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-6px); }
  40% { transform: translateX(6px); }
  60% { transform: translateX(-4px); }
  80% { transform: translateX(4px); }
}
.shake { animation: shake 0.3s ease; }

@keyframes popIn {
  0% { transform: scale(0.6); opacity: 0; }
  70% { transform: scale(1.06); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}
.pop-in { animation: popIn 0.3s cubic-bezier(0.34, 1.56, 0.64, 1); }

@keyframes ribbonPop {
  0% { transform: scale(0.78); opacity: 0; filter: brightness(1.8); }
  16% { opacity: 1; }
  55% { transform: scale(1.04); filter: brightness(1.35); }
  100% { transform: scale(1); opacity: 1; filter: brightness(1); }
}
#phase-banner.ribbon-pop { animation: ribbonPop 0.3s cubic-bezier(0.22, 1, 0.36, 1); }

@keyframes flashBorder {
  0% { box-shadow: 0 0 0 1px var(--cat, var(--gold)), 0 0 22px var(--cat, var(--gold)); }
  100% { box-shadow: none; }
}
.pcard.resolving { animation: flashBorder 0.3s ease-out; z-index: 8; }

@keyframes napkinFlip {
  0% { transform: rotateY(0); }
  49% { transform: rotateY(90deg); filter: brightness(2); }
  51% { transform: rotateY(90deg); }
  100% { transform: rotateY(0); }
}
.tcard.napkin-flip { animation: napkinFlip 0.3s ease; }

@keyframes shredOut {
  to { transform: translateY(70px) rotate(9deg) scale(0.7); opacity: 0; filter: saturate(0.2); }
}
.tcard.shredding { animation: shredOut 0.3s ease-in forwards; pointer-events: none; }

@keyframes playOut {
  to { transform: translateY(-90px) scale(0.85); opacity: 0; }
}
.tcard.playing-out { animation: playOut 0.3s ease-in forwards; pointer-events: none; }

/* ---------- bar pulses ---------- */
@keyframes barPulseHot {
  0% { box-shadow: 0 0 0 0 rgba(255, 77, 94, 0.7); }
  100% { box-shadow: 0 0 0 12px rgba(255, 77, 94, 0); }
}
.heat-bar.pulse-hot { animation: barPulseHot 0.3s ease-out; }

@keyframes barPulseCool {
  0% { box-shadow: 0 0 0 0 rgba(65, 245, 143, 0.7); }
  100% { box-shadow: 0 0 0 12px rgba(65, 245, 143, 0); }
}
.heat-bar.pulse-cool { animation: barPulseCool 0.3s ease-out; }

@keyframes hpChunk {
  0% { filter: brightness(2.2); }
  100% { filter: brightness(1); }
}
.fw-bar.chunk { animation: hpChunk 0.3s ease-out; }

/* ---------- heat threshold states ---------- */
@keyframes warnShake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-1px); }
  75% { transform: translateX(1px); }
}
#heat-panel.warn { animation: warnShake 0.5s ease infinite; }

@keyframes alarmGlow {
  0%, 100% { border-color: var(--line); }
  50% { border-color: var(--red); box-shadow: 0 0 22px rgba(255, 77, 94, 0.35); }
}
#heat-panel.danger { animation: warnShake 0.3s ease infinite, alarmGlow 0.8s ease infinite; }

/* screen-edge alarm vignette at 90%+ heat */
#screenfx.alarm::before {
  content: "";
  position: absolute; inset: 0;
  box-shadow: inset 0 0 140px rgba(255, 30, 50, 0.28);
  animation: heartPulse 0.8s ease infinite;
}

/* ---------- barrier ---------- */
@keyframes barrierSpark {
  0% { opacity: 1; transform: scale(0.6); }
  100% { opacity: 0; transform: scale(1.5); }
}
#barrier-panel.spark { animation: hpChunk 0.3s ease-out; }

@keyframes barrierShatter {
  0% { transform: scale(1); filter: brightness(1); }
  30% { transform: scale(1.06); filter: brightness(2.4); }
  60% { transform: scale(0.98) rotate(-1deg); }
  100% { transform: scale(1); filter: brightness(1); }
}
#barrier-panel.shatter { animation: barrierShatter 0.3s ease; }

@keyframes heartLight {
  0% { transform: scale(1); }
  50% { transform: scale(1.7); }
  100% { transform: scale(1); }
}
.b-heart.lighting { animation: heartLight 0.3s cubic-bezier(0.34, 1.56, 0.64, 1); }

/* ---------- AI reactions ---------- */
@keyframes eyeTwitch {
  0%, 100% { transform: translate(0, 0); }
  25% { transform: translate(-5px, 2px); }
  50% { transform: translate(4px, -3px); }
  75% { transform: translate(-2px, -2px); }
}
.ai-eye.twitch .ai-pupil { animation: eyeTwitch 0.3s ease; }

@keyframes glitch {
  0%, 100% { transform: translate(0); filter: none; }
  20% { transform: translate(-2px, 1px); filter: hue-rotate(60deg); }
  40% { transform: translate(2px, -1px); filter: hue-rotate(-60deg) saturate(3); }
  60% { transform: translate(-1px, -1px); }
  80% { transform: translate(1px, 1px); filter: hue-rotate(30deg); }
}
#ai-bar.glitch { animation: glitch 0.3s steps(2) 2; }

@keyframes statusBlink { 50% { opacity: 0.25; } }
.ai-status.blink { animation: statusBlink 0.3s step-end 3; }

/* ---------- hand type title reveal ---------- */
@keyframes handReveal {
  0% { transform: scale(0.7); opacity: 0; letter-spacing: 0.4em; }
  60% { transform: scale(1.08); opacity: 1; }
  100% { transform: scale(1); opacity: 1; letter-spacing: 0.1em; }
}
.pv-hand.reveal { animation: handReveal 0.3s cubic-bezier(0.34, 1.56, 0.64, 1); }

/* ---------- floating feedback numbers ---------- */
@keyframes floatUp {
  0% { transform: translateY(0); opacity: 0; }
  15% { opacity: 1; }
  100% { transform: translateY(-60px); opacity: 0; }
}
.float-num {
  position: fixed; z-index: 97; pointer-events: none;
  font-family: var(--mono); font-weight: 700; font-size: 17px;
  animation: floatUp 1.15s ease-out forwards;
  text-shadow: 0 2px 8px rgba(0, 0, 0, 0.8);
}

/* ---------- damage beam ---------- */
.beam {
  position: fixed; z-index: 94; pointer-events: none;
  height: 3px; border-radius: 2px;
  transform-origin: left center;
  background: linear-gradient(90deg, transparent, var(--orange), #fff);
  box-shadow: 0 0 12px var(--orange);
  animation: beamZip 0.32s ease-in forwards;
}
@keyframes beamZip {
  0% { clip-path: inset(0 100% 0 0); opacity: 1; }
  60% { clip-path: inset(0 0 0 0); }
  100% { clip-path: inset(0 0 0 70%); opacity: 0; }
}

/* ---------- full-screen flashes ---------- */
@keyframes flashGold { 0% { opacity: 0.55; } 100% { opacity: 0; } }
#screenfx.flash-gold::after {
  content: ""; position: absolute; inset: 0;
  background: radial-gradient(circle, rgba(255, 215, 94, 0.5), rgba(255, 160, 40, 0.15));
  animation: flashGold 0.8s ease-out forwards;
}
@keyframes flashRed { 0% { opacity: 0.6; } 100% { opacity: 0; } }
#screenfx.flash-red::after {
  content: ""; position: absolute; inset: 0;
  background: radial-gradient(circle, rgba(255, 40, 60, 0.5), rgba(120, 0, 20, 0.25));
  animation: flashRed 0.9s ease-out forwards;
}

/* red lockout sweep on defeat */
@keyframes lockSweep {
  0% { transform: translateY(-100%); }
  100% { transform: translateY(100%); }
}
#screenfx.lockout::before {
  content: "";
  position: absolute; left: 0; right: 0; top: 0; height: 100%;
  background: linear-gradient(180deg, transparent, rgba(255, 20, 40, 0.35) 45%, rgba(255, 20, 40, 0.5) 50%, rgba(255, 20, 40, 0.35) 55%, transparent);
  animation: lockSweep 0.9s ease-in forwards;
}

/* ---------- payload sequence FLIP transitions ---------- */
.flip-moving { transition: transform 0.32s cubic-bezier(0.22, 1, 0.36, 1); }

/* ---------- modal entrance ---------- */
@keyframes modalIn {
  from { transform: translateY(26px) scale(0.94); opacity: 0; }
  to   { transform: none; opacity: 1; }
}
#modal { animation: modalIn 0.4s cubic-bezier(0.22, 1, 0.36, 1); }

/* ---------- prep screen entrance stagger ---------- */
@keyframes riseIn {
  from { transform: translateY(16px); opacity: 0; }
  to   { transform: none; opacity: 1; }
}
.rise-in { animation: riseIn 0.4s cubic-bezier(0.22, 1, 0.36, 1) backwards; }

/* ---------- big breathing activation glows ---------- */
@keyframes breatheGlow {
  0%, 100% {
    box-shadow: 0 0 6px var(--glow-c), 0 0 0 1px var(--glow-c);
    transform: scale(1);
  }
  50% {
    box-shadow: 0 0 26px var(--glow-c), 0 0 48px var(--glow-c2, transparent), 0 0 0 2px var(--glow-c);
    transform: scale(1.025);
  }
}

/* spike just fired: huge cyan breathing highlight */
.spike-row.spike-activated {
  --glow-c: rgba(63, 217, 255, 0.75);
  --glow-c2: rgba(63, 217, 255, 0.25);
  border-color: var(--cyan);
  animation: breatheGlow 1.1s ease-in-out infinite;
  z-index: 2;
}

/* crew armed: persistent green breathing glow while the selected hand satisfies them */
.crew-row.crew-armed {
  --glow-c: rgba(65, 245, 143, 0.6);
  --glow-c2: rgba(65, 245, 143, 0.2);
  border-color: var(--green);
  animation: breatheGlow 1.6s ease-in-out infinite;
  opacity: 1 !important;
  z-index: 2;
}
.crew-row.crew-armed .crew-state { background: #0a2a1c; color: var(--green); border-color: var(--green); }

/* ---------- fly-out exits ---------- */
@keyframes flyToAi {
  0% { transform: none; opacity: 1; }
  100% { transform: translateY(-130vh) rotate(14deg) scale(0.75); opacity: 0; }
}
.fly-to-ai { animation: flyToAi 0.3s cubic-bezier(0.5, 0, 0.9, 0.4) forwards !important; pointer-events: none; }

@keyframes flyDiscard {
  0% { transform: none; opacity: 1; }
  100% { transform: translateY(120vh) rotate(-20deg) scale(0.8); opacity: 0.2; }
}
.fly-discard { animation: flyDiscard 0.3s cubic-bezier(0.5, 0, 0.9, 0.4) forwards !important; pointer-events: none; z-index: 7; }

/* stage payload clone that already resolved */
#stage .stage-pcard.resolved { border-color: var(--cat, var(--gold)); }

/* center-stage idle: payloads and played cards hover as one readable attack packet */
@keyframes stageHover {
  0%, 100% { transform: translateY(0) rotate(0deg); }
  50% { transform: translateY(-7px) rotate(0.35deg); }
}

@keyframes targetFocusPulse {
  0%, 100% { filter: brightness(1); }
  50% { filter: brightness(1.35); }
}
.target-focus {
  animation: targetFocusPulse 0.65s ease-in-out infinite;
}

/* ---------- resolving lock ---------- */
#screen-game.resolving #hand-cards,
#screen-game.resolving #payload-hand,
#screen-game.resolving #sequence-slots,
#screen-game.resolving #actions .btn:not(#btn-restart) {
  pointer-events: none;
}
#screen-game.resolving #actions .btn:not(#btn-restart) { opacity: 0.45; }
