Files
orisys-app/apps/studio/docs/ui-palette.md
T
2026-09-12 13:51:05 +08:00

162 lines
7.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Orisys Customer 配色规范
本文件记录客户端的品牌配色体系、它与 UI 设计稿的关系,以及每一处有意偏离设计稿
的理由。所有色值都存放在主题令牌文件里,控件代码中**不允许出现十六进制颜色**:
```
orisys-app/shared/src/orisys_app_shared/theme/colors_dark.json
orisys-app/shared/src/orisys_app_shared/theme/colors_light.json
```
规则由 `apps/customer/tools/ui_check.py` 的 `audit_palette()` 机械校验,pytest 套件
(`tests/test_ui_smoke.py::test_palette_rules_hold`)复用它,因此只有一个真值来源。
---
## 1. 设计稿色号 → 令牌映射
| 设计稿 | 角色 | 落地令牌 |
|---|---|---|
| `#003893` | 品牌主色 / 底图色 | `accent`、`plot_fn`(浅色);`arrow_canvas` 使用了更深的 logo 藏青 |
| `#4D62BE` | 交互蓝 | `accent_hover`(浅色)、`accent`(深色)、`focus_ring`(浅色) |
| `#12315D` | logo 实际藏青(见 §3.1) | `brand_bar_bg`、`arrow_canvas`(浅色) |
| `#FA02F3` | 洋红 | `flow_ramp` 第 3 档(原值保留) |
| `#FE5853` | 珊瑚 | `flow_ramp` 第 4 档(提亮为 `#FF8A6B`,见 §3.2);`danger` 家族取自同一色相 |
| `#D8FF00` | 柠檬绿 | `flow_ramp` 第 5 档(原值保留)、`plot_fy`(深色) |
| `#D5D5D5` | 应用画布 | **未采用**,改为 `#E1E6EF`(见 §3.3) |
---
## 2. 实测对比度(WCAG)
对比度用标准相对亮度公式实算(`tools/ui_check.py` 中的 `contrast_ratio`)。
正文门槛 4.5:1,图形/控件/状态指示门槛 3.0:1。
### 2.1 设计稿本身的实测结果
| 组合 | 比值 | 判定 |
|---|---|---|
| 白字 on `#003893` | 10.57 | AAA ✅ |
| 白字 on `#4D62BE` | 5.52 | AA ✅ |
| `#4D62BE` on `#D5D5D5` | 3.76 | 图形达标,12–13px 文字**不达标** ⚠️ |
| `#D5D5D5` vs 白卡 | 1.47 | 卡片层次偏弱 ⚠️ |
| `#D8FF00` on `#D5D5D5` | 1.27 | 不可用 ❌ |
| `#D8FF00` on `#003893` | 9.17 | 极佳 ✅ |
| `#FA02F3` on `#003893` | 3.20 | 达标 ✅ |
| `#FE5853` on `#003893` | 3.39 | 达标 ✅ |
| **`#FA02F3` vs `#FE5853`** | **1.06** | **色带中段的亮度平台 ❌** |
| 白字 on `#FE5853` | 3.12 | 珊瑚色不能承载白字 ❌ |
设计稿的色相选择是可靠的;三个霓虹色的**相对亮度**为 0.268 → 0.287 → 0.861,
色相沿 302° → 2° → 69° 单调前进 127°,作为"位移幅值 → 颜色"的顺序色带是正确用法。
问题在于中段:洋红与珊瑚亮度几乎相同(1.06:1),只靠 60° 色相差区分,在灰度
打印与色觉障碍下会糊成一片。
### 2.2 落地后
浅色主题(节选):白字 on `accent` 10.57,白字 on `accent_hover` 5.52,
`plot_fn/fx/fy` 对 `plot_bg` 分别 10.11 / 6.00 / 4.89,
`brand_bar_fg` on `brand_bar_bg` 12.94,`input_border` 对四种底均 ≥3.08。
深色主题(节选):白字 on `accent` 5.52,`accent` 对 `panel_bg` 3.09(贴线但仍达标),
`plot_fn/fx/fy` 分别 7.61 / 6.16 / 15.73,`focus_ring` 对 `input_bg` 6.51。
三通道可分辨性(色相差 / 相对亮度比):
| 主题 | FN vs FX | FN vs FY | FX vs FY |
|---|---|---|---|
| 浅色 | 97.0° / 1.68 | 135.5° / 2.07 | 127.5° / 1.23 |
| 深色 | 96.7° / 1.24 | 154.7° / 2.07 | 108.7° / 2.55 |
规则是"色相差 ≥90° **或** 相对亮度比 ≥1.2",两主题均满足。颜色在任何情况下都不是
唯一编码:每个曲线有文字标签,每张数值卡有同色通道徽标。
---
## 3. 对设计稿的四处有意偏离
### 3.1 品牌藏青用 logo 实际取色 `#12315D`
`logo.png` 与 `logo_topbar.png` 采样后字形的实际颜色都是 `#12315D`
(H215 S80.6% V36.5%),而设计稿写的是 `#003893`(H217 但 S100% V57.6%)。
两者同色相家族,但后者明显更亮更艳。顶栏品牌条与浅色主题的箭头画布采用 logo
实际色,以保证"标识色"与"界面色"一致。
### 3.2 色带第 4 档由 `#FE5853` 提亮为 `#FF8A6B`
见 §2.1:保留设计稿珊瑚色会在色带中段留下 1.06:1 的亮度平台。提亮后色带相对亮度
为 **0.031 → 0.128 → 0.268 → 0.405 → 0.861**,严格单调。
第 3 档洋红与第 5 档柠檬绿**保留设计稿原值不动**。
### 3.3 画布 `#D5D5D5` → `#E1E6EF`
`#D5D5D5` 是无彩色(H=0 S=0% L=84%)。现代浅色画布普遍在 96–98% 亮度,目的是让
白卡"浮起来";而在 `#D5D5D5` 上白卡只有 1.47:1,且 Qt 的 QSS 不支持 `box-shadow`,
卡片只能靠 1px 描边分离,观感会发平、发旧。改为品牌微蓝灰后:
- 保留设计稿"灰底 + 白卡"的角色分工;
- `#4D62BE` 在画布上的对比度从 3.76 升到 4.41。
### 3.4 补齐语义色与深色主题
设计稿没有 success/warning/error/info,也只有浅色版;本应用默认主题是深色。
同时原深色主题的语义色是一整套 Google Material 色
(`#8ab4f8` / `#34a853` / `#fbbc04` / `#ea4335` / `#1a73e8`),对一个测量仪器
产品属于即时可识别的品牌冲突,已全部替换为品牌衍生色。
`danger` 在深色主题被拆成两个令牌:`danger`(亮,用于卡片上的红字与状态指示)
与 `danger_fill`(暗,用于承载白字的危险按钮)—— 一个色值无法同时满足两个方向。
---
## 4. 品牌化箭头色带
设计稿的霓虹三色是**一张 colormap**(按位移幅值着色),不是三个分类色。因此它落在
箭头可视化上,而不是 UI 控件上:
```
flow_ramp = 画布色, #6E4AD0, #FA02F3, #FF8A6B, #D8FF00
```
- 第 1 档等于画布色,这样**零位移区域自然融入背景**;
- 由 `orisys_app_shared.acquisition.arrows.flow_colormap(theme)` 生成 256 档
BGR 查找表,经 `draw_arrows(colormap=...)` 注入 SDK(**SDK 无需改动**);
- LUT 缓存的键是 ramp 字符串本身,因此切换主题后立刻生效;
- 非法 ramp 永不抛异常,回退到内置默认色带。
箭头画布在两个主题里都是品牌深蓝(浅 `#12315D` / 深 `#0B1830`),这也是霓虹色带
唯一可用的背景 —— 色带第 3 档起对画布均 ≥3.0:1。**绘图区(`plot_bg`)保持浅色**,
所以浅色主题下霓虹只出现在箭头画布上,力曲线使用浅色安全的品牌三色。
---
## 5. 有记录在案的豁免
以下项目**不**被 `audit_palette()` 检查,理由是它们属于装饰而非状态指示:
| 项 | 现状 | 理由 |
|---|---|---|
| 装饰性 1px 容器描边 | `card_border` / `panel_border` / `plot_grid` / `separator`(1.16–1.45:1) | WCAG 1.4.11 针对交互控件的边界与状态指示;容器轮廓属于装饰 |
| 禁用态文字 | 深色 `text_muted` on `button_bg` = 4.07 | WCAG 1.4.3 明确豁免禁用控件 |
输入框的静止描边**不在豁免之列** —— 它被强制要求对 `input_bg`/`panel_bg`/`card_bg`/`toolbar_bg`
四种底均 ≥3.0:1(实测 3.08–4.09),这与 Material 3 描边式输入框的做法一致。焦点态同样由
`focus_ring` 保证 ≥3.0:1。
深色主题的 `accent` 对 `panel_bg` 为 3.09:1(设计稿原值 `#4D62BE`),贴线但达标;
若后续视觉上偏软,可单点提升为 `#5468C6`(白字仍为 5.03)。
---
## 6. 复核方式
```powershell
$py = "D:\orisys_ws\orisys-app\.venv-build\Scripts\python.exe"
$env:PYTHONPATH = "D:\orisys_ws\orisys-app\shared\src;D:\orisys_ws\orisys-app\apps\customer\src"
cd D:\orisys_ws\orisys-app\apps\customer
& $py tools/ui_check.py # 含 palette 规则段落
& $py tools/ui_snapshot.py --theme dark --lang zh_CN --demo --out outputs/_snap_dark.png
& $py tools/ui_snapshot.py --theme light --lang en_US --sensor finger --panels cal,3d --size 1600x900 --demo --out outputs/_snap_light.png
```