clone-ui

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

clone-ui

克隆UI

Faithful, multi-source web UI cloning. Optimized for fidelity over speed: the goal is "looks identical to the source" first, "fits the project conventions" second.
基于多源的精准Web UI克隆工具。优先保证保真度而非速度:核心目标是“与源视觉完全一致”,其次才是“适配项目规范”。

Fidelity tiers (read this first)

保真度层级(请先阅读)

The output quality of this skill scales with the source material available. Be upfront with the user about what tier you're working in:
TierInputs availableAchievable result
A — Full sourceLive screenshot via browser MCP + rendered DOM + computed styles"close visual match" → "pixel-perfect" possible
B — Static fetchWebFetch HTML works (no JS hydration) + screenshot user provided"close visual match" likely
C — Provided assetsUser-supplied screenshot/HTML, no live access"close visual match" if assets are good
D — Memory onlyNo fetchable source, no screenshot — only training data"rough sketch" max — say so explicitly
If you land in Tier D, stop and tell the user before writing code. A clone built from training data is almost certainly stale (sites change copy/layout often) and the user is better served by capturing a screenshot first. Offer to walk them through
take_screenshot
MCP setup or ask for a manual capture rather than producing low-fidelity output silently.
本技能的输出质量随可用源材料的丰富程度提升。请明确告知用户当前所处的层级:
层级可用输入可实现效果
A — 完整源浏览器MCP获取的实时截图 + 渲染后的DOM + 计算样式可实现“高度视觉匹配”→“像素级完美”
B — 静态抓取WebFetch可获取HTML(无JS hydration) + 用户提供的截图大概率实现“高度视觉匹配”
C — 用户提供资源用户提供的截图/HTML,无在线访问权限若资源质量良好,可实现“高度视觉匹配”
D — 仅依赖记忆无可抓取源、无截图 — 仅依赖训练数据最多实现“粗略草图” — 请明确告知用户
若处于D层级,在编写代码前请先告知用户。基于训练数据构建的克隆几乎肯定过时(网站内容/布局经常变化),用户最好先捕获截图。可主动指导用户设置
take_screenshot
MCP,或请求用户手动提供截图,避免默默生成低保真度输出。

Optional but strongly recommended: Chrome DevTools MCP

可选但强烈推荐:Chrome DevTools MCP

When chrome-devtools-mcp is installed and active, you have access to:
  • take_screenshot
    — capture the current viewport (use multiple viewports for responsive)
  • take_snapshot
    — DOM + accessibility tree (post-hydration, includes JS-rendered content)
  • Network/console inspection for sites that need login flow
These tools elevate every clone from Tier B/C to Tier A. If the user asks you to clone a live URL and these tools are NOT available, mention it once at the start: "I'd recommend installing chrome-devtools-mcp for higher-fidelity clones — see the skill's setup section. I'll proceed with what's available."
If unsure whether the MCP is available, just try calling
take_screenshot
once early in Phase 2 — if it fails, you know you're in Tier B or below.
chrome-devtools-mcp已安装并激活时,你可使用以下功能:
  • take_screenshot
    — 捕获当前视口(针对响应式设计可捕获多视口)
  • take_snapshot
    — 获取DOM + 无障碍树(hydration后,包含JS渲染内容)
  • 网络/控制台检查,适用于需要登录流程的网站
这些工具可将所有克隆任务从B/C层级提升至A层级。若用户要求克隆在线URL但未安装这些工具,请在开始时提及一次:“我建议安装chrome-devtools-mcp以获得更高保真度的克隆效果——请查看技能的设置部分。我将基于现有资源继续操作。”
若不确定MCP是否可用,可在第二阶段初期尝试调用
take_screenshot
一次——若调用失败,则说明处于B层级或更低。

Concurrency: chrome-devtools is single-browser

并发限制:chrome-devtools为单浏览器实例

chrome-devtools-mcp
runs one shared Chrome instance per Claude Code session. If multiple subagents spawn in parallel and each tries to clone a different URL, they will fight over the same browser tab focus — one agent's
navigate_page
/
resize_page
/
new_page
switches the active tab away from a sibling's work, and the sibling's next
take_screenshot
or
evaluate_script
then runs against the wrong page.
Two mitigations, in order of preference:
  1. Use isolated contexts. When opening a new page, pass
    isolatedContext: true
    (or the equivalent flag for whichever
    new_page
    -style call your MCP version supports). Each agent gets its own browser context with its own page list — no cross-contamination.
  2. Serialize runs. If isolated contexts aren't available or reliable, run sw-clone tasks one at a time. The skill's per-task duration (~3-5 minutes for a real Tier A clone) makes this acceptable for most workflows.
