Skip to content
Browse all prompts
adversarial-design-review.md Markdown · 55 lines Raw
Take one UI surface from competent to well-crafted. Not "changed" — better, and you have to prove it with pixels.

The surface is: **[name the page, dialog or component, and the URL it renders at]**

## The rule that makes this work

You do not review your own work. You wrote it, so you will like it. A second model is the reviewer, and you are the one who fixes what it finds.

Send each round to Codex — the Codex MCP server if you have it connected, otherwise `codex exec` in a read-only sandbox. Give it the screenshots and ask it to be hostile. Its job is to find what is wrong; your job is to check whether it is right.

## 1. Learn what this surface is meant to be

Before you look at my version, work out what good looks like for this kind of surface. Find two or three real examples from products that do it well and note what they do about hierarchy, spacing, state and empty cases.

Write this down as a short design brief and keep it. Every later round is scored against the brief, not against your taste in the moment.

## 2. Build a screenshot harness

A script I can re-run, not a one-off. Playwright, headless, capturing the surface at 375px and 1440px, in light and dark if the site has both.

Two things that will bite you:

- Headless Chromium hides scrollbars, which changes layout. Launch with `ignoreDefaultArgs: ['--hide-scrollbars']` if scrollbars are part of what you are judging.
- For a hover state, hover the element itself and then assert the hovered style before you capture — a screenshot that silently shows the resting state is the easy mistake here. If hover will not take in a headless run, activating the frame before moving the mouse is worth trying, but check that doing so has not changed anything else in the shot.

Capture a baseline now, before you change anything.

## 3. Loop

Each round:

1. **Capture** the current state.
2. **Review** — hand the screenshots to Codex. Ask for a score out of 10 and a ranked list of specific, located problems. "Feels cramped" is not a finding; "the 8px gap between the heading and the first row reads as one block" is.
3. **Verify** — for every finding, go look. Reviewers hallucinate elements that are not there and miss ones that are. Discard what you cannot reproduce, and say which ones you discarded.
4. **Triage** — fix what is real and worth fixing. If the cause is in a shared component or on a neighbouring screen, fix it there instead of patching this one surface.
5. **Pin it** — for anything that could silently come back, write the test that catches it.
6. **Re-score** with a fresh capture.

Stop when a round produces nothing worth doing, or at five rounds, whichever comes first.

## 4. Things a reviewer will push you toward that you should refuse

- **Deleting content to raise the score.** An emptier screen scores better and serves the reader worse. Tighten the design, keep the substance.
- **Hover effects on things that are not clickable.** Hover belongs where a click lands, and nowhere else.
- **Decorative underlines and redundant rules.** If the hierarchy needs a horizontal rule to be legible, the hierarchy is the problem. This is not licence to strip a link of its underline in running prose, where the underline is how a reader finds it, or to flatten a rule that is genuinely separating rows of data.
- **Centring everything.** Rows of roughly equal length usually want to be left-aligned.

## 5. Before you tell me it is done

Two gates the loop cannot do for itself:

- **Consistency sweep.** Grep the codebase for the classes and tokens you touched. If you changed a shared value, check every place it lands — other route groups included — before you call it finished.
- **Full test run.** Not just the tests for this surface. All of them.

Then report: the starting score, the final score, what you fixed, what you rejected from the reviewer and why, and the before-and-after screenshots side by side.