# Design Frontend

> 前端/数字产品设计通用原则专项方法论。当产出是 Web/App 界面、交互数字产品、或含动效的页面，需要"像专业前端设计师一样"打磨信息架构、文案、视觉观感与动效时触发。覆盖：结构装置即信息、反模板校准（避免AI默认观感）、复杂度匹配愿景、文案即物料（UX写作）、动效编排时刻、动效语义与具体手法、前端设计通用原则。触发词：「前端设计」「网页界面」「数字产品」「UX写作」「反AI模板」「结构装置」「文案」「动效编排」「signature元素」。

- Skill: `yang20040317-svg/design-frontend` (Agent Skill)
- Install (CLI): `npx skillmds@latest add yang20040317-svg/design-frontend`
- Raw SKILL.md: https://api.skillmd.com/api/skills/yang20040317-svg/design-frontend/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: yang20040317-svg (https://skillmd.com/u/yang20040317-svg)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/yang20040317-svg/design-frontend

---


# design-frontend ｜ 前端设计通用原则专项

> 本技能是 design-workflow 主技能抽离出的**专项方法论**，专治"把数字产品/网页/App 界面做得不像 AI 默认模板、信息结构诚实、动效克制有意图"。
> 来源署名见 `../references/来源署名/anthropics-frontend-design.md`（Anthropic 前端设计通用原则文档 · 公开通用原则）。

## 一、结构装置即信息（编号/眉标/分隔线/标签须承载真相）

- **核心**：编号、眉标（eyebrow）、分隔线、标签等"结构装置"应**编码内容真相**，而非装饰。它们要么说明内容本身的秩序，要么一无是处。
- **质疑装饰性编号**：`01 / 02 / 03` 仅当内容**真是序列**（真实流程、带序时间轴、步骤必须按序读）时才用；若只是并列清单，编号是假秩序 → 删掉，改用其他区分手段（间距/分组/图标）。
- **自检**：每条编号/分隔线被删后，读者是否丢失了某条**关于内容本身**的信息？若否，它就是装饰，删。

## 二、反模板校准（避免 AI 默认观感）

> 下面是**需警惕的默认观感**——它们本身合法，但当 brief 未指定某一轴时，别把自由浪费在这些"无意识默认"上。brief 原话优先（它明确要求时照做）。

- **默认观感 A**：暖米白底（近 `#F4F1EA`）+ 高对比衬线 Display + 陶土橙点缀。
- **默认观感 B**：近黑底 + 单一荧光绿 / 朱红点缀。
- **默认观感 C**：报纸式细线规则 + 零圆角 + 密集多栏。

**校准方法**：定稿前自问"换一个相似 brief 我是否也会落到这？"——若答案是"会"，且 brief 没要求，就换一个**为该 brief 定制的**方向。

## 三、复杂度匹配愿景

- **极简方向** → 功力在间距 / 字 / 细节的精度，不在加东西；**极繁方向** → 需层次、纹理、动效、精雕细节撑住，否则显空。
- **优雅 = 把所选方向执行到位**，而非堆效果。与「信息优先级·主信息唯一」「把大胆用在一处」同源：signature 元素是唯一记忆点，其余安静、克制。
- 自检：删掉一个装饰后整体是否成立甚至更好？若成立，说明它本不该在。

## 四、文案即物料（UX 写作）

- **文案是设计材料，非装饰**：文字出现在设计里，只为让人更易理解、更易使用。带来与间距/颜色同等的自觉性。
- **从用户侧写**：用用户能掌控/辨识的词命名（"管理通知"而非"webhook 配置"）；描述它做什么，而非推销它。
- **主动语态 + 同名一贯**：按钮"发布"→ 提示"已发布"，同一动作全程同名，词汇是导航的路标。
- **失败/空状态是引导时刻，非情绪**：说清错在哪、怎么修（错误不道歉、不模糊）；空屏是行动邀请，不是空白。
- 与「文字」模块区分：本技能管"说什么/怎么写"（内容），主技能 `02-感知物料/文字.md` 管"怎么排/什么字体"（形式）。

