verify-ui
Verify CSS/UI changes match what the user asked for. Uses deterministic computed style checks to avoid LLM confirmation bias. Use when: (1) After CSS or layout changes the user asks to verify, (2) Use...
File Structure
verify- ui/
├── SKILL. md
└── scripts/
└── verify- styles. mjsVerify UI
Verify that CSS/UI changes actually match what was requested.
Core Principle
The user asked you to do something ("add a border", "center the dialog", "make it full width on mobile"). After implementing, verify that the specific thing they asked for is actually working. Not a generic checklist — verify the requirement.
Step 1: Clarify What to Verify
If the requirement is clear — translate it to verifiable CSS properties:
| User said | Verify these properties |
|---|---|
| "add a border" | border-style (not none), border-width (not 0px), border-color |
| "center the dialog" | margin (should be auto or symmetric), bounding box position |
| "full width on mobile" | width at narrow viewport, max-width |
| "remove rounded corners" | border-radius (should be 0px) |
| "make text bigger" | font-size |
| "fix the z-index" | z-index, stacking relative to other elements |
If the requirement is vague ("check the result", "verify it looks good", "confirm it works") — ask the user back:
"What specifically should I verify? For example: is it about the border, the positioning, the spacing, the colors, or something else?"
Do NOT proceed with a generic screenshot check when you don't know what you're looking for. That's how confirmation bias happens.
Step 2: Extract Computed Styles
Run the verification script targeting the element in question:
LOGDIR=$(node $HOME/.claude/scripts/get-logdir.js)
mkdir -p "$LOGDIR"
node $HOME/.claude/skills/verify-ui/scripts/verify-styles.mjs "<URL>" "<SELECTOR>" "$LOGDIR/verify-ui" "<WIDTHS>" "<SCHEMES>"Detect viewport widths from the project's breakpoints:
grep -n "breakpoint" src/styles/global.css 2>/dev/nullPick widths that test each side of each breakpoint. Default: 400,800,1200. Default schemes: light,dark.
Parse the JSON output. Find the properties relevant to the user's request and compare against expected values.
[PASS] border-style: solid (expected: not "none")
[FAIL] border-width: 0px (expected: 1px) ← THIS IS THE PROBLEMIf the computed style check reveals the issue, fix it. No screenshot analysis needed — the data is deterministic.
Step 3: Visual Confirmation (if computed styles pass)
If computed styles look correct but the user's concern might be visual (layout, spacing, alignment), read the captured screenshots:
Read each screenshot with the Read tool
Describe what you see — specifically about the thing the user asked for
Compare against the requirement
Report whether it matches
NEVER say "looks correct" without stating what specific thing you checked and what you observed.
Limited-env browser fallback (web/WSL)
verify-styles.mjs includes a browser-resolver that falls back to a pre-installed Chromium when the default Playwright cache (~/ on Mac, ~/.cache/ms-playwright/ on Linux/WSL) is absent — e.g. on Claude Code web, where the browser-download CDN is blocked. Resolution order: default cache (Mac/local, unchanged) → PLAYWRIGHT_EXECUTABLE_PATH → newest /. On Linux (WSL, native, web container) the resolver passes --no-sandbox --disable-gpu --disable-dev-shm-usage on every branch — including the default cache — so a browser sitting in ~/.cache/ms-playwright/ launches without the "No usable sandbox!" error. On Mac/darwin no flags are added and the default-cache branch returns {} (unchanged). In-container, bind the dev server to 127.0.0.1 (*.localhost does not resolve there). When you cannot serve locally at all, verify against the PR preview deploy — see /'s "Verify against the PR preview deploy".
WSL prerequisite: a fresh WSL2 Ubuntu is missing Chromium's shared libraries (libnss3, libgbm, libasound2, …). The flags above silence the sandbox error, but if the libs are absent the launch still fails with "Host system is missing dependencies to run browsers". Run npx playwright install-deps once (it uses sudo) to install them.
When to Use Multiple Widths/Themes
Always if the change involves responsive behavior (breakpoint-dependent styling)
Always if the change involves colors or borders (may be invisible in one theme)
Not needed for changes that are viewport/theme independent (e.g., changing font-weight)
Anti-Patterns
Generic "take a screenshot and verify" — verify WHAT? If you don't know, ask.
"Looks correct" after glancing at screenshot — state what you checked.
Running verification without knowing what you're looking for — confirmation bias guaranteed.
Checking only one viewport width when the change is responsive — you'll miss breakpoint issues.