/* ============================================================================
 * effects.css — atmosphere: scanlines, film grain, vignette, glitch, pulses
 * Decorative only. All overlays are pointer-events:none so they never block taps.
 * ========================================================================= */

.fx {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 50;
  max-width: var(--frame-max);
  margin: 0 auto;
}

/* CRT scanlines */
.fx--scanlines {
  background: repeating-linear-gradient(
    0deg,
    rgba(0, 0, 0, 0) 0px,
    rgba(0, 0, 0, 0) 2px,
    rgba(0, 0, 0, 0.18) 3px,
    rgba(0, 0, 0, 0) 4px
  );
  mix-blend-mode: multiply;
  opacity: 0.6;
}

/* animated film grain (fades slightly as the world warms/awakens) */
.fx--grain {
  opacity: calc(0.14 - var(--awaken) * 0.06);
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='120' height='120'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
  animation: grain 0.6s steps(2) infinite;
}

/* vignette to focus the eye */
.fx--vignette {
  background: radial-gradient(120% 100% at 50% 45%, transparent 55%, rgba(0,0,0,0.6) 100%);
}

/* ---- glitch: applied to #screen-game when ORACLE intrudes ---- */
#screen-game.glitching .bg { animation: glitch-shift 0.65s steps(2) both; }
#screen-game.glitching .dialogue__text,
#screen-game.glitching .dialogue__speaker {
  animation: glitch-text 0.65s steps(2) both;
}
#screen-game.glitching::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 40;
  pointer-events: none;
  background: repeating-linear-gradient(
    0deg, rgba(225,29,143,0.12) 0, rgba(34,211,238,0.12) 2px, transparent 4px);
  mix-blend-mode: screen;
  animation: glitch-flash 0.65s steps(3) both;
}

/* ---- rhythm pulses ---- */
.pulse {
  position: absolute;
  transform: translate(-50%, -50%) scale(0.2);
  border-radius: 50%;
  border: 2px solid var(--accent);
  background: radial-gradient(circle, color-mix(in srgb, var(--glow) 45%, transparent), transparent 70%);
  box-shadow: 0 0 24px var(--glow), inset 0 0 18px var(--glow);
  /* grow + glow across its lifetime (--life set inline by rhythm.js) */
  animation: pulse-life var(--life, 1500ms) linear forwards;
}
.pulse--hit { animation: pulse-hit 0.26s var(--ease) forwards; }
.pulse--miss { animation: pulse-miss 0.22s ease-out forwards; }

/* ============================ keyframes ============================ */
@keyframes blink { 0%, 60% { opacity: 0.7; } 80%, 100% { opacity: 0.15; } }

@keyframes grain {
  0% { transform: translate(0, 0); }
  50% { transform: translate(-4%, 3%); }
  100% { transform: translate(3%, -2%); }
}

@keyframes glitch-shift {
  0% { transform: translate(0,0) scale(1); filter: none; }
  20% { transform: translate(-6px, 2px); filter: hue-rotate(40deg) saturate(2); }
  40% { transform: translate(5px, -3px); filter: hue-rotate(-30deg); }
  60% { transform: translate(-3px, 1px); }
  100% { transform: translate(0,0) scale(1); }
}
@keyframes glitch-text {
  0% { text-shadow: 2px 0 #22d3ee, -2px 0 #e11d8f; }
  50% { text-shadow: -3px 0 #22d3ee, 3px 0 #e11d8f; transform: translateX(2px); }
  100% { text-shadow: 0 0 10px var(--glow); transform: none; }
}
@keyframes glitch-flash { 0%,100% { opacity: 0; } 30%,60% { opacity: 1; } }

@keyframes pulse-life {
  0%   { transform: translate(-50%, -50%) scale(0.2); opacity: 0; }
  30%  { transform: translate(-50%, -50%) scale(1);   opacity: 1; }
  100% { transform: translate(-50%, -50%) scale(1.25); opacity: 0.25; }
}
@keyframes pulse-hit {
  0%   { transform: translate(-50%, -50%) scale(1); opacity: 1; }
  100% { transform: translate(-50%, -50%) scale(1.8); opacity: 0;
         box-shadow: 0 0 60px var(--glow); }
}
@keyframes pulse-miss {
  0%   { opacity: 0.6; }
  100% { transform: translate(-50%, -50%) scale(0.6); opacity: 0; }
}

/* respect reduced-motion preferences */
@media (prefers-reduced-motion: reduce) {
  .fx--grain { animation: none; }
  .bg { transition: opacity 0.6s ease; }
}