Symptom that you're hitting the focus drift bug: a
take_screenshot
returns the wrong page, or an
evaluate_script
returns DOM from a URL you didn't navigate to. If you see this, recover by calling
new_page
(which auto-selects) and re-navigating.
chrome-devtools-mcp
在每个Claude Code会话中仅运行一个共享Chrome实例。若多个子代理并行启动且各自尝试克隆不同URL,它们会争夺同一浏览器标签页的焦点——一个代理的
navigate_page
/
resize_page
/
new_page
操作会将活动标签页切换至其他代理的工作页面,导致其他代理后续的
take_screenshot
evaluate_script
操作针对错误页面执行。
两种缓解方案,按优先级排序:
  1. 使用隔离上下文。打开新页面时,传入
    isolatedContext: true
    (或你的MCP版本支持的等效标志)。每个代理将获得独立的浏览器上下文及页面列表——不会互相干扰。
  2. 序列化执行。若隔离上下文不可用或不稳定,则逐个执行sw-clone任务。单个任务的执行时长约为3-5分钟(针对真实的A层级克隆),此方案对大多数工作流而言是可接受的。
出现焦点漂移问题的症状:
take_screenshot
返回错误页面,或
evaluate_script
返回未访问URL的DOM。若出现此情况,可通过调用
new_page
(会自动选中新页面)并重新导航来恢复。

Auth-gated UIs (logged-in views)

需要权限验证的UI(登录后视图)

