From craft-skills
Audits UI visual regressions post-development: starts dev server, screenshots changed routes (.tsx/.vue/.svelte), compares via Haiku vision AI against aesthetic-direction.md/ux-brief.md, flags issues before browser tests.
How this skill is triggered — by the user, by Claude, or both
Slash command
/craft-skills:design-reviewThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Automated visual regression and design-contract audit that runs between `develop` (implementation) and `browser-test` (functional testing).
Automated visual regression and design-contract audit that runs between develop (implementation) and browser-test (functional testing).
Why it exists: paper-grade UX briefs and clean impl-agent output can still produce subtle visual regressions — conditional chrome that desyncs heights, wrapped prices, misaligned grids — that only become visible when the UI renders. This skill catches those with a cheap vision-model pass before the functional test layer runs.
craft-skills:develop calls this after Step 3.5 (post-develop LLM review) and before Step 4 (verification)craft-skills:craft, implement, finalize call this as a phase between Develop and Browser TestSkip when:
.tsx/.vue/.svelte files in .shared-state.md changes).claude/aesthetic-direction.md does not exist (log: "No aesthetic direction found; skip design-review. Run craft-skills:aesthetic-direction to enable.")@playwright/mcp MCP server is not available (text-only fallback — see Step 4c)$ARGUMENTS:
.shared-state.md or git diff --name-only/compare or /compare,/clients → screenshot these specific routes# Verify aesthetic direction exists
if [ ! -f .claude/aesthetic-direction.md ]; then
echo "AESTHETIC_MISSING"
exit 0
fi
# Detect changed UI files
if [ -f .shared-state.md ]; then
CHANGED_UI=$(grep -E '\.(tsx|vue|svelte|jsx)' .shared-state.md | head -20)
else
CHANGED_UI=$(git diff --name-only HEAD | grep -E '\.(tsx|vue|svelte|jsx)$' | head -20)
fi
if [ -z "$CHANGED_UI" ]; then
echo "NO_UI_CHANGES"
exit 0
fi
echo "READY"
echo "$CHANGED_UI"
AESTHETIC_MISSING → skip and log messageNO_UI_CHANGES → skip silentlyREADY → continue# Skip if already running on expected port
PORT=${DEV_PORT:-3000}
if lsof -ti:$PORT -sTCP:LISTEN >/dev/null 2>&1; then
echo "DEV_SERVER_ALREADY_RUNNING on :$PORT"
else
# Start in background, wait for readiness
npm run dev > /tmp/craft-dev-$$.log 2>&1 &
DEV_PID=$!
for i in {1..30}; do
sleep 1
if curl -s http://localhost:$PORT > /dev/null 2>&1; then
echo "DEV_SERVER_STARTED pid=$DEV_PID port=$PORT"
break
fi
done
if [ $i -ge 30 ]; then
echo "DEV_SERVER_FAILED" && exit 1
fi
fi
Record whether the skill started the server (so Step 6 knows whether to stop it).
From the changed UI files, map to routes:
src/app/.../page.tsx → the route pathimporters_of (chain until page.tsx)ux-brief.md exists, use its "Touch" section to identify the features/routes affectedIf mapping is unclear, ask the user: "Which routes should I screenshot? (e.g. /compare, /clients)"
Load Playwright MCP tools via ToolSearch (browser_navigate, browser_take_screenshot, browser_resize).
For each route:
1. Resize browser to 1440x900 (desktop reference)
2. Navigate to http://localhost:${PORT}{route}
3. If login redirect: pause and ask user to log in (use existing session cookies afterwards)
4. Take full-page screenshot: .claude/plans/{feature-dir}/screenshots/{route-slug}-desktop.png
5. Resize to 375x812 (mobile reference)
6. Screenshot again: {route-slug}-mobile.png
7. If ux-brief identifies specific interaction states (hover, expanded, error),
reproduce each and screenshot as {route-slug}-{state}.png
If Playwright MCP is not available:
# Capture DOM snapshot + computed styles via dev server fetch
curl -s http://localhost:${PORT}{route} > /tmp/dom-snapshot.html
# Note: this is a weaker signal; Haiku can only review markup/class usage, not rendered output
echo "TEXT_FALLBACK: vision regression not possible; review DOM only"
The review in Step 5 reads the DOM snapshot and the AESTHETIC_DIRECTION to flag class/token violations, but cannot catch layout/alignment bugs.
Dispatch an agent using the Agent tool: general-purpose, haiku model. Prompt:
You are performing a design review. No code changes. Read-only.
Inputs you must read:
1. .claude/aesthetic-direction.md — the project's design contract
2. {ux-brief-path} if it exists (feature-specific success criteria)
3. The screenshots at .claude/plans/{feature-dir}/screenshots/
Compare the rendered UI (screenshots) against:
- The aesthetic direction (color, typography, spacing, density, signature elements)
- The ux-brief's "Success criteria" section (if brief exists)
- General regression heuristics: uniform height of sibling cards, no text wrapping where not intended, consistent alignment, no overlap or clipping, color-not-only encoding, visible focus states (where focus is visible in a screenshot)
Output a structured review file at .claude/plans/{feature-dir}/design-review.md:
# Design Review — {feature}
## Summary
- Status: PASS / MINOR_ISSUES / MAJOR_ISSUES
- Screenshots reviewed: {list}
## Aesthetic compliance
- {PASS/FAIL} Typography: {observation}
- {PASS/FAIL} Color palette: {observation}
- {PASS/FAIL} Density & spacing: {observation}
- {PASS/FAIL} Signature elements: {observation}
## Regression findings
### (list, if any)
- [SEVERITY: critical|major|minor] Description — evidence: {screenshot filename + region} — suggested fix: {1-2 sentences}
## UX-brief success criteria
For each criterion in the brief, mark PASS/FAIL with evidence from the screenshot.
## Recommended next action
- PASS → proceed to browser-test
- MINOR_ISSUES → fix via develop agent (small, specific patches listed above); re-run design-review
- MAJOR_ISSUES → escalate to Sonnet/Opus design-review; may require ux-brief revision
End with a JSON block:
{
"status": "PASS" | "MINOR_ISSUES" | "MAJOR_ISSUES",
"finding_count": N,
"critical": N,
"major": N,
"minor": N,
"next": "proceed" | "fix-and-rerun" | "escalate"
}
Haiku is fast and cheap. Use it as the first-pass filter. Average cost: 10-20K tokens per review.
If Haiku's JSON returns status: MAJOR_ISSUES or critical > 0:
Dispatch a second agent: general-purpose, sonnet or opus model. Same inputs plus Haiku's findings. Sonnet/opus produces the authoritative review and patch list.
If the issue is at the brief/aesthetic level (not just a code bug), the escalation may recommend:
frontend-design to update the aesthetic directionux-brief to revise the briefThis is rare — most issues are at the impl level and fix via develop agent.
Based on the review's next field:
| next | Action |
|---|---|
proceed | Report: "Design review passed. Proceeding to browser-test." Shutdown dev server if this skill started it. |
fix-and-rerun | Dispatch a sonnet fix agent with the specific patches from the review. After fixes, re-run Step 4-5 (screenshot + review). Max 2 iterations, then escalate. |
escalate | Report findings to the caller (craft/develop/implement). User sees the review and decides: revise brief, revise impl, or accept as-is. |
# Stop dev server if this skill started it
if [ "$DEV_SERVER_STARTED" = true ]; then
kill $DEV_PID 2>/dev/null
fi
# Screenshots are kept in .claude/plans/{feature-dir}/screenshots/ for traceability
.claude/plans/{feature-dir}/design-review.md.claude/plans/{feature-dir}/screenshots/develop/SKILL.md Step 3.75 (inserted between 3.5 post-develop review and 4 verification):
### Step 3.75: Design Review (conditional)
If .shared-state.md "Created / Modified Files" includes UI files (.tsx/.vue/.svelte):
Invoke craft-skills:design-review
Based on status:
- PASS → continue to Step 4 Verification
- MINOR_ISSUES → design-review dispatches fix agent automatically; re-enter this step after
- MAJOR_ISSUES → STOP. Report to user, await guidance
| Missing | Behavior |
|---|---|
| Playwright MCP | Text-only fallback (DOM snapshot review). Cannot catch rendered-layout bugs. Log: "Playwright unavailable; design-review is text-only. Install @playwright/mcp for visual regression." |
| Haiku / any Claude API access | Skip skill. Log and proceed to browser-test — human catches issues there. |
| Login required, no test credentials | Pause and ask user to log in (per existing browser-test convention) |
| Dev server fails to start | Abort skill, report error, skip to Step 6 cleanup. Do NOT block pipeline — browser-test will surface the same issue functionally. |
.claude/aesthetic-direction.md missing | Skip skill silently. Log: "No aesthetic direction. Run craft-skills:aesthetic-direction to enable design-review." |
ux-brief.md missing | Run review against aesthetic-direction only. No success-criteria check, just regression heuristics. |
| Scenario | Tokens |
|---|---|
| Clean feature (PASS on first Haiku pass) | ~10-15K |
| Minor issues, one fix round (Haiku → sonnet fix → Haiku re-check) | ~40-60K |
| Major issues, escalated to Sonnet/Opus review | ~80-120K |
Typical: 15-20K / feature (most changes pass first round).
Haiku-vision is ~8-10× cheaper than Opus-vision and, for the specific task of "does this screenshot match the design-contract and ux-brief success criteria," performs adequately on 70-80% of cases. Escalation to Sonnet/Opus happens only when Haiku's judgment is uncertain or flags MAJOR issues. This follows the same two-tier pattern as craft's local-LLM-first + Sonnet-fallback for implementation.
npx claudepluginhub alexiolan/craft-skills --plugin craft-skillsUse when a backpressured loop has a front-end/UI change and needs to compare the rendered result against its design reference (a Figma frame or images on a Linear ticket) — catching layout, spacing, contrast, and visual-consistency defects automated tests and happy-path clicking miss.
Conducts 7-phase frontend design review with WCAG 2.1 AA accessibility checks, responsive testing, visual polish for PR reviews, UI audits, layout issues.
Performs comprehensive UI/UX design reviews using Playwright for live environment testing, responsive validation across viewports, WCAG 2.1 AA accessibility scans, visual polish, interaction flows, and code health analysis.