/* One readable beat at a time, on the existing photographed paper. These
   timings all fit INSIDE Royale's existing 1600ms protected explosion phase.
   No control, life total, game deadline, geometry or fuse timing changes. */

/* Round 2: the last photographed fragments used to stay fully opaque until
   the 960ms cleanup. Preserve shipping-impact's four held atlas poses and
   its exact footprint; only their common matte envelope retires softly.
   The single-frame material fallback keeps its own earlier animation. */
#zineRoyaleApp.bomtafel:not([data-material-state="fallback"])[data-phase="exploding"] .bomb-burst {
  animation: shipping-impact 960ms steps(1, end) both,
    finish-burst-clear 960ms linear both;
}
@keyframes finish-burst-clear {
  0%, 58% { opacity: 1; animation-timing-function: ease-out; }
  100% { opacity: 0; }
}

#zineRoyaleApp.bomtafel[data-phase="exploding"] .royale-result {
  animation: finish-royale-result 280ms steps(1, end) 360ms both;
}
@keyframes finish-royale-result {
  0% { opacity: 0; transform: translateY(5px) rotate(.6deg); }
  14% { opacity: 1; transform: translateY(5px) rotate(.6deg); }
  50% { opacity: 1; transform: translateY(-1px) rotate(-.2deg); }
  78%, 100% { opacity: 1; transform: none; }
}

/* The card is fully landed before its missing life blinks. All three lives
   are shown first; centre and score card share this exact clock. Keep this
   selector across roundEnd so a phase publication cannot replay the loss.
   The native after-value is always present in the accessible DOM. */
#zineRoyaleApp.bomtafel .paper-heart[data-losing="true"] {
  animation: finish-heart-loss 1400ms steps(1, end) both;
}
@keyframes finish-heart-loss {
  0%, 48% { opacity: 1; transform: none; }
  56% { opacity: .12; transform: none; }
  66% { opacity: 1; transform: none; }
  80% { opacity: var(--empty-heart, .17); transform: translate(8%, 22%) rotate(12deg); }
  90%, 100% { opacity: var(--empty-heart, .17); transform: none; }
}

/* Resuming a hidden/covered result shows its current outcome, never a second
   life disappearing. Stage motion writes only this presentation marker; a
   fresh visible explosion/winner clears it. No animationend is required. */
#zineRoyaleApp.bomtafel[data-stage-result-settled="true"] .paper-heart[data-losing="true"] {
  animation: none !important;
  opacity: var(--empty-heart, .17);
  transform: none;
}
#zineRoyaleApp.bomtafel[data-stage-result-settled="true"]:is([data-phase="exploding"], [data-phase="roundEnd"], [data-phase="matchEnd"]) .royale-result {
  animation: none !important;
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce), (forced-colors: active) {
  #zineRoyaleApp.bomtafel[data-phase="exploding"] .royale-result {
    animation: none !important; opacity: 1; transform: none;
  }
  #zineRoyaleApp.bomtafel .paper-heart[data-losing="true"] {
    animation: none !important; opacity: var(--empty-heart, .17); transform: none;
  }
}
