/* sophicly-theme-wipe.css — site-wide support for the bottom-right theme wipe.
   ═══════════════════════════════════════════════════════════════════════════
   Pairs with assets/js/sophicly-theme-wipe.js. Both are loaded on every page
   EXCEPT the home page and the dashboard (Neil's call, 2026-08-16).

   ⭐⭐ THE SUPPRESSION RULE BELOW IS THE FIX FOR A BUG THAT TOOK THREE ATTEMPTS.
   A View Transition snapshots the NEW page immediately after the theme flips. If
   anything is TRANSITIONING its colours at that instant, the new snapshot is
   nearly the same picture as the old one — the wipe then reveals an identical
   image, which looks like nothing at all, and the slow CSS fade plays out
   afterwards on the live DOM as the only thing the eye can follow. That reads as
   "it fades from everywhere / radiates from the centre", which is exactly how
   Neil described it every time.

   The specific offender was `html body { transition: background-color
   var(--swh-arrival) linear }` — the site-wide arrival reveal, unscoped,
   computing to 1.8s. MEASURED on production: one toggle ramped <body> through 32
   distinct colours.

   ⭐ IT SUPPRESSES `*`, NOT A LIST OF SELECTORS, AND THAT IS DELIBERATE. Naming
   body/#main/.spl-main only covers the selectors that carried the transition on
   the day it was diagnosed; the moment another lane moves it, adds one to a
   wrapper, or introduces a new themed surface, the cover silently lapses and the
   bug returns with nothing to announce it. `*` cannot be out-guessed.

   It costs nothing else: `transition` and `animation` are different properties,
   so running animations are untouched, and the ::view-transition pseudos live in
   their own tree that `*` does not match — the wipe itself is unaffected. The
   window is the wipe's own ~550ms, removed on finish and by a timeout floor. */
html.spl-theme-wiping *,
html.spl-theme-wiping *::before,
html.spl-theme-wiping *::after {
    transition: none !important;
}

/* The snapshots are opaque-backed so a one-frame GPU seam cannot flash through,
   and the UA cross-fade is suppressed so the clip is the only reveal. Kept as CSS
   for stock browsers; the JS drives the same contract through WAAPI because author
   CSS on these pseudos is not reliably applied in every Chrome build. */
::view-transition-old(root),
::view-transition-new(root) {
    animation: none !important;
    mix-blend-mode: normal;
}

::view-transition-old(root) { z-index: 1; background-color: var(--vt-bg-old, #232427); }
::view-transition-new(root) { z-index: 2; background-color: var(--vt-bg-new, #232427); }
