cmux-next: glass over art keeps main text readable, like iOS, and shows the art
Over background art, the window's glass held every text role (primary, secondary, tertiary) at WCAG contrast against the art's darkest and lightest colors (BackdropArtRange.scrimOpacity). That pinned the tint at 0.82โ1.0 for every theme, so a work's own 0.7 tint never applied and the art showed through at 6โ14%.
Leo asked for iOS-style glass ("IOS IOS", 2026-10-18). iOS keeps primary text readable over a wallpaper and lets secondary text ride on the material. This PR does the same by default, and adds a setting to go back.
ArtLegibility(CmuxNextDesign) has two cases:.primary(default) counts only primary text at AA in the floor..allis the old rule.- It is part of the backdrop repaint key, so changing it repaints every window and workspace scope.
appearance.glassLegibility(CmuxNextSettings) takes"primary"(Main Text) or"all"(All Text). It has a Settings choice under Window, with strings in all 21 languages; the non-English ones are markedneeds_review.SettingsApplierapplies it, so CmuxNextApp does not grow.- Floor over Hokusai. These numbers come from my model of the derivation, not from the app:
| Theme | All text (before) | Main text (now) |
|---|---|---|
| Clay Orange | 0.85 | 0.63 |
| Soft Blue | 0.82 | 0.58 |
| Clay Orange Light | ~1.0 | 0.49 |
| Soft Blue Light | 0.96 | 0.43 |
- Trade-off: secondary and tertiary text can fall below AA over the brightest or darkest parts of a work. Reduce Transparency is unchanged and stays opaque.
- Follow-ups: blurring the art (with a slider), glass overlays, and composer glass with a native refracting rim.
Tests: GlassLegibilityTests (the main-text floor is lower and keeps primary text at AA) and GlassLegibilitySettingTests (default, "all", a bad value plus its diagnostic). Before/after tour media will follow once #21655, which adds the glass tour, is on the base.
๐ค Generated with Claude Code
Need help on this PR? Tag @codesmith-bot with what you need.
Summary by cubic
The glass over background art now keeps only primary text at WCAG AA by default, like iOS glass over a wallpaper, so far more of the art shows (about 0.43โ0.63 tint instead of 0.82โ1.0).
appearance.glassLegibilitytakes"primary"(Main Text, the default) or"all"(All Text, the old dense glass); a bad value falls back to Main Text with a diagnostic.- The choice lives on
ThemeScopeand inherits like art:SettingsAppliersets it on the app scope, so changing it repaints every window and workspace scope from the root.WindowBackdroptakes it as a parameter from the scope that paints, and Settings' unset Opacity slider now rests on the same tint floor the window paints. - Secondary and tertiary text can drop below AA over the brightest or darkest parts of a work; Reduce Transparency is unchanged. A see-through webview's tertiary text now maps to the secondary tier to match.
- Ships the setting schema, MDM docs, agent policy, and strings in all 21 languages (non-English marked
needs_review).
Tests
GlassLegibilityTestscovers the lower primary-only floor, the"all"floor holding every role, backdrop inheritance, the window backdrop floor, and the unset Opacity slider following the choice.GlassLegibilitySettingTestscovers the default,"all", and a bad value plus its diagnostic.