本文整理开源项目 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 层级来自亮度差,而不是强轮廓

面板、卡片、输入区、弹层之间的层级主要靠:

  1. 微亮度差异;
  2. 发丝线;
  3. 轻阴影;
  4. 高度语义 token。

而不是靠:

  • 2px 粗边框;
  • 明显黑色投影;
  • 强背景色分割。

2.4 动效有“质量”

这里的动画不是 opacity 0 -> 1 的机械过渡,而是模拟有质量的物体:

也就是:

  • m:质量;
  • c:阻尼;
  • k:刚度;
  • x:当前位置;
  • x_target:目标位置。

这套模型带来的直接感受是:

  • 点击有按压反馈;
  • 弹层有轻微落地感;
  • 抽屉像磁吸归位;
  • 消息气泡不是“闪现”,而是“进入”。

3. 色彩体系

3.1 品牌色:Clay / Terracotta

当前 code-examples/cds-theme.css 中的实现:

TokenLightDark语义
--cds-clay#d97757#d97757主品牌色
--cds-clay-hover#cc5a36#e08264Hover
--cds-clay-light#fbf3ef#fbf3ef(未单独覆盖)基础极浅品牌底色
--cds-fill-brand-subtlevar(--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 文本颜色

TokenLightDark用途
--cds-text-primary#151515#f5f5f5主文本
--cds-text-secondary#525252#a3a3a3次级文本
--cds-text-muted#8a8a8a#666666弱文本、占位符

文本颜色不是纯黑纯白,而是略带灰度,降低视觉攻击性。

3.3 透明度阶梯

系统使用 alpha token 构建交互填充和边框:

TokenLightDark用途
--cds-alpha-0hsla(0,0%,8%,0)rgba(255,255,255,0)透明
--cds-alpha-1hsla(0,0%,8%,0.05)rgba(255,255,255,0.05)Ghost hover
--cds-alpha-2hsla(0,0%,8%,0.10)rgba(255,255,255,0.09)标准边框
--cds-alpha-3hsla(0,0%,8%,0.20)rgba(255,255,255,0.18)强边框
--cds-alpha-4hsla(0,0%,8%,0.35)rgba(255,255,255,0.30)重分割线

这层 alpha 体系让 hover / selected / border 不需要额外调色,直接复用同一亮度语言。

3.4 危险色

TokenLightDark
--cds-fill-danger#ef4444#f87171

危险色用于确认对话框、破坏性操作,不与品牌 Clay 混用。


4. 表面层级与空间结构

4.1 当前 CSS 实现

code-examples/cds-theme.css 中的 Surface 阶梯:

TokenLightDark语义
--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:

--cds-ring-hairline: 1px;

高分屏下会缩至:

--cds-ring-hairline: 0.5px;

甚至:

--cds-ring-hairline: calc(1px / 3);

目的:

  • 避免 1px 线在高 DPI 屏幕上过重;
  • 保持“纸面被切开”的精细感。

5.2 单闭合边框原则

这是组件规范里的重要规则:

如果外层容器已经有 border,内部次级按钮、chip、附件胶囊不应再加 border。

例如:

  • Composer 外层已有 inset 0 0 0 1px border;
  • 内部 Ghost 按钮、chip 使用填充色;
  • 不出现“边框套边框”。

这能显著降低视觉噪点。

5.3 焦点环

焦点环不是简单的 outline,而是带品牌色的复合阴影:

Light mode:

--cds-focus-shadow:
  inset 0 0 0 1px var(--cds-surface-1),
  0 0 0 1.5px var(--cds-clay),
  0 0 6px 1px rgba(217, 119, 87, 0.25);

Dark mode 会增加光晕强度:

0 0 8px 2px rgba(217, 119, 87, 0.35);

特征:

  • 双层;
  • Clay 色;
  • 微光;
  • 可见但不刺眼。

5.4 阴影尺度

Light mode 中阴影非常轻:

Token典型用途
--cds-shadow-sm普通卡片
--cds-shadow-md弹层、菜单
--cds-shadow-lg大浮层
--cds-shadow-popoverPopover 双环
--cds-shadow-composer输入框
--cds-shadow-drop-glow拖拽态 / 强调态

Composer 的 light 阴影只有:

0 4px 20px rgba(0, 0, 0, 0.035)

这说明系统的空间感主要靠:

表面亮度 + 发丝边 + 极轻阴影

而不是厚投影。


6. 圆角拓扑

圆角是这套系统里最能体现组件性格的部分。

6.1 当前 CSS token

Token值用途
--radius-xs2px极小元素
--radius-sm4px小控件
--radius-md6px标准按钮
--radius-lg8px常规交互按钮
--cds-panel-radius10px面板、卡片
--radius-xl12px大按钮、代码块
--radius-2xl16px对话框
--cds-message-bubble-radius18px用户消息气泡
--cds-radius-composer20px主输入框
--df-radius-pill999px胶囊控件

6.2 规律

  • 小控件:小圆角,保持精度。
  • 面板:中等圆角,稳定。
  • 弹窗:较大圆角,柔和不突兀。
  • 输入框:20px,亲和力强。
  • 分段选择器:999px,形成胶囊形态。

6.3 组件对应

组件圆角气质
按钮精准、克制
Segmented Control胶囊、顺滑
Chat Composer大圆角、纸面容器
User Bubble柔和对话容器
Dialog稳定、正式
Code Block12px,技术感但不生硬

7. 字体与排版规则

7.1 不提交专有二进制字体

仓库策略:

  • 不包含 .ttf / .otf;
  • 不包含商业字体;
  • 使用系统字体回退栈。

Tailwind 配置中包含:

system-ui

以及常规系统字体序列。

这保证了:

  • 无需随项目分发额外字体文件;
  • 包体干净;
  • 各平台使用原生最佳字体渲染。

7.2 数字必须稳定

所有动态数字必须使用:

font-variant-numeric: tabular-nums;

或者 Tailwind:

tabular-nums

适用:

  • 时间;
  • 倒计时;
  • token 用量;
  • token 预算;
  • 音频频率;
  • diff 行号;
  • 消息长度;
  • 成本估算。

目的:

  • 数字变化时宽度不抖动;
  • 表格和代码对齐稳定;
  • 避免流式输出时布局跳动。

7.3 深色模式字重补偿

仓库包含深色模式下的字重光学补偿规则,例如:

.dark .font-medium,
.dark .font-semibold,
.dark .font-bold

这类规则用于对抗浅色文字在深色背景上的视觉膨胀或发虚。

7.4 图标光学对齐

行内图标通常需要垂直光学修正,文档体系提到类似:

vertical-align: -0.125em;

目的是让图标和文字基线视觉对齐,而不是几何对齐。


8. 动效哲学:物理弹簧而非线性动画

8.1 核心原则

系统明确反对:

transition: all 0.3s linear;
transition: all 0.5s ease;

推荐:

  • Framer Motion spring;
  • 精调 CSS cubic-bezier;
  • 有质量、有阻尼、有收敛的运动。

8.2 二阶阻尼谐振子

ClaudeMotionPresets.ts 中包含数学求解器:

并计算:

其中:

  • :欠阻尼,阶跃响应会出现过冲;
  • :临界阻尼;
  • :过阻尼,零初速度阶跃响应无过冲。

这意味着动效不是视觉猜测,而是可以用物理参数描述。

8.3 动效的三个层级

  1. 触觉反馈

    • 按钮按压;
    • 小控件;
    • 时间极短。
  2. 内容进入

    • 消息气泡;
    • 卡片展开;
    • Popover。
  3. 结构移动

    • 抽屉吸附;
    • 面板拖拽;
    • 分割条 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
PopoverSPRING_SNAPPY
卡片展开SPRING_SNAPPY
消息进入SPRING_SNAPPY / 定制变体
成功反馈SPRING_GENTLE
抽屉吸附SPRING_HEAVY_SNAP
分割条 snapSPRING_HEAVY_SNAP

10. CSS 缓动曲线与时间尺度

10.1 标准 CSS 曲线

ClaudeMotionPresets.ts 中定义:

名称曲线用途
OVERSHOOTcubic-bezier(0.34, 1.3, 0.64, 1)气泡、胶囊入场
EASE_OUT_EXPOcubic-bezier(0.16, 1, 0.3, 1)阴影、焦点、模糊渐变
DECELcubic-bezier(0.165, 0.84, 0.44, 1)抽屉滑入
SHARP_PRESScubic-bezier(0.32, 0.72, 0, 1)按压缩放

10.2 常用时间尺度

从组件代码中可见:

时长用途
100ms瞬时按压
120ms分段控件咬合
150mshover / scroll mask / 冷却窗口
200msComposer / panel 过渡
220ms阴影与边框过渡
300ms面板滑入
2.4s状态呼吸灯
1.2sactive 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 技术栈

类别技术
UIReact 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-全量版本更新深度逆向分析.md

16.4 质量门禁

AGENTS.md 要求代码修改后执行:

npm run typecheck
npm run build

两者都必须 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_SNAPPYstiffness: 600, damping: 30, mass: 0.6ζ 约 0.791,过冲约 1.8%,约 0.22s
SPRING_BOUNCYstiffness: 400, damping: 25, mass: 0.8ζ 约 0.612,过冲约 8.8%,约 0.38s
SPRING_GENTLEstiffness: 220, damping: 24, mass: 1.0ζ 约 0.809,过冲约 1.5%,约 0.48s
SPRING_HEAVY_SNAPstiffness: 1200, damping: 80, mass: 0.1ζ 约 1.826,过阻尼

上表右栏保留了规范原文中的数字,但其中两处阻尼比与参数不一致。按第 8 节公式复算:SPRING_BOUNCY 的 ,SPRING_HEAVY_SNAP 的 。因此表中原文过冲与收敛时间不宜直接作为验收值;实际收敛时间还取决于位移、初速度与停止阈值。

19.2 ClaudeMotionPresets.ts 当前实现

预设参数
SPRING_BOUNCYstiffness: 600, damping: 30, mass: 1.0
SPRING_SNAPPYstiffness: 320, damping: 28, mass: 1.0
SPRING_GENTLEstiffness: 380, damping: 18, mass: 1.0
SPRING_HEAVY_SNAPstiffness: 1200, damping: 80, mass: 0.1

19.3 结论

这可能是两种情况之一:

  1. AGENTS.md 描述的是更新后的规范意图,但代码未同步;
  2. 代码是实际实现,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. 参考文件

本文主要依据以下文件,链接固定到同一提交,便于复查:


附:最终风格画像

如果把这套系统交给一个新设计师,只用一段话描述:

使用暖灰纸面和四层微亮度表面构建空间;用陶土橙作为唯一强品牌色,只出现在焦点、确认和激活状态;边框是发丝线,阴影极轻;组件圆角从 6px 到 20px 按语义递进;文本和数字必须稳定;动效来自弹簧物理,有质量、有阻尼、有收敛;交互必须防御 IME、滚动劫持、拖拽误触和窄容器破碎;最终呈现出一个安静、可信、像现代编辑器一样的桌面 AI 界面。