做产品 PMaker
空格的键盘
一页一个样
列表页
新建
详情页
新建
弹窗里
新建
三个圆角、三个字号、三个内边距
一处定义,处处引用
Button / primary
新建
padding: 8px 16px
radius: 6px
font: 12px / 600
bg: var(--color-primary)
改一次,全站跟着变

同一个按钮在三个页面长了三个样。不是谁做错了,是它从来没被定义过。

Components First, Then Pages

Lock down the dozen most common components first, then build pages out of them. Do it the other way around and every page grows its own style.

What you will run into
  • 同一个按钮在不同页面上圆角、字号、内边距都不一样
  • 改一个样式要在七八个文件里各改一遍,还漏了两处
  • 让 AI 做新页面,它又造了一套新的卡片样式

This problem is especially sharp in vibecoding. The AI only ever sees the current page — it has no global view — so every page means it reinvents the button. Without a ready-made component set, it will absolutely make its own.

Components-first has a side benefit: it turns a design decision from "every time" into "once." Once the button's corner radius is set, the next few dozen pages never have to think about it again.

Which Dozen to Lock First

组件要定清楚什么
按钮主要 / 次要 / 危险三种,每种含默认、悬停、按下、禁用、加载五个状态
输入框默认、聚焦、报错、禁用、只读,加上标签和提示文字的位置
卡片内边距、圆角、边框还是阴影,二选一别都用
列表项行高、分隔方式、悬停态、选中态
标签状态色一套,尺寸一到两种
弹窗 / 抽屉宽度、标题区、内容区、按钮区的固定结构
空态 / 加载 / 错误三个通用组件,全站复用(见四态齐全)
提示条成功、警告、错误三种,位置和消失时机统一
These eight categories cover the vast majority of any interface. Once they're set, new pages are basically assembly work — no more styling decisions.

When you define them, write the exact values — not "slightly smaller radius." Values should be drawn from the spacing and type scale variables, not newly invented each time.

同一个「主按钮」,两种做法 每个页面各造一套 圆角、字号、内边距全都不一样 AI 每次只看到当前这一个页面,没有全局视野 一套组件被复用 按钮组件 新页面基本就是拼装,不再需要做样式决定 圆角定完一次,后面几十个页面都不用再想 你不给它一套现成的组件,它就一定会自己造——这不是 AI 不听话,是它手上没有别的选择。 定组件时数值要从间距和字号那两组变量里取,而不是各自新定一套。
These eight categories cover the vast majority of any interface. Once they're set, new pages are basically assembly work — no more styling decisions.

Note for the AI

CLAUDE.md · Component rules
## 组件

项目已有的组件在 src/components/ui/ 下。
做任何页面之前,先看一遍这个目录。

强制要求:
- 需要按钮、输入框、卡片、列表项、标签、弹窗、
  空态、加载态、错误态时,一律使用已有组件,
  不要在页面里写内联样式或新建同类组件。
- 已有组件不满足需求时,先告诉我缺什么、
  建议怎么扩展(加一个 variant 还是加一个 prop),
  等我确认再改。不要绕过去自己写一个。
- 新建组件时,颜色 / 间距 / 字号 / 圆角必须引用设计变量,
  不允许写死数值。
- 每个组件都要实现完整状态:按钮五态、输入框五态。

做完页面后,列出你用到的所有组件,
以及有没有新建或修改过任何组件。

That last line is a lightweight audit. It lets you catch the AI quietly inventing a new component, instead of finding out on page five that the style has drifted.