ui-design-ref
前端 UI 设计规范参考与决策辅助。当 agent 需要为 Citado 实现或审查 UI 组件时,使用本 skill 核对 token 选择、状态定义、对比度与语义色规则。适用场景包括:新增交互组件、调整颜色/状态样式、选择 Tailwind 工具类、审查 hover/active/selected 实现是否合规。ALWAYS use this skill when implementing or reviewing UI components in packages/fe.
| Name | ui-design-ref |
|---|---|
| Path | ui-design-ref |
| Version | 1.0.0 |
| Origin | local |
| Source | SkillHub |
| Author | seekthought |
| Project | citado |
| Tags | ui-design design-system tokens citado |
| License | MIT |
Install
skillctl install -r skillhub ui-design-ref
Citado UI Design Reference
本 skill 汇总了 Citado 前端 UI 实现所需的设计决策依据,包括品牌色基准、token 体系、状态语义规则,以及外部设计系统对标资料。agent 在实现任何 UI 改动前应先核对本文件。
1. 核心规约文件
在做任何 UI 实现决策前,必须先读以下文件:
specs/ui.yaml— Citado UI 状态规约(Default/Hover/Active/Selected 定义、语义色边界、禁止模式)packages/fe/src/App.css— 全局 CSS token 定义(:root/.dark两套完整 token)
2. Citado 品牌色基准
来源:
packages/fe/public/logo/primary.svg
| 色值 | 品牌角色 | 在 token 中的映射 | 备注 |
|---|---|---|---|
#2273EC |
品牌蓝 | --primary 色阶(hue |
主交互、主按钮、选中强调 |
#A1D438 |
品牌绿 | --success 语义色 |
仅用于成功/完成,不参与通用交互态 |
#383838 |
品牌炭灰 | 深色模式文字辅助参考 | 不直接用于 token |
规则:所有通用交互态 token 必须与品牌蓝 #2273EC 色相族(hue ≈ 235245)对齐,不得向绿色偏移(hue ≈ 135150)。
3. Token 体系快照
来源:
packages/fe/src/App.css
核心交互 Token
| Token | 浅色值 | 深色值 | 职责 |
|---|---|---|---|
--primary |
oklch(0.47 0.15 241) |
oklch(0.74 0.12 238) |
品牌蓝主交互 |
--primary-foreground |
oklch(0.985 0.002 250) |
oklch(0.18 0.018 250) |
主交互前景色 |
--accent |
oklch(0.925 0.014 246) |
oklch(0.31 0.022 246) |
中性弱交互层(hover) |
--accent-foreground |
oklch(0.31 0.022 248) |
oklch(0.92 0.01 252) |
弱交互前景色 |
语义色 Token
| Token | 浅色值 | 深色值 | 职责 |
|---|---|---|---|
--success |
oklch(0.52 0.16 145) |
oklch(0.72 0.15 142) |
语义绿(成功/完成) |
--success-foreground |
oklch(0.985 0.002 250) |
oklch(0.18 0.02 145) |
成功前景色 |
--warning |
oklch(0.72 0.16 68) |
oklch(0.82 0.14 72) |
语义琥珀(警告) |
--warning-foreground |
oklch(0.985 0.002 250) |
oklch(0.15 0.02 70) |
警告前景色 |
--destructive |
oklch(0.577 0.245 27.325) |
oklch(0.704 0.191 22.216) |
语义红(错误/危险) |
装饰色 Token(非交互)
| Token | 浅色值 | 深色值 | 职责 |
|---|---|---|---|
--canvas-glow-accent |
oklch(0.84 0.06 142 / 0.12) |
oklch(0.6 0.05 142 / 0.08) |
装饰绿(背景光晕,禁止用于交互) |
Tailwind 工具类映射规则
- 主交互:
bg-primary,text-primary,border-primary/20,bg-primary/10 - 弱交互 hover:
hover:bg-accent,bg-accent/40 - Selected 态(品牌蓝 subtle):
bg-primary/10 text-primary border-primary/20 - 语义成功:
bg-success/10 text-success border-l-success - 语义警告:
bg-warning/10 text-warning border-l-warning - 语义危险:
bg-destructive/10 text-destructive border-l-destructive
4. 四态状态实现规则
每个交互组件必须明确定义以下四个状态:
| 状态 | 语义 | 实现方向 |
|---|---|---|
| Default | 静止基线 | 透明或容器底色,品牌色或中性前景 |
| Hover | 短暂预反馈 | hover:bg-accent 或 hover:bg-primary/8 |
| Active | 瞬时按压(非 Selected) | Hover 底色加深一阶 |
| Selected | 持续已选中状态 | bg-primary/10 text-primary border-primary/20 |
关键区分:Active 仅表示"正在按压",Selected 表示"当前已生效/激活",两者不可混用。
5. 语义色使用边界
| 颜色 | 允许场景 | 禁止场景 |
|---|---|---|
| 品牌蓝 | 主交互、主按钮、Selected 强调 | 禁止用于成功/错误语义 |
绿/success |
成功 toast、完成态 badge | 禁止用于通用 hover/active/selected |
琥珀/warning |
警告提示、待操作状态 | 禁止用于非警告类交互 |
红/destructive |
错误、危险操作 | 禁止用于非异常类主交互 |
中性/accent |
ghost hover、弱交互容器反馈 | 禁止用于 Selected 主强调 |
6. 对比度硬性要求
来源:W3C WCAG 2.2
| 类型 | 最低要求 | 适用范围 |
|---|---|---|
| 正文文本 | 4.5:1 | 所有按钮文字、标签、正文 |
| 大号文本(18pt+) | 3:1 | 标题、页眉 |
| 非文本控件状态 | 3:1 | focus ring、selected ring、边框 |
验证流程:在实现主按钮、Selected 态、focus ring 时必须以数值对比度为准,而非主观视觉判断。
6.1 实底与透明度审查
当用户明确要求"不要透明""要实底""不要透出底层内容"时,必须同时检查两层:
- 组件 class 是否仍带
/xx透明度后缀 - token 本体是否已经自带 alpha
规则:仅去掉 class 上的透明度后缀并不等于得到实底。如果 token 本体含 alpha,视觉上仍然是半透明。
优先策略:
- 优先使用真正的 solid surface token 或稳定包装层
- 不要在组件里默认假定现有
surfacetoken 已经不透明
6.2 Motion 决策规则
同槽位状态切换
- 当两个状态共享同一视觉槽位时,优先保留同一个容器,只做内容淡切、颜色过渡或轻量位移。
- 不要默认把状态切换建模成 keyed enter/exit 弹出。
面板与表单展开
- 面板、表单、drawer 类展开收起应优先体现方向性,优先使用高度、宽度或位置变化。
- 未明确要求前,不要默认使用 scale 或 spring 弹跳。
何时允许更强动画
- 只有在产品明确要求"弹出感""卡片浮现感"时,才使用明显的 presence pop、scale 或 spring。
- 同一槽位的状态芯片、badge、同步状态、过滤状态,不应做整块弹出。
7. 外部设计系统参考
以下资料是本规约的制定依据,agent 在遇到规约未覆盖的场景时,应优先参考以下顺序查阅:
7.1 颜色体系与状态语义
| 系统 | 参考内容 | 链接 |
|---|---|---|
| Fluent UI | Token 结构、Brand/Neutral/Semantic 三层拆分、Rest/Hover/Pressed/Selected 阶梯 | https://microsoft.github.io/fluentui-design-tokens/ |
| Carbon Design | Button 状态阶梯 | https://carbondesignsystem.com/components/button/style/ |
| Carbon Design | Content Switcher Selected vs Hover | https://v10.carbondesignsystem.com/components/content-switcher/style/ |
| Material Design 3 | Color System(Tonal Palette、Roles) | https://m3.material.io/styles/color/system/overview |
| Ant Design | 色彩规范(品牌色/功能色/中性色职责拆分) | https://2x.ant.design/docs/spec/colors-cn |
| Radix UI Colors | 语义色阶规范(P3 色域、Step 命名约定) | https://www.radix-ui.com/colors |
| GitHub Primer | 颜色基础、浅/深模式 token 策略 | https://primer.style/design/foundations/color |
| Shopify Polaris | 交互色与语义色建模 | https://polaris.shopify.com/design/colors |
7.2 可访问性规范
| 规范 | 参考内容 | 链接 |
|---|---|---|
| WCAG 2.2 | 文本对比度(SC 1.4.3) | https://www.w3.org/WAI/WCAG22/Understanding/contrast-minimum.html |
| WCAG 2.2 | 非文本对比度(SC 1.4.11) | https://www.w3.org/WAI/WCAG22/Understanding/non-text-contrast.html |
| APCA | 下一代感知对比度算法 | https://www.myndex.com/APCA/ |
7.3 对比度校验工具
- oklch 对比度在线计算:https://oklch.com/
- Colour Contrast Checker:https://colourcontrast.cc/
- APCA Contrast Calculator:https://www.myndex.com/APCA/
8. 常见错误模式(Forbidden Patterns)
在审查或实现 UI 时,遇到以下情况直接判定为违规:
- 绿色 hover:
hover:bg-success,hover:bg-green-*,hover:bg-accent(当 accent 被误配为绿色时) - Active 替代 Selected:用
active:bg-…CSS 伪类来表达"当前已选中"持续状态 - 混用 Selected 定义:同一个组件族有的用
bg-accent/20,有的用bg-primary/10,有的只加ring - 硬编码前景色:主按钮直接写
text-white或text-black而不经对比度校验 - 绿色装饰色渗透到交互态:
canvas-glow-accent(绿色光晕)不得与按钮 hover/active 混用 - 伪实底:用户要求实底时,只去掉 class 上的
/xx,却没有检查 token 本身是否带 alpha - 同槽位弹出:状态 chip、badge、同步状态默认做 keyed enter/exit 或 scale pop
- 无方向面板动效:展开收起类交互默认交给 spring 或 scale,而不是先定义方向性
9. 实施检查清单
在提交 UI 改动前,逐项确认:
- 新组件是否定义了 Default / Hover / Active / Selected 四态的 token 归属?
- Hover 与 Active 是否在同一色相体系内(品牌蓝或中性色,不混用)?
- 文本前景色对比度是否 ≥ 4.5:1(非文本 ≥ 3:1)?
- 绿色(success)和红色(destructive)是否仅出现在语义场景?
- Selected 态是否与 Active(瞬时按压)视觉可区分?
- Token 是否使用 Tailwind 工具类(
bg-primary/10)而非硬编码 oklch 值? - 浅色与深色主题是否同时覆盖?
- 如果用户要求实底,是否同时检查了 class 透明度后缀和 token 本体 alpha?
- 同槽位状态切换是否保留了稳定容器,而不是默认整块弹出?
- 面板/表单展开是否体现了明确方向,而不是默认 scale 或 spring?