clonecn

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

clonecn - shadcn/ui Theme Generator

clonecn - shadcn/ui 主题生成器

Use this skill to create or edit assets for a shadcn/ui theme (style family like Vega or Nova, CSS variables, and extra CSS styles) either from an existing site/app, or from a general style direction (e.g. "Generate a theme resembling the Apple website", "Create a brutalist theme with orange as the accent color").
使用此技能从现有网站/应用,或从通用风格方向(例如“生成类似苹果官网的主题”、“创建以橙色为强调色的粗野主义主题”)创建或编辑shadcn/ui主题资源(包括Vega或Nova等风格系列、CSS变量以及额外CSS样式)。

Inputs

输入

  • Screenshots of the site/app to copy
  • URL of the site/app to copy (e.g. "apple.com")
  • Site/app name to copy (e.g. "Apple website")
  • General style direction (e.g. "brutalist website with orange as an accent color")
If the user provided a URL or site/app name:
  • If you know the site/app, create a description of the style.
  • Retrieve screenshots of the site/app, either through web search or using Playwright if available (see "Playwright" below). Always try to retrieve both light and dark modes.
  • Retrieve computed CSS styles for key controls (button, input, card, surface, etc) using Playwright if available (see "Playwright" below).
If the user hasn't provided anything, explain to him what the possible inputs are and ask him to provide one.
  • 要复刻的网站/应用截图
  • 要复刻的网站/应用网址(例如 "apple.com")
  • 要复刻的网站/应用名称(例如 "Apple website")
  • 通用风格方向(例如 "以橙色为强调色的粗野主义网站")
如果用户提供了网址或网站/应用名称:
  • 如果你了解该网站/应用,创建一份风格描述。
  • 获取该网站/应用的截图,可以通过网页搜索或使用Playwright(如果可用,详见下方“Playwright”部分)。务必尝试获取浅色和深色两种模式的截图。
  • 如果Playwright可用,获取关键控件(按钮、输入框、卡片、表层等)的计算后CSS样式(详见下方“Playwright”部分)。
如果用户未提供任何内容,向其说明可能的输入类型并请求提供相关信息。

Playwright

Playwright

To use Playwright, check if it is available in the environment. Prefer ad hoc Playwright CLI usage via
pnpm dlx playwright@latest ...
when that is practical, because it avoids adding Playwright to the workspace dependencies.
Use
--color-scheme
to get both light and dark modes, and
--full-page
to get the entire page.
For example:
bash
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
If ad hoc CLI usage is not practical and the task clearly benefits from Playwright, then install it in the workspace. If the user provided a screenshot, you do not need it.
要使用Playwright,请检查环境中是否已安装。如果可行,优先通过
pnpm dlx playwright@latest ...
临时使用Playwright CLI,因为这样可以避免将Playwright添加到工作区依赖中。
使用
--color-scheme
参数获取浅色和深色模式,使用
--full-page
参数获取完整页面截图。
示例:
bash
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。

Workflow

工作流程

  1. Design reference. Based on user input (screenshots, description, URLs, etc), try to define the design reference: colors (primary, secondary, accent, background, foreground, etc), spacing, style (e.g. brutalist, flat, skeuomorphic, minimalist,...), etc.
  2. Define shadcn/ui theme. Generate a shadcn/ui theme that matches the design reference as closely as possible (for more details see "shadcn/ui theming"):
  3. Pick a style family first (Vega, Nova, Maia, Lyra, Mira or Luma) that most closely match the screenshot.
  4. Generate distinct dark and light blocks of CSS variables to match the design reference.
  5. If crucial aspects of the design reference cannot be matched with the style family and CSS variables, consider adding additional CSS styles (e.g. background patterns, special treatment on buttons, etc).
  6. Adjust. If playwright is available, check the generated output by making a screenshot of the preview URL with
    chrome=0
    (see "Preview URL" below) and compare it to the design reference. Make adjustments if needed.
  7. Finalize. Return a concise output (in this exact order):
  • **Summary**: {one short style summary}
  • (Optional)
    **Screenshots**:
    followed by the Playwright screenshots (light and dark modes) if any.
  • **Style**: {style family}
  • **CSS**:
    followed by a fenced code block with the CSS (both CSS variables and extra CSS if any).
  • **Preview**: [Open in your browser]({preview URL})
    (see "Preview URL" below). Generate a final version of the preview URL with the LATEST version of the theme (after adjustments). Do NOT use the
    chrome
    option.
  1. 设计参考。根据用户输入(截图、描述、网址等),尝试定义设计参考:颜色(主色、辅助色、强调色、背景色、前景色等)、间距、风格(例如粗野主义、扁平化、拟物化、极简主义等)等。
  2. 定义shadcn/ui主题。生成尽可能匹配设计参考的shadcn/ui主题(更多细节见“shadcn/ui主题定制”):
  3. 首先选择一个与截图最匹配的风格系列(Vega、Nova、Maia、Lyra、Mira或Luma)。
  4. 生成匹配设计参考的浅色和深色模式CSS变量块。
  5. 如果设计参考的关键部分无法通过风格系列和CSS变量匹配,考虑添加额外的CSS样式(例如背景图案、按钮的特殊处理等)。
  6. 调整。如果Playwright可用,通过使用
    chrome=0
    参数(详见下方“预览网址”)截取预览网址的截图,并与设计参考进行比较。如有需要,进行调整。
  7. 定稿。按以下精确顺序返回简洁的输出:
  • **摘要**: {简短风格总结}
    -(可选)
    **截图**: 
    后跟Playwright截取的截图(浅色和深色模式,如果有的话)。
  • **风格**: {风格系列}
  • **CSS**: 
    后跟包含CSS的代码块(包括CSS变量和额外CSS,如果有的话)。
  • **预览**: [在浏览器中打开]({预览网址})
    (详见下方“预览网址”)。生成包含最新版本主题(调整后)的最终预览网址。请勿使用
    chrome
    选项。

shadcn/ui theming

shadcn/ui主题定制

shadcn/ui themes are broken down in 3 parts:
  • Style family: Vega, Nova, Maia, Lyra, Mira or Luma.
  • CSS variables:
    :root
    and
    .dark
    blocks of CSS variables.
  • (Optional) Extra CSS: useful to override or extend styles when CSS variables and the selected style family are not enough.
shadcn/ui主题分为三部分:
  • 风格系列:Vega、Nova、Maia、Lyra、Mira或Luma。
  • CSS变量:
    :root
    .dark
    块中的CSS变量。 -(可选)额外CSS:当CSS变量和所选风格系列不足以满足需求时,用于覆盖或扩展样式。

Style families

风格系列

Baseline shadcn/ui styles that define the default shape language that sits underneath your theme tokens: component spacing, density, border treatment, default shadow behavior, and how rounded or sharp controls feel.
Pick one of the following 6 options based on what is closest to the design direction:
  • nova
    : medium rounding, regular density. Buttons are
    rounded-lg text-sm
    (
    h-7
    /
    h-8
    /
    h-9
    for
    sm
    /
    default
    /
    lg
    sizes), inputs are
    h-8 rounded-lg
    .
  • vega
    : firmer outlines and slightly larger controls than
    nova
    . Buttons are
    rounded-md
    (
    h-8
    /
    h-9
    /
    h-10
    for
    sm
    /
    default
    /
    lg
    sizes), inputs are
    h-9 rounded-md
    , outline controls often feel more pronounced (
    shadow-xs
    on some controls).
  • maia
    : very rounded controls, generous horizontal padding. Buttons are
    rounded-4xl
    (
    h-8
    /
    h-9
    /
    h-10
    for
    sm
    /
    default
    /
    lg
    sizes), inputs are
    h-9 rounded-4xl
    .
  • lyra
    : square corners, compact spacing, smaller typography, finer rings. Buttons are
    rounded-none text-xs ring-1
    (
    h-7
    /
    h-8
    /
    h-9
    for
    sm
    /
    default
    /
    lg
    sizes), inputs are
    h-8 rounded-none text-xs ring-1
    .
  • mira
    : tightest spacing, smallest control profile. Buttons are
    text-xs
    and tighter padding (
    h-6
    /
    h-7
    /
    h-8
    for
    sm
    /
    default
    /
    lg
    sizes), inputs are
    h-7 rounded-md
    .
  • luma
    : very rounded controls, softer/fill-heavy surfaces, larger form controls. Buttons are
    rounded-4xl
    and tighter padding (
    h-8
    /
    h-9
    /
    h-10
    for
    sm
    /
    default
    /
    lg
    sizes), inputs are
    h-9 rounded-3xl
    .