## 五、动效编排时刻

- **一个编排好的"主角时刻" > 零散微动画**：开场序列 / 滚动揭示 / 一处精心设计的入场，比到处撒hover/脉冲更抓人。先问"这段动效服务于哪个 subject 的瞬间"，再决定做不做。
- **额外动画 = AI 生成感信号**：动效过多、过碎会让成品显"AI slop"。同屏同时运动元素**默认** ≤3–5 个——克制是高级感的来源；**破格触发器**：单焦点 / signature 记忆点元素允许 1 个突破预算（其余让位、错峰）。
- **与"主观输出"校准**：若动效让观者意识到"这里在动"而非"这里在讲"，就是过了。尊重 `prefers-reduced-motion` 仍是硬底线。

## 六、动效语义与具体手法

> 仅抽通用设计原理；具体动效编辑器类工作流不纳入。

- **动效传达语义，而非装饰**：每个动效应能一句话说清"它传达了什么意图 / 状态 / 情绪"（如打字=启动感、扫光=强调、进度=等待）。动效是"信息层"不是"烟花层"。
  - **"语义"≠"功能语义"，情绪 / 玩味意图也算可命名载荷**：随光标漂浮、随滚动轻轻晃、明明不传达具体信息但就是"轻松好玩"的动效，其意图即"松弛 / 有趣 / 玩味"，**合法**。真正要砍的只有"既无语义、又无情绪、只是因为默认'东西该动'才堆上去"的 AI-slop 式动效。一句话判别：能说出"它让观者感到什么 / 想到什么"→ 保留；说不出任何感受也无功能用途 → 砍。
- **文本动效：文字作为一等动效对象（Kinetic Typography）**：文字不只是静态信息，可独立运动——逐字浮现 / 解密、数字滚动计数、焦点跳跃、字符位移。用于**强调关键信息或建立节奏**，而非让所有文字都动；与「同屏运动元素默认 ≤3–5」预算同守（单焦点破格除外）。
- **沿路径运动**：元素可沿手绘 / 吸附路径（直线 · 圆 · 椭圆）运动，制造"视线被引导沿某轨迹走"的叙事感。
- **统一运动动词表**：用一套稳定动词（进入 / 强调 / 退出 / 路径 / 序列）描述所有动效，跨元素一致、便于组合与交接。
- **动效可组合叠加**：进 / 出场、强调、注意等预设可叠加至任意层（文本 / 图 / 视频）快速组合含义；但叠加仍受「同屏默认 ≤3–5 元素」预算约束（单焦点破格除外）。

## 七、动效通用性能与降级（与主技能动画模块配套）

- **只动 `transform` / `opacity`**（GPU 友好），避免动 `width/height/top`（触发重排）；目标 60fps，低端机保底 30fps。
- **无障碍降级（必做）**：尊重 `prefers-reduced-motion`——动效降为瞬时淡入/直接切换，不位移、不闪烁、不循环。关键信息（报错、状态）不能只靠动效传达。

## 八、交互工程对错清单（功能型产品 UI / APP 专用）

> **适用边界（重要）**：本节仅用于**功能性产品界面 / APP 交互组件**——toast、表单、下拉、按钮、拖拽、键盘操作等以「顺手、响应快、不烦人」为核心价值的界面（写程序 / 做 APP 的场景）。
> **不适用**：以设计感 / 氛围 / 叙事 / 传播为目标的网页、海报、品牌页、叙事长页——那种场景回到主技能 `动画.md`（数量预算 + 破格）与 `references/惊艳手法库.md`，按「饱满有意图」的标准走，**不套用本节清单**。
> 来源：吸收自 emilkowalski/skills（MIT），来源署名见 `references/来源署名/emilkowalski-skills.md`。

### 对错清单（AI 最容易错的点）

