Stop blurring the animated scene on static glass (2x frame time)

The MacBook ran hot browsing the app: the ice scene animates constantly, so
every backdrop-filter surface re-ran its blur on every frame. Measured on
desktop (2x CPU throttle, software renderer): p50 frame 66.6ms baseline,
33.3ms with the static surfaces not filtering, 16.7ms with the scene's
animation also off; frames over 34ms: 128 -> 14.

The glass recipe is split: floating layers (sheets, dropdowns, dialogs, the
sticky header/chrome/tab bar) keep the blur (backdrop-blur-lg, what phones
already used); static layers (cards, the sidebar rail, the gate, the study
prompt card) keep the identical tint, rim, highlight and shadow without the
filter. The study prompt card moves from glass-panel to card + glass-solid,
which is the same surface recipe.

Quality: a deterministic pixel diff (scene motion frozen, both themes,
desktop + phone) shows a ~1% colour shift in the card backdrops — invisible.
The mobile axe contrast audit and the bubbles suite stay green.
tests/bubble-perf.mjs now also reports the glass cost. README: decision 61.
SW -> freezmo-v49.
This commit is contained in:
Martin Dvořák 2026-10-12 19:47:36 +00:00
commit 1f2e702b4e
5 changed files with 63 additions and 18 deletions

View file

@ -1361,6 +1361,20 @@ Things I chose while building, with the reasoning:
phase-1 suite (43 checks, including the real route mapping against a stub Ollama returning a
monthly-limit body, a two-device sync round-trip, and the generation guards below).
61. **Glass that sits still doesn't blur.** The MacBook got hot just browsing: the ice scene animates
constantly, and every `backdrop-filter` surface re-runs its blur on every frame while the backdrop
moves — the whole card and rail area was re-blurring the scene ~60 times a second. Measured on
desktop (2x CPU throttle, software renderer): p50 frame 66ms with everything blurring, 33ms once
the static surfaces stopped, 17ms with the scene's animation also off — frames over 34ms dropped
from 128 to 14. The recipe is now split: **floating glass** (sheets, dropdowns, dialogs, the
sticky header/chrome/tab bar — the layers that can have content scroll underneath) keeps the
blur, now `backdrop-blur-lg` (which is what phones already used), while **static glass** (cards,
the rail, the gate, the study prompt card) keeps the exact same tint, rim, highlight and shadow
without the filter. A deterministic before/after pixel diff (scene motion frozen) shows the
change is a ~1% colour shift in the card backdrops — invisible in both themes.
`tests/bubble-perf.mjs` now reports the glass cost too, so a future blurred surface over the
scene shows up immediately.
60. **There is exactly one loading screen.** The deck wizard had the good one — the app icon, the
rotating stage message as the headline, the progress bar, the stage checklist, a tip and
Cancel — while the homework flows showed a spinner with a title and the route loads a pulsing