image-mockup-recreator

Recreate a reference screenshot or mockup image as a live HTML/CSS artifact, using headless-browser screenshots, an SSIM visual diff score, and pixel-grid overlays to iteratively close the gap between

SKILL.md

GitHub

Image Mockup Recreator

Turn one reference image into a live HTML/CSS artifact through a measured iterate-and-score loop, not a single guess. Combines a Sequential Workflow (setup → build → publish) with an Iterative Refinement inner loop (render → score → adjust). Works from a flat image only — no Figma source needed.

Steps

# Step Action Output / Gate
1 Stage reference Copy source image to scratch dir as target.<ext>. Read exact pixel size (python3 -c "from PIL import Image; print(Image.open('target.png').size)"). Tell user scratch dir path now — all renders/heatmaps/grids land there fixed viewport size, never drift between iterations (SSIM depends on it)
2 Build first pass Single self-contained HTML sized exactly to target dims (width/height px on html,body). Absolute-position major regions (header/logo, content, side panels, footer) at estimated coords. Skip fine detail. Avoid filter: brightness(0) invert(1) on colored emoji (corrupts glyphs in headless Chromium) — use inline SVG icons (stroke="currentColor", fill="none") instead every region present, roughly placed
3 Render + score python3 scripts/screenshot.py <html_path> <out.png> --width <W> --height <H> [--executable-path /usr/bin/google-chrome]<br>python3 scripts/compare_ssim.py target.<ext> <out.png> --json --output-diff heatmap.png<br>python3 scripts/compare_color.py target.<ext> <out.png> --grid 4x4 --json<br>Read JSON score each round as progress signal. Open heatmap.png early and whenever bbox list alone is unclear — number hides mismatch type; heatmap reveals doubled/offset outlines. For mismatch direction, prefer overlay (step 6) SSIM 0-1 + verdict + ≤5 diff boxes; heatmap = location; color-diff flags palette drift beyond threshold (SSIM under-penalizes e.g. #3B82F6 vs #2563EB). Playwright missing-browser error → check which google-chrome chromium chromium-browser before playwright install
4 Iterate Loop: per flagged SSIM/color region, use grid (step 5) + overlay (step 6) to find fix — no vague "looks off" edits, heatmap alone unreliable for position/size (blur hides direction). One focused change category per round (bg shape, icons, font weight, spacing, one position, one color token), re-render, re-score. Compare new vs prior screenshot before keeping — score drop can mean regression or metric penalizing legit change. Don't swap flat gradients for stock photos hoping texture helps — SSIM penalizes wrong high-frequency detail harder than flat color, so unrelated stock imagery scores worse than clean gradient despite looking "more real." Only real matching source imagery helps stop when: score plateaus 2 rounds with no category left, OR user confirms good enough, OR ~8-10 rounds passed
5 Pixel grid (every 2-3 rounds, or before any position/size fix) python3 scripts/grid_image.py target.<ext> target_grid.png --spacing 50 --color "#ff00ff" (same for <out.png>; --spacing 20 on a crop for exact px offset). Run proactively, not just when stuck. Turns "card looks shifted" into "card is 20px too far left" exact pixel offsets for spacing fixes — change only that offset, don't re-derive layout
6 Red/green overlay (default tool for spotting what's wrong — before heatmap) python3 scripts/overlay_diff.py target.<ext> <out.png> overlay.png. Target grayscale → green channel, render grayscale → red channel: yellow = match, pure green = target has it/render missing or offset, pure red = render has it/target doesn't. Doubled green/red outline = shifted or wrong size; side tells direction to move. More actionable than SSIM heatmap (blurred, ≤5 bboxes) which is only good for first coarse pass. Don't invert one image's colors before diffing — destroys signal. Re-run after every position/size fix to confirm direction, not overshoot fastest way to see mismatch direction; still crop+compare flagged region before editing. SSIM number and overlay can disagree in magnitude — trust overlay for "positioned/sized right", trust score only for "page better or worse overall"
7 Clarify scope (if ambiguous) Ask: pixel/texture fidelity (real photos, gradients, font hinting) or structural fidelity (layout, spacing, correct components)? SSIM is texture-sensitive — plateau at ~0.5-0.6 is normal once structure confirmed correct, without real matching photos. Use score deltas + diff_region boxes as trustworthy signal; don't chase a target number once structure confirmed and remaining gap is asset-texture only
8 Publish Publish HTML as Artifact. Republish same file path on every later change stable URL across whole refinement session

Reference files