<!--
Responsibilities:
- Record explicit non-mappings between Figma and code.
- Explain why each non-mapping is intentional, temporary, or pending repair.
- Give audits a single place to distinguish documented divergences from bugs.
-->

<!--
Split 2026-05-14 — Tier 1-A Sprint 3 (commit TBD)
26 决议 entries 已迁到 divergences-decisions.json (+ schema)；本 md narrative 大幅保留。
活跃 SoT：
- 结构化决议 → src/design-system/translation/divergences-decisions.json
- 完整 rationale / 实证 / 历史 → 本 md
-->

# Divergences

## Figma SVG export pipeline limitation — Icon Variable resolved-to-hex

**问题**：Figma 的 SVG image export API 把 Color Variable 引用**解析为 literal hex**后再返回 SVG 字符串——**丢失了 Variable 绑定语义**。

**实证**：
- 设计师在 figma 端把 icon path fill 绑定 `Color Type/Icon/Default` Variable
- `Color Type/Icon/Default` Variable alias 到 `UX/Grey/grey-6 #9E9E9E`（dark mode）/ `UX/Grey/grey-8 #595959`（light mode）
- `pnpm sync:icons` 调 figma image API 拿到 SVG → 收到的字符串里 fill 是某个 literal hex（具体是哪个 hex，取决于 figma 当时 export pipeline 实现 / placeholder 选择）
- 经实证，TVU figma library 中**单色非品牌图标的 path fill literal = `#dbdbdb`**（实际不是 `Color Type/Icon/Default` 的解析值 `#9e9e9e`，而是 figma palette 的 `UX/Grey/grey-4 #DBDBDB`——designer 把 grey-4 用作"应该是 Icon/Default"的占位语义；理由不可考但实证如此）

**Code 端治本** ([`figma-sync/export-icons.mjs`](../../../figma-sync/export-icons.mjs) `transformSvgCurrentColor`)：
- 拉到 SVG 后扫所有 `<path fill="#xxx"/>`
- 任何 path fill === `#dbdbdb` 改成 `fill="currentColor"`（per-path 转换，不分 mono/multi）
- 其它 hex 值（语义色 / app-brand / 第三方 logo 色）保留不动——它们封装在 catalog SVG 内部，外部组件通过 `<Icon name="..." />` 引用，颜色不会泄漏

**消费方 fallback**：
- Icon 组件本身（`src/components/Icon/Icon.vue`）`.icon` 元素**不强制设 color** — 避免破坏现有消费者 cascade-based color override pattern (`InputNumber:disabled` / `Message status` 等通过父级 `color: var(--xxx)` 让 icon 继承)
- 消费组件容器自己设 `color: var(--icon-default)` 实现"icon 默认 = `--icon-default`"语义（实证：`Message.__close` / `InputNumber.__btn` / `Notification` 默认状态等）
- 这是消费者 responsibility，不是 Icon 组件 responsibility

**Audit 回归保护**（[`figma-sync/audit-icon-fill-currentcolor.mjs`](../../../figma-sync/audit-icon-fill-currentcolor.mjs)）：
- 只 ERROR `path fill === "#dbdbdb"`
- 当前 finding = 0；非 0 = 真 bug（transform 漏了 / 新 icon 引入未走 pipeline）

**Why 不视为 figma↔code 漂移**：
- figma 端：设计师用 Variable，意图正确
- code 端：transform 把 export pipeline 限制还原为 currentColor 语义
- 两端语义一致，只是 figma 的 export 把 Variable 解析掉了——不是 designer 写错，也不是 code 自创规则

**未来 figma 端重新绑定 Variable 后**（设计师 review 把 icon path fill 从 #dbdbdb 改成绑定 `Color Type/Icon/Default`），仍然走相同 transform 链路（Variable 解析为 #9e9e9e 后会被 `transformSvgCurrentColor` 转 currentColor，前提：扩展 NEUTRAL_HEX_SET 包括 `#9e9e9e` / `#595959`，或 transform 改为更智能 figma metadata 检测）。本次实现保守只覆盖现状 `#dbdbdb`。

**决议详情**：[`divergences-decisions.json`](./divergences-decisions.json) `id: icon-variable-resolved-to-hex`

---

## 组件级映射（Component-level Translation）

### DateTime ↔ Select.feature=date|time

- 设计侧契约：Figma Select component 通过 feature 属性容纳 default / normal / multiselect / time-default / time-normal / date-default / date-normal 等 7+ 个变体
- 代码侧契约：按功能拆分为：
  · Select（覆盖 feature=default | normal | multiselect）
  · DateTime（覆盖 feature=time-default | time-normal | date-default | date-normal）
- 拆分理由：网站文档按用户功能组织（选择 vs 时间日期输入），Vue 生态约定也分别处理
- 设计源：Figma 不修改，保留单一 Select 组件
- 出处声明：DateTime.vue 顶部注释 + docs 页 intro 中明确 "Source: Figma Select component, feature=date | time variants"
- 后续审计：DateTime 应对照 Select.feature=date|time 子集审，不报"Figma 缺失"
- 当前仓库状态：docs 页 intro 已写明来源；`src/components/DateTime/DateTime.vue` 当前不存在，因此文件头注释待组件文件落位后补充
- 代码侧暂无独立组件文件
- **决议详情**：[`divergences-decisions.json`](./divergences-decisions.json) `id: datetime-select-feature-topology`

### Input ↔ input box/filled + input box/line

- 设计契约：Figma 用 line / filled 两个 family 表达视觉风格
- 代码契约：单一 Input 组件，通过 prop（如 variant / appearance）切换两种风格
- 拆分理由：开发侧统一 import，避免 InputFilled / InputLine 两个组件
- 后续审计：Input audit 应对照 (input box/filled ∪ input box/line)，不视为 Figma 缺失
- **决议详情**：[`divergences-decisions.json`](./divergences-decisions.json) `id: input-dual-family-single-component`

### Select ↔ select box/filled + select box/line

- 设计契约：同 Input 的 line / filled 双家族
- 代码契约：单一 Select 组件
- 后续审计：Select audit 对照 (select box/filled ∪ select box/line)，且 **不含 feature=date | time**（已拆分到 DateTime 的展示页）
- **决议详情**：[`divergences-decisions.json`](./divergences-decisions.json) `id: select-dual-family-single-component`

### Breadcrumb ↔ Breadcrumb/Item（容器聚合）

- 设计契约：Figma 公开 Item，未公开容器
- 代码契约：Breadcrumb 是容器组件承担布局；BreadcrumbItem 对应 Figma Item
- 后续审计：Breadcrumb 容器组件允许“代码侧多容器、Figma 缺失”；BreadcrumbItem 对照 Figma 主体
- **决议详情**：[`divergences-decisions.json`](./divergences-decisions.json) `id: breadcrumb-item-container-topology`

### Steps ↔ Step/Item（容器聚合）

- 设计契约：Figma 公开 Item，未公开容器
- 代码契约：Steps 容器 + StepItem 对应 Figma Item
- 后续审计：同 Breadcrumb 模式
- **决议详情**：[`divergences-decisions.json`](./divergences-decisions.json) `id: steps-item-container-topology`

### Button ↔ 8 个 Button/{theme} {size} component sets

- 设计契约：Figma 用 8 个独立 set 拆分主题/尺寸（如 Button/dark L、Button/light M 等）
- 代码契约：单一 Button 组件，通过 props（theme / size / type）覆盖全部
- 拆分理由：开发侧避免 8 个不同 import
- 后续审计：Button audit 对照 8 个 set 的属性并集
- **决议详情**：[`divergences-decisions.json`](./divergences-decisions.json) `id: button-eight-sets-single-component`

### Icon ↔ 大量 icon/* component sets（资产聚合）

- 设计契约：Figma 发布大量 icon/{category}/{name} component sets
- 代码契约：Icon.vue 是运行时 registry 入口，通过 name prop 加载具体图标
- 拆分理由：动态资产层，不对应单一组件
- 后续审计：Icon 不走标准 props/variants 流程；改走 icon-aliases.ts 完整性核对（每个 alias 都能 resolve 到存在的 Figma 图标）
- **决议详情**：[`divergences-decisions.json`](./divergences-decisions.json) `id: icon-registry-asset-aggregation`

### Logo ↔ icon/logo/TVU + icon/logo/ts

- 设计契约：Figma 在 icon 资产中维护两个 logo set
- 代码契约：Logo 通过 type prop（tvu | ts）切换
- 后续审计：Logo audit 对照 (icon/logo/TVU ∪ icon/logo/ts)
- **决议详情**：[`divergences-decisions.json`](./divergences-decisions.json) `id: logo-icon-assets-aggregation`
- **2026-07-02（META-02）**：Logo 已提升为 canonical `src/canonical/Logo.vue` 并进双框架库（WC + React wrapper），见下方 `## Logo / MenuList / UserMenu` 段 + `id: logo-menulist-usermenu-code-first-2026-07-02`。

### ~~time/calendar ↔ icon/Time/**Calender**（Figma 端拼写 typo）~~ ✅ resolved 2026-05-28

- **closure**：Figma 端已把 component 重命名为 `icon/Time/Calendar`（dist 资产同步为 `dist/icons/svg/Time/Calendar__1243_23532.svg`）。divergence 不再成立 — Figma 名 = code 名 = 正字法 `Calendar`。
- **检测来源**：`pnpm audit:figma-vs-sot` (BRIDGE-MOCKUP-008 Phase D, 2026-05-28) drift type C 报 `SoT: icon/Time/Calender → figma library: icon/Time/Calendar`；SoT `figma_name` 字段 in-place patch 后复跑 C=0。
- **登记日期**：2026-05-26（pilot 35-icon binding 回填时发现） · **closure**：2026-05-28
- **memory 实证**：[[feedback_name-search-absent-fallacy]] 2026-05-26 case 已完成 Figma 端落地。

### Alert ↔ ✅ RESOLVED（组件已删除，CANONICAL-030）

- **结论（2026-06-04，owner ack）**：确定性核实 Figma 发布库**无 Alert 组件**（只有 Notification + Popup Box）→ 命中历史选项 c：Alert 是代码侧自创组件 → 按硬规则 #3（不创建未登记组件）**删除**。
- 落地：`src/components/Alert/` 已删 + 无 `src/index.ts` 导出 + 无 canonical wrapper（verify：`ls src/components/Alert src/canonical/Alert.vue` 均不存在）。
- 历史选项（保留 provenance）：a) Notification variant 重命名；b) 独立未发布 set；c) 代码自创应删 ← 命中。
- **决议详情**：[`divergences-decisions.json`](./divergences-decisions.json) `id: alert-figma-source-unconfirmed`（status `resolved-deleted`）

## Code 端双源（AI 工具消费指引）

> 本节不登记 Figma↔Code 错位，登记**code 端两份实现并存**的情况。AI 工具（Claude / Codex / Cursor / Cline）需要明确以哪份为准，避免落到错文件。

### Badge 双源 — `canonical/Badge.vue` 是 SoT，`components/Badge/Badge.vue` 是 legacy

- **真源**：[`src/canonical/Badge.vue`](../../canonical/Badge.vue) —— `src/index.ts:8` 导出，npm 包消费这份
  - API：`color: 'Black' | 'Blue' | 'Green' | 'Orange' | 'Red'` / `tag: 'Filled' | 'Line'` / `type: 'Circle' | 'Rectangle'`
  - 用大写枚举值对齐 Figma axis name
