Visual self review
Skill logicleap-labs/claude-plugins/plugins/visual-quality/skills/visual-self-review
Open Claude Code plugins for shipping AI output that's actually good. By Josh Matthews / LogicLeap Ltd.
npx -y skills add logicleap-labs/claude-plugins --skill visual-self-reviewAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
MANDATORY acceptance gate before declaring ANY visual or UI work "done", "good", "working", or before screenshotting an interface and ending the task. Use whenever you build, redesign, restyle, or fix a user-facing screen in ANY stack — Xcode/SwiftUI/UIKit apps, iOS/macOS, web (Next.js/React/HTML), Electron, Flutter, generated design mockups — and whenever you are asked to "review the screenshot", "check what you built", "is this good", "spot the issues", or "look at this design". Forces a structured, written, adversarial inspection of the ACTUAL rendered pixels (not the code, not your memory of intent) so obvious defects — blank/unlabelled elements, dead empty space, duplicated or garbage content, misalignment, inconsistent spacing, truncation, low contrast, leftover placeholders, broken states, and lag/jank — are caught BEFORE you claim completion. Triggers on "done", "looks good", "finished the UI", "here's the redesign", "screenshot", "ship it".
SKILL.md
10.4 KB, as published. Nobody here has run it
Visual Self-Review — the acceptance gate for anything with pixels
Read this whole file before you write your review. This skill exists because of one specific, repeated failure: you build a screen, screenshot it, glance at it, decide "looks like an app → done", and hand over work with defects so obvious a human spots them in two seconds. You are fully capable of seeing those defects. You just don't look — you pattern-match. This skill replaces the glance with a forced serial scan.
The rule that makes everything else work:
You do not get to judge a screen until you have transcribed it. Describe first. Judge second. A holistic "looks good" is banned as a first move — it is the exact reflex that ships broken UI.
The worked example that triggered this skill (study it)
A redesigned task app ("Cadence") was screenshotted and declared good enough to end the task. When then asked to "review the issues", the obvious ones were still missed. Here is what a two-second human look caught and the model didn't:
- A sidebar item with NO text. Under "WORKSPACE" there is a filled pill — and it is completely blank. An interactive nav row rendering zero label. Unmissable the instant you list the sidebar items one by one. Missed because nobody listed them.
- A huge dead gradient void at the top of the page. The entire top band above the stat cards is empty — no page title, no heading, no breadcrumb, nothing. ~15% of the viewport is wasted space that screams "unfinished". Missed because nobody accounted for every region of the screen.
- Garbage/duplicated content rendered as if fine. The timeline shows "prepare the seed round data room" seven times in a row (09:00, 09:30, 10:00, 10:30, 11:35, 12:05, 12:35). Obviously broken data being presented as a finished feature. Missed because nobody read the list top to bottom.
- Reported lag, never measured. "Disgracefully laggy" — and no performance pass was ever run.
None of these need design taste. They need looking. That is all this skill enforces.
Step 1 — Render the real thing (never review code or memory)
You review pixels that actually rendered, never the source you wrote, never your intent. The code can be perfect and the screen still broken (data, layout, async, theme, hit-testing). Capture the actual current state:
- Web / Next.js / React: use the preview MCP —
preview_startif needed, thenpreview_screenshotfor visuals andpreview_snapshotfor the accessibility/DOM tree. Usepreview_resizefor the responsive + dark-mode passes. Usepreview_console_logs/preview_networkfor errors. (Per project rules: nevernpm run devvia Bash — use the preview launch config.) - Xcode / iOS / macOS: build & run, then capture the simulator:
xcrun simctl io booted screenshot /tmp/vsr.png(or Device → Screenshot, or the SwiftUI preview canvas) and then Read the PNG back so you actually see it. A green build is NOT a render check — SwiftUI layout, Auto Layout, dynamic type, dark mode and hit areas all fail at runtime with a clean compile. - Generated mockups / image designs: Read the image you produced.
- Capture every state you changed: default, loading, empty, error, the long-content case, light AND dark, and the smallest target width. A screen is not reviewed until each state you touched has a screenshot you have actually looked at.
If you cannot render it, say so plainly and do not claim it works. "Compiles" / "types pass" / "should render" are not verification — they never catch CSS, layout, hit-testing, data, or browser/OS-specific bugs.
Step 2 — Transcribe before you judge (the core mechanic — do not skip)
For each screenshot, write out a literal inventory. This is serial, not holistic. You are forbidden from writing any verdict until this is done.
- Read every text string visible, top-to-bottom, left-to-right. Transcribe them verbatim. The moment a clickable/interactive element has no text where text belongs, you have found a defect — flag it. (This is what catches the blank sidebar item.)
- Account for every region of the frame: top bar, sidebar, header, main content, each card, footer. For each region state what it contains. If a region contains nothing, that empty space is a defect candidate — name it and justify why it's intentional or fix it. (This is what catches the dead void.)
- Read every list/repeated element in full. Do not "..." past them. Repetition, duplication, obviously-fake or placeholder data (lorem, "Title", "prepare the seed round data room" ×7) is a defect. (This is what catches garbage data.)
- Note the alignment grid: do edges line up? Are paddings equal? Are sibling cards the same height? Is type on a consistent scale?
Only after this inventory exists may you evaluate.
Step 3 — Sweep the defect taxonomy (assume defects exist)
Frame it adversarially: assume there are at least three defects and your job is to find them. "I found none" almost always means you didn't look — re-scan the regions you skimmed. Walk every class:
| # | Defect class | What you're hunting | The tell |
|---|---|---|---|
| 1 | Missing / blank content | interactive element with no label, icon with no glyph, image that didn't load, undefined/NaN/null rendered | a box where text/content should be |
| 2 | Dead space | large empty bands, no page title/heading, orphaned whitespace, content not filling its container | "is this region supposed to be empty?" |
| 3 | Duplicate / garbage data | repeated rows, placeholder/lorem left in, fake seed data shown as real | reading the list in full |
| 4 | Misalignment | edges not aligned, off-grid elements, ragged margins, uneven gutters | trace vertical/horizontal edges |
| 5 | Inconsistent spacing / sizing | unequal padding between siblings, mismatched card heights, random gaps | compare sibling to sibling |
| 6 | Typography | mixed scales, weights, fonts; orphan/widow lines; ALL-CAPS inconsistency | compare every text size to its neighbours |
| 7 | Truncation / overflow | clipped text, "…", content escaping its box, horizontal scrollbars | check long-content + narrow-width shots |
| 8 | Contrast / legibility | low-contrast text, text on busy gradient, invisible-until-hover affordances | squint test; check the gradient areas |
| 9 | Broken states | empty/loading/error states unstyled or showing raw errors | force each state |
| 10 | Overlap / z-index | elements on top of each other, cut-off shadows, modal behind content | look at layering |
| 11 | Alignment to intent | does it match what was asked? missing requested feature/section? | re-read the original request |
| 12 | Performance / jank | see Step 4 | measure, don't guess |
For each defect: state where (region + the transcribed text near it), what's wrong, and severity (blocker / obvious-to-user / polish). Blockers and obvious-to-user defects MUST be fixed, not noted.
Step 4 — Performance pass (because "laggy" is a real defect)
If you touched anything interactive, measure responsiveness — don't eyeball it once and move on.
- Web: check
preview_console_logsfor errors/warnings andpreview_networkfor slow/failed/duplicated requests. Watch for re-render storms (the same request firing repeatedly = the data-duplication bug above is often also a perf bug). Exercise the interaction (preview_click, scroll) and confirm it's smooth. Look for layout thrash, unthrottled scroll/resize handlers, unmemoised lists, animatingwidth/height/topinstead oftransform. - Xcode: scroll long lists in the simulator; watch for hitches. A laggy list is usually unmeasured
bodyrecomputation, missingid/Equatable, heavy work on the main thread, or images decoded on-scroll. - Lag the user reported is a blocker, not a footnote. Find the cause (profile / read the render path), fix it, re-verify.
Step 5 — Fix, re-render, re-review
Every blocker and obvious-to-user defect: fix it, then re-capture the screenshot and run Steps 2–3 again on the new image. A fix you didn't re-screenshot is a fix you didn't verify. Loop until a clean pass.
Definition of Done (all required — do not claim "done" until every box is true)
- The screen was actually rendered and screenshotted, and you looked at the image (Read it back). Every state you changed has its own shot (default / empty / loading / error / long-content / light + dark / narrowest width).
- A written transcription (Step 2) exists for each shot — every text string read, every region accounted for, every list read in full.
- The full taxonomy (Step 3) was swept; defects listed with location + severity.
- Every blocker / obvious-to-user defect is fixed and re-screenshotted — not just noted.
- A performance pass (Step 4) was run if anything interactive changed; reported lag chased to root cause and fixed.
- The result was checked against the original request — nothing asked-for is missing.
- Your report shows the proof (the screenshots / log output) and states plainly what you checked and what you found. If something is unverified, say which and why.
"Looks done" is not done. A clean compile is not a render. A glance is not a review. If a human would spot it in two seconds, missing it is the failure this skill exists to prevent — there is no excuse, because you can see it too. You just have to look, one element at a time.