# 一套可计算的界面设计规范

本文展示如何把色彩、对比度、色阶、设计令牌、组件状态与交付校验整理成一套可复用的界面规则。

适用范围：文中品牌色、色阶和尺寸令牌是一套计算示例，不是本资料库网站或 `words-app-yunxiao` 的现行主题配置。应用到具体项目时，应以目标项目的本地约定和全局令牌为准；本资料库站点的样式令牌定义在 `public/assets/site.css`。`words-app-yunxiao` 的实践提示还应核对现有页面状态和多端交互，不能只验算令牌表；执行要点见[界面基础规范](interface-foundations.md)。

来源：个人知识库《一套可计算的界面设计规范》（UI 设计规范 v1.0）。

| 项目 | 规格 |
| --- | --- |
| 版本 | v1.0 |
| 品牌色 | 4 个 / 2 族 |
| 色阶 | 每条 10 级 |
| 中性色阶 | 12 级 |
| 圆角令牌 | 5 档 |
| 对比度依据 | WCAG 2.1 |

> 从四个品牌色到一个完整令牌体系 —— 每一个数值都可追溯、可复现、可被下一个执行者直接使用。

## 00 文档说明

这份文档描述的不是一版视觉稿，而是一套**可被复用的规则**。它的每一个数值都可以被追溯、被计算、被验证 —— 颜色为什么只能是这四个、圆角为什么只有五档、层级为什么不能用阴影，本文都给出可核对的依据，而不是「这样比较好看」。

全文共 13 个章节，分为三层：**价值层**（§01 原则）、**系统层**（§02–§07 色彩与令牌）、**执行层**（§08–§12 组件、检查与复用）。若只有 5 分钟，读 §01 与 §11；若要动手实现，直接进 §06 与 §12。

> **阅读路径**
> **决策者**：§01 设计原则 → §02.5 角色分配 → §11 跨项目复用。  
> **设计师**：§02 色彩系统 → §03 色阶推演 → §05 渐变规范 → §07 层级表达。  
> **前端**：§04 中性色阶 → §06 设计令牌 → §08 组件规范 → §12 交付检查清单。

### 文档约定

- 所有色值采用 `#RRGGBB` 大写十六进制，不使用 `rgba()`、`hsla()` 或任何带透明通道的写法。
- 对比度一律按 WCAG 2.1 相对亮度公式计算，标注格式为 `数值:1`。分级含义：**AAA** ≥ 7:1，**AA** ≥ 4.5:1，**AA·大字** ≥ 3:1（仅限 ≥24px 常规或 ≥18.66px 粗体）。
- 「档位」指 10 级色阶中的位置，本系统用 `50 / 100 / … / 900` 标记，数值越小越浅。
- 本文档界面遵守其定义的禁则；键盘焦点通过令牌色块保持可见，见 §09.2。

## 01 设计原则

以下五条不是风格偏好，是**约束**。约束与偏好的区别在于：约束可以判定违反与否，偏好只能争论。这五条里没有一条提到「好看」。

### 原则一 · 先定约束，再定风格

风格是约束的结果，不是起点。当有人提出「我想要蓝色加粉色」时，讨论必然滑向审美判断；当陈述改为「现有做法会随内容增长而失控」时，讨论才进入逻辑判断。所有视觉决策都应能回答同一个问题：*它约束了什么？*

### 原则二 · 层级用明度差与色块表达

模块层级优先使用相邻明度差与色块拼接。阴影禁用，描边不表达层级、选中或焦点；只有相邻两面没有可用明度差、又确实需要标明边界时，才使用令牌 `--line-subtle`。

### 原则三 · 颜色角色由对比度决定，不由审美决定

一个颜色能承担什么角色，取决于它压在白底上的对比度数值。过 7:1 才能做正文，过 4.5:1 能做小字，3:1 只能做大字与按钮，低于 3:1 就只能做装饰。**先算，再分配**。本系统中藏青之所以是主色，唯一原因是它 9.61:1，是四色中唯一能承载正文的。

### 原则四 · 令牌唯一，不留自由值

任何视觉值都必须来自令牌表。出现一个 `13px` 的字号或 `10px` 的圆角，就意味着系统出现了漏洞。令牌化的目的不是整洁，是**可交接** —— 下一个执行者不需要问「这里该用多少」。

### 原则五 · 强调色的价值来自它的稀缺

强调色一旦铺开就失效。玫红在本系统中的每一次出现都对应一个明确的动作或重点，出现频率约占总面积的 **3% 以下**。这是刻意控制的配额，不因「这里有点空」而调高。

> **一句话总纲**
> **用可计算的规则替代不可争论的审美**。规则一旦成立，后续任何人照着做都能得到一致结果，不需要再回到「好不好看」这个无法收敛的问题上。

## 02 色彩系统

先给结论：**这四个色不是四个独立色，而是两族颜色**。冷色族两个（藏青、青蓝），粉族两个（玫红、浅粉）。每一族都是一「深」一「浅」，浅色从深色派生而来。这是这套配色看起来成套的根本原因，也是它可被复用的前提。

### 2.1 品牌色定义

四色之外，本系统不引入任何第五个色相。全部界面的色彩表达由这四色加一条中性灰阶完成。

- **结构色 · 藏青** — #0D3D9F；RGB 13 61 159；HSL 220.3° 84.9% 33.7%；明度档位 700；白底对比 9.61:1
- **强调色 · 玫红** — #F7226F；RGB 247 34 111；HSL 338.3° 93.0% 55.1%；明度档位 500；白底对比 3.88:1
- **装饰色 · 青蓝** — #0DAACD；RGB 13 170 205；HSL 190.9° 88.1% 42.7%；明度档位 600；白底对比 2.75:1
- **装饰色 · 浅粉** — #F88EC6；RGB 248 142 198；HSL 328.3° 88.3% 76.5%；明度档位 200；白底对比 2.17:1

> **命名纠正**
> 玫红常被误称为「鲑红」。**#F7226F 的色相是 338.3°，属于偏冷的品红**；鲑红（salmon）大致落在 6° 附近，是橙粉。两者相差一个色温区。命名精确在色彩工作里不是修辞问题 —— 它决定了后续推导方向：从 338.3° 往浅走得到浅粉，从 6° 往浅走得到蜜桃色，是完全不同的结果。

### 2.2 色相结构：两族，不是四个

把四个色的色相角排到色环上，结构立刻显现：

- **冷色族**：藏青 `220.3°` 与青蓝 `190.9°`，相差 **-29.4°** —— 属于*邻近色*关系，不是同一色也不构成对比色。
- **粉族**：玫红 `338.3°` 与浅粉 `328.3°`，相差 **10.0°** —— 这已经不是「邻近」，而几乎是*同一色相*。

这意味着浅粉并不是一个独立选择的粉色，它就是玫红**提亮后的版本**；青蓝也不是一个独立的蓝，它是藏青沿色环偏移 -29.4° 后的邻近色。辅色有出处，所以不打架。

> **可验证的判据**
> 把两个「辅色」单独拿出来问：「它从哪个主色派生出来的？」**如果答不上来，这个辅色就是错的**，无论它看起来多合适。本条判据在 §11 的复用配方里会再次用到。

