cmux-next: glass over art keeps main text readable, like iOS, and shows the art

Closed
TE
17d ago
+1011-44

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.
    • .all is 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 marked needs_review. SettingsApplier applies it, so CmuxNextApp does not grow.
  • Floor over Hokusai. These numbers come from my model of the derivation, not from the app:
ThemeAll text (before)Main text (now)
Clay Orange0.850.63
Soft Blue0.820.58
Clay Orange Light~1.00.49
Soft Blue Light0.960.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


View with [code]smith Autofix with [code]smith
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.glassLegibility takes "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 ThemeScope and inherits like art: SettingsApplier sets it on the app scope, so changing it repaints every window and workspace scope from the root. WindowBackdrop takes 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

  • GlassLegibilityTests covers 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. GlassLegibilitySettingTests covers the default, "all", and a bad value plus its diagnostic.