/* VHS layer (spec.md > VHS Layer). Strength follows --vhs, set per screen by js/app.js.
   This is the CSS fallback that always works. When WebGL is available, js/crt.js draws the
   richer shader on top and the CSS scanlines step back (html.has-crt). */

/* ── Overlay: scanlines, vignette, slow flicker ─────────────────── */

.vhs {
  border-radius: inherit;
  background:
    repeating-linear-gradient(
      to bottom,
      rgba(0, 0, 0, calc(0.10 + 0.22 * var(--vhs))) 0 1px,
      transparent 1px 3px
    ),
    radial-gradient(ellipse at 50% 50%, transparent 55%, rgba(0, 0, 0, calc(0.35 + 0.25 * var(--vhs))) 100%);
  animation: vhs-flicker 6s ease-in-out infinite;
}

@keyframes vhs-flicker {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: calc(1 - 0.08 * var(--vhs));
  }
}

/* With the shader running, it draws the scanlines and vignette itself. */
.has-crt .vhs {
  background: none;
  animation: none;
}

.crt {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border-radius: inherit;
  pointer-events: none;
  z-index: 11;
}

/* ── Phosphor glow: text on a CRT bleeds a little light ────────── */

.tv__screen {
  --glow: calc(2px + 4px * var(--vhs));
}

.answer__text,
.first__text,
.timer,
.blue__play,
.saved__title,
.early__text {
  text-shadow:
    0 0 var(--glow) rgba(217, 222, 232, calc(0.25 + 0.25 * var(--vhs))),
    calc(0.6px * var(--vhs)) 0 0 rgba(255, 60, 60, calc(0.35 * var(--vhs))),
    calc(-0.6px * var(--vhs)) 0 0 rgba(60, 120, 255, calc(0.35 * var(--vhs)));
}

/* ── Glitch: a short shift and red/blue split on each revealed answer ─ */

.glitch {
  animation: vhs-glitch 300ms steps(1, end);
}

@keyframes vhs-glitch {
  0% {
    transform: translateX(-6px) skewX(-4deg);
    filter: drop-shadow(3px 0 0 rgba(255, 50, 50, 0.8)) drop-shadow(-3px 0 0 rgba(50, 110, 255, 0.8));
    clip-path: inset(0 0 55% 0);
  }
  25% {
    transform: translateX(5px);
    filter: drop-shadow(-2px 0 0 rgba(255, 50, 50, 0.7)) drop-shadow(2px 0 0 rgba(50, 110, 255, 0.7));
    clip-path: inset(40% 0 0 0);
  }
  50% {
    transform: translateX(-3px);
    filter: drop-shadow(2px 0 0 rgba(255, 50, 50, 0.5)) drop-shadow(-2px 0 0 rgba(50, 110, 255, 0.5));
    clip-path: inset(0);
  }
  75% {
    transform: translateX(1px);
    filter: none;
  }
  100% {
    transform: none;
    filter: none;
  }
}

/* ── Screen change: freeze, then glitch (js/motion.js > switchGlitch) ── */

/* The old picture, frozen. It sits over the new screen (under the VHS layers) and takes no clicks. */
.freeze {
  position: absolute;
  inset: 0;
  z-index: 9;
  pointer-events: none;
  border-radius: inherit;
  background: radial-gradient(ellipse at 50% 45%, #0b1222 0%, var(--glass) 70%);
  animation: vhs-freeze 340ms steps(1, end) forwards;
}

.freeze--blue {
  background: var(--vcr-blue);
}

/* A held VHS frame shows a thin noise bar near the bottom. */
.freeze::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: 78%;
  height: 7px;
  background: repeating-linear-gradient(90deg, rgba(255, 255, 255, 0.35) 0 3px, transparent 3px 7px, rgba(255, 255, 255, 0.15) 7px 9px, transparent 9px 14px);
  opacity: 0.8;
}

/* 0–40 %: still. Then bands of the old picture jump sideways with a red/blue split, the new screen
   showing through the gaps, until the old picture is gone. Stepped, so it cuts like tape, not slides. */
@keyframes vhs-freeze {
  0%,
  39% {
    transform: none;
    filter: none;
    clip-path: inset(0 0 0 0);
    opacity: 1;
  }
  40% {
    transform: translateX(-14px);
    filter: drop-shadow(4px 0 0 rgba(255, 50, 50, 0.85)) drop-shadow(-4px 0 0 rgba(50, 110, 255, 0.85));
    clip-path: inset(0 0 58% 0);
  }
  55% {
    transform: translateX(10px);
    filter: drop-shadow(-3px 0 0 rgba(255, 50, 50, 0.8)) drop-shadow(3px 0 0 rgba(50, 110, 255, 0.8));
    clip-path: inset(30% 0 34% 0);
  }
  70% {
    transform: translateX(-6px);
    filter: drop-shadow(2px 0 0 rgba(255, 50, 50, 0.7)) drop-shadow(-2px 0 0 rgba(50, 110, 255, 0.7));
    clip-path: inset(66% 0 6% 0);
  }
  85%,
  100% {
    transform: none;
    filter: none;
    clip-path: inset(100% 0 0 0);
    opacity: 0;
  }
}

/* The new screen jitters once as the picture locks on, after the freeze. */
.lock-on {
  animation: vhs-lock-on 200ms steps(1, end) 140ms;
}

@keyframes vhs-lock-on {
  0% {
    transform: translateX(6px);
    filter: drop-shadow(-2px 0 0 rgba(255, 50, 50, 0.6)) drop-shadow(2px 0 0 rgba(50, 110, 255, 0.6));
  }
  50% {
    transform: translateX(-3px);
    filter: none;
  }
  100% {
    transform: none;
    filter: none;
  }
}

/* ── Blue VCR screen: a loading bar, like a tape being read ─────── */

/* Fixed-size cells that light up one by one, left to right: real progress, never stretched. */
.blue__bar {
  display: grid;
  grid-template-columns: repeat(20, 1fr);
  gap: 3px;
  width: min(320px, 60%);
  height: 22px;
  margin-top: 22px;
  padding: 3px;
  border: 2px solid #ffffff;
}

.blue__cell {
  background: #ffffff;
  opacity: 0;
}

.blue__cell.is-on {
  opacity: 1;
}

/* ── Reduced motion: flicker and glitch off, scanlines stay ─────── */

@media (prefers-reduced-motion: reduce) {
  .vhs {
    animation: none;
  }

  .glitch,
  .freeze,
  .lock-on {
    animation: none;
  }
}

/* The same, chosen in the room controls (html.reduce-motion, set by js/prefs.js). */
.reduce-motion .vhs,
.reduce-motion .glitch,
.reduce-motion .freeze,
.reduce-motion .lock-on {
  animation: none;
}

/* High contrast: the scanlines and the shader layer step back so the text stands out. */
.high-contrast .crt {
  opacity: 0.35;
}