### 2.3 饱和度约束：全系统收敛在 84–93%

这是整套配色最容易被忽略、却最关键的一条。四个色的饱和度分别为：

| 颜色 | 色相 H | 饱和度 S | 明度 L | 与基准的差距 |
| --- | --- | --- | --- | --- |
| 藏青 | 220.3° | **84.9%** | 33.7% | 0.0 个百分点 |
| 玫红 | 338.3° | **93.0%** | 55.1% | 8.1 个百分点 |
| 青蓝 | 190.9° | **88.1%** | 42.7% | 3.2 个百分点 |
| 浅粉 | 328.3° | **88.3%** | 76.5% | 3.4 个百分点 |

全部落在 **84.9% – 93.0%** 这个极窄的区间内，极差仅 **8.1 个百分点**。这是「高级感」的真正来源：*色相可以拉得很开，饱和度必须齐*。

> **最常见的一种破坏**
> 只要把其中任意一个色的饱和度降到 40% 左右（例如常见的莫兰迪灰蓝），**整套配色会立刻显得拼凑**。原因是其余三色仍在 85% 以上，唯一那个低饱和色会被读成「没调好」，而不是「刻意柔和」。若要降低整体饱和度，必须**四个一起降**，保持极差不变。

### 2.4 明度阶梯与档位锚定：四色分处四个不重叠的明度带

把明度轴切成一架 10 级阶梯，四个品牌色**精确落在四个不同档位上**，彼此不重叠。这不是巧合，是这套配色能同时容纳四色而不混乱的结构性原因 —— 它们压根不在同一个明度区间里竞争。

| 颜色 | 明度 L | 锚定档位 | 偏差 | 所处明度带 |
| --- | --- | --- | --- | --- |
| 藏青 | 33.7% | 700 | 0.0 | 暗 |
| 青蓝 | 42.7% | 600 | 0.0 | 中暗 |
| 玫红 | 55.1% | 500 | 0.0 | 中亮 |
| 浅粉 | 76.5% | 200 | 0.0 | 亮 |

明度依次为 **33.7% → 42.7% → 55.1% → 76.5%**，相邻间隔 9.0 / 12.4 / 21.4 个百分点，呈*递增*排列。间隔之所以递增，是因为人眼对亮部差异的分辨力弱于暗部 —— 亮区需要更大的明度跨度才能产生同等程度的「不同感」。四个色之所以看起来层次分明，正是因为它在暗端收得紧、亮端放得开。

> **为什么这条重要**
> 很多配色方案失败的原因不是颜色选得难看，而是**四个色挤在同一条明度带上**。挤在一起就必然争夺同一角色，最终只能靠加大面积或加饱和度来强行区分，结果就是页面花。本系统在数值层面就已经把四个色的位置错开了。

### 2.5 对比度与角色分配：角色是算出来的

明度差直接决定对比度，对比度直接决定这个色能用在哪里。下表是四个色压在白底（#FFFFFF）上的实测值：

| 颜色 | 色值 | 压白底对比度 | 白底等级 | 白色压它 | 系统角色 |
| --- | --- | --- | --- | --- | --- |
| 藏青 | #0D3D9F | **9.61:1** | AAA | 9.61:1 | 结构色 —— 正文、标题、深色区块、主按钮 |
| 玫红 | #F7226F | **3.88:1** | AA·大字 → 大字 AA | 3.88:1 | 强调色 —— 行动按钮、大字、跳色、标签 |
| 青蓝 | #0DAACD | **2.75:1** | 不达标 | 2.75:1 | 装饰色 —— 图标、徽章、图形元素 |
| 浅粉 | #F88EC6 | **2.17:1** | 不达标 | 2.17:1 | 装饰色 —— 底色衬、深底上的点缀 |

这张表解释了一个常被误解的现象：**角色不是设计者决定的，是数值算出来的**。

- 藏青 **9.61:1**，远过 7:1 的 AAA 线 —— 所以它可以承担正文，进而可以承担结构。
- 玫红 **3.88:1**，差一点够不到 4.5:1 的 AA 正文线 —— 所以*它不能做正文*，只能用于 ≥18.66px 粗体的大字与实心按钮。**这不是保守，是可用性红线**。
- 青蓝 2.75:1、浅粉 2.17:1 完全不具备承载语义的能力 —— 只能退到装饰层。

反过来说：如果一定要让玫红承担正文，就必须把它的明度压到 33.7% 附近（即色阶 700 档），但那会让它变成一种暗红，**失去作为强调色所需的视觉音量**。这是一次此消彼长，本系统选择保留它的音量，因此把它限制在大字与按钮。

### 2.6 对比度矩阵

以下是四个品牌色与关键中性色两两之间的实测对比度。深蓝数字＝≥4.5:1 可用于正文；玫红数字＝3–4.5:1 仅限大字；灰字＝<3:1 禁止承载文字。

| 前景 ↓ / 背景 → | 藏青 | 玫红 | 青蓝 | 浅粉 | 近黑 | 中灰 | 浅灰 | 白 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 藏青 | 1.00 | 2.48 | 3.50 | 4.43 | 1.90 | 1.67 | 7.90 | 9.61 |
| 玫红 | 2.48 | 1.00 | 1.41 | 1.79 | 4.71 | 1.49 | 3.19 | 3.88 |
| 青蓝 | 3.50 | 1.41 | 1.00 | 1.27 | 6.66 | 2.10 | 2.26 | 2.75 |
| 浅粉 | 4.43 | 1.79 | 1.27 | 1.00 | 8.42 | 2.66 | 1.78 | 2.17 |
| 近黑 | 1.90 | 4.71 | 6.66 | 8.42 | 1.00 | 3.17 | 15.02 | 18.28 |
| 中灰 | 1.67 | 1.49 | 2.10 | 2.66 | 3.17 | 1.00 | 4.74 | 5.77 |
| 浅灰 | 7.90 | 3.19 | 2.26 | 1.78 | 15.02 | 4.74 | 1.00 | 1.22 |
| 白 | 9.61 | 3.88 | 2.75 | 2.17 | 18.28 | 5.77 | 1.22 | 1.00 |

读法：行是前景，列是背景。例如「玫红 × 藏青」= 2.48:1，说明玫红文字压在藏青底上不达标；反过来「藏青 × 玫红」= 2.48:1，同样不达标。**藏青与玫红不能互为文字与底色** —— 这是本系统一条硬性配对禁令。

## 03 色阶推演

上面四个品牌色只是「一个点」。要支撑整个界面，每个品牌色都需要扩展成一条**色阶** —— 一条从近白到近黑的 10 级梯度。本节给出这套色阶的推导公式，公式可直接套用到任意新色。

### 3.1 三条推演规则

色阶不是「调浅一点、调深一点」试出来的。它由三条明确规则生成，因此结果可复现、可审计。

> **规则一 · 色相锁定**
> 整条色阶 **色相 H 恒定不变**。取色阶上的任何一档，色相角都等于基准色相的原始值。这是「同一条色阶」之所以成立的唯一依据。

