docs: UI consistency audit and fix design spec

Full audit of design system adoption, color consistency, inline styles,
layout patterns, and CSS module duplication across the server UI.
Includes 6-phase fix plan.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-04-09 14:45:32 +02:00
parent 827ba3c798
commit bfed8174ca
2 changed files with 396 additions and 0 deletions

View File

@@ -0,0 +1,139 @@
# UI Consistency Fix — Design Spec
**Date:** 2026-04-09
**Goal:** Bring the cameleer3-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.
## Phase 1: Extract Shared CSS Modules
### 1a. Table Section Pattern
Create `ui/src/styles/table-section.module.css` containing:
- `.tableSection`, `.tableHeader`, `.tableTitle`, `.tableMeta`, `.tableRight`
Update these 5 files to import from shared module instead of local definitions:
- `pages/DashboardTab/DashboardTab.module.css`
- `pages/Admin/AuditLogPage.module.css`
- `pages/Admin/ClickHouseAdminPage.module.css`
- `pages/Routes/RoutesMetrics.module.css`
- `pages/Routes/RouteDetail.module.css`
### 1b. Log Panel Pattern
Create `ui/src/styles/log-panel.module.css` containing:
- `.logCard`, `.logHeader`, `.logToolbar`, `.logSearchWrap`, `.logSearchInput`, `.logSearchClear`, `.logClearFilters`, `.logEmpty`, `.sortBtn`, `.refreshBtn`, `.headerActions`
Update `AgentHealth.module.css` and `AgentInstance.module.css` to import shared.
### 1c. Rate Color Classes
Create `ui/src/styles/rate-colors.module.css`:
- `.rateGood`, `.rateWarn`, `.rateBad`, `.rateNeutral`
Update DashboardTab, RouteDetail, RoutesMetrics.
### 1d. Tap Modal Dedup
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.
Files to fix (priority order):
1. `ExecutionDiagram/ExecutionDiagram.module.css` (~57 violations)
2. `ProcessDiagram/ProcessDiagram.module.css` (~20 violations)
3. `Dashboard/Dashboard.module.css` (4 violations including naked `#5db866`)
4. `DashboardTab/DashboardTab.module.css` (rgba shadow)
5. `RoutesMetrics/RoutesMetrics.module.css` (rgba shadow)
6. `AppsTab/AppsTab.module.css` (`--accent` + rgba)
7. `AgentHealth/AgentHealth.module.css` (`#fff`)
8. `LoginPage.module.css`, `ContentTabs.module.css`, `EnvironmentSelector.module.css` (undefined vars)
## Phase 3: Fix Hardcoded Colors in TSX
Create `ui/src/utils/theme-colors.ts`:
```ts
// Reads CSS custom properties from the document root at call time.
// Use for SVG attributes where var() isn't supported in JS string contexts.
export function cssVar(name: string): string {
return getComputedStyle(document.documentElement).getPropertyValue(name).trim();
}
```
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).
Also fix TSX color references in:
- `pages/Dashboard/Dashboard.tsx` (hardcoded `#3D7C47`)
- `components/LayoutShell.tsx` (inline `color: 'var(--error)'` -> CSS class)
Leave data-visualization computed `hsl()` values (Treemap, PunchcardHeatmap, DiagramNode heatmap) — these are intentional gradients.
## Phase 4: Eliminate Inline Styles
### 4a. Create Missing CSS Modules
- `pages/Admin/AdminLayout.module.css` — extract the single inline layout style
- `pages/Admin/DatabaseAdminPage.module.css` — extract all inline layout/typography
- `auth/OidcCallback.module.css` — extract full-page layout
### 4b. Extract Shared Components
- Create `components/PageLoader.tsx` — replaces the 3 copy-pasted `<Spinner>` + flex + padding patterns in router.tsx, RuntimePage, DashboardPage
### 4c. Move Static Inline Styles to CSS Modules
Priority files (most violations):
- `AppsTab.tsx` — fixed-width inputs -> size classes, visually-hidden pattern, table cell layouts
- `LayoutShell.tsx` — StarredList styles
- `EnvironmentsPage.tsx` — save/cancel button rows, raw `<select>` styling
- `RouteDetail.tsx` — heading styles, tab panel margins
## Phase 5: Replace Native HTML with DS Components (time-permitting)
1. `EnvironmentSelector.tsx` — bare `<select>` -> DS `Select`
2. `ExecutionDiagram/tabs/LogTab.tsx` — raw table -> DS `LogViewer`
3. `AppsTab.tsx` sub-tab bars -> DS `SegmentedTabs` or `Tabs`
4. `AppConfigDetailPage.tsx``<select>` -> DS `Select`, `<input checkbox>` -> DS `Toggle`, `<label>` -> DS `FormField`
5. `AgentHealth.tsx` — config bar `<select>` -> DS `Select`, action `<button>` -> DS `Button`
## Out of Scope
- Responsive design (zero `@media` queries) — separate initiative
- Data visualization color scales (Treemap, PunchcardHeatmap) — intentional computed gradients
- ProcessDiagram SVG structural class names (`className="nodes"`) — semantic, acceptable
- Adding new DS tokens to the design-system package — use `color-mix()` locally if needed
## Success Criteria
- Zero naked hex values in CSS modules
- Zero `var(--token, #fallback)` patterns (strip fallbacks)
- Zero undefined CSS variable names
- CSS class duplication reduced from ~22% to <5%
- All pages with >3 inline styles get a CSS module
- Shared `PageLoader` component replaces copy-pasted spinner pattern