mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-27 12:56:01 -06:00
a4c01c1a77
* feat(ui): save appearance preferences per user profile When a Control UI connection is bound to an authenticated user profile (trusted-proxy, Tailscale, GitHub identity), theme, theme mode, and accent become per-profile: stored in the existing user_preferences KV store via users.prefs.set, overriding gateway-wide ui.prefs, with live cross-device updates over a new additive users.prefs.changed event scoped to the same merged profile. Restore default deletes only the profile key and falls back to the gateway-wide value. talk.config projects the caller's profile accent for native clients. Profile-less connections (token/password/none auth) keep the existing gateway-config behavior byte-identically. Release-note context: on multi-person gateways appearance choices are now personal and follow you across devices; an admin restyling their own UI no longer reskins the whole team. * chore(protocol): allowlist users.prefs.changed for mobile clients iOS and Android resolve the profile accent through talk.config on connect and config refresh; live per-profile appearance push on natives is a named follow-up. * chore(protocol): regenerate Swift/Kotlin models for users.prefs.changed * fix(ui): honor explicit defaults and identity switches for profile appearance Addresses the three ClawSweeper review findings: - resetValue for profile-bound appearance keys is the deletion fallback (gateway value), so an explicit product-default selection persists as a profile write instead of being misclassified as a reset. - An identity switch between two known scopes forces a full appearance reconcile and clears appearance keys the returning identity never set, so a shared browser cannot keep the previous profile's look (boot keeps the last-seen shortcut). - talk.config joins the profile-dependent dispatch gate so a pending GitHub identity sync completes before the profile accent is projected; token clients pass through untouched. * chore(ui): satisfy assertion-safety ratchet and docs formatting * refactor(ui): extract server-prefs storage primitives server-prefs.ts crossed the 700-line cap after the review fixes; the stateless localStorage persistence primitives move to server-prefs-storage.ts (no behavior change). Shrink-prunes the assertion-safety baseline for the moved casts. * fix(ui): keep imported custom themes out of profile storage Custom palettes are browser-local by contract, so a profile must never carry theme=custom to a browser that cannot render it. The wire contract drops custom from the storable theme values (readers self-heal any stored value), a profile-bound custom selection stays retained browser-local (including the offline-queued path), and the exhaustive theme test now encodes the exception.
OpenClaw Design System
OpenClaw's visual language is a dark-first, glass-surface system built around a deep charcoal base (#0e1015), a punchy signature red accent (#ff5c5c), and layered frosted-glass surfaces that create depth without solid panels. Motion is crisp and purposeful — fast micro-interactions (100ms) with spring-loaded expansions. All interactive elements meet WCAG 2.1 AA contrast requirements on dark backgrounds.
Contents
| File | What it covers |
|---|---|
| glass-surfaces.md | Two glass tiers, exact CSS values, no-solid-panels rule, @supports fallback |
| color-tokens.md | All design tokens with values, usage, contrast ratios, and anti-patterns |
| motion.md | Duration scale, easing functions, prefers-reduced-motion pattern, animation inventory |
| accessibility.md | WCAG checklist: contrast, focus, tap targets, ARIA, skip link, focus trap |
| settings-design.md | Settings page anatomy: sections, groups, rows, controls, status dots, migration rules |
Guiding Principles
- Glass, not solid — Surfaces use
backdrop-filterblur + semi-transparent backgrounds. No flat opaque panels in the main chrome. - Depth through layering — The background scale (
--bg,--bg-accent,--bg-elevated,--bg-hover,--bg-muted) communicates hierarchy without heavy borders. - Accent with restraint — Signature red (
--accent: #ff5c5c) for primary actions only; teal (--accent-2) for secondary/status. - Motion serves meaning — Animations telegraph state changes; they never play for decoration alone.
- Accessible by default — Every component ships with focus-visible styles, correct ARIA roles, and ≥4.5:1 contrast on text.