> **规则二 · 明度插值**
> 以**基准色所锚定的档位为支点**，向亮端（L=97%）与暗端（L=12%）两个方向线性插值。支点档位的色值精确等于原始品牌色。

> **规则三 · 饱和补偿**
> 从支点向亮端，饱和度线性衰减至基准的 **62%**；向暗端衰减至 **88%**。这一步不可省 —— 明度大幅变化时饱和度必须同步补偿，否则亮端会发灰、暗端会发黑。

> **为什么亮端要「降饱和」**
> 这不是审美调整，是补偿。在 HSL 空间里把明度推到 97% 而保持饱和度不变，颜色会逼近纯色而不是逼近白色，视觉上会显得刺眼；反过来让饱和度同步下降，得到的才是真正像「被光稀释过的同色」。暗端同理：明度压到 12% 而饱和度不降，会糊成一种发黑的浊色。

### 3.2 推导算法

**伪代码 · 色阶生成**
```text
// 输入：基准色 (H, S, L) 与其锚定档位 k
// 输出：10 档色阶 L[0..9] ∈ {50,100,200,...,900}

for i in 0..9:
  if i <= k:                    // 亮端
    t = (i - k) / (0 - k)
    L = L_base + (97.0 - L_base) * t
    S = S_base * (1 - (1 - 0.62) * t)
  else:                          // 暗端
    t = (i - k) / (9 - k)
    L = L_base + (13.0 - L_base) * t
    S = S_base * (1 - (1 - 0.88) * t)
  hex[i] = HSL_to_HEX(H, S, L)   // H 恒定，从不修改
```

把四个品牌色代入这套算法，得到的支点档位分别是 **700 / 600 / 500 / 200**，与 §2.4 的锚定表一致。这也是为什么浅粉的色阶几乎是从「已提亮」的位置向两端展开 —— 它本身就坐在阶梯的亮区。

### 3.3 四条色阶

- **藏青**：锚点 700 · 色相锁定 220.3° · 基准饱和度 84.9%
- **玫红**：锚点 500 · 色相锁定 338.3° · 基准饱和度 93.0%
- **青蓝**：锚点 600 · 色相锁定 190.9° · 基准饱和度 88.1%
- **浅粉**：锚点 200 · 色相锁定 328.3° · 基准饱和度 88.3%

### 3.4 各色阶明细与可用性

「压白底」为该色作为文字压在白底上的对比度；「白色压它」为白色文字压在该色上的对比度；「白底等级」以「压白底」判定。

#### 藏青 · 基准 #0D3D9F（档位 700）

| 档位 | 色值 | 饱和度 | 明度 | 压白底 | 白色压它 | 白底等级 | 标记 |
| --- | --- | --- | --- | --- | --- | --- | --- |
| 50 | #F3F6FB | 52.6% | 97.0% | 1.08:1 | 1.08:1 | 不达标 | — |
| 100 | #CFDAF2 | 57.2% | 88.0% | 1.4:1 | 1.4:1 | 不达标 | — |
| 200 | #A8BEEA | 61.9% | 78.9% | 1.87:1 | 1.87:1 | 不达标 | — |
| 300 | #7FA1E5 | 66.5% | 69.9% | 2.58:1 | 2.58:1 | 不达标 | — |
| 400 | #5483E2 | 71.1% | 60.8% | 3.67:1 | 3.67:1 | AA·大字 | — |
| 500 | #2764E1 | 75.7% | 51.8% | 5.25:1 | 5.25:1 | AA | — |
| 600 | #154FC5 | 80.3% | 42.7% | 7.1:1 | 7.1:1 | AAA | — |
| 700 | #0D3D9F | 84.9% | 33.7% | 9.61:1 | 9.61:1 | AAA | **锚点** |
| 800 | #0C2B6B | 79.8% | 23.4% | 13.35:1 | 13.35:1 | AAA | — |
| 900 | #08193A | 74.7% | 13.0% | 17.35:1 | 17.35:1 | AAA | — |

#### 玫红 · 基准 #F7226F（档位 500）

| 档位 | 色值 | 饱和度 | 明度 | 压白底 | 白色压它 | 白底等级 | 标记 |
| --- | --- | --- | --- | --- | --- | --- | --- |
| 50 | #FCF3F6 | 57.7% | 97.0% | 1.09:1 | 1.09:1 | 不达标 | — |
| 100 | #F5CFDD | 64.7% | 88.6% | 1.41:1 | 1.41:1 | 不达标 | — |
| 200 | #F1A8C3 | 71.8% | 80.2% | 1.89:1 | 1.89:1 | 不达标 | — |
| 300 | #F07FA8 | 78.9% | 71.9% | 2.53:1 | 2.53:1 | 不达标 | — |
| 400 | #F2528C | 85.9% | 63.5% | 3.3:1 | 3.3:1 | AA·大字 | — |
| 500 | #F7226F | 93.0% | 55.1% | 3.88:1 | 3.88:1 | AA·大字 | **锚点** |
| 600 | #D80B55 | 90.2% | 44.6% | 5.12:1 | 5.12:1 | AA | — |
| 700 | #A30B42 | 87.4% | 34.0% | 7.82:1 | 7.82:1 | AAA | — |
| 800 | #6F092E | 84.6% | 23.5% | 11.97:1 | 11.97:1 | AAA | — |
| 900 | #3C061A | 81.8% | 13.0% | 17.03:1 | 17.03:1 | AAA | — |

#### 青蓝 · 基准 #0DAACD（档位 600）

| 档位 | 色值 | 饱和度 | 明度 | 压白底 | 白色压它 | 白底等级 | 标记 |
| --- | --- | --- | --- | --- | --- | --- | --- |
| 50 | #F3FAFC | 54.6% | 97.0% | 1.06:1 | 1.06:1 | 不达标 | — |
| 100 | #CEECF3 | 60.2% | 88.0% | 1.24:1 | 1.24:1 | 不达标 | — |
| 200 | #A6E0ED | 65.8% | 78.9% | 1.45:1 | 1.45:1 | 不达标 | — |
| 300 | #7BD5E9 | 71.4% | 69.8% | 1.68:1 | 1.68:1 | 不达标 | — |
| 400 | #4ECCE8 | 76.9% | 60.8% | 1.89:1 | 1.89:1 | 不达标 | — |
| 500 | #1EC5E9 | 82.5% | 51.8% | 2.06:1 | 2.06:1 | 不达标 | — |
| 600 | #0DAACD | 88.1% | 42.7% | 2.75:1 | 2.75:1 | 不达标 | **锚点** |
| 700 | #0D819A | 84.6% | 32.8% | 4.54:1 | 4.54:1 | AA | — |
| 800 | #0B596A | 81.1% | 22.9% | 7.92:1 | 7.92:1 | AAA | — |
| 900 | #07323B | 77.5% | 13.0% | 13.74:1 | 13.74:1 | AAA | — |

#### 浅粉 · 基准 #F88EC6（档位 200）

