feat(ui): tokenize presence dots + status/bot badges (LC-198) #249

Merged
nrupard merged 2 commits from feat/lc-198-icons-avatars into main 2026-05-28 16:21:48 +02:00
Owner

LC-198 polish, slice 1: presence / status / bot color tokens. The icon-system consolidation (shared <svg> partial / sprite) and the deterministic-initials-bg-from-user-id are out of scope here and stay open under LC-198.

What's tokenized

Surface Before After
partials/avatar.html presence dot bg-green-500 / yellow-400 / red-500 / slate-400, ring-white bg-success / warning / danger / content-subtle, ring-surface-elevated
status/picker.html radio swatches same hardcoded palette same token set
settings/page.html profile presence dot (h-4 w-4) same hardcoded palette + ring-white same token set + ring-surface-elevated
ws/user_status_update.html live-update JS classList toggles on the hardcoded names classList toggles on the token names (server + WS stay byte-identical now)
partials/enclave_switcher.html unread/invites chip bg-red-500 text-white bg-danger text-danger-content
room/message.html bot author badge bg-indigo-100 text-indigo-700 bg-surface-sunken text-content-muted (the badge is a role label, not a state indicator - neutral chip is the right shape)

Why this works in every theme

The LC-190 palette already has --success / --warning / --danger / --content-subtle / --surface-elevated defined for :root (light), [data-theme="dark"], [data-theme="hc-light"], and [data-theme="hc-dark"]. So all six surfaces above recolor at theme switch with no template change. Light and hc-light keep the same general "red dot = dnd" reading; dark uses the lighter palette so the dot stays legible on the dark surface; high-contrast goes to the AA shades.

Not in this PR (still open under LC-198)

  • Icon-system consolidation: ~12 distinct inline SVGs across composer.html, dm_header.html, layout.html, enclave_switcher.html, etc. Each carries its own viewBox + class list. Plan is to add partials/icon.html (or an Askama-side sprite include) and adopt incrementally.
  • Deterministic initials background per user id. The current fallback is a single neutral chip; per-user color makes 8+ member lists scan much faster but needs a hash-to-bucket helper in Rust + 6-8 token-mapped utility classes in main.css.
  • Call-UI palette (layout.html line 60-94) keeps its intentional slate/indigo dark dressing for the video-overlay UX; tokenizing would change the look and belongs in a separate call-polish ticket.

Tests

just test + just test-saas green. No fixture regen needed - LC-77 webhook + email-inbox render fixtures don't include presence dots or the bot badge.

🤖 Generated with Claude Code