chrome-devtools-mcp
launches Chrome with
--isolated
by default — a fresh user-data-dir with no cookies, no extensions, no logged-in sessions. This is great for repeatability, but it means:
The MCP can only directly observe what a logged-out visitor sees. If the user asks you to clone a logged-in view (the GitHub authenticated app header, Gmail inbox, Linear's project view, any SaaS dashboard),
take_screenshot
will return either the marketing/landing version of the page or a sign-in prompt — not the target the user wants.
When this happens, be honest about what tier of source material you actually have:
  • Visual tokens (color palette, typography, font sizes, button styles) usually still match between logged-out and logged-in surfaces of the same product → Tier A for tokens.
  • Layout, components, copy of the logged-in page itself → unobservable → Tier D (memory only) for those parts.
Report this honestly in your output as "Tier mixed: tokens A, layout D" rather than claiming a uniform tier. The user gets to decide whether mixed-tier output is good enough or whether they want to take a manual screenshot of the logged-in view and provide it as Tier C input.
If the user explicitly opts into observing the logged-in view, two paths forward:
  1. Ask them to drop the
    --isolated
    flag from their
    ~/.claude/settings.json
    chrome-devtools entry and restart Claude Code so the MCP attaches to a Chrome with their existing session cookies. Trade-off: their personal browsing state becomes visible to the agent.
  2. Ask them to take a manual screenshot of the logged-in view and provide its file path. The skill operates on that screenshot as a Tier C input.
Don't silently fall back to memory and pretend you observed a logged-in surface. That produces misleading output and erodes user trust in the skill.
chrome-devtools-mcp
默认使用
--isolated
参数启动Chrome——即全新的用户数据目录,无Cookie、无扩展、无登录会话。这有助于保证可重复性,但也意味着:
MCP仅能直接观察未登录访客可见的内容。若用户要求克隆登录后视图(如GitHub认证应用头部、Gmail收件箱、Linear项目视图、任何SaaS仪表盘),
take_screenshot
将返回页面的营销/着陆版本或登录提示——而非用户所需的目标内容。
出现此情况时,请如实告知用户实际可用的源材料层级:
  • 视觉令牌(调色板、排版、字体大小、按钮样式)通常在同一产品的未登录和登录界面中保持一致 → 令牌部分为A层级
  • 登录后页面的布局、组件、内容 → 无法观察 → 这些部分为D层级(仅依赖记忆)。
请在输出中如实报告为**“混合层级:令牌A,布局D”**,而非声称统一层级。用户可自行决定混合层级输出是否足够,或是否需要手动捕获登录后视图的截图并作为C层级输入提供。
若用户明确希望观察登录后视图,有两种解决方案:
  1. 请求用户在
    ~/.claude/settings.json
    的chrome-devtools配置项中移除
    --isolated
    标志,然后重启Claude Code,使MCP连接到包含现有会话Cookie的Chrome实例。权衡:用户的个人浏览状态将对代理可见。
  2. 请求用户手动捕获登录后视图的截图并提供文件路径。技能将基于该截图作为C层级输入进行操作。
请勿默默依赖记忆构建并假装已观察到登录后界面。这会产生误导性输出,损害用户对技能的信任。

When to use

使用场景

Trigger this skill whenever the user gives you:
  • A screenshot (single or multi-viewport)
  • A live URL to clone
  • Raw HTML/CSS
  • A Figma frame export
  • Any combination of the above
…and asks you to build, recreate, match, or implement that UI in their codebase.
当用户提供以下内容之一,并要求在其代码库中构建、重新创建、匹配或实现该UI时,触发此技能:
  • 截图(单视口或多视口)
  • 需克隆的在线URL
  • 原始HTML/CSS
  • Figma帧导出文件
  • 上述任意组合

When not to use

非使用场景

  • The user asks for an original design ("design a hero section for X") — that's a creative task, not a clone task.
  • The user asks for code review of an existing implementation — different skill.
  • The user wants only data extraction (e.g. scraping content from HTML) without rebuilding the UI.

  • 用户要求原创设计(如“为X设计一个Hero区域”)——这是创意任务,而非克隆任务。
  • 用户要求对现有实现进行代码审查——属于其他技能范畴。
  • 用户仅需数据提取(如从HTML中抓取内容)而无需重建UI。

The six-phase flow

六阶段流程

Cloning quality collapses when phases are skipped. Resist the urge to jump to "write the code" — every skipped phase shows up as visible drift in the final result.
  1. Inventory inputs — figure out what sources of truth you have
  2. Gather — fetch / read every available source
  3. Plan — break the target into components, identify breakpoints + interactive states
  4. Implement — translate sources into code in the user's stack
  5. Verify — compare side-by-side, list every drift
  6. Polish — fix drifts in priority order until parity

跳过任意阶段都会导致克隆质量下降。请勿急于“编写代码”——每跳过一个阶段,最终结果都会出现明显偏差。
  1. 盘点输入 — 明确可用的真实数据源
  2. 收集资源 — 获取/读取所有可用源
  3. 规划 — 将目标拆分为组件,确定断点 + 交互状态
  4. 实现 — 将源转换为符合用户技术栈的代码
  5. 验证 — 逐段对比,列出所有偏差
  6. 优化 — 按优先级修复偏差直至完全匹配

Phase 1 — Inventory inputs

阶段1 — 盘点输入

List what you have. Each input type has different fidelity:
InputFidelityLimitations
Screenshot (PNG/JPG)Visual truth — what user actually seesNo exact color values, no font names, no exact px
Live URLHighest — rendered DOM + computed stylesMay be auth-gated, may rate-limit, JS-heavy sites need real browser
Raw HTML (view-source)Markup truth, but pre-hydrationMissing JS-rendered content, inlined styles only
Rendered HTML (post-hydration)DOM truthStill no computed styles unless captured
Computed styles dump (JSON / DevTools export)Style truth — exact px/colors/fontsTied to one viewport + state
Figma exportDesign truth — exact tokensMay not match actual rendered site
If the user only gave one source, ask if more are available before starting:
"I have the screenshot. Do you also have the live URL or raw HTML? Multi-source clones are dramatically more accurate — even view-source HTML helps."
If only a screenshot is available, that's still workable, but flag the lower fidelity ceiling upfront.

列出所有可用输入。不同输入类型的保真度不同:
输入类型保真度局限性
截图(PNG/JPG)视觉真相——用户实际看到的内容无精确颜色值、字体名称、像素尺寸
在线URL最高——渲染后的DOM + 计算样式可能需要权限验证、可能触发速率限制、JS密集型网站需要真实浏览器
原始HTML(view-source)标记真相,但为hydration前状态缺失JS渲染内容,仅包含内联样式
渲染后HTML(hydration后)DOM真相若未捕获则无计算样式
计算样式转储(JSON / DevTools导出)样式真相——精确的像素/颜色/字体值仅对应单个视口 + 状态
Figma导出设计真相——精确令牌可能与实际渲染网站不符
若用户仅提供一种源,开始前请询问是否有更多可用源
“我已获取截图。请问是否还有在线URL或原始HTML?多源克隆的准确性会大幅提升——即使是view-source HTML也有帮助。”
若仅提供截图,仍可进行操作,但需提前告知用户保真度上限较低。

Phase 2 — Gather

阶段2 — 收集资源

For each input the user has, pull it into context:
针对用户提供的每个输入,将其纳入上下文:

Screenshot

截图

Read
the file path. The image is your visual truth — refer back to it constantly.
If multiple viewport screenshots exist (e.g.
screenshot-w375.png
,
screenshot-w1440.png
), open the largest first to understand the desktop layout, then each smaller width to map the responsive transitions.
Read
文件路径。图片是你的视觉真相——请不断参考。
若存在多视口截图(如
screenshot-w375.png
screenshot-w1440.png
),先打开最大尺寸的截图以理解桌面布局,再查看每个较小尺寸的截图以梳理响应式过渡效果。

Live URL

在线URL

Preferred path (Tier A): Chrome DevTools MCP. If
take_screenshot
and
take_snapshot
are available, use them —
take_snapshot
returns post-hydration DOM (handles SPAs cleanly) and
take_screenshot
gives you visual truth. Capture at minimum 1440px (desktop) and 375px (mobile) viewports; add 768px (tablet) if the layout has 3+ breakpoints.
Fallback path (Tier B): WebFetch. Grabs markdown-converted content. WebFetch does NOT render JavaScript — it gives you the static HTML response only.
For JS-heavy SPAs (React, Vue, Next.js apps), WebFetch will return a near-empty
<div id="root">
. WebFetch may also be denied by some sites' bot detection (Cloudflare, etc.). In either case, the right move is to either:
  1. Ask the user to install Chrome DevTools MCP (see Setup section)
  2. Ask the user to capture the rendered DOM (via DevTools "Copy outerHTML" on
    <body>
    ) and provide it as raw HTML
  3. Ask the user for a screenshot
Do not silently fall back to building from training-data memory — that produces Tier D output even when the user thinks they're getting Tier B. Tell them upfront what tier you're operating in.
首选方案(A层级):Chrome DevTools MCP。若
take_screenshot
take_snapshot
可用,请使用它们——
take_snapshot
返回hydration后的DOM(可完美处理SPA),
take_screenshot
提供视觉真相。至少捕获1440px(桌面)和375px(移动端)视口;若布局有3个以上断点,可添加768px(平板)视口。
备选方案(B层级):WebFetch。获取转换为markdown的内容。WebFetch不渲染JavaScript——仅返回静态HTML响应。
针对JS密集型SPA(React、Vue、Next.js应用),WebFetch将返回近乎空的
<div id="root">
。部分网站的机器人检测(如Cloudflare等)也可能阻止WebFetch。无论哪种情况,正确的做法是:
  1. 请求用户安装Chrome DevTools MCP(请查看设置部分)
  2. 请求用户捕获渲染后的DOM(通过DevTools对
    <body>
    执行“复制外部HTML”)并作为原始HTML提供
  3. 请求用户提供截图
请勿默默依赖训练数据构建——这会生成D层级输出,而用户可能以为自己获得的是B层级输出。请提前告知用户当前所处层级。

Raw HTML

原始HTML

Read
the file or paste. Look for:
  • Class names → likely Tailwind, BEM, CSS modules, or custom
  • Inline styles → exact values to honor
  • <link rel="stylesheet">
    → fetch those CSSes too if user has them
  • <style>
    blocks → inline CSS rules
  • Font imports → Google Fonts links,
    @font-face
    declarations
Read
文件或粘贴内容。重点关注:
  • 类名 → 可能为Tailwind、BEM、CSS Modules或自定义类名
  • 内联样式 → 需严格遵循的精确值
  • <link rel="stylesheet">
    → 若用户提供相关CSS文件,也请一并获取
  • <style>
    块 → 内联CSS规则
  • 字体导入 → Google Fonts链接、
    @font-face
    声明

Computed styles / context

计算样式 / 上下文

If the user provides a context dump (JSON, markdown, CSS variable list),
Read
it. These are gold — exact values beat eyeballed values every time. Prioritize them as source of truth.

若用户提供上下文转储(JSON、markdown、CSS变量列表),请
Read
这些内容。这些是黄金资源——精确值始终优于目测值。请优先将其作为真相来源。

Phase 3 — Plan

阶段3 — 规划

Before writing any code, produce these four artifacts (briefly — bullet lists, not essays):
编写代码前,请生成以下四个成果(简洁呈现——使用项目符号列表,而非长篇大论):

3a. Component breakdown

3a. 组件拆分

Break the target into logical components. Match the user's project conventions — if they use functional React with hooks, plan that way; if they use Vue SFCs, plan that way.
HomePage
├── HeroSection
│   ├── Logo
│   ├── NavMenu
│   └── HeadlineGroup
├── FeatureGrid (3 cards)
└── Footer
将目标拆分为逻辑组件。匹配用户的项目规范——若用户使用带hooks的函数式React,请按此规划;若用户使用Vue SFC,请按此规划。
HomePage
├── HeroSection
│   ├── Logo
│   ├── NavMenu
│   └── HeadlineGroup
├── FeatureGrid (3 cards)
└── Footer

3b. Breakpoint map

3b. 断点映射

Identify breakpoints from screenshots OR CSS (
@media
queries). Common patterns:
WidthBehavior
≥ 1280pxDesktop: 3-col grid, full nav
768–1279pxTablet: 2-col grid, condensed nav
< 768pxMobile: 1-col, hamburger menu
从截图或CSS(
@media
查询)中识别断点。常见模式:
宽度范围行为
≥ 1280px桌面端:3列网格、完整导航
768–1279px平板端:2列网格、紧凑导航
< 768px移动端:1列、汉堡菜单

3c. Design tokens

3c. 设计令牌

Extract or eyedrop:
  • Colors: primary, secondary, text, bg, border (hex codes — exact)
  • Typography: font family, weights used, base size, line-height, scale ratio
  • Spacing: detect the grid (4px? 8px?), list common gaps
  • Radius: card radius, button radius
  • Shadows: subtle? prominent? elevation levels
If you have computed styles → use those values verbatim. If only screenshot → use a color picker mentally and round to the closest sensible value (e.g.
#4F46E5
not
#4F47E4
).
提取或目测获取:
  • 颜色:主色、辅助色、文本色、背景色、边框色(十六进制代码——精确值)
  • 排版:字体族、使用的字重、基础字号、行高、比例系数
  • 间距:识别网格(4px?8px?),列出常见间距
  • 圆角:卡片圆角、按钮圆角
  • 阴影:柔和?突出?层级
若有计算样式 → 直接使用这些值。若仅提供截图 → 手动取色并四舍五入至最合理的值(如
#4F46E5
而非
#4F47E4
)。

3d. Interactive states

3d. 交互状态

Even from a single screenshot, infer states from visible cues:
  • Buttons usually have
    :hover
    ,
    :active
    ,
    :focus
  • Inputs have
    :focus
    ,
    :disabled
    ,
    :invalid
  • Cards may have
    :hover
    lift
  • Nav items may have
    aria-current
    styling
If the user provides a live URL or context dump with
:hover
rules, capture those exactly.

即使仅提供单张截图,也可从可见线索推断状态:
  • 按钮通常有
    :hover
    :active
    :focus
    状态
  • 输入框有
    :focus
    :disabled
    :invalid
    状态
  • 卡片可能有
    :hover
    悬浮效果
  • 导航项可能有
    aria-current
    样式
若用户提供在线URL或包含
:hover
规则的上下文转储,请精确捕获这些规则。

Phase 4 — Implement

阶段4 — 实现

Stack detection

技术栈检测

Auto-detect from
package.json
:
bash
undefined
package.json
自动检测:
bash
undefined

Use Read on package.json

使用Read读取package.json


| Detected dependency | Stack |
|---|---|
| `next` | Next.js (App or Pages router — check `app/` vs `pages/`) |
| `react` (no Next) | React + Vite/CRA |
| `vue` | Vue 3 |
| `svelte` | SvelteKit |
| `astro` | Astro |
| (none, or no `package.json` at all) | **Plain HTML + CSS + JS** — write `index.html`, `styles.css`, and `app.js` as siblings the user can open directly in a browser. See "Default plain output" below. |

| 检测到的依赖 | 技术栈 |
|---|---|
| `next` | Next.js(App或Pages路由——检查`app/`与`pages/`) |
| `react`(无Next) | React + Vite/CRA |
| `vue` | Vue 3 |
| `svelte` | SvelteKit |
| `astro` | Astro |
| 无依赖,或无`package.json` | **纯HTML + CSS + JS** — 编写`index.html`、`styles.css`和`app.js`作为同级文件,用户可直接在浏览器中打开。请查看下文“默认纯输出”。 |

Default plain output

默认纯输出

When there's no project context to match (the user is in an empty folder, in their home directory, or just dropped a prompt without pointing you at a codebase), default to a three-file plain web structure:
index.html
styles.css
app.js
Rationale: most real-world web pages need some interactivity even if it looks minimal — hamburger menu toggle, smooth-scroll behavior, an intersection observer for nav-on-scroll, a dropdown. Always scaffolding all three files (even if
app.js
starts as a couple lines) avoids the awkward "I built it pure CSS but now you want a menu toggle, here's a fourth file" moment.
If the source page is genuinely zero-JS (a static brochure with no interactivity at all), you can omit
app.js
— but call it out in your output: "no JS file created since the source has no interactive behavior." Otherwise default to all three.
Do not introduce a build step (no Vite, no Tailwind CDN unless you explicitly verify the user wants that, no
npm install
). The whole point of the plain default is the user can double-click
index.html
and see the result.
当无项目上下文可匹配时(用户处于空文件夹、主目录,或仅提供提示而未指向代码库),默认采用三文件纯Web结构
index.html
styles.css
app.js
rationale:即使看起来简单,大多数真实网页也需要一些交互性——如汉堡菜单切换、平滑滚动行为、导航滚动监听的交叉观察器、下拉菜单。始终搭建这三个文件(即使
app.js
最初只有几行代码),可避免出现“我用纯CSS构建,但现在你需要菜单切换,这里是第四个文件”的尴尬情况。
若源页面确实无JS(无交互性的静态宣传页),可省略
app.js
——但需在输出中说明:“未创建JS文件,因源页面无交互行为。”否则默认生成三个文件。
请勿引入构建步骤(无需Vite、无需Tailwind CDN,除非明确确认用户需要、无需
npm install
)。纯输出的核心优势是用户可双击
index.html
直接查看结果。

Styling detection

样式方案检测

FoundUse
tailwindcss
Tailwind classes
styled-components
/
emotion
CSS-in-JS
*.module.css
CSS Modules
sass
/
*.scss
Sass
(none)Plain CSS in a
.css
file next to the component
Match the user's existing conventions, don't introduce new ones. If they use Tailwind, don't write inline styles. If they use CSS Modules, don't suggest Tailwind.
检测到的内容使用方案
tailwindcss
Tailwind类
styled-components
/
emotion
CSS-in-JS
*.module.css
CSS Modules
sass
/
*.scss
Sass
无上述内容纯CSS,放在组件旁的
.css
文件中
匹配用户现有规范,请勿引入新方案。若用户使用Tailwind,请勿编写内联样式。若用户使用CSS Modules,请勿推荐Tailwind。

Fidelity rules (non-negotiable)

保真度规则(不可妥协)

These are the rules that separate a real clone from a "looks-roughly-similar" approximation:
  1. Exact colors — read from CSS or eyedrop precisely. Never approximate.
  2. Exact spacing — measure pixel gaps in the screenshot or read from computed styles.
    mt-3
    vs
    mt-4
    is a visible difference.
  3. Exact font — if Google Fonts, import the same family + weights. If system font stack, match it.
  4. Exact radius
    rounded-md
    (6px) ≠
    rounded-lg
    (8px). Be precise.
  5. Exact icons — if the source uses Lucide, use Lucide. If Heroicons, use Heroicons. Don't substitute.
  6. No invented content — keep the source's text verbatim unless the user explicitly says to replace it. Lorem ipsum is a code smell here.
  7. Match the layout primitive — if the source uses CSS Grid, don't reimplement with flexbox + nth-child hacks.
以下规则是区分“真实克隆”与“大致相似”近似效果的关键:
  1. 精确颜色 — 从CSS读取或精确取色。绝不近似。
  2. 精确间距 — 测量截图中的像素间距或从计算样式读取。
    mt-3
    mt-4
    的差异是可见的。
  3. 精确字体 — 若为Google Fonts,导入相同字体族 + 字重。若为系统字体栈,完全匹配。
  4. 精确圆角
    rounded-md
    (6px)≠
    rounded-lg
    (8px)。请精确设置。
  5. 精确图标 — 若源使用Lucide,请使用Lucide。若使用Heroicons,请使用Heroicons。请勿替换。
  6. 不编造内容 — 严格保留源文本,除非用户明确要求替换。此处使用Lorem ipsum是不良实践。
  7. 匹配布局原语 — 若源使用CSS Grid,请勿用flexbox + nth-child技巧重新实现。

Anti-patterns (from prior cloning failures)

反模式(来自过往克隆失败案例)

  • ❌ "Close enough" colors — pick a color picker and copy hex
  • ❌ Skipping the responsive viewports — always implement all breakpoints, not just desktop
  • ❌ Inferring content from context — copy the actual text, don't summarize
  • ❌ Using only the static HTML when JS-rendered DOM is available — the JS version is the truth
  • ❌ Refactoring "while you're there" — clone first, refactor in a separate pass

  • ❌ “差不多”的颜色——使用取色器复制十六进制值
  • ❌ 跳过响应式视口——始终实现所有断点,而非仅桌面端
  • ❌ 从上下文推断内容——复制真实文本,请勿总结
  • ❌ 仅使用静态HTML而忽略JS渲染DOM——JS版本才是真相
  • ❌ 边克隆边“重构”——先完成克隆,再单独进行重构

Phase 5 — Verify

阶段5 — 验证

After implementing, don't claim done yet. Verify in two passes:
实现完成后,请勿立即声称完成。请通过两轮验证:

Pass A — Visual diff

A轮 — 视觉对比

Preferred (Tier A): MCP-driven diff loop. If Chrome DevTools MCP is available and the user has a working dev server (
npm run dev
/
pnpm dev
), use
take_screenshot
against the local URL at each viewport, then compare visually against the source screenshot you captured earlier. This is the closest thing to an automated regression diff.
Fallback (Tier B+): manual side-by-side. Open the cloned page in a browser, place it next to the source screenshot, and look for:
  • Color drift (your blue vs their blue)
  • Spacing drift (4px difference in padding adds up)
  • Font weight mismatch (
    font-medium
    vs
    font-semibold
    is visible)
  • Layout drift (alignment, gap, wrap)
  • Missing states (hover doesn't change, focus ring missing)
For multi-viewport clones, resize the browser to each breakpoint and verify all of them — not just the one that's currently open. With MCP, this is
take_screenshot
at each width; without, it's manual resize.
首选(A层级):MCP驱动的对比循环。若Chrome DevTools MCP可用且用户有运行中的开发服务器(
npm run dev
/
pnpm dev
),请对本地URL的每个视口调用
take_screenshot
,然后与之前捕获的源截图进行视觉对比。这是最接近自动化回归对比的方式。
备选(B+层级):手动并排对比。在浏览器中打开克隆页面,将其与源截图并排,检查以下内容:
  • 颜色偏差(你的蓝色与源蓝色)
  • 间距偏差(4px的内边距差异会累积)
  • 字体字重不匹配(
    font-medium
    font-semibold
    差异可见)
  • 布局偏差(对齐、间距、换行)
  • 缺失状态(hover无变化、焦点环缺失)
针对多视口克隆,请将浏览器调整至每个断点并逐一验证——而非仅验证当前打开的视口。使用MCP时,可在每个宽度调用
take_screenshot
;无MCP时,手动调整浏览器尺寸。

Pass B — Drift list

B轮 — 偏差列表

Produce a written list:
Drift detected:
- Hero headline: source 56px, mine 48px → bump font-size
- CTA button: source has 12px shadow blur, mine has 4px → adjust shadow
- Card grid: source has 24px gap, mine has 32px → reduce gap
- Mobile nav: source slides in from right, mine fades → change transition

No drift detected on:
- Color palette
- Typography family
- Footer layout
If the list has > 0 items in "drift detected" → loop back to Phase 4 and fix. Do not declare done with known drifts.

生成书面列表:
检测到的偏差:
- Hero标题:源为56px,我的实现为48px → 增大字号
- CTA按钮:源阴影模糊为12px,我的实现为4px → 调整阴影
- 卡片网格:源间距为24px,我的实现为32px → 减小间距
- 移动端导航:源从右侧滑入,我的实现为淡入 → 修改过渡效果

未检测到偏差的内容:
- 调色板
- 字体族
- 页脚布局
若“检测到的偏差”列表中有>0项 → 返回阶段4进行修复。请勿在已知存在偏差的情况下声称完成

Phase 6 — Polish

阶段6 — 优化

Last 10% — the bits that distinguish "implemented" from "shipped":
  • Hover transitions match the source's easing + duration
  • Focus rings are visible and accessible
  • Touch targets ≥ 44px on mobile
  • prefers-reduced-motion
    respects (if source has motion)
  • Dark mode handling (if source supports it and user's stack does)
  • Image
    alt
    attributes (don't leave
    alt=""
    on meaningful imagery)
  • <title>
    and meta tags if cloning a full page

最后10%的工作——区分“已实现”与“可交付”的细节:
  • Hover过渡效果匹配源的缓动函数 + 时长
  • 焦点环可见且符合无障碍标准
  • 移动端触摸目标≥44px
  • 尊重
    prefers-reduced-motion
    (若源有动画效果)
  • 暗黑模式处理(若源支持且用户技术栈支持)
  • 图片
    alt
    属性(有意义的图片请勿留空
    alt=""
  • 若克隆完整页面,添加
    <title>
    和元标签

Output expectations

输出预期

When you finish, hand the user:
  1. List of files created/modified with paths
  2. Drift list from Phase 5 showing what was checked and what's clean
  3. Known limitations (e.g. "couldn't match the parallax effect — needs a JS library the project doesn't have")
  4. Suggested next steps if any (e.g. "you may want to extract the button styles into a reusable component once you have 2-3 instances")
Don't claim "pixel-perfect" unless you've actually verified pixel-level parity. "Close visual match" is honest; "pixel-perfect" requires receipts.

完成后,请向用户提供:
  1. 创建/修改的文件列表及路径
  2. 阶段5的偏差列表,说明已检查内容及无偏差内容
  3. 已知限制(如“无法匹配视差效果——需要项目中未包含的JS库”)
  4. 建议后续步骤(如“当你有2-3个按钮实例时,可考虑将按钮样式提取为可复用组件”)
除非已实际验证像素级匹配,否则请勿声称“像素级完美”。“高度视觉匹配”是诚实的表述;“像素级完美”需要验证依据。

Quick reference: tooling map

工具速查

NeedPreferred (Tier A)Fallback (Tier B+)
Capture live URL
take_screenshot
+
take_snapshot
(Chrome DevTools MCP)
WebFetch
(text only)
Read user-provided screenshot
Read
(image rendering)
Read raw HTML/CSS
Read
Find files in user's project
Glob
Search for existing components/styles
Grep
Run dev server for visual verification
Bash
(e.g.
pnpm dev
)
Diff cloned output vs source
take_screenshot
of local + visual compare
Manual side-by-side in browser
The Chrome DevTools MCP path is the difference between "looks roughly like the brand" and "matches the live page". When it's not available and the user asks for a live URL clone, surface that limitation early — don't bury it in NOTES.md after the fact.
需求首选(A层级)备选(B+层级)
捕获在线URL
take_screenshot
+
take_snapshot
(Chrome DevTools MCP)
WebFetch
(仅文本)
读取用户提供的截图
Read
(图片渲染)
读取原始HTML/CSS
Read
查找用户项目中的文件
Glob
搜索现有组件/样式
Grep
运行开发服务器进行视觉验证
Bash
(如
pnpm dev
对比克隆输出与源对本地页面调用
take_screenshot
并进行视觉对比
在浏览器中手动并排对比
Chrome DevTools MCP方案是“大致符合品牌风格”与“匹配在线页面”的区别所在。当该方案不可用且用户要求克隆在线URL时,请提前告知此限制——请勿在完成后将其隐藏在NOTES.md中。

Setup: installing Chrome DevTools MCP

设置:安装Chrome DevTools MCP

If the user asks how to enable the higher-fidelity path, share these steps:
  1. Edit
    ~/.claude/settings.json
    (Mac/Linux) or
    C:\Users\<name>\.claude\settings.json
    (Windows). Add to the
    mcpServers
    block:
    json
    {
      "mcpServers": {
        "chrome-devtools": {
          "command": "npx",
          "args": ["-y", "chrome-devtools-mcp@latest"]
        }
      }
    }
  2. Restart Claude Code so the MCP server loads.
  3. Verify with a probe: ask the agent to call
    take_screenshot
    against any URL — if it works, you're set.
Or run the bundled setup script:
~/.claude/skills/sw-clone/scripts/install-chrome-devtools-mcp.ps1
(Windows) /
.sh
(Unix). The script appends the config without overwriting existing
mcpServers
entries.
若用户询问如何启用高保真度方案,请分享以下步骤:
  1. 编辑
    ~/.claude/settings.json
    (Mac/Linux)或
    C:\Users\<name>\.claude\settings.json
    (Windows)。在
    mcpServers
    块中添加:
    json
    {
      "mcpServers": {
        "chrome-devtools": {
          "command": "npx",
          "args": ["-y", "chrome-devtools-mcp@latest"]
        }
      }
    }
  2. 重启Claude Code以加载MCP服务器。
  3. 通过探测验证:请求代理对任意URL调用
    take_screenshot
    ——若成功,则设置完成。
或运行捆绑的安装脚本:
~/.claude/skills/sw-clone/scripts/install-chrome-devtools-mcp.ps1
(Windows)/
.sh
(Unix)。该脚本会追加配置,不会覆盖现有
mcpServers
条目。