/* effects.css — fumée, vignette, grain, tonnerre, shake, screamer */

/* ── Décors de pièce (2 couches en fondu enchaîné, tout au fond) ── */
.fx-bg {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-size: cover;
  background-position: center;
  opacity: 0;
  transition: opacity 900ms ease;
}

.fx-bg.is-visible {
  opacity: 1;
}

/* scrim permanent : les décors restent des FONDS, le texte reste roi (CONTRAST-1) */
.fx-bg::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(ellipse at 50% 45%, rgba(10, 8, 18, 0.45) 0%, rgba(10, 8, 18, 0.78) 100%);
}

/* ── Fumée (canvas particules, au-dessus du décor, sous l'UI) ── */
#fx-fog {
  position: fixed;
  inset: 0;
  z-index: 1;
  width: 100vw;
  height: 100vh;
  pointer-events: none;
}

/* ── Vignette « Visage » (statique, coût zéro) ── */
#fx-vignette {
  position: fixed;
  inset: 0;
  z-index: 5;
  pointer-events: none;
  background: radial-gradient(ellipse at 50% 45%, transparent 55%, rgba(0, 0, 0, 0.55) 100%);
}

/* ── Grain film (PNG bruit tuilé, animation steps) ── */
#fx-grain {
  position: fixed;
  inset: -64px;
  z-index: 6;
  pointer-events: none;
  background: url("../images/web/grain.png") repeat;
  opacity: 0.05;
  animation: grain-shift 900ms steps(10) infinite;
}

@keyframes grain-shift {
  0% { transform: translate(0, 0); }
  20% { transform: translate(-18px, 12px); }
  40% { transform: translate(10px, -22px); }
  60% { transform: translate(-24px, -8px); }
  80% { transform: translate(16px, 18px); }
  100% { transform: translate(0, 0); }
}

/* ── Flash tonnerre ── */
#fx-thunder {
  position: fixed;
  inset: 0;
  z-index: 50;
  pointer-events: none;
  background: #eef0ff;
  opacity: 0;
}

#fx-thunder.is-flashing {
  animation: thunder-flash 550ms ease-out both;
}

@keyframes thunder-flash {
  0% { opacity: 0; }
  8% { opacity: 0.95; }
  20% { opacity: 0.05; }
  32% { opacity: 0.5; }
  100% { opacity: 0; }
}

/* ── Shake du plateau ── */
#stage.is-shaking {
  animation: stage-shake 450ms ease-in-out both;
}

@keyframes stage-shake {
  0%, 100% { transform: translate(0, 0) rotate(0); }
  15% { transform: translate(-8px, 4px) rotate(-0.4deg); }
  30% { transform: translate(7px, -5px) rotate(0.4deg); }
  45% { transform: translate(-6px, -4px) rotate(-0.3deg); }
  60% { transform: translate(5px, 5px) rotate(0.3deg); }
  75% { transform: translate(-3px, 2px) rotate(-0.15deg); }
}

/* ── Screamer ── */
#fx-screamer {
  position: fixed;
  inset: 0;
  z-index: 100;
  background: #000;
  display: none;
}

#fx-screamer.is-active {
  display: block;
  animation: screamer-in 120ms steps(2) both;
}

@keyframes screamer-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

#screamer-visual {
  position: absolute;
  inset: 0;
  background-repeat: no-repeat;
}

#fx-screamer.is-jittering #screamer-visual {
  animation: screamer-jitter 90ms steps(2) infinite;
}

@keyframes screamer-jitter {
  0% { transform: scale(1) translate(0, 0); }
  25% { transform: scale(1.04) translate(-14px, 8px); }
  50% { transform: scale(1) translate(12px, -10px); }
  75% { transform: scale(1.05) translate(-8px, -12px); }
  100% { transform: scale(1.02) translate(10px, 10px); }
}

/* ── Repli reduced-motion : le screamer reste une image fixe, sans strobe ── */
@media (prefers-reduced-motion: reduce) {
  #fx-grain {
    animation: none;
  }
  #fx-screamer.is-active {
    animation: none;
    opacity: 1;
  }
}
