One Ask-style glass everywhere, cache-busted Aero wallpaper
The background "didn't change" because the service worker's asset cache kept serving the previous wallpaper bytes (stale-while-revalidate returns the cached copy first, and an old worker can outlive a deploy). Both aero images carry a ?v=3 query now, so a stale cache cannot answer for them. "Everything should look like the Ask button" is literal: the rail, the cards, the chips, the segments and the buttons share one recipe - the pre-blurred wallpaper under a ~15% veil with the bright rim. The blur bake is regenerated at 640x400 with a shadow lift (gamma 0.86) and a saturation nudge, so the scene's colours stay vivid instead of washing to a milky film. The wizard's phone action bar loses Aero's heavy water-blue slab for the same glass, and nested chrome inside sheets keeps its flat fills (the sheet itself is the real glass there). Contrast: 0 below-minimum findings on every screen and theme, 0 axe violations. Version 0.3.2, SW -> freezmo-v63.
This commit is contained in:
parent
c88ad2865a
commit
0c5d0ffb11
5 changed files with 70 additions and 60 deletions
21
README.md
21
README.md
|
|
@ -1407,10 +1407,23 @@ Things I chose while building, with the reasoning:
|
|||
painted the dark palette over the bright wallpaper, until a theme toggle re-applied the
|
||||
classes. The stored value now decides alone and the class is toggled explicitly;
|
||||
`tests/mobile-test.mjs` pins it with a dark-`colorScheme` browser context. And the surfaces
|
||||
drop their thick white veils (a card top measured ~71% white) for a 14% base veil plus the
|
||||
gloss over the pre-blurred wallpaper — the scene is clearly visible through the glass, small
|
||||
chrome (rows, chips, segments, buttons) keeps slightly more veil, and the pixel-contrast scan
|
||||
that re-runs in the deploy e2e gate still passes.
|
||||
drop their thick white veils (a card top measured ~71% white) for thin veils over the
|
||||
pre-blurred wallpaper — the scene is clearly visible through the glass, and the
|
||||
pixel-contrast scan still passes.
|
||||
|
||||
67. **The Aero wallpaper URL is cache-busted, and every surface is one glass.** Two fixes from
|
||||
one report. The background "didn't change" because the service worker's asset cache kept
|
||||
serving the previous wallpaper bytes (stale-while-revalidate returns the cached copy first,
|
||||
and the old worker can outlive a deploy): both aero images now carry a `?v=3` query, so a
|
||||
stale cache cannot answer for them, and future wallpaper swaps get a new query too. And
|
||||
"everything should look like the Ask button" is now literal: the rail, the cards, the chips,
|
||||
the segments and the buttons all share one recipe — the pre-blurred wallpaper under a ~15%
|
||||
veil (the minimum the pixel-contrast scan needs) with the bright rim. The blur bake is
|
||||
shadow-lifted (gamma 0.86) and slightly saturated so the scene's colours stay vivid instead
|
||||
of washing out to a milky film, the wizard's phone action bar (Aero's `--page` token was the
|
||||
saturated water blue, a heavy slab over the photo) joins in, and nested chrome inside sheets
|
||||
keeps its flat fills (the sheet itself is the real glass there). `tests/contrast.mjs` is back
|
||||
to 0 findings across every screen and theme.
|
||||
|
||||
65. **Slide content never flex-shrinks, and the AI note appears once.** A long typed answer in a
|
||||
short-answer activity shrank the textarea inside the slide's flex column (58px instead of its
|
||||
|
|
|
|||
101
app/globals.css
101
app/globals.css
|
|
@ -208,7 +208,7 @@
|
|||
--surface: #ffffff;
|
||||
--surface-raised: #ffffff;
|
||||
--surface-strong: rgb(255 255 255 / 0.72);
|
||||
--card-hover-bg: rgb(255 255 255 / 0.9);
|
||||
--card-hover-bg: rgb(255 255 255 / 0.5);
|
||||
--surface-sunken: rgb(255 255 255 / 0.5);
|
||||
--hairline: rgb(255 255 255 / 0.75);
|
||||
--card-border: var(--glass-border);
|
||||
|
|
@ -222,7 +222,7 @@
|
|||
wizard's step help): darker here, because they sit on the water. */
|
||||
--color-frost-600: #16324a;
|
||||
--color-frost-700: #102a41;
|
||||
--hover: rgb(255 255 255 / 0.45);
|
||||
--hover: rgb(255 255 255 / 0.32);
|
||||
--focus: #0369a1;
|
||||
|
||||
/* Pale blue glass, like the mock: bright enough for dark navy text. */
|
||||
|
|
@ -261,7 +261,7 @@
|
|||
in public/aero/). Only the moving bubbles are drawn on top; the image
|
||||
already has grass, sun, water and clouds. */
|
||||
.aero .ice-scene {
|
||||
background-image: url("/aero/background.webp");
|
||||
background-image: url("/aero/background.webp?v=3");
|
||||
background-size: cover;
|
||||
background-position: center 42%;
|
||||
background-repeat: no-repeat;
|
||||
|
|
@ -288,17 +288,17 @@
|
|||
|
||||
/* The Aero gloss for the floating surfaces (sheets, dropdowns and the sticky
|
||||
chrome keep a real backdrop-filter — they sit over scrolling content).
|
||||
Thin like the card glass: the old 75% top read as a white lid. */
|
||||
Thin like the card glass: a whisper of sheen, not a white lid. */
|
||||
.aero .glass-panel,
|
||||
.aero .study-chrome,
|
||||
.aero .tabbar,
|
||||
.aero .glass {
|
||||
background-image: linear-gradient(
|
||||
180deg,
|
||||
rgb(255 255 255 / 0.5) 0%,
|
||||
rgb(255 255 255 / 0.18) 46%,
|
||||
rgb(255 255 255 / 0.05) 47%,
|
||||
rgb(255 255 255 / 0.14) 100%
|
||||
rgb(255 255 255 / 0.32) 0%,
|
||||
rgb(255 255 255 / 0.1) 46%,
|
||||
rgb(255 255 255 / 0.03) 47%,
|
||||
rgb(255 255 255 / 0.1) 100%
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -361,10 +361,8 @@
|
|||
@apply backdrop-blur-md backdrop-saturate-150;
|
||||
}
|
||||
|
||||
/* The thin glass the Ask / Import JSON buttons use: a 34% white tint over the
|
||||
sharp wallpaper with a bright rim — no pre-blurred layer, so it reads as
|
||||
glass rather than as a white chip. Rail rows, the active nav item and the
|
||||
active segment all match it. */
|
||||
/* Bright white rims on the study/homework segments (the frosted fill itself
|
||||
comes from the shared glass recipe below). */
|
||||
.aero .segmented > button,
|
||||
.aero .segmented > a {
|
||||
border-color: rgb(255 255 255 / 0.5);
|
||||
|
|
@ -388,44 +386,28 @@
|
|||
stay thin too. Contrast is pixel-scanned in all three themes, so the tints
|
||||
cannot drop below what the text needs. */
|
||||
.aero {
|
||||
--glass-bg: rgb(228 246 255 / 0.3);
|
||||
--glass-solid-bg: rgb(232 248 255 / 0.42);
|
||||
--glass-sheet-bg: rgb(232 248 255 / 0.74);
|
||||
--surface-strong: rgb(255 255 255 / 0.32);
|
||||
--surface-sunken: rgb(255 255 255 / 0.24);
|
||||
--nav-active-bg: rgb(255 255 255 / 0.38);
|
||||
--glass-bg: rgb(228 246 255 / 0.26);
|
||||
--glass-solid-bg: rgb(232 248 255 / 0.34);
|
||||
--glass-sheet-bg: rgb(232 248 255 / 0.68);
|
||||
--surface-strong: rgb(255 255 255 / 0.26);
|
||||
--surface-sunken: rgb(255 255 255 / 0.2);
|
||||
--nav-active-bg: rgb(255 255 255 / 0.3);
|
||||
}
|
||||
|
||||
/* Liquid glass without the per-frame cost: every surface shows a pre-blurred
|
||||
copy of the wallpaper, glued to the viewport (`background-attachment:
|
||||
fixed`), with the tint and the gloss layered on top. Blurring the live
|
||||
scene instead measured 66ms per frame at 2x CPU throttle — the bubbles move
|
||||
behind every surface, so a real backdrop-filter re-runs ~60 times a second
|
||||
(vs 17ms with nothing blurring). The look is the same; the cost is zero. */
|
||||
/* Liquid glass — one recipe for every surface, so the rail, the cards, the
|
||||
chips, the segments and the buttons all read exactly like the Ask pill: a
|
||||
pre-blurred, slightly lifted copy of the wallpaper (glued to the viewport,
|
||||
same cover/42% geometry as the scene) under a whisper-thin veil and a
|
||||
bright rim. Real backdrop-filter is skipped on purpose: the bubbles move
|
||||
behind every surface, so it re-runs ~60 times a second (measured 66ms per
|
||||
frame at 2x CPU throttle vs 17ms with nothing blurring). The veils are the
|
||||
minimum the pixel-contrast scan needs to hold 4.5:1 for the small muted
|
||||
text — anything more and the glass reads as a white panel. */
|
||||
.aero .card,
|
||||
.aero .glass-solid,
|
||||
.aero .sidebar-surface,
|
||||
.aero .gate-card,
|
||||
.aero .list-group {
|
||||
background-image:
|
||||
linear-gradient(
|
||||
180deg,
|
||||
rgb(255 255 255 / 0.3) 0%,
|
||||
rgb(255 255 255 / 0.1) 46%,
|
||||
rgb(255 255 255 / 0.04) 53%,
|
||||
rgb(255 255 255 / 0.14) 100%
|
||||
),
|
||||
linear-gradient(rgb(255 255 255 / 0.14), rgb(255 255 255 / 0.14)),
|
||||
url("/aero/background-blur.webp");
|
||||
background-size: 100% 100%, 100% 100%, cover;
|
||||
background-position: 0 0, 0 0, center 42%;
|
||||
background-attachment: scroll, scroll, fixed;
|
||||
background-repeat: no-repeat, no-repeat, no-repeat;
|
||||
}
|
||||
|
||||
/* The small chrome — rail rows, the active nav item, chips, segments and the
|
||||
buttons — gets the same frosted glass with a touch more veil, so its small
|
||||
text pops over the busy wallpaper. */
|
||||
.aero .list-group,
|
||||
.aero .nav-action,
|
||||
.aero .nav-row[aria-current="page"],
|
||||
.aero .nav-row[data-active="true"],
|
||||
|
|
@ -439,25 +421,40 @@
|
|||
background-image:
|
||||
linear-gradient(
|
||||
180deg,
|
||||
rgb(255 255 255 / 0.42) 0%,
|
||||
rgb(255 255 255 / 0.16) 46%,
|
||||
rgb(255 255 255 / 0.08) 53%,
|
||||
rgb(255 255 255 / 0.2) 100%
|
||||
rgb(255 255 255 / 0.16) 0%,
|
||||
rgb(255 255 255 / 0.05) 46%,
|
||||
rgb(255 255 255 / 0.04) 53%,
|
||||
rgb(255 255 255 / 0.09) 100%
|
||||
),
|
||||
linear-gradient(rgb(255 255 255 / 0.12), rgb(255 255 255 / 0.12)),
|
||||
url("/aero/background-blur.webp");
|
||||
linear-gradient(rgb(255 255 255 / 0.15), rgb(255 255 255 / 0.15)),
|
||||
url("/aero/background-blur.webp?v=3");
|
||||
background-size: 100% 100%, 100% 100%, cover;
|
||||
background-position: 0 0, 0 0, center 42%;
|
||||
background-attachment: scroll, scroll, fixed;
|
||||
background-repeat: no-repeat, no-repeat, no-repeat;
|
||||
}
|
||||
|
||||
/* The wizard's phone action bar: Aero's page token is the saturated water
|
||||
blue, which read as a heavy slab over the photo — give it the same thin
|
||||
glass as everything else (it already has a real backdrop blur). */
|
||||
.aero [data-wizard-bar] {
|
||||
background: rgb(255 255 255 / 0.24);
|
||||
border-top-color: rgb(255 255 255 / 0.6);
|
||||
box-shadow: 0 -14px 34px -22px rgb(2 62 110 / 0.5);
|
||||
}
|
||||
|
||||
/* The phone tab bar carries its labels right at the bottom of the water, so
|
||||
it keeps a little more veil than the cards. */
|
||||
.aero .tabbar {
|
||||
background-image:
|
||||
linear-gradient(rgb(255 255 255 / 0.48), rgb(255 255 255 / 0.48)),
|
||||
url("/aero/background-blur.webp");
|
||||
linear-gradient(
|
||||
180deg,
|
||||
rgb(255 255 255 / 0.26) 0%,
|
||||
rgb(255 255 255 / 0.12) 46%,
|
||||
rgb(255 255 255 / 0.1) 53%,
|
||||
rgb(255 255 255 / 0.16) 100%
|
||||
),
|
||||
url("/aero/background-blur.webp?v=3");
|
||||
background-size: 100% 100%, cover;
|
||||
background-position: 0 0, center 42%;
|
||||
background-attachment: scroll, fixed;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "freezmo",
|
||||
"version": "0.3.1",
|
||||
"version": "0.3.2",
|
||||
"private": true,
|
||||
"license": "GPL-3.0-only",
|
||||
"scripts": {
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 8.7 KiB |
|
|
@ -9,7 +9,7 @@
|
|||
*
|
||||
* Bumping CACHE_VERSION is how a new deploy invalidates old assets.
|
||||
*/
|
||||
const CACHE_VERSION = "freezmo-v62";
|
||||
const CACHE_VERSION = "freezmo-v63";
|
||||
const SHELL_CACHE = `${CACHE_VERSION}-shell`;
|
||||
const ASSET_CACHE = `${CACHE_VERSION}-assets`;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue