feat(ui): tokenize soft-success + soft-warning callouts (LC-224) #267

Merged
nrupard merged 2 commits from feat/lc-224-success-warning-tokenize into main 2026-05-29 20:35:00 +02:00
Owner

Summary

Sibling to LC-215 (danger) and LC-222 (accent) — same sweep for success and warning surface families. Flagged during LC-221 review: the bridge healthy + stale chips stayed bright pale-green / pale-amber in dark mode while LC-215 fixed the errored chip to dim red, creating a three-chip mismatch on /admin/bridges. Same hardcoded bg-green-* / bg-amber-* shape repeats across ~22 sites.

Palette additions

Six new tokens per theme (3 per family). *-surface-content follows the LC-222 contrast lesson: dark themes flip to --content (slate-200) so text reads on the dim surface; saturated success/warning text on green-950 / amber-950 would fail WCAG AA. Light + hc themes use the saturated dark-green / amber for affordance.

Token Light Dark hc-light hc-dark
--success-surface #f0fdf4 (green-50) #052e16 (green-950) #dcfce7 (green-100) #0a0a0a
--success-border #86efac (green-300) #14532d (green-900) #15803d (green-700) #bbf7d0 (green-200)
--success-surface-content #047857 (emerald-700) var(--content) var(--success) var(--success)
--warning-surface #fffbeb (amber-50) #451a03 (amber-950) #fef3c7 (amber-100) #0a0a0a
--warning-border #fcd34d (amber-300) #78350f (amber-900) #b45309 (amber-700) #fde68a (amber-200)
--warning-surface-content var(--warning) var(--content) var(--warning) var(--warning)

Tailwind utilities exposed: bg-{success,warning}-surface, border-{success,warning}-border, text-{success,warning}-surface-content.

Sweep (22 sites across 21 files)

  • 10 saved/created banners (admin, settings, enclave)
  • 7 created-token blocks (api-tokens + 6 admin/room secret-pair blocks)
  • 5 missing-secret warning callouts
  • 3 stronger warning callouts (backup_restore, admin/settings, retention_preview)
  • Pinned strip
  • 3 chips (bridge healthy + stale, public-enclave badge)
  • 3 standalone text-emerald-700 (bookmark icon, 2 flash messages)
  • Webhook actor badge + mention-popover broadcast # avatar
  • Email verified/unverified pills

Test plan

  • just build-css emits all 6 new utility rules.
  • cargo check -p lets-chat-server clean.
  • Grep AC clean: no bg-(green|emerald)-(50|100|200) / bg-amber-(50|100|200) / border-(green|amber)-(100|200|300|400) / text-(green|emerald)-(700|800) / text-amber-(700|800) remains in server/templates/.
  • Visual smoke on staging under all 4 themes: bridges page (3 chips now theme together), saved banners flash and stay readable, pinned strip themes, "this device" / "verified" pills theme.
  • Operator-brand smoke: a non-green/amber brand color doesn't affect success/warning (they track --success/--warning, not --accent).

Out of scope

  • bg-red-* (LC-215).
  • Solid-fill bg-success / bg-warning buttons — none exist today.
  • Saturated text-success / text-warning standalone uses (short text on neutral ground) stay as-is.
## Summary Sibling to LC-215 (danger) and LC-222 (accent) — same sweep for success and warning surface families. Flagged during LC-221 review: the bridge healthy + stale chips stayed bright pale-green / pale-amber in dark mode while LC-215 fixed the errored chip to dim red, creating a three-chip mismatch on `/admin/bridges`. Same hardcoded `bg-green-*` / `bg-amber-*` shape repeats across ~22 sites. ## Palette additions Six new tokens per theme (3 per family). `*-surface-content` follows the LC-222 contrast lesson: dark themes flip to `--content` (slate-200) so text reads on the dim surface; saturated success/warning text on green-950 / amber-950 would fail WCAG AA. Light + hc themes use the saturated dark-green / amber for affordance. | Token | Light | Dark | hc-light | hc-dark | |--------------------|----------------------|-----------------------|----------------------|----------------------| | `--success-surface` | `#f0fdf4` (green-50) | `#052e16` (green-950) | `#dcfce7` (green-100) | `#0a0a0a` | | `--success-border` | `#86efac` (green-300)| `#14532d` (green-900) | `#15803d` (green-700)| `#bbf7d0` (green-200)| | `--success-surface-content` | `#047857` (emerald-700)| `var(--content)` | `var(--success)` | `var(--success)` | | `--warning-surface` | `#fffbeb` (amber-50) | `#451a03` (amber-950) | `#fef3c7` (amber-100)| `#0a0a0a` | | `--warning-border` | `#fcd34d` (amber-300)| `#78350f` (amber-900) | `#b45309` (amber-700)| `#fde68a` (amber-200)| | `--warning-surface-content` | `var(--warning)` | `var(--content)` | `var(--warning)` | `var(--warning)` | Tailwind utilities exposed: `bg-{success,warning}-surface`, `border-{success,warning}-border`, `text-{success,warning}-surface-content`. ## Sweep (22 sites across 21 files) - 10 saved/created banners (admin, settings, enclave) - 7 created-token blocks (api-tokens + 6 admin/room secret-pair blocks) - 5 missing-secret warning callouts - 3 stronger warning callouts (backup_restore, admin/settings, retention_preview) - Pinned strip - 3 chips (bridge healthy + stale, public-enclave badge) - 3 standalone text-emerald-700 (bookmark icon, 2 flash messages) - Webhook actor badge + mention-popover broadcast `#` avatar - Email verified/unverified pills ## Test plan - [x] `just build-css` emits all 6 new utility rules. - [x] `cargo check -p lets-chat-server` clean. - [x] Grep AC clean: no `bg-(green|emerald)-(50|100|200)` / `bg-amber-(50|100|200)` / `border-(green|amber)-(100|200|300|400)` / `text-(green|emerald)-(700|800)` / `text-amber-(700|800)` remains in `server/templates/`. - [ ] Visual smoke on staging under all 4 themes: bridges page (3 chips now theme together), saved banners flash and stay readable, pinned strip themes, "this device" / "verified" pills theme. - [ ] Operator-brand smoke: a non-green/amber brand color doesn't affect success/warning (they track --success/--warning, not --accent). ## Out of scope - `bg-red-*` (LC-215). - Solid-fill `bg-success` / `bg-warning` buttons — none exist today. - Saturated `text-success` / `text-warning` standalone uses (short text on neutral ground) stay as-is.
feat(ui): tokenize soft-success + soft-warning callouts (LC-224)
All checks were successful
check-secrets / Kingfisher (push) Successful in 4s
check-secrets / Nosey parker (push) Successful in 4s
check-secrets / TruffleHog (push) Successful in 4s
check-secrets / Kingfisher (pull_request) Successful in 4s
check-secrets / Nosey parker (pull_request) Successful in 4s
check-secrets / TruffleHog (pull_request) Successful in 4s
Check / clippy + fmt + tests (pull_request) Successful in 2m9s
cdbf759c53
Sibling to LC-215 (danger) and LC-222 (accent) — same sweep for the success and warning surface families. Reported during LC-221 review: the bridge healthy + stale chips stayed bright pale-green / pale-amber in dark mode while LC-215 fixed the errored chip to dim red, creating a three-chip mismatch on `/admin/bridges`. The same hardcoded `bg-green-*` / `bg-amber-*` shape repeats across ~22 sites — saved banners, missing-secret callouts, pinned strip, retention preview, public-enclave chip, mention-popover broadcast avatar, bookmark icons, flash messages, the message-actor webhook badge, and the email-verified / unverified status pills.

Six new palette tokens (3 per family), per theme, in `server/assets/main.css`:

| Token              | Light                | Dark                  | hc-light             | hc-dark              |
|--------------------|----------------------|-----------------------|----------------------|----------------------|
| `--success-surface`         | `#f0fdf4` (green-50) | `#052e16` (green-950) | `#dcfce7` (green-100) | `#0a0a0a`            |
| `--success-border`          | `#86efac` (green-300)| `#14532d` (green-900) | `#15803d` (green-700)| `#bbf7d0` (green-200)|
| `--success-surface-content` | `#047857` (emerald-700)| `var(--content)`    | `var(--success)`     | `var(--success)`     |
| `--warning-surface`         | `#fffbeb` (amber-50) | `#451a03` (amber-950) | `#fef3c7` (amber-100)| `#0a0a0a`            |
| `--warning-border`          | `#fcd34d` (amber-300)| `#78350f` (amber-900) | `#b45309` (amber-700)| `#fde68a` (amber-200)|
| `--warning-surface-content` | `var(--warning)`     | `var(--content)`      | `var(--warning)`     | `var(--warning)`     |

Foreground tokens follow the LC-222 contrast lesson: dark themes flip the `*-surface-content` to `--content` (slate-200) so text reads on the dim surface (saturated success/warning text would fail WCAG AA on green-950 / amber-950, same shape as the LC-222 dark-mode `text-accent on bg-accent-surface` failure). Light themes use the saturated dark-green / amber text for affordance.

Tailwind utilities exposed via `server/tailwind.config.js`: `bg-success-surface`, `border-success-border`, `text-success-surface-content`, and the warning equivalents.

Template sweep (22 sites across 21 files):

**Saved / created success banners (10 sites):** `admin/anti_spam.html`, `admin/branding.html`, `admin/settings.html:51,128,131`, `enclave/branding.html`, `settings/page.html:12,263,288`. `bg-green-50 text-success text-sm` (and `bg-green-100 text-green-800` variants) -> `bg-success-surface border border-success-border text-success-surface-content text-sm`.

**Created-token blocks (7 sites):** `admin/bots`, `admin/outgoing_webhooks`, `admin/bridges`, `settings/api_tokens`, `room/webhooks`, `room/feeds`, `room/email_inboxes`. Outer `bg-green-50 border border-green-200` + inner monospace token `border-green-200` -> tokens (outer gets surface-content text, inner code keeps `bg-surface-elevated` with tokenized border).

**Missing-secret warning callouts (5 sites):** `admin/bots`, `admin/bridges`, `room/webhooks`, `room/email_inboxes`, `room/feeds`. `bg-amber-50 text-warning text-sm` -> tokens.

**Stronger warning callouts (3 sites):** `admin/backup_restore`, `admin/settings`, `room/retention_preview`. `border border-amber-300 bg-amber-50` variants -> `bg-warning-surface border border-warning-border text-warning-surface-content`.

**Pinned strip (1 site):** `partials/pinned_strip.html` `border-b border-border bg-amber-50` -> `border-b border-warning-border bg-warning-surface`.

**Chips (3 sites):** `admin/bridges.html` healthy + stale bridge chips, `admin/enclaves.html` + `enclave/page.html` public-enclave badge. `bg-green-100 text-emerald-700` / `bg-amber-100 text-warning` / `bg-emerald-100 text-emerald-700` -> `bg-{success,warning}-surface text-{success,warning}-surface-content`. No border on chips per the LC-215 chip-vs-panel carve-out.

**Standalone text-emerald-700 (3 sites):** bookmark icon in `room/message.html`, flash messages in `enclave/group_member_row_result.html` + `invite_row_result.html`. `text-emerald-700` -> `text-success-surface-content` (works as standalone text on neutral surface because the token value is dark green in light themes; reads on dark surface in dark themes via the slate-200 flip).

**Webhook actor badge in message.html:26 + mention-popover broadcast avatar:** `bg-emerald-100 text-emerald-700` -> `bg-success-surface text-success-surface-content`. The LC-198 wrap-up note flagged actor badges as deferred but this commit folds them in since the swap is mechanically the same.

**Email verified / unverified pills (`settings/page.html:91,93`):** `bg-green-100 text-green-800` -> `bg-success-surface border border-success-border text-success-surface-content`; `bg-amber-100 text-amber-800` -> `bg-warning-surface border border-warning-border text-warning-surface-content`.

Out of scope:
- `bg-red-*` already swept by LC-215.
- Solid-fill `bg-success` / `bg-warning` buttons (none exist today; would use existing `*-content` tokens for foreground).
- `text-success` / `text-warning` standalone uses (verified email checkmark text, pinned strip pin icon, etc.) stay as the saturated text color; they sit on the page or warning-surface ground and are short enough to absorb the contrast trade-off.

Verified: `just build-css` emits all 6 new utility rules (`.bg-success-surface`, `.bg-warning-surface`, `.border-success-border`, `.border-warning-border`, `.text-success-surface-content`, `.text-warning-surface-content`). `cargo check -p lets-chat-server` clean. Grep AC clean: `grep --recursive --extended-regexp 'bg-(green|emerald)-(50|100|200)|bg-amber-(50|100|200)|border-(green|amber)-(100|200|300|400)|text-(green|emerald)-(700|800)|text-amber-(700|800)' server/templates/` returns no results.

#LC-224
fix(ui): code-review fixes for LC-224 success/warning sweep
All checks were successful
Check / clippy + fmt + tests (pull_request) Successful in 2m0s
check-secrets / TruffleHog (push) Successful in 3s
check-secrets / Nosey parker (pull_request) Successful in 3s
check-secrets / Kingfisher (pull_request) Successful in 4s
check-secrets / Nosey parker (push) Successful in 5s
check-secrets / Kingfisher (push) Successful in 5s
check-secrets / TruffleHog (pull_request) Successful in 6s
Create release / Create release from merged PR (pull_request) Has been skipped
9a9f85f37f
Three findings addressed in one follow-up commit so PR #267 ships clean.

1. Dark `--success-surface` (`#052e16`) collided with dark `--success-content` (also `#052e16`); same shape for `--warning-surface` (`#451a03`) vs `--warning-content` (`#451a03`). Same latent footgun LC-215 fixed for danger: anyone composing `bg-success-surface text-success-content` renders invisible text in dark mode. Nudged the surfaces 2 shades darker (`#031b0d` for success, `#2d1003` for warning) so the two cannot compose silently invisible.

2. Light `--warning-surface-content` was `var(--warning)` (amber-600 `#d97706`) which on amber-50 surface gives only ~3.0:1 contrast — fails WCAG AA for normal text. Asymmetric with success which had already hardcoded emerald-700 (`#047857`) for exactly this reason. Switched warning to hardcoded amber-700 (`#b45309`) — ~5.0:1 contrast, AA pass — for symmetric posture and tightened up the catalog comment to explain BOTH content tokens are explicit darker shades rather than `var(--success)` / `var(--warning)`.

3. Webhook actor badge in `room/message.html:26` reverted from `bg-success-surface text-success-surface-content` back to `bg-emerald-100 text-emerald-700`. LC-198 wrap-up listed all three actor badges (webhook emerald, email sky, bridge violet) as deferred TOGETHER; my LC-224 sweep tokenized only the webhook one, breaking the three-badge symmetry on every message row that mixes actor kinds. Reverting restores the symmetry until the actor-badges follow-up ticket lands.

Verified: `just build-css` clean, `cargo check -p lets-chat-server` clean.

#LC-224
nrupard deleted branch feat/lc-224-success-warning-tokenize 2026-05-29 20:35:00 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
psa-systems/lets-chat!267
No description provided.