| ❌ 错 | ✅ 对 | 为什么 |
|---|---|---|
| `transition: all` | `transition: transform 200ms ease-out` | all 触发布局重算，不可预期 |
| 从 `scale(0)` 进场 | `scale(0.95) + opacity:0` 起步 | 物体不从虚无中出现 |
| 入场用 `ease-in` | `ease-out` 或自定义曲线 | ease-in 起步慢 = 界面迟钝 |
| popover `transform-origin: center` | 锚定触发器 `var(--transform-origin)` | 从触发点"长出来"；模态框例外（居中） |
| Framer 简写 `x`/`y`/`scale` | `transform:"translateX()"` | 简写不走硬件加速 |
| 键盘触发加动画 | **完全不加** | 高频操作，动画=延迟感 |
| hover 无媒体查询 | `@media (hover:hover) and (pointer:fine)` | 触摸屏 tap 会误触发 hover |
| 高频元素用 keyframes | 用 CSS transitions | 可中断、可重定向 |
| Enter/Exit 同速 | 退出比进入快 | 退出是系统响应，必须快 |
| blur > 20px | ≤ 20px | Safari 高模糊昂贵 |
| stagger 间隔过长 | 30–80ms | 太长显拖沓 |
| spring bounce > 0.3 | 0.1–0.3，多数 UI 避免 | 弹太狠 = 玩具感 |

### 参数表（"对"长什么样）

```css
--ease-out:    cubic-bezier(0.23, 1, 0.32, 1);   /* UI 交互默认 */
--ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);  /* 屏上元素 A→B 移动 */
--ease-drawer: cubic-bezier(0.32, 0.72, 0, 1);   /* iOS 抽屉 */
```

- **时长表**（UI 硬上限 300ms）：按钮按压 100–160ms · tooltip 125–200ms · dropdown 150–250ms · modal/drawer 200–500ms · 营销/展示动画可更长
- 按钮按压：`:active scale(0.97)` + `transform 160ms ease-out`
- spring：Apple 风格 `{type:"spring", duration:0.5, bounce:0.2}`；传统 `{mass:1, stiffness:100, damping:10}`
- 拖拽 dismiss：速度阈值 `velocity > 0.11`

### 评审输出格式（Review 三列）

动效评审一律用 Markdown 三列表 `Before | After | Why`（禁止"Before:/After:"分行格式）：

| Before | After | Why |
|---|---|---|
| `transition: all 300ms` | `transition: transform 200ms ease-out` | 只动需要动的属性 |
| `transform: scale(0)` | `transform: scale(0.95); opacity:0` | 现实物体不从虚无出现 |
| `ease-in` on dropdown | `ease-out` 自定义曲线 | ease-in 显迟钝 |

### 决策顺序与目的门控（动效该不该做、为什么做）

> 对错清单管"做对了没有"，本段管"该不该做、为谁做"——顺序在前，参数在后。

- **顺序即纪律**：先过"该不该动"的频率门控（见上「频率–动效决策原则」），再命名"目的"，最后才选曲线/时长参数。不要没定目的就先挑缓动。
- **目的命名门控**：每个动效必须能用下列之一命名；命名不出 → 不做（"看起来酷"在高频元素上是停手的理由，不是做的理由）：
  - **反馈**（确认界面听到了用户）· **空间一致性**（显示某物从哪来/去哪）· **状态指示**（让状态变化可读）· **防止突兀变化**（bridging 否则会瞬移的内容）· **解释**（演示原理，仅营销/引导）· **愉悦**（**仅限**罕见/首次层级，如引导、成功、庆祝）。
- **功能优先于风格**：用户正在读或操作的数据不应为"风格"而移动；装饰性鼠标跟随动效属于营销页，不属于数据密集型界面里的图表。
- **键盘触发的动作直接判负**：命令面板开关等每天开合上百次的操作，正确做法是零动画（主流命令面板无开合动画即为此理）。

## 自检清单（交付前）

- [ ] 每个编号 / 眉标 / 分隔线被删后是否丢失了关于内容的真相？（结构装置即信息）
- [ ] 是否落入了某个 AI 默认观感（暖米白+衬线+陶土橙 / 近黑+荧光绿 / 报纸细线密栏）而无 brief 支撑？
- [ ] 复杂度是否匹配愿景（极简不加、极繁有层次）？
- [ ] 文案是否从用户侧写、主动语态、同名一贯、空状态是引导而非情绪？
- [ ] 动效是否每个都可命名意图（语义或情绪）？无意图的 AI-slop 动效是否已砍？
- [ ] 是否只动 `transform`/`opacity`、尊重 `prefers-reduced-motion`？
- [ ] 是否有一个精心编排的"主角时刻"而非零散微动画？
- [ ] 【功能型产品 UI / APP】是否过了「八、交互工程对错清单」（transition:all / scale(0) / ease-in 入场 / 键盘操作不动效 / hover 门控 / 时长 ≤300ms）？
- [ ] 【有目标稿 / 设计稿 / 参考稿时】是否过了**双评审闸门**：盲 scout 只拿到并排比对图（**不**给意图、spec、ID、参数、builder 辩护）→ 放行；且**每个关键特征单独过闸**（logo 轮廓 / 主视觉主体 / 标题层级 / 品牌色落点 / signature 元素）？**关键特征失败不得被整体分掩盖**。
- [ ] 改稿是否**只改挑战者**、冠军不动、失败事务性回滚？连续三次无实质改进是否已换路子而非继续磨？（机制见主技能 `05-主观输出/感觉.md`「补充 · 双评审闸门」）

## 边界与维护

- 本技能只管"前端/数字产品的通用设计原则"，具体排版/配色/留白等落到主技能 `design-workflow` 的对应层。
- 动效的具体时序/缓动/时长数值见主技能 `02-感知物料/动画.md`；本技能聚焦"意图与克制"层面。
- 若要在通用设计流程里用：由主技能 `design-workflow` 在载体=UI/数字产品/网页时路由到本技能。

## 补充 · 动效审计与组件选型纪律

> 来源：吸收自 emilkowalski/skills 的 `improve-animations`（存量动效审计工作流）与 `pick-ui-library`（组件选型纪律），已通用化、去具体库名，未引入其私有 IP。与既有「交互工程对错清单」「频率–动效决策原则」构成「该不该做 → 做对没有 → 存量体检」完整链路。

### 一、存量动效审计工作流（对已有前端/UI 代码库做"动效体检"）

当任务不是"从零做动效"而是"这个 App 动效很烂 / 帮我审计一遍"时，按以下流程产出可执行的修复计划（**只读分析、不改源码**）：

1. **摸排（Recon）**：先摸清技术栈（框架 / 动效库 / 组件库）、动效驻留处（全局 token、Tailwind 配置、keyframes、`transition`/`animate` 用法、手势 handler）、既有约定（缓动 token、时长标尺——计划须沿用而非另起一套）、产品性格（玩具感消费 App vs 严谨仪表盘）、**频率图**（哪些元素每天被触发 100+ 次 vs 偶尔 vs 罕见，驱动严重性）。
2. **八维审计**：目的与频率 / 缓动与时长 / 物理感与锚点 / 可中断性 / 性能 / 无障碍 / 一致性(token) / 缺失机会。大仓库可拆成并行子任务按维度查。
3. **分级定级**：按「影响 ÷ 成本」排序；HIGH=破坏手感（UI 错缓动、键盘/高频动作加了动画、掉帧、scale(0)）；MEDIUM=明显不对（错锚点、动态 UI 不可中断、缺 reduced-motion）；LOW=打磨（stagger、blur 遮罩交叉淡入、token 收敛）。
4. **产出自包含计划**：每条发现写成一个计划，精确到 文件路径 + 当前代码摘录 + 目标值（具体 cubic-bezier / 时长 / spring 配置，源自既有约定，不近似编造）+ 验证方式（慢放 / 逐帧 / 真机手势）。不自动改源码、先让人选要修哪几条。
5. **别重复已有决策**：若代码/注释已记录刻意的动效权衡，尊重它、标注而非举报。

### 二、组件选型纪律（先选型，别手写废弃组件）

当任务需要的其实是一个"组件"而非"一段动画"（toast / drawer / command menu / dropdown / 数字滚动 / 虚拟化长列表 / 状态管理 / 条件 className 等）：