- **legacy**：[`src/components/Badge/Badge.vue`](../../components/Badge/Badge.vue) —— 不进 npm 导出，仅为 `playground/App.vue` + `src/legacy/index.ts` + `playground/docs/pages/atomicAssets.ts` 保留
  - API：`type: 'brand' | 'red' | 'orange' | 'blue'` / `size: 'm' | 's'` / `dot: boolean` / `count: number` / `max: number`
  - 跟 Figma Badge axes 完全错位：legacy 没有 `tag` / `Circle/Rectangle` 概念，多出 `count/dot/max` 等运行时字段
- **为什么并存**：canonical 是完整 rewrite（不 wrap legacy 因为 Figma↔legacy API 错位太大无法 wrap），legacy 仍被 playground 等本地消费场使用，故未删
- **AI 工具消费规则**（重要）：
  - 拿 Figma URL → 生成 Vue 代码：**必须**用 canonical（grep `src/index.ts` 顺导出链）
  - Read tool 默认按路径 grep 时容易落到 legacy（因 `src/components/<X>/<X>.vue` 是更"标准"路径）→ 已在 legacy Badge.vue 文件头加显式 LEGACY 警告注释引导
- **后续审计**：Badge audit 对照 canonical/Badge.vue + Figma Badge component set；legacy Badge.vue 不进 audit 范围
- **后续清理路径**（M1 后再考虑，不在当前 v2 路线图）：
  - 选项 a：迁 playground/App.vue 到 canonical Badge（接受 dot/count/max 功能丢失或移到 canonical）
  - 选项 b：保留 legacy 作 playground 测试场，永久双源
- **来源**：T4-spike Badge vertical slice 跑 Claude 测试 1 时发现 — Claude 落 legacy，Codex 落 canonical，输出不一致；2026-04-30 登记本条
- **决议详情**：[`divergences-decisions.json`](./divergences-decisions.json) `id: badge-canonical-legacy-dual-source`

### 其它 16 组件不算双源

`src/canonical/<X>.vue` 内部 `import Base<X> from '../components/<X>/<X>.vue'` 形成 wrapper 层（Figma-aligned 桥层 wrap legacy 实现层），是健康架构，**不动 legacy**。涉及组件：Breadcrumb / CheckBox / FormItem / InputNumber / Notification / Pagination / Progress / Message / Radio / Rating / Slider / Steps / Switch / Tab / Table / Tooltip / TopBar。

## dropdown-disabled-hover-preview-state

- **形态**：Figma `Drop down List/Item` 有 `Disabled=Yes, Hover=Yes` variant（带 hover bg），但 code 故意 block：`.dropdown-item:hover:not(.dropdown-item--disabled)`
- **类型**：design preview state vs runtime UX 决策
- **决策**：code 保留 `:not(.dropdown-item--disabled)` — disabled 项不响应 hover 是 UX 标准（hover 暗示 interactive，disabled 表示 inactive；交互直觉冲突）。Figma 该 variant 仅 design preview。
- **凭据**：P17 discovery report §5 B3 + P17c Apply 2026-05-28
- **verifier 处理**：mapWarnings 加 `"DropDownListSelect disabled+hover is Figma preview state; code intentionally suppresses for runtime UX correctness"`；这 4 field 归 B_RESIDUAL_SCHEMA_GAP

## 设计态属性批量不映射

### Figma `dark theme` 属性（Input/CheckBox/Radio/Switch/Select/Tooltip）

- Property type: `VARIANT` (`on/off`)
- Reason: 设计态主题预览开关；运行时主题由全局 ThemeProvider / CSS 变量处理
- Status: accepted documented divergence
- 例外：`Notification.theme` 和 `Message.theme` 是单实例运行时切换（toast 的 dark/light 不依赖全局），已映射为代码 prop
- **决议详情**：[`divergences-decisions.json`](./divergences-decisions.json) `id: figma-dark-theme-design-state`

### Figma `enable` 属性（Input/CheckBox/Radio/Switch/Select）

