| name | ui-fix-observe-first |
| description | Use when fixing, auditing, improving, or building ANY web UI — before reading or editing component code. Fires on contrast/a11y/overflow/responsive/hover-focus/layout complaints, "polish the UI", "audit the page/site", "make it premium", or any visual change (including a local authed dashboard). |
UI fix — observe first
The two rules (non-negotiable)
- Never diagnose or claim a UI change from code — render, measure, cite. Runtime defects (contrast, overflow, wrap, responsive, hover/focus, layout shift, stacking) do NOT exist in the JSX. No measurement = not a finding. "It compiles" / "the JSX looks right" is not an observation.
- Correctness is yours to fix; taste is decided by evidence + council, not by asking the operator. Aesthetic direction goes through current competitive research + the thinktank; you bring the operator the result, not the question.
FLOW A — fix / improve an existing UI
- Prompt fires the ui-observe-first hook → render before you read code.
- RENDER the live page at 375 + 1440. Public page → chrome-devtools MCP. Authed dashboard (a local, session-gated app) → claude-in-chrome with a live session.
- OBSERVE quantitatively — layered, not one tool (automation catches only part of the problem surface; Lighthouse is a floor, not conformance):
- axe-core (the engine — Deque, "zero false positives", what Lighthouse wraps a subset of). On a live claude-in-chrome page, inject + run it:
javascript_tool → load https://cdnjs.cloudflare.com/ajax/libs/axe-core/4.x/axe.min.js then await axe.run(). Catches contrast, missing labels, ARIA validity, duplicate IDs. Public page: use chrome-devtools Lighthouse + performance_start_trace (LCP/INP/CLS).
- computed-style WCAG contrast (fallback / precise pin):
javascript_tool computes the ratio of an element's color vs its effective bg (AA normal ≥4.5, large/UI ≥3.0). Use when axe can't be injected.
- a11y tree (
read_page) + console errors (read_console) + a full-page screenshot.
- Keyboard pass (highest-leverage manual step, ~30% of automated-missed issues): Tab from the top — focus visible at all times? logical order? no traps? sticky nav doesn't steal focus (WCAG 2.2 focus-not-obscured)?
- Reflow: check 320px width / 200% zoom for overflow. 24px tap targets (WCAG 2.2).
- PIN the exact defect — cite the measurement (ratio, px, element, axe rule id). No evidence = not a finding.
- Split findings:
- 4a CORRECTNESS (contrast <4.5 AA, a11y, CLS, overflow, wrong-hex, light-mode, focus/keyboard) → fix directly, one class at a time, on the design-token
var(--*) (e.g. src/index.css @theme tokens, never raw hex).
- 4b AESTHETIC DIRECTION (premium feel / how bold) → do NOT ask the operator. Use available web-research tools to study current authoritative competitive patterns (what Vercel / Linear / Stripe + A/B data actually do) → convene the thinktank / Workflow-council to decide the forks → ship the quick-wins, let the council settle taste; bring the operator the result.
- GATE: check-types + FULL test suite, never a scoped run (e.g.
tsc -b + vitest run + eslint). Add the static a11y layer where possible (eslint-plugin-jsx-a11y — 0 runtime cost).
- SHIP: commit (subject <100 chars, lowercase) → PR → CI green. (a LOCAL-only dashboard has no hosted-preview step; "ship" = PR→CI-green.)
- RE-RENDER to verify — the fix landed AND nothing regressed, at dark + light + mobile. A dashboard that serves a prebuilt static bundle needs a rebuild first (e.g.
npm run build → restart the local server), then re-measure on the running instance. Track 3 numbers per page: axe violations, contrast ratios, keyboard pass.
- SCORE: run the UI-quality rating pass → 9+.
FLOW B — develop a new UI
Same spine, generate-step in front: 0. Declare the design tokens first → 1. Generate (claude.ai/design default; Figma if a designer must touch it) → 2. Assets (Figma MCP / claude.ai-design — no aura.build in this env) → 3. Build in src/ on the tokens → then Flow A steps 2–8.
Receipts (this process, proven 2026-07-03)
- Found the tertiary-text token failing WCAG AA (3.85:1 measured on cards) → lifted to
#868d99 (5.56:1), re-measured green → shipped as a token fix. A GLOBAL token fix that lifted every page at once.
- The AuthGate "low-contrast button" was a screenshot-eyeball FALSE POSITIVE — measurement showed 14.47:1 (AAA). This is exactly why rule 1 exists: measure, don't eyeball.
Cross-references
- A peer-review council — for the 4b aesthetic-direction decision.
- Available web-research tools — for the 4b current competitive-pattern research (Vercel/Linear/Stripe).