:root {
  --clarity: 0;        /* 0 = fully hidden; rises toward the cap; never reaches 1 */
  --base-blur: 26px;   /* blur applied to items at clarity 0 */
  --mx: 50%;           /* cursor x, updated by main.js */
  --my: 50%;           /* cursor y */
}

* { box-sizing: border-box; margin: 0; padding: 0; }

html, body {
  height: 100%;
  background: #040405;
  overflow: hidden;
  cursor: crosshair;
}

#stage {
  position: fixed;
  inset: 0;
  background: radial-gradient(ellipse at center, #111114 0%, #040405 75%, #000 100%);
}

/* Isolate so item z-indexes stay contained here (1..999) instead of lifting above
   the grain/vignette/text layers. The whole collage sits at z-index 2 — above the
   text (which images can therefore cover), below the global grain + vignette. */
#collage { position: absolute; inset: 0; isolation: isolate; z-index: 2; }

/* A scattered media item. Centered on its (left, top) point and rotated. */
.item {
  position: absolute;
  transform: translate(-50%, -50%) rotate(var(--rot, 0deg));
  opacity: 0;
  filter: blur(calc(var(--base-blur) * (1 - var(--clarity)))) grayscale(0.7) brightness(0.85);
  transition: opacity 2.5s ease;
  box-shadow: 0 6px 40px rgba(0, 0, 0, 0.7);
  overflow: hidden;                /* clip VHS overlays + displaced edges to the frame */
  will-change: filter, opacity;
}
.item.revealed { opacity: calc(0.25 + 0.6 * var(--clarity)); }
.item img, .item video { display: block; width: 100%; height: auto; }

/* Hover is the ONLY clarity — and it arrives as a broken VHS/CRT signal.
   The media element runs through the #vhs SVG displacement filter (warp +
   horizontal tearing) plus a heavy chroma split; ::before carries scanlines +
   a rolling tracking band, ::after carries flickering signal snow. The figure
   blur is dropped (filter: none) so the picture is sharp-but-corrupted, and a
   judder keyframe fakes a signal that won't lock. z-index is raised in main.js. */
.item.vhs {
  filter: none;                                   /* drop the ambient blur — this is the clarity */
  opacity: 1;                                     /* fully present on hover, regardless of dwell time */
  transition: opacity 0.12s ease;                 /* snap in on hover; base 2.5s fades it back on leave */
  animation: vhs-roll 4.5s linear infinite;
}
.item.vhs img,
.item.vhs video {
  filter: url(#vhs)
          drop-shadow(4px 0 rgba(255, 0, 60, 0.85))
          drop-shadow(-4px 0 rgba(0, 229, 255, 0.85))
          contrast(1.35) saturate(1.3) brightness(0.95);
}

/* Scanlines (static) + the bright rolling tracking band (animated, layer 1). */
.item.vhs::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 2;
  background-image:
    /* tracking band */
    linear-gradient(
      to bottom,
      transparent 0%,
      rgba(255, 255, 255, 0.22) 44%,
      rgba(255, 255, 255, 0.55) 50%,
      rgba(255, 255, 255, 0.22) 56%,
      transparent 100%
    ),
    /* scanlines */
    repeating-linear-gradient(
      to bottom,
      rgba(0, 0, 0, 0.40) 0px,
      rgba(0, 0, 0, 0.40) 1px,
      transparent 1px,
      transparent 3px
    );
  background-repeat: no-repeat, repeat;
  background-size: 100% 22%, 100% 3px;
  background-position: 0 -30%, 0 0;
  mix-blend-mode: screen;
  animation: vhs-track 1.8s linear infinite;
}

/* Flickering signal snow (animated, on its own layer to avoid background-position clashes). */
.item.vhs::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 3;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='s'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23s)'/%3E%3C/svg%3E");
  background-size: 110px 110px;
  mix-blend-mode: screen;
  opacity: 0.65;
  animation: vhs-snow 0.18s steps(2) infinite;
}

@keyframes vhs-roll {
  /* MUST keep translate(-50%,-50%) + rotate(var(--rot)) or the item un-centers. */
  0%, 86%  { transform: translate(-50%, -50%) rotate(var(--rot)); }
  88%      { transform: translate(calc(-50% - 2px), calc(-50% - 9px)) rotate(var(--rot)); }
  90%      { transform: translate(calc(-50% + 2px), calc(-50% + 3px)) rotate(var(--rot)); }
  92%, 100% { transform: translate(-50%, -50%) rotate(var(--rot)); }
}
@keyframes vhs-track {
  /* Bright band sweeps top -> bottom; scanline layer holds still. */
  0%   { background-position: 0 -30%, 0 0; }
  100% { background-position: 0 130%, 0 0; }
}
@keyframes vhs-snow {
  0%   { background-position: 0 0; }
  50%  { background-position: -41px 17px; }
  100% { background-position: 23px -11px; }
}

/* Global film grain — thins as clarity rises but never disappears. At z-index 3
   it sits above the collage, so it grains EVERYTHING uniformly: text, ambient
   images, and the hovered/glitching image alike. */
#grain {
  position: absolute;
  inset: -50%;
  pointer-events: none;
  z-index: 3;
  opacity: calc(0.5 - 0.25 * var(--clarity));
  mix-blend-mode: overlay;
  background-size: 180px 180px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  animation: grainshift 0.6s steps(3) infinite;
}
@keyframes grainshift {
  0% { transform: translate(0, 0); }
  33% { transform: translate(-3%, 2%); }
  66% { transform: translate(2%, -2%); }
  100% { transform: translate(0, 0); }
}

/* Darkness that follows the cursor — a small clear pool, black beyond. Top layer. */
#vignette {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 4;
  background: radial-gradient(circle at var(--mx) var(--my),
    transparent 0%, transparent 22%, rgba(0, 0, 0, 0.85) 75%);
}

/* Below the collage (z-index 1) so images can cover the text as they reveal. */
#text-layer { position: absolute; inset: 0; pointer-events: none; z-index: 1; }

/* First-person glitch fragments. */
.fragment {
  position: absolute;
  transform: translate(-50%, -50%);
  font-family: ui-monospace, "SFMono-Regular", Menlo, monospace;
  font-size: clamp(14px, 2.4vw, 28px);
  letter-spacing: 3px;
  white-space: nowrap;
  color: #c9ccd6;
  text-shadow: 1.5px 0 #b1003a, -1.5px 0 #1aa0c4;
  opacity: 0;
  animation: frag 7s ease forwards;
}
.fragment.urgent {
  color: #fff;
  font-size: clamp(18px, 3.4vw, 40px);
  text-shadow: 2.5px 0 #ff003c, -2.5px 0 #00e5ff;
}
@keyframes frag {
  0% { opacity: 0; }
  12% { opacity: 0.85; }
  18% { opacity: 0.2; }
  24% { opacity: 0.8; }
  80% { opacity: 0.7; }
  100% { opacity: 0; }
}