- **先按任务语义归类**，再决定用什么；用户说的库名未必等于真实任务类型（"我要个下拉"本质是 UI 原语任务）。
- **优先成熟库而非手写**：手写 `<div>` dropdown 极易漏掉焦点管理 / 无障碍 / 关闭逻辑；数字滚动重渲染文本不如专用组件处理数位过渡。
- **先看项目已装什么**：已用某库就沿用，别引入竞争依赖制造改动噪音。
- **简单 hover/fade 用原生 CSS**，不要为此引一个动效库。
- 具体库随生态演进，按需查当前推荐——本技能不固化具体库名（避免过时）。

### 三、组件实现基底：shadcn/ui（接入方式）

> 当载体 = React/Next.js + Tailwind 的 Web 应用，需要做按钮 / 弹窗 / 表单 / 下拉等**生产级交互组件**时，用 shadcn/ui 作组件源，避免每次从零造轮子。它是「组件选型纪律」的具体落地推荐（非唯一解；项目已用其他体系则沿用之，不强行替换）。

- **是什么**：可复制粘贴的组件**源码**（非 npm 黑盒依赖）。用 CLI 把组件源拉进你项目的 `components/ui/`，代码归你所有、可改可提交，不锁定版本、不随上游发版突变。
- **接入步骤**：
  1. 前置：已初始化 React/Next.js 项目 + 已配置 Tailwind CSS（shadcn 不替你装框架与 Tailwind）。
  2. 初始化：`npx shadcn@latest init`（按提示设 `--base-color`、路径别名等；`--base-color` 只是初始化配置项，不在此强行规定审美方向）。
  3. 添加组件：`npx shadcn@latest add button dialog sheet card input select tabs`（按需列组件名，逐个把源码拉到本地 `components/ui/`）。
  4. 使用：直接 `import { Button } from "@/components/ui/button"` 调用；要改就改本地源码，改动随项目走。
- **底层**：Radix UI（键盘 / 焦点 / ARIA 无障碍原语）+ Tailwind CSS 工具类。
- **与「零运行时依赖」原则一致**：拉一次即落本地文件，构建期无 CDN 拉取、无外部运行时（呼应 hogwarts3d 召回坑：CDN 拉 Three.js 致用户端"点击没反应"）。
- **边界**：它是**组件源**，不替代五层设计方法与本技能的设计原则；审美、结构、动效克制仍由 design-workflow 定。纯 HTML / vanilla JS 项目用不了（需 React 生态）。`npx shadcn init` 会在 `globals.css` 生成一套默认 neutral 色板（取决于所选 `--base-color`）——那是**占位脚手架**，请用工位流 `02-感知物料` 层产出的色板覆盖之；本技能不规定任何色值。
- **演进提示**：CLI 命令与 `--base-color` 取值随 shadcn 版本变化，以 `ui.shadcn.com/docs` 当前文档为准，本段不固化具体命令参数。

## 补充 · 字体实现基底：Fontsource（自托管字体接入方式）

> 当载体 = 网页 / Web 应用，需要把字体**自托管**进项目（而非运行期从 Google Fonts CDN 拉）时，用 Fontsource 作字体交付源。它与 shadcn/ui 同源：都是「零外部运行时」原则的落地——呼应 hogwarts3d 召回坑。
- **是什么**：把开源字体打成独立 npm 包；安装后字体文件随构建产物落本地，运行期**无外部字体请求**（对比 Google Fonts CDN：省一次 DNS+TCP、版本锁定、隐私、可离线）。
- **接入步骤**：
  1. 装包：`npm install @fontsource/<字体名>`（静态字重）或 `npm install @fontsource-variable/<字体名>`（可变字体，推荐）。
  2. 引入：入口 CSS `@import '@fontsource/<字体名>/<字重>.css';`（如 `/400.css`、`/600.css`），或在 JS `import '@fontsource/inter/400.css'`。
  3. 使用：CSS 里 `font-family: '<字体名>';`，权重按引入的 css 走。
  4. 构建：Vite/Next/webpack 等打包器把 woff2 一并产出，无需手动搬文件。
