/* ============================================================
   usestop v2 — grain system (two layers)
   Layer 1: always-on SVG fractalNoise on body::after, 5%, overlay
   Layer 2: scroll-reactive intensity via --grain-intensity custom
            property (set by JS based on viewport/section).
   Owned by Garth. Include AFTER typography-v2.css.
   ============================================================ */

:root {
  /* JS writes 0.03 .. 0.12 here. Default 0.05 = hero baseline. */
  --grain-intensity: 0.05;
  --grain-scale: 0.9;
}

/* ---- Layer 1: always-on fine grain -------------------------- */
body.v2::after {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 9998;
  opacity: 0.05;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='220' height='220'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch' seed='7'/><feColorMatrix values='0 0 0 0 0.96  0 0 0 0 0.94  0 0 0 0 0.90  0 0 0 0.55 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
  background-size: 220px 220px;
}

/* ---- Layer 2: scroll-reactive coarser grain ----------------- */
body.v2::before {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 9997;
  opacity: var(--grain-intensity);
  mix-blend-mode: soft-light;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='340' height='340'><filter id='n2'><feTurbulence type='fractalNoise' baseFrequency='0.35' numOctaves='3' stitchTiles='stitch' seed='3'/><feColorMatrix values='0 0 0 0 1  0 0 0 0 0.78  0 0 0 0 0.55  0 0 0 0.8 0'/></filter><rect width='100%' height='100%' filter='url(%23n2)'/></svg>");
  background-size: calc(340px * var(--grain-scale)) calc(340px * var(--grain-scale));
  transition: opacity 220ms ease-out;
}

/* per-section intensity hints — JS reads section data-grain
   and writes --grain-intensity; these class hooks let Worker
   set default intensities declaratively on the section wrapper.
*/
.v2 [data-grain="hero"]    { --grain-intensity-target: 0.11; }
.v2 [data-grain="cta"]     { --grain-intensity-target: 0.12; }
.v2 [data-grain="reading"] { --grain-intensity-target: 0.03; }
.v2 [data-grain="gallery"] { --grain-intensity-target: 0.06; }

/* reduced motion: freeze scroll-reactive layer at its mid value
   to avoid motion cues from opacity oscillation */
@media (prefers-reduced-motion: reduce) {
  body.v2::before { opacity: 0.055; transition: none; }
}

/* high-density screens — smaller repeat tile so grain doesn't
   look blocky on 3x retina */
@media (min-resolution: 2dppx) {
  :root { --grain-scale: 0.7; }
}