- Property type: `VARIANT`（`on/off` 或 `yes/no`）
- Reason: 设计态预览开关；运行时禁用由代码 `disabled` prop 处理
- Status: accepted documented divergence
- **决议详情**：[`divergences-decisions.json`](./divergences-decisions.json) `id: figma-enable-design-state`

### Figma `status` 属性的设计态值

- 出现：`Input` / `CheckBox` / `Radio` / `Select`
- 不映射的值：`hover` / `click` / `error` 等纯视觉状态预览（**Input/Select 的内容态见下方改名说明**）
- 已映射为运行时的值（详见 `docs/internal/runtime-additions.md`）：`Switch.status=live`、`Select.status=multi select`
- Reason: 多数 status 值由 CSS pseudo-classes + 运行时 `error` / `disabled` prop 处理
- Status: accepted documented divergence (with exceptions)
- **决议详情**：[`divergences-decisions.json`](./divergences-decisions.json) `id: figma-status-design-state-values`

### ⚠️ BREAKING — Input/Select `status` 内容态改名（2026-06-08，commit `ccb41049`）

owner 在 Figma 把 **Input box / Select box（line + filled 4 个 set）** 的 `status` 轴内容态值改名（"便于 AI 语义识别"），code 已 1:1 对齐（option B，canonical == Figma）：

| Figma 旧值 | Figma 新值 | 语义 | 渲染驱动 |
|---|---|---|---|
| `default` | `Placeholder` | 占位态（空值）| `modelValue === ''` |
| `normal` | `Value` | 有值态 | `modelValue !== ''` |
| `multi select` | （未改）| Select 多选 | `multiple` / `status==='multi select'` |

- **影响范围**：`InputBoxBase/Line/Filled` + `SelectBoxBase/Line/Filled` 的 `status` prop **公开类型** 由 `'default' \| 'normal' \| …` 改为 `'Placeholder' \| 'Value' \| …`（`'Filled'` 死值保留、`'multi select'` 保留）。
- **消费方迁移**：`<InputBoxLine status="default">` → `status="Placeholder"`；`status="normal"` → `status="Value"`。**默认值也从 `'default'` 改为 `'Placeholder'`**，故只用默认值的消费方无需改。
- **不受影响**：`Button`（`status=default\|hover\|disable\|loading`）与 `Progress`（`status=default\|success\|error\|warning`）的**同名 `status` 轴是无关轴，未改**。
- **非视觉改动**：渲染零变化（drift-gate A_TRUE_DRIFT=0、render-verification 一致）；改的只是轴值命名。
- **发版**：属破坏性 API 改名，下个 `0.x.0` minor 的 changelog 应标注。
- Status: accepted — code aligned to Figma (no residual divergence)

### Figma `UX` 属性的设计态值

- 出现：`Input` / `Select`
- 不映射的值：`click` / `default` / `hover` / `error` 等纯视觉状态预览
- 已映射为运行时的值（详见 `docs/internal/runtime-additions.md`）：`Select.UX=editable`
- Status: accepted documented divergence (with exceptions)
- **决议详情**：[`divergences-decisions.json`](./divergences-decisions.json) `id: figma-ux-design-state-values`

### Figma `Show Icon` / `Show Option` 属性（CheckBox/Radio）

- Property type: `BOOLEAN`
- Reason: 设计态装饰开关；运行时由 Vue slot 处理图标和文案的显隐
- Status: accepted documented divergence
- **决议详情**：[`divergences-decisions.json`](./divergences-decisions.json) `id: figma-show-icon-option-design-state`

### Figma `Content` SLOT（Input/FormItem/Notification/Message）

- Property type: `SLOT`
- Reason: Figma SLOT ≠ Vue slot API；Vue 默认 slot 已承担同等职责
- Status: accepted documented divergence
- 注：`FormItem.Label` 和 `Tooltip.Content` 是双形态决策，单独登记于 `## API 双形态映射`
- **决议详情**：[`divergences-decisions.json`](./divergences-decisions.json) `id: figma-content-slot-vue-slot`

### Figma `Icon` SLOT（CheckBox/Radio）