- **与「零运行时依赖」原则一致**：字体文件进本地构建，运行期不连 Google Fonts CDN（呼应 hogwarts3d 召回坑）。
- **边界**：它是**字体交付源**，不替你选字；**用哪款字由工位流 `02-感知物料` 层定**（字体属感知物料，见 `modules/02-感知物料/文字.md`）。Fontsource 只负责把 workflow 选定的字自托管进来。具体包名/引入路径随版本演进，以 fontsource.org/docs 当前文档为准。

## 补充 · 组件过渡选型参考（CSS 落地 · 仅组件级 CSS 过渡载体时调用）

> **触发边界**：本段仅在「载体 = 网页 / Web 应用，需要做**组件级 CSS 过渡**（下拉 / 模态 / 成功 / 错误抖动 / 骨架屏 / Tab 等常见交互的进出场）」时调用。它**不替代**第八节 emilkowalski 的「该不该动 / 做对没有」——那两条是通用纪律，本段是"选哪个过渡 + 用什么节奏 token"的选型层。可与 GSAP 段并列：本段管"选哪个过渡 / 词汇与节奏 token"，GSAP 段管"用 JS 库怎么写"；两者皆须先过第八节。
> 来源：吸收自 Jakubantalik/transitions.dev（开源 CSS 过渡库 + agent skill），已**去名化为通用选型纪律与词汇表**；具体 CSS 片段随源站演进，以官方当前版本为准，本段不粘贴源码。

### 一、匹配纪律：先元素 → 再动词 → 平局按开销

- **先匹配可见 UI 元素，再匹配动词**：同一"打开"动词因元素不同落不同过渡——表面从触发器生长 → `menu dropdown`（有锚点）；表面居中、无锚点 → `modal`（居中）；表面滑入页面某区 → `panel reveal`。
- **平局按开销取舍（默认选更轻的）**：`card resize` > `panel reveal`；`dropdown` > `modal`；`success check` > 整模态庆祝。除非设计明确要求更重的表面，否则默认低开销。
- **无清晰匹配 → 回退让人选**，不猜测塞一个过渡。
- **组合而非堆砌**：`success check` 是纯动画；若还需从 spinner 换到对勾，须搭配 `icon swap` 组合，而非把 check 当万能庆祝。

### 二、组件过渡词汇表（命名即沟通）

> 把常见交互的动效**命名规范化**——命名本身就是设计词汇，避免每次"即兴发挥"导致各组件节奏散掉。下面复用率最高的核心词汇（按交互意图分组，非穷举）：

| 意图 | 命名过渡 | 何时用 |
|---|---|---|
| 容器尺寸变化 | `card resize` | 元素宽/高随布局态变化 |
| 数字更新 | `number pop-in` | 数值变化时逐位带模糊滑入 |
| 触发点上方小徽标 | `notification badge` | 触发器上方悬浮小圆点弹出 |
| 文本原地替换 | `text states swap` | 文本原地内容变更（带模糊上下移） |
| 锚定触发器生长 | `menu dropdown` | 原点感知的下拉，从触发器长出 |
| 居中弹出层 | `modal` | 居中、无锚点的对话框（缩放进出） |
| 滑入页面某区 | `panel reveal` | 侧栏/抽屉滑入某区域（带交叉模糊） |
| 双屏切换 | `page side-by-side` | 列表↔详情 / 步骤1↔步骤2 |
| 同槽位两图标 | `icon swap` | 同一位置两个图标交叉淡入缩放 |
| 成功/完成时刻 | `success check` | 对勾/支付完成/文件上传（淡+旋+Y浮+描边绘制） |
| 横向堆叠悬停 | `avatar group hover` | 头像/芯片行中悬停某项（距离衰减弹起） |
| 校验错误反馈 | `error state shake` | 表单错误/无效字段（分段 cubic-bezier 抖+自动回正） |
| 清空文本字段 | `input clear with dissolve` | 搜索框×/筛选重置（飞出+逐词 dissolve） |
| 占位→真实内容 | `skeleton loader and reveal` | 列表行/卡片加载后交叉淡入真实内容 |
| 进行中"活"文本 | `shimmer text` / `thinking states` | 加载标签/流式状态（循环扫光，纯 CSS） |
| 互斥选项移动高亮 | `tabs sliding` | 视图切换/分段控件（药丸指示跟随） |
| 悬停/聚焦提示 | `tooltip open/close` | 图标提示/信息泡（延迟淡入、即时退出） |
| 堆叠文字入场 | `texts reveal` | 主视觉/空状态/引导步（错落模糊升起） |

