/*
 * transition.css — the `c` key. All three effects, one choreography, ~900ms.
 *
 *   0-250ms   CRT glitch burst covers the board
 *   150-450ms pieces dissolve out / discs bloom in (staggered wave)
 *   250-750ms the board flips in 3D and the other game is on the back
 *   650-900ms everything settles
 *
 * Piece counts don't match (32 chess pieces vs <=24 discs on dark squares only),
 * so there is no 1:1 mapping. A staggered whole-layer dissolve hides that entirely.
 * Transform + opacity + filter only. Nothing here touches layout.
 */

#crt-overlay {
  position: absolute; inset: -4%;
  z-index: 60;
  opacity: 0;
  pointer-events: none;
  border-radius: 12px;
  background:
    repeating-linear-gradient(0deg, rgba(255,255,255,.10) 0 1px, transparent 1px 3px),
    linear-gradient(105deg, rgba(0,255,255,.16), rgba(255,0,128,.16));
  mix-blend-mode: screen;
  will-change: opacity, transform, filter;
}
#crt-overlay.fire { animation: crtGlitch 260ms steps(2, end) 1; }

@keyframes crtGlitch {
  0%   { opacity: 0;  transform: translate3d(0,0,0)            }
  10%  { opacity: .95; transform: translate3d(-3px, 2px, 0); filter: hue-rotate(25deg) contrast(1.5) }
  25%  { opacity: .8;  transform: translate3d(4px, -3px, 0);  filter: hue-rotate(-40deg) contrast(1.25) }
  40%  { opacity: .95; transform: translate3d(-2px, -1px, 0); filter: hue-rotate(60deg) saturate(1.6) }
  60%  { opacity: .7;  transform: translate3d(2px, 1px, 0);   filter: none }
  100% { opacity: 0;   transform: translate3d(0,0,0);         filter: none }
}

/* The flip. 900ms total but the rotation itself owns 250-750. */
#board-3d.flipping { animation: boardFlip 620ms cubic-bezier(.65,.02,.32,1) 240ms 1 both; }
#board-3d.flipping.back { animation-name: boardFlipBack; }

@keyframes boardFlip     { from { transform: rotateY(0deg)   } to { transform: rotateY(180deg) } }
@keyframes boardFlipBack { from { transform: rotateY(180deg) } to { transform: rotateY(360deg) } }

/* Resting state for whichever face is showing. */
#board-3d.show-back { transform: rotateY(180deg); }

/* The dissolve. --i is the cell index; the wave reads diagonally. */
.morph-out { animation: morphOut 300ms ease-in 150ms both; animation-delay: calc(150ms + var(--i, 0) * 6ms); }
.morph-in  { animation: morphIn  340ms cubic-bezier(.2,.9,.3,1.3) both; animation-delay: calc(300ms + var(--i, 0) * 6ms); }

@keyframes morphOut { to   { opacity: 0; transform: scale(.55) rotate(-8deg) } }
@keyframes morphIn  {
  from { opacity: 0; transform: scale(.55) }
  70%  { opacity: 1; transform: scale(1.03) }
  to   { opacity: 1; transform: scale(1) }
}

/* Ignore input for the duration; Switcher.busy also guards in JS. */
#stage.switching { pointer-events: none; }

@media (prefers-reduced-motion: reduce) {
  /* Same commit path, no theatre — a 120ms crossfade. State must never diverge. */
  #crt-overlay.fire { animation: none; }
  #board-3d.flipping, #board-3d.flipping.back { animation: none !important; }
  #board-3d.show-back { transform: none; }
  .face-back { transform: none; }
  .morph-out { animation: rmFade 120ms ease-out both; }
  .morph-in  { animation: rmFadeIn 120ms ease-out both; }
  @keyframes rmFade   { to { opacity: 0 } }
  @keyframes rmFadeIn { from { opacity: 0 } to { opacity: 1 } }
}