Guardrail: do not default to
luma
. Pick
luma
only when the reference clearly shows multiple soft-pill signals (e.g. pill buttons + highly rounded form controls + filled/soft control surfaces). If mixed/unclear, prefer
nova
(or
vega
for denser enterprise chrome).
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 variables (aka theme tokens)

CSS变量(又称主题令牌)

TokenWhat it controlsUsed by
background
/
foreground
The default app background and text color.The page shell, page sections, and default text.
card
/
card-foreground
Elevated surfaces and the content inside them.
Card
, dashboard panels, settings panels.
popover
/
popover-foreground
Floating surfaces and the content inside them.
Popover
,
DropdownMenu
,
ContextMenu
, and other overlays.
primary
/
primary-foreground
High-emphasis actions and brand surfaces.Default
Button
, selected states, badges, and active accents.
secondary
/
secondary-foreground
Lower-emphasis filled actions and supporting surfaces.Secondary buttons, secondary badges, and supporting UI.
muted
/
muted-foreground
Subtle surfaces and lower-emphasis content.Descriptions, placeholders, empty states, helper text, and subdued surfaces.
accent
/
accent-foreground
Interactive hover, focus, and active surfaces.Ghost buttons, menu highlight states, hovered rows, and selected items.
destructive
Destructive actions and error emphasis.Destructive buttons, invalid states, and destructive menu items.
border
Default borders and separators.Cards, menus, tables, separators, and layout dividers.
input
Form control borders and input surface treatment.
Input
,
Textarea
,
Select
, and outline-style controls.
ring
Focus rings and outlines.Buttons, inputs, checkboxes, menus, and other focusable controls.
chart-1
...
chart-5
The default chart palette.Charts and chart-driven dashboard blocks.
sidebar
/
sidebar-foreground
The base sidebar surface and default sidebar text.The
Sidebar
container and its default content.
sidebar-primary
/
sidebar-primary-foreground
High-emphasis actions inside the sidebar.Active items, icon tiles, badges, and sidebar CTAs.
sidebar-accent
/
sidebar-accent-foreground
Hover and selected states inside the sidebar.Sidebar menu hover states, open items, and interactive rows.
sidebar-border
Sidebar-specific borders and separators.Sidebar headers, groups, and internal dividers.
sidebar-ring
Sidebar-specific focus rings.Focused controls inside the sidebar.
radius
The base corner radius scale.Cards, inputs, buttons, popovers, and the derived
radius-*
tokens.
令牌控制内容适用组件
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
交互式悬停、聚焦和活动状态表层。幽灵按钮、菜单高亮状态、悬停行和选中项。
destructive
破坏性动作和错误强调。破坏性按钮、无效状态和破坏性菜单项。
border
默认边框和分隔线。卡片、菜单、表格、分隔线和布局分隔符。
input
表单控件边框和输入表层处理。
Input
Textarea
Select
和轮廓样式控件。
ring
聚焦边框和轮廓。按钮、输入框、复选框、菜单和其他可聚焦控件。
chart-1
...
chart-5
默认图表调色板。图表和基于图表的仪表板区块。
sidebar
/
sidebar-foreground
侧边栏基础表层和默认侧边栏文本。
Sidebar
容器及其默认内容。
sidebar-primary
/
sidebar-primary-foreground
侧边栏内的高强调动作。活动项、图标 tiles、徽章和侧边栏CTA。
sidebar-accent
/
sidebar-accent-foreground
侧边栏内的悬停和选中状态。侧边栏菜单悬停状态、展开项和交互式行。
sidebar-border
侧边栏专用边框和分隔线。侧边栏标题、分组和内部分隔符。
sidebar-ring
侧边栏专用聚焦边框。侧边栏内的聚焦控件。
radius
基础圆角比例。卡片、输入框、按钮、弹出框,以及派生的
radius-*
令牌。

Extra CSS

额外CSS

Allow lightweight CSS treatment beyond vars when it materially improves resemblance:
  • Textures and subtle noise,
  • Stronger borders/outline language,
  • Shadow style
  • Button depth or skeuomorphic hints,
  • Custom radius language,
  • Etc.
当CSS变量和风格系列无法充分匹配设计时,允许添加轻量级CSS处理:
  • 纹理和细微噪点,
  • 更粗的边框/轮廓样式,
  • 阴影样式
  • 按钮深度或拟物化提示,
  • 自定义圆角样式,
  • 等等。

Fonts

字体

Fonts should be handled directly in the generated CSS so users need zero extra setup.
Use this pattern:
  1. Define
    --font-sans
    and
    --font-mono
    in
    :root
    .
  2. Assign them to crucial areas (e.g.
    body
    , headings, and code-like UI).
  3. If custom fonts are needed, use Google Fonts via CSS
    @import
    (not framework/font-loader setup).
  4. Override fonts in
    .dark
    only when dark mode typography actually differs.
css
@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); }
字体应直接在生成的CSS中处理,以便用户无需额外设置。
使用以下模式:
  1. :root
    中定义
    --font-sans
    --font-mono
  2. 将它们分配给关键区域(例如
    body
    、标题和类代码UI)。
  3. 如果需要自定义字体,使用通过CSS
    @import
    引入的Google Fonts
    (而非框架/字体加载器设置)。
  4. 仅当深色模式排版确实不同时,才在
    .dark
    中覆盖字体。
css
@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 {
  /* 可选:仅当深色模式需要不同字体时使用 */
  /* --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); }

Guidelines

指南

  • Always provide dark and light themes, unless the user specifically requested otherwise. When doing so, try to use the light and dark themes from the reference (e.g. user provided screenshots, Playwright screenshots, CSS), and if not possible derive specific colors for each theme that take into account the context of the dark or light theme (e.g. you may need a lighter shade for
    --primary
    when in dark mode).
  • shadcn/ui gives components default styles (border, radius, shadow, etc). Do not assume you are styling blank elements.
  • For
    --radius
    , use
    rem
    not
    px
    and keep it in a sane range:
    0rem
    to
    1.25rem
    (hard max
    2rem
    only for explicit user requests).
  • For components that should look flat, avoid adding visible borders; consider disabling ring and shadow, and keep borders transparent unless the reference clearly shows a stroke. This is particularly important for buttons and inputs.
  • Colors:
    • Pay special attention to the key colors:
      • --background
        .
        --foreground
        define the background of the app and default color of the text.
      • --primary
        /
        --primary-foreground
        for the background and text of primary buttons or ctas.
      • --accent
        /
        --accent-foreground
        for the hover/active state for tables, sidebars, dropdown menus, etc.
      • Other colors that may be easy to pick like
        --sidebar
        /
        --sidebar-foreground
        and
        --card
        /
        --card-foreground
        since they're easily identifiable components.
    • Prefer OKLCH colors.
  • Fonts:
    • Do not define
      --font-sans
      as a mono font, or
      --font-mono
      as a sans font.
    • Assign fonts explicitly to elements (
      body
      , headings,
      code
      , etc) as well as component-specific selectors when needed. For example, if all elements on the page are using a mono font, except for the buttons that may use a sans font, we would use
      body { @apply font-mono; }
      and
      .cn-button { @apply font-sans }
      .
    • Only override font vars in
      .dark
      when dark mode typography is different from light mode typography.
    • If a serif font is needed, define
      --font-serif
      and use it in the same way we use
      --font-mono
      and
      --font-sans
      .
    • For custom fonts, use Google Fonts only and load them with CSS
      @import url('https://fonts.googleapis.com/...&display=swap')
      . Do not require extra setup (
      next/font
      , npm font packages, local font files, manual HTML edits).
    • Keep default stacks intact: keep default sans fallbacks in
      --font-sans
      , and default mono fallbacks in
      --font-mono
      .
    • Do not list every
      cn-*
      class. Include only high-impact selectors (e.g.
      .cn-button
      ,
      .cn-input
      ,
      .cn-textarea
      ,
      .cn-select-trigger
      ,
      .cn-native-select
      ,
      .cn-kbd
      ) when they materially improve resemblance.
    • For more details on how to use fonts, see "Fonts" above.
  • Buttons:
    • Buttons have the following classes:
      • 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
      • Component style defaults (nova) applied to
        cn-button
        :
        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
      • variant and size classes
    • If using gradients on buttons, ensure
      bg-clip-padding
      , border color, and box-shadow do not create a halo around the button.
    • Evaluate
      default
      ,
      secondary
      ,
      outline
      , and
      ghost
      separately.
    • If the reference has stronger product chrome, override the
      .cn-button
      class directly.
  • Inputs:
    • Inputs have the following classes:
      • 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
      • Component style defaults (nova) applied to
        cn-input
        :
        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
    • If the reference has stronger product chrome, do not stop at
      --input
      ; override the relevant
      .cn-input
      ,
      .cn-textarea
      ,
      .cn-select-trigger
      , and
      .cn-native-select
      classes directly.
  • 始终提供浅色和深色主题,除非用户明确要求不提供。这样做时,尽量使用参考中的浅色和深色主题(例如用户提供的截图、Playwright截图、CSS),如果无法实现,则根据浅色或深色主题的上下文推导特定颜色(例如在深色模式下,
    --primary
    可能需要更浅的色调)。
  • shadcn/ui为组件提供默认样式(边框、圆角、阴影等)。不要假设你正在为空白元素设置样式。
  • 对于
    --radius
    ,使用
    rem
    而非
    px
    ,并保持在合理范围内:
    0rem
    1.25rem
    (仅在用户明确要求时才使用最大
    2rem
    )。
  • 对于应显示为扁平化的组件,避免添加可见边框;考虑禁用边框和阴影,除非参考明确显示描边,否则保持边框透明。这对于按钮和输入框尤为重要。
  • 颜色:
    • 特别注意关键颜色:
      • --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
      、边框颜色和阴影不会在按钮周围产生光晕。
    • 分别评估
      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
      类。

Example

示例

css
: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);
}
css
: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);
}

Preview URL

预览网址

The preview URL should encode the full raw CSS string (Base64URL-encoded UTF-8) into the URL hash and include
mode
and
style
. It can also include a query param for preview chrome:
chrome=0|1
(
0
hides header/frame,
1
shows it). Example:
https://clonecn.com/?chrome=0#css={encoded CSS}&mode=light|dark&style=nova|vega|maia|lyra|mira|luma
.
Use
scripts/encode.js
to generate the preview URL:
bash
node scripts/encode.js --css ./theme.css --mode dark --style vega --chrome 0
Parameters:
  • --css <path>
    : path to the CSS source file to encode (should include the full
    :root
    block, full
    .dark
    block, and any extra CSS overrides). Default:
    ./theme.css
    .
  • --mode <light|dark>
    : initial preview mode in the URL hash. Default:
    dark
    .
  • --style <nova|vega|maia|lyra|mira|luma>
    : style family in the URL hash. Default:
    vega
    .
  • --chrome <0|1>
    : preview chrome in URL query (
    0
    hides header/frame,
    1
    shows it). Default:
    1
    . Only use in the adjust step, do not use for output.
  • --origin <url>
    : preview app origin. Default:
    https://clonecn.com
    .
预览网址应将完整的原始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
生成预览网址:
bash
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