### 三、Motion Tokens：节奏一致性的来源

> 所有组件过渡共享一套**语义化 timing token**（不是魔法数字）——这才是"整站节奏一致"的真正机制，类比色彩/间距 token。

**共享尺度（推荐基线，可据品牌微调）**
```css
/* Durations */
--duration-stagger:   40ms;   /* 逐项错开偏移 */
--duration-micro:     80ms;   /* tooltip/路径延迟、shake 段、大错开 */
--duration-quick:    150ms;   /* modal/dropdown 关闭、text swap、tooltip 出现 */
--duration-fast:     250ms;   /* icon swap、dropdown/modal 打开、tabs、page slide */
--duration-medium:   350ms;   /* panel 关闭、toast 关闭 */
--duration-slow:     400ms;   /* panel 打开、骨架揭示、input clear */
--duration-very-slow:500ms;   /* 强调时刻、badge 出现、text reveal、success check */
/* Easings */
--ease-smooth-out: cubic-bezier(0.22, 1, 0.36, 1); /* 进出/位移/缩放通用 */
--ease-in-out:     ease-in-out;   /* icon/text/text-reveal/skeleton swap */
--ease-out:        ease-out;      /* tooltip */
--ease-linear:     linear;        /* shimmer/skeleton pulse/spinner */
--ease-bounce:     cubic-bezier(0.34, 1.36, 0.64, 1); /* badge pop 打开 */
/* Distances / Scales / Blur */
--distance-base: 8px;   --distance-medium: 12px;  --distance-large: 30px;
--scale-small: 0.98;    --scale-medium: 0.97;     --scale-large: 0.96;
--blur-small: 2px;      --blur-medium: 3px;       --blur-large: 8px;
```

- **按"用途"而非"原始数值"映射**：以用途对齐 token（如某关闭动效用 300ms 仍归 `--duration-quick` 若用途为"modal close"），数字接近不强行替换。
- **每个过渡都自带 `prefers-reduced-motion` 守卫**（硬底线，删掉即过不了无障碍审计）。
- **低开销优先 + 最小 diff**：只改必需文件，不引动效库；无框架依赖、粘贴即用。
- **禁止 `transition: all`**：枚举精确属性，避免无关样式"搭便车"。

> 注：具体每个过渡的 CSS 片段、按组件覆盖的私有变量（如 `--resize-dur`、`--badge-*`）不在此段——那是 copy-paste 资产，随源站演进；需要时从官方取当前片段。本段只固「选型纪律 + 命名词汇 + token 体系」三层方法论。

## 补充 · GSAP 落地参考（库专用 · 仅 GSAP 载体时调用）

> **触发边界**：本段仅在「载体 = 网页 / Web 应用，且**已选定 GSAP** 作为动效实现库」时调用。它**不替代**第八节「交互工程对错清单」与本节上半「存量审计 / 组件选型纪律」——那两条是通用纪律，本段是 GSAP 的具体写法落地。GSAP 当前全部插件免费（含原 Club 专属的 SplitText / MorphSVG，商业可用），从公共 `gsap` npm 包安装即可。
> 来源：吸收自 greensock/gsap-skills（官方 GSAP AI 技能集，MIT），已**去名化为通用写法骨架**；具体 API 参数随 GSAP 版本演进，以官方文档当前版本为准。

### 一、何时选 GSAP 而非 CSS
- 需要**时间线序列控制**（多步编排）、**运行时控制**（暂停/反转/seek）、**复杂缓动**、**滚动驱动**（ScrollTrigger）、**JS 动态计算值**时用 GSAP；极简过渡用原生 CSS 即可，不引库。

