本文整理开源项目 open-claude-ui 的视觉语言、设计令牌、组件规范与交互物理,基于 2026 年 10 月 15 日读取的代码快照 2834bc1。这里的 CDS 指该项目对 Claude 风格界面的开源实现与整理;文中的参数不应视为 Anthropic 官方发布的设计规范。
阅读时需要区分两层:AGENTS.md 规定的设计目标,以及 CSS、TypeScript 文件实际实现的值。两者目前存在差异,第 19 节集中对照。
1. 一句话概括
open-claude-ui 的设计目标不是做一个“炫技 UI 库”,而是还原现代桌面 AI 客户端中那种:
安静、温润、可信、有质量感的编辑式界面;它靠低对比表面、发丝边框、陶土橙点缀和物理弹簧动效,而不是靠高饱和渐变、强发光和夸张弹跳。
如果用几个关键词描述:
- Editorial Warmth:人文、编辑排版、纸感。
- Clay / Terracotta:陶土橙作为唯一强品牌色。
- Low-Contrast Surface Layering:微亮度层级,不靠硬边框。
- Hairline Border:发丝线边框。
- Physics-Based Motion:弹簧、阻尼、质量。
- Interaction Guardrails:IME、滚动劫持、拖拽死区、容器响应式防御。
- Zero Binary Asset:不引入专有字体和录音资产。
2. 设计哲学
2.1 温润,而不是科技冷感
这套系统的第一视觉印象是“暖”。
它刻意避免:
- 赛博朋克式蓝紫渐变;
- 高饱和霓虹色;
- 强发光边框;
- 玻璃拟态滥用;
- 大面积品牌色铺陈;
- 厚重黑色描边。
它追求的是:
- 暖灰背景;
- 近白纸面;
- 温暖陶土橙点缀;
- 阴影极轻;
- 文本层级清晰但不刺眼;
- 界面像一本安静的现代编辑器。
2.2 克制
品牌色 #d97757 是系统里少数强情绪颜色,因此它被严格控制在:
- 主按钮;
- 焦点环;
- 状态呼吸点;
- 激活态;
- 少量强调文本;
- 拖拽 glow;
- 思考状态微光。
它不做大面积铺陈,也不承担背景色职责。
2.3 层级来自亮度差,而不是强轮廓
面板、卡片、输入区、弹层之间的层级主要靠:
- 微亮度差异;
- 发丝线;
- 轻阴影;
- 高度语义 token。
而不是靠:
- 2px 粗边框;
- 明显黑色投影;
- 强背景色分割。
2.4 动效有“质量”
这里的动画不是 opacity 0 -> 1 的机械过渡,而是模拟有质量的物体:
也就是:
m:质量;c:阻尼;k:刚度;x:当前位置;x_target:目标位置。
这套模型带来的直接感受是:
- 点击有按压反馈;
- 弹层有轻微落地感;
- 抽屉像磁吸归位;
- 消息气泡不是“闪现”,而是“进入”。
3. 色彩体系
3.1 品牌色:Clay / Terracotta
当前 code-examples/cds-theme.css 中的实现:
| Token | Light | Dark | 语义 |
|---|---|---|---|
--cds-clay | #d97757 | #d97757 | 主品牌色 |
--cds-clay-hover | #cc5a36 | #e08264 | Hover |
--cds-clay-light | #fbf3ef | #fbf3ef(未单独覆盖) | 基础极浅品牌底色 |
--cds-fill-brand-subtle | var(--cds-clay-light) | rgba(217, 119, 87, 0.15) | 适配明暗主题的品牌底色 |
--cds-text-accent | #d97757 | #d97757 | 强调文本 |
--cds-fill-brand | #d97757 | #d97757 | 主按钮填充 |
--cds-fill-brand-hover | #cc5a36 | #e08264 | 主按钮 hover |
设计意图:
- Light mode 下 hover 加深,保持纸面稳定;
- Dark mode 下 hover 变亮,符合深色界面交互惯例;
- 品牌色承担“焦点、确认、激活”,不是大面积装饰。
3.2 文本颜色
| Token | Light | Dark | 用途 |
|---|---|---|---|
--cds-text-primary | #151515 | #f5f5f5 | 主文本 |
--cds-text-secondary | #525252 | #a3a3a3 | 次级文本 |
--cds-text-muted | #8a8a8a | #666666 | 弱文本、占位符 |
文本颜色不是纯黑纯白,而是略带灰度,降低视觉攻击性。
3.3 透明度阶梯
系统使用 alpha token 构建交互填充和边框:
| Token | Light | Dark | 用途 |
|---|---|---|---|
--cds-alpha-0 | hsla(0,0%,8%,0) | rgba(255,255,255,0) | 透明 |
--cds-alpha-1 | hsla(0,0%,8%,0.05) | rgba(255,255,255,0.05) | Ghost hover |
--cds-alpha-2 | hsla(0,0%,8%,0.10) | rgba(255,255,255,0.09) | 标准边框 |
--cds-alpha-3 | hsla(0,0%,8%,0.20) | rgba(255,255,255,0.18) | 强边框 |
--cds-alpha-4 | hsla(0,0%,8%,0.35) | rgba(255,255,255,0.30) | 重分割线 |
这层 alpha 体系让 hover / selected / border 不需要额外调色,直接复用同一亮度语言。
3.4 危险色
| Token | Light | Dark |
|---|---|---|
--cds-fill-danger | #ef4444 | #f87171 |
危险色用于确认对话框、破坏性操作,不与品牌 Clay 混用。
4. 表面层级与空间结构
4.1 当前 CSS 实现
code-examples/cds-theme.css 中的 Surface 阶梯:
| Token | Light | Dark | 语义 |
|---|---|---|---|
--cds-surface-0 | #f5f5f3 | #0b0b0a | 页面底色 Canvas |
--cds-surface-1 | #fcfcfb | #151515 | 侧边栏 / 中间层 |
--cds-surface-2 | #ffffff | #1a1a19 | 消息气泡 / 卡片 |
--cds-surface-3 | #ffffff | #20201e | 输入区 / 高层表面 |
--cds-surface-popover | #ffffff | #222220 | 悬浮弹层 |
4.2 层级使用规则
- 页面永远比内容容器暗或更“远”;
- 输入区比页面更亮,制造“可输入终端”的引导;
- Popover 比普通卡片更亮或更实,保证浮层可读;
- Dark mode 下通过更亮的高层表面与 alpha 叠加保持层级。
4.3 设计特征
这套 Surface 体系的关键不是“颜色差异大”,而是:
- 差异小但稳定;
- 明度递进语义一致;
- 设计意图是避免极端对比;当前浅色 CSS 仍使用纯白高层表面,落地时需与规范对齐;
- 让界面看起来像纸面堆叠,而不是塑料卡片堆叠。
5. 边框与阴影策略
5.1 发丝边
Light mode:
--高分屏下会缩至:
--甚至:
--/ 3);目的:
- 避免 1px 线在高 DPI 屏幕上过重;
- 保持“纸面被切开”的精细感。
5.2 单闭合边框原则
这是组件规范里的重要规则:
如果外层容器已经有 border,内部次级按钮、chip、附件胶囊不应再加 border。
例如:
- Composer 外层已有
inset 0 0 0 1px border; - 内部 Ghost 按钮、chip 使用填充色;
- 不出现“边框套边框”。
这能显著降低视觉噪点。
5.3 焦点环
焦点环不是简单的 outline,而是带品牌色的复合阴影:
Light mode:
--),
0 0 0 1),
0 0 6);Dark mode 会增加光晕强度:
0 0 8);特征:
- 双层;
- Clay 色;
- 微光;
- 可见但不刺眼。
5.4 阴影尺度
Light mode 中阴影非常轻:
| Token | 典型用途 |
|---|---|
--cds-shadow-sm | 普通卡片 |
--cds-shadow-md | 弹层、菜单 |
--cds-shadow-lg | 大浮层 |
--cds-shadow-popover | Popover 双环 |
--cds-shadow-composer | 输入框 |
--cds-shadow-drop-glow | 拖拽态 / 强调态 |
Composer 的 light 阴影只有:
0 4)这说明系统的空间感主要靠:
表面亮度 + 发丝边 + 极轻阴影
而不是厚投影。
6. 圆角拓扑
圆角是这套系统里最能体现组件性格的部分。
6.1 当前 CSS token
| Token | 值 | 用途 |
|---|---|---|
--radius-xs | 2px | 极小元素 |
--radius-sm | 4px | 小控件 |
--radius-md | 6px | 标准按钮 |
--radius-lg | 8px | 常规交互按钮 |
--cds-panel-radius | 10px | 面板、卡片 |
--radius-xl | 12px | 大按钮、代码块 |
--radius-2xl | 16px | 对话框 |
--cds-message-bubble-radius | 18px | 用户消息气泡 |
--cds-radius-composer | 20px | 主输入框 |
--df-radius-pill | 999px | 胶囊控件 |
6.2 规律
- 小控件:小圆角,保持精度。
- 面板:中等圆角,稳定。
- 弹窗:较大圆角,柔和不突兀。
- 输入框:20px,亲和力强。
- 分段选择器:999px,形成胶囊形态。
6.3 组件对应
| 组件 | 圆角气质 |
|---|---|
| 按钮 | 精准、克制 |
| Segmented Control | 胶囊、顺滑 |
| Chat Composer | 大圆角、纸面容器 |
| User Bubble | 柔和对话容器 |
| Dialog | 稳定、正式 |
| Code Block | 12px,技术感但不生硬 |
7. 字体与排版规则
7.1 不提交专有二进制字体
仓库策略:
- 不包含
.ttf/.otf; - 不包含商业字体;
- 使用系统字体回退栈。
Tailwind 配置中包含:
system-ui以及常规系统字体序列。
这保证了:
- 无需随项目分发额外字体文件;
- 包体干净;
- 各平台使用原生最佳字体渲染。
7.2 数字必须稳定
所有动态数字必须使用:
或者 Tailwind:
tabular-nums适用:
- 时间;
- 倒计时;
- token 用量;
- token 预算;
- 音频频率;
- diff 行号;
- 消息长度;
- 成本估算。
目的:
- 数字变化时宽度不抖动;
- 表格和代码对齐稳定;
- 避免流式输出时布局跳动。
7.3 深色模式字重补偿
仓库包含深色模式下的字重光学补偿规则,例如:
这类规则用于对抗浅色文字在深色背景上的视觉膨胀或发虚。
7.4 图标光学对齐
行内图标通常需要垂直光学修正,文档体系提到类似:
目的是让图标和文字基线视觉对齐,而不是几何对齐。
8. 动效哲学:物理弹簧而非线性动画
8.1 核心原则
系统明确反对:
推荐:
- Framer Motion spring;
- 精调 CSS cubic-bezier;
- 有质量、有阻尼、有收敛的运动。
8.2 二阶阻尼谐振子
ClaudeMotionPresets.ts 中包含数学求解器:
并计算:
其中:
- :欠阻尼,阶跃响应会出现过冲;
- :临界阻尼;
- :过阻尼,零初速度阶跃响应无过冲。
这意味着动效不是视觉猜测,而是可以用物理参数描述。
8.3 动效的三个层级
-
触觉反馈
- 按钮按压;
- 小控件;
- 时间极短。
-
内容进入
- 消息气泡;
- 卡片展开;
- Popover。
-
结构移动
- 抽屉吸附;
- 面板拖拽;
- 分割条 snap。
9. 四套弹簧预设与使用场景
注意:本节以
code-examples/ClaudeMotionPresets.ts当前实现为准。仓库中的AGENTS.md对预设命名和参数还有另一套“规范意图值”,详见第 19 节。
9.1 SPRING_BOUNCY
当前实现:
export const SPRING_BOUNCY: Transition = {
type: "spring",
stiffness: 600,
damping: 30,
mass: 1.0,
};文件注释描述:
- 按钮点击;
- 开关切换;
- 图标按压;
- 高频微弹;
- 利落归位。
9.2 SPRING_SNAPPY
当前实现:
export const SPRING_SNAPPY: Transition = {
type: "spring",
stiffness: 320,
damping: 28,
mass: 1.0,
};文件注释描述:
- 气泡上浮;
- 卡片展开;
- Popover 唤起;
- 沉稳顺滑;
- 微冲后平稳着陆。
9.3 SPRING_GENTLE
当前实现:
export const SPRING_GENTLE: Transition = {
type: "spring",
stiffness: 380,
damping: 18,
mass: 1.0,
};文件注释描述:
- 点赞;
- 复制成功;
- 新消息微提示;
- 情绪反馈更明显;
- 跳跃感更强。
9.4 SPRING_HEAVY_SNAP
当前实现:
export const SPRING_HEAVY_SNAP: Transition = {
type: "spring",
stiffness: 1200,
damping: 80,
mass: 0.1,
};文件注释描述:
- 抽屉和侧边栏手势吸附;
- 面板分割拖拽;
- 过阻尼;
- 零过冲;
- 磁吸般咬合。
9.5 快速决策树
| 场景 | 推荐预设 |
|---|---|
| 按钮点击 | SPRING_BOUNCY |
| 开关切换 | SPRING_BOUNCY |
| Popover | SPRING_SNAPPY |
| 卡片展开 | SPRING_SNAPPY |
| 消息进入 | SPRING_SNAPPY / 定制变体 |
| 成功反馈 | SPRING_GENTLE |
| 抽屉吸附 | SPRING_HEAVY_SNAP |
| 分割条 snap | SPRING_HEAVY_SNAP |
10. CSS 缓动曲线与时间尺度
10.1 标准 CSS 曲线
ClaudeMotionPresets.ts 中定义:
| 名称 | 曲线 | 用途 |
|---|---|---|
OVERSHOOT | cubic-bezier(0.34, 1.3, 0.64, 1) | 气泡、胶囊入场 |
EASE_OUT_EXPO | cubic-bezier(0.16, 1, 0.3, 1) | 阴影、焦点、模糊渐变 |
DECEL | cubic-bezier(0.165, 0.84, 0.44, 1) | 抽屉滑入 |
SHARP_PRESS | cubic-bezier(0.32, 0.72, 0, 1) | 按压缩放 |
10.2 常用时间尺度
从组件代码中可见:
| 时长 | 用途 |
|---|---|
100ms | 瞬时按压 |
120ms | 分段控件咬合 |
150ms | hover / scroll mask / 冷却窗口 |
200ms | Composer / panel 过渡 |
220ms | 阴影与边框过渡 |
300ms | 面板滑入 |
2.4s | 状态呼吸灯 |
1.2s | active pulse |
10.3 动效纪律
- 不做长时间漂浮;
- 不做夸张回弹;
- 不让动画阻塞交互;
- 不使用
transition: all大范围模糊动画目标; - 阴影、颜色、transform 分开控制;
- 动画应可被用户输入打断。
11. 滚动、渐隐与流式输出行为
11.1 滚动渐隐
ScrollFadeContainer.tsx 使用非线性 alpha mask,而不是简单线性渐变。
核心思想:
- 顶部和底部边缘不生硬切断;
- mask 随滚动位置动态调整;
- 动画时长约
150ms; - 使用
transition-[mask-image]。
这类设计让长列表在视觉上像“自然淡出”,而不是被硬裁剪。
11.2 滚动 pinning 防劫持
useClaudeScrollPinning.ts 的核心规则:
performance.now() - lastUserInputAt > 150也就是:
用户手动滚动后,150ms 内不要强制接管滚动。
它还包含底部容差,例如约 40px:
- 用户接近底部时继续 pin;
- 用户向上离开底部时停止 pin;
- 流式输出不能 hijack 视口。
11.3 流式 UI 稳定性
为了防止 LLM 流式输出造成跳动,系统要求:
- 动态数字
tabular-nums; - 高度变化使用稳定 spring;
- 滚动行为有冷却窗口;
- 行号和表格使用固定宽度;
- 状态切换有明确生命周期。
12. 核心组件风格
12.1 Button
特点:
- 尺寸阶梯:XS / SM / MD / LG;
- Variant:Primary、Secondary、Ghost、Outline、Danger;
- Primary 使用 Clay;
- Ghost 依赖透明填充;
- Secondary 依赖低强度填充;
- 按压时使用轻微 scale,例如
active:scale-[0.98]或0.95; - 不用厚边框制造层级。
12.2 Segmented Control
特点:
999px胶囊轨道;- thumb 绝对定位;
- 2px 几何 padding;
- CSS 与 Framer Motion 双模式;
- 极窄容器下隐藏文本只保留图标;
- thumb 使用快速咬合动画。
CSS 模式:
left = calc(2px + activeIndex * (100% - 4px) / total)
width = calc((100% - 4px) / total)上面是几何计算示意;activeIndex 和 total 需要由组件逻辑代入。
12.3 Chat Composer
特点:
- 20px 圆角;
- 使用
field-sizing: content自适应高度; - 高度范围约 48px 到 384px;
- 阴影极轻;
- 焦点时出现 Clay 复合焦点环;
- 内部工具按钮不再重复加边框;
- Enter 发送必须处理 IME composition。
12.4 Message Bubbles
风格是不对称:
- User:轻背景、18px 圆角、气泡感;
- Assistant:透明排版、无边框,不使用气泡;
- 对话流更像文档流,而不是纯 IM。
这符合 AI 产品中“助手回答是内容主体”的阅读模式。
12.5 Thinking Accordion
特点:
- 折叠展开使用 spring / grid 高度动画;
- 单个 Clay 呼吸点;
- 生成过程中强制展开;
- 状态克制,不做复杂噪声。
12.6 Confirmation Dialog
特点:
- 16px 圆角;
- Popover 双环阴影;
- 高斯模糊遮罩;
- Focus trap;
- 支持 Danger 和 Default 两种语义。
12.7 Attachment Card
特点:
- 面板半径约 10px;
- 桌面端磁贴布局;
- 输入框内则为行内胶囊;
- 文件缩略图有 grow-in 入场;
- 不使用复杂描边。
13. 交互防御规则
这部分是本仓库最重要的工程价值之一。
13.1 CJK IME 守卫
中文、日文、韩文输入法在选词或确认候选字时会触发 Enter。
如果直接监听:
if (e.key === "Enter") send();会导致用户还没完成输入就把半成品消息发送出去。
正确写法:
const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
if (e.nativeEvent.isComposing || e.keyCode === 229) return;
if (e.key === "Enter" && !e.shiftKey) {
e.preventDefault();
handleSendMessage();
}
};必须同时处理:
isComposing;keyCode === 229。
13.2 滚动劫持防御
LLM 流式输出时不能每来一个 token 就强制 scroll to bottom。
规则:
- 用户手动滚动后记录时间;
- 150ms 内不抢滚动;
- 底部 40px 容差;
- 用户离开底部后停止 pin;
- 用户重新回到底部附近才恢复 pin。
13.3 拖拽死区
拖拽类交互必须设置约 4px deadzone。
适用于:
- 侧边栏列表拖拽;
- 面板分割条;
- 画布拖动;
- Lightbox pan / zoom。
目的:
- 点击不被误判为拖拽;
- 鼠标微抖不触发 reorder;
- 手势意图更明确。
13.4 容器响应式
系统使用 @container,而不是只依赖 viewport。
原因:
- 组件可能出现在侧边栏、弹窗、分栏中;
- 组件真实可用宽度由容器决定;
- 只看 viewport 会误判空间。
典型行为:
- Segmented Control 在极窄宽度下隐藏文字;
- 只保留 icon;
- 防止 glyph break 和文本挤压。
14. 可访问性与键盘行为
14.1 Roving Focus
useClaudeRovingFocus.ts 提供:
- 一维列表导航;
- 二维网格导航;
- Arrow keys;
- Home / End;
- 边界跳转;
- 符合 WAI-ARIA 模式。
14.2 Focus trap
对话框和 Popover 需要:
- 焦点进入;
- Tab 循环限制;
- Escape 关闭;
- 初始焦点明确;
- 关闭后焦点恢复。
14.3 焦点视觉
焦点不是浏览器默认 outline,而是:
- Clay 色;
- 双环;
- 微光;
- 高可见度;
- 不破坏整体气质。
15. 资产与版权边界
15.1 不提交专有二进制资产
仓库明确禁止:
.ttf.otf.mp3.wav
如果属于专有商业资产,也不应被分发。
15.2 字体替代方案
使用系统字体栈,保证:
- 避免额外分发专有字体文件;
- 无额外网络依赖;
- 平台原生渲染质量。
15.3 音频替代方案
提示音不使用录音文件,而是通过 Web Audio API 振荡器合成。
特点是:
- 纯代码;
- 零二进制;
- 可控频率;
- 防爆音 gain ramp;
- 音量轻,约 30% 级别。
16. 工程结构与技术栈
16.1 技术栈
| 类别 | 技术 |
|---|---|
| UI | React 18+ |
| 类型 | TypeScript 5.5+ |
| 样式 | Tailwind CSS 3.4+ |
| 动效 | Framer Motion 11+ |
| 图标 | lucide-react |
| 桌面 | Electron 31 |
| 构建 | tsc |
16.2 核心目录
code-examples/
cds-theme.css
tailwind.config.js
ClaudeMotionPresets.ts
CdsButton.tsx
SegmentedControl.tsx
ChatComposer.tsx
ChatMessageBubbles.tsx
ThinkingAccordion.tsx
ScrollFadeContainer.tsx
useClaudeScrollPinning.ts
...16.3 文档体系
docs/
01-设计哲学与设计令牌体系.md
02-基础原子组件与交互控件.md
03-会话核心流与指令交互引擎.md
04-动效物理学、着色器与环境光影.md
05-视听多媒体与产物交互物理学.md
06-系统级桌面架构与协作拓扑.md
07-工程配置与资产代码库总览.md
08-AI-Agent-前端-UI-与动效开发指南.md
09-Claude-Desktop-2.0-全量版本更新深度逆向分析.md16.4 质量门禁
AGENTS.md 要求代码修改后执行:
两者都必须 0 error。
以上是修改组件代码时的仓库要求;本文的源码整理不代表这些组件已完成跨平台运行与视觉验收。
17. 反模式清单
以下是这套体系明确不推荐的做法。
视觉反模式
- 使用纯黑
#000作为主背景; - 使用纯白
#fff作为大面积背景且不加层级处理; - 使用高饱和蓝紫渐变;
- 大面积使用 Clay 色;
- 厚边框套厚边框;
- 卡片内部按钮再画边框;
- 使用强霓虹 glow;
- 用深黑粗描边模拟层级。
动效反模式
transition: all 0.3s linear;transition: all 0.5s ease;- 夸张 bounce;
- 长时间漂浮;
- 所有组件共用一个动画参数;
- 让动画阻塞输入;
- 流式输出时反复强制滚动到底部。
交互反模式
- Enter 直接发送,不判断 IME;
- 忽略
keyCode === 229; - 只用 viewport 做组件响应式;
- 拖拽没有 deadzone;
- 弹层没有 focus trap;
- 动态数字不使用
tabular-nums。
资产反模式
- 提交商业字体;
- 提交录音提示音;
- 添加来源不明的图标资源;
- 使用专有 UI 截图作为可再分资产。
18. 落地 Checklist
视觉检查
-
使用
--cds-*语义 token; - 不硬编码散乱 HEX;
- Light / Dark 都检查;
- Surface 层级符合 0~3 语义;
- 品牌色只用于强调;
- 圆角使用 token;
- 边框遵守单闭合原则;
- 阴影保持轻量;
- 深色模式不是简单反色。
排版检查
- 使用系统字体栈;
- 不引入二进制字体;
-
动态数字使用
tabular-nums; - 行内图标做光学对齐;
- 深色模式检查字重补偿。
动效检查
- 优先使用 canonical spring presets;
-
不写
transition: all ... linear; - 按场景选择 Bouncy / Snappy / Gentle / Heavy Snap;
- 弹层、气泡、抽屉使用不同物理参数;
- 动画可以被用户输入打断;
- 阴影和颜色变化使用 expo ease out;
- 按压缩放保持短促。
交互检查
- Composer Enter 有 IME guard;
-
同时判断
isComposing和keyCode === 229; - 滚动 pinning 有 150ms 冷却;
- 拖拽有 4px deadzone;
- 窄容器下组件不破碎;
- 弹层有 focus trap;
- 键盘导航符合 roving focus 模式。
工程检查
-
不提交
.ttf/.otf/.mp3/.wav; - 音效使用 Web Audio API 合成;
-
修改 TS 后运行
npm run typecheck; -
修改 TS 后运行
npm run build; - 两个命令均为 0 error;
-
新组件导出在
src/index.ts中保持一致。
19. 当前仓库中的规范差异
本仓库的 AGENTS.md 和 code-examples/ClaudeMotionPresets.ts 对弹簧预设存在两套不同描述。
19.1 AGENTS.md 中的规范意图
AGENTS.md 描述为:
| 预设 | 参数 | 特征(AGENTS.md 原文描述) |
|---|---|---|
SPRING_SNAPPY | stiffness: 600, damping: 30, mass: 0.6 | ζ 约 0.791,过冲约 1.8%,约 0.22s |
SPRING_BOUNCY | stiffness: 400, damping: 25, mass: 0.8 | ζ 约 0.612,过冲约 8.8%,约 0.38s |
SPRING_GENTLE | stiffness: 220, damping: 24, mass: 1.0 | ζ 约 0.809,过冲约 1.5%,约 0.48s |
SPRING_HEAVY_SNAP | stiffness: 1200, damping: 80, mass: 0.1 | ζ 约 1.826,过阻尼 |
上表右栏保留了规范原文中的数字,但其中两处阻尼比与参数不一致。按第 8 节公式复算:SPRING_BOUNCY 的 ,SPRING_HEAVY_SNAP 的 。因此表中原文过冲与收敛时间不宜直接作为验收值;实际收敛时间还取决于位移、初速度与停止阈值。
19.2 ClaudeMotionPresets.ts 当前实现
| 预设 | 参数 |
|---|---|
SPRING_BOUNCY | stiffness: 600, damping: 30, mass: 1.0 |
SPRING_SNAPPY | stiffness: 320, damping: 28, mass: 1.0 |
SPRING_GENTLE | stiffness: 380, damping: 18, mass: 1.0 |
SPRING_HEAVY_SNAP | stiffness: 1200, damping: 80, mass: 0.1 |
19.3 结论
这可能是两种情况之一:
AGENTS.md描述的是更新后的规范意图,但代码未同步;- 代码是实际实现,
AGENTS.md描述的是另一版逆向结论。
在真实开发中建议:
- 以
AGENTS.md作为 agent 强制规范; - 以
ClaudeMotionPresets.ts作为当前可执行事实; - 修改动效时先统一两者,再开始扩散组件。
另外,AGENTS.md 中描述的 Surface 色值与 cds-theme.css 当前实现也存在差异。例如:
AGENTS.md:light Surface 0 为#fcfcfb;cds-theme.css:light Surface 0 为#f5f5f3。
同样建议先确认目标版本,再统一 token 源头,避免同一系统里出现两套互不一致的值。
19.4 组件实现仍需逐项核对
规范要求不代表每个示例已经实现全部防护。这个快照中的 ChatComposer.tsx 在 Enter 发送路径中尚未检查 isComposing 或 keyCode === 229,还使用了 transition-all 与带边框的内部附件。复用时应按第 13 节补齐输入法守卫,并按边框与动效规范逐项检查。
20. 参考文件
本文主要依据以下文件,链接固定到同一提交,便于复查:
- AGENTS.md
- README.md
- package.json
- code-examples/cds-theme.css
- code-examples/tailwind.config.js
- code-examples/ClaudeMotionPresets.ts
- code-examples/CdsButton.tsx
- code-examples/SegmentedControl.tsx
- code-examples/ChatComposer.tsx
- code-examples/ChatMessageBubbles.tsx
- code-examples/ScrollFadeContainer.tsx
- code-examples/useClaudeScrollPinning.ts
- code-examples/useClaudeRovingFocus.ts
- docs/README.md
- docs/01-设计哲学与设计令牌体系.md
- docs/04-动效物理学、着色器与环境光影.md
- docs/08-AI-Agent-前端-UI-与动效开发指南.md
附:最终风格画像
如果把这套系统交给一个新设计师,只用一段话描述:
使用暖灰纸面和四层微亮度表面构建空间;用陶土橙作为唯一强品牌色,只出现在焦点、确认和激活状态;边框是发丝线,阴影极轻;组件圆角从 6px 到 20px 按语义递进;文本和数字必须稳定;动效来自弹簧物理,有质量、有阻尼、有收敛;交互必须防御 IME、滚动劫持、拖拽误触和窄容器破碎;最终呈现出一个安静、可信、像现代编辑器一样的桌面 AI 界面。