- Property type: `SLOT`
- Reason: 同 Content SLOT 决策
- Status: accepted documented divergence
- **决议详情**：[`divergences-decisions.json`](./divergences-decisions.json) `id: figma-icon-slot-vue-slot`

### Figma Progress.theme 属性（伪主题，特殊登记）

- Property type: `VARIANT` (`dark/light`)
- 现状：figma 真源 dark/light variant 视觉完全相同（fills 同色 `#cccccc`）；code 之前在 `.progress--light` selector 自创视觉差，违反双层导入精神
- 修复（T1b 2026-04-29）：删除 `src/components/Progress/Progress.vue` 中 `.progress--light` selector + 删除 `:class` 中 `progress--${theme}` 部分；视觉切换由站点级 ThemeProvider + CSS 变量（`--bg-layer3` 等）自动驱动
- **track bg token 确认（INFRA-F41 2026-06-08）**：live Figma `get_variable_defs(4915:7195)` = `Color Type/Background/Layer_3`（dark #262626 / light #f0f0f0）→ `--progress-track-bg: var(--bg-layer3)`。**supersede CANONICAL-004**（其曾改为 `--line-deep` #353535）——FIGMA_AS_SOURCE_OF_TRUTH，回归 T1b 原意。已注解 `.progress__track`→4915:7195，verifier PASS。
- `Progress.theme` prop 保留：runtime + canonical 两层 API 不动（避免破坏调用方），prop 变成 vestigial（无视觉差异作用）；待 Phase 6.4 评估是否 deprecate
- Status: accepted documented divergence（按 figma 真源对齐，code 不自创视觉差）
- 区别于 line 81 的 Class B 5 组件：Class B 是"figma 设计态预览开关，runtime 不暴露 prop"；Progress 是"figma 真伪主题，runtime + canonical 都暴露 prop 但视觉无差异"
- **决议详情**：[`divergences-decisions.json`](./divergences-decisions.json) `id: progress-pseudo-theme-accepted-divergence`

## API 双形态映射

### FormItem.label ↔ Figma Label SLOT

- Figma form: `SLOT`
- Code form: 双形态（`string` prop 或 named `#label` slot）
- 实现规则：
  - 简单文本 → 用 prop（如 `label="Form Label"`）
  - 复杂内容（含图标、富文本）→ 用 `#label` 命名 slot
  - 同时存在时命名 slot 优先
  - **default slot 保持原语义**（content/control 区域），不冲突
- Status: ✅ implemented in Phase 6.6a (2026-05-14); Tooltip part Phase 6.6b pending
- **决议详情**：[`divergences-decisions.json`](./divergences-decisions.json) `id: formitem-label-dual-form`

### Tooltip.content ↔ Figma Content SLOT

- Figma form: `SLOT`
- Code form: 双形态（`string` prop 或 named `#content` slot）
- 实现规则：
  - 简单文本 → 用 prop（如 `content="Description"`）
  - 复杂内容（含图标、富文本）→ 用 `#content` 命名 slot
  - 同时存在时命名 slot 优先
  - **default slot 保持原语义**（trigger 元素），不冲突
- Status: ✅ implemented in Phase 6.6b (2026-05-14); 配套 Phase 6.6a FormItem.label 已 ship (commit 529bb366)
- **决议详情**：[`divergences-decisions.json`](./divergences-decisions.json) `id: tooltip-content-dual-form`

### Badge API 拆分（type 同名异义）

- **历史问题**：legacy `src/components/Badge/Badge.vue` `type=brand/red/orange/blue`（颜色语义）vs Figma `Type=Circle/Rectangle`（形状语义）—— 同名异义。
- **决策（已实施）**：canonical Badge 拆分为三轴对齐 Figma：
  - `color`：颜色语义（`Neutral | Blue | Green | Orange | Red`），对齐 Figma Color
  - `tag`：填充样式（`Filled | Line`），对齐 Figma Tag
  - `type`：形状语义（`Circle | Rectangle`），**对齐 Figma Type axis 命名**（项目翻译层最小化原则——避免在翻译层登记额外 `type ↔ Type` 命名 alias）
