fix(ui): every modal dims the screen the same way, and with the theme - #81
Merged
Conversation
T3 was planned as "the 16 ad-hoc alphas are the de-facto elevation system". Measured, that premise does not hold. There are 14 distinct alphas across 32 sites, and there is no elevation system for them to be: hideGit draws no shadows anywhere, and a modal is told apart from the screen by its scrim and its own surface colour rather than by depth. What they are is four unrelated jobs sharing a spelling — a scrim, an interaction state, a background wash, and fading something out. Reading them that way turned up a real defect. Six places dim the screen behind a modal. Five build the scrim from `palette.background` at 0.75. The sixth used `Color::BLACK` at 0.55 — and the sixth is `overlay`, which draws every confirmation, action sheet, prompt and device-code dialog. So on the light theme, the modals people see most were the only things on screen dimmed with black, while a plan editor or a command palette dimmed it with the page. `Palette::selection` already records the general form of this: an alpha tuned on a dark background does not transfer to a light one, which is why the selection colours are opaque per-theme values. The scrim was the case that had not learned it. So `theme::scrim` is the one way to dim the screen, and `HOVERED` and `DISABLED` are named for the same reason one step smaller — a control dimmed 0.5 in one dialog and 0.35 in another is the same drift. Both outliers are corrected. The scrim is pinned by a test that it differs between the two palettes, which is what `Color::BLACK` could never satisfy. The relations between the three constants are compile-time assertions rather than tests: clippy is right that a runtime assertion over constants proves nothing, and a wrong value should fail the build. The background washes are left alone. They are the case `Palette::selection` is actually about, they need opaque per-palette colours rather than a named alpha, and that is the colour-roles work rather than this.
This was referenced Aug 21, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
T3 — and the premise did not hold.
The plan called the ad-hoc alphas "the de-facto elevation system". Measured: 14 distinct alphas across 32 sites in 13 files, and there is no elevation system for them to be — hideGit draws no shadows anywhere. A modal is told apart from the screen by its scrim and its own surface colour, not by depth.
They are four unrelated jobs sharing a spelling: a scrim, an interaction state, a background wash, and fading something out. Reading them that way is what turned up the defect below.
The defect
Six places dim the screen behind a modal.
plan.rs,palette.rs,shortcuts.rs,settings.rs,search.rspalette.backgroundat 0.75overlay.rsColor::BLACKat 0.55The odd one out is
overlay, which draws every confirmation, action sheet, prompt and device-code dialog. So on the light theme, the modals people see most were the only things on screen dimmed with black, while a plan editor or a command palette dimmed it with the page.Palette::selectionalready records the general form of this — "an alpha tuned on a dark background does not transfer", which is why the selection colours are opaque per-theme values. The scrim was the case that had not learned it.What lands
theme::scrim(palette)is the one way to dim the screen, used by all six.HOVEREDandDISABLEDare named for the same reason one step smaller: a control dimmed0.5in the plan editor and0.35in a dialog is the same drift. Both outliers corrected.How it is pinned
The scrim's test asserts it differs between the two palettes — which
Color::BLACKcould never satisfy, whatever its alpha. That is the invariant, not the number.The relations between the three constants are compile-time assertions, not tests:
I wrote them as a test first and clippy caught it, exactly as in #80: a runtime assertion over constants proves nothing about a run, and a wrong value should fail the build.
Sabotage — three, all confirmed
Color::BLACKthe_scrim_follows_the_theme_rather_than_being_blackDISABLEDbecomes more opaque thanHOVEREDSCRIMdrops belowDISABLEDWhat is deliberately left
The background washes —
accentat 0.12,borderat 0.5, and the rest. Those are the casePalette::selectionis actually about: they need opaque per-palette colours rather than a named alpha, and picking those colours is the colour-roles work later in the plan, not a token rename.Screenshots
None retaken. The four committed ones show no modal, and the one scrim visible among them — the command palette's — already used
palette.backgroundand is unchanged. The change is visible on a confirmation dialog in the light theme, which none of them contain; the palette-differs test is what stands in for that, and it is a stronger check than an image.Gate
cargo fmt --all -- --check,cargo clippy --workspace --all-targets --all-features --locked -- -D warnings,cargo test --workspace --all-features --locked— 896 tests, all green.