/* ══════════════════════════════════════════════════════════════════════════════
   SITE KIT · THE GROUNDS                                         grounds.css v1.0 (2026-10-08)
   What is BEHIND each band: the paper, a wash of it, a tint, a photograph with the words on it, a texture,
   and how one band hands over to the next. Measured on the luxury winners (client-site-design/reference/grounds.md
   has every number) and checked by the gate's GROUNDS section.

   Load it AFTER finish.css and BEFORE site.css:
     extraCss: [..., 'presets.css', 'finish.css', 'grounds.css', 'site.css']
   Every selector is a plain class or sits inside :where(), so a site's own stylesheet always wins.
   It reads --paper, --ink, --accent (and the finish tokens) and falls back to the kit's.
   --grounds:1 is how the gate knows a page has opted in (GROUNDS rows fail instead of warn).

   THE LADDER (pick a band's ground from here, never invent a fill):
     paper      the page ground                                  class g-paper  (or nothing)
     wash       paper with a breath of the accent in it          g-wash, g-wash-2 (deeper)
     tint       paper pulled toward the ink                      g-tint
     photo      a photograph, the ONLY dark a light site has     g-photo + a scrim class
     room       a bright colour room (cinema layer, cinema.css)  C.room()
     never      a flat dark band (DARK BAND), a pure #FFF band on tinted paper (WHITE HOLE)
   ══════════════════════════════════════════════════════════════════════════════ */
:root{
  --grounds:1;
  --g-paper:var(--paper,#F7F3EA);
  --g-ink:var(--ink,#1B2419);
  --g-accent:var(--accent-txt,var(--accent,#7A5C2E));
  /* the ladder, mixed in OKLab so a wash keeps the paper's warmth instead of greying (sRGB mixes go muddy) */
  --g-wash:color-mix(in oklab,var(--g-accent) 6%,var(--g-paper));
  --g-wash-2:color-mix(in oklab,var(--g-accent) 12%,var(--g-paper));
  --g-tint:color-mix(in oklab,var(--g-ink) 5%,var(--g-paper));
  --g-tint-2:color-mix(in oklab,var(--g-ink) 9%,var(--g-paper));
  /* a scrim is the INK, not black: black over a warm photograph goes grey-green; the ink keeps the photograph's colour */
  --g-scrim:var(--g-ink);
  --g-scrim-a:.62;              /* the strength at the dense end (winners sit between .35 and .75) */
  --g-hair:color-mix(in srgb,var(--g-ink) 12%,transparent);
  --g-grain:.07;                /* desktop only, see .g-grain */
}

/* ── 1. the ladder as bands ─────────────────────────────────────────────────── */
.g-paper{background-color:var(--g-paper)}
.g-wash{background-color:var(--g-wash)}
.g-wash-2{background-color:var(--g-wash-2)}
.g-tint{background-color:var(--g-tint)}
.g-tint-2{background-color:var(--g-tint-2)}
/* a wash that is LIT, not filled: the accent breathes in from one corner, the ink from the other (finish.css .washband
   is the same idea with the finish tokens; this one takes a side) */
.g-lit{background-image:radial-gradient(110% 80% at 0% 0%,var(--g-wash-2),transparent 60%),radial-gradient(90% 70% at 100% 100%,var(--g-tint-2),transparent 58%)}
.g-lit.flip{background-image:radial-gradient(110% 80% at 100% 0%,var(--g-wash-2),transparent 60%),radial-gradient(90% 70% at 0% 100%,var(--g-tint-2),transparent 58%)}
/* a two-stop gradient room: paper to wash-2, top to bottom, so a long band is not one flat fill */
.g-fade{background-image:linear-gradient(in oklab 180deg,var(--g-paper),var(--g-wash-2))}
.g-fade.up{background-image:linear-gradient(in oklab 0deg,var(--g-paper),var(--g-wash-2))}

/* ── 2. a photograph as the ground, with the words on it ───────────────────── */
/* <section class="g-photo scrim-b"> <img|picture|video class="g-media"> <div class="g-on"> words </div> </section>
   The media fills the band; the scrim sits between it and the words; .g-on carries the paper-coloured type. */
.g-photo{position:relative;isolation:isolate;overflow:clip;color:var(--g-paper);background-color:color-mix(in srgb,var(--g-ink) 7%,var(--g-paper))}
.g-photo>.g-media,.g-photo>picture.g-media>img,.g-photo>video.g-media{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block;z-index:0}
.g-photo>picture.g-media{position:absolute;inset:0;z-index:0}
.g-photo>.g-on{position:relative;z-index:2}
/* everything on a photograph takes the band's ink. :is() carries a class's specificity, so this beats the kit's
   body.light h1 (which paints headings in the ink: on a dark scrim that is unreadable, and the gate caught it 2026-10-08) */
:is(.g-photo,.g-photo.light) :is(h1,h2,h3,h4,p,.eyebrow,.label,.kicker,.lede,em,li,blockquote){color:inherit}   /* (0,3,0): beats body.light .eyebrow whatever the sheet order */
/* the scrims: a gradient of the INK that is dense where the words are and clear where the photograph is.
   -b bottom, -t top, -l left, -r right, -spot a soft pool under a centred headline, -flat an even veil (last resort) */
.g-photo::before{content:"";position:absolute;inset:0;z-index:1;pointer-events:none}
.scrim-b::before{background:linear-gradient(to top,color-mix(in srgb,var(--g-scrim) calc(var(--g-scrim-a) * 100%),transparent) 0%,color-mix(in srgb,var(--g-scrim) calc(var(--g-scrim-a) * 40%),transparent) 38%,transparent 72%)}
.scrim-t::before{background:linear-gradient(to bottom,color-mix(in srgb,var(--g-scrim) calc(var(--g-scrim-a) * 100%),transparent) 0%,color-mix(in srgb,var(--g-scrim) calc(var(--g-scrim-a) * 40%),transparent) 38%,transparent 72%)}
.scrim-l::before{background:linear-gradient(to right,color-mix(in srgb,var(--g-scrim) calc(var(--g-scrim-a) * 100%),transparent) 0%,color-mix(in srgb,var(--g-scrim) calc(var(--g-scrim-a) * 45%),transparent) 42%,transparent 76%)}
.scrim-r::before{background:linear-gradient(to left,color-mix(in srgb,var(--g-scrim) calc(var(--g-scrim-a) * 100%),transparent) 0%,color-mix(in srgb,var(--g-scrim) calc(var(--g-scrim-a) * 45%),transparent) 42%,transparent 76%)}
.scrim-spot::before{background:radial-gradient(60% 55% at 50% 55%,color-mix(in srgb,var(--g-scrim) calc(var(--g-scrim-a) * 90%),transparent),transparent 100%)}
.scrim-flat::before{background:color-mix(in srgb,var(--g-scrim) calc(var(--g-scrim-a) * 55%),transparent)}
.scrim-none::before{background:none}
/* a LIGHT photograph (sky, snow, a white room) takes the words in ink over a wash of the paper instead */
.g-photo.light{color:var(--g-ink)}
.g-photo.light.scrim-b::before{background:linear-gradient(to top,color-mix(in srgb,var(--g-paper) 82%,transparent),color-mix(in srgb,var(--g-paper) 40%,transparent) 40%,transparent 72%)}
.g-photo.light.scrim-t::before{background:linear-gradient(to bottom,color-mix(in srgb,var(--g-paper) 82%,transparent),color-mix(in srgb,var(--g-paper) 40%,transparent) 40%,transparent 72%)}
.g-photo.light.scrim-l::before{background:linear-gradient(to right,color-mix(in srgb,var(--g-paper) 84%,transparent),color-mix(in srgb,var(--g-paper) 44%,transparent) 44%,transparent 76%)}
.g-photo.light.scrim-r::before{background:linear-gradient(to left,color-mix(in srgb,var(--g-paper) 84%,transparent),color-mix(in srgb,var(--g-paper) 44%,transparent) 44%,transparent 76%)}
/* the words sit on the quiet side of the photograph (quiet.py says which): .g-on.left / .right / .centre / .bottom */
.g-on{display:flex;flex-direction:column;justify-content:center;min-height:100%;padding:clamp(28px,6vw,96px) 0}
.g-on.left{align-items:flex-start;text-align:left}
.g-on.right{align-items:flex-end;text-align:right}
.g-on.centre{align-items:center;text-align:center}
.g-on.bottom{justify-content:flex-end}
.g-on.top{justify-content:flex-start}
/* a quiet photograph band with NO words needs no scrim: the gate never asks for one (SCRIM ON NOTHING is a note) */

/* ── 3. a photograph that stays put behind the words (the fixed layer the winners pin) ──
   background-attachment:fixed is broken on iOS; this is the working version: a sticky media inside a tall band.
   <section class="g-pin"><div class="g-pin-media"><img></div><div class="g-pin-on">words that scroll over it</div></section> */
.g-pin{position:relative;isolation:isolate}
.g-pin-media{position:sticky;top:0;height:100svh;overflow:clip;z-index:0}
.g-pin-media>img,.g-pin-media>video{width:100%;height:100%;object-fit:cover;display:block}
.g-pin-on{position:relative;z-index:1;margin-top:-100svh}

/* ── 4. textures: paper fibre and grain, desktop only, never over the words ─────
   The winners that use a texture keep it faint (opacity .04 to .12) and tone-on-tone. Grain is noise on a phone
   (finish.md), so every texture here is behind a (min-width:761px) gate. */
.g-fibre,.g-grain{position:relative;isolation:isolate}
.g-fibre::after,.g-grain::after{content:"";position:absolute;inset:0;z-index:0;pointer-events:none;display:none}
.g-fibre>*,.g-grain>*{position:relative;z-index:1}
@media (min-width:761px){
  /* paper fibre: two faint repeating hatches of the ink, like laid paper under a lamp */
  .g-fibre::after{display:block;opacity:.05;background-image:repeating-linear-gradient(104deg,var(--g-ink) 0 1px,transparent 1px 7px),repeating-linear-gradient(14deg,var(--g-ink) 0 1px,transparent 1px 11px)}
  /* grain: an SVG turbulence tile, still (the animated one is cinema's .cine-grain) */
  .g-grain::after{display:block;opacity:var(--g-grain);mix-blend-mode:multiply;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='.3 .3 .3 0 0 .3 .3 .3 0 0 .3 .3 .3 0 0 0 0 0 .9 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E")}
}
/* a tone-on-tone motif from the client's world pressed into the ground (an SVG the site provides as --g-motif) */
.g-motif{position:relative;isolation:isolate}
.g-motif::after{content:"";position:absolute;inset:0;z-index:0;pointer-events:none;opacity:.06;background:var(--g-motif) center/var(--g-motif-size,420px) repeat}
.g-motif>*{position:relative;z-index:1}

/* ── 5. the edge between two bands ──────────────────────────────────────────── */
/* a hairline where two bands of the same ground meet (the winners' commonest soft edge) */
.edge-hair{border-top:1px solid var(--g-hair)}
/* a card from this band pulled up over the previous one (an overlap reads as depth without a shadow) */
.edge-overlap{position:relative;z-index:2;margin-top:calc(-1 * var(--overlap,72px))}
/* this band rounds its top corners over the previous one (a panel laid on the page) */
.edge-round{border-top-left-radius:var(--edge-r,28px);border-top-right-radius:var(--edge-r,28px);position:relative;z-index:1;margin-top:calc(-1 * var(--edge-r,28px))}
/* air: two paper bands that should breathe apart instead of touching */
.edge-air{margin-top:clamp(40px,6vw,96px)}

/* ── 6. a phone keeps the ground, loses the weight ──────────────────────────── */
@media (max-width:760px){
  .g-on{padding:28px 0}
  .scrim-l::before,.scrim-r::before{background:linear-gradient(to top,color-mix(in srgb,var(--g-scrim) calc(var(--g-scrim-a) * 100%),transparent) 0%,color-mix(in srgb,var(--g-scrim) calc(var(--g-scrim-a) * 40%),transparent) 42%,transparent 78%)}
  .g-photo.light.scrim-l::before,.g-photo.light.scrim-r::before{background:linear-gradient(to top,color-mix(in srgb,var(--g-paper) 84%,transparent),color-mix(in srgb,var(--g-paper) 44%,transparent) 44%,transparent 78%)}
  .g-on.left,.g-on.right{align-items:flex-start;text-align:left;justify-content:flex-end}
  .edge-overlap{--overlap:40px}
}
@media (prefers-reduced-motion:reduce){.g-pin-media{position:relative;height:auto}.g-pin-on{margin-top:0}}
