kitchen-sink-design-system

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Kitchen Sink Design System

Kitchen Sink 设计系统

Build every component for real, wire it into a single sink page, and let the page prove the design system works.
实际构建每个组件,将其接入单个Sink页面,通过该页面验证设计系统的可行性。

Core Philosophy

核心理念

  • Source of truth — The sink page is the canonical reference for design direction. If it's not in the sink, it doesn't exist.
  • No placeholders — Every component rendered on the sink page must be a real, importable module. Never use draft placeholders or TODO stubs.
  • Layered semantics — Every component follows a base + variant architecture. Shared structure in the base, visual differences in the variant layer.
  • Progressive disclosure — Start with core primitives, layer in app-level components, finish with data display. Each tier builds on the last.
  • Design-forward — Define design direction in the sink first; production pages consume what the sink establishes.
  • Agent-readable — The design system should be equally consumable by human developers and AI coding agents. Semantic tokens, typed props, and explicit contracts over implicit conventions.
  • Framework-native — Respect each framework's idioms. Don't impose React conventions on a Hugo project or vice versa.
  • 唯一可信源 — Sink页面是设计方向的权威参考。未在Sink中体现的内容,视为不存在。
  • 无占位符 — Sink页面中渲染的每个组件都必须是可导入的真实模块。禁止使用草稿占位符或TODO存根。
  • 分层语义化 — 每个组件遵循「基础+变体」架构。基础层包含共享结构,变体层处理视觉差异。
  • 渐进式披露 — 从核心基础组件开始,逐步构建应用级组件,最后实现数据展示组件。每个层级都基于上一层级构建。
  • 设计优先 — 先在Sink中定义设计方向;生产页面直接复用Sink中确立的规范。
  • AI Agent 可读 — 设计系统需同时适配人类开发者和AI编码Agent。采用语义化Token、类型化Props,通过显式约定替代隐式规则。
  • 框架原生 — 遵循各框架的惯用写法。不要在Hugo项目中强加React约定,反之亦然。

Phase 0: Detect Stack

阶段0:检测技术栈

Before anything else, identify the project's framework and lock in the implementation strategy. If you cannot see the file tree, stop and request it.
在开始任何工作前,先识别项目的框架并锁定实现策略。若无法查看文件树,请停止并请求获取。

Detection Signals

检测标识

Signal file / directoryFramework
next.config.*
,
app/
or
pages/
Next.js (React)
hugo.toml
,
hugo.yaml
,
layouts/partials/
Hugo
astro.config.*
,
src/components/
Astro
nuxt.config.*
Nuxt (Vue)
svelte.config.*
SvelteKit
None of the aboveStatic HTML/CSS
标识文件/目录框架
next.config.*
,
app/
pages/
Next.js (React)
hugo.toml
,
hugo.yaml
,
layouts/partials/
Hugo
astro.config.*
,
src/components/
Astro
nuxt.config.*
Nuxt (Vue)
svelte.config.*
SvelteKit
以上均不满足静态HTML/CSS

Strategy Table

策略映射表

Once detected, lock in these mappings for the rest of the workflow:
ConceptReact / Next.jsHugoAstroStatic HTML
Component
.tsx
in
components/
.html
partial in
themes/<theme>/layouts/partials/components/
.astro
in
src/components/
Reusable HTML snippet
Component call
<Button variant="primary" />
{{ partial "components/button" (dict ...) }}
<Button variant="primary" />
Copy/paste or
include
Props / paramsReact props (TypeScript)
dict
context
Astro props (TypeScript)CSS classes / data-attrs
Interactivity
useState
, event handlers
Alpine.js
x-data
or
<details>
client:load
+ framework islands
Vanilla JS or Alpine.js
Sink route
app/sink/page.tsx
content/sink/_index.md
+
themes/<theme>/layouts/sink/list.html
src/pages/sink.astro
sink.html
Prod guard
process.env
check → return
null
Config overlay or
hugo.Environment
check
import.meta.env
check
Don't deploy the file
ShortcodesN/A (components serve both roles)
themes/<theme>/layouts/shortcodes/
wrapping partials
Components usable in MDXN/A
Content authorsComponents in MDXShortcodes in markdownComponents in MDX /
.astro
N/A
Utility helper
cn()
via
clsx
+
tailwind-merge
classnames
partial or inline concat
cn()
or
class:list
Inline concat
检测完成后,在后续工作流中严格遵循以下映射关系:
概念React / Next.jsHugoAstro静态HTML
组件
components/
下的
.tsx
文件
themes/<theme>/layouts/partials/components/
下的
.html
局部文件
src/components/
下的
.astro
文件
可复用HTML片段
组件调用
<Button variant="primary" />
{{ partial "components/button" (dict ...) }}
<Button variant="primary" />
复制粘贴或
include
引入
Props / 参数React props (TypeScript)
dict
上下文
Astro props (TypeScript)CSS类 / data属性
交互性
useState
、事件处理器
Alpine.js
x-data
<details>
client:load
+ 框架孤岛
Vanilla JS 或 Alpine.js
Sink路由
app/sink/page.tsx
content/sink/_index.md
+
themes/<theme>/layouts/sink/list.html
src/pages/sink.astro
sink.html
生产环境防护
process.env
校验 → 返回
null
配置覆盖或
hugo.Environment
校验
import.meta.env
校验
不部署该文件
短代码无(组件同时承担两种角色)
themes/<theme>/layouts/shortcodes/
包裹局部文件
可在MDX中使用的组件
内容作者MDX中的组件Markdown中的短代码MDX /
.astro
中的组件
工具函数基于
clsx
+
tailwind-merge
cn()
classnames
局部文件或内联拼接
cn()
class:list
内联拼接

Additional Detection Checks

额外检测项

After identifying the framework, also detect:
  1. CSS approach — Tailwind (which version?), vanilla CSS, CSS modules, Sass, etc.
  2. Icon library — Lucide, Heroicons, inline SVG, icon fonts, Hugo module, etc.
  3. Interactivity layer — Alpine.js, HTMX, vanilla JS, React, Vue, Svelte, none.
  4. CMS — TinaCMS (
    tina/
    ), Decap/Netlify CMS (
    static/admin/
    ), Sanity, Contentful, plain markdown, none.
  5. Existing component patterns — Where do components live? What naming conventions are in use? Is there an existing helper like
    cn()
    ?
Adapt all subsequent phases to what you detected. Do not impose one framework's conventions on another.
识别框架后,还需检测:
  1. CSS方案 — Tailwind(具体版本?)、原生CSS、CSS Modules、Sass等。
  2. 图标库 — Lucide、Heroicons、内联SVG、图标字体、Hugo模块等。
  3. 交互层 — Alpine.js、HTMX、Vanilla JS、React、Vue、Svelte、无。
  4. CMS — TinaCMS (
    tina/
    )、Decap/Netlify CMS (
    static/admin/
    )、Sanity、Contentful、纯Markdown、无。
  5. 现有组件模式 — 组件存放位置?命名规范?是否已有
    cn()
    这类工具函数?
后续所有阶段均需适配检测结果。禁止将某一框架的约定强加给其他框架。

Tailwind Detection

Tailwind 版本检测

Detect which Tailwind version is in use, then read the appropriate source:
  • Tailwind v3 — Read
    tailwind.config.js
    /
    tailwind.config.ts
    for
    theme.extend
    (custom colors, spacing, fonts, breakpoints).
  • Tailwind v4 — No config file required. Read
    globals.css
    ,
    app.css
    , or the project's main CSS entry for
    @theme
    blocks and CSS custom properties (
    --color-*
    ,
    --spacing-*
    ,
    --font-*
    ). Also check for
    @import "tailwindcss"
    as a v4 indicator.
  • Detection heuristic: If
    tailwind.config.*
    exists → v3. If the CSS entry contains
    @theme
    or
    @import "tailwindcss"
    → v4.
  • No Tailwind — Read the project's main CSS for custom properties, Sass variables, or hardcoded values.
检测项目使用的Tailwind版本,然后读取对应来源:
  • Tailwind v3 — 读取
    tailwind.config.js
    /
    tailwind.config.ts
    中的
    theme.extend
    (自定义颜色、间距、字体、断点)。
  • Tailwind v4 — 无需配置文件。读取
    globals.css
    app.css
    或项目主CSS入口中的
    @theme
    块和CSS自定义属性(
    --color-*
    --spacing-*
    --font-*
    )。同时检查是否包含
    @import "tailwindcss"
    作为v4的标识。
  • 检测规则:若存在
    tailwind.config.*
    → v3。若CSS入口包含
    @theme
    @import "tailwindcss"
    → v4。
  • 无Tailwind — 读取项目主CSS中的自定义属性、Sass变量或硬编码值。

Phase 0b: Design System Discovery

阶段0b:设计系统发现

Before building anything, determine whether the project already has a documented design system or needs one created from scratch. This phase branches into two modes.
在开始构建前,先确定项目是否已有文档化的设计系统,还是需要从零创建。本阶段分为两种模式。

Discovery Manifest

发现清单

Scan the project root (and common subdirectories like
docs/
,
.github/
,
.cursor/
,
.agent/
) for any of these files:
Brand & style guides:
  • GEMINI.md
    ,
    CLAUDE.md
    ,
    AGENTS.md
    ,
    COPILOT.md
  • .cursorrules
    ,
    .cursor/rules
  • .github/copilot-instructions.md
  • brand-guide.md
    ,
    STYLE.md
    ,
    BRAND.md
  • design-tokens.json
    ,
    tokens.css
    ,
    tokens.json
  • CONTENT_GUIDELINES.md
    ,
    VOICE.md
    ,
    BRAND_VOICE.md
Agent configuration files:
  • .clinerules
    ,
    .windsurfrules
  • .agent/skills/*/SKILL.md
  • README.md
    (check for design system or brand sections)
Hugo-specific:
  • data/design-tokens.json
    ,
    data/tokens.json
  • assets/css/
    for custom properties
If any of these contain design direction (colors, typography, voice, component patterns), enter Adopt mode. Otherwise, enter Establish mode.
扫描项目根目录(以及
docs/
.github/
.cursor/
.agent/
等常见子目录),查找以下任意文件:
品牌与风格指南:
  • GEMINI.md
    ,
    CLAUDE.md
    ,
    AGENTS.md
    ,
    COPILOT.md
  • .cursorrules
    ,
    .cursor/rules
  • .github/copilot-instructions.md
  • brand-guide.md
    ,
    STYLE.md
    ,
    BRAND.md
  • design-tokens.json
    ,
    tokens.css
    ,
    tokens.json
  • CONTENT_GUIDELINES.md
    ,
    VOICE.md
    ,
    BRAND_VOICE.md
Agent配置文件:
  • .clinerules
    ,
    .windsurfrules
  • .agent/skills/*/SKILL.md
  • README.md
    (检查是否包含设计系统或品牌相关章节)
Hugo专属:
  • data/design-tokens.json
    ,
    data/tokens.json
  • assets/css/
    中的自定义属性
如果任意文件包含设计方向(颜色、排版、语气、组件模式),进入适配模式。否则,进入创建模式

Adopt Mode — Existing Brand Guide

适配模式 — 已有品牌指南

When the project already has documented design direction:
  1. Ingest — Read all discovered guide files. Extract:
    • Color palette (named tokens with hex/HSL values)
    • Typography scale (font families, sizes, weights)
    • Spacing system (if documented)
    • Voice & tone adjectives
    • Component patterns already specified
  2. Map — For every extracted token, identify:
    • The corresponding Tailwind config value, CSS custom property, or Hugo
      data/
      entry
    • Whether it's a primitive token (raw color:
      --blue-500
      ) or semantic token (purpose:
      --color-interactive
      )
  3. Audit — Scan existing components for drift:
    • Hardcoded hex values instead of tokens
    • Arbitrary Tailwind values (
      w-[37px]
      ) instead of design scale
    • Inconsistent naming conventions
    • Missing dark mode support
  4. Surface gaps — Report what the guide documents vs. what actually exists in code
当项目已有文档化的设计方向时:
  1. 导入 — 读取所有发现的指南文件,提取:
    • 调色板(带十六进制/HSL值的命名Token)
    • 排版层级(字体族、字号、字重)
    • 间距系统(若已文档化)
    • 语气形容词
    • 已指定的组件模式
  2. 映射 — 为每个提取的Token确定:
    • 对应的Tailwind配置值、CSS自定义属性或Hugo
      data/
      条目
    • 它是基础Token(原始颜色:
      --blue-500
      )还是语义化Token(用途:
      --color-interactive
  3. 审计 — 扫描现有组件是否存在偏差:
    • 使用硬编码十六进制值而非Token
    • 使用任意Tailwind值(
      w-[37px]
      )而非设计规范
    • 命名规范不一致
    • 缺失深色模式支持
  4. 梳理差距 — 报告指南文档内容与代码实际实现的差异

Establish Mode — No Guide Exists

创建模式 — 无指南

When the project has no documented design system:
  1. Extract — Scan existing CSS/Tailwind for de-facto tokens:
    • Run through
      globals.css
      ,
      tailwind.config.*
      , component files (or Hugo's
      assets/css/
      , Astro's
      src/styles/
      )
    • Catalog every color, font, and spacing value actually in use
    • Identify the implicit palette and type scale
  2. Propose — Generate a
    design-tokens.md
    with:
    • Discovered palette organized as primitive → semantic layers
    • Recommended additions to fill gaps (e.g., missing destructive color, no muted variant)
    • Type scale (H1–H6, body, caption) with sizes and weights
    • Spacing ramp mapped to Tailwind's scale (or CSS custom properties for non-Tailwind projects)
  3. Voice — Define initial voice & tone:
    • Propose 3–5 voice adjectives based on the project's domain
    • Draft tone map for common UI states
    • Apply the project's franchise placeholder convention (per user rules)
  4. Approve — Present the proposal to the user. Do NOT proceed to Phase 1 until tokens and voice are approved.
Automated option: Run
bash scripts/scan_components.sh [component_dir]
from the skill directory to get a Phase 0 discovery report + EXISTING / MISSING inventory against the tiered checklist.
Reference: design-system-discovery.md
当项目无文档化设计系统时:
  1. 提取 — 扫描现有CSS/Tailwind中的实际Token:
    • 遍历
      globals.css
      tailwind.config.*
      、组件文件(或Hugo的
      assets/css/
      、Astro的
      src/styles/
    • 记录所有实际使用的颜色、字体和间距值
    • 识别隐含的调色板和排版层级
  2. 提议 — 生成
    design-tokens.md
    ,包含:
    • 按「基础→语义化」层级整理的已发现调色板
    • 填补差距的建议补充内容(如缺失的警示色、无柔和变体)
    • 排版层级(H1–H6、正文、说明文字)及对应字号和字重
    • 与Tailwind层级映射的间距体系(或非Tailwind项目的CSS自定义属性)
  3. 语气定义 — 初始定义品牌语气:
    • 根据项目领域提议3–5个语气形容词
    • 为常见UI状态草拟语气映射表
    • 遵循用户规则中的项目专属占位符约定
  4. 确认 — 将提案提交给用户。在Token和语气获得批准前,不得进入阶段1。
自动化选项: 从技能目录运行
bash scripts/scan_components.sh [component_dir]
,获取阶段0发现报告+基于分层清单的「已存在/缺失」组件清单。
参考: design-system-discovery.md

Phase 1: Inventory & Plan

阶段1:组件清单与规划

Compare existing components against the tiered checklist. Mark each:
  • EXISTING — import from codebase as-is
  • MISSING — create the component, then wire it into the sink
  • SHORTCODE/MDX CANDIDATE — if a component is meant for content authors (not just the sink), also create the content-author-facing wrapper (shortcode for Hugo, MDX export for React/Astro, etc.)
将现有组件与分层清单对比,为每个组件标记:
  • 已存在 — 直接从代码库导入
  • 缺失 — 创建组件,然后接入Sink页面
  • 短代码/MDX候选 — 若组件面向内容作者(而非仅Sink页面),还需创建面向内容作者的封装(Hugo为短代码,React/Astro为MDX导出等)

Tier 1: Core Primitives (mandatory)

层级1:核心基础组件(必填)

  • Typography: H1–H6, paragraph, list (ol/ul), inline code, blockquote
  • Buttons: primary, secondary, outline, ghost, destructive; sizes sm/md/lg; disabled state
  • Badges / Tags: color variants, dismissible
  • Avatars: image, initials fallback, sizes, status indicator
  • Icons: render a sampler grid from the project's icon library
  • Cards: basic, with header/footer, interactive (hover lift)
  • Modals / Dialogs: trigger + overlay + close behavior
  • Alerts / Toasts: info, success, warning, error variants
  • Form controls: text input, textarea, select, checkbox, radio, toggle/switch, with label + error states
  • 排版:H1–H6、段落、列表(ol/ul)、行内代码、块引用
  • 按钮:主要、次要、轮廓、幽灵、警示变体;小/中/大尺寸;禁用状态
  • 徽章/标签:颜色变体、可关闭
  • 头像:图片、首字母 fallback、尺寸、状态指示器
  • 图标:渲染项目图标库的示例网格
  • 卡片:基础款、带头部/尾部、可交互(悬停上浮)
  • 模态框/对话框:触发+遮罩+关闭逻辑
  • 提示/通知:信息、成功、警告、错误变体
  • 表单控件:文本输入框、文本域、选择器、复选框、单选框、开关/切换器,带标签+错误状态

Tier 2: Navigation & Layout (include when app-level complexity exists)

层级2:导航与布局(应用级复杂度项目需包含)

  • Tabs: horizontal, with active/disabled states
  • Breadcrumbs: with separator and current-page indicator
  • Sidebar / Nav: collapsible, with active link
  • Dropdown menu: trigger + item list + keyboard nav
  • Accordion / Collapsible: expand/collapse with animation
  • Tooltip / Popover: hover and click triggers
  • Navigation patterns: header, sidebar, mobile menu
  • Footer variants
  • 标签页:横向、带激活/禁用状态
  • 面包屑:带分隔符和当前页指示器
  • 侧边栏/导航:可折叠、带激活链接
  • 下拉菜单:触发+选项列表+键盘导航
  • 手风琴/可折叠:展开/折叠带动画
  • 提示框/弹出层:悬停和点击触发
  • 导航模式:头部、侧边栏、移动端菜单
  • 页脚变体

Tier 3: Content-Author Components (CMS-dependent)

层级3:内容作者组件(依赖CMS)

Include when the site has a CMS or content authors who write markdown/MDX:
  • Callout / admonition (info, warning, tip, caution)
  • Figure / image with caption
  • Button / CTA (link styled as button)
  • Embed (YouTube, etc.)
  • Card grid (n-up layout of cards from content)
For Hugo, each of these should have both a partial (for templates) and a shortcode (for content authors). For React/Astro, the component serves both roles via MDX.
当站点包含CMS或编写Markdown/MDX的内容作者时,需包含:
  • 提示框/警告框(信息、警告、提示、注意)
  • 带说明的图片/图表
  • 按钮/CTA(链接样式化为按钮)
  • 嵌入(YouTube等)
  • 卡片网格(从内容生成的n列卡片布局)
对于Hugo,每个组件需同时包含局部文件(供模板使用)和短代码(供内容作者使用)。对于React/Astro,组件可直接通过MDX承担两种角色。

Tier 4: Data Display (include when data-heavy views exist)

层级4:数据展示(数据密集型视图项目需包含)

  • Table: sortable headers, striped rows, responsive scroll
  • Stats / KPI cards: value, label, trend indicator
  • Charts: placeholder pattern using the project's chart library (Recharts, Chart.js, etc.)
  • Progress bar / Skeleton loaders: determinate and indeterminate states
  • 表格:可排序表头、条纹行、响应式滚动
  • 统计/KPI卡片:数值、标签、趋势指示器
  • 图表:使用项目图表库(Recharts、Chart.js等)的占位符模式
  • 进度条/骨架屏:确定和不确定状态

Phase 2: Layered Component Architecture

阶段2:分层组件架构

Every component — whether EXISTING or newly created — must follow the base + variant pattern. This makes components predictable for both humans and AI agents. The exact mechanism depends on the framework detected in Phase 0.
所有组件——无论已存在还是新建——都必须遵循基础+变体模式。这能让组件对人类和AI Agent都具有可预测性。具体实现方式取决于阶段0检测到的框架。

React / Next.js — CVA Pattern

React / Next.js — CVA 模式

Use
class-variance-authority
(CVA) or an equivalent pattern to separate structural base classes from variant-specific classes:
tsx
import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "@/lib/utils"; // clsx + tailwind-merge wrapper

// ── Base + Variants ──────────────────────────────────────────────
const buttonVariants = cva(
  // Base: shared structure (always applied)
  "inline-flex items-center justify-center rounded-md font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50",
  {
    variants: {
      variant: {
        primary:     "bg-primary text-primary-foreground hover:bg-primary/90",
        secondary:   "bg-secondary text-secondary-foreground hover:bg-secondary/80",
        outline:     "border border-input bg-transparent hover:bg-accent",
        ghost:       "hover:bg-accent hover:text-accent-foreground",
        destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
      },
      size: {
        sm: "h-8 px-3 text-sm",
        md: "h-10 px-4 text-sm",
        lg: "h-12 px-6 text-base",
      },
    },
    compoundVariants: [
      { variant: "destructive", size: "lg", class: "font-semibold" },
    ],
    defaultVariants: {
      variant: "primary",
      size: "md",
    },
  }
);

// ── Component ────────────────────────────────────────────────────
interface ButtonProps
  extends React.ButtonHTMLAttributes<HTMLButtonElement>,
    VariantProps<typeof buttonVariants> {}

export function Button({ className, variant, size, ...props }: ButtonProps) {
  return (
    <button className={cn(buttonVariants({ variant, size }), className)} {...props} />
  );
}
使用
class-variance-authority
(CVA)或等效模式,将结构基础类与变体专属类分离:
tsx
import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "@/lib/utils"; // clsx + tailwind-merge 封装

// ── 基础 + 变体 ──────────────────────────────────────────────
const buttonVariants = cva(
  // 基础:共享结构(始终生效)
  "inline-flex items-center justify-center rounded-md font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50",
  {
    variants: {
      variant: {
        primary:     "bg-primary text-primary-foreground hover:bg-primary/90",
        secondary:   "bg-secondary text-secondary-foreground hover:bg-secondary/80",
        outline:     "border border-input bg-transparent hover:bg-accent",
        ghost:       "hover:bg-accent hover:text-accent-foreground",
        destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
      },
      size: {
        sm: "h-8 px-3 text-sm",
        md: "h-10 px-4 text-sm",
        lg: "h-12 px-6 text-base",
      },
    },
    compoundVariants: [
      { variant: "destructive", size: "lg", class: "font-semibold" },
    ],
    defaultVariants: {
      variant: "primary",
      size: "md",
    },
  }
);

// ── 组件 ────────────────────────────────────────────────────
interface ButtonProps
  extends React.ButtonHTMLAttributes<HTMLButtonElement>,
    VariantProps<typeof buttonVariants> {}

export function Button({ className, variant, size, ...props }: ButtonProps) {
  return (
    <button className={cn(buttonVariants({ variant, size }), className)} {...props} />
  );
}

Hugo — Dict Context Pattern

Hugo — 字典上下文模式

Hugo components use Go template partials with a
dict
context contract:
go
{{/* layouts/partials/components/button.html */}}
{{/* 
  Params:
    .label    (string, required) — Button text
    .variant  (string, optional) — "primary"|"secondary"|"outline"|"ghost"|"destructive", default "primary"
    .size     (string, optional) — "sm"|"md"|"lg", default "md"
    .disabled (bool, optional)   — default false
    .href     (string, optional) — If set, renders as <a> instead of <button>
    .class    (string, optional) — Additional CSS classes
*/}}

{{- $variant := .variant | default "primary" -}}
{{- $size := .size | default "md" -}}
{{- $disabled := .disabled | default false -}}

{{- $baseClass := "btn" -}}
{{- $variantClass := printf "btn--%s" $variant -}}
{{- $sizeClass := printf "btn--%s" $size -}}
{{- $disabledClass := cond $disabled "btn--disabled" "" -}}

{{- $classes := delimit (slice $baseClass $variantClass $sizeClass $disabledClass .class) " " -}}

{{ if .href }}
  <a href="{{ .href }}" class="{{ $classes }}">{{ .label }}</a>
{{ else }}
  <button class="{{ $classes }}"{{ if $disabled }} disabled{{ end }}>{{ .label }}</button>
{{ end }}
Call it:
{{ partial "components/button" (dict "label" "Submit" "variant" "primary") }}
Hugo组件使用Go模板局部文件,通过
dict
上下文约定:
go
{{/* layouts/partials/components/button.html */}}
{{/* 
  参数:
    .label    (字符串,必填) — 按钮文本
    .variant  (字符串,可选) — "primary"|"secondary"|"outline"|"ghost"|"destructive",默认 "primary"
    .size     (字符串,可选) — "sm"|"md"|"lg",默认 "md"
    .disabled (布尔值,可选)   — 默认 false
    .href     (字符串,可选) — 若设置,则渲染为<a>而非<button>
    .class    (字符串,可选) — 额外CSS类
*/}}

{{- $variant := .variant | default "primary" -}}
{{- $size := .size | default "md" -}}
{{- $disabled := .disabled | default false -}}

{{- $baseClass := "btn" -}}
{{- $variantClass := printf "btn--%s" $variant -}}
{{- $sizeClass := printf "btn--%s" $size -}}
{{- $disabledClass := cond $disabled "btn--disabled" "" -}}

{{- $classes := delimit (slice $baseClass $variantClass $sizeClass $disabledClass .class) " " -}}

{{ if .href }}
  <a href="{{ .href }}" class="{{ $classes }}">{{ .label }}</a>
{{ else }}
  <button class="{{ $classes }}"{{ if $disabled }} disabled{{ end }}>{{ .label }}</button>
{{ end }}
调用方式:
{{ partial "components/button" (dict "label" "提交" "variant" "primary") }}

Astro — Props Interface Pattern

Astro — Props 接口模式

Astro components use TypeScript
Props
in frontmatter:
astro
---
// src/components/Button.astro

interface Props {
  variant?: 'primary' | 'secondary' | 'outline' | 'ghost' | 'destructive';
  size?: 'sm' | 'md' | 'lg';
  disabled?: boolean;
  href?: string;
  class?: string;
}

const {
  variant = 'primary',
  size = 'md',
  disabled = false,
  href,
  class: extraClass,
} = Astro.props;

const classes = [
  'btn',
  `btn--${variant}`,
  `btn--${size}`,
  disabled && 'btn--disabled',
  extraClass,
].filter(Boolean).join(' ');
---

{href ? (
  <a href={href} class:list={[classes]}><slot /></a>
) : (
  <button class:list={[classes]} disabled={disabled}><slot /></button>
)}
Astro组件在前置代码中使用TypeScript
Props
astro
---
// src/components/Button.astro

interface Props {
  variant?: 'primary' | 'secondary' | 'outline' | 'ghost' | 'destructive';
  size?: 'sm' | 'md' | 'lg';
  disabled?: boolean;
  href?: string;
  class?: string;
}

const {
  variant = 'primary',
  size = 'md',
  disabled = false,
  href,
  class: extraClass,
} = Astro.props;

const classes = [
  'btn',
  `btn--${variant}`,
  `btn--${size}`,
  disabled && 'btn--disabled',
  extraClass,
].filter(Boolean).join(' ');
---

{href ? (
  <a href={href} class:list={[classes]}><slot /></a>
) : (
  <button class:list={[classes]} disabled={disabled}><slot /></button>
)}

Static HTML — BEM + Data-Attribute Pattern

静态HTML — BEM + 数据属性模式

For projects without a framework, use BEM class conventions and document the contract in a comment:
html
<!--
  Button Component
  Classes: .btn, .btn--primary|secondary|outline|ghost|destructive, .btn--sm|md|lg, .btn--disabled
  Data attrs: none
-->
<button class="btn btn--primary btn--md">Submit</button>
对于无框架项目,使用BEM类约定并在注释中记录契约:
html
<!--
  按钮组件
  类名: .btn, .btn--primary|secondary|outline|ghost|destructive, .btn--sm|md|lg, .btn--disabled
  数据属性: 无
-->
<button class="btn btn--primary btn--md">提交</button>

Rules (All Frameworks)

通用规则(所有框架)

  1. Base layer — Shared structural classes: layout, border-radius, font-size, focus ring, transitions, disabled state. These NEVER change between variants.
  2. Variant layer — Only what differs: colors, borders, shadows, backgrounds. Defined as named variants.
  3. Type / param export — Always export the variant types (React:
    VariantProps<>
    , Hugo: param comment block, Astro:
    Props
    interface) so consumers (including AI agents) can discover available variants.
  4. Escape hatch — Accept an additional class prop and merge it last so consumers can override when necessary.
  5. No raw conditionals — Never use
    isDestructive ? "bg-red-500" : "bg-blue-500"
    inline. All visual branching goes through the variant API.
  1. 基础层 — 共享结构类:布局、圆角、字号、聚焦环、过渡、禁用状态。变体间这些属性永不改变。
  2. 变体层 — 仅包含差异化内容:颜色、边框、阴影、背景。定义为命名变体。
  3. 类型/参数导出 — 始终导出变体类型(React:
    VariantProps<>
    , Hugo: 参数注释块, Astro:
    Props
    接口),以便使用者(包括AI Agent)发现可用变体。
  4. 扩展出口 — 接受额外类Prop并最后合并,方便使用者在必要时覆盖样式。
  5. 禁止原生条件判断 — 禁止在代码中使用
    isDestructive ? "bg-red-500" : "bg-blue-500"
    这类原生条件判断。所有视觉分支都需通过变体API实现。

Semantic Design Tokens

语义化设计Token

Components should reference semantic token names, not primitive color names:
❌ Primitive✅ Semantic
bg-blue-500
bg-primary
text-gray-500
text-muted-foreground
border-red-500
border-destructive
bg-gray-100
bg-muted
The semantic layer means dark mode, theme changes, and brand pivots only require updating the token definitions — component code stays unchanged.
组件应引用语义化Token名称,而非基础颜色名称:
❌ 基础Token✅ 语义化Token
bg-blue-500
bg-primary
text-gray-500
text-muted-foreground
border-red-500
border-destructive
bg-gray-100
bg-muted
语义化层级意味着深色模式、主题变更和品牌调整仅需更新Token定义——组件代码无需修改。

Utility Fallback

工具函数 fallback

If the project lacks a class-merging utility:
  • React — Add a local
    cn()
    using
    clsx
    +
    tailwind-merge
    , or a minimal version if those aren't in
    package.json
    .
  • Hugo — Create a
    themes/<theme>/layouts/partials/helpers/classnames.html
    partial:
    go
    {{- $classes := slice -}}
    {{- range . -}}{{- if . -}}{{- $classes = $classes | append . -}}{{- end -}}{{- end -}}
    {{- delimit $classes " " -}}
  • Astro — Use
    class:list={[...]}
    (built-in).
  • Static — Inline concatenation or a tiny JS helper.
若项目缺少类合并工具函数:
  • React — 使用
    clsx
    +
    tailwind-merge
    添加本地
    cn()
    ,若项目
    package.json
    中无依赖则实现最简版本。
  • Hugo — 创建
    themes/<theme>/layouts/partials/helpers/classnames.html
    局部文件:
    go
    {{- $classes := slice -}}
    {{- range . -}}{{- if . -}}{{- $classes = $classes | append . -}}{{- end -}}{{- end -}}
    {{- delimit $classes " " -}}
  • Astro — 使用内置的
    class:list={[...]}
  • 静态HTML — 内联拼接或小型JS工具函数。

Phase 3: Voice & Tone

阶段3:语气与语调

Every design system is incomplete without content guidance. The sink page should include a Voice & Tone section that documents how the product communicates.
缺少内容规范的设计系统是不完整的。Sink页面应包含语气与语调章节,说明产品的沟通方式。

Voice Definition

语气定义

Voice is the brand's consistent personality. Define it with 3–5 adjectives:
Voice: [adjective], [adjective], [adjective]
Example: "Confident, approachable, precise"
Voice rules:
  • Voice NEVER changes. It's the same in error messages, onboarding, and marketing.
  • If the project has a
    GEMINI.md
    or brand guide with personality descriptors, extract them.
  • If not, propose adjectives based on the project's domain and audience.
语气是品牌的一致个性。用3–5个形容词定义:
语气: [形容词1], [形容词2], [形容词3]
示例: "自信、亲和、精准"
语气规则:
  • 语气永不改变。错误提示、引导流程和营销内容中保持一致。
  • 若项目有
    GEMINI.md
    或包含个性描述的品牌指南,直接提取。
  • 若无,则根据项目领域和受众提议形容词。

Tone Map

语调映射

Tone is the emotional inflection that adapts to context. Map it to user emotional states:
User StateToneExample
Pleased / celebratingEnthusiastic"You're all set! Your changes are live."
Neutral / browsingInformative"3 items in your cart."
Confused / stuckSupportive"Let's get you back on track. Try..."
Frustrated / errorEmpathetic"Something went wrong. Here's what you can do."
First-time / onboardingEncouraging"Welcome! Let's set up your workspace."
语调是适配场景的情绪倾向。将其与用户情绪状态映射:
用户状态语调示例
满意/庆祝热情"设置完成!您的修改已生效。"
中立/浏览告知"购物车中有3件商品。"
困惑/受阻支持"我们帮您解决问题。请尝试..."
沮丧/错误共情"出现问题了。以下是解决方法。"
首次使用/引导鼓励"欢迎!让我们开始设置您的工作区。"

Content Patterns

内容模式

Document standard copy patterns for recurring UI states:
Empty states — Tell the user what goes here and how to populate it:
  • ✅ "No projects yet. Create your first one to get started."
  • ❌ "No data."
Error messages — Answer three questions: What happened? Why? How to fix it:
  • ✅ "We couldn't save your changes. The file may have been modified by someone else. Try refreshing and saving again."
  • ❌ "Error: 409"
Success confirmations — Concise, affirming, with clear next step:
  • ✅ "Profile updated. Changes will appear within a few minutes."
  • ❌ "Success!"
Loading states — Set expectations:
  • ✅ "Loading your dashboard..." or a skeleton with shimmer
  • ❌ Empty space with a spinner and no context
Destructive actions — Confirm with specifics:
  • ✅ "Delete 'Project Alpha'? This action cannot be undone."
  • ❌ "Are you sure?"
记录常见UI状态的标准文案模式:
空状态 — 告知用户此处应填充内容及填充方式:
  • ✅ "暂无项目。创建首个项目开始使用。"
  • ❌ "无数据。"
错误提示 — 回答三个问题:发生了什么?为什么?如何解决?
  • ✅ "无法保存您的修改。文件可能已被他人修改。请刷新后重试。"
  • ❌ "错误: 409"
成功确认 — 简洁肯定,明确下一步:
  • ✅ "资料已更新。修改将在几分钟内生效。"
  • ❌ "成功!"
加载状态 — 明确预期:
  • ✅ "正在加载您的仪表盘..." 或带微光动画的骨架屏
  • ❌ 仅显示加载 spinner 的空白区域
破坏性操作 — 明确确认:
  • ✅ "删除'Project Alpha'?此操作无法撤销。"
  • ❌ "确定要执行此操作吗?"

Franchise Placeholders

专属占位符

Per project convention, pick a pop-culture franchise for placeholder content (form labels, sample data, empty states, example names). Document the chosen franchise in the sink page header and use it consistently:
  • Form input placeholder: "Entered by Gandalf the Grey"
  • Sample table row: "Frodo Baggins | Shire | Ring Bearer"
  • Empty state: "The Shire is quiet. No hobbits have signed up yet."
Reference: voice-and-tone.md
遵循项目约定,选择一个流行文化IP作为占位符内容(表单标签、示例数据、空状态、示例名称)。在Sink页面头部记录所选IP并保持一致使用:
  • 表单输入框占位符: "由甘道夫输入"
  • 示例表格行: "佛罗多·巴金斯 | 夏尔 | 持戒人"
  • 空状态: "夏尔很安静。还没有霍比特人注册。"
参考: voice-and-tone.md

Phase 3b: Image & Illustration

阶段3b:图片与插图

Photography sourced from the web cannot be used directly — copyright, licensing, and brand inconsistency all prevent it. Every kitchen sink / brand guide must define an illustration style and a reinterpretation pipeline so found reference photos can be transformed into brand-safe illustrated assets.
直接使用网络来源的照片存在版权、许可和品牌不一致问题。每个Kitchen Sink/品牌指南都必须定义插图风格重制流程,以便将参考照片转换为品牌安全的插图资产。

Defining the Illustration Style

定义插图风格

During discovery (Phase 0b), extract or establish the illustration language:
DimensionExample Values
Renderingflat vector, line art, watercolor wash, paper-cut, low-poly 3D, ink sketch
Palettebrand palette only, monochrome + accent, analogous warm, full-spectrum muted
Detail levelminimal / iconic, moderate / editorial, high / realistic
Strokenone (filled shapes), uniform weight, hand-drawn taper, thick outline
Textureclean / digital, grain / risograph, paper / organic
Mood keywords3–5 adjectives that align with Voice (Phase 3), e.g. "warm, approachable, confident"
Document these in the brand guide and render 3–5 sample illustrations on the sink page as the canonical references.
在发现阶段(阶段0b),提取或确立插图语言:
维度示例值
渲染方式扁平化矢量、线稿、水彩晕染、剪纸风、低多边形3D、墨水素描
调色板仅品牌色、单色+强调色、暖色调类比色、全光谱低饱和
细节程度极简/标志性、中等/编辑级、高/写实
描边无(填充形状)、统一粗细、手绘渐变、粗轮廓
纹理干净/数字感、颗粒/ risograph、纸张/有机感
情绪关键词3–5个与语气(阶段3)匹配的形容词,如 "温暖、亲和、自信"
在品牌指南中记录这些内容,并在Sink页面渲染3–5个示例插图作为权威参考。

Reinterpretation Workflow

重制流程

When the agent or designer finds a reference photo:
  1. Describe the subject — Write a concise description of what's depicted (pose, setting, objects, mood), stripping photographer-specific style.
  2. Apply the brand filter — Compose a generation prompt combining the subject description with the project's illustration style tokens (rendering, palette, detail, stroke, texture, mood).
  3. Generate — Use AI image generation (
    generate_image
    tool or equivalent) with the composed prompt. The prompt must explicitly reference the brand's illustration style, not the original photo.
  4. Validate — Check the output against the sink page's illustration samples for style consistency. Regenerate if drift is detected.
  5. Optimize — Export at appropriate sizes/formats (WebP for web, SVG if vector-compatible), add
    alt
    text following content design guidelines.
当Agent或设计师找到参考照片时:
  1. 描述主体 — 简洁描述照片内容(姿势、场景、物品、情绪),去除摄影师专属风格。
  2. 应用品牌滤镜 — 组合主体描述与项目插图风格Token(渲染方式、调色板、细节、描边、纹理、情绪)生成提示词。
  3. 生成 — 使用AI图像生成工具(
    generate_image
    或等效工具),传入组合后的提示词。提示词必须明确引用品牌插图风格,而非原始照片。
  4. 验证 — 检查输出是否与Sink页面的插图示例风格一致。若存在偏差则重新生成。
  5. 优化 — 导出为合适尺寸/格式(WebP用于网页,矢量兼容则用SVG),根据内容设计规范添加
    alt
    文本。

Prompt Template

提示词模板

[Subject description]. Rendered in [rendering style] with [palette description].
[Detail level] detail, [stroke style] strokes, [texture] finish.
The mood is [mood keywords]. No photographic elements.
Example:
A barber trimming a customer's beard in a classic barbershop chair.
Rendered in flat vector style with a warm palette of cream, rust,
and charcoal. Moderate detail, thick outline strokes, subtle grain
texture. The mood is confident, nostalgic, and welcoming.
No photographic elements.
[主体描述]。采用[渲染风格]渲染,使用[调色板描述]。
[细节程度]细节,[描边风格]描边,[纹理]质感。
情绪为[情绪关键词]。无摄影元素。
示例:
理发师在经典理发椅上为顾客修剪胡须。
采用扁平化矢量风格渲染,使用奶油色、铁锈色和炭灰色的暖色调调色板。
中等细节,粗轮廓描边,细微颗粒质感。
情绪为自信、怀旧、亲和。
无摄影元素。

Sink Page Section

Sink页面章节

The kitchen sink MUST include an Illustration Gallery section:
  • 3–5 canonical illustrations showing the brand's visual language
  • Side-by-side comparison: photo reference → illustrated output (demonstrating the reinterpretation)
  • A rendered prompt template pre-filled with the project's style tokens
  • Light/dark mode rendering of each illustration
Kitchen Sink必须包含插图画廊章节:
  • 3–5个展示品牌视觉语言的权威插图
  • 并排对比:参考照片 → 插图输出(演示重制流程)
  • 预填充项目风格Token的渲染提示词模板
  • 每个插图的亮色/暗色模式渲染效果

Content Rules

阶段4:动效与交互

  • Never use unmodified photos — every image must pass through the reinterpretation pipeline
  • Publish the prompt — store the generation prompt alongside the asset for reproducibility
  • Style drift detection — if a new illustration doesn't visually match the sink samples, adjust the prompt or flag for review
  • Alt text — every illustration gets descriptive alt text per content design guidelines (Phase 3)
Reference: image-reinterpretation.md
动画是产品的肢体语言。在Sink中记录动效模式,确保项目中动效的一致性和目的性。

Phase 4: Motion & Interaction

动效原则

Animation is the body language of the product. Document motion patterns in the sink to ensure consistent, purposeful animation across the project.
  1. 有目的性 — 每个动画都要传递信息(入场、退场、状态变化、反馈)。禁止纯装饰性动画。
  2. 有信息量 — 动效引导用户关注变化内容和下一步操作。
  3. 一致性 — 相同类型的变化使用相同动画。模态框入场方式始终一致。
  4. 尊重用户 — 始终遵循
    prefers-reduced-motion
    设置,提供 fallback 行为。

Motion Principles

时长层级

  1. Purposeful — Every animation communicates something (entrance, exit, state change, feedback). No animation for decoration alone.
  2. Informative — Motion guides attention to what changed and where to look next.
  3. Consistent — Same type of change = same animation. A modal always enters the same way.
  4. Respectful — Always honor
    prefers-reduced-motion
    . Provide fallback behavior.
定义与项目动效需求匹配的命名时长:
Token时长适用场景
--duration-instant
100ms微交互:切换、颜色变化、悬停效果
--duration-fast
200ms小型展示:提示框、下拉菜单、徽章
--duration-normal
300ms标准过渡:模态框、面板、页面元素
--duration-slow
500ms大型展示:整页过渡、复杂编排

Duration Scale

缓动曲线

Define named durations mapped to the project's motion needs:
TokenDurationUse Case
--duration-instant
100msMicro-interactions: toggles, color changes, hover effects
--duration-fast
200msSmall reveals: tooltips, dropdowns, badges
--duration-normal
300msStandard transitions: modals, panels, page elements
--duration-slow
500msLarge reveals: full-page transitions, complex orchestration
Token曲线适用场景
--ease-out
cubic-bezier(0, 0, 0.2, 1)
入场 — 元素进入屏幕
--ease-in
cubic-bezier(0.4, 0, 1, 1)
退场 — 元素离开屏幕
--ease-in-out
cubic-bezier(0.4, 0, 0.2, 1)
状态变化 — 元素在原位变换

Easing Curves

常见模式

TokenCurveUse Case
--ease-out
cubic-bezier(0, 0, 0.2, 1)
Entrances — element arriving on screen
--ease-in
cubic-bezier(0.4, 0, 1, 1)
Exits — element leaving screen
--ease-in-out
cubic-bezier(0.4, 0, 0.2, 1)
State changes — element transforming in place
在Sink的动效示例章节记录以下模式:
  • 悬停上浮
    translateY(-2px)
    + 阴影增强,
    --duration-instant
    --ease-out
  • 淡入 — 透明度 0→1,
    --duration-fast
    --ease-out
  • 滑入 — translateY(8px→0) + 透明度 0→1,
    --duration-normal
    --ease-out
  • 展开/折叠 — 高度 0→auto 配合 overflow hidden,
    --duration-normal
    --ease-in-out
  • 骨架屏微光 — 渐变扫过动画,
    --duration-slow
    ,线性,无限循环
  • 模态框入场 — scale(0.95→1) + 透明度 0→1,
    --duration-normal
    --ease-out
  • 模态框退场 — scale(1→0.95) + 透明度 1→0,
    --duration-fast
    --ease-in

Common Patterns

简化动效适配

Document these in the sink's Motion Sampler section:
  • Hover lift
    translateY(-2px)
    + shadow increase,
    --duration-instant
    ,
    --ease-out
  • Fade in — opacity 0→1,
    --duration-fast
    ,
    --ease-out
  • Slide in — translateY(8px→0) + opacity 0→1,
    --duration-normal
    ,
    --ease-out
  • Expand/collapse — height 0→auto with overflow hidden,
    --duration-normal
    ,
    --ease-in-out
  • Skeleton shimmer — gradient sweep animation,
    --duration-slow
    , linear, infinite
  • Modal entrance — scale(0.95→1) + opacity 0→1,
    --duration-normal
    ,
    --ease-out
  • Modal exit — scale(1→0.95) + opacity 1→0,
    --duration-fast
    ,
    --ease-in
将所有动画包裹在
prefers-reduced-motion
检查中:
css
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}
对于Tailwind,使用
motion-safe:
motion-reduce:
修饰符。
参考: motion-guidelines.md

Reduced Motion

阶段5:构建组件

Wrap all animations in a
prefers-reduced-motion
check:
css
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}
For Tailwind, use
motion-safe:
and
motion-reduce:
modifiers.
Reference: motion-guidelines.md
对于阶段1中标记为缺失的每个组件,使用框架原生模式创建。

Phase 5: Build Components

文件位置与命名

For every MISSING item from Phase 1, create the component using the framework's native patterns.
框架位置命名约定
React / Next.js
components/
components/ui/
Button.tsx
,
card.tsx
— 匹配项目现有约定
Hugo
themes/<theme>/layouts/partials/components/
button.html
,
card.html
Astro
src/components/
Button.astro
,
Card.astro
静态HTML
components/
includes/
button.html
,
card.html

File Location & Naming

组件创建标准(所有框架)

FrameworkLocationConvention
React / Next.js
components/
or
components/ui/
Button.tsx
,
card.tsx
— match existing project convention
Hugo
themes/<theme>/layouts/partials/components/
button.html
,
card.html
Astro
src/components/
Button.astro
,
Card.astro
Static HTML
components/
or
includes/
button.html
,
card.html
  1. 创建组件 — 在项目既定的组件位置创建,提供稳定的导出/接口。
  2. 文档化接口 — 在文件顶部记录接口:
    • React: TypeScript接口或JSDoc Props注释。
    • Hugo: Go模板注释块,列出预期的
      dict
      键、类型和默认值。
    • Astro: 前置代码中的TypeScript
      Props
      接口。
    • 静态HTML: 注释块说明预期的类/数据属性。
  3. 使用设计Token — 从项目的Tailwind配置、CSS自定义属性或Hugo
    data/
    条目获取;避免使用任意/魔法值。
  4. 组件自包含 — 仅依赖项目已有的依赖。
  5. 交互组件可实际交互 — 使用项目的交互层实现:
    • React:
      useState
      、事件处理器
    • Hugo: Alpine.js
      x-data
      <details>/<summary>
      (零JS方案)
    • Astro:
      client:load
      + 框架孤岛
    • 静态HTML: Vanilla JS、Alpine.js 或
      <details>/<summary>
  6. 应用变体模式 — 遵循阶段2的变体模式(React用CVA,Hugo用字典参数,Astro用Props)。
  7. 应用语气与语调 — 遵循阶段3的内容模式。错误提示回答「发生了什么/为什么/如何解决」。空状态引导用户操作。
  8. 应用动效 — 遵循阶段4的动效模式,使用定义的时长和缓动Token。
  9. 立即将组件接入Sink页面。禁止使用占位符。

Component Creation Standard (All Frameworks)

内容作者封装

  1. Create the component in the project's established component location with a stable export/interface.
  2. Document the interface at the top of the file:
    • React: TypeScript interface or JSDoc props comment.
    • Hugo: Go template comment block listing expected
      dict
      keys, their types, and defaults.
    • Astro: TypeScript
      Props
      interface in frontmatter.
    • Static: Comment block describing expected classes/data attributes.
  3. Use design tokens from the project's Tailwind config, CSS custom properties, or Hugo
    data/
    entries; avoid arbitrary/magic values.
  4. Keep components self-contained — rely only on dependencies already in the project.
  5. Make interactive components actually interactive using whatever the project's interactivity layer is:
    • React:
      useState
      , event handlers
    • Hugo: Alpine.js
      x-data
      or
      <details>/<summary>
      for zero-JS
    • Astro:
      client:load
      + framework islands
    • Static: vanilla JS, Alpine.js, or
      <details>/<summary>
  6. Apply the variant pattern from Phase 2 (CVA for React, dict params for Hugo, Props for Astro).
  7. Apply voice & tone patterns from Phase 3. Error messages answer what/why/fix. Empty states guide the user.
  8. Apply motion patterns from Phase 4. Use the defined duration and easing tokens.
  9. Wire the component into the sink page immediately. No placeholders.
当组件在阶段1中标记为短代码/MDX候选时:
  • Hugo — 在
    themes/<theme>/layouts/shortcodes/
    创建短代码,包裹局部文件。传递所有相关参数。
  • React / Astro — 组件本身可在MDX中使用。确保已从项目的MDX组件注册表导出。
  • 静态HTML — 记录复制粘贴的使用说明。

Content-Author Wrappers

阶段6:组装Sink页面

When a component is marked as a SHORTCODE/MDX CANDIDATE in Phase 1:
  • Hugo — Create a shortcode in
    themes/<theme>/layouts/shortcodes/
    that wraps the partial. Pass through all relevant parameters.
  • React / Astro — The component itself is usable in MDX. Ensure it's exported from the project's MDX component registry.
  • Static — Document usage instructions for copy/paste inclusion.
根据阶段0检测到的框架创建Sink路由文件。

Phase 6: Assemble Sink Page

Sink路由创建

Create the sink route file based on the framework detected in Phase 0.
React / Next.js
app/sink/page.tsx
  • 添加
    "use client"
    指令。
  • process.env.NEXT_PUBLIC_VERCEL_ENV === "production"
    时返回
    null
  • examples/minimal-sink.tsx
    为起始模板。
Hugo
content/sink/_index.md
+
layouts/sink/list.html
  • 前置元数据:
    type: sink
    ,从站点地图排除(
    sitemap: exclude
    ),隐藏导航。
  • 布局: 检查
    hugo.Environment
    site.Params.showSink
    ;生产环境中重定向。
  • 推荐生产环境防护: 在
    config/production/hugo.toml
    中配置覆盖
    showSink = false
  • examples/minimal-sink.html
    为起始模板。
Astro
src/pages/sink.astro
  • 检查
    import.meta.env.PROD
    ,返回重定向或空页面。
SvelteKit
src/routes/sink/+page.svelte
  • 使用
    $app/environment
    检查环境。
Nuxt
pages/sink.vue
  • 使用
    useRuntimeConfig()
    检查环境。
静态HTML
sink.html
  • 生产部署时不包含该文件。

Sink Route Creation

架构规则

React / Next.js
app/sink/page.tsx
  • Add
    "use client"
    directive.
  • Return
    null
    when
    process.env.NEXT_PUBLIC_VERCEL_ENV === "production"
    .
  • Use
    examples/minimal-sink.tsx
    as a starter template.
Hugo
content/sink/_index.md
+
layouts/sink/list.html
  • Frontmatter:
    type: sink
    , exclude from sitemap (
    sitemap: exclude
    ), hide from nav.
  • Layout: check
    hugo.Environment
    or
    site.Params.showSink
    ; redirect in production.
  • Preferred production guard: config overlay at
    config/production/hugo.toml
    with
    showSink = false
    .
  • Use
    examples/minimal-sink.html
    as a starter template.
Astro
src/pages/sink.astro
  • Check
    import.meta.env.PROD
    and return redirect or empty page.
SvelteKit
src/routes/sink/+page.svelte
  • Use
    $app/environment
    to check for production.
Nuxt
pages/sink.vue
  • Use
    useRuntimeConfig()
    to check environment.
Static HTML
sink.html
  • Simply don't include in production deployment.
  • 禁止导入其他页面/路由文件 — 仅导入组件或在本地定义工具函数。
  • Sink页面是开发工具 — 从生产环境、站点地图、RSS、搜索索引和导航中排除。

Architecture Rules

Sink页面布局

  • Never import other page/route files — only import components or define helpers locally.
  • The sink page is a dev tool — exclude it from production, sitemap, RSS, search indexes, and navigation.
无论使用哪种框架,Sink页面都遵循相同的章节结构。仅需调整语法以匹配框架。
章节顺序:
  1. 头部 — 标题、描述、最后更新时间戳、专属IP声明
  2. 设计Token — 调色板(基础→语义化)、排版层级、间距体系
  3. 语气与语调 — 语气定义、语调映射、内容模式示例
  4. 插图画廊 — 权威插图、重制示例、提示词模板
  5. 站点头部 — 内联渲染,测试响应式断点和导航状态
  6. 站点页脚 — 内联渲染,测试链接列和品牌一致性
  7. 排版 — H1–H6、正文、说明文字、列表、块引用、行内代码
  8. 按钮 — 所有变体×尺寸×状态(变体网格)
  9. 徽章 — 颜色变体、可关闭
  10. 卡片 — 基础款、带头部/尾部、可交互
  11. 表单控件 — 所有输入类型,带标签+错误状态
  12. 模态框与对话框 — 可正常打开/关闭的演示
  13. 提示框 — 所有严重程度变体
  14. 动效示例 — 悬停上浮、淡入、滑入、展开/折叠的交互演示
  15. 内容作者示例 — 短代码/MDX组件的渲染效果(若适用)
  16. 层级2组件 — 标签页、面包屑、手风琴、提示框、下拉菜单(若适用)
  17. 层级4组件 — 表格、统计卡片、进度条、骨架屏(若适用)
  18. 混沌实验室 — Token可视化、状态矩阵、亮色/暗色模式并排对比

Sink Page Layout

混沌实验室

The sink page follows the same section structure regardless of framework. Adapt the syntax to match.
Sections (in order):
  1. Header — Title, description, last-updated timestamp, franchise declaration
  2. Design Tokens — Color palette (primitive → semantic), typography scale, spacing ramp
  3. Voice & Tone — Voice definition, tone map, content pattern examples
  4. Illustration Gallery — Canonical illustrations, reinterpretation examples, prompt template
  5. Site Header — Rendered inline to test responsive breakpoints and nav states
  6. Site Footer — Rendered inline to test link columns and brand consistency
  7. Typography — H1–H6, body, caption, lists, blockquote, inline code
  8. Buttons — All variants × sizes × states (variant grid)
  9. Badges — Color variants, dismissible
  10. Cards — Basic, with header/footer, interactive
  11. Form Controls — All input types with label + error states
  12. Modals & Dialogs — Working open/close demo
  13. Alerts — All severity variants
  14. Motion Sampler — Interactive demos of hover lift, fade, slide, expand/collapse
  15. Content-Author Specimens — How shortcodes/MDX components render (if applicable)
  16. Tier 2 components — Tabs, breadcrumbs, accordion, tooltip, dropdown (if applicable)
  17. Tier 4 components — Table, stats cards, progress, skeleton (if applicable)
  18. Chaos Laboratory — Token visualization, state matrix, dark/light side-by-side
  1. Token可视化 — 程序化渲染设计Token(颜色、间距)。
    • React: 通过
      resolveConfig
      导入解析后的配置。
    • Hugo: 构建时将Token导出到
      data/design-tokens.json
      ,通过
      site.Data
      读取。
    • Astro: 前置代码中导入配置。
    • 静态HTML: 手动维护JSON文件或通过脚本生成。
  2. 状态矩阵 — 并排渲染变体(默认、悬停、聚焦、禁用、激活)。
  3. 主题测试 — 亮色和暗色列,通过包裹类强制切换。
  4. 响应式存根 — 固定宽度的
    iframe
    容器(320px、768px),验证移动端布局。

Chaos Laboratory

阶段7:验证

  1. Token visualization — Programmatically render design tokens (colors, spacing).
    • React: Import resolved config via
      resolveConfig
      .
    • Hugo: Export tokens to
      data/design-tokens.json
      at build time, read with
      site.Data
      .
    • Astro: Import config in frontmatter.
    • Static: Maintain a JSON file manually or generate with a script.
  2. State matrix — Render variants side by side (default, hover, focus, disabled, active).
  3. Theme test — Light and dark columns, forced via wrapper class.
  4. Responsive stubs
    iframe
    containers with fixed widths (320px, 768px) to verify mobile layouts.
在Sink页面完成前,运行以下检查。命令因框架而异。

Phase 7: Verify

自动化检查

Run these checks before considering the sink complete. Commands vary by framework.
框架构建代码检查
Next.js
pnpm build
pnpm lint
Hugo
hugo --minify
hugo --templateMetrics
(检查模板错误)
Astro
pnpm build
pnpm lint
SvelteKit
pnpm build
pnpm lint
Nuxt
pnpm build
pnpm lint
静态HTMLHTML验证工具
可选可访问性审计:
pnpm dlx @axe-core/cli http://localhost:<port>/sink

Automated Checks

手动检查清单

FrameworkBuildLint
Next.js
pnpm build
pnpm lint
Hugo
hugo --minify
hugo --templateMetrics
(check for template errors)
Astro
pnpm build
pnpm lint
SvelteKit
pnpm build
pnpm lint
Nuxt
pnpm build
pnpm lint
StaticN/AHTML validator
Optional accessibility audit:
pnpm dlx @axe-core/cli http://localhost:<port>/sink
  • A. 完整性 — 所有层级1组件已存在。层级2/3/4组件已按需包含。
  • B. 真实组件 — 每个渲染元素都从项目组件位置导入(无仅内联的模拟组件)。
  • C. 分层架构 — 每个组件都使用框架适配的变体模式(React用CVA,Hugo用字典参数,Astro用Props,静态HTML用BEM)。
  • D. 语义化Token — 组件代码中无硬编码十六进制值或基础颜色名称。
  • E. 交互性 — 模态框可打开、切换器可切换、标签页可切换、下拉菜单可展开。所有有状态组件均可正常工作。
  • F. 语气与语调 — 内容模式已文档化。错误提示回答「发生了什么/为什么/如何解决」。空状态引导用户操作。
  • G. 动效 — 动画使用定义的时长/缓动Token。已遵循
    prefers-reduced-motion
    设置。
  • H. 主题 — 亮色/暗色列渲染正确。无绕过Token的硬编码颜色。
  • I. 生产环境防护 — 通过框架原生机制将Sink页面从生产环境排除。
  • J. 无导入循环 — Sink页面未导入任何页面/路由文件。
  • K. 内容作者封装 — 短代码/MDX导出传递所有相关参数(若适用)。

Manual Checklist

CMS注意事项

  • A. Completeness — Every Tier 1 item is present. Tier 2/3/4 items included where relevant.
  • B. Real components — Every rendered element is imported from the project's component location (no inline-only markup pretending to be a component).
  • C. Layered architecture — Every component uses the framework-appropriate variant pattern (CVA for React, dict params for Hugo, Props for Astro, BEM for static).
  • D. Semantic tokens — No hardcoded hex values or primitive color names in component code.
  • E. Interactivity — Modals open, toggles toggle, tabs switch, dropdowns expand. Every stateful component works.
  • F. Voice & tone — Content patterns documented. Error messages answer what/why/fix. Empty states guide the user.
  • G. Motion — Animations use defined duration/easing tokens.
    prefers-reduced-motion
    respected.
  • H. Theming — Dark/light columns render correctly. No hard-coded colors bypassing tokens.
  • I. Production guard — Sink page is excluded from production via the framework's native mechanism.
  • J. No import cycles — Sink page does not import any page/route file.
  • K. Content-author wrappers — Shortcodes/MDX exports pass through all relevant parameters (if applicable).
Sink页面永远不由CMS管理——它是开发工具。
但当存在CMS时,面向内容作者的组件(层级3)应遵循CMS内容模型:
  • TinaCMS — 组件参数应与
    tina/config.ts
    集合中定义的字段对齐。注意:TinaCMS可视化编辑需要React——在Hugo项目中,Tina仅作为Markdown/前置元数据编辑器GUI。
  • Decap CMS — 组件参数应与
    static/admin/config.yml
    中的小部件类型映射。
  • 基于MDX的CMS(Contentful、Sanity等) — 导出的组件应匹配CMS schema预期的Props形状。

CMS Notes

AI Agent 适配性

The sink page is never CMS-managed — it's a developer tool.
However, when a CMS is present, content-author-facing components (Tier 3) should respect the CMS content model:
  • TinaCMS — Component params should align with the fields defined in
    tina/config.ts
    collections. Note: TinaCMS visual editing requires React — in Hugo projects, Tina functions only as a markdown/frontmatter editor GUI.
  • Decap CMS — Component params should map to widget types in
    static/admin/config.yml
    .
  • MDX-based CMS (Contentful, Sanity, etc.) — Exported components should match the expected props shape from the CMS schema.
以下实践确保设计系统可被AI编码Agent(Cursor、Copilot、Claude、Gemini等)最优使用:
  1. 语义化Token优先于基础Token
    --color-interactive
    传达意图;
    --blue-500
    则不能。当Token编码用途时,AI Agent能做出更优决策。
  2. 机器可读格式 — 将Token存储为CSS自定义属性和/或JSON。人类和Agent均可解析。
  3. 类型化Props即API — 每个组件的类型接口(React
    VariantProps<>
    , Hugo字典契约, Astro
    Props
    )实际上就是其API契约。AI Agent使用此生成正确用法。
  4. 基于用途的命名 — Token命名基于其用途,而非外观
    • color-button-background-brand
      ,
      text-muted-foreground
    • blue-dark
      ,
      gray-light
  5. 规则文件 — 若项目有
    .cursorrules
    ,
    .github/copilot-instructions.md
    ,
    GEMINI.md
    CLAUDE.md
    ,确保其中引用了设计系统Token和组件约定。AI Agent会优先读取这些文件。
  6. 唯一可信源 — Sink页面就是参考。若AI Agent需要理解设计系统,直接指向Sink页面和Token定义。

AI Agent Readiness

配套技能

These practices ensure the design system is optimally consumable by AI coding agents (Cursor, Copilot, Claude, Gemini, etc.):
  1. Semantic tokens over primitives
    --color-interactive
    communicates intent;
    --blue-500
    does not. AI agents make better decisions when tokens encode purpose.
  2. Machine-readable format — Store tokens in CSS custom properties AND/OR JSON. Both humans and agents can parse them.
  3. Typed props are the API — Every component's type interface (React
    VariantProps<>
    , Hugo dict contract, Astro
    Props
    ) is effectively its API contract. AI agents use this to generate correct usage.
  4. Purpose-based naming — Name tokens for what they DO, not what they LOOK LIKE:
    • color-button-background-brand
      ,
      text-muted-foreground
    • blue-dark
      ,
      gray-light
  5. Rules file — If the project has a
    .cursorrules
    ,
    .github/copilot-instructions.md
    ,
    GEMINI.md
    , or
    CLAUDE.md
    , ensure the design system tokens and component conventions are referenced there. AI agents read these files first.
  6. Single source of truth — The sink page IS the reference. If an AI agent needs to understand the design system, point it at the sink page and the token definitions.
本技能与其他设计类技能配合使用效果更佳。若有可用技能,可 leverage:
  • design-lookup — 用于从网络搜索CSS组件、SVG图标和设计模式。在创建模式阶段需要组件样式灵感,或寻找特定SVG资产(加载 spinner、分隔符、图标)加入Sink时非常有用。
  • 前端/网页设计指南技能 — 若项目或用户有单独的前端设计标准、网页设计指南或品牌标识技能(如项目专属视觉标识技能),在阶段0b发现时读取。其规则和约束应融入Token系统和语气定义。
  • deep-research — 从零开始建立新设计系统时,若用户需要评估设计系统方案、对比组件库或调研竞品美学,可用于全面研究。
当多个技能适用时,Kitchen Sink技能作为整合者——它消费配套技能的输出(设计参考、品牌标识、研究结果),并将其编码到组件库和Sink页面中。

Companion Skills

反模式

This skill works well in conjunction with other design-oriented skills. When available, leverage them:
  • design-lookup — Use to search for CSS components, SVG icons, and design patterns from the web. Helpful during Establish mode when you need inspiration for component styling or when looking for specific SVG assets (spinners, dividers, icons) to include in the sink.
  • Frontend / web design guidelines skills — If the project or user has a separate skill for frontend design standards, web design guidelines, or brand identity (e.g., a project-specific visual identity skill), read it during Phase 0b discovery. Its rules and constraints should feed into the token system and voice definition.
  • deep-research — Use for comprehensive research when establishing a new design system from scratch and the user wants to evaluate design system approaches, compare component libraries, or survey competitor aesthetics.
When multiple skills apply, the kitchen sink skill acts as the integrator — it consumes the outputs of companion skills (design references, brand identity, research findings) and codifies them into the component library and sink page.
  • 草稿占位符
    {/* TODO: 添加按钮 */}
    绝对不可接受。必须构建真实组件。
  • 任意Tailwind值 — 使用
    w-[35px]
    text-[#ff0000]
    而非配置Token。
  • 原生条件类 — 使用
    isDestructive ? "bg-red-500" : "bg-blue-500"
    而非变体。
  • 导入页面文件
    import X from "../other-page/page"
    会导致耦合和构建问题。
  • 跳过层级 — 未构建层级1按钮就直接开发层级4图表。
  • 静态模拟 — 无法打开的模态框、无法切换的切换器、无法切换的标签栏。
  • 一次性内联组件 — 若在Sink中渲染,就应作为可导入模块放在组件目录中。
  • 基于外观的Token命名
    blue-primary
    而非
    color-interactive
    。语义化命名可在品牌调整时保留。
  • 缺失语气指南 — 无内容模式的Sink只是半个设计系统。
  • 装饰性动画 — 无目的的动画。每个动画都应传递信息或引导用户。
  • 框架不匹配 — 在Hugo或静态HTML项目中强加React习惯(JSX、Hooks)。

Anti-patterns

参考

  • Draft placeholders
    {/* TODO: add button */}
    is never acceptable. Build the real component.
  • Arbitrary Tailwind values
    w-[35px]
    or
    text-[#ff0000]
    instead of using config tokens.
  • Raw conditional classes
    isDestructive ? "bg-red-500" : "bg-blue-500"
    instead of using variants.
  • Importing page files
    import X from "../other-page/page"
    creates coupling and build issues.
  • Skipping tiers — Don't jump to Tier 4 charts before Tier 1 buttons exist.
  • Static mockups — A modal that doesn't open, a toggle that doesn't toggle, a tab bar that doesn't switch.
  • One-off inline components — If it's rendered in the sink, it belongs in the component directory as an importable module.
  • Appearance-based token names
    blue-primary
    instead of
    color-interactive
    . Semantic names survive brand pivots.
  • Missing voice guidance — A sink without content patterns is only half a design system.
  • Decorative animation — Motion without purpose. Every animation should inform or guide.
  • Framework mismatch — Imposing React idioms (JSX, hooks) on a Hugo or static HTML project.
如需详细的组件规格(预期Props、变体、状态、可访问性)、Sink页面章节模板和具体代码示例:
  • 组件: component-catalog.md
  • 发现: design-system-discovery.md
  • 语气与语调: voice-and-tone.md
  • 图片与插图: image-reinterpretation.md
  • 动效: motion-guidelines.md

Reference

For detailed per-component specs (expected props, variants, states, accessibility), the sink page section template, and concrete code examples:
  • Components: component-catalog.md
  • Discovery: design-system-discovery.md
  • Voice & Tone: voice-and-tone.md
  • Image & Illustration: image-reinterpretation.md
  • Motion: motion-guidelines.md