Your agent gets a real website wrong because you gave it a picture. Give it values instead: the hex codes, the font names, the spacing scale and, when you need a whole section, the actual markup. A model that has the numbers does not have to guess them.
There are four ways to do that. They go from five minutes by hand to nothing at all.
Why the screenshot fails
A screenshot is pixels. The model looks at a heading and estimates 48px. It was 56px. It sees a purple and writes #6366f1. The brand color was #635bff. It cannot tell that the page uses a 4px spacing grid, or that the font is a custom typeface and not the system one.
Asking harder does not help. "Match the spacing exactly" is an instruction about information the model was never given.
Screenshots are still good for one thing: layout. Keep using them for where things go. Stop using them for what the values are.
1. Copy the computed styles from devtools
This works on any site, today, with nothing installed. Open the page, open the console, and run:
const el = document.querySelector('main section') // the section you want
const pick = ['color', 'backgroundColor', 'fontFamily', 'fontSize', 'fontWeight',
'lineHeight', 'letterSpacing', 'padding', 'gap', 'borderRadius', 'boxShadow']
const rows = [el, ...el.querySelectorAll('h1, h2, p, a, button')].slice(0, 12).map((n) => {
const s = getComputedStyle(n)
return {
tag: n.tagName.toLowerCase(),
text: n.textContent.trim().slice(0, 40),
...Object.fromEntries(pick.map(p => [p, s[p]]))
}
})
copy(JSON.stringify(rows, null, 2))
copy() is a console helper in Chrome, Edge and Firefox. The JSON is now on your clipboard. Paste it into the chat with:
Build this section in my project. Use exactly these computed values.
Do not invent colors, sizes or fonts that are not in the list.
Computed styles are what the browser actually rendered, after every stylesheet and media query, so they are the truth for your screen size. The limit is that they are for one viewport and no hover states. Resize the window and run it again if you need the mobile values.
2. Keep a tokens file in the repo
If you match the same reference more than once, stop pasting. Put the values where the agent reads them on every task:
<!-- CLAUDE.md, .cursor/rules, or AGENTS.md -->
## Design reference: acme.com
- Primary #635bff, text #0a2540, background #ffffff, muted #425466
- Font: "Sohne", system-ui. Weights 400 and 600.
- Type scale: 14, 16, 20, 32, 56 px
- Spacing: 4, 8, 16, 24, 48 px. Radius 8 px.
- Use only these values. Ask before adding a new one.
This is the cheapest fix with the largest effect. The agent stops drifting between tasks because the constraints never leave its context.
3. Paste the section's markup
For "rebuild this pricing table", values are not enough. The agent also needs the structure. In devtools, right-click the section, choose Copy, then Copy outerHTML, and paste that along with the computed styles.
It is ugly. The markup carries the source site's class names, which mean nothing without its stylesheet, and a real section can be thousands of lines. It still beats a screenshot, because the copy, the nesting and the image URLs are real.
4. Let the agent fetch it itself
The first three methods all have you in the middle, copying. An MCP server removes you: the agent calls a tool with a URL and gets the values back while it works.
With one connected you type this:
Match the hero on linear.app. Pull the real design first.
The agent calls a design extraction tool, receives the section as a component with the resolved colors, fonts and spacing, and writes against that. Setup is a URL in ChatGPT, Claude and Cursor, and one command in Claude Code.
The four, compared
| Method | Setup | You copy each time | Gets structure | Gets hover and breakpoints |
|---|---|---|---|---|
| Screenshot | None | Yes | Roughly | No |
| Devtools snippet | None | Yes | No | No |
| Tokens file in the repo | 10 minutes | No | No | No |
| Pasted outerHTML + styles | None | Yes | Yes | No |
| MCP server | 2 minutes | No | Yes | Yes |
My recommendation: do the tokens file today whatever else you choose. It costs ten minutes and fixes the most common complaint. Add an MCP server when you rebuild sections often enough that copying becomes the slow part.
Common problems
The agent still invents a color. Your list was missing a role, usually the muted text or the border. Add it, and say "use only these".
The font is wrong. The site uses a licensed typeface your project does not have. The agent cannot fix that. Pick the closest font you are allowed to use and put that in the tokens file.
It looks right at desktop and breaks on a phone. Computed styles are for one width. Give the agent the mobile values too, or the breakpoints.
The page is a JavaScript app and the HTML is nearly empty. Tools that read the served HTML find little. Copy from devtools after the page has rendered, or use an extractor that runs the page in a browser first.
Or use one API call
MiroMiro is the MCP server from method 4, and the same thing as a REST API. It resolves which CSS rules win for each element of a live page and returns the result as data:
curl "https://miromiro.app/api/v1/code?url=linear.app§ion=hero&framework=jsx" \
-H "Authorization: Bearer $MIROMIRO_API_KEY"
You get the section as a React component, the tokens it uses, and its image and font URLs. Other calls return the brand palette, the full token set, or every image and icon on the page.
To connect it to an agent, follow the page for yours: ChatGPT, Claude, Claude Code, Codex or Cursor. There is no key to paste. You can start for free, with 300 credits a month and no card.
It reads public pages only, and complex sections do not always come back clean. Look at what it returned before you trust it.
Summary
Screenshots are for layout. Values have to come from the page. Start with a tokens file in the repo, use the devtools snippet for one-offs, and connect an MCP server once you are copying more than you are building.
Frequently asked questions
Why does AI-generated UI look almost right but not quite?
Every value was estimated from pixels. A default blue for the brand color, 48px for a 56px heading, a system font for a custom one. Small errors, and a lot of them.
Is a screenshot ever enough?
For layout, yes. For colors, type, spacing and copy, no. Use both: the screenshot for where things go, the values for what they are.
Can Claude or Cursor read a live website's CSS?
They can fetch the files, but working out which of several thousand rules applies to which element is the hard part. An extraction tool does that and returns the answer.
What should I put in the prompt?
The values, and the sentence "use exactly these, do not invent others". Explicit numbers beat adjectives.
Skip the maintenance - one API call
Design tokens, brand data, fonts, SVGs, images, and section code from any URL. 300 free credits a month, no card.
Soraia · Founder, MiroMiro
Building MiroMiro: a browser extension and API that extract design tokens, assets, and production-ready code from any live website. The gotchas in these posts come from the extraction engine's own commit history.
Follow on X