Ice scene: the glossy orbs become rising bubbles, ~38% more transparent
- Orbs rise from below the bottom edge to above the top edge, each with its own 36-68s pass (slower on phones), a negative delay (scene already populated on load), own horizontal position, a gentle sway and a slight scale drift; opacity fades in/out at the edges so the loop never pops. - Only transform + opacity animate, each orb on its own composited layer (will-change: transform); no filter/backdrop-filter, nothing animates size/offsets/shadow. The glacier blobs are untouched. - Opacity lowered ~38% in both themes: 0.55->0.34 light, 0.8->0.5 dark, phone overrides 0.32->0.2 / 0.42->0.26. - prefers-reduced-motion: rise removed, orbs return to the old static placements (a paused-from-start CSS animation is not applied in Chrome and would park them below the fold); tab hidden: a visibility listener parks the whole scene (.ice-paused), blob drift included. - Measured with a CDP perf trace on a 4x throttled phone profile: p95 33.4ms, 0 frames over 34ms, no long tasks - identical to the pre-change baseline; ~0.6% extra main-thread CPU. Desktop stays compositor-bound from the pre-existing blob drift, as before. tests/bubble-perf.mjs keeps it repeatable. - New bubbles suite (34 checks) in the repo harness; the axe contrast matrix is now 16 runs (360/390/1280 x dark/light x EN/CS) and passes. - SW cache -> freezmo-v31; README decision 46. Full suite: 11/11 suites, 424 checks.
This commit is contained in:
parent
dbd5dfbc58
commit
6b6a6ea158
9 changed files with 419 additions and 31 deletions
|
|
@ -1,12 +1,27 @@
|
|||
"use client";
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
/**
|
||||
* The fixed ice scene behind every screen: a navy (or pale) base, four slow
|
||||
* drifting glacier blobs, glossy ice orbs and a whisper of grain. Purely
|
||||
* decorative — it never intercepts pointer events, and the drift stops under
|
||||
* `prefers-reduced-motion`.
|
||||
* drifting glacier blobs, glossy ice orbs that rise slowly and fade at the
|
||||
* edges, and a whisper of grain. Purely decorative — it never intercepts
|
||||
* pointer events, only transform/opacity animate (each on its own composited
|
||||
* layer), the rise stops under `prefers-reduced-motion`, and everything parks
|
||||
* while the tab is hidden so a background tab costs no compositor work.
|
||||
*/
|
||||
export function IceBackdrop() {
|
||||
const [hidden, setHidden] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const apply = () => setHidden(document.hidden);
|
||||
apply();
|
||||
document.addEventListener("visibilitychange", apply);
|
||||
return () => document.removeEventListener("visibilitychange", apply);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="ice-scene" aria-hidden>
|
||||
<div className={`ice-scene${hidden ? " ice-paused" : ""}`} aria-hidden>
|
||||
<span className="ice-blob ice-blob-a" />
|
||||
<span className="ice-blob ice-blob-b" />
|
||||
<span className="ice-blob ice-blob-c" />
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue