From b5c4f237cd6dd8a94640847c6fe5d9804d41a5b0 Mon Sep 17 00:00:00 2001 From: Martin Dvorak Date: Thu, 15 Oct 2026 16:00:37 +0000 Subject: [PATCH] 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. --- README.md | 14 +++++++++++ app/globals.css | 64 +++++++++++++++++++++++++++++++++++++++++++++++++ package.json | 2 +- public/sw.js | 2 +- 4 files changed, 80 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5e9b0c3..99ca516 100644 --- a/README.md +++ b/README.md @@ -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 "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 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% diff --git a/app/globals.css b/app/globals.css index ad7d4d4..a1a4300 100644 --- a/app/globals.css +++ b/app/globals.css @@ -753,6 +753,17 @@ border: 1px solid rgb(255 255 255 / 0.6); 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. */ .aero .page-heading { @@ -797,6 +808,59 @@ 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, body { height: 100%; diff --git a/package.json b/package.json index 524b975..2a0f3bf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "freezmo", - "version": "0.6.5", + "version": "0.6.6", "private": true, "license": "GPL-3.0-only", "scripts": { diff --git a/public/sw.js b/public/sw.js index ded614a..dd64b33 100644 --- a/public/sw.js +++ b/public/sw.js @@ -9,7 +9,7 @@ * * 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 ASSET_CACHE = `${CACHE_VERSION}-assets`;