结构:四层表面、三级文字、一个主色、五个状态
| 层 | token | 用在哪 |
|---|---|---|
| 页底 | background |
整页的灰地 |
| 内嵌 | muted |
表头行、代码块、选中行、统计分组底 |
| 交互底 | secondary / accent |
次级按钮 / hover 与键盘高亮 |
| 面板 | card(popover 同值) |
内容面板、卡片、弹层,浮在灰地上 |
文字三级:foreground(必读)→ muted-foreground(辅助)→ subtle(不必读)。没有第四级;需要更弱的对比说明信息本来就不该出现。
主色 primary 一个,ring / float 是它的别名。状态五色各配一个 -soft 浅底:success warning destructive info pending。
用色比例
一个典型列表页里各色所占面积:灰白(background + card + muted)≈ 90%,文字黑灰 ≈ 8%,主色 < 1%(一个按钮),状态色 ≈ 1%(一列 pill)。如果一屏里主色或状态色超过 5%,几乎一定是用错了地方。
对比度(实测,WCAG 2)
| 文字 | 底 | 浅色 | 暗色 | 石板青 | 石板青暗 | 结论 |
|---|---|---|---|---|---|---|
foreground |
card |
17.4 | 14.3 | 17.4 | 14.3 | 正文,AAA |
foreground |
background |
15.6 | 15.4 | 15.6 | 15.4 | AAA |
muted-foreground |
card |
4.7 | 5.8 | 5.0 | 5.8 | AA |
muted-foreground |
background |
4.2 | 6.2 | 4.5 | 6.2 | 浅色下略低。辅助文字尽量放在 card 上 |
subtle |
card |
2.7 | 3.4 | 2.8 | 3.4 | 不达标,故只承载不必读信息 |
primary-foreground |
primary |
17.3 | 14.6 | 9.0 | 7.0 | 主按钮 |
success |
success-soft |
5.1 | 8.0 | 5.1 | 8.0 | 芯片 |
warning |
warning-soft |
4.3 | 6.5 | 4.3 | 6.5 | 浅色下略低,粗体 + 图标补偿 |
destructive |
destructive-soft |
5.2 | 5.9 | 5.2 | 5.9 | 芯片 |
info |
info-soft |
5.1 | 6.5 | 5.1 | 6.5 | 芯片 |
pending |
pending-soft |
4.1 | 5.4 | 4.1 | 5.4 | 同 warning |
on-status |
destructive |
6.0 | 6.7 | 6.0 | 6.7 | 危险按钮 |
| 状态色 | card |
5.0–6.1 | 6.2–9.8 | — | — | 状态色作文字直接放在面板上 |
border |
card |
1.3 | 1.5 | 1.3 | 1.5 | 装饰线,不承载意义 |
三处加粗的是灵构原值,照实保留,不为达标偷偷改色。处理:① 辅助文字优先放 card 上;② 状态芯片粗体 + 图标,颜色只是辅助,本来就不许只靠颜色;③ 现场端(要求 ≥7:1)的状态芯片改用实心状态底 + on-status 字。
图表色板
六个分类色 chart-1 … chart-6 = 六套主题的主色提到同一明度:石板青、钢蓝、赭褐、玄紫、松墨、中性灰。图表在任何主题下都长一样,不随换肤变;「其他 / 未分类」固定 chart-6。网格与坐标轴用 chart-grid,比 border 再淡一档。
- 按序取色,不跳;超过六个分类先合并再画。
- 单序列图表(一个指标的趋势)不用分类色,用
muted-foreground折线 +foreground端点(Metric 里的 sparkline 就是)。 - 状态类图表(正常 / 超期 / 故障占比)用状态色,不用分类色——语义已经被占死了。
- 涨跌:
rise红、fall绿,与状态色的红绿是同一对 token,方向语义在中国场景里与状态语义一致(红 = 涨 = 要注意)。
暗色
底 hsl(207 23% 8%) 而不是纯黑;面板 card 只比底亮一点,靠 shadow-hairline 分层;状态色提亮一档,其实心底上的文字改用 on-status(深色);主色反转为浅色。四层表面在暗色下的明度顺序反过来:越上层越亮。
不做的事
- 不做 50–950 的色阶表。语义 token 已经覆盖了所有用途,色阶表只会让人绕过语义直接取色。需要一个「更淡的灰」时,先问是不是
muted。 - 不做透明度叠加(
foreground/60)表达层级,用muted-foreground;透明度会随底色变,对比不可控。 - 不给同一语义配两种颜色(成功用绿又用蓝)。