### 二、核心 Tween 正确写法
- 属性名用 **camelCase**（`backgroundColor`、`rotationX`）。
- 优先 **transform 别名**（`x`/`y`/`scale`/`rotation`/`xPercent`）而非手写 `transform` 字符串——顺序一致、性能更稳、跨浏览器可靠。
- **`autoAlpha` 优于 `opacity`**：值为 0 时自动 `visibility:hidden`，避免隐形元素挡点击。
- 全局默认节奏用 `gsap.defaults({ duration: 0.6, ease: "power2.out" })` 收敛。

### 三、最易错点（AI 写 GSAP 的高频坑）
- **`from()`/`fromTo()` 的 `immediateRender`**：同一元素同一属性堆叠多个 `from` 时，后者初始态会覆盖前者——给后者设 `immediateRender: false`，保留第一个动画的终态。
- **用 timeline + 位置参数代替 `delay` 链**：多步用 `gsap.timeline()` 与位置参数（`"+=0.2"` / `"-=0.1"` / `"<"` / 标签）编排，别用一串 `delay`。
- **ScrollTrigger 只能挂在顶级 tween / timeline 上**，不能挂 timeline 内部的子 tween；`scrub` 与 `toggleActions` **不要同用**一个触发器（scrub 胜出，逻辑冲突）。
- **横向滚动用 `containerAnimation` 时子动画必须 `ease:"none"`**，否则破坏滚动 1:1 映射。
- **布局变化（新内容 / 图片 / 字体 / 动态 DOM）后调用 `ScrollTrigger.refresh()`**；视口 resize 自动处理，动态内容不会。
- 生产移除 `markers: true`；所有插件使用前 `gsap.registerPlugin(...)` 注册一次。
- **清理**：vanilla 用 `gsap.context()` 或 `gsap.matchMedia()` 的 `revert()` 回收；高频更新属性用 `gsap.quickTo()` 复用单 tween，别每帧 new tween。

### 四、性能与降级（与第八节、第七节一致）
- 只动 `transform` / `opacity`（GPU 友好）；`will-change` 只给真正在动的元素；离屏动画 pause/kill。
- **无障碍**：用 `gsap.matchMedia()` 响应 `prefers-reduced-motion`——`reduceMotion` 条件为真时 `duration: 0` 或直接跳过，不位移不循环。与第七节「尊重 reduced-motion 是硬底线」同源。

### 五、常用 web 插件速查（仅 vanilla/web 相关）
| 插件 | 用途 | 一句话关键模式 |
|---|---|---|
| SplitText | 文本拆字/词/行做逐单位错开 | `SplitText.create(".h",{type:"chars"})` → `gsap.from(split.chars,{...stagger})` |
| CustomEase | 内置缓动不够时自定义曲线 | `CustomEase.create("n",".17,.67,.83,.67")` 作 ease |
| Flip | 布局状态间动画（FLIP 技术） | `state=Flip.getState()` → 改 DOM → `Flip.from(state,{...})` |
| ScrollSmoother | 平滑滚动包装（需固定 DOM 结构） | 注册于 ScrollTrigger 之后；`#smooth-wrapper > #smooth-content` |
| ScrollToPlugin | 滚动到某元素/坐标（非 ScrollTrigger 场景） | `gsap.to(window,{scrollTo:{y:"#sec"}})` |
| Draggable+Inertia | 拖拽与释放动量 | `Draggable.create(".b",{type:"x,y",inertia:true})` |
| MorphSVG / MotionPath | SVG 形变 / 沿路径运动 | `morphSVG:"#target"` / `motionPath:{path:"#p"}` |

> 注：React/Vue/Svelte 框架适配、gsap.utils 辅助函数等不在此段（属框架/工具层）；本段只固「易错纪律 + 关键骨架」，避免随版本过期。设计感网页的 GSAP 动效仍须先过第八节「该不该动 / 做对没有」与第五~七节「编排时刻 / 语义 / 性能降级」，GSAP 只是实现手段，不豁免设计纪律。

