/* ============================================================================
   mk-bgfade.css — THE PAGE GROUND FADES BETWEEN SECTION COLOURS
   ----------------------------------------------------------------------------
   Founder item F, FT-20260819-jehnean-review:

     "In the Salient theme Signal there's this effect... they fade the background
      colour from the colour in one section to the colour in the next. I would
      very much like us to do that... especially between what makes a safe stay
      unique and the next sections, why these locations / toxins avoidance /
      ecological considerations. And similarly the building requirements. It
      would be a really nice feeling of fading rather than just a hard line."

   Lane `r4:bgfade-impl`. Owns this file and `js/mk-bgfade.js` outright.
   The measured donor teardown this implements is `review/bgfade/MECHANIC.md`
   (612 lines) — read it before changing any number here. Every constant below
   is a MEASURED donor value, not a taste choice.

   DONOR, SHA-VERIFIED THROUGH THE SALIENT MCP
   -------------------------------------------
   Component            Salient's own `nectar-color-change-bg`
   Route                /salient/signal/
   SHA-256              bb028a868c2081b4197a99a087132b00ba3a07e6a221c8b8ab0f31f99007e8a2
   Bytes                169,954
   Reference commit     cea2884a7525f70723ba7238d22205a9f603cd24
   Contract SHA-256     21dfcde96773c349ca6d30359581e801c34da784ccff0fb1336def4d9da0b98d

   `salient_usage_contract` was the first governed call, then `salient_health`
   (ok, kill switch inactive, 600 routes, all manifest rows byte-and-hash
   verified), then `salient_template_provenance`. The same SHA-256 was then
   re-computed from the pinned mirror on disk and matched. The donor's enrolment
   contract was read out of those exact bytes: five rows, each carrying BOTH
   `data-color-change-section-bg-color` and `data-color-change-section-text-color`.

   =========================================================================
   1. WHAT THE DONOR ACTUALLY DOES — AND THE ONE THING IT DOES NOT DO
   =========================================================================
   MECHANIC.md §3 measured it live over CDP. The result is worth stating at the
   top of this file because it is the opposite of the obvious implementation:

     · The colour TARGET is a hard STEP in scroll. Sweeping scrollY in 5px
       increments, the target var jumps in ONE frame at the crossover. There is
       no scroll-position interpolation anywhere in the component.
     · The RENDERED colour is a CSS `transition: background-color 0.8s` with the
       DEFAULT timing function. Fitted against 96 in-flight frames of the live
       curve: `ease` RMSE 0.0099, vs ease-out 0.0807, linear 0.2149,
       ease-in-out 0.2193, ease-in 0.3510. 0.0099 is inside the sampling floor.

   So the softness the founder asked for is THE TRANSITION, not a scroll-mapped
   lerp. Do not "improve" this with a custom bezier and do not map it to scroll
   offset. At ~1,000px/s the fade happens to span ~830px of travel; at half that
   speed, ~415px; and if the reader stops dead on the seam it completes in place
   in 0.8s. Nothing about the reader's gesture is metered, sampled or held.

   THIS IS ALSO WHY IT SATISFIES REQ-SCROLL-01 ("you scroll clamped everything...
   super janky... too rigid"). A time-anchored curve cannot inherit the stutter
   of the gesture that triggered it. A scroll-mapped one inherits every
   irregularity — which is precisely what "janky" meant. There is no wheel
   listener, no `preventDefault`, and no `scroll-snap-type` in this file or in
   `js/mk-bgfade.js`; the donor has none either (its only scroll listener is
   `{passive: true}`).

   =========================================================================
   2. THE GROUND IS `.ocm-effect-wrap`, NOT `body` — MEASURED
   =========================================================================
   MECHANIC.md §5.1, re-verified by this lane on the current bytes. The ancestor
   paint chain above any section:

       [data-section]              rgb(244,249,251)   its own colour
       #ajax-content-wrap          rgba(0,0,0,0)      transparent (site.css §0.1)
       .ocm-effect-wrap-inner      rgba(0,0,0,0)
       .ocm-effect-wrap            rgb(244,236,226)   <-- THE OPAQUE GROUND
       body                        rgb(11,15,18)      never visible
       html                        rgba(0,0,0,0)

   Setting only `body`'s background is a NO-OP — the research lane painted body
   magenta and measured 0.00% magenta on all 17 sections. `.ocm-effect-wrap`
   measures exactly the document height (24,683 = document scrollHeight), so it
   is the correct and complete ground surface.

   `body` is deliberately NOT touched here. `css/site.css` paints it
   `--mk-surface-ink` (#0b0f12) on purpose — that is the overscroll colour, and
   the donor's habit of listing `body` in its ground rule would change it.

   THE #f4ece2 IS SALIENT'S WARM DEMO DEFAULT LEAKING INTO OUR BUILD.
   It was invisible only because every section painted over it. The moment the
   ladder sections are flattened (§4) it becomes a real, visible surface, so
   §3 repoints it at a Mykrobial token in the same change — MECHANIC.md §5.1
   asked for exactly this.

   =========================================================================
   3. THE HOOK IS ALREADY IN OUR BUILD — THIS IS ASSEMBLY, NOT AUTHORSHIP
   =========================================================================
   Our vendored `salient-dynamic-styles-multi-id-37.q-6d7044fbbd.css` already
   carries the donor's OWN ground rule, verbatim:

       body,.container-wrap,.material .ocm-effect-wrap,…,.wpml-ls-statics-footer
         { background-color: var(--nectar-page-background-color,#f4ece2); }

   `--nectar-page-background-color` is the exact custom property the donor's
   script writes. So the paint side needed no new rule at all — only a default
   and a transition. That is why this file is short.

   REPOINTING THAT VAR IS PROVABLY SAFE ON THIS PAGE, and it was checked rather
   than assumed. Of the EIGHTEEN selectors in that rule, exactly THREE exist in
   our document (`document.querySelectorAll(...).length > 0`):

       body                        overridden to --mk-surface-ink by site.css
       .container-wrap             overridden to transparent at ID specificity
       .material .ocm-effect-wrap  the ground — the one we want

   The other fifteen (`#page-header-wrap`, `.portfolio-items .col`,
   `.nectar-global-section.*`, `.project-title`, the carousel-wrap trio, …) match
   nothing. Repointing therefore reaches one visible element, and it also means
   a future lane that DOES introduce one of those fifteen inherits a Mykrobial
   colour instead of the foreign beige.

   The var is also the whole reason `js/mk-bgfade.js` writes ONE property:
   `--mk-page-bg` is the Mykrobial-named source of truth, and Salient's own name
   is an alias pointing at it.  */