- **同名异义隔离**：[`badge-canonical-legacy-dual-source`](./divergences-decisions.json) decision 锁定 canonical 是 npm SoT；legacy 仅留 playground/App.vue + `src/legacy/index.ts` + atomicAssets demo，**不导出 npm**——consumer 看不到 legacy.type=颜色，AI 从 Figma URL → canonical.type 永远是形状语义，0 歧义。
- Status: ✅ implemented (canonical Badge.vue 自 checkpoint `9e3ca1ae` 起即为新 API；Phase 6.7 ack 2026-05-14 — SoT drift artifact 在 pickup 2026-05-14 被发现并修正)
- **早期 decision 措辞 "split into color + shape"**：`shape` 是形状语义描述，**不是 prop name 规定**；canonical 用 `type` 保持与 Figma "Type" axis 命名一致
- **决议详情**：[`divergences-decisions.json`](./divergences-decisions.json) `id: badge-api-split`

### Button 双 API 完成迁移决策

- 现状：`variant` / `size` / `disabled` / `loading` 旧 API 与 `canonicalColor` / `canonicalStyle` / `canonicalRadius` / `canonicalFixedWidth` / `canonicalStatus` / `canonicalIcon` / `canonicalSize` 双轨并存
- 决策：完成迁移到 canonical contract
- 步骤：
  1. 补全 canonical API：新增 `canonicalTheme: 'dark' | 'light'`（覆盖 Figma 8 个 set 的 theme 维度）
  2. 文档主推 canonical API
  3. 旧 API（`variant` / `size` / `disabled` / `loading`）标 `@deprecated`，保留一个版本
  4. 下版本删除旧 API
- Status: ✅ resolved in Phase 6.8 (2026-05-18) — canonicalTheme axis added; legacy API @deprecated since v0.5.0, removed in v0.6.0
- TODO: 实现待 Phase 6.8
- **决议详情**：[`divergences-decisions.json`](./divergences-decisions.json) `id: button-canonical-api-migration`

## Message.interact

- Figma property: `interact`
- Code mapping: not mapped
- Reason: design-time preview switch only; runtime interaction is handled by CSS `:hover` / `:active` and event handlers.
- Status: accepted documented divergence
- **决议详情**：[`divergences-decisions.json`](./divergences-decisions.json) `id: promptmessage-interact-design-state`

## Notification.success

- Figma property/value: no `success` status exists in the published Notification component set
- Code mapping: historical runtime-only status
- Reason: code invented a status outside the Figma family
- Status: ✅ resolved (2026-04-28, Phase 6.3)
- Resolution: code 中已无 `success` runtime status；本轮删除残留 dead CSS `.notif--success`
- **决议详情**：[`divergences-decisions.json`](./divergences-decisions.json) `id: notification-success-deletion`
- **⚠️ 2026-06-10 superseded（非回归）**：owner 把 Notification 重构为双轴 `form` × `type`（set 1408:17154 已 republish），`type='success'` 现在是**已发布的合法 Figma 轴值**（slide / alert 用，绿色 `Success 2` 图标）。原删除（2026-04-28）删的是旧扁平模型里**无 Figma 源**的 success status，当时正确；新的 `type=success` 有 Figma 源、非 divergence，已在 `prop-aliases.json` component-prop-012 登记 exact-match。

## Notification.type

- Figma property/value: no legacy `type` axis exists in the published Notification component set
- Code mapping: historical legacy compatibility axis
- Reason: code invented a second semantic axis outside the Figma family
- Status: ✅ resolved (2026-04-28, Phase 6.3)
- Resolution: 历史 legacy `type` 轴已不存在于 runtime 或 canonical Notification 实现；grep 验证无残留
- **决议详情**：[`divergences-decisions.json`](./divergences-decisions.json) `id: notification-type-deletion`
- **⚠️ 2026-06-10 superseded（非回归）**：双轴重构后 Notification 现在**有**一个 Figma-published `type` 轴（severity：warning/secondary warning/error/info/success/none），与旧的被删 legacy `type`（形状轴、无 Figma 源）语义不同。新 `type` 1:1 对齐 Figma、非 divergence，已在 `prop-aliases.json` component-prop-012 登记 exact-match。

