/* wrong-hour.css — synthesized SFX/VFX ("the wrong hour"), K208
   NO-PIN auto-deploying component. Progressive: JS off -> no effects, page
   identical (homepage D1 zero-JS invariant holds — nothing here is required).

   ONE DIAL: --wh-rot (0..1) = time-of-day bleed x user VFX intensity, set by JS.
   Color-only degradation — the ambient tint uses mix-blend-mode:color, so
   LIGHTNESS is held: contrast and legibility never drop (trap #20 ported).
   Interaction one-shots (.wh-fx stage + .wh-glitch heading kick) scale by
   --wh-fxi / --wh-gl (the same 3am swell) — legibility-safe, brief, off under
   prefers-reduced-motion. K207: the [fx] + [synth bed] chips stay clickable even
   when the playlist is switched off. Uses site design tokens. */

:root{ --wh-rot: 0; --wh-abr: 0px; }

/* fixed overlay stack — under the ambient bar (z 100); never intercepts input */
.wh-layer{ position: fixed; inset: 0; pointer-events: none; z-index: 90; }

/* B0 · the bleed — hue + saturation drift toward red, lightness held */
.wh-tint{
  background: var(--c-accent, #c41e3a);
  mix-blend-mode: color;
  opacity: calc(var(--wh-rot) * 0.30);
}

/* B1 · vignette — edges only, legibility-safe */
.wh-vignette{
  background: radial-gradient(120% 100% at 50% 42%, transparent 55%, #000 130%);
  opacity: calc(var(--wh-rot) * 0.55);
}

/* B1 · scanlines — kept low so body text survives */
.wh-scan{
  background: repeating-linear-gradient(0deg,
    rgba(0,0,0,0) 0px, rgba(0,0,0,0) 1px,
    rgba(0,0,0,.5) 2px, rgba(0,0,0,.5) 3px);
  mix-blend-mode: multiply;
  opacity: calc(var(--wh-rot) * 0.16);
}

/* B3 · grain / ash — real canvas noise frames, set + cycled by JS */
.wh-grain{
  background-repeat: repeat;
  background-size: 150px 150px;
  opacity: calc(var(--wh-rot) * 0.6);
}
/* (grain animation is JS-driven — canvas noise frames; see wrong-hour.js buildGrain) */

/* B4-lite · chromatic aberration — headings only, off body text (legibility) */
h1, h2{
  text-shadow:
    calc(var(--wh-abr) * -1) 0 rgba(255,42,60, calc(var(--wh-rot) * .5)),
    var(--wh-abr) 0 rgba(48,120,255, calc(var(--wh-rot) * .42));
  transition: text-shadow 140ms ease-out;   /* lets the glitch kick ease off */
}

/* ---- VFX one-shot stage — interaction effects, one at a time ---- */
/* z 92: above the ambient layers (90), below the ambient bar (100) + boot (300).
   opacity 0 at rest; a modifier class runs a brief keyframe then JS removes it. */
.wh-fx{ position: fixed; inset: 0; pointer-events: none; z-index: 92; opacity: 0; }

/* buttons — a quick CRT brightness flick (screen blend, lightness only) */
@keyframes wh-flick{
  0%,100%{ opacity: 0; }
  8%{ opacity: calc(var(--wh-fxi,.5) * .16); }
  24%{ opacity: calc(var(--wh-fxi,.5) * .05); }
  46%{ opacity: calc(var(--wh-fxi,.5) * .12); }
}
.wh-fx--flick{ background: var(--c-fg, #f0ebe5); mix-blend-mode: screen; animation: wh-flick 200ms steps(6, end); }

/* nav — an accent tint pulse (mix-blend:color holds lightness, legibility-safe) */
@keyframes wh-pulse{ 0%,100%{ opacity: 0; } 30%{ opacity: calc(var(--wh-fxi,.5) * .5); } }
.wh-fx--pulse{ background: var(--c-accent, #c41e3a); mix-blend-mode: color; animation: wh-pulse 320ms ease-out; }

/* burst — a short static / grain flash */
@keyframes wh-burst{ 0%,100%{ opacity: 0; } 30%{ opacity: calc(var(--wh-fxi,.5) * .5); } }
.wh-fx--burst{
  background:
    repeating-linear-gradient(0deg, rgba(0,0,0,.55) 0 1px, transparent 1px 2px),
    repeating-linear-gradient(90deg, rgba(255,255,255,.22) 0 1px, transparent 1px 3px);
  mix-blend-mode: overlay;
  animation: wh-burst 240ms steps(5, end);
}

/* roll — one scanline sweeping down the screen */
@keyframes wh-roll{
  0%{ transform: translateY(-40%); opacity: 0; }
  14%{ opacity: calc(var(--wh-fxi,.5) * .6); }
  100%{ transform: translateY(140%); opacity: 0; }
}
.wh-fx--roll{
  background: linear-gradient(180deg, transparent, rgba(255,255,255,.14) 46%, rgba(255,255,255,.14) 54%, transparent);
  mix-blend-mode: screen; animation: wh-roll 380ms linear;
}

/* bloom — a soft vignette breathe */
@keyframes wh-bloom{ 0%,100%{ opacity: 0; } 40%{ opacity: calc(var(--wh-fxi,.5) * .7); } }
.wh-fx--bloom{ background: radial-gradient(120% 100% at 50% 45%, transparent 50%, #000 130%); animation: wh-bloom 460ms ease-out; }

/* typing — the headings shiver (chromatic kick), scaled by --wh-gl, eased by the base transition */
html.wh-glitch h1, html.wh-glitch h2{
  text-shadow:
    calc(var(--wh-gl,.5) * -3px) 0 rgba(255,42,60,.75),
    calc(var(--wh-gl,.5) * 3px) 0 rgba(48,120,255,.6),
    0 calc(var(--wh-gl,.5) * 1px) rgba(255,255,255,.05);
}

/* B6 · boot / degauss flash — one-shot (JS adds .wh-boot--go) */
.wh-boot{
  position: fixed; inset: 0; z-index: 300; pointer-events: none;
  background: var(--c-fg, #f0ebe5); opacity: 0; transform-origin: 50% 50%;
}
.wh-boot--go{ animation: wh-boot 900ms ease-out forwards; }
@keyframes wh-boot{
  0%{ opacity: .85; transform: scaleY(1); }
  9%{ opacity: .8; transform: scaleY(.005); }   /* collapse to a line */
  24%{ opacity: .6; transform: scaleY(.005); }
  100%{ opacity: 0; transform: scaleY(1); }      /* open */
}

/* FX popover — the [synth bed] + [fx] chips live in the ambient bar (reuse .ambient-btn) */
.wh-panel{
  position: fixed; right: var(--s-3, .75rem); bottom: 3rem; z-index: 101;
  width: min(19rem, 92vw);
  background: var(--c-bg-elevated, #161616);
  border: var(--bw-thin, 1px) solid var(--c-border, #2a2a2a);
  padding: var(--s-3, .75rem);
  font-family: var(--font-mono, monospace); font-size: var(--t-xs, .75rem);
  color: var(--c-fg-muted, #8a847b);
  display: none;
}
.wh-panel[data-open="true"]{ display: block; }
.wh-head{
  display: flex; justify-content: space-between; margin-bottom: .5rem;
  color: var(--c-fg, #f0ebe5); letter-spacing: var(--ls-wide, .06em);
}
.wh-hour{ color: var(--c-accent, #c41e3a); }
.wh-row{ display: flex; align-items: center; gap: var(--s-2, .5rem); margin: .4rem 0; }
.wh-row label{ min-width: 3.4rem; text-transform: uppercase; letter-spacing: var(--ls-wide, .06em); }
.wh-range{ flex: 1; height: 1rem; accent-color: var(--c-accent, #c41e3a); }
.wh-val{ min-width: 2.6rem; text-align: right; color: var(--c-fg-dim, #5a554f); }
.wh-amb{ flex: 1; text-align: left; }
.wh-note{ margin: .6rem 0 0; color: var(--c-fg-dim, #5a554f); font-size: 11px; line-height: 1.45; }
.wh-note b{ color: var(--c-fg-muted, #8a847b); font-weight: 600; }

/* ambience source toggle — accent when the generated bed is live */
.wh-bedchip[aria-pressed="true"], .wh-amb[aria-pressed="true"]{ color: var(--c-accent, #c41e3a); }

/* K207 · keep the [fx] + [synth bed] chips live even when the playlist is off
   (the ambient player sets pointer-events:none on its controls at data-state="off";
   ours are effect controls, not playlist controls). */
.ambient-player[data-state="off"] .wh-chip,
.ambient-player[data-state="off"] .wh-bedchip{
  opacity: 1 !important;
  pointer-events: auto !important;
}

/* a11y — motion off; static tint/vignette stay, audio unaffected */
/* K208 - strangeness ghosts: intrusive words + phantom link destinations.
   Fixed, never intercept input; brief fade in/out, drift up; scaled by --wh-gi
   (the 3am swell). JS gates on the vfx slider + !reduce; also hidden below. */
.wh-ghost{
  position: fixed; z-index: 95; pointer-events: none;
  transform: translate(-50%, -50%);
  font-family: var(--font-mono, monospace);
  font-size: var(--t-sm, .875rem);
  white-space: nowrap; opacity: 0;
  will-change: opacity, transform;
}
.wh-ghost--word{
  color: var(--c-accent, #c41e3a);
  font-family: var(--font-body, Georgia, serif); font-style: italic;
  font-size: var(--t-base, 1rem);
  text-shadow: 0 0 6px rgba(196,30,58,.4);
  animation: wh-ghost-word 820ms ease-in-out forwards;
}
.wh-ghost--link{
  color: var(--c-fg-muted, #8a847b); letter-spacing: var(--ls-wide, .06em);
  text-shadow: 0 0 5px rgba(0,0,0,.6);
  animation: wh-ghost-link 900ms ease-out forwards;
}
@keyframes wh-ghost-word{
  0%{ opacity: 0; transform: translate(-50%, -44%); }
  22%{ opacity: calc(var(--wh-gi,.6) * .85); }
  60%{ opacity: calc(var(--wh-gi,.6) * .62); }
  100%{ opacity: 0; transform: translate(-50%, -64%); }
}
@keyframes wh-ghost-link{
  0%{ opacity: 0; transform: translate(-50%, -46%); }
  30%{ opacity: calc(var(--wh-gi,.6) * .8); }
  100%{ opacity: 0; transform: translate(-50%, -72%); }
}
/* mood cycle button in the [fx] popover (reuses .ambient-btn) */
.wh-mood{ flex: 1; text-align: left; }

@media (prefers-reduced-motion: reduce){
  .wh-grain{ animation: none; }
  .wh-ghost{ display: none !important; }
  .wh-boot, .wh-boot--go{ animation: none !important; opacity: 0 !important; }
  .wh-fx{ display: none !important; }
  h1, h2{ text-shadow: none !important; transition: none !important; }
  html.wh-glitch h1, html.wh-glitch h2{ text-shadow: none !important; }
}