:root {
  /* The page ground. A Mykrobial token, replacing Salient's #f4ece2 fallback. */
  --mk-page-bg: var(--mk-surface-mist);          /* #f4f9fb — 01/02/03's colour */

  /* Salient's own name for the same thing, aliased so the vendored rule above
     needs no edit. One source of truth: write --mk-page-bg, both names follow. */
  --nectar-page-background-color: var(--mk-page-bg);

  /* MEASURED: 0.8s, default `ease` (§1). `js/mk-bgfade.js` overwrites this
     INLINE on <html> to 0s for the first ~100ms so the opening colour lands
     without animating, then restores it — the donor's own anti-flash ordering. */
  --mk-bgfade-dur: 0.8s;
}

/* ---------------------------------------------------------------------------
   3.1 THE GROUND, RESTATED AT A SPECIFICITY THAT CANNOT BE LOST
   ---------------------------------------------------------------------------
   §3 already makes the vendored rule do the right thing, so this is belt and
   braces — but cheap belt and braces, and the failure it guards against is
   silent. If a later lane drops, reorders or re-minifies the vendored dynamic
   stylesheet, the ground would revert to `body`'s INK (#0b0f12) showing through
   flattened sections: a black page, not a subtly wrong one.

   `body.mk-page .ocm-effect-wrap` is (0,0,2,1) and beats Salient's
   `.material .ocm-effect-wrap` (0,0,2,0) on specificity alone, so this holds at
   any link position. It is the same value, so it is a visual no-op today. */
body.mk-page .ocm-effect-wrap {
  background-color: var(--mk-page-bg);
}

