The .ft-stage scene (a flex column, rgb(26, 26, 36) background, at least 300 px tall) holds a 200 px tall .transition-preview screen with 12 px corners and overflow: hidden, and the .trigger-btn button below it. Inside the screen, three layers overlap with position: absolute; inset: 0: page A (.old-content, violet gradient), page B (.new-content, cyan to green gradient, hidden by opacity: 0; visibility: hidden) and, on top (z-index: 10), the .fade-through-overlay veil: a solid #0a0a0f at opacity 0 that lets clicks through (pointer-events: none).
On click, the script adds the .animating class to the veil, which plays @keyframes fadeThrough over 1.2 s ease-in-out: opacity 0 → 1 at 40%, held until 60%, back to 0 at 100%. The screen is fully black from 0.48 s to 0.72 s; at 0.6 s, in the middle of that black, the script toggles the .is-b class on .transition-preview, and two rules swap the pages (A goes to opacity: 0; visibility: hidden, B to 1 and visible). At 1.2 s, .animating is removed. Since the swap happens under an opaque veil, no frame shows A and B together — that is the difference with a crossfade, where both pages overlap halfway.
The page you reach is a state, not a moment: .is-b stays set, page B holds until the next click, which replays the veil and brings A back (measured in Chromium 151, Firefox 153 and WebKit 26.5: B shown as long as nothing is touched, back to A on the second click, then B again). During the animation, the button gets aria-disabled="true" and the script ignores clicks, rather than disabled: a disabled button loses keyboard focus (measured in Chromium and Firefox, focus goes back to body), and the Enter key would no longer work to go back. The script walks through every .ft-stage of the page, with no id and no global function: several screens coexist, each with its own button. A variant in the catalog takes the screen through a solid color instead of black.
CSS (@keyframes on opacity, inset) + 1.5 KB of JavaScript (classList, matchMedia), no dependency. Measured in Chromium 151, Firefox 153 and WebKit 26.5: opaque veil at swap time, page B held, back to A on the next click, keyboard focus kept, direct swap under reduced motion. The inset property, which places the three layers, sets the minimum versions: Chrome 87, Firefox 66, Safari 14.1.
Without JavaScript, page A stays on screen and the button does nothing: provide a regular link to the B content if the page must work without script. In a browser without inset (Safari before 14.1), replace inset: 0 with top: 0; right: 0; bottom: 0; left: 0 on .transition-content and .transition-overlay.