## PillCounter（code-first，无 Figma 源）

- Figma property/value: 已发布库**无** `Pill/Counter` 组件（只有 `Pill Status` 8 变体已发布）
- Code: `src/canonical/PillCounter.vue`（已 npm 导出，4 kind code-first）
- Reason: PillCounter 是 code-first 产物（计数徽标），设计师尚未在 Figma 发布对应组件；故 `figma-to-code-mapping.json` 无 approved 映射，`audit:figma-library-vs-canonical` B-side 经 `KNOWN_CANONICAL_NO_MAPPING` 白名单豁免（带原因）。
- Status: accepted documented divergence（等设计师发布 `Pill/Counter` 后补 figma-to-code-mapping，撤白名单）
- 关联：backlog BRIDGE-MOCKUP-003（PillCounter code-first 标注）/ CANONICAL-028（Pill Status 已收口）；`scripts/audit-figma-library-vs-canonical.mjs` `KNOWN_CANONICAL_NO_MAPPING`
- 注：InputBoxBase / SelectBoxBase 同样不在 mapping 里，但性质不同——它们是被已映射的 Line/Filled 公开面 wrap 的**内部 base**（非 code-first 无源），同样登记在该白名单。

## Logo / MenuList / UserMenu（code-first 双框架组件，META-02，2026-07-02）

- **Figma 侧**：已发布库**无** standalone `Logo` / `MenuList` / `UserMenu` component-set。等价物只作为 `Top bar` 组件的**内部图层**存在（`Menu List` + `Menu` items；账号区 `PM` 头像 + `Account Name`）+ 品牌图标资产（`icon/logo/TVU`、`icon/logo/ts`）。无独立组件节点可 1:1 对齐。
- **Code 侧**：`src/canonical/{Logo,MenuList,UserMenu}.vue` 进**双框架库**（WC `defineCustomElement` + React wrapper，经 `components.config.ts`），**不经** `src/index.ts`（已发布 Vue 包未动）。Logo 提升现有 base `components/Logo/Logo.vue`（渲染 registry 品牌 SVG）；MenuList 抽取 topbar 菜单模式（horizontal 品牌下划线 / vertical 品牌色 + 末尾 `action/selected` 勾选）；UserMenu 合成实心头像→下拉面板（账号头 name+role+email、custom actions 用 MenuList 面板体、行内语言切换、退出）。全 token 化（无裸 hex）、图标走 registry。
- **Reason**：META-02——`CLAUDE_DESIGN_RULES.md` §2-3 要求这三者作为可消费组件在 claude.ai/design 双框架库落地，但 Figma 只在 TopBar 内部建模。Owner 拍板 code-first 2026-07-02（独立排期 ack）。有 Figma 源处保真（Logo 资产、TopBar 菜单模式）；UserMenu 下拉壳按设计规则 spec 属 code-first。
- **Status**: accepted documented divergence。`audit:figma-library-vs-canonical` + `audit:render-verification-coverage` 经共享白名单 `figma-data/audit-allowlist/canonical-exempt.json` 豁免（带原因）；不在 render-verification manifest（无 Figma 节点）→ render-gate-UNVERIFIED，与 PillCounter/Breadcrumb 同 posture，保真靠 `audit:binding-config-parity` + smoke test + 同生成器管线。
- **决议详情**：[`divergences-decisions.json`](./divergences-decisions.json) `id: logo-menulist-usermenu-code-first-2026-07-02` · 关联 backlog META-02。若未来发布为 standalone Figma 组件，1:1 reconcile 并关闭本 divergence。
