/* bg-v2.css - neutral "Graphite" page background.
 *
 * Repaints the fixed full-viewport backdrop (div.bg) from EverWonder's indigo/electric-blue
 * to a neutral near-black -> mid-grey. Owner-directed, 27 Aug 2026: "change the blue and
 * purple color gradient in the background to something more dark, maybe dark grey".
 * Chosen from six rendered variants (see _preview-bg-grey.html) - variant 2, "Graphite".
 *
 * WHY THIS IS A SEPARATE FILE, AND WHY THE SELECTORS CARRY .bg
 *
 * The rules being overridden live in an inline <style> in the BODY of the captured page
 * (index.html, in the .css-embed block that follows the bg-shape divs). This stylesheet is
 * linked from <head>, so it loses any same-specificity cascade tie on document order. Each
 * selector below is therefore scoped to the .bg ancestor - (0,2,0) against the source's
 * (0,1,0) - which wins on specificity without needing !important.
 *
 * WHAT ACTUALLY PRODUCES THE COLOUR
 *
 * Two things, and both have to move together:
 *
 *   1. [data-bg-layer="dark"] is the flat base gradient.
 *   2. left-dark / right-dark are blurred (49px) streaks composited with
 *      mix-blend-mode: color-dodge at 0.4 opacity. Dodge is what turned a merely-navy
 *      base into the vivid electric blue, and what pushed the upper half violet.
 *
 * Retinting only the base leaves the dodge streaks pulling their own hue back through it.
 * The streak colours below are neutral greys precisely so the dodge stays a brightness
 * effect rather than a colour one.
 *
 * DELIBERATELY NOT TOUCHED
 *
 *   - [data-bg-layer="light"], left-glow and right-light. Those belong to the light theme
 *     state, which only section_capabilities triggers; the theme JS animates their opacity.
 *   - body's background-color, which is var(--_theme---background). .bg is
 *     position:fixed/inset:0 and body sets overscroll-behavior:none, so it never shows.
 *     Overriding the token would reach the light theme and the nav/button tints that
 *     derive from the same midnight-blue swatch.
 */

.bg [data-bg-layer="dark"] {
  background: linear-gradient(180deg, #0f0f11 30%, #4a4e55 100%), #0f0f11;
}

.bg [data-shape-id="left-dark"],
.bg [data-shape-id="right-dark"] {
  background: linear-gradient(181deg, #b9bfc7 0%, #3a3e44 100%);
}

/* THE GRAIN LAYER - a 512px REPEATING TILE, not a full-viewport image.
 * Paired with STRUCTURAL EDIT 53, which turns `img.bg-noise` into `div.bg-noise`.
 *
 * WHY. The scrape shipped the grain as a 1920x1080 <img> plus a four-step srcset,
 * and it was the heaviest asset on the page by four times: 809,571 B for the 1920w
 * file, and 546,768 B for the 1600w variant that every phone actually picked
 * (sizes="100vw", so a 390px viewport at DPR 3 asks for 1170px and rounds up).
 *
 * It could not be compressed out of that. The RGB planes of that file are pure
 * black - EVERY pixel - and the whole picture lives in the alpha channel as
 * near-white noise: measured autocorrelation +0.24 at lag 1, -0.16 at lag 2, zero
 * by lag 3. Noise is close to incompressible by construction, so re-encoding only
 * trades bytes for grain: AVIF q=20 still weighed 399,560 B and had already sanded
 * the grain's standard deviation down from 49.56 to 46.23. There is no quality
 * setting that gets a full-frame 1920x1080 field of this under 200 KB intact.
 *
 * Tiling does, because the grain has no structure above 3px to repeat. The tile is
 * a literal 512x512 crop of the shipped asset - the same encoder, the same grain,
 * source pixels rather than a regenerated field - and at q=50 it is 104,454 B, or
 * 3.19 bits/px against the original's 3.12, so it is encoded very slightly RICHER
 * than the file it replaces. Grain std 49.37 vs 49.56; lag-1/2/3 autocorrelation
 * matches to three decimals. Composited at the real .3 opacity / soft-light over
 * the real backdrop and amplified 6x, the repeat is not findable by eye.
 *
 * Net: 809,571 -> 104,454 B on desktop, 546,768 -> 104,454 B on phones, and the
 * four _responsive/ variants are no longer referenced at all (they stay on disk,
 * unreferenced, like the other dormant assets).
 *
 * WHY background-size IS EXPLICIT. `auto` would already resolve to the intrinsic
 * 512x512, so this pins behaviour we are relying on rather than changing it. The
 * tile is laid out in CSS px, so a DPR-2 screen upscales it 2x - exactly what the
 * 1920w image did on a 1920px DPR-2 viewport before.
 *
 * z-index, opacity: .3 and mix-blend-mode: soft-light all still come from the
 * source sheet's `.bg-noise` rule, which applies to a div unchanged; only
 * object-fit is now inert. Nothing else about the layer moves.
 */
.bg .bg-noise {
  background-image: url("../images/noise-tile-512.avif");
  background-repeat: repeat;
  background-size: 512px 512px;
}
