268 lines
12 KiB
Markdown
268 lines
12 KiB
Markdown
# UI 基线(CYBER 暗色单主题)
|
||
|
||
本文件是 hermes-ui 的**视觉语言唯一依据**。页面样式与本文冲突时,以本文为准;
|
||
本文没覆盖的场景,先在 `docs/arco-mapping.md` 补映射、再回本文补约定,然后才动代码。
|
||
|
||
- 样板页:`views/LoginView.vue`(装饰位面 + 表单)、`components/layout/AppSidebar.vue`(导航 + 弹窗 + tag)
|
||
- 令牌源:`packages/client/src/styles/variables.scss`(CSS 变量 + SCSS 委托变量)
|
||
- Arco 实际外观由 `styles/global.scss` 的 Arco token bridge 决定;`styles/arco-theme.ts` 是意图说明与测试锚点
|
||
- 组件映射:`docs/arco-mapping.md`
|
||
|
||
> **历史**:本文件曾描述「黑白水墨(Pure Ink)」三主题(ink light / ink dark / comic)。
|
||
> 亮度/风格切换器已移除,暗色是唯一主题,该描述不再适用。
|
||
> 当前主题推进状态见 `docs/cyber-theme-plan.md`。
|
||
|
||
---
|
||
|
||
## 1. 三色语义系统(最高优先级)
|
||
|
||
> **每种颜色只承担一种含义,不得混用。**
|
||
|
||
| 颜色 | 令牌 | 含义 | 典型用途 |
|
||
|---|---|---|---|
|
||
| 霓虹青 | `--accent-primary` | **系统本体** | 品牌、主按钮、当前选中、链接 |
|
||
| 琥珀橙 | `--warning` | **需要你介入** | 审批、等待确认、上下文将满、中断态 |
|
||
| 荧光绿 | `--success` | **机器在动** | 工具成功、流式输出、连接健康 |
|
||
| 红 | `--error` | **出错** | 仅表示出错,不参与上面三色分工 |
|
||
|
||
- 失败时**不要**靠「加深强调色」表达,必须换到 `--error` —— 否则四个语义挤在同一色相里,紧急程度就读不出来了。
|
||
- `--accent-info` 是第四种蓝,只在需要与青/橙/绿都区分开时用(如链接性提示)。
|
||
- 同一语义在全项目**必须用同一个令牌**。看到两个文件里「橙」是不同色值,就是 bug。
|
||
|
||
### 状态色的完整取值
|
||
|
||
| 令牌 | OKLCH | RGB 三元组 | 说明 |
|
||
|---|---|---|---|
|
||
| `--accent-primary` | `oklch(0.805 0.148 188)` | `0, 221, 209` | 霓虹青 |
|
||
| `--accent-hover` | `oklch(0.870 0.150 188)` | `16, 243, 230` | 悬停态 |
|
||
| `--accent-muted` | `oklch(0.520 0.060 188)` | — | 弱化强调 |
|
||
| `--success` | `oklch(0.860 0.190 128)` | `173, 231, 78` | 荧光绿 |
|
||
| `--warning` | `oklch(0.780 0.155 68)` | `247, 162, 50` | 琥珀橙 |
|
||
| `--error` | `oklch(0.665 0.185 22)` | `240, 90, 94` | 红 |
|
||
| `--accent-info` | `oklch(0.700 0.110 245)` | `95, 165, 222` | 蓝 |
|
||
| `--kanban-review` | `oklch(0.722 0.177 305.5)` | `192, 132, 252` | 看板 `review` 列分类色(**分类色,非语义色**) |
|
||
|
||
> `--kanban-review` 是唯一的分类色令牌:看板 9 个列状态装不进三色语义系统,
|
||
> 按「流程阶段」维度分色。它仍然走令牌体系,所以 `rgba(var(--kanban-review-rgb), α)`
|
||
> 能拼出弱底色。
|
||
|
||
**半透明用 RGB 三元组拼 alpha**,因为 OKLCH 无法直接拆 alpha:
|
||
|
||
```scss
|
||
color: rgba(var(--accent-primary-rgb), 0.55);
|
||
box-shadow: 0 0 12px rgba(var(--success-rgb), 0.22);
|
||
```
|
||
|
||
每个需要拼 alpha 的令牌都有配套的 `--*-rgb`。要新增半透明语义色,**必须同时加 RGB 三元组**。
|
||
|
||
### 语义底与语义线
|
||
|
||
| 令牌 | 值 | 用途 |
|
||
|---|---|---|
|
||
| `--accent-soft` | `oklch(0.805 0.148 188 / 0.13)` | 强调色弱底 |
|
||
| `--success-soft` / `--success-line` | `… / 0.12` / `… / 0.40` | 绿色弱底 / 绿边框 |
|
||
| `--warning-soft` / `--warning-line` | `… / 0.12` / `… / 0.42` | 橙色弱底 / 橙边框 |
|
||
| `--error-soft` / `--error-line` | `… / 0.11` / `… / 0.42` | 红色弱底 / 红边框 |
|
||
|
||
---
|
||
|
||
## 2. 背景与描边
|
||
|
||
背景由深到浅四层,**越靠上层越亮**(向上浮):
|
||
|
||
| 角色 | 令牌 | OKLCH | 用途 |
|
||
|---|---|---|---|
|
||
| 页面底 | `--bg-primary` | `oklch(0.155 0.012 250)` | 页面底色 |
|
||
| 次级底 | `--bg-secondary` | `oklch(0.130 0.012 250)` | 卡片 / 面板(比页面更沉) |
|
||
| 侧栏 | `--bg-sidebar` | `oklch(0.118 0.013 251)` | 比卡片更沉 |
|
||
| 容器 | `--bg-card` | `oklch(0.185 0.014 248)` | 容器 / 输入区(比页面更亮) |
|
||
| 容器悬停 | `--bg-card-hover` | `oklch(0.225 0.016 246)` | |
|
||
| 输入底 | `--bg-input` | `oklch(0.105 0.012 252)` | 比卡片更沉,形成凹陷感 |
|
||
| 代码底 | `--code-bg` | `oklch(0.115 0.014 250)` | |
|
||
|
||
描边发丝线分两档:`--border-color`(`oklch(0.305 0.018 242)`)、`--border-light`(`oklch(0.255 0.016 244)`)。
|
||
|
||
**硬编码 hex 是 bug**,除非是图表色板(见 §7)。
|
||
|
||
---
|
||
|
||
## 3. 文字
|
||
|
||
| 角色 | 令牌 | OKLCH | 用途 |
|
||
|---|---|---|---|
|
||
| 正文 | `--text-primary` | `oklch(0.945 0.006 200)` | |
|
||
| 次要 | `--text-secondary` | `oklch(0.860 0.008 210)` | |
|
||
| 弱化 | `--text-muted` | `oklch(0.705 0.014 230)` | |
|
||
| 极弱 | `--text-faint` | `oklch(0.520 0.014 236)` | 禁用态 / 极次要信息 |
|
||
| 强调色上文字 | `--text-on-accent` | `oklch(0.160 0.030 200)` | 深色,保证对比 |
|
||
| 浮层上文字 | `--text-on-overlay` | `oklch(0.945 0.006 200)` | |
|
||
|
||
反色场景**一律用 `--text-on-accent`**,不要硬编码白/黑。
|
||
|
||
---
|
||
|
||
## 4. 字体栈
|
||
|
||
```scss
|
||
// UI(系统中英混排)
|
||
$font-ui: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Hiragino Sans GB',
|
||
'Microsoft YaHei', 'Segoe UI', Roboto, sans-serif;
|
||
|
||
// 代码 / 命令 / 版本号
|
||
$font-code: ui-monospace, 'JetBrains Mono', 'SF Mono', Menlo, 'Cascadia Code', monospace;
|
||
|
||
// 终端(xterm 在 JS 里读这个,所以必须是 CSS 自定义属性)
|
||
--font-mono: ui-monospace, 'JetBrains Mono', 'JetBrainsMono Nerd Font',
|
||
'Nerd Font', 'SF Mono', Menlo, 'Cascadia Code', 'MesloLGS NF',
|
||
'Hack Nerd Font', monospace;
|
||
```
|
||
|
||
- **Nerd Font 回退段不能删**:默认 shell 提示符会输出私有区字形(分支、箭头、分隔符,如 `U+E0A0`–`U+E0D4`),缺了这些字形会整片显示为豆腐块。
|
||
- `$font-display` 复用 `$font-code` —— 等宽是 CYBER 的核心排版特征。
|
||
- 等宽字体只用于:代码块、命令、版本号、命令行提示、标识与数据。
|
||
|
||
---
|
||
|
||
## 5. 圆角 / 间距 / 字号阶梯
|
||
|
||
**圆角**(`$radius-*`)—— 发丝线 + 小圆角,**硬边而非圆润**:
|
||
|
||
| token | 值 | 用途 |
|
||
|---|---|---|
|
||
| `$radius-sm` | 6px | 按钮、输入框、小卡片、tag(与 Arco `borderRadius: 6` 对齐) |
|
||
| `$radius-md` / `$radius-lg` | 8px | 面板、弹窗、大卡片 |
|
||
|
||
**间距**:4px 基数,常用档 `4 / 8 / 12 / 16 / 24 / 32`。组件内边距多用 12/16,区块间 24/32。
|
||
|
||
**布局尺寸**:
|
||
|
||
| token | 值 |
|
||
|---|---|
|
||
| `$sidebar-width` | 240px |
|
||
| `$sidebar-collapsed-width` | 64px |
|
||
| `$header-height` | 60px |
|
||
| `$breakpoint-mobile` | 768px |
|
||
|
||
**字号阶梯**:
|
||
|
||
| px | 用途 |
|
||
|---|---|
|
||
| 10 | 分组标签(uppercase + letter-spacing) |
|
||
| 11–12 | 辅助信息、meta、tag |
|
||
| 13 | 次要正文、列表项、错误提示 |
|
||
| 14 | 正文默认(`body` 基准) |
|
||
| 15 | 输入框文字(`$font-code` 场景) |
|
||
| 16 | 小标题 |
|
||
| 26 | 登录页等展示型大标题 |
|
||
|
||
**过渡**:`$transition-fast: 0.15s ease` / `$transition-normal: 0.25s ease`。
|
||
|
||
---
|
||
|
||
## 6. 霓虹效果层
|
||
|
||
`styles/global.scss` 提供的 mixin,是 CYBER 辨识度的来源:
|
||
|
||
| mixin / 动画 | 用途 |
|
||
|---|---|
|
||
| `neon-tube` | 霓虹灯管:主按钮、激活态边框 |
|
||
| `neon-sheen` | 表面扫光 |
|
||
| `neon-pulse` | 呼吸微光 |
|
||
| `@keyframes live-ring` | **「机器在动」的唯一指示形态**(单色绿,不轮播) |
|
||
| `@keyframes led-breathe` | 状态灯呼吸(仅连通时) |
|
||
|
||
### 「机器在动」只长一个样
|
||
|
||
流式输出、语音播放、工具执行中、连接健康 —— 全部用 `live-ring`(荧光绿单色呼吸)。
|
||
|
||
**不要做多色轮播**:同屏内四种语义色同时在闪,等于四种颜色都不再表达含义。
|
||
这条在 P0 修 `rainbow-glow` 时被违反过,回归护栏在
|
||
`tests/e2e/chat-cyber-semantics.spec.ts`。
|
||
|
||
### 状态灯 `.cy-led`
|
||
|
||
7px 圆点 + 发光。连通=绿(呼吸),断开=红(**静止**)。
|
||
|
||
**一个死掉的连接不该看起来还在动** —— 断开态不呼吸。
|
||
|
||
### 发光条用 inset box-shadow
|
||
|
||
左侧/顶部发光条用 `box-shadow: inset 2px 0 0 <color>`,**不要用 `border-left`** ——
|
||
border 会把内容宽度挤动 2px,列表行高对不齐。
|
||
|
||
---
|
||
|
||
## 7. 图表色板(唯一允许硬编码颜色的地方)
|
||
|
||
图表/数据可视化的分类色按数据维度取色,**不走语义三色** —— 它们表达的是
|
||
「这是第几个类别」,不是「状态」。
|
||
|
||
规则:
|
||
- 同一张图内的分类色必须**互相可辨**(色相间隔足够)
|
||
- 图表色板集中定义在图表组件内,不散落
|
||
- 图表**状态**(成功/失败/警告)仍走语义令牌
|
||
- 图表色**不得**与语义色撞色到读者会误读为状态的程度
|
||
|
||
---
|
||
|
||
## 8. 组件使用约定
|
||
|
||
- **消息 / 对话框 / 通知**:只准调 `composables/useMessage|useDialog|useNotification`
|
||
适配层(签名冻结),**不得**在页面里直接 import Arco 的 `Message` / `Modal` / `Notification`。
|
||
- **Modal vs Drawer**:短内容确认、纯信息展示用 `a-modal`
|
||
(信息型弹窗 `:footer="false"`);需要表单编辑、长内容滚动的场景用 `a-drawer`。
|
||
- **按钮**:语义 `type` + `status` 组合(warning 按钮 = `type="primary" status="warning"`);
|
||
占满宽用 `long`;尺寸 `size="mini|small|medium|large"`;提交按钮 `html-type="submit"`,
|
||
加载态用 `:loading`。
|
||
- **输入框**:`a-input` 关闭了 attrs 透传,`autofocus` 无效 —— 需要自动聚焦时
|
||
`ref` + `onMounted` 调 `focus()`;密码框 `type="password"`。
|
||
- **表格空态**:用 `a-empty`,不手写占位文案。
|
||
- **loading**:按钮级用 `a-button :loading`,区域级用 `a-spin :loading`,
|
||
全局任务进度用 `useMessage().loading(...)`(用完 close/destroy)。
|
||
- **表单**:`a-form` + `a-form-item`,校验规则 API 与 naive 不同,逐例适配。
|
||
- **tag**:`color="arcoblue"` 等内建色,`:bordered="false"` 直接支持。
|
||
|
||
### Arco 组件的暗色
|
||
|
||
项目**不挂 ConfigProvider**。Arco 的实际外观由 `styles/global.scss` 里的
|
||
`--color-*` / `--arcoblue-*` / `--green-*` / `--orange-*` 变量覆盖承载。
|
||
|
||
改主色时要同时改两处:`global.scss` 的 token bridge 和 `styles/arco-theme.ts`
|
||
(后者是意图说明 + 测试锚点)。
|
||
|
||
**Arco 的 RGB 三元组变量不能当颜色用**:
|
||
`--arcoblue-6` 的值是 `22,93,255` 而不是 `#165dff`。
|
||
写成 `color: var(--arcoblue-6)` 会被静默丢弃并回落到 Arco 默认色。
|
||
正确写法:`color: rgba(var(--arcoblue-6), 1)`。
|
||
|
||
---
|
||
|
||
## 9. 装饰位面的边界
|
||
|
||
装饰位面(ArkScope vendor 组件等纯视觉层)的判定标准:
|
||
|
||
> **不得承载信息、不得承载交互、不得影响可读性。**
|
||
|
||
| 允许 | 禁止 |
|
||
|---|---|
|
||
| 登录页标题区装饰位面 | 聊天页(消息区 / 输入区 / 侧边栏) |
|
||
| Journey 图谱的背景层 | 任何表单页(Skills / Profiles / Settings / Models) |
|
||
| 首屏 loading / 空状态 | 任何表格页(Usage / Logs / Jobs / Kanban) |
|
||
| | 任何点击交互密集区域 |
|
||
|
||
**`pointer-events: none` 是硬要求**,装饰层绝不能吃掉点击
|
||
(样板:`LoginView.vue` 的 `.login-decor`,外加 `aria-hidden="true"`)。
|
||
|
||
vendor 素材边界:`vendor/arkscore/` 下**零图片/音视频素材**,
|
||
由 `tests/client/arkscope-vendor.test.ts` 机械化卡住;Provenance 见
|
||
`vendor/arkscore/PROVENANCE.md`。
|
||
|
||
---
|
||
|
||
## 10. 四条不可破的规则
|
||
|
||
1. **不引入第三个 UI 库**——只允许 Arco Design Vue(+ 现有图标/工具链)。
|
||
2. **消息气泡内部不用 Arco 组件**(性能红线,见 Phase 006)。
|
||
3. **装饰层一律 `pointer-events: none`**,不承载信息与交互。
|
||
4. **颜色只走令牌**——语义色走三色系统,图表色走 §7 色板,硬编码 hex 一律视为待修。
|