/* ---------------------------------------------------------------------------
   3.2 THE TRANSITION — ARMED ONLY BY THE SCRIPT
   ---------------------------------------------------------------------------
   `body.mk-bgfade-on` is added at +100ms, after the first colour has been
   applied with the duration pinned at 0s. Until then this rule does not exist,
   so the page cannot fade in from the default ground on load.

   NO TIMING FUNCTION IS NAMED. That is the measured donor value: CSS default
   `ease` = cubic-bezier(0.25, 0.1, 0.25, 1), fitted at RMSE 0.0099 (§1).

   ONLY `background-color` IS DECLARED, AND THAT IS A DELIBERATE DEPARTURE FROM
   THE DONOR'S OWN RULE, WHICH READS
       .material .ocm-effect-wrap{transition:background-color 0.8s,
                                  transform 0.8s cubic-bezier(.15,.2,.1,1)}
   MECHANIC.md §5.1 flagged that clobbering an existing transform transition was
   the risk here and told the implementer to re-check the computed value rather
   than assume. Checked, and the answer is the opposite of the warning:

     · computed `transition` on .ocm-effect-wrap today is `all 0s ease 0s`;
       CSS.getMatchedStylesForNode returns ZERO matched rules setting
       `transition` on that element.
     · Salient's transform transition is real but is scoped
       `body[data-slide-out-widget-area-style=slide-out-from-right] .ocm-effect-wrap`
       (skin-material.css @51506). OUR body is `fullscreen-inline-images`
       (_shell/head-tail.html), so it cannot match.

   So there is nothing to preserve — and restating the transform leg anyway
   would ADD 0.8s of motion to the off-canvas menu, which today snaps at 0s.
   That is `r3:menu-x`'s component, and inventing motion in it from this lane
   would be authorship, not assembly. Declared: background-color only. */
body.mk-bgfade-on.mk-page .ocm-effect-wrap,
body.mk-bgfade-on {
  transition: background-color var(--mk-bgfade-dur);
}

/* ---------------------------------------------------------------------------
   3.3 THE TEXT LEG — WIRED, INERT, ONE ATTRIBUTE FROM LIVE
   ---------------------------------------------------------------------------
   The donor sets THREE custom properties, not one: `--nectar-page-background-color`,
   `--nectar-page-text-color`, `--nectar-page-light-text-color`.

   MEASURED FINDING, worth recording because it corrects the obvious reading of
   the donor: on Signal the text leg IS A NO-OP. All five enrolled rows declare
   the SAME value — `data-color-change-section-text-color="var(--nectar-font-color)"`
   — so the property is rewritten on every switch and never changes. The donor
   does not flip text colour on this demo; it only carries the machinery.

   We do not need it either: every colour in our ladder is a near-white blue-grey
   (#f4f9fb / #e6eef2 / #cbd6dc), so body ink stays legible throughout. MECHANIC.md
   §5.2 measured the same conclusion from the other direction — the three dark or
   photographic sections seal themselves completely, so no dark enrolment leg
   exists to need one.

   THIS RULE IS THEREFORE GATED, NOT MERELY UNUSED. `js/mk-bgfade.js` adds
   `mk-bgfade-fg` ONLY if at least one enrolled section declares `data-mk-fg`.
   With no such section the selector never matches and this file cannot affect
   text colour at all — which is the point: an ungated `color: var(--mk-page-fg,
   inherit)` on body would out-specify nothing today and silently out-specify a
   section tomorrow. A future dark enrolment is one attribute, not a rewrite. */
body.mk-bgfade-fg {
  color: var(--mk-page-fg);
}
body.mk-bgfade-fg.mk-bgfade-on {
  transition: background-color var(--mk-bgfade-dur),
              color            var(--mk-bgfade-dur);
}

/* ---------------------------------------------------------------------------
   4. REDUCED MOTION — THE COLOUR STILL LANDS, IT JUST LANDS INSTANTLY
   ---------------------------------------------------------------------------
   The donor has NO prefers-reduced-motion branch anywhere; this is ours, and it
   follows `css/reduced-motion.css`'s rule 2 — disable by writing the END state,
   never by cancelling and leaving the element mid-way. Here the end state IS the
   correct section colour, so cancelling the transition is the complete fix: the
   ground is right on every frame, it simply steps instead of fading.

   `js/mk-bgfade.js` ALSO honours the query independently, at the source, by
   holding `--mk-bgfade-dur` at 0s and never arming. Both halves are deliberate:
   the script's half survives this stylesheet being dropped, and this half
   survives the script's `matchMedia` being unavailable. Neither is redundant
   with the other, because they fail in different directions.

   `!important` is NOT used. Nothing above is `!important` and no inline style
   writes `transition` on these elements, so specificity is sufficient — the
   CONVENTIONS §8.6 bar for `!important` is not met here. */
@media (prefers-reduced-motion: reduce) {
  body.mk-bgfade-on.mk-page .ocm-effect-wrap,
  body.mk-bgfade-on,
  body.mk-bgfade-fg.mk-bgfade-on {
    transition: none;
  }
}
