/* alive/grain.css - depth atmosphere: gradient + grain composed (v1, 18 Jul 2026)
   Why: flat single-accent has no depth model; a gradient without grain reads as unfinished.
   Technique: feTurbulence fractalNoise as a DISPLACEMENT map on a pseudo-element BEHIND
   content (not a noise overlay, which darkens/oversaturates) - text and shadows stay crisp.

   Usage:
     <section class="alive-atmosphere" style="--atmo-a:#0f1420; --atmo-b:#1d2b4a; --atmo-glow:#ff5c00">
   Content inside needs position:relative (or use .alive-atmosphere > * default below). */

.alive-atmosphere {
  position: relative;
  isolation: isolate;
  overflow: clip; /* the ::before bleeds -40px for displaced edges; never leak scroll width */
  background: var(--atmo-a, #0f1420);
}
.alive-atmosphere > * { position: relative; z-index: 1; }

/* Layer 1: the composed gradient + glow */
.alive-atmosphere::before {
  content: "";
  position: absolute;
  inset: -40px;                 /* bleed so displaced edges never show */
  z-index: 0;
  background:
    radial-gradient(60% 50% at 72% 18%,
      color-mix(in srgb, var(--atmo-glow, #ff5c00) 26%, transparent), transparent 70%),
    radial-gradient(80% 70% at 15% 85%,
      color-mix(in srgb, var(--atmo-b, #1d2b4a) 85%, transparent), transparent 75%),
    linear-gradient(160deg, var(--atmo-a, #0f1420), var(--atmo-b, #1d2b4a));
  filter: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg'><filter id='g'><feTurbulence type='fractalNoise' baseFrequency='0.97' numOctaves='3' stitchTiles='stitch' result='n'/><feDisplacementMap in='SourceGraphic' in2='n' scale='120' xChannelSelector='R' yChannelSelector='G'/></filter></svg>#g");
}

/* Layer 2: fine static grain veil at low opacity (breaks any remaining banding) */
.alive-atmosphere::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: 0.05;
  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='4' stitchTiles='stitch'/></filter><rect width='120' height='120' filter='url(%23n)'/></svg>");
  background-size: 120px 120px;
  mix-blend-mode: overlay;
}

/* Light-surface variant: softer glow, grain only */
.alive-atmosphere--light {
  background: var(--atmo-a, #faf8f4);
}
.alive-atmosphere--light::before {
  background:
    radial-gradient(55% 45% at 70% 12%,
      color-mix(in srgb, var(--atmo-glow, #ff5c00) 12%, transparent), transparent 70%),
    linear-gradient(165deg, var(--atmo-a, #faf8f4), var(--atmo-b, #efe9df));
}
.alive-atmosphere--light::after { opacity: 0.035; mix-blend-mode: multiply; }
