Aero: nested tiles in the real-blur chrome drop the baked backdrop

Chrome cannot anchor a background-attachment: fixed layer inside a
backdrop-filter ancestor, so the composer's attach button baked the blurred
wallpaper against its own box and read as a solid, mismatched tile (often a
dark crop of grass) next to the pale field. Inside .glass-panel /
.study-chrome / .glass / .tabbar the nesting chrome (surface tokens,
white/xx fills, chips, cards) now drops the bake and keeps its flat token
fill - the panel's own blur is the glass - mirroring the existing
.glass-sheet carve-out. The composer's textarea keeps its brighter field
recipe (exempted via :not()), and .aero .btn-ghost gains the same carve-out
so the study pager's arrows sit flat in the pill.

Probe: the attach tile samples the band glass (115,137,118) instead of a
dark mis-crop (73,102,77). All 15 suites green, contrast scan clean.

Version 0.6.6, SW v88.
This commit is contained in:
Martin Dvořák 2026-10-15 16:00:37 +00:00
commit b5c4f237cd
4 changed files with 80 additions and 2 deletions

View file

@ -1434,6 +1434,20 @@ Things I chose while building, with the reasoning:
(measured: 268..1280 at a 1280 window) — a flat pane floating 40px inside the scene read as (measured: 268..1280 at a 1280 window) — a flat pane floating 40px inside the scene read as
"cut off next to the sidebar". "cut off next to the sidebar".
97. **Nested tiles inside the real-blur chrome drop the baked backdrop.** "Frutiger aero theme —
the attachment button looks completely different to the other ones." The composer band, the
chat header and the study pager keep a real `backdrop-filter` (they float over scrolling
content), but Chrome cannot anchor a `background-attachment: fixed` layer *inside* a blurred
ancestor: the bake is laid out against the element itself, so the attach button sampled a tiny
(often dark, sometimes oddly green) crop of the wallpaper instead of the glass behind it — a
solid, mismatched tile next to the pale field. Fix in the same spirit as the sheet carve-out:
inside `.glass-panel` / `.study-chrome` / `.glass` / `.tabbar` the nesting chrome (`surface`
tokens, white/xx fills, chips, cards) drops the bake and keeps its flat token fill — the
panel's own blur *is* the glass — while the composer's textarea keeps its brighter tile
recipe (exempted by `:not()`), and `.aero .btn-ghost` gains the same carve-out so the study
pager's arrows sit flat in the pill. Probes pin it: the attach tile now samples the band
(115,137,118) instead of a dark mis-crop (73,102,77), all suites green, contrast scan 0.
96. **Skipping a card is not a mistake.** "You can just scroll all the way down and it counts 96. **Skipping a card is not a mistake.** "You can just scroll all the way down and it counts
everything as incorrect even if you technically just skip it to do it later." The study feed's everything as incorrect even if you technically just skip it to do it later." The study feed's
results treated *every* card without a result as missed: swiping to the end recorded a 0% results treated *every* card without a result as missed: swiping to the end recorded a 0%

View file

@ -753,6 +753,17 @@
border: 1px solid rgb(255 255 255 / 0.6); border: 1px solid rgb(255 255 255 / 0.6);
color: var(--text); color: var(--text);
} }
/* Inside the real-blur chrome (study pager), the ghost buttons drop the bake
too — same anchoring bug as every other nested tile, and the pill's own
blur is the glass they should match. */
.aero .glass-panel .btn-ghost,
.aero .glass .btn-ghost,
.aero .study-chrome .btn-ghost,
.aero .tabbar .btn-ghost {
background-image: none;
border-color: var(--glass-border);
background-color: rgb(255 255 255 / 0.23);
}
/* Page headings that sit straight on the wallpaper. */ /* Page headings that sit straight on the wallpaper. */
.aero .page-heading { .aero .page-heading {
@ -797,6 +808,59 @@
background-image: none; background-image: none;
} }
/* The same principle extends to the floating chrome that carries a real
backdrop blur — the chat header, the composer band, the desktop pickers,
the study pill and the phone tab bar (the `.glass` header bar too).
Chrome cannot anchor a `background-attachment: fixed` layer inside a
backdrop-filter ancestor: the bake is laid out against the element itself,
so a small tile samples a tiny random detail of the wallpaper and reads as
a solid, mismatched button — the composer's attach button rendered as a
dark patch of grass next to the pale glass field. The panel's own blur is
the glass here, exactly like inside sheets, so nested chrome drops the
bake and keeps its flat token fill. The composer's field is deliberately
exempt (`:not()` on the bake selectors): its brighter glass tile is its
own thin recipe, and it is the wide element that still anchors correctly. */
.aero .glass-panel .card,
.aero .glass-panel .glass-solid,
.aero .glass-panel .sidebar-surface,
.aero .glass-panel .gate-card,
.aero .glass-panel .list-group,
.aero .glass-panel .nav-action,
.aero .glass-panel .nav-row[aria-current="page"],
.aero .glass-panel .nav-row[aria-pressed="true"],
.aero .glass-panel .nav-row[data-active="true"],
.aero .glass-panel .glass-chip,
.aero .glass-panel .glass-pill,
.aero .glass-panel .btn-secondary,
.aero .glass-panel .chat-empty,
.aero .glass-panel .segmented,
.aero .glass-panel [class*="bg-white/35"],
.aero .glass-panel [class*="bg-white/40"],
.aero .glass-panel [class*="bg-white/45"],
.aero .glass-panel [class*="bg-white/50"],
.aero .glass-panel [class*="bg-white/55"],
.aero .glass-panel [class*="bg-white/60"],
.aero .glass-panel [class*="bg-white/70"],
.aero .glass-panel [class*="bg-[var(--surface)]"],
.aero .glass-panel [class*="bg-[var(--surface-strong)]"]:not(textarea):not(input[type="search"]),
.aero .glass-panel [class*="bg-[var(--surface-sunken)]"],
.aero .glass-panel [class*="bg-frost-50"] {
background-image: none;
}
.aero .study-chrome [class*="bg-white/35"],
.aero .study-chrome [class*="bg-white/40"],
.aero .study-chrome [class*="bg-white/45"],
.aero .study-chrome [class*="bg-white/50"],
.aero .study-chrome [class*="bg-white/55"],
.aero .study-chrome [class*="bg-white/60"],
.aero .study-chrome [class*="bg-white/70"],
.aero .study-chrome [class*="bg-[var(--surface)]"],
.aero .study-chrome [class*="bg-[var(--surface-strong)]"],
.aero .study-chrome [class*="bg-[var(--surface-sunken)]"],
.aero .study-chrome [class*="bg-frost-50"] {
background-image: none;
}
html, html,
body { body {
height: 100%; height: 100%;

View file

@ -1,6 +1,6 @@
{ {
"name": "freezmo", "name": "freezmo",
"version": "0.6.5", "version": "0.6.6",
"private": true, "private": true,
"license": "GPL-3.0-only", "license": "GPL-3.0-only",
"scripts": { "scripts": {

View file

@ -9,7 +9,7 @@
* *
* Bumping CACHE_VERSION is how a new deploy invalidates old assets. * Bumping CACHE_VERSION is how a new deploy invalidates old assets.
*/ */
const CACHE_VERSION = "freezmo-v87"; const CACHE_VERSION = "freezmo-v88";
const SHELL_CACHE = `${CACHE_VERSION}-shell`; const SHELL_CACHE = `${CACHE_VERSION}-shell`;
const ASSET_CACHE = `${CACHE_VERSION}-assets`; const ASSET_CACHE = `${CACHE_VERSION}-assets`;