LC-198 polish, slice 1: presence / status / bot color tokens. The icon-system consolidation (shared `<svg>` partial / sprite) and the deterministic-initials-bg-from-user-id are out of scope here and stay open under LC-198. ### What's tokenized | Surface | Before | After | |---|---|---| | `partials/avatar.html` presence dot | `bg-green-500 / yellow-400 / red-500 / slate-400`, `ring-white` | `bg-success / warning / danger / content-subtle`, `ring-surface-elevated` | | `status/picker.html` radio swatches | same hardcoded palette | same token set | | `settings/page.html` profile presence dot (h-4 w-4) | same hardcoded palette + `ring-white` | same token set + `ring-surface-elevated` | | `ws/user_status_update.html` live-update JS | classList toggles on the hardcoded names | classList toggles on the token names (server + WS stay byte-identical now) | | `partials/enclave_switcher.html` unread/invites chip | `bg-red-500 text-white` | `bg-danger text-danger-content` | | `room/message.html` bot author badge | `bg-indigo-100 text-indigo-700` | `bg-surface-sunken text-content-muted` (the badge is a role label, not a state indicator - neutral chip is the right shape) | ### Why this works in every theme The LC-190 palette already has `--success / --warning / --danger / --content-subtle / --surface-elevated` defined for `:root` (light), `[data-theme="dark"]`, `[data-theme="hc-light"]`, and `[data-theme="hc-dark"]`. So all six surfaces above recolor at theme switch with no template change. Light and hc-light keep the same general "red dot = dnd" reading; dark uses the lighter palette so the dot stays legible on the dark surface; high-contrast goes to the AA shades. ### Not in this PR (still open under LC-198) - Icon-system consolidation: ~12 distinct inline SVGs across `composer.html`, `dm_header.html`, `layout.html`, `enclave_switcher.html`, etc. Each carries its own viewBox + class list. Plan is to add `partials/icon.html` (or an Askama-side sprite include) and adopt incrementally. - Deterministic initials background per user id. The current fallback is a single neutral chip; per-user color makes 8+ member lists scan much faster but needs a hash-to-bucket helper in Rust + 6-8 token-mapped utility classes in main.css. - Call-UI palette (`layout.html` line 60-94) keeps its intentional slate/indigo dark dressing for the video-overlay UX; tokenizing would change the look and belongs in a separate call-polish ticket. ### Tests `just test` + `just test-saas` green. No fixture regen needed - LC-77 webhook + email-inbox render fixtures don't include presence dots or the bot badge. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
feat(ui): tokenize presence dots + status/bot badges (LC-198)
Some checks failed
check-secrets / TruffleHog (push) Successful in 3s
check-secrets / Nosey parker (push) Successful in 4s
check-secrets / Kingfisher (push) Successful in 4s
check-secrets / TruffleHog (pull_request) Successful in 5s
check-secrets / Nosey parker (pull_request) Successful in 6s
check-secrets / Kingfisher (pull_request) Successful in 7s
Check / clippy + fmt + tests (pull_request) Failing after 15s
53cfb3371a
LC-189 polish epic, LC-198 first slice. Avatar/presence/badge colors now read from the LC-190 semantic token palette so they recolor across every theme (light, dark, hc-light, hc-dark) instead of staying pinned to one slate/red/green/yellow shade. The broader icon-system consolidation and deterministic-initials-bg-from-id are out of scope for this commit and stay open under LC-198.

partials/avatar.html: presence dot reads `bg-success/warning/danger/content-subtle` (was bg-green-500/yellow-400/red-500/slate-400). Ring is `ring-surface-elevated` (was ring-white), so the dot reads cleanly on dark themes too.

status/picker.html: the three radio swatches (online/away/dnd) match the new tokens.

settings/page.html: the larger profile presence dot uses the same token set + ring.

ws/user_status_update.html: the JS class-swap mapping for live presence updates rewritten in lockstep. Server and live updates use the same four class names so a refresh and a WS update render identically.

partials/enclave_switcher.html: per-enclave unread/invites count chip uses `bg-danger text-danger-content` (was bg-red-500 text-white) so it theme-tracks the badge contrast (white-on-red in light, lighter-red palette in dark, white-on-red-700 in hc).

room/message.html: bot author badge is now a neutral muted chip (`bg-surface-sunken text-content-muted`) instead of the static indigo-100/700 pair - the badge is a role label, not a state indicator, so neutral fits better than a chroma.

just test + just test-saas green. No fixture regen needed (the LC-77 webhook/email-inbox fixtures don't include presence dots or the bot badge).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
fix(ui): bot badge stays visible on row hover (LC-198)
Some checks failed
check-secrets / TruffleHog (push) Successful in 3s
check-secrets / Nosey parker (pull_request) Successful in 4s
check-secrets / TruffleHog (pull_request) Successful in 4s
check-secrets / Kingfisher (push) Successful in 5s
check-secrets / Kingfisher (pull_request) Successful in 6s
check-secrets / Nosey parker (push) Successful in 6s
Check / clippy + fmt + tests (pull_request) Failing after 15s
Create release / Create release from merged PR (pull_request) Has been skipped
f1426af287
Self-review on PR #249 caught it: `bg-surface-sunken` for the bot badge matches the parent message row's `hover:bg-surface-sunken`, so on hover the badge merges with the row background and only the "BOT" text remains visible without a chip outline. Switched to an outlined chip (`border border-border bg-surface-elevated text-content-muted`) which keeps the badge visually grounded in both rest and hover state, across every theme.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
nrupard deleted branch feat/lc-198-icons-avatars 2026-05-28 16:21:49 +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!249
No description provided.