设计与 UI
让界面看起来有意识且高级,而不是模板化的千篇一律。这是应用构建器中最重要的质量杠杆。将其应用于 DOM / 叠加 UI — 页面、浏览器外壳、HUD、菜单、表单。(对于 3D 游戏玩法画布,请参阅 building-games 技能;本技能管理叠加在它之上的 DOM UI。)
阅读 references/ 目录获取深度内容(按需加载 — 不要全部内联):
references/refined-ui.md— 完整的产品浏览器外壳/叠加设计系统。references/typography.md— 字号层级、配对、节奏。references/surfaces.md— 高度、边框、阴影、分层。references/animations.md— 动效、缓动函数、过渡。references/performance.md— 保持 UI 流畅(60fps,无卡顿)。
1. 设计系统优先(在任何样式工作之前完成)
先定义系统,然后基于它进行组合。永远不要随意使用临时值。
- CSS 中的令牌(Tailwind v4 是 CSS 优先)。 将色板、圆角和字体放在
src/styles.css的@theme下作为 CSS 变量;通过 Tailwind 工具类使用它们。单一数据源。@import "tailwindcss"; @theme { --color-bg: #0b0b0f; --color-surface: #16161d; --color-fg: #e7e7ea; --color-muted: #a0a0ab; --color-primary: #14b8a6; --color-border: #26262f; --radius: 0.75rem; --font-sans: "Inter", system-ui, sans-serif; } - 使用 shadcn/ui 组件(Radix 原语 +
cva变体 +tailwind-merge)来构建按钮、对话框、下拉菜单、输入框等。它们兼具可访问性和一致性。将它们生成到src/components/ui中;通过令牌而非内联十六进制色值来设置样式。 - Tailwind v4 基础修复 — 按钮需要指针光标。 v4 的 Preflight 使
<button>使用cursor: default,感觉像是有缺陷。在src/styles.css中一次性添加此代码,以便按钮/可点击角色显示指针:@layer base { button:not(:disabled), [role="button"]:not(:disabled) { cursor: pointer; } } - 禁止临时样式: JSX 中不得出现原始十六进制色值、不得使用
text-white/bg-black字面量、不得使用像p-[16px]或text-[13px]这样的任意值。如果需要某个值,请将其转换为令牌或刻度步骤。
2. 量化检查清单(防止“丑陋”的廉价规则)
- 颜色总数 ≤ 3–5 种(一个主色 + 中性色 + 最多一个强调色)。不要随意添加额外的色相。除非特别要求,否则不要默认使用紫色。
- 字体家族 ≤ 2 种(通常一种)。为标题和正文搭配一对字体,或者只使用一种。
- 行高 1.4–1.6 用于正文;大标题的行高更紧凑。
- 当覆盖背景颜色时,同时覆盖前景/文本颜色(必须保持对比度 — 同时检查浅色和深色模式)。
- 移动端优先:先设计约 390px 宽度的布局,然后放大。没有水平溢出;点击目标 ≥ 44px。
- 一致的间距刻度(基于 4/8 的倍数)。充足的留白优于内容拥挤。
- 一种强调色,谨慎使用,主要用于主要操作 — 而不是到处使用。
3. 反“AI 泛化”(使输出看起来模板化的特征 — 避免)
- 无渐变色块填充,没有用巨大的英雄渐变替代内容。
- 不要使用 emoji 作为图标 — 使用真实的图标集(
lucide-react)。 - 不要使用手绘 SVG 插图/地图/图表 — 使用真实的库(
recharts用于图表)或真实的生成图像。 - 最终产品中不要有占位图片 / 灰色 Lorem 方块 — 生成真实图片或使用真实内容;在 Canvas 图片上设置
crossOrigin="anonymous"。 - 避免过度使用的字体外观(仅默认系统字体,或 Comic Sans 级别的选择)。
- 每个元素都应物有所值。 减少装饰性噪音。建立一个系统,然后有意图地变化 — 而不是随机。
- 就地编辑应用时,匹配现有 UI;不要引入第二种视觉语言。
4. 布局与层次结构
- 清晰的视觉层次:每个视图一个主要操作;大小/粗细/颜色表达重要程度。请参阅
references/typography.md和references/surfaces.md。 - 使用真实的布局结构(网格/弹性布局、容器最大宽度),而不是绝对定位的 hack。对齐到一致的网格。
- 空状态、加载状态和错误状态是设计的一部分 — 不要交付空白/卡顿的中间状态。
5. 动效(微妙、有目的)
- 短暂、缓和的过渡(150–250ms)用于悬停/按压/进入;尊重
prefers-reduced-motion。详情请参阅references/animations.md。 - 永远不要以导致卡顿的方式为布局添加动画;优先使用 transform/opacity。
6. 游戏叠加层(当此技能与 building-games 配合使用时)
游戏玩法画布归 building-games 所有。此技能为 DOM 叠加层设置样式:开始/“点击开始”画面、HUD、分数、菜单、暂停、移动端控制。保持叠加层在画布上方可读(背景、对比度),并使其不干扰指针锁定/游戏玩法的输入路径。
完成检查清单(在您宣布 UI 完成之前)
- 令牌已在
@theme中定义;JSX 中没有临时十六进制色值 / 任意值。 - 颜色 ≤ 5 种,字体 ≤ 2 种,间距刻度一致。
- 对比度得到保持;无论背景在哪里被覆盖,前景色也随之覆盖。
- 移动端(约 390px)没有溢出;点击目标 ≥ 44px。
- 使用真实图标/图片/图表 — 没有任何反泛化特征。
- 已处理加载/空/错误状态;动效微妙且符合减少动效偏好。
- 已在浏览器中渲染并目视检查(请参阅 AGENTS.md 中的验证步骤),而不仅仅是 curl 测试。