update theme

This commit is contained in:
2026-10-09 11:19:56 +07:00
parent 5c15b0e840
commit 70540abd5d
11 changed files with 137 additions and 27 deletions
+72 -4
View File
@@ -117,7 +117,7 @@ is only consumed via `sync_base` or not at all.
| Old | New | Notes | Uses |
| --- | --- | --- | --- |
| `text` | `text` | | 16 |
| `text_muted` | `text_muted` | | 53 |
| `text_muted` | `text_muted` | light value darkened to `neutral(0.45)` (~5.3:1) — AppKit's secondary label was too faint on the chrome grey | 53 |
| `text_placeholder` | `text_faint` | | 25 |
| `text_accent` | `accent` | | 1 |
| `text_danger` | `danger` | soft/inline error copy → `danger_muted` | 10 |
@@ -146,8 +146,8 @@ is only consumed via `sync_base` or not at all.
| `danger_background` | `danger_strong` | destructive plate; tinted chips → `danger_muted` | 4 |
| `danger_hover` / `danger_active` / `danger_selected` | plate-hover helper | one helper that brightens (dark) / darkens (light) a plate | 1/1/1 |
| `danger_disabled` | `wash()` at disabled alpha | | 1 |
| `warning_foreground` | `text` | icons/rules may use `warning` | 5 |
| `warning_background` | `warning_muted` | | 5 |
| `warning_foreground` | `warning` | `warning_muted` is a translucent amber wash; the label is the amber token itself | 5 |
| `warning_background` | `warning_muted` | translucent amber wash (`warning` at 10% light / 16% dark) | 5 |
| `warning_hover` / `warning_active` / `warning_selected` | `element_hover` / `element_active` | on the chip | 1/1/1 |
| `warning_disabled` | `wash()` at disabled alpha | | 1 |
| `ghost_element_background` | transparent | drop | 6 |
@@ -163,7 +163,7 @@ is only consumed via `sync_base` or not at all.
| `tab_background` | `surface` | | 2 |
| `tab_foreground` | `text_muted` | | 1 |
| `tab_hover_background` | `element_hover` | | 2 |
| `tab_active_background` | `bg` | active tab merges with the content plane, hairline separates | 1 |
| `tab_active_background` | `element_active` | one rung past `element_hover` (darker in light, brighter in dark); hairline separates from the plane | 1 |
| `tab_active_foreground` | `text` | | 2 |
| `scrollbar_*` (5 tokens) | gpui-base scrollbar tokens | via `sync_base` only | 0 |
| `drop_target_background` | `drop_target` | | 1 |
@@ -363,6 +363,41 @@ passes inside this crate); `cargo check -p ui`, `cargo check --workspace`,
`cargo test -p theme` (11 tests) and `cargo clippy -p ui -p theme` are green.
Public APIs, element structure, sizes and heights unchanged (D2, D7).
Light-mode review fixes (after running the app):
- **Warning chip is a wash, not a plate.** Bezel's `warning_muted` is a
strong amber (800 light / 200 dark) meant to carry white/black ink; on a
button it read as muddy brown. Both appearances now derive
`warning_muted` as a translucent wash of the `warning` token (10% light,
16% dark) and pair it with `warning`-toned labels; button hover/active
deepen the plate with the plate helpers, and `sync_legacy` maps
`warning_foreground` → `warning`. A contrast test measures the label
against the wash flattened onto the content plane.
- **Inputs lost their grey.** Light `input_bg` was pure white; it is now
`neutral(0.950)`, one rung below the chrome grey like the old scale's
step-3 input plate. Dark stays bezel's white-at-3%.
- **Dock planes move to `bg`.** The dock tab bar, title strip and panel
container read `bg` (white light / `#060606` dark — bezel's main panel),
matching the old near-white `panel_background`. Sidebar keeps `surface`
(the chrome grey).
- **Active tab is a wash, not white.** The dock tab's selected plane is
`element_active` — one rung past the `element_hover` hover (darker in
light, brighter in dark). The segmented tab's active segment stays a
white raised plate with a shadow. `sync_legacy.tab_active_background`
follows.
- **Sidebar text contrast.** Light `text_muted` moves from AppKit's
secondary label (~4:1, ~3.7:1 on the grey sidebar) to `neutral(0.45)`
(~5.3:1 on white), which also narrows the dark/light muted gap. Faint
stays AppKit-faint by design (placeholders).
- `Brand::branded` now skips `apply` for the default brand so the test's
no-op assertion holds now that a shipped token (`text_muted`) diverges
from the AppKit ink `apply` would re-assert.
- **Danger plates carry white ink in both appearances** (bezel's
destructive pairing — their `buttons.rs` hardcodes `gpui::white()` over
`danger_strong`): Danger button, error notification plate, title-bar
close hover, and `sync_base.destructive_foreground`. Visually a dark-mode
change only; light `on_accent` was already near-white.
Validation remaining: run desktop, walk every component in light/dark
against the Phase 0 screenshots.
@@ -371,6 +406,39 @@ against the Phase 0 screenshots.
Mechanical per the mapping table; ~370 sites across 8 crates. Use the
deprecated accessors as the worklist — the goal is zero deprecated hits.
Semantic states, per bezel's own widgets (`crates/ui/src/widgets/{status,
content,buttons}.rs`) — the recipes consumer banners, pills and state marks
should follow:
- **Strips (error/warning).** Bezel ships exactly two — "two tones, not a
level enum"; there is no info strip. Recipe: background = the semantic
token at 6% opacity, hairline ring = the same token at 20%, label and
leading triangle icon = the family's ink step at 90%, all at
`surface_radius()`. In coop tokens: error → bg `danger` at 6%, ring
`danger` at 20%, ink `danger_muted` (we kept bezel's ink step for danger);
warning → bg `warning_muted` (our wash token), ring `warning` at 20%, ink
`warning`.
- **Success pill.** Bezel's `badge_active`: background = `success` at 12%,
ink = `success_muted` at 90%, `rounded_full`, no border.
- **State dots.** No enum — the caller passes the tone
(`success`/`busy`/`warning`/`danger`, `text_faint` for "nothing yet") to a
6px bead.
- **Destructive controls.** Bezel's plate is `danger_strong` with **white
ink in both appearances** (`gpui::white()` in their `buttons.rs`), hover
dims the whole control to 90% opacity, and role is independent of emphasis
(a quiet destructive control is a ghost with `danger_strong`-toned text).
coop now carries the white-ink rule in button, notification error plate,
title-bar close hover, and `sync_base.destructive_foreground`.
- **Info.** No semantic tone — neutral copy on `text_muted`, or the quiet
hairline badge.
- Known divergence (kept deliberately): bezel keeps `warning_muted` as the
family's ink token and bakes wash alphas at call sites; coop bakes the
warning wash into the `warning_muted` token (10% light / 16% dark) because
the legacy `warning_background` alias and the button plate need a token,
and pairs it with `warning`-toned ink. The danger family keeps bezel's
exact semantics (`danger` wash source, `danger_muted` ink, `danger_strong`
plate).
- [ ] `crates/chat_ui` (largest: ~200 sites) — chips and rows on
`elevated_surface_background` review to `surface_raised` vs
`surface_card`; reactions/toggles to `element_*`; report banners to