---
name: screenshot-to-html
description: >-
Replicate a UI screenshot/image/mockup into a high-fidelity, self-contained
HTML page. Faithful image-to-HTML / screenshot-to-code cloning that matches the
RENDERED result (not copied computed numbers) through a render -> screenshot ->
compare -> refine loop using the local Chrome. Use whenever the user gives an
image/screenshot/mockup/Figma export and wants HTML/CSS (plain or Tailwind), or
asks to "复刻 / 还原 / clone / recreate / turn this design into a webpage".
---
# screenshot-to-html — Screenshot to High-Fidelity HTML
Turn a UI image into a clean, self-contained HTML page whose **rendered output
matches the target image**. Respond to the user in their language (they often
write Chinese); keep chat replies short and let the work happen in files.
## Core principle: replicate the RENDERED state, not the COMPUTED state
The target image is the ground truth of the final **rendered pixels**. Reproduce
that, not a mechanical transcription of per-element values.
- **Computed-state cloning (do NOT do this).** Eyedropper every hex, "measure"
pixel coordinates/sizes, and paste `getComputedStyle`-style numbers into
absolute-positioned divs. Result: magic-number soup, non-semantic, not
responsive, brittle — and small extraction errors compound so it looks *worse*.
- **Rendered-state cloning (DO this).** Read the design like a developer: infer
semantic structure, a small set of **design tokens** (palette, type scale,
spacing rhythm, radii, shadows), and **layout intent** (flex/grid). Build it,
then **render your code, screenshot it, and compare against the target**, and
iterate. Optimize "does my render look like the target," goal: `render(code) ≈ target`.
This is why the workflow is a feedback loop, not a one-shot dump.
## Workflow
Copy this checklist and track progress:
```
- [ ] Phase 0 — Setup (inputs, stack, target width, deps, assets)
- [ ] Phase 1 — Read the design (global -> components -> exact text)
- [ ] Phase 2 — Build the first draft (semantic + tokens, self-contained)
- [ ] Phase 3 — Rendered-state loop (render, compare, fix; repeat 2-4x)
- [ ] Phase 4 — Interactivity & states (affordances + behavior, then verify)
- [ ] Phase 5 — Final checks
- [ ] Phase 6 — Enhance with motion (optional)
```
### Phase 0 — Setup
- Confirm inputs: the target image path(s) and the desired output file path.
- **Assets are automatic (no questions by default).** Fill each slot with what gives the
sharpest, most faithful result — not "crop everything": user-supplied assets win; real logos as
inline SVG / official files; **specific unique content cropped from the source**
(`scripts/crop.mjs`) when that region is sharp; generic photos from Unsplash / `picsum`; a
`https://placehold.co` block as last resort. Quality gate: never ship a blurry upscaled crop —
swap a soft crop for a sharp stock photo. Only ask **once** (non-blocking) if an asset is
brand-critical AND no layer can approximate it. See *Images & assets* in [reference.md](reference.md).
- Pick the **stack** (ask only if unclear): `vanilla` (HTML + plain CSS,
self-contained, default) or `tailwind` (HTML + Tailwind CDN). See *Stacks*.
- **Understand the canvas & scale FIRST — before writing any CSS.** Read the pixel
size (`sips -g pixelWidth -g pixelHeight `), then decide a **design width in
CSS px**, not the raw pixel count:
- Screenshots are usually retina (`@2x`/`@3x`), so the file is 2-3x the CSS width.
Do **not** just divide and build at that size — that ships a shrunken page with
`~10px` nav text that looks tiny at 100% zoom. Map to a **real breakpoint**:
web -> `1280` or `1440`; mobile -> `375`/`390`/`393`.
- Build at that width with **real-world type sizes** (hero ~48-72px, body ~16-18px)
and keep it **responsive/fluid** (`clamp()`, `max-width`, `%`), so it opens at a
normal size and adapts — never a fixed miniature.
- Run the render/compare loop at this design width; `--scale 2` only sharpens the
diff, it does **not** mean "author at half size."
- Ensure render deps once (no browser download): `npm i -D playwright-core`.
### Phase 1 — Read the design (global first, then local)
Look at the image carefully and write a short build spec. **Global before local:**
- Layout: page max-width, column grid, section order, alignment.
- Color tokens: name 4-8 colors (bg, surface, ink, muted, brand, accent, line).
Account for gradients/overlays/opacity — never trust one pixel.
- Type: families (serif vs sans, geometric vs humanist -> closest Google Font),
the heading->body **scale**, weights, letter-spacing, line-height.
- Spacing rhythm (base 4/8px), border-radii, shadow depth, borders/dividers.
- Components: nav, hero, feature/bento, stats, cards, testimonials, CTA, footer —
note structure and repetition (build one, loop the data).
- Content: transcribe the **exact visible text** (do not invent or translate it).
Do NOT record pixel coordinates. Record *relationships and tokens*.
For the full rubric see [reference.md](reference.md).
### Phase 2 — Build the first draft
- One **self-contained** file (inline `