| 档位 | 色值 | 饱和度 | 明度 | 压白底 | 白色压它 | 白底等级 | 标记 |
| --- | --- | --- | --- | --- | --- | --- | --- |
| 50 | #FCF3F8 | 54.7% | 97.0% | 1.09:1 | 1.09:1 | 不达标 | — |
| 100 | #F5C5DF | 71.5% | 86.8% | 1.51:1 | 1.51:1 | 不达标 | — |
| 200 | #F88EC6 | 88.3% | 76.5% | 2.17:1 | 2.17:1 | 不达标 | **锚点** |
| 300 | #F464B0 | 86.8% | 67.4% | 2.88:1 | 2.88:1 | 不达标 | — |
| 400 | #EF3A9A | 85.3% | 58.4% | 3.66:1 | 3.66:1 | AA·大字 | — |
| 500 | #E71484 | 83.8% | 49.3% | 4.35:1 | 4.35:1 | AA·大字 | — |
| 600 | #BB126B | 82.2% | 40.2% | 6.16:1 | 6.16:1 | AA | — |
| 700 | #900F53 | 80.7% | 31.1% | 8.83:1 | 8.83:1 | AAA | — |
| 800 | #650C3B | 79.2% | 22.1% | 12.58:1 | 12.58:1 | AAA | — |
| 900 | #3B0723 | 77.7% | 13.0% | 16.93:1 | 16.93:1 | AAA | — |

> **从色阶取色的规则**
> **先确定需要的对比度，再到色阶上找对应档位**，而不是先挑一个好看的颜色再想办法让它可读。要正文就取 ≤ 600 档的深端，要大字就取 500–700 档，要底色就取 50–200 档，要装饰就取 300–400 档。*档位与用途是一一对应的*。

> **关于 800 / 900 两档**
> 这两档在常规界面里使用频率很低，但它们不是冗余。它们的用途是**深色模式底色**与**大面积深色区块** —— 用 700 档（即品牌色本身）铺满整屏会显得过饱和，800/900 档则是它压制后的版本，同色相、更低明度、更低饱和，适合作为整片背景。这是深色模式能在不引入任何新色相的前提下成立的原因。

## 04 中性色阶

四个品牌色只解决「强调」，不解决「结构」。级别、分隔、底层、正文、边框（的概念）、禁用态 —— 这些占界面面积 90% 以上的角色，全部由一条中性色阶承担。本节定义这条色阶，以及**隔几级才看得出来**这个实操问题。

### 4.1 十二级冷调灰阶

色阶共 12 级，从纯白 `N0` 到近黑 `N11`。两条设计决定：

- **数量取 12 而非 10**。层级表达需要足够细的颗粒度，尤其在浅端 —— 表层层级之间的差距必须小而连续，级数太少会导致「要么看不出，要么太跳」。
- **带蓝色倾向（H=222）**。品牌主色藏青的色相是 220.3°，灰阶取 222° 与之基本一致，且饱和度极低（最高 35%，最暗端 26%）。结果是每一级灰都带一丝察觉不到的冷调。*纯中性灰（S=0）与这组高饱和品牌色放在一起会显得脏*，这是常见问题，带倾向的灰可以消除它。

### 4.2 各级用途分配

| 令牌 | 色值 | 明度 | 压白底 | 压近黑 | 白底等级 |
| --- | --- | --- | --- | --- | --- |
| N0 | #FFFFFF | 100.0% | 1:1 | 18.28:1 | 不达标 |
| N1 | #F7F9FB | 97.8% | 1.06:1 | 17.32:1 | 不达标 |
| N2 | #F1F3F8 | 95.8% | 1.11:1 | 16.47:1 | 不达标 |
| N3 | #E5E9F1 | 92.2% | 1.22:1 | 15.02:1 | 不达标 |
| N4 | #D9DEEA | 88.5% | 1.35:1 | 13.57:1 | 不达标 |
| N5 | #C7CEDE | 82.5% | 1.58:1 | 11.59:1 | 不达标 |
| N6 | #A3ADC4 | 70.5% | 2.25:1 | 8.12:1 | 不达标 |
| N7 | #7F89A1 | 56.5% | 3.5:1 | 5.22:1 | AA·大字 |
| N8 | #5D6679 | 42.0% | 5.77:1 | 3.17:1 | AA |
| N9 | #414858 | 30.0% | 9.16:1 | 2:1 | AAA |
| N10 | #2B3140 | 21.0% | 12.99:1 | 1.41:1 | AAA |
| N11 | #11151D | 9.0% | 18.28:1 | 1:1 | AAA |

| 令牌 | 色值 | 系统用途 | 禁止用途 |
| --- | --- | --- | --- |
| N0 | #FFFFFF | 页面底色、卡片底、深色块上的文字 | — |
| N1 | #F7F9FB | 极轻微的表层浮动（悬停态） | 正文底色（与白几乎不可分） |
| N2 | #F1F3F8 | 分区底色、侧栏底、说明块底 | — |
| N3 | #E5E9F1 | 次级底块、表格隔行、禁用底 | — |
| N4 · N5 | #D9DEEA · #C7CEDE | 分隔块、占位图形、禁用控件底 | 承载文字 |
| N6 | #A3ADC4 | 占位图形、装饰条、图标底 | 承载文字 |
| N7 | #7F89A1 | 辅助文字（≥18.66px 粗体） | 小字正文 |
| N8 | #5D6679 | **正文与次要文字（默认）** | — |
| N9 | #414858 | 正文强调、小字正文 | — |
| N10 | #2B3140 | 标题、深色底块 | — |
| N11 | #11151D | 深色区块底、页脚、代码块底、主标题 | — |

> **一处需要留意**
> N8（#5D6679，压白底 5.77:1）与 N9（#414858，9.16:1）都达标，区别在**用途**而不在达标与否：N8 是默认正文，N9 是正文中需要「更重一点」的部分。两者同时出现时差距才可读，单独使用无法察觉差别。

### 4.3 层级差：隔几级才看得出来

这是实操中最常踩的一个坑。相邻两级看起来「几乎一样」，隔一级仍然不够，隔两级才刚够分辨。以下是以浅端底色为基准的实测对比度：

| 间隔 | 典型对比度 | 视觉判断 | 建议用法 |
| --- | --- | --- | --- |
| 相邻 1 级 | 1.05 – 1.18 : 1 | 几乎不可辨，需要并排对比才能察觉 | 仅用于悬停态等极微妙反馈 |
| 隔 2 级 | 1.11 – 1.31 : 1 | 可辨，边界清楚但不抢戏 | **表层层级默认值**（卡片浮起 / 下沉） |
| 隔 3 级 | 1.22 – 1.53 : 1 | 明确分区，无需任何辅助元素 | 区块级分区、侧栏与主区 |
| 隔 4 级以上 | 1.35 – 2.18 : 1 | 强对比，接近「另一个界面」 | 深色区块、页脚、强调区 |

结论直接可用：**表层层级用隔 2 级，区块分区用隔 3 级**。这两个数字替代了原本由描边和阴影承担的层级表达。

> **为什么不能只隔 1 级**
> 因为屏幕不是纸。在低色域、低亮度、有环境光的实际使用条件下，1.05:1 的差距会被完全抹掉；而对视觉正常的人来说它本就在可辨阈值的边缘。**设计评审时在好显示器上看是「能看出来」的，到用户手里就是「没看出来」**。取 2 级是留出安全余量，不是浪费层级。

