close
Skip to content

fix(ui): solid glass fallback when backdrop-filter is unsupported (#1817) - #2569

Merged
kyleseaman merged 1 commit into
mainfrom
fix/glass-surface-backdrop-fallback-1817
Aug 10, 2026
Merged

fix(ui): solid glass fallback when backdrop-filter is unsupported (#1817)#2569
kyleseaman merged 1 commit into
mainfrom
fix/glass-surface-backdrop-fallback-1817

Conversation

@bolichen97

@bolichen97 bolichen97 commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

Closes #1817

Summary

On the Linux AppImage build the notifications bell panel renders see-through. Root cause: every glass surface in the dashboard derives its real opacity entirely from backdrop-filter.glass-surface carries only a 3–8% alpha gradient, .topbar-glass a transparent color-mix, and the notification sheet's floating cards a 55% color-mix + backdrop-blur. Where the engine does not support the property, the blur declaration is dropped at parse time and only the near-invisible tint remains. website/src/index.css had no @supports fallback anywhere.

Change

  • website/src/index.css — new @supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) block (both prefixes tested — Electron/Chromium historically supported one or the other), mirroring the existing prefers-reduced-transparency fallback so there is one consistent degradation story: solid var(--bg) for .glass-surface/.topbar-glass, solid var(--card) for the notification cards. Borders and shadows untouched, so panels stay visually delimited. Placed before the a11y overrides; those use !important and later source order, so they still win when both apply.
  • website/src/components/notifications/NotificationFeed.tsx — adds a notif-material class hook to the six mac-variant translucent card surfaces. Justification for going beyond the two glass classes: the reported surface is these cards (on v0.1.3 and on main the bell sheet is intentionally transparent, macOS-NC style, and every readable element is a floating color-mix+backdrop-blur card — .glass-surface there is only the error-boundary fallback). They fail exactly the same way, so they get exactly the same fallback. Class-name-only change, no logic.
  • Scope check on the other translucent classes: .file-chip composes .glass-surface in markup, so it is already covered; .glass-refract::before is a decorative highlight that does not depend on backdrop-filter for opacity — excluded.

Under the fallback, hover/active background tints flatten (borders still convey state) — the same trade the existing prefers-reduced-transparency override already makes. Platforms with working backdrop-filter never match the query: zero visual change on macOS/Windows and on Linux with a compositor.

Verification

A feature query cannot be exercised by vitest/jsdom, so per the issue's nature this is verified by build + asserting screenshots instead of a unit test:

  • New harness website/scripts/capture-glass-surface-fallback.mjs runs the real built SPA. Desktop Chromium always parses backdrop-filter, so the fallback branch is proven on a scratch copy of dist with the query guard rewritten to a tautology — the rule body is byte-identical to what ships, only the guard is forced. Frames assert computed styles, not just pixels:
    • 01-glass-normal: unmodified dist — card bg color(srgb … / 0.55) (translucent, glass unchanged) ✔
    • 02-fallback-solid: forced guard, dark — card bg rgb(33, 29, 37) (opaque) ✔
    • 03-fallback-light: forced guard, light — card bg rgb(255, 255, 255) (theme-following) ✔
normal (glass, unchanged) fallback forced (dark) fallback forced (light)
normal solid light

Close-ups of the panel region: normal · fallback dark · fallback light

Local gates: npx tsc -b ✔, npx vitest run ✔ (12,162 pass; two full-suite teardown flakes in unrelated apps pass in isolation), isort/flake8/mypy ✔, python -m pytest 40,368 pass with 65 failures that are host-environmental (this box denies unshare(CLONE_NEWUSER), so the sandbox backend is unavailable; identical failures on clean main).

Known residual

A feature query detects parse support, not runtime compositing failure. Linux GPU states where Chromium parses backdrop-filter but silently fails to composite it are not covered — that would need JS runtime probing and is beyond a CSS-only degradation story. This fix covers engines/builds where the property is genuinely unsupported (flag-gated or compiled out), and establishes the fallback pattern such probing could later toggle.

@bolichen97
bolichen97 requested a review from a team August 10, 2026 14:39
@bolichen97
bolichen97 requested a review from a team as a code owner August 10, 2026 14:39
@github-actions github-actions Bot added the readiness: checking Automated validation is still running label Aug 10, 2026
@github-actions

github-actions Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

GPT 5.6 Review — ✅ no blocking findings

GPT 5.6 completed its review of 97d6a98deb9565a3adf6e50caae17f6bf1a90ef8 and found no blocking issues.

This comment is updated in place on each push.

Review details

No findings.
[GPT-REVIEWED] 97d6a98

False positive or not applicable? A repository writer can comment:
/ai-review override gpt 97d6a98deb9565a3adf6e50caae17f6bf1a90ef8: <one-sentence reason>

@github-actions

github-actions Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Opus 4.8 Review — ✅ no blocking findings

Reviewed 97d6a98deb9565a3adf6e50caae17f6bf1a90ef8 — this comment is updated in place on each push.

Review details

This is a small, low-risk CSS + class-name change. Let me verify the key semantic concern: whether the notif-material fallback override interacts badly with the accent-subtle prompt banner and active states.

The diff shows:

  • New @supports not (...) block scoped to .topbar-glass, .glass-surface, .notif-material — applies only when backdrop-filter is unsupported, so zero change on supported engines.
  • .notif-material added to 6 mac-variant surfaces; !important overrides Tailwind hover/active tints under fallback.

The one place notif-material overrides a non-glass background is the prompt banner (bg-accent-subtle) and active card. Under the fallback those flatten to var(--card), losing the accent tint — but that's the same deliberate degradation the PR states (borders convey state), only reached on unsupported engines. Degraded-but-functional, not a defect. On supported engines nothing changes.

No crash, no security issue, no guard removal, no normal-path breakage. Committed temp-screenshots/ PNGs are repo clutter but carry no user/system consequence chain.

No findings.

[OPUS-REVIEWED] 97d6a98

Verdict parsed from the review's SHA-scoped output markers for commit 97d6a98deb9565a3adf6e50caae17f6bf1a90ef8.

False positive or not applicable? A repository writer can comment:
/ai-review override fable 97d6a98deb9565a3adf6e50caae17f6bf1a90ef8: <one-sentence reason>

@github-actions

github-actions Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Design Review (Fable 5) — 🟡 CONCERNS

Advisory design-level review of 97d6a98deb9565a3adf6e50caae17f6bf1a90ef8 — updated in place on each push; does not block merge.

Design-Verdict: CONCERNS

Sound fallback pattern, but no reproduction on an affected environment — the query may never match where #1817 actually happens.

Watch

  • The fix only activates on parse-time non-support ("older Chromium/Electron builds where it was flag-gated, or Linux builds compiled without it"), yet any recent Chromium/Electron — including a Linux AppImage — parses backdrop-filter; if the reporter's failure is the compositing-failure mode the PR itself carves out ("Linux GPU states where Chromium parses backdrop-filter but silently fails to composite it are not covered"), the @supports not block never matches, the panel stays see-through, and "Closes Transparent notifications section on Linux/AppImage #1817" auto-closes an unfixed issue. All verification runs on a tautology-forced guard, not the reported environment — confirm the fallback fires on an actual AppImage repro (or reword to "mitigates" and keep the issue open) before treating this as the fix.

[DESIGN-REVIEWED] 97d6a98

@github-actions

github-actions Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

UX Review (Fable 5) — ✅ PASS

Advisory UX-level review of 97d6a98deb9565a3adf6e50caae17f6bf1a90ef8 — updated in place on each push; does not block merge.

UX-Verdict: PASS

Solid-card fallback reads cleanly in both themes and mirrors the existing reduced-transparency degradation; no new strings, flows, or controls to misread.

Suggestions

  • The !important in .notif-material{ background:var(--card) !important } (index.css) also overrides hover:bg-[color-mix(…var(--card)_70%…)] and the active row's bg-accent-subtle / prompt strip tint — on fallback platforms notification rows give zero hover acknowledgment and the selected row keeps only its accent border. Add fallback-scoped state rules inside the same @supports block (e.g. .notif-material:hover{ background:var(--bg-hover) !important } and an active-card equivalent) so pointer feedback and selection tint survive the degradation.

[UX-REVIEWED] 97d6a98

@github-actions github-actions Bot added readiness: action required A blocking check or review needs attention and removed readiness: checking Automated validation is still running labels Aug 10, 2026
)

Every glass surface derives its real opacity from backdrop-filter alone:
.glass-surface carries a 3-8% alpha gradient, .topbar-glass a transparent
color-mix, and the notification sheet's floating cards a 55% color-mix +
backdrop-blur. Where the engine does not support backdrop-filter the blur
declaration is dropped at parse time and only the near-invisible tint
remains -- the transparent notifications panel reported on Linux/AppImage.

Add an '@supports not ((backdrop-filter) or (-webkit-backdrop-filter))'
block mirroring the existing prefers-reduced-transparency fallback: solid
var(--bg) for .glass-surface/.topbar-glass, solid var(--card) for the new
.notif-material hook on the notification cards. Borders and shadows stay,
so panels remain delimited; platforms with working backdrop-filter never
match the query and keep the glass look unchanged.

A feature query cannot be exercised by vitest/jsdom, so the fallback is
verified by an asserting Playwright harness against the built SPA with
the query guard forced on a scratch copy of dist (screenshots under
temp-screenshots/glass-surface-fallback/).

Closes #1817
@bolichen97
bolichen97 force-pushed the fix/glass-surface-backdrop-fallback-1817 branch from 08966be to 97d6a98 Compare August 10, 2026 15:07
@github-actions github-actions Bot added readiness: checking Automated validation is still running readiness: action required A blocking check or review needs attention readiness: passed Eligible automated validation passed for the current revision and removed readiness: action required A blocking check or review needs attention readiness: checking Automated validation is still running labels Aug 10, 2026
@kyleseaman
kyleseaman merged commit 08ec974 into main Aug 10, 2026
84 of 88 checks passed
@kyleseaman
kyleseaman deleted the fix/glass-surface-backdrop-fallback-1817 branch August 10, 2026 18:54
@github-actions github-actions Bot removed the readiness: passed Eligible automated validation passed for the current revision label Aug 10, 2026
encomjp pushed a commit to encomjp/kirocrew-customapi that referenced this pull request Aug 22, 2026
…rodotdev#1817) (kirodotdev#2569)

Every glass surface derives its real opacity from backdrop-filter alone:
.glass-surface carries a 3-8% alpha gradient, .topbar-glass a transparent
color-mix, and the notification sheet's floating cards a 55% color-mix +
backdrop-blur. Where the engine does not support backdrop-filter the blur
declaration is dropped at parse time and only the near-invisible tint
remains -- the transparent notifications panel reported on Linux/AppImage.

Add an '@supports not ((backdrop-filter) or (-webkit-backdrop-filter))'
block mirroring the existing prefers-reduced-transparency fallback: solid
var(--bg) for .glass-surface/.topbar-glass, solid var(--card) for the new
.notif-material hook on the notification cards. Borders and shadows stay,
so panels remain delimited; platforms with working backdrop-filter never
match the query and keep the glass look unchanged.

A feature query cannot be exercised by vitest/jsdom, so the fallback is
verified by an asserting Playwright harness against the built SPA with
the query guard forced on a scratch copy of dist (screenshots under
temp-screenshots/glass-surface-fallback/).

Closes kirodotdev#1817
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Transparent notifications section on Linux/AppImage

2 participants