/* ==========================================================================
   atmosphere.css — The atmospheric layer for "The System Underneath" (round 4)
   Owner: pc4 (task 037). Pure presentation. ZERO JavaScript, zero new hex
   values, zero new fonts, zero new origins.

   What this sheet adds, per specs/visual-direction.md §"Atmospherics":
     - a fine film grain over the dark surfaces (CSS-tiled inline SVG noise),
     - engineered "stage light" glow fields on the hero,
     - faint light-from-the-seam transitions where one section meets the next.

   Every colour is derived from an EXISTING token in css/tokens.css via
   color-mix() — the same technique styles.css already uses. No literal colour
   is introduced here. ADVENTURE-DIRECTION.md still governs: no ambient canvas,
   the LCP element stays text.

   Load order: this sheet must come AFTER css/styles.css so its layered
   background-images composite over the section background-colors styles.css
   sets. It only ever ADDS background-image layers (longhand) — it never
   rewrites background-color, so the base surfaces are untouched.

   ---------------------------------------------------------------------------
   MERGE-GATE HOOK (head owns the <head> seam — do NOT self-insert):
     Add, after css/styles.css and before css/adventure.css in index.html:
         <link rel="stylesheet" href="css/atmosphere.css">
     Requested via results/team-notes/pc4-037-r4.md + cc-send to desktop-wsl.
   Until that link lands this file is an intentional stowaway (perf-budget's
   stowaway check will flag it — expected, resolves at merge).
   ========================================================================== */

/* --------------------------------------------------------------------------
   0. Local atmospheric variables — ALL built from existing tokens.
      Nothing below this block references a raw colour; it references these,
      and these reference tokens.css. That is the single seam to audit.
   -------------------------------------------------------------------------- */
:root {
    /* Film grain: a monochrome fractal-noise tile, blended soft-light so it
       reads as texture on the dark ground rather than TV static. Inline data
       URI — no network request, no images/ file needed. */
    --atmo-grain:
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)' opacity='0.5'/%3E%3C/svg%3E");

    /* Engineered light: accent glow at the intensity the blueprint grid uses,
       and a deeper pool for the hero's lower vignette. */
    --atmo-glow: color-mix(in srgb, var(--accent) 12%, transparent);
    --atmo-glow-soft: color-mix(in srgb, var(--accent) 6%, transparent);
    --atmo-vignette: color-mix(in srgb, var(--bg-0) 85%, transparent);

    /* Section seam: a thread of accent light spilling down from where the
       previous section ends. Faint by design. */
    --atmo-seam: color-mix(in srgb, var(--accent) 5%, transparent);
    --atmo-seam-line: color-mix(in srgb, var(--line-hi) 40%, transparent);
}

/* --------------------------------------------------------------------------
   1. Film grain — over the hero and every content section.
      Applied as a background-image LAYER on the element itself; background-color
      (set by styles.css) shows through the grain's soft-light blend. Because it
      lives on the element (not a fixed overlay) it correctly rides above each
      section's opaque surface instead of being hidden behind it.
   -------------------------------------------------------------------------- */
.hero,
.section {
    background-image: var(--atmo-grain);
    background-repeat: repeat;
    background-blend-mode: soft-light;
}

/* Alternating sections keep their bg-1 colour (styles.css .section:nth-child
   (even)); the grain layer above is inherited from .section, so the texture is
   uniform across both surface tones. Nothing to override here — documented so
   the absence of a rule is understood, not assumed missing. */

/* --------------------------------------------------------------------------
   2. Section transition — light from the seam.
      A hairline of accent light + a short glow at the top edge of each section
      marks the transition without any new markup. Painted as extra background
      layers ABOVE the grain, still compositing over background-color.
      background-position/size pin the seam to the top; the grain (last layer)
      tiles the whole box.
   -------------------------------------------------------------------------- */
.section {
    background-image:
        linear-gradient(180deg, var(--atmo-seam) 0, transparent 200px),
        linear-gradient(180deg, var(--atmo-seam-line) 0, var(--atmo-seam-line) 1px, transparent 1px),
        var(--atmo-grain);
    background-repeat: no-repeat, no-repeat, repeat;
    background-position: top center, top center, top left;
    background-size: 100% 200px, 100% 1px, 160px 160px;
    background-blend-mode: normal, normal, soft-light;
}

/* The hero opens the page — no section precedes it, so it gets no seam, only
   grain (rule 1) and its own light field (rule 3). */

/* --------------------------------------------------------------------------
   3. Hero light field — the "stage light" on the dark surface.
      styles.css owns .hero::before (the blueprint grid). This uses the free
      .hero::after, sits below .hero .container (z-index:1), and slowly drifts.
      The drift is the ONLY motion this sheet introduces; §4 neutralises it.
   -------------------------------------------------------------------------- */
.hero::after {
    content: '';
    position: absolute;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    background-image:
        radial-gradient(ellipse 70% 60% at 22% 28%, var(--atmo-glow) 0, transparent 60%),
        radial-gradient(ellipse 90% 70% at 80% 100%, var(--atmo-vignette) 0, transparent 55%);
    animation: atmo-drift 24s ease-in-out infinite alternate;
    will-change: transform, opacity;
}

@keyframes atmo-drift {
    from { transform: translate3d(0, 0, 0); opacity: 0.85; }
    to   { transform: translate3d(2.5%, -1.5%, 0); opacity: 1; }
}

/* --------------------------------------------------------------------------
   4. Reduced motion — atmospherics degrade to fully static.
      The grain and every gradient are already static; only the hero drift
      animates, so it is the one thing to stop. Belt-and-suspenders: the global
      reduce block in styles.css already forces animation-duration to 0.01ms;
      here we also cancel the animation outright and pin the transform so the
      light field rests in its neutral position.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
    .hero::after {
        animation: none;
        transform: none;
        opacity: 1;
        will-change: auto;
    }
}
