关于 clonecn
clonecn 是用于创建和编辑 shadcn/ui 主题的 Skill,可根据截图、网址、应用名称或风格描述生成主题,并支持预览后调整。
主要功能
- 01根据视觉参考生成主题
- 02提供六种 shadcn/ui 风格
- 03生成明暗模式 CSS 变量
- 04支持额外 CSS 样式
- 05预览并检查截图
适用场景
- 01依据网站截图制定主题
- 02根据网址或应用名称生成主题
- 03按风格描述创建主题
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ hunvreus/ clonecn --skill clonecn安装后在 Claude Code 中输入/clonecn确认已加载。
附带文件agents/openai.yaml
详细介绍
clonecn - shadcn/ui 主题生成器
使用此技能创建或编辑 shadcn/ui 主题资源(包括 Vega 或 Nova 等风格系列、CSS 变量和额外 CSS 样式),可基于现有网站/应用,也可根据整体风格方向生成(例如“生成一个仿照 Apple 网站的主题”“创建一个以橙色为强调色的粗野主义主题”)。
输入
- 要仿照的网站/应用截图
- 要仿照的网站/应用 URL(例如“apple.com”)
- 要仿照的网站/应用名称(例如“Apple 网站”)
- 整体风格方向(例如“以橙色为强调色的粗野主义网站”)
如果用户提供了 URL 或网站/应用名称:
- 如果你了解该网站/应用,请描述其风格。
- 获取该网站/应用的截图,可以通过网络搜索,也可以在 Playwright 可用时使用它(见下方“Playwright”)。务必尝试获取浅色和深色模式的截图。
- 如果 Playwright 可用,使用它获取关键控件(按钮、输入框、卡片、表面等)的计算后 CSS 样式(见下方“Playwright”)。
如果用户没有提供任何内容,请向其说明可提供哪些输入,并请其提供一项。
Playwright
要使用 Playwright,请检查环境中是否可用。在实际可行时,优先通过 pnpm dlx playwright@latest ... 临时使用 Playwright CLI,因为这样无需将 Playwright 添加为工作区依赖项。
使用 --color-scheme 获取浅色和深色模式,并使用 --full-page 获取整页截图。
例如:
pnpm dlx playwright@latest install chromium
pnpm dlx playwright@latest screenshot --full-page --color-scheme light https://playbooks.com .output/playbooks-light.png
pnpm dlx playwright@latest screenshot --full-page --color-scheme dark https://playbooks.com .output/playbooks-dark.png
如果临时使用 CLI 不可行,且任务明显适合使用 Playwright,则在工作区中安装它。如果用户提供了截图,则无需使用 Playwright。
工作流
- 设计参考。根据用户输入(截图、描述、URL 等),尝试确定设计参考:颜色(主色、次色、强调色、背景色、前景色等)、间距、风格(例如粗野主义、扁平化、拟物化、极简主义等)。
- 定义 shadcn/ui 主题。生成与设计参考尽可能匹配的 shadcn/ui 主题(详情请参阅“shadcn/ui 主题设计”)。
- 先选择最符合截图的风格系列(Vega、Nova、Maia、Lyra、Mira 或 Luma)。
- 生成彼此独立的深色和浅色 CSS 变量代码块,以匹配设计参考。
- 如果风格系列和 CSS 变量无法匹配设计参考中的关键要素,可考虑添加额外的 CSS 样式(例如背景图案、按钮的特殊样式等)。
- 调整。如果 Playwright 可用,请使用
chrome=0对预览 URL 截图,检查生成的效果并与设计参考进行比较(见下方“预览 URL”)。如有需要,请进行调整。 - 完成。按以下确切顺序返回简洁的结果:
**Summary**: {一行简短的风格总结}- (可选)
**Screenshots**:后附 Playwright 截图(如有浅色和深色模式)。 **Style**: {风格系列}**CSS**:后附包含 CSS 的围栏代码块(含 CSS 变量和额外 CSS,如有)。**Preview**: [在浏览器中打开]({preview URL})(见下方“预览 URL”)。使用主题的最新版本(完成调整后)生成最终预览 URL。不要使用chrome选项。
shadcn/ui 主题设计
shadcn/ui 主题分为 3 个部分:
- 风格系列:Vega、Nova、Maia、Lyra、Mira 或 Luma。
- CSS 变量:包含 CSS 变量的
:root和.dark代码块。 - (可选)额外 CSS:当 CSS 变量和所选风格系列不足以实现所需效果时,可用于覆盖或扩展样式。
样式系列
定义默认形状语言的基线 shadcn/ui 样式,位于主题令牌之下:组件间距、密度、边框处理、默认阴影效果,以及控件的圆润或锐利程度。
根据最接近的设计方向,从以下 6 个选项中选择:
nova:中等圆角,常规密度。按钮采用rounded-lg text-sm(sm/default/lg尺寸分别为h-7/h-8/h-9),输入框采用h-8 rounded-lg。vega:轮廓更硬朗,控件比nova略大。按钮采用rounded-md(sm/default/lg尺寸分别为h-8/h-9/h-10),输入框采用h-9 rounded-md,轮廓控件通常更醒目(某些控件带有shadow-xs)。maia:控件圆角很大,水平内边距宽裕。按钮采用rounded-4xl(sm/default/lg尺寸分别为h-8/h-9/h-10),输入框采用h-9 rounded-4xl。lyra:方角、紧凑间距、较小字号、更精细的环形描边。按钮采用rounded-none text-xs ring-1(sm/default/lg尺寸分别为h-7/h-8/h-9),输入框采用h-8 rounded-none text-xs ring-1。mira:间距最紧凑,控件轮廓最小。按钮采用text-xs并使用更紧凑的内边距(sm/default/lg尺寸分别为h-6/h-7/h-8),输入框采用h-7 rounded-md。luma:控件圆角很大,表面更柔和、填充感更强,表单控件尺寸更大。按钮采用rounded-4xl并使用更紧凑的内边距(sm/default/lg尺寸分别为h-8/h-9/h-10),输入框采用h-9 rounded-3xl。
注意事项:不要默认选择 luma。只有在参考设计明确呈现多个柔和胶囊形特征时(例如:胶囊按钮 + 高度圆润的表单控件 + 填充感强或柔和的控件表面),才选择 luma。如果风格混合或不明确,优先选择 nova(对于密度更高的企业风格界面,则优先选择 vega)。
CSS 变量(又称主题令牌)
| 令牌 | 控制内容 | 使用位置 |
|---|---|---|
background / foreground | 应用的默认背景色和文本颜色。 | 页面外壳、页面区块和默认文本。 |
card / card-foreground | 突出显示的表面及其内部内容。 | Card、仪表板面板、设置面板。 |
popover / popover-foreground | 浮动表面及其内部内容。 | Popover、DropdownMenu、ContextMenu 和其他覆盖层。 |
primary / primary-foreground | 高强调度操作和品牌表面。 | 默认 Button、选中状态、徽章和活动强调色。 |
secondary / secondary-foreground | 低强调度的填充式操作和辅助表面。 | 次要按钮、次要徽章和辅助 UI。 |
muted / muted-foreground | 微妙的表面和低强调度内容。 | 描述、占位符、空状态、辅助文本和弱化的表面。 |
accent / accent-foreground | 交互式悬停、焦点和活动表面。 | Ghost 按钮、菜单高亮状态、悬停行和选中项。 |
destructive | 破坏性操作和错误强调。 | 破坏性按钮、无效状态和破坏性菜单项。 |
border | 默认边框和分隔线。 | 卡片、菜单、表格、分隔符和布局分隔线。 |
input | 表单控件边框和输入表面样式。 | Input、Textarea、Select 和轮廓样式控件。 |
ring | 焦点环和轮廓。 | 按钮、输入框、复选框、菜单和其他可聚焦控件。 |
chart-1 ... chart-5 | 默认图表调色板。 | 图表和由图表驱动的仪表板区块。 |
sidebar / sidebar-foreground | 侧边栏的基础表面和默认侧边栏文本。 | Sidebar 容器及其默认内容。 |
sidebar-primary / sidebar-primary-foreground | 侧边栏内的高强调度操作。 | 活动项、图标块、徽章和侧边栏 CTA。 |
sidebar-accent / sidebar-accent-foreground | 侧边栏内的悬停和选中状态。 | 侧边栏菜单悬停状态、打开的项和交互式行。 |
sidebar-border | 侧边栏专用边框和分隔线。 | 侧边栏标题、分组和内部分隔线。 |
sidebar-ring | 侧边栏专用焦点环。 | 侧边栏内聚焦的控件。 |
radius | 基础圆角比例。 | 卡片、输入框、按钮、弹出层和派生的 radius-* 令牌。 |
额外 CSS
除了变量之外,也可以使用轻量级 CSS 样式,在能显著提升相似度时尤为如此:
- 纹理和细微噪点,
- 更醒目的边框/轮廓样式,
- 阴影样式
- 按钮立体感或拟物化细节,
- 自定义圆角样式,
- 等等。
字体
应直接在生成的 CSS 中处理字体,让用户无需进行额外设置。
请采用以下模式:
- 在
:root中定义--font-sans和--font-mono。 - 将它们应用于关键区域(例如
body、标题和类代码 UI)。 - 如果需要自定义字体,请通过 CSS
@import使用 Google Fonts(不要使用框架/字体加载器配置)。 - 仅当深色模式下的排版确实不同时,才在
.dark中覆盖字体。
@import url('https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;700&family=IBM+Plex+Mono:wght@400;500;700&display=swap');
:root {
--font-sans: 'Space Grotesk', ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif;
--font-mono: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace;
}
.dark {
/* Optional: only if dark mode needs different font choices */
/* --font-sans: ...; */
/* --font-mono: ...; */
}
body { font-family: var(--font-sans); }
h1, h2, h3 { font-family: var(--font-sans); }
code, pre, kbd, samp { font-family: var(--font-mono); }
指南
- 始终提供深色和浅色主题,除非用户明确要求其他主题。提供主题时,尽量使用参考内容中的浅色和深色主题(例如用户提供的截图、Playwright 截图、CSS);如果无法做到,请根据深色或浅色主题的上下文为每种主题选定具体颜色(例如,深色模式下可能需要为
--primary使用更浅的色调)。 - shadcn/ui 会为组件提供默认样式(边框、圆角、阴影等)。不要假设你要为没有样式的元素添加样式。
- 对于
--radius,使用rem而非px,并保持在合理范围内:0rem至1.25rem(仅在用户明确要求时,硬性上限可放宽至2rem)。 - 对于应呈现扁平外观的组件,避免添加明显的边框;可以考虑禁用 ring 和阴影,并让边框保持透明,除非参考内容清楚地显示了描边。这对按钮和输入框尤其重要。
- 颜色:
- 特别关注关键颜色:
--background和--foreground定义应用的背景和默认文本颜色。--primary/--primary-foreground用于主要按钮或 CTA 的背景和文本。--accent/--accent-foreground用于表格、侧边栏、下拉菜单等的悬停/激活状态。- 其他容易识别的颜色,例如
--sidebar/--sidebar-foreground和--card/--card-foreground,也值得关注,因为它们对应的组件很容易识别。
- 优先使用 OKLCH 颜色。
- 特别关注关键颜色:
- 字体:
- 不要将
--font-sans定义为等宽字体,也不要将--font-mono定义为无衬线字体。 - 根据需要为元素(
body、标题、code等)以及特定组件选择器明确指定字体。例如,如果页面上的所有元素都使用等宽字体,按钮除外(按钮可以使用无衬线字体),可以使用body { @apply font-mono; }和.cn-button { @apply font-sans }。 - 仅当深色模式的字体排版与浅色模式不同时,才在
.dark中覆盖字体变量。 - 如果需要衬线字体,请定义
--font-serif,并像使用--font-mono和--font-sans一样使用它。 - 对于自定义字体,仅使用 Google Fonts,并通过 CSS
@import url('https://fonts.googleapis.com/...&display=swap')加载。不要要求额外设置(next/font、npm 字体包、本地字体文件、手动编辑 HTML)。 - 保留默认字体栈:在
--font-sans中保留默认无衬线字体回退,在--font-mono中保留默认等宽字体回退。 - 不要列出每个
cn-*类。仅在能显著提升相似度时,包含影响较大的选择器(例如.cn-button、.cn-input、.cn-textarea、.cn-select-trigger、.cn-native-select、.cn-kbd)。 - 有关如何使用字体的更多详情,请参阅上文“字体”。
- 不要将
- 按钮:
- 按钮具有以下类:
cn-button group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-all outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0- 应用于
cn-button的组件默认样式(nova):focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-medium focus-visible:ring-3 aria-invalid:ring-3 active:not-aria-[haspopup]:translate-y-px [&_svg:not([class*='size-'])]:size-4 - 变体和尺寸类
- 如果按钮使用渐变,请确保
bg-clip-padding、边框颜色和 box-shadow 不会在按钮周围形成光晕。 - 分别评估
default、secondary、outline和ghost。 - 如果参考内容具有更鲜明的产品界面风格,请直接覆盖
.cn-button类。
- 按钮具有以下类:
- 输入框:
- 输入框具有以下类:
cn-input w-full min-w-0 outline-none file:inline-flex file:border-0 file:bg-transparent file:text-foreground placeholder:text-muted-foreground disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50- 应用于
cn-input的组件默认样式(nova):dark:bg-input/30 border-input focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 disabled:bg-input/50 dark:disabled:bg-input/80 h-8 rounded-lg border bg-transparent px-2.5 py-1 text-base transition-colors file:h-6 file:text-sm file:font-medium focus-visible:ring-3 aria-invalid:ring-3 md:text-sm
- 如果参考内容具有更鲜明的产品界面风格,不要只调整
--input;请直接覆盖相关的.cn-input、.cn-textarea、.cn-select-trigger和.cn-native-select类。
- 输入框具有以下类:
示例
:root {
--background: oklch(0.9818 0.0054 95.0986);
--foreground: oklch(0.3438 0.0269 95.7226);
--card: oklch(0.9818 0.0054 95.0986);
--card-foreground: oklch(0.1908 0.002 106.5859);
--popover: oklch(1 0 0);
--popover-foreground: oklch(0.2671 0.0196 98.939);
--primary: oklch(0.6171 0.1375 39.0427);
--primary-foreground: oklch(1 0 0);
--secondary: oklch(0.9245 0.0138 92.9892);
--secondary-foreground: oklch(0.4334 0.0177 98.6048);
--muted: oklch(0.9341 0.0153 90.239);
--muted-foreground: oklch(0.6059 0.0075 97.4233);
--accent: oklch(0.9245 0.0138 92.9892);
--accent-foreground: oklch(0.2671 0.0196 98.939);
--destructive: oklch(0.1908 0.002 106.5859);
--destructive-foreground: oklch(1 0 0);
--border: oklch(0.8847 0.0069 97.3627);
--input: oklch(0.7621 0.0156 98.3528);
--ring: oklch(0.6171 0.1375 39.0427);
--chart-1: oklch(0.5583 0.1276 42.9956);
--chart-2: oklch(0.6898 0.1581 290.4107);
--chart-3: oklch(0.8816 0.0276 93.128);
--chart-4: oklch(0.8822 0.0403 298.1792);
--chart-5: oklch(0.5608 0.1348 42.0584);
--sidebar: oklch(0.9663 0.008 98.8792);
--sidebar-foreground: oklch(0.359 0.0051 106.6524);
--sidebar-primary: oklch(0.6171 0.1375 39.0427);
--sidebar-primary-foreground: oklch(0.9881 0 0);
--sidebar-accent: oklch(0.9245 0.0138 92.9892);
--sidebar-accent-foreground: oklch(0.325 0 0);
--sidebar-border: oklch(0.9401 0 0);
--sidebar-ring: oklch(0.7731 0 0);
--font-sans:
ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI',
Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif,
'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
--font-serif: ui-serif, Georgia, Cambria, 'Times New Roman', Times, serif;
--font-mono:
ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono',
'Courier New', monospace;
--radius: 0.5rem;
--shadow-x: 0;
--shadow-y: 1px;
--shadow-blur: 3px;
--shadow-spread: 0px;
--shadow-opacity: 0.1;
--shadow-color: oklch(0 0 0);
--shadow-2xs: 0 1px 3px 0px hsl(0 0% 0% / 0.05);
--shadow-xs: 0 1px 3px 0px hsl(0 0% 0% / 0.05);
--shadow-sm:
0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 1px 2px -1px hsl(0 0% 0% / 0.1);
--shadow: 0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 1px 2px -1px hsl(0 0% 0% / 0.1);
--shadow-md:
0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 2px 4px -1px hsl(0 0% 0% / 0.1);
--shadow-lg:
0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 4px 6px -1px hsl(0 0% 0% / 0.1);
--shadow-xl:
0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 8px 10px -1px hsl(0 0% 0% / 0.1);
--shadow-2xl: 0 1px 3px 0px hsl(0 0% 0% / 0.25);
--tracking-normal: 0em;
--spacing: 0.25rem;
}
.dark {
--background: oklch(0.2679 0.0036 106.6427);
--foreground: oklch(0.8074 0.0142 93.0137);
--card: oklch(0.2679 0.0036 106.6427);
--card-foreground: oklch(0.9818 0.0054 95.0986);
--popover: oklch(0.3085 0.0035 106.6039);
--popover-foreground: oklch(0.9211 0.004 106.4781);
--primary: oklch(0.6724 0.1308 38.7559);
--primary-foreground: oklch(1 0 0);
--secondary: oklch(0.9818 0.0054 95.0986);
--secondary-foreground: oklch(0.3085 0.0035 106.6039);
--muted: oklch(0.2213 0.0038 106.707);
--muted-foreground: oklch(0.7713 0.0169 99.0657);
--accent: oklch(0.213 0.0078 95.4245);
--accent-foreground: oklch(0.9663 0.008 98.8792);
--destructive: oklch(0.6368 0.2078 25.3313);
--destructive-foreground: oklch(1 0 0);
--border: oklch(0.3618 0.0101 106.8928);
--input: oklch(0.4336 0.0113 100.2195);
--ring: oklch(0.6724 0.1308 38.7559);
--chart-1: oklch(0.5583 0.1276 42.9956);
--chart-2: oklch(0.6898 0.1581 290.4107);
--chart-3: oklch(0.213 0.0078 95.4245);
--chart-4: oklch(0.3074 0.0516 289.323);
--chart-5: oklch(0.5608 0.1348 42.0584);
--sidebar: oklch(0.2357 0.0024 67.7077);
--sidebar-foreground: oklch(0.8074 0.0142 93.0137);
--sidebar-primary: oklch(0.325 0 0);
--sidebar-primary-foreground: oklch(0.9881 0 0);
--sidebar-accent: oklch(0.168 0.002 106.6177);
--sidebar-accent-foreground: oklch(0.8074 0.0142 93.0137);
--sidebar-border: oklch(0.9401 0 0);
--sidebar-ring: oklch(0.7731 0 0);
--font-sans:
ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI',
Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif,
'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
--font-serif: ui-serif, Georgia, Cambria, 'Times New Roman', Times, serif;
--font-mono:
ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono',
'Courier New', monospace;
--radius: 0.5rem;
--shadow-x: 0;
--shadow-y: 1px;
--shadow-blur: 3px;
--shadow-spread: 0px;
--shadow-opacity: 0.1;
--shadow-color: oklch(0 0 0);
--shadow-2xs: 0 1px 3px 0px hsl(0 0% 0% / 0.05);
--shadow-xs: 0 1px 3px 0px hsl(0 0% 0% / 0.05);
--shadow-sm:
0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 1px 2px -1px hsl(0 0% 0% / 0.1);
--shadow: 0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 1px 2px -1px hsl(0 0% 0% / 0.1);
--shadow-md:
0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 2px 4px -1px hsl(0 0% 0% / 0.1);
--shadow-lg:
0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 4px 6px -1px hsl(0 0% 0% / 0.1);
--shadow-xl:
0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 8px 10px -1px hsl(0 0% 0% / 0.1);
--shadow-2xl: 0 1px 3px 0px hsl(0 0% 0% / 0.25);
}
预览 URL
预览 URL 应将完整的原始 CSS 字符串(以 Base64URL 编码的 UTF-8)编码到 URL 哈希中,并包含 mode 和 style。还可以添加用于预览界面元素的查询参数:chrome=0|1(0 隐藏页眉/边框,1 显示页眉/边框)。示例:https://clonecn.com/?chrome=0#css={encoded CSS}&mode=light|dark&style=nova|vega|maia|lyra|mira|luma。
使用 scripts/encode.js 生成预览 URL:
node scripts/encode.js --css ./theme.css --mode dark --style vega --chrome 0
参数:
--css <path>:要编码的 CSS 源文件路径(应包含完整的:root块、完整的.dark块以及任何额外的 CSS 覆盖样式)。默认值:./theme.css。--mode <light|dark>:URL 哈希中的初始预览模式。默认值:dark。--style <nova|vega|maia|lyra|mira|luma>:URL 哈希中的样式系列。默认值:vega。--chrome <0|1>:URL 查询参数中的预览界面元素(0隐藏页眉/边框,1显示页眉/边框)。默认值:1。仅在调整步骤中使用,不要用于输出。--origin <url>:预览应用的源地址。默认值:https://clonecn.com。