## 05 渐变规范

界面及其配套视觉统一使用纯色与明确的色阶，不使用渐变。层级通过明度差和色块拼接表达；强调或状态变化应从既定令牌中选择单一档位。

- 禁止线性、径向、锥形以及由品牌色过渡到透明的渐变。
- 渐变背景上的文字对比度会随位置变化，难以稳定验证；文字与背景应使用确定的颜色值。
- 需要表现色彩层次时，使用色阶中的实色或离散的纯色色块，不使用连续过渡。

## 06 设计令牌

令牌是这套系统的最小单位。原则很简单：**凡是会被重复使用、且需要保持一致的值，都必须有一个名字**。令牌表之外不允许存在任何自由值。

### 6.1 命名规范

- `--c-{role}` —— 品牌色。用**角色**命名而非色相名（`--c-struct` 而不是 `--c-navy`）。理由：若哪天品牌换成绿色，「结构色」这个名字依然成立，而「藏青」会变成一个说谎的名字。
- `--n{0-11}` —— 中性色阶。数字即明度序位，越小越浅。
- `--r-size` / `--sp1…--sp9` / `--fs-size` —— 尺寸类令牌，序号或语义名均可，但同一类必须统一。
- `--line-subtle` —— 唯一允许的细线令牌，仅用于相邻两面没有可用明度差且仍需标明边界的情况。
- `--c-role` 与 `--n0…--n11` 之外的语义色一律**不新增**。需要「成功 / 警告 / 危险」时，从现有色阶取档，不引入新色相（见 §11.4）。

### 6.2 完整令牌表

**CSS 自定义属性 · 全量令牌**
```css
/* ——— 品牌色 · 4 ——— */
--c-struct: #0D3D9F;   /* 结构色 · 藏青 */
--c-accent: #F7226F;   /* 强调色 · 玫红 */
--c-deco-1: #0DAACD;   /* 装饰色 · 青蓝 */
--c-deco-2: #F88EC6;   /* 装饰色 · 浅粉 */

/* ——— 中性色阶 · 12 ——— */
--n0: #FFFFFF;
--n1: #F7F9FB;
--n2: #F1F3F8;
--n3: #E5E9F1;
--n4: #D9DEEA;
--n5: #C7CEDE;
--n6: #A3ADC4;
--n7: #7F89A1;
--n8: #5D6679;
--n9: #414858;
--n10: #2B3140;
--n11: #11151D;

/* ——— 同明度边界补充线 · 唯一形态 ——— */
--line-subtle: 1px solid var(--n4);

/* ——— 圆角 · 5 档 ——— */
--r-sm: 8px; --r-md: 12px; --r-lg: 20px;
--r-pill: 999px; --r-full: 50%;

/* ——— 间距 · 9 档 ——— */
--sp1: 4px; --sp2: 8px; --sp3: 12px; --sp4: 16px;
--sp5: 24px; --sp6: 32px; --sp7: 48px; --sp8: 64px; --sp9: 96px;

/* ——— 字号 · 8 档 / 行高 · 4 档 ——— */
--fs-xs: 12px; --fs-sm: 13px; --fs-base: 15px; --fs-md: 17px;
--fs-lg: 22px; --fs-xl: 30px; --fs-2xl: 44px; --fs-3xl: 64px;
--lh-tight: 1.2; --lh-snug: 1.45; --lh-base: 1.7; --lh-loose: 1.85;

/* ——— 字重 · 4 档 ——— */
--w-reg: 400; --w-med: 500; --w-bold: 700; --w-black: 900;

/* ——— 动效 · 3 档 ——— */
--dur-fast: 120ms; --dur-base: 200ms; --dur-slow: 320ms;
--ease: cubic-bezier(.2,.7,.3,1);

/* ——— 层级 · 5 档 ——— */
--z-base: 0; --z-sticky: 100; --z-dropdown: 300;
--z-modal: 600; --z-toast: 900;
```

### 6.3 圆角：五档封顶

圆角是最容易被「顺手写个值」破坏的一项。本系统圆角只有五档，没有 `border-radius: 10px` 这样的写法，圆角为 0 时**不声明该属性**（默认值即 0），因此也不占用档位。

- `--r-sm 8px`
- `--r-md 12px`
- `--r-lg 20px`
- `--r-pill 999px`
- `--r-full 50%`

| 令牌 | 值 | 适用元素 |
| --- | --- | --- |
| --r-sm | 8px | 标签内块、小按钮、单选块、代码内联块 |
| --r-md | 12px | 输入框、次级卡片、色块、分页项 |
| --r-lg | 20px | 主卡片、区块容器、弹层、图片容器 |
| --r-pill | 999px | 主按钮、标签、徽章、输入胶囊 |
| --r-full | 50% | 头像、圆点标记、圆形徽章 |
| （默认） | 0 | 页面区块、整屏容器、深色区块 —— **不声明** |

> **一条容易忽略的规则**
> 嵌套时的圆角必须**外大内小**：外层容器用 `--r-lg`，内部元素最多用到 `--r-md`。若内外同值，内层圆角在视觉上会显得比外层更圆，破坏规整感。这是几何问题，不是审美问题。

### 6.4 间距：九档等比

间距从 4px 起，按约 1.5 倍递增。所有 `padding` / `margin` / `gap` 只能取这九档。

- `--sp1` — 4px
- `--sp2` — 8px
- `--sp3` — 12px
- `--sp4` — 16px
- `--sp5` — 24px
- `--sp6` — 32px
- `--sp7` — 48px
- `--sp8` — 64px
- `--sp9` — 96px

| 令牌 | 值 | 典型用途 |
| --- | --- | --- |
| --sp1 | 4px | 图标与文字之间、标签内边距 |
| --sp2 | 8px | 行内元素间距、紧凑列表项间距 |
| --sp3 | 12px | 列表项内边距、表单字段内边距 |
| --sp4 | 16px | 卡片内边距（紧凑）、网格间距（密） |
| --sp5 | 24px | 卡片内边距（标准）、组件之间 |
| --sp6 | 32px | 卡片内边距（宽松）、区块内元素间距 |
| --sp7 | 48px | 区块之间的间距 |
| --sp8 | 64px | 大区块之间的间距 |
| --sp9 | 96px | 章节级留白、页面上下边距 |

### 6.5 字号与行高

- `--fs-3xl 64px / 1.2` — 页面主标题
- `--fs-2xl 44px / 1.2` — 区块大标题
- `--fs-xl 30px / 1.2` — 章节标题
- `--fs-lg 22px / 1.45` — 卡片标题 / 导语
- `--fs-md 17px / 1.7` — 正文强调
- `--fs-base 15px / 1.7` — 默认正文
- `--fs-sm 13px / 1.7` — 辅助文字
- `--fs-xs 12px / 1.7` — 标注 · 元信息

**行高与字号成反比**：字号越大行高越紧（64px 配 1.2），字号越小行高越松（13px 配 1.7）。原因是文字越大，行间的视觉空隙本身就越大，再配大行高会散架；文字越小越需要额外的行间距来保证横向阅读不串行。上表中各条已按此规则配对，直接取用即可。

### 6.6 字重与动效

> **字重 · 四档**
> `400` 正文 · `500` 次级强调 · `700` 小标题与按钮 · `900` 大标题与数字。  
> 中文环境下**不使用 100–300 的细体**：中文字形笔画密集，细体在小字号下笔画会糊成一片，可读性显著低于西文。

> **动效 · 三档**
> `120ms` 悬停、按下等即时反馈 · `200ms` 展开、淡入等常规过渡 · `320ms` 弹层、抽屉等大幅位移。  
> 缓动统一使用 `cubic-bezier(.2,.7,.3,1)`（快出慢停）。**禁止为动效添加任何形式的不透明度变化**，需要弱化时用色阶换色。

> **令牌化的验收标准**
> 把样式文件里所有的字面色值、尺寸数字搜一遍 —— **如果出现任何不属于令牌表的值，令牌化就没有完成**。这项检查应该在每次提交前自动执行，而不是靠人眼复查。

## 07 层级表达

本节规定如何用明度差、色块和留白表达层级。边界细线仅按下文的同明度例外使用，不表达层级或状态。

### 7.1 三种手段与优先级

| 优先级 | 手段 | 承担范围 | 数值依据 |
| --- | --- | --- | --- |
| 1 | **底色切换** | 区块级分区、页面段落划分 | 相邻区块隔 3 级（≈1.3:1） |
| 2 | **色块嵌套** | 同类元素内的层级、卡片与底的关系 | 卡片与底隔 2 级（≈1.2:1） |
| 3 | **尺寸与留白** | 紧密相邻的模块边界、分组 | 间距差 ≥ 2 档（如 24px vs 48px） |

优先级的意义在于**用最上面的手段解决问题**。能用底色切换解决的，就不要动用色块嵌套 —— 每往下一层，页面的视觉复杂度就上升一级。相邻面无法采用明度差区分、且确实需要边界时，才使用 `--line-subtle`；它不用于层级或状态。

### 7.2 核心推论：浮起与下沉

> **两条方向相反的规则**
> **浅灰底上放白块 → 白块比底亮，读作「浮起」。**  
> **白底上放浅灰块 → 灰块比底暗，读作「下沉」。**  
> 相邻区块应*反向交替*：白 → 灰 → 白 → 灰。全程同向会导致层级链条断裂，读者无法判断哪一层更靠前。

- N3 底 · 隔 2 级
- N0 卡片 · 比底更亮 → 浮起
- N3 底 · 隔 2 级
- N0 底 · 基准
- N2 卡片 · 比底更暗 → 下沉
- N0 底 · 基准

上图两行分别为「白卡浮在灰底上」与「灰卡沉在白底上」。两者的层级关系在视觉上同样清晰，但方向相反 —— 不要在同一页里混用两种方向表达同一层级。

### 7.3 五个常见场景的对照做法

| 场景 | 无描边 / 无阴影的做法 | 关键数值 |
| --- | --- | --- |
| 卡片 | 底 N2，卡片 N0；悬停时卡片转 N1 | 差 2 级 · 悬停差 1 级 |
| 导航栏 | 不做毛玻璃、不加下边线。栏底用 N0，与内容区之间以 **64px 留白**区隔 | 留白 ≥ --sp8 |
| 弹层 / 对话框 | 用 N0 大圆角块压在 N3 遮色底上。遮色底用**实色**而非半透明 —— 需要遮住内容时，用能完整覆盖的实色 | --r-lg + --z-modal |
| 表头 | 表头行用 N11 深底 + 白色文字；数据行白 / N1 交替。利用深色表头本身形成分界，无需分割线 | 行间隔 1 级 |
| 分组 / 分隔 | 用「间距差」表达：组内元素间距 --sp2，组间 --sp6 | 间距差 4 档 |
| 选中态 | 底色整体切换 + 文字色同步切换，**不使用边框变化** | 对比度 ≥ 4.5:1 |

> **最常见的三个破坏动作**
> **一、**当卡片与页面底色已有明度差时仍加描边 —— 这会重复表达边界，使版式变碎；只有相邻面无可用明度差且仍需标界时，才使用 `--line-subtle`。**二、**为了「跟背景分开」给导航栏加毛玻璃 —— 模糊是一种深度伪造，属于透明度家族的补偿手法，与扁平化冲突。**三、**用 `box-shadow` 做卡片浮起 —— 阴影的本质是模拟光照下的深度，本系统不承认这个隐喻，改用色阶明度差。

正确 · 底色分层
卡片标题
卡片以底色浮起，边界由明度差自然形成。
错误 · 描边分层
卡片标题
描边与底色同时表达层级，信息重复且版面变碎。
右侧反例在已有明度差时仍加描边；本系统的细线例外只用于相邻面无可用明度差的边界。

## 08 组件规范

本节给出核心组件的规范。每个组件只使用令牌表中的值；常规状态和键盘焦点都通过底色与文字色表达。边界细线仅按 §10 的同明度例外使用，不叠加阴影或透明度。

### 按钮

- 主要行动 / 次要行动 / 安静按钮 / 已禁用
- 小号 / 默认 / 大号

| 层级 | 底色 | 文字 | 悬停 | 使用约束 |
| --- | --- | --- | --- | --- |
| 主要行动 | --c-accent | --n0 | --n10 | 每屏最多 1 个 |
| 次要行动 | --c-struct | --n0 | --n11 | 同组内不超过 1 个 |
| 安静按钮 | --n0 | --n10 | --n3 | 用于「取消 / 返回」等非决策操作 |
| 禁用 | --n4 | --n7 | 不变 | 用底色表达禁用，不降低透明度 |

> **为什么禁用态不用透明度**
> 把按钮设成 `opacity: .4` 是最省事的做法，但它带来两个问题：一是**文字对比度同样被削弱**，禁用态文字往往掉到 2:1 以下，视力不佳的用户完全看不见；二是**引入了透明度这个维度**，与系统禁则冲突。正确做法是用 `--n4` 底 + `--n7` 文字，对比度约 2.6:1，正好处在「可辨认但明显不活跃」的区间。

### 输入框

- 默认态 · 占位文字 N7 / 聚焦态 · `:focus-visible` 焦点指示（见 §09.2） / 错误态 · 文字转强调色
- **默认态**：N0 底，占位文字 N7。不要给输入框加描边 —— 它的边界由与页面底色的明度差确立；若页面本身是白色，则输入框改用 N2 底。
- **聚焦态**：使用 `:focus-visible` 切换为焦点色块（见 §09.2），不加描边。
- **错误态**：**不用红色底**，将文字与下方提示改为强调色玫红，并保持 `--w-med` 字重。错误信息必须同时有文字说明，不能只靠颜色。

### 标签与徽章

- 结构标签 / 中性标签 / 强调标签 / 深色标签
- 进行中 / 待处理 / 已归档
标签统一使用 `--r-pill` 圆角。**状态区分优先用「圆点 + 文字」而非「整块变色」**因为色盲用户无法分辨纯色块的差异，而圆点位置与文字是无障碍的。

### 卡片

- 分类标签 / 卡片标题写在两行以内的位置 / 正文使用 N8，行高 1.45。卡片底色 N0，悬停转 N1 —— 变化只有一级，足以提示可交互，但不造成闪烁感。 / 元信息 · N7 / 变体 / 灰底卡片（下沉式） / 当页面底色为白时，卡片改用 N2 底。用于信息密集的列表页，视觉重量比白卡更轻。 / 元信息 · N7
两处卡片的元信息与正文对比度：正文 N8 = 5.77:1（达标），元信息 N7 = 3.5:1（**仅限 ≥18.66px 粗体**，若尺寸更小须换用 N8）。

### 分页

- ‹ / 1 / 2 / 3 / ›
选中项用强调色实心（`--r-md` 圆角，非胶囊），其余用 N0 底、悬停转 N3。**不使用边框表达选中** —— 选中是一个状态，用填充表达比用轮廓表达更明确。

> **组件层的一条通则**
> 悬停、选中、禁用、错误和键盘焦点都通过底色与文字色表达；焦点态使用 §09.2 的单一色块方案，不叠加描边、阴影或透明度。

## 09 可访问性

可访问性不是附加项，它是本系统中**唯一可以推翻其他规则**的约束。当视觉规则与可用性冲突时，可用性优先。

### 9.1 对比度门槛

| WCAG 等级 | 门槛 | 本系统中可用该级别的颜色 |
| --- | --- | --- |
| AAA · 正文 | ≥ 7:1 | 藏青（9.61:1）、N9（9.16:1）、N10（12.99:1）、N11（18.28:1）、色阶 600–900 档 |
| AA · 正文 | ≥ 4.5:1 | N8（5.77:1）、藏青色阶 500–900 档、玫红 800 档、青蓝 800 档 |
| AA · 大字 | ≥ 3:1 | 玫红（3.88:1）、N7（3.5:1）、各色阶 400–500 档 |
| 不达标 | < 3:1 | 青蓝（2.75:1）、浅粉（2.17:1）、N0–N6 —— **禁止承载文字** |

「大字」定义为 ≥ 24px 常规字重，或 ≥ 18.66px 粗体。低于此尺寸一律按正文门槛 4.5:1 判定。

> **两个高频违规**
> **一、**把 N7（3.5:1）用作 13px 的辅助文字。这个对比度只够大字，13px 下不达标。辅助文字请用 N8。  
> **二、**白字压玫红做按钮文案。3.88:1 处于大字线，若按钮文字小于 18.66px 粗体则违规。做法是把按钮文字改为 `--w-bold` 且尺寸 ≥ 18.66px，或把按钮底色换成藏青。

### 9.2 键盘焦点：用色块保持可见

> 键盘操作必须始终有可见焦点提示。WCAG 2.1 [成功准则 2.4.7](https://www.w3.org/WAI/WCAG21/Understanding/focus-visible.html)要求键盘可操作界面存在焦点可见的操作模式；焦点状态色块还应符合[1.4.11 非文本对比度](https://www.w3.org/WAI/WCAG21/understanding/non-text-contrast.html)，与相邻颜色至少达到 3:1。

- 仅对 `:focus-visible` 切换焦点色块，并同步调整文字色；不使用 `outline`、边框、阴影或透明度。
- 相邻底色为 N0–N6 时，使用 `--c-struct` 底色与 `--n0` 文字；相邻底色为 N7–N11 时，使用 `--n0` 底色与 `--n11` 文字。两组焦点色块均与相邻底色达到至少 3:1，文字对比度也达标。
- 相邻面使用品牌色时，从现有令牌中选取与相邻颜色对比度达到 3:1 的焦点底色，并选择满足文本对比度要求的文字色。
- **不得移除键盘焦点指示**；焦点仅通过色块和文字色表达，不叠加描边。

### 9.3 色盲与色彩依赖

本系统的核心色彩分工对色盲相对友好，原因在于**角色由明度而非色相区分**：藏青（L=33.7%）与玫红（L=55.1%）的明度差达 21.4 个百分点，即使在完全无色觉的情况下，两者仍可被区分。

但仍然必须遵守三条：

- **不用颜色单独承载信息。**错误态不能只靠变红，必须同时有文字说明或图标。
- **状态区分优先使用形状与位置。**圆点、序号、图标位置在无色觉时仍然有效。
- **若未来扩展辅助色（见 §11.4），必须通过色盲安全校验。**新增色相应分别模拟红色盲、绿色盲、蓝色盲三种情况下的可区分性。

### 9.4 其他硬性要求

| 项目 | 要求 |
| --- | --- |
| 点击目标 | 可交互元素最小 44×44px，间距 ≥ 8px |
| 正文宽度 | 单行 40–75 字符（中文约 25–40 字），超出须分栏 |
| 正文字号 | 不小于 15px；移动端不小于 15px |
| 动效 | 提供 `prefers-reduced-motion` 降级；不出现 3 次/秒以上的闪烁 |
| 语义结构 | 标题层级连续；表格使用真实 `table` 元素并标注表头 |
| 语言标注 | 页面声明 `lang`；中英混排时英文片段单独标注 |

## 10 禁用清单

以下十条为界面硬性约束。相邻面没有可用明度差且仍需边界时，描边仅按本节规定使用；其余禁则不得违反。建议第 §12 的检查清单与此处逐条对应。

- **禁止任何形式的渐变**；界面及配套视觉不得出现线性、径向、锥形或透明度渐变。层级由色阶明度差和纯色色块承担（§05）。
- **描边仅作同明度边界补充**；只有相邻两面没有可用明度差、且仍需要标明边界时，允许使用 `--line-subtle`。描边不用于层级、选中或焦点；键盘焦点使用 §09.2 的色块状态。
- **禁止阴影**；不得使用 `box-shadow`、`text-shadow`、`filter: drop-shadow`。阴影是深度伪造，与扁平化冲突。
- **禁止透明度**；不得使用 `rgba()`、`hsla()`、`opacity < 1`、`backdrop-filter`。需要弱化时改用色阶上的更浅档位。
- **禁止自由圆角值**；圆角只能取五档令牌，其余值一律不允许。圆角为 0 时不声明属性。
- **禁止自由尺寸值**；间距、字号只能取令牌。出现 `13px` 字号、`10px` 圆角、`18px` 间距即视为违规。
- **禁止引入第五个色相**；品牌外色相一律不得进入界面。需要语义色（成功 / 警告 / 危险）时，从现有色阶取档（§11.4）。
- **禁止藏青与玫红互为文字与底色**；两者互压对比度为 2.48:1 与 2.48:1，均不达标。
- **禁止用颜色单独承载信息**；错误、状态、分类必须同时有文字、图标或位置差异。
- **禁止文字压在渐变上**；渐变上的对比度是区间而非确定值，可访问性无法保证。

> **自查方式**
> 十条中有六条可以自动检测。建议在提交前执行一次字符串扫描：搜索 `gradient`、`box-shadow`、`rgba(`、`opacity` 和 `border`；仅当边界满足同明度条件时，才允许使用 `--line-subtle`。同时检查是否存在令牌表外的 `px` 值。这项检查应当成为流程的一部分，而不是依赖人工复查 —— **能被自动检测的规范，才有资格被称为规范**。

## 11 跨项目复用

本节回答最初那个问题：这套配色逻辑能不能套用到其他项目上。**结论是能，但必须补上三个约束** —— 否则会退化成一堆看起来还行、放在一起却散架的颜色。

### 11.1 五步配方

| 步骤 | 动作 | 硬性约束 | 校验方法 |
| --- | --- | --- | --- |
| 1 | 定 1–2 个主题色 | 明度压到 **30%–40%**，饱和度过 **80%** | 算压白底对比度，需 ≥ 7:1 |
| 2 | 为每个主题色派生浅色辅助色 | 同色相提亮 或 邻近色偏移 ≤ 30° | 必须能回答「它从哪个色派生」 |
| 3 | 把四个色的饱和度收进窄区间 | 极差 ≤ **10 个百分点** | 列表比对饱和度数值 |
| 4 | 把明度错开到不同档位 | 四个色落在 **四个不重叠**的明度带 | 映射到 10 级阶梯，看档位是否重复 |
| 5 | 补一条中性色阶 | **10–12 级**，带 3–5% 的品牌色相倾向 | 检查最浅端相邻两级是否可辨（≥1.05:1） |

### 11.2 关键约束：辅助色必须有出处

> **本系统最重要的一条复用规则**
> **辅助色不能独立选择，它必须从某个主题色派生而来。**  
>   
> 本例中：青蓝之于藏青是*邻近色偏移*（+-29.4°，同一族）；浅粉之于玫红是*同族提亮*（色相差仅 10.0°，明度 +21.4 个百分点）。两者都有明确的出处。  
>   
> 反之，若插入一个无关的浅黄或浅绿，**即使它的对比度完全合格、明度也错开了，视觉上仍会立刻散掉** —— 因为它没有出处。这是「配色是否成套」的分水岭。

### 11.3 三种常见错法

错误一 · 四色同明度
四个色的明度都落在 45%–60% 区间。结果：四个色争夺同一角色，只能靠加大面积来区分，页面必然花。修复方式是按 §11.1 步骤 4 把明度错开。

错误二 · 饱和度不齐
三个色在 85% 以上，一个色在 45% 附近。结果：那个低饱和色会被读成「没调好」。若要整体柔和，必须四个一起降，保持极差 ≤ 10 个百分点。

错误三 · 辅助色另起炉灶
主题色是蓝，辅助色却选了一个与蓝毫无关系的浅绿或浅黄。结果：两套语言互不相认。修复方式是回到 §11.2，让辅助色从主题色派生。

错误四 · 跳过对比度直接分配角色
凭「这个色好看」决定它做标题。结果：上线后才发现该色压白底只有 2.5:1，无法承载文字，只能临时调整字号或加粗，破坏版面。修复方式是先算对比度，再决定角色。

### 11.4 语义色（成功 / 警告 / 危险）怎么办

这是一个绕不开的问题：本系统禁止引入第五个色相，但产品通常需要红、黄、绿三态。

**处理原则：语义色从现有色阶取档，而不新增色相。**

| 语义 | 本系统处理 | 依据 |
| --- | --- | --- |
| 危险 / 错误 | 使用强调色玫红及其色阶 700–900 档 | 玫红在这个系统里本身承担「需要注意」的角色，语义一致 |
| 成功 / 完成 | 使用结构色藏青及其色阶 500–700 档 | 以品牌主色表达正向状态，避免引入绿色 |
| 警告 / 待处理 | 使用装饰色青蓝及其色阶 600–800 档 | 青蓝处于色环的「冷偏中」位置，可作为中性提醒 |
| 中性 / 归档 | 使用中性色 N7–N8 | — |

> **这条规则的适用边界**
> 该做法适合**品牌调性统一、信息密度中等**的产品（内容站、SaaS、品牌页）。**不适用于金融、医疗、工业控制等强语义行业** —— 那些场景下「红必须代表涨或危险、绿必须代表跌或安全」是不可让步的行业惯例与安全要求，此时应当保留标准语义色相，并把品牌色退到装饰层。*规范的价值在于被遵守，而规范的前提是承认例外。*

### 11.5 换色时的改动清单

若要把这套系统迁移到另一个品牌色，需要改动的只有以下几处，其余全部自动继承：

1. 四个品牌色令牌值（`--c-struct` / `--c-accent` / `--c-deco-1` / `--c-deco-2`）
2. 中性色阶的色相倾角（把 H=222 换成新主色的色相）
3. 用 §03 的算法重跑四条色阶
4. 复核对比度表，确认步骤 1 的四个色仍满足原有角色分配

圆角、间距、字号、字重、动效、层级、组件规范**全部不需要改动** —— 这正是把「视觉手段」与「系统规范」分开的价值：换肤不动骨架。

## 12 交付检查清单

共 31 项，覆盖色彩、令牌、层级、扁平化、可访问性、交付六个维度。建议逐条勾选，未通过项不得交付。

### 色彩

- 页面中只出现 4 个品牌色相 + 1 条中性色阶，无第五色相
- 四个品牌色的饱和度极差 ≤ 10 个百分点
- 四个品牌色的明度落在互不重叠的档位
- 所有文字对比度达标：正文 ≥ 4.5:1，大字 ≥ 3:1
- 未出现「藏青文字压玫红底」或反向的配对
- 颜色未单独承载信息（有文字 / 图标 / 位置辅助）

### 令牌

- 样式文件中无字面色值，全部引用令牌
- 圆角只取五档，无自由值
- 间距、字号只取令牌表内的值
- 嵌套元素圆角外大内小
- 增删一个主题色时，只改令牌定义即可全局生效

### 层级

- 无任何 box-shadow / text-shadow / drop-shadow
- 描边只在相邻面无可用明度差且仍需标界时使用 `--line-subtle`；不用于层级、选中或焦点
- 相邻区块明度差 ≥ 2 级（表层）/ ≥ 3 级（区块）
- 页面区块底色方向反向交替，未全程同向
- 弹层使用实色遮色底，未使用半透明

### 扁平化

- 无 rgba() / hsla()
- 无 opacity < 1 的装饰性用法
- 无 backdrop-filter
- 禁用态用色阶表达，未使用透明度
- 无任何形式的界面层渐变

### 可访问性

- 键盘可完整遍历页面，焦点始终可见
- 键盘焦点使用 §09.2 的色块指示，未被隐藏
- 可点击目标 ≥ 44×44px
- 正文宽度在 25–40 中文字符之间
- 提供了 prefers-reduced-motion 降级

### 交付

- 已附完整令牌表与色阶明细
- 色阶由公式生成，可复现，非手工微调
- 已附对比度矩阵与达标标注
- 已说明语义色的处理方式与适用边界
- 新色接入流程已在文档中写明

> **最后一条**
> 这份文档的终点不是「这套视觉好不好看」，而是「**这套规则能不能被下一个执行者直接使用**」。  
>   
> 因此交付时请附上令牌表、色阶明细与对比度矩阵 —— 让接受方不必再问任何一个「这里该用什么值」的问题。*可复用的规则，比漂亮的页面更值得被交付。*
