/*
 * Retreat landing — grainy blue band utility (decision-log #14)
 *
 * ── R1-3 fix (2026-08-15): SVG synthetic noise replaced with a raster tile ──
 * Alain's call on the assembled page: the SVG feTurbulence noise (fine
 * per-pixel speckle, ~0.5KB) read "not as close to the original" as the
 * supplied reference (blue-grain-patch-ref.webp / the vault's full-res
 * blue-grain-patch.png) — the real reference is a soft cloudy/paper mottle
 * with large, low-frequency blobs and faint horizontal banding, not fine
 * grain. Iterated the CSS-only path first, per decision-log #14's own
 * order of operations:
 *   1. Lowered feTurbulence baseFrequency by ~100x (1.15 -> ~0.01) for
 *      larger blobs, raised numOctaves 2->4, added feGaussianBlur — this
 *      DID produce the right blob scale, but every amplitude high enough to
 *      read as visible mottle also visibly desaturated/lightened the base
 *      blue toward pale cyan (screenshot-compared side by side against the
 *      reference — the reference's actual pixel variance is tiny: interior
 *      sampling put the blue channel stdev at ~2-9 out of a 198 mean, a
 *      ~2-5% coefficient of variation, achieved through large soft-edged
 *      patches, not high-contrast noise). Getting the blob SIZE right with
 *      synthetic turbulence while holding the AMPLITUDE down at the
 *      reference's real (very subtle) level turned out to fight itself:
 *      turbulence's own alpha/contrast knobs are coupled to its frequency
 *      in a way that kept overshooting toward visibly milky/cyan.
 *   2. Decision-log #14 explicitly allows a raster-tile fallback when CSS
 *      "genuinely can't get close" — invoked here. A 512x512 crop from the
 *      ACTUAL supplied reference (not a synthetic approximation) was pulled
 *      from a flat interior region of blue-grain-patch.png (avoiding the
 *      rounded-corner edges). Exported at webp q90, well under the 100KB
 *      target — assets/images/retreat/blue-grain-tile.webp.
 *
 *      R1 KICKBACK ROUND 1 FIX (finding #5): the first cut of this tile
 *      used a naive edge-cross-fade blend (roll the crop by half in both
 *      axes, feather the resulting center seam) and STILL had a visible
 *      hard horizontal edge around ~80% height (a lighter band below) plus
 *      faint vertical edges near the margins — the crop's own large-scale
 *      brightness variation didn't cancel out across that blend, so the
 *      tile visibly repeated into a grid. Replaced with Moisan's periodic-
 *      plus-smooth decomposition (FFT-domain: solve for the maximally
 *      smooth component whose boundary jump matches the crop's actual
 *      top/bottom and left/right mismatch, subtract it — the remainder is
 *      the periodic component, which tiles by construction, not by visual
 *      approximation). Verified numerically, not eyeballed: mean absolute
 *      pixel difference across the top/bottom boundary dropped from 9.8
 *      (naive blend) to 2.1, and left/right from 7.0 to 1.9 — both now
 *      BELOW the tile's own interior row-to-row variation (~5-7), i.e. the
 *      boundary reads as less discontinuous than two random interior rows
 *      already do. Pixel-stat character preserved: mean RGB (0.9, 91.2,
 *      198.6) vs. the pre-fix tile's (2.05, 96.6, 198.2) and the reference
 *      patch's (1.44, 92.1, 198.5) — same ballpark; stdev (2.0, 10.5, 4.5)
 *      vs. pre-fix (5.2, -, -) — same order of magnitude, texture visibly
 *      unchanged. Re-verified as a 3x3 tiled grid at real pixel scale
 *      (scratchpad-local, not committed) — no visible seam on either axis.
 *      52KB, still well under the 100KB target.
 * (R1-3's original text here described a "very subtle rgba scrim gradient
 * layered on top" of the tile — REMOVED, see the R1 kickback round 1 fix
 * note below the base-color paragraph: in a two-layer `background-image`
 * the first-listed layer paints on top, so the opaque tile fully occluded
 * that gradient the entire time it existed. It was dead CSS, not a subtle
 * visible effect, and the reference patch has no real vertical gradient to
 * reproduce per the base-color sampling below anyway.)
 *
 * Base color sampled directly from the reference patch (not eyeballed):
 * ImageMagick point-sampled 9 locations across the opaque interior —
 * consistently #0157C7-#0365C6, essentially flat (no real vertical
 * gradient in the source despite the "subtle vertical variation" brief).
 * dominant flat value is --retreat-blue-grain (token-overrides.css — review
 * round 1 finding #5, "page tokens" heading — single home for
 * .retreat-page custom props); still used as background-color fallback
 * (paints instantly before the tile image loads, and for any no-image
 * fallback case).
 *
 * R1 KICKBACK ROUND 1 FIX (finding #4): the two-layer `background-image`
 * below used to list the tile FIRST and a scrim `linear-gradient()` SECOND
 * — in CSS multi-layer backgrounds the first-listed layer paints on TOP,
 * so the opaque tile fully occluded the gradient underneath it; the
 * rgba() scrim was dead CSS the entire time (and the only raw rgba()
 * literal in this round, against the tokens-not-hex rule). Deleted rather
 * than reordered — the paragraph above already documents that the
 * reference patch has no real vertical gradient to reproduce, so there
 * was nothing under the tile worth un-hiding. `background-image` is now a
 * single layer (the tile); `background-repeat`/`background-size` follow
 * suit as single values instead of two-layer lists;
 * `background-blend-mode` is removed entirely (blend-mode with a single
 * layer against `background-color` was already a no-op — `normal` is the
 * default). `background-color` fallback is UNCHANGED (paints instantly
 * pre-load, correct as-is, see the paragraph above).
 *
 * ── ::after -> two-layer background (review round 1, finding #4) ──
 * The original noise layer was a `::after` pseudo with `inset: 0` and no
 * z-index, painting OVER band content (any text/media inside the band sat
 * under the noise layer, losing contrast). Replaced with a two-layer
 * `background-image` on the element itself (now: tile + scrim gradient, in
 * one property) — no pseudo, so there is nothing left to stack above the
 * band's real children.
 *
 * Round 3 fix (finding #6b): `position: relative` and `isolation: isolate`
 * were leftovers from the old `::after`-pseudo approach (relative anchored
 * the absolutely-positioned overlay; isolate contained its blend-mode
 * stacking context). Neither is used by anything — grepped the theme for
 * `.retreat-band` usage; only the proof page references the class, with no
 * absolutely-positioned children and no other stacking-context dependency.
 * Both removed.
 */

.retreat-band--blue {
  overflow: hidden;
  background-color: var(--retreat-blue-grain);
  background-image: url("../../../images/retreat/blue-grain-tile.webp");
  background-repeat: repeat;
  background-size: 512px 512px;
}

/* Rounded modifier — R1-2 fix (2026-08-15): the full-bleed grain bands
 * (hero, join) themselves round at 100px, node-verified (see
 * token-overrides.css's --radius-band header comment for the SVG/pixel
 * evidence) — NOT the same r20 (--radius-md) that the smaller white
 * cards/panels elsewhere on the page use (leave-with, guides video slot,
 * testimonial cards, logistics video, what-isn't cards all stay --radius-md,
 * untouched, comp-verified separately per section). --radius-band lives in
 * token-overrides.css (single home for .retreat-page custom props); the
 * fallback here covers the editor canvas per the existing --retreat-col-gap/
 * --font-price precedent (S3/hero.css), since the canvas may lack the
 * `.retreat-page` ancestor that supplies the real value. */
.retreat-band--blue.retreat-band--rounded {
  border-radius: var(--radius-band, 100px);
}
