**Goal:** Bring the cameleer-server UI to consistent design system usage — eliminate CSS duplication, hardcoded colors, inline styles, and native HTML where DS components exist.
**Source:** `UI-CONSISTENCY-AUDIT.md` (same repo, same date)
---
## Approach: Fix by Category
Extract shared patterns first (unblocks everything), then sweep all files per issue type. Phases are independent after Phase 1 and can run in parallel.
Remove duplicate tap modal CSS from `RouteDetail.module.css` — it already uses the `TapConfigModal` component which has its own CSS module.
### 1e. Refresh Indicator Dedup
Move `.refreshIndicator`, `.refreshDot`, `.refreshText`, `@keyframes pulse` to shared module. Update DashboardTab and RoutesMetrics.
### 1f. Other Small Dedup
-`.chartCard` — shared between AgentInstance and RouteDetail
-`.section` — shared between AppConfigDetailPage and OidcConfigPage
-`.metaGrid/.metaLabel/.metaValue` — shared between AboutMeDialog and UserManagement
## Phase 2: Fix Hardcoded Colors in CSS
For each CSS module file:
- Replace naked hex values with design system variables
- Strip hex fallbacks from `var(--token, #hex)` -> `var(--token)`
- Fix undefined variable names:
-`--accent` -> `--amber`
-`--bg-base` -> `--bg-body`
-`--surface` -> `--bg-surface`
-`--bg-surface-raised` -> `--bg-raised`
- For tint colors without DS tokens (e.g., `#FDF2F0` error background), check if DS provides equivalents. If not, define them as local CSS custom properties at the component level using `color-mix()` from DS base colors.
Then replace all hex literals in ProcessDiagram components:
-`DiagramNode.tsx` (~20 values)
-`CompoundNode.tsx` (~8 values)
-`DiagramEdge.tsx` (~3 values)
-`ConfigBadge.tsx` (~3 values)
-`ErrorSection.tsx` (~2 values)
-`NodeToolbar.tsx` (~2 values)
-`Minimap.tsx` (~3 values)
-`ProcessDiagram.tsx` (~2 values)
Note: SVG `fill` and `stroke` attributes DO support `var()` in modern browsers. Where the color is a static attribute (not computed in JS), use `fill="var(--success)"` directly. Only use `cssVar()` where the value must be a JS string (e.g., in computed color logic).