| name | qa |
| description | Visual + a11y QA — screenshot-first critique, contrast, touch targets, mockup-vs-impl diff. For adversarial logic checks use `/verify`. Triggers "visual QA", "QA check", "does this look right", "a11y check", "contrast check", post-component changes. |
| context | fork |
| allowed-tools | ["mcp__chrome-devtools__navigate_page","mcp__chrome-devtools__take_snapshot","mcp__chrome-devtools__take_screenshot","mcp__chrome-devtools__click","mcp__chrome-devtools__fill","mcp__chrome-devtools__hover","mcp__chrome-devtools__press_key","mcp__chrome-devtools__resize_page","mcp__chrome-devtools__evaluate_script","Agent"] |
| requires | [{"mcp":"chrome-devtools","install":"Configure chrome-devtools MCP — see mcp-configs/recommended.json"}] |
Visual QA Validation
Core Philosophy
- Screenshot first, then critique. Always look at the actual rendered output, not just the code.
- Be specific. "The spacing looks off" is useless. "The gap between the heading and paragraph is 32px but should be 16px based on the surrounding spacing rhythm" is useful.
- Prioritize impact. Not every pixel matters. Focus on what users will actually notice.
- Reference the intent. Compare against design tokens, mockups, or stated design goals.
Quick Start
The Chrome DevTools MCP exposes browser automation as tool calls. Typical sequence:
mcp__chrome-devtools__navigate_page (type: "url", url: "http://localhost:3000") — load the page
mcp__chrome-devtools__take_snapshot — text-based a11y tree with element uids (cheap, preferred first step)
mcp__chrome-devtools__take_screenshot — visual capture for review
- Interact via
click / fill / hover / press_key using the uids from the snapshot
Review Categories (Priority Order)
1. Layout & Spacing
Check for:
- Consistent spacing rhythm (is everything on the spacing grid?)
- Alignment -- are elements that should be aligned actually aligned?
- Padding consistency within similar components
- Container widths and max-widths
- No horizontal overflow
- Responsive behavior (if multiple viewport screenshots available)
Common issues:
- Inconsistent padding in cards (e.g., 24px top, 16px sides)
- Elements slightly off-grid (15px instead of 16px)
- Text not aligned with adjacent elements
- Sections with wildly different vertical spacing
2. Typography
Check for:
- Hierarchy -- is it clear what's a heading vs body vs caption?
- Line length -- body text should be 45-75 characters per line
- Line height -- too tight or too loose for the font size?
- Font weight usage -- are weights used consistently for the same role?
- Heading hierarchy is correct (h1 > h2 > h3)
- Orphans/widows -- single words on their own line in headings
Common issues:
- Heading that doesn't look like a heading (weight/size too close to body)
- Body text line length > 80 characters (hard to read)
- Inconsistent heading sizes across sections
- All-caps text without letter-spacing adjustment
3. Color & Contrast
Check for:
- Text meets 4.5:1 contrast ratio
- UI elements meet 3:1 contrast ratio
- Consistent use of brand colors
- Color meaning consistency (is the same blue used for links AND errors?)
- Dark mode issues (if applicable)
- Hover/active state visibility
- UI elements are distinguishable
Common issues:
- Light gray text on white background (contrast fail)
- Primary color used for too many different purposes
- Borders that are nearly invisible
- Status colors that conflict (green for danger, red for success)
4. Visual Hierarchy
Check for:
- Eye flow -- where does the eye go first? Is that correct?
- CTA prominence -- is the primary action the most visible element?
- Information density -- too sparse or too crowded?
- Grouping -- are related items visually grouped?
- White space -- is it used intentionally or just leftover?
Common issues:
- Two equally prominent CTAs competing for attention
- Important information buried below less important elements
- Sections that feel disconnected from each other
- Dense walls of text without visual breaks
5. Component Quality
Check for:
- Button sizing and padding consistency
- Input field styling consistency
- Card styling consistency (shadows, borders, radius)
- Icon sizing and alignment with text
- Image aspect ratios and cropping
Common issues:
- Buttons with inconsistent padding or height
- Mixed border-radius values (some 8px, some 12px, some 4px)
- Icons misaligned with adjacent text baselines
- Images stretched or poorly cropped
6. Accessibility
7. Polish & Micro-details
Check for:
- Hover states exist and are visible
- Focus states for keyboard navigation
- Loading states (skeleton screens, spinners)
- Empty states (what shows when there's no data?)
- Transitions between states (abrupt vs smooth)
- Error states are clear
Common issues:
- No hover state on interactive elements
- Focus ring removed with no replacement
- Abrupt content shifts when data loads
- No empty state -- just a blank area
8. Responsive Issues
Check for:
- Content readable on mobile (not too small)
- Touch targets >= 44px on mobile
- Navigation accessible on small screens
- Images not overflowing containers
- Horizontal scroll (almost always a bug)
Use mcp__chrome-devtools__resize_page to switch between desktop (1440×900), tablet (768×1024), and mobile (375×667) viewports.
Workflow
- Navigate to target URL
- Snapshot the a11y tree (text-based, returns
uids for interactive elements)
- Screenshot the current state
- Analyze against the review categories above
- Score using the output format below
- Report issues with actionable fixes
After Building a Component
- Render the component in the browser
- Take a screenshot
- Run visual QA review
- Fix issues
- Re-screenshot and verify
After Building a Full Page
- Screenshot at desktop (1440px), tablet (768px), and mobile (375px) — use
resize_page between captures
- Run responsive review across all three
- Run full review on the desktop version
- Fix issues, prioritizing critical ones
Fresh-Eyes Gate (unprimed second look)
Mandatory before declaring a user-reported visual bug fixed or claiming a visual change verified. Primed eyes pass defects that fresh eyes catch — after staring at the implementation, you see what you meant to render, not what rendered.
- Capture the exact screenshots under review, plus tight 2x–4x crops of every disputed area (if the complaint is "too faint", "wrong order", or "misaligned", the crop is mandatory).
- Spawn a fresh subagent and pass ONLY the images, the crops, and a short neutral task ("list concrete visible defects with confidence levels"). No thread history, no implementation details, no expected answer — leaking either teaches it your blind spot.
- When comparing two candidates, ask which is less wrong, not which matches a baseline.
- Treat overlap between its critique and yours as high-priority evidence; treat its novel high-confidence findings as bugs to inspect, not taste notes to dismiss.
Comparing to a Mockup
- Get the mockup image:
- From Figma (preferred): Use the Figma MCP directly —
mcp__figma__get_design_context returns structured design specs (tokens, dimensions, component props) instead of pixel-pushing screenshots. The MCP server's own instructions cover URL parsing and the design-to-code workflow.
- Manual: Figma export, screenshot, or user-provided image
- Screenshot the implementation at the same viewport size
- Run comparison review
- Fix deviations by priority
Tool Cheat-Sheet
| Action | Tool |
|---|
| Load a URL | mcp__chrome-devtools__navigate_page { type: "url", url } |
Text a11y tree with uids (cheap) | mcp__chrome-devtools__take_snapshot |
| Screenshot | mcp__chrome-devtools__take_screenshot |
| Click an element | mcp__chrome-devtools__click { uid } |
| Fill input / select option | mcp__chrome-devtools__fill { uid, value } |
| Hover an element | mcp__chrome-devtools__hover { uid } |
| Press key (Enter, Tab, Escape, …) | mcp__chrome-devtools__press_key { key } |
| Resize viewport | mcp__chrome-devtools__resize_page { width, height } |
| Run JS in page | mcp__chrome-devtools__evaluate_script |
Output Formats
Full Review
## QA Report: [Page/Component]
**Overall impression:** [One sentence -- first gut reaction]
**Quality score:** [1-10] / 10
### Critical Issues (fix before shipping)
1. **[Category]:** [Specific issue with exact details]
-> **Fix:** [Actionable recommendation]
### Improvements (should fix)
1. **[Category]:** [Specific issue]
-> **Fix:** [Recommendation]
### Minor Polish (nice to fix)
1. **[Category]:** [Specific issue]
-> **Fix:** [Recommendation]
### What's Working Well
- [Specific praise -- what's well-executed]
- [Another positive]
### Passed Checks
- [x] Touch targets adequate
- [x] Heading hierarchy correct
### Issues Found
- [ ] Missing alt text on hero image
-> Add alt="..." to components/hero/index.tsx:15
- [ ] Contrast too low on muted text
-> Change text-gray-400 to text-gray-500
### Recommendations
- Consider adding loading skeleton for async content
Quick Review
## Quick QA: [Page/Component Name]
Score: [X]/10
Top 3 fixes:
1. [Most impactful issue + fix]
2. [Second issue + fix]
3. [Third issue + fix]
Looks good: [What's working]
Comparison Review (Implementation vs Mockup)
## Design vs Implementation Review
**Fidelity score:** [1-10] / 10
### Deviations Found
1. **[Element]:** Mockup shows [X], implementation has [Y]
Impact: [High/Medium/Low]
-> **Fix:** [How to match the mockup]
### Matching Well
- [Elements that accurately match the design]
Prerequisites
Requires the chrome-devtools MCP server (shipped in mcp-configs/recommended.json and installed by setup.sh).