Files
cameleer-server/docs/superpowers/specs/2026-04-09-ui-consistency-fix-design.md
hsiegeln f24a5e5ff0
All checks were successful
CI / cleanup-branch (push) Has been skipped
CI / build (push) Successful in 1m20s
CI / docker (push) Successful in 27s
CI / deploy-feature (push) Has been skipped
CI / deploy (push) Successful in 40s
docs: update CLAUDE.md, audit, and spec for today's changes
- CLAUDE.md: security (last-admin guard, password policy, brute-force,
  token revocation), environment filtering (queries + commands), Docker
  reconciliation, UI shared patterns, V8/V9 migrations
- UI-CONSISTENCY-AUDIT.md: marked RESOLVED
- UI consistency design spec: marked COMPLETED

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 16:54:54 +02:00

6.4 KiB

Status: COMPLETED — All 5 phases executed on 2026-04-09.

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:

// 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