Files
Agent-System-Dev/DESIGN.md
T
weichen 8af945a1d5 Make development gates preserve work and verifiable evidence
Why: cleanup, component synchronization, receipt recording and credential handling could contradict the documented development boundaries.

Evidence: SELF 75 isolated governance tests and source checks are captured in .task/feature-governance-reliability.md; combination and CI verification follow.

Impact: hardens local task and CI tooling, aligns policy and component documentation, and adds continuous regression tests without changing product behavior.

Refs: .task/feature-governance-reliability.md; policy/governance.md; policy/platform-admission.md
2026-10-05 12:36:02 +00:00

299 lines
18 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Agent-System-Dev 设计系统(DESIGN.md)
写给 Agent 与人:在本仓生成或修改任何 UI 之前,先遵循本文,再发明新的视觉规则。
违反本文视为**设计系统缺陷**,不是风格偏好。
四原则:**美观、现代、简洁、易用**。每条规则都是四原则在某一维度上的可执行化。
参照体系:ZCode(zai-org/ZCode)开源仓的 DESIGN.md、`packages/ui/src/styles.css`
主题真值与动效配方。本文的色板、字号标尺、圆角层级、动效参数均逐条对照其源码校准。
---
## 1. 产品性格
Agent-System-Dev 是桌面优先、Web 兼容的 AI 工作台。界面应**冷静、高密度、可操作**,而非装饰性的。
为长会话、高信息密度、可读的对话与工具输出、键盘驱动的工作流而设计。
避免:营销式大留白、默认渐变装饰、大面积品牌色铺底、背景/卡片/浮层层次含混。
## 2. 主题
- 用户可选主题:跟随系统 / 浅色 / 深色。实现为 `:root[data-theme='dark' | 'light']`。
- 深色基准为 Zai Dark 复刻;浅色基准为 Zai Light。**令牌唯一来源:`@ui/tokens.css`**。
- 禁止在组件里出现裸色值(hex/rgb 字面量);一切颜色经语义令牌消费。
守护测试(`design-guard.test.ts`)以基线棘轮拦截新增裸值。
### 2.1 表面阶梯(层次靠背景阶梯,不是描边堆叠)
| 令牌 | 深色 (Zai Dark) | 浅色 (Zai Light) | 用途 |
|---|---|---|---|
| `--bg-inset` | `#101010` | `#ececee` | 窗口间隙(面板化布局的"底座")、代码底 |
| `--bg` | `#161616` | `#f8f8f8` | 应用底、主区背景 |
| `--bg-panel` | `#202020` | `#ffffff` | 侧栏/面板/头部 |
| `--bg-raised` | `#2b2b2b` | `#ffffff` | 卡片、输入、菜单、浮层 |
| `--bg-hover` | `rgba(255,255,255,.05)` | `rgba(13,13,13,.05)` | 通用悬停 |
| `--bg-active` | `rgba(255,255,255,.10)` | `rgba(13,13,13,.08)` | 选中态 |
### 2.2 边框(发丝三档)
`--border-soft: rgba(255,255,255,.06)` / `--border: rgba(255,255,255,.10)` /
`--border-strong: rgba(255,255,255,.15)`(浅色对应 13,13,13 的 .08/.10/.16)。
边框只做轮廓;选中优先用 `--bg-active` 填充而非换边框色。
### 2.3 文本
`--text`(主读文本,深 `#d4d4d4` / 浅 `#262626` / 墨绿 `#082d4f`)。
`--text-dim`:深 66% / 浅 68% / 墨绿 70%。
`--text-faint`:深 52% / 浅与墨绿 58%。
用文本层级制造信息密度,先于增加更多边框或颜色。
门槛(`contrast-guard.test.ts`,WCAG 2.1):
- `--text` 与 `--text-dim` 在主区表面(`--bg`、`--bg-panel`、`--bg-raised`、代码底 `--bg-inset`)不低于 **4.5:1**。
- `--text-faint` 不低于 **3:1**,并且**只用于装饰**:占位符、chevron、kbd、关闭图标的默认色。
- 承载决策或需要读完的文字从 `--text-dim` 起步:表头、确认详情、工具清单、空态说明、设置项描述、状态词。不要把 faint 当内容色。
侧栏另用 `--text-sidebar-dim`(墨绿 78%)与 `--text-sidebar-faint`(墨绿 62%),门槛与主区相同,只跟 `--bg-sidebar` 对拍。
侧栏会把 `--text*` 重映射成侧栏色。挂在侧栏 DOM 里、但画在主区纸面上的浮层(账户菜单)改用 `--text-workspace*`,这是同一套文字的不被重映射的副本。
### 2.4 强调与语义色
- 交互强调蓝:`--accent`(深 `#4099ff` / 浅 `#0b7fff`)。**只用于**链接、选中指示、聚焦环、
进行中指示;不做大面积铺底、不做主按钮底色。
- 主按钮:单色系反色——`--primary`(深 `#ffffff` / 浅 `#0d0d0d`)配 `--primary-foreground`
(反向黑/白)。品牌色保持克制。
- 语义图形色:`--ok #46bf72`、`--warn #ff8a30`、`--err #ff5c5c`(浅色与墨绿 `#1e8a3e` / `#d17300` / `#e03131`)。
语义色只表语义。图形色(状态点、描边、色条)在 `--bg` / `--bg-panel` / `--bg-raised` 上不低于 **3:1**。
**图形色不作文字。** 链接、状态词、差异文字、空闲状态字用下面的文字档。
- 文字档(同一色相,专门保证 4.5:1,含铺在 `*-soft` 上):
| 令牌 | 深色 | 浅色 / 墨绿 | 用途 |
|---|---|---|---|
| `--accent-text` | `#58a6ff` | `#0858b0` | 链接、动作字 |
| `--warn-text` | `#ff8a30` | `#8d4d00` | 警告文字;也作警告徽标底 |
| `--err-text` | `#ff7272` | `#a92525` | 错误文字;也作错误徽标底 |
| `--ok-text` | `#46bf72` | `#17682f` | 成功状态字 |
| `--idle-text` | `#929292` | `#636363` | 空闲状态字 |
| `--diff-add-text` | `#7dcea0` | `#17682f` | 差异增加的文字 |
| `--diff-remove-text` | `#ff9b9b` | `#a92525` | 差异删除的文字 |
徽标:底用对应 `*-text`,字用 `--text-on-semantic`(深 `#101010` / 浅与墨绿 `#ffffff`)。
- 等你确认用 `--wait`(深 `#8b93ff` / 浅 `#3a46c8` / 墨绿 `#3d5a9a`)和 `--wait-soft`。
不借用成功绿,也不用红或橙装饰等待。
- 差异视图:增加用 `--diff-add` / `--diff-add-text`,删除用 `--diff-remove` / `--diff-remove-text`。
- 空闲任务的图形用 `--task-idle`,文字用 `--idle-text`。定时任务用 `--task-scheduled`。两者不要混成同一种灰。
### 2.5 墨绿主题(可选,`data-theme='molv'`)
暖纸白工作区、深海军蓝左栏与顶栏、翠绿强调。只覆盖表面与语义色;字号标尺、圆角、间距沿用 §3–§5,不另起一套。左栏与顶栏消费 `--bg-sidebar` / `--text-sidebar*`(深色与浅色下别名到面板与正文,墨绿下翻成海军蓝)。
| 令牌 | 墨绿 | 用途 |
|---|---|---|
| `--bg-inset` | `#e0e0db` | 窗口间隙 |
| `--bg` | `#f2f2f0` | 对话主区 |
| `--bg-panel` | `#fbfbfa` | 右栏等面板 |
| `--bg-sidebar` | `#082d4f` | 左栏、顶栏 |
| `--text` | `#082d4f` | 主读文本 |
| `--text-sidebar` | `#e9f0f6` | 左栏与顶栏文字 |
| `--accent` | `#165f49` | 主区交互强调(翠绿)。不用于侧栏 |
| `--accent-sidebar` | `#8fd4b4` | 侧栏内的强调:active 图标、聚焦边、选中条 |
| `--primary` / `--primary-foreground` | `#082d4f` / `#f3f8f5` | 主区主按钮 |
| `--primary-sidebar` / `--primary-sidebar-foreground` | `#e9f0f6` / `#082d4f` | 侧栏上的主按钮(「新建任务」) |
深色与浅色下,侧栏三令牌别名到主区:`--primary-sidebar` 同 `--primary`,深色 `--accent-sidebar` 同 `--accent`。浅色侧栏是白底,`--accent-sidebar` 改走 `--accent-text`(`#0b7fff` 在白底上不足 4.5:1)。侧栏内的 active、聚焦和主按钮只消费这组令牌,不直接用主区 `--accent` / `--primary`。
### 2.6 文档纸面(主题不变量)
Office 分页预览是**内容**,不是界面。纸面与默认墨色固定,三套主题同值:
| 令牌 | 值 | 用途 |
|---|---|---|
| `--paper` | `#ffffff` | docx 页、幻灯片等文档纸面 |
| `--paper-ink` | `#000000` | 纸面上没有自带颜色的文字的默认墨色 |
规则:保留文档自己的字号、颜色、表格和图片样式。禁止用 `--bg` / `--text` 等主题令牌覆盖这些内联样式。界面只负责纸面周围的底座(`--bg-inset`)和按栏宽等比缩放。
## 3. 字号标尺(唯一字号体系)
全局唯一可调变量 `--ui-font-size`(默认 14px),派生:
| 令牌 | 公式 | 默认 | 角色 |
|---|---|---|---|
| `--fs-ui-xl` | +4px | 18 | 阅读标题 h1 |
| `--fs-ui-lg` | +2px | 16 | 阅读标题 h2 |
| `--fs-ui-base` | = | 14 | 正文、常用按钮、区块标题 |
| `--fs-ui-caption` | −1px | 13 | 紧凑辅助文案 |
| `--fs-ui-sm` | −2px | 12 | 次要信息、行内代码 |
| `--fs-ui-xs` | −3px | 11 | 仅徽标与图标性字符 |
| `--fs-ui-tooltip` | 同 `--fs-ui-sm` | 12 | 提示气泡。不另起字号 |
| `--fs-code` | −2px | 12 | 代码块、终端、Diff。随 `--ui-font-size` 缩放 |
规则:UI 组件一律用标尺令牌;禁止行内 `font-size` 数值与 Tailwind 式任意字号
(守护测试棘轮拦截)。用户调字号只改 `--ui-font-size`,不改根字号;图标、间距、圆角不随字号缩放。
设置中心「界面字号」提供 13 / 14 / 16 / 18 四档,写入 `--ui-font-size`,只存在本机(`localStorage`),不进账号设置。
表头用 `--fs-ui-sm` + `--text-dim`,不用 xs,也不要对中文做 `uppercase`。
例外:文档正文保留自己的阅读字号(约 13.5px),不跟界面标尺走。
字体:`--font` 系统栈优先(-apple-system/PingFang SC…);路径、命令、代码、快捷键用 `--mono`。
## 4. 间距
基数 4px。节奏:4(图标与文字)→ 8(控件内边距/行内间隙)→ 12(紧凑列表行)→
16(卡片/面板标准内边距)→ 20–24(大区块/对话框内部)。用少量重复间距,不用任意值。
## 5. 圆角(按嵌套层级,不按组件重要性)
| 令牌 | 值 | 用途 |
|---|---|---|
| `--radius-xs` | 4 | 最内层(嵌在 6px 控件里的小元素) |
| `--radius-sm` | 6 | 基础控件(嵌套时降档)、chip |
| `--radius` | 8 | 输入、菜单壳、工具行 |
| `--radius-lg` | 12 | 卡片、气泡、工具调用块、**面板(见 §6)** |
| `--radius-xl` | 16 | 对话框、全屏视图壳 |
| `--radius-full` | 999 | 仅用于刻意的胶囊/圆形 |
嵌套降档:12 → 8 → 6 → 4;最内层不低于 4。对话框内部重新从 12 起算。
禁止任意值。`rounded-full` 不因组件类型自动获得。
## 6. 布局:面板化工作区
桌面工作区 = 浮在 `--bg-inset` 底座上的**独立圆角面板**(左栏 / 对话主区 / 预览区 / 右栏):
面板 `--radius-lg` 圆角 + `--border-soft` 发丝描边,面板之间 **4px 间隙**,应用四周 4px 内衬。
拖拽分隔条:透明 4px 命中区,hover/拖拽时显示 2px `--border-strong` 指示线(两端留出面板圆角)。
预览区插在对话与右栏之间,只在当前会话有打开的文件时出现。宽度可拖(420–1100),
用 `--bg`,不受右栏 560 上限约束。打开第一张标签时收起右栏,关掉最后一张时恢复右栏原状。
标签按会话记住,切回该会话时恢复。
层次规则:左栏与右栏用 `--bg-panel`,对话主区与预览区用 `--bg`;窄屏可退化为通栏。
信息架构原则:**对话优先**——普通用户仅凭对话即可完成全部工作,右栏纯辅助、可完全收起;
系统管理类视图独立成区(管理员专属入口),不混入用户设置。
## 7. 海拔(Elevation)
克制深度,分层顺序:背景对比 > 发丝描边 > 浮层阴影 > 注意级阴影。
- 基础层:无阴影,靠背景阶梯;
- 卡片:无阴影或 `--shadow-md` 极弱;
- 菜单/弹层:`--shadow-md`;
- Toast/重要浮卡:`--shadow-lg`。
禁止用大软阴影做普通布局分层。
## 8. 动效(MotionKit)
动效解释状态变化,不装饰屏幕。快、低调;禁止长弹簧(仅点赞/完成反馈可用一次过冲)。
**全部动效经 `@ui/motion.css` 的 `mk-*` 工具类消费;组件文件禁止私有 `@keyframes`**
(守护测试拦截)。所有动效在 `prefers-reduced-motion: reduce` 下禁用。
| 工具类 | 参数 | 用途 |
|---|---|---|
| `mk-stream-in` | opacity,900ms `cubic-bezier(0.16,1,0.3,1)` | 流式内容进场(可按 token 加延迟) |
| `mk-rise-in` | fade + translateY(4px),180ms | 列表行/卡片进入 |
| `mk-waterfall` | clip-path + translateY(−12px),260ms `cubic-bezier(0.22,1,0.36,1)` | 建议列表逐条瀑布 |
| `mk-col` / `mk-col-inner` | 高度 grid-rows 300ms ease-in-out + 内层 fade | 折叠/展开(@ui Collapsible) |
| `mk-sweep` | 文字扫光,300% 渐变 4s linear | **运行态指示(不用 spinner)** |
| `mk-breathe` | opacity .4↔1,1.2s | 状态点呼吸 |
| `mk-pop` | 450ms `cubic-bezier(0.34,1.56,0.64,1)` | 点赞/完成过冲反馈(唯一弹性) |
| `mk-shimmer` | 背景扫光 1.8s linear | 加载占位 |
| `mk-overlay-in` / `mk-modal-in` | 140ms fade / 160ms fade+translateY(6px)+scale(.99) | 弹层进入 |
| `mk-panel-grow` | flex-grow 过渡 200ms ease-out(用时挂、transitionend 摘) | 面板开合 |
## 9. 组件范式
### 9.1 工具调用块(ToolBlock 契约,参照 ZCode ToolLayout)
单行摘要:`[图标][工具名][主文本][副文本][状态词]`。
- 运行中:工具名文字扫光(`mk-sweep`),状态词最弱色;**不用旋转图标**(长流式期省渲染);
- 完成默认收起;`autoOpen`(如 edit/read 类)运行时自动展开一次,用户可再收起;
- 完成边沿(running→completed)自动收起一次,不阻止用户手动展开;
- 展开态按 id 记忆,切回不丢;
- 失败不强制展开:状态词虚线下划线,hover tooltip 给报错,支持一键复制;
- 内容懒渲染,收起后延迟卸载(300ms,配合高度动画)。
- 模型、卡片和文档里的 HTML 只经 `@ui` `safeHtml` 写入。外部图片和音视频不直接加载,改成带来源域名的链接;同源地址、`data:image` 和 `blob:` 照常显示。
### 9.2 折叠(@ui Collapsible 原语)
一切折叠区(过程输出、长回复、任务卡)用它:外壳高度动画 + 内容 fade 两层分离、
300ms 延迟卸载、展开态记忆。禁止再写 `<details>` 折叠。
### 9.3 一个动作一个入口
同一对象只允许一个主要操作路径:一个工件 = 一个预览落位(对话右侧预览区)+ 预览区标题栏上的一个下载。
对话里的文件卡片负责打开这个预览区;卡片菜单里的下载是同一下载动作的就近入口,不另开预览器。
全屏 overlay 是预览区的放大,不是第二落位。禁止弹窗套弹窗。
### 9.4 按钮
Primary(`--primary` 反色)、Ghost(透明,hover 出表面)、Danger(语义红)。
同一面板内保持动作层级,不把每个动作都升为 primary。
### 9.5 菜单与浮层
菜单壳 `--radius`(8) + `--shadow-md` + 紧凑行(`--radius-sm` 6 的行、`--fs-ui-base`);
菜单是紧凑动作行,不是迷你按钮。交互浮层必须盖过被动 tooltip。
### 9.6 工作时间线与标签条
助手消息在运行中按时间线逐行展开,终轮结束后折成一行。
- 运行中过程块展开,块头是中文阶段(思考中、正在编写、正在运行并计时、回复中、整理回复中),带 `mk-sweep`。
对用户的解说按正文样式直接显示。查阅和搜索合并成一行;执行、写入、委派每次一条 ToolBlock:
编写参数时显示「编写中」和脚本尾部,运行时显示计时和输出尾部,结束后可展开看完整参数与结果。
终轮检查在过程区单独一行(通过,或未通过及原因),不写进给用户的回复。
- 终轮结束后,过程段收进 Collapsible,触发行为「已工作 X 分 Y 秒 · N 次工具调用 · N 个文件」。
用户在运行中手动折过的,结束后沿用这次选择。最终回复(终轮正文、交付物、错误)留在折叠行下面;
交付物卡片等到最终回复出来、这一轮结束后才出现,工作过程中不挂预览条。
若这次没有终轮正文,把最后一段解说提到折叠行下面,不把回复藏进过程里。
不在每一轮 `responding` 时来回折叠。同一轮同名工件只留最新一张,并注明更新次数。
- 文件卡片:图标、名称、「类型 · 大小」、右侧「预览」。正文里的 `art_` 编号若对得上工件,在正文后补一张卡片;
对不上则显示「未找到该文件」,不伪装成可打开的文件。
- 标签条用 `@ui` `TabStrip`:点击激活、× 关闭、中键关闭,溢出横向滚动。只消费令牌与 `mk-*`。
## 10. 信息架构与文案
- 普通用户界面只暴露任务与对话;插件/代理/治理类能力归系统管理区(管理员可见)。
- 右栏收起时功能零缺失(D31:弹层不承载唯一步骤,每个操作另有对话内路径)。
- 中文文案:动宾结构、不带句点结尾;快捷键用 `⌘`/kbd 标注。
- 布局按 `--text-expansion`(1.3)给按钮和标签留膨胀空间。不要把宽度定死成当前中文的字数。截断不是唯一生存手段。
### 10.1 快捷键
| 动作 | 按键 |
|---|---|
| 新建任务 | ⌘N / Ctrl+N |
| 折叠或展开左栏 | ⌘B / Ctrl+B |
| 打开第 n 个工作区 | ⌘1–9 / Ctrl+1–9 |
## 11. 禁止清单(守护测试覆盖项)
1. 组件/样式文件里新增裸色值(hex/rgb 字面量)——走令牌;
2. 组件文件里私有 `@keyframes`——走 MotionKit;
3. TSX 行内 `font-size`——走字号标尺;
4. 运行态用旋转 spinner——用 `mk-sweep`/`mk-breathe`;
5. 弹窗套弹窗;
6. 同一对象出现第二个预览落位(预览只在预览区,全屏是它的放大);
7. `<details>` 折叠——用 Collapsible。
8. 绕过 `safeHtml` 直接把 HTML 字符串写进页面(`dangerouslySetInnerHTML` 或非空的 `innerHTML` 赋值)。
9. 文字与背景的对比度低于门槛(正文与文字档 4.5:1,装饰 faint 与图形语义色 3:1)——`contrast-guard.test.ts`。
## 12. 演进规则
改风格须在**同一变更集**中成对修改:UI 仓 PR 调整 `tokens.css`(必要时 `motion.css`),
Dev 组合 PR 更新 `DESIGN.md` 并固定对应 UI 提交;两者互链,附前后值对照并验证精确组合。
不允许只改代码不改文档。新增视觉规则先问:它属于结构、表面、交互还是状态?
拿不准时,选更安静的方案、用更强的信息层级。
### 12.1 对比度与字号(2026-10-05)前后值
| 令牌 | 之前 | 之后 |
|---|---|---|
| `--text-dim` | 三主题 62% | 深 66% / 浅 68% / 墨绿 70% |
| `--text-faint` | 深 38% / 浅与墨绿 42% | 深 52% / 浅与墨绿 58% |
| `--text-sidebar-dim` / `faint`(墨绿) | 72% / 46% | 78% / 62% |
| `--warn`(浅色、墨绿) | `#e07b00`(白底 2.99:1) | `#d17300` |
| `--fs-ui-xs` | −4px(10px) | −3px(11px),仅徽标 |
| 文字档 `*-text`、`--text-on-semantic`、`--accent-sidebar`、`--primary-sidebar`、`--fs-code`、`--idle-text` | 无 | 见 §2.4–§3。图形色不再当文字用 |