/* ============================================================
   site-pixel-bg.css — "living parchment" sitewide pixel field
   Fixed full-viewport backdrop (#bgx-field) behind ALL page
   content, shared by index / primae / ui-anima. JS adds
   .bgx-on to <body>; every rule that changes the page is
   scoped under it, so nothing shifts if the script fails.
   All hooks are bgx- prefixed.
   ============================================================ */

#bgx-field {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 0;
    overflow: hidden;
    pointer-events: none; /* never intercepts input; JS listens on window */
}

.bgx-canvas {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    display: block;
    /* low-res buffer scaled up -> crisp fat pixels */
    image-rendering: -moz-crisp-edges;
    image-rendering: crisp-edges;
    image-rendering: pixelated;
}

/* ---- Stacking: content above the field ----------------------
   header is already sticky + z-index:100 (layout.css) and the
   skip-link is absolute + z-index:1000 (base.css); raising
   main and footer completes the order without touching them. */
body.bgx-on > main,
body.bgx-on > footer {
    position: relative;
    z-index: 1;
}

/* ---- Let the field show through ------------------------------
   Default section grounds are transparent (cream = the field).
   The alternating bands and the footer keep their color but go
   slightly translucent so the grain reads through; cards, demo
   windows and other component surfaces stay fully opaque. */
body.bgx-on main .section:nth-of-type(even) {
    background: color-mix(in srgb, var(--surface-alt, #efece4) 92%, transparent);
}

body.bgx-on .marquee-band {
    background: color-mix(in srgb, var(--surface-alt, #efece4) 92%, transparent);
}

body.bgx-on footer {
    background: color-mix(in srgb, var(--surface-alt, #efece4) 94%, transparent);
}

/* ---- bgx-contrast: text over the living field reads ink, not gray ----
   Muted gray (#6c6b61) loses apparent contrast over pixel texture; when
   the backdrop is on, step the muted token down toward ink sitewide.
   (Opaque cards/demos inherit too — consistent, and only ever darker.) */
body.bgx-on { --color-muted: #474640; }
body.bgx-on .section-desc,
body.bgx-on .subtitle,
body.bgx-on .act-support,
body.bgx-on .coda-support,
body.bgx-on .about-body p,
body.bgx-on .body { color: #3a3934; }

/* ============================================================
   bgx-veil — reading grounds for text that sits on the raw field
   ============================================================
   Principal text blocks get a soft cream halo (blurred box-shadow,
   zero layout shift) so glyphs never land on grain. The halo is a
   *ground match*, not a decoration: it is only correct where the
   thing behind the text is the cream field itself.

   One inherited token drives the whole system:

     --bgx-veil: <cream>      halo on   (default: the field ground)
     --bgx-veil: transparent  halo off  (any already-flat ground)

   Turning it off on a container switches every veiled descendant
   off with it, so contexts are named once, below, instead of being
   patched selector-by-selector. */
body.bgx-on { --bgx-veil: var(--color-bg, #f5f4ef); }

/* --- Grounds that are already flat: no veil, ever ---------------
   A cream halo over a tinted band or an opaque card is a *lighter*
   rectangle — it reads as a hard-edged stain and collides with the
   frames around it. These surfaces mute the field on their own
   (bands sit at 92% opacity; cards/demo chrome are solid), so text
   on them is legible with no help. */
body.bgx-on :is(
    main .section:nth-of-type(even),   /* alternating --surface-alt band */
    .marquee-band,
    footer,
    .card,
    .team-card,
    [class*="-app"],                   /* demo windows: pd-app, ua-app…  */
    [class*="-win"],
    [class*="-page"],
    [class*="-panel"],
    [class*="-stage"],
    [class*="-card"],
    [class*="-viz"]
) { --bgx-veil: transparent; }

body.bgx-on .section-header,
body.bgx-on .subtitle,
body.bgx-on .section-desc,
body.bgx-on .about-body,
body.bgx-on .evalproblem .body,
body.bgx-on .act-label,
body.bgx-on .act-statement,
body.bgx-on .act-support,
body.bgx-on .coda-statement,
body.bgx-on .coda-support,
body.bgx-on .manifesto-coda,
body.bgx-on .domain-head,
body.bgx-on .faq,
body.bgx-on .waitlist-form,
body.bgx-on .about-status,
body.bgx-on figcaption {
    background: var(--bgx-veil);
    /* wide + soft: the falloff must never resolve into an edge */
    box-shadow: 0 0 28px 4px var(--bgx-veil);
    border-radius: 4px;
}

/* --- No veil inside a veil -------------------------------------
   Where one veiled block nests in another, the inner halo only adds
   a second, offset rectangle around ground that is already cream. */
body.bgx-on .section-header .subtitle,
body.bgx-on .section-header .section-desc,
body.bgx-on .about-body p,
body.bgx-on .manifesto-coda .act-label,
body.bgx-on .manifesto-coda .act-statement,
body.bgx-on .manifesto-coda .act-support,
body.bgx-on .manifesto-coda .coda-statement,
body.bgx-on .manifesto-coda .coda-support {
    background: transparent;
    box-shadow: none;
}

/* --- Captions -------------------------------------------------
   A caption is a thin full-width line wedged between a component
   frame and whatever comes next, so a solid ground under it reads as
   a painted stripe. Captions get a *scrim* instead: enough cream to
   settle the grain under 11px mono, sheer enough that the field still
   runs through it and no band appears. Kept clear of the frame above
   and the block below. */
body.bgx-on figcaption {
    --bgx-scrim: color-mix(in srgb, var(--bgx-veil) 66%, transparent);
    background: var(--bgx-scrim);
    box-shadow: 0 0 14px 1px var(--bgx-scrim);
    margin-bottom: var(--space-sm, 14px);
}
