Files
toor 01d9e301fc
Build / build (push) Canceled after 0s
Playwright / browser (push) Canceled after 0s
initialize Electron desktop app and remove unused files
2026-10-25 01:09:01 +08:00

12 KiB
Raw Permalink Blame History

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:

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. 字体栈

// 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 一律视为待修。