adopt CYBER neon-dark theme tokens

Replace the Pure Ink light/dark/comic theme system with the CYBER
single-theme dark palette from the reviewed prototype: OKLCH surfaces,
one neon-cyan accent, and monospace-first typography.

Arco components were reading colors from arco.css because no
ConfigProvider was mounted, so the theme values in arco-theme.ts never
took effect. Bridge CYBER into Arco through its --color-* variables in
global.scss instead, and align arco-theme.ts to match.

Brightness and style switches are gone: useTheme now pins dark, the
comic font faces and locale keys are removed, and ThemeSwitch.vue is
deleted along with its sidebar slot and display setting.
This commit is contained in:
2026-10-19 13:04:49 +08:00
parent 145d240dc2
commit 282624f801
12 changed files with 197 additions and 384 deletions
+15 -9
View File
@@ -1,14 +1,20 @@
// Arco Design theme tokens for hermes-ui (Phase 005 baseline).
// Dark mode is carried by `body[arco-theme='dark']` CSS overrides, not a second theme object.
// See docs/ui-baseline.md for the frozen visual language.
// Arco Design theme tokens for hermes-ui — CYBER.
//
// 这些值是「参考值」,不是运行时来源:项目没有挂 ConfigProvider,Arco 的实际外观
// 由 styles/global.scss 里的 --color-* 变量覆盖决定(见那里的 Arco token bridge)。
// 保留本文件是为了让读取 token 的人能在一处看到意图,以及给测试一个可断言的锚点。
// 改色时请同时改 global.scss 的 Arco token bridge,两处保持一致。
export const arcoTheme = {
// 延续旧版克制灰阶
colorPrimary: '#2f2f2f',
colorBgLayout: '#fafafa',
colorBgContainer: '#ffffff',
// 霓虹青 oklch(0.805 0.148 188) ≈ rgb(45, 212, 191)
colorPrimary: '#2dd4bf',
// 页面底 / 卡片底,对应 oklch(0.155 0.012 250) 与 oklch(0.130 0.012 250)
colorBgLayout: '#1a1d23',
colorBgContainer: '#14171c',
borderRadius: 6,
fontFamily: 'Inter, system-ui, -apple-system, sans-serif',
fontFamilyMono: '"JetBrains Mono", "Fira Code", monospace',
fontFamily:
'-apple-system, BlinkMacSystemFont, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Segoe UI", Roboto, sans-serif',
fontFamilyMono:
'ui-monospace, "JetBrains Mono", "SF Mono", Menlo, "Cascadia Code", monospace',
}
export type ArcoTheme = typeof arcoTheme
+96 -59
View File
@@ -1,54 +1,6 @@
@use 'variables' as *;
@use 'code-block';
@font-face {
font-family: 'Comic Neue';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('/fonts/ComicNeue-Bold.ttf') format('truetype');
}
@font-face {
font-family: 'ZCOOL KuaiLe';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('/fonts/ZCOOLKuaiLe-Regular.ttf') format('truetype');
}
@font-face {
font-family: 'Zen Maru Gothic';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('/fonts/ZenMaruGothic-Regular.ttf') format('truetype');
}
@font-face {
font-family: 'Zen Maru Gothic';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url('/fonts/ZenMaruGothic-Bold.ttf') format('truetype');
}
@font-face {
font-family: 'Gaegu';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('/fonts/Gaegu-Regular.ttf') format('truetype');
}
@font-face {
font-family: 'Gaegu';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url('/fonts/Gaegu-Bold.ttf') format('truetype');
}
*,
*::before,
*::after {
@@ -75,13 +27,98 @@ textarea {
}
}
// Theme transition (applied programmatically on toggle, not on load)
html.theme-transitioning,
html.theme-transitioning *,
html.theme-transitioning *::before,
html.theme-transitioning *::after {
transition: background-color 0.3s ease, color 0.3s ease, border-color 0.3s ease,
box-shadow 0.3s ease, fill 0.3s ease, stroke 0.3s ease !important;
// ─── Arco Design token bridge ──────────────────────────────────
// arco-theme.ts 不是运行时来源(没有 ConfigProvider),Arco 的实际外观由 arco.css
// 里的 --color-* 变量决定。这里把 CYBER 令牌翻译成 Arco 变量,让 a-select /
// a-input / a-tag / a-table / a-modal 等自有控件与项目配色对齐。
// 变量表见 node_modules/@arco-design/web-vue/dist/arco.css 的 :root 块。
html[arco-theme='dark'],
:root {
--color-primary-light-1: oklch(0.30 0.060 188);
--color-primary-light-2: oklch(0.39 0.075 188);
--color-primary-light-3: oklch(0.50 0.095 188);
--color-primary-light-4: oklch(0.60 0.115 188);
--color-primary-light-5: oklch(0.68 0.130 188);
--color-primary-light-6: oklch(0.805 0.148 188);
--color-primary: oklch(0.805 0.148 188);
--color-primary-dark-1: oklch(0.760 0.144 188);
--color-primary-dark-2: oklch(0.700 0.138 188);
--color-primary-dark-3: oklch(0.640 0.130 188);
--color-primary-dark-4: oklch(0.580 0.120 188);
--color-primary-dark-5: oklch(0.520 0.108 188);
--color-primary-dark-6: oklch(0.460 0.094 188);
--color-success-light-1: oklch(0.28 0.050 165);
--color-success-light-2: oklch(0.42 0.078 165);
--color-success-light-3: oklch(0.58 0.108 165);
--color-success: oklch(0.760 0.140 165);
--color-warning-light-1: oklch(0.30 0.052 85);
--color-warning-light-2: oklch(0.46 0.082 85);
--color-warning-light-3: oklch(0.62 0.112 85);
--color-warning: oklch(0.810 0.145 85);
--color-danger-light-1: oklch(0.28 0.062 22);
--color-danger-light-2: oklch(0.42 0.096 22);
--color-danger-light-3: oklch(0.56 0.138 22);
--color-danger: oklch(0.665 0.185 22);
--color-link-light-1: oklch(0.30 0.060 188);
--color-link-light-2: oklch(0.42 0.084 188);
--color-link-light-3: oklch(0.54 0.110 188);
--color-link-light-4: oklch(0.66 0.136 188);
--color-link-light-5: oklch(0.74 0.148 188);
--color-link-light-6: oklch(0.805 0.148 188);
--color-link: oklch(0.805 0.148 188);
// 容器与文字
--color-text-1: oklch(0.945 0.006 200);
--color-text-2: oklch(0.860 0.008 210);
--color-text-3: oklch(0.705 0.014 230);
--color-text-4: oklch(0.520 0.014 236);
--color-text-disabled: oklch(0.420 0.012 238);
--color-bg-1: oklch(0.155 0.012 250);
--color-bg-2: oklch(0.130 0.012 250);
--color-bg-3: oklch(0.185 0.014 248);
--color-bg-4: oklch(0.225 0.016 246);
--color-bg-5: oklch(0.255 0.018 247);
--color-fill-1: oklch(0.185 0.014 248);
--color-fill-2: oklch(0.225 0.016 246);
--color-fill-3: oklch(0.255 0.018 247);
--color-fill-4: oklch(0.285 0.018 246);
--color-border-1: oklch(0.305 0.018 242);
--color-border-2: oklch(0.255 0.016 244);
--color-border-3: oklch(0.225 0.014 246);
--color-border-4: oklch(0.195 0.014 248);
--color-fill-2-hover: oklch(0.255 0.018 247);
--color-fill-3-hover: oklch(0.285 0.018 246);
--radius-small: 4px;
--radius-medium: 6px;
--radius-large: 8px;
--font-size-body-1: 14px;
--font-size-body-2: 13px;
--font-size-body-3: 12px;
// CYBER 的核心排版特征:标题、页头、数据用等宽
--font-family: #{$font-ui};
--font-family-body: #{$font-ui};
--font-family-code: #{$font-code};
}
// Arco 暗色态:强制走暗色变量(属性挂在 <html> 上,Arco 官方选择器可能匹配 body)
body {
color: $text-primary;
background-color: $bg-primary;
}
// Arco 组件里的滚动条与焦点环对齐 CYBER
.arco-scrollbar-thumb {
background-color: $border-color !important;
}
html, body {
@@ -146,8 +183,8 @@ a {
}
::-webkit-scrollbar {
width: 6px;
height: 6px;
width: 8px;
height: 8px;
background: transparent;
}
@@ -158,10 +195,10 @@ a {
::-webkit-scrollbar-thumb {
background: $border-color;
border-radius: 3px;
border-radius: 4px;
&:hover {
background: $text-muted;
background: rgba(var(--accent-primary-rgb), 0.5);
}
}
+52 -117
View File
@@ -1,132 +1,64 @@
// 黑白水墨 — Pure Ink
// 纯黑白灰,无彩色
// 支持 light / dark / comic 三主题
// CYBER — 霓虹暗色单主题
// 设计语言见 prototype_reference/hermes-ui-cyber-api.html 与 hermes-ui-cyber-login.html。
// 暗色为唯一主题:亮度/风格切换器已移除,因此这里只有一组令牌,没有 .dark / .comic 变体。
// 唯一强调色是霓虹青 oklch(0.805 0.148 188),状态色仅用于语义,不参与装饰。
// ─── CSS Custom Properties ─────────────────────────────────────
:root {
// Backgrounds
--bg-primary: #fafafa;
--bg-secondary: #f0f0f0;
--bg-sidebar: #f5f5f5;
--bg-card: #ffffff;
--bg-card-hover: #fafafa;
--bg-input: #ffffff;
// Backgrounds — 由深到浅的四层
--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); // 输入框,比卡片更沉,形成凹陷感
// Borders
--border-color: #e0e0e0;
--border-light: #ebebeb;
// Borders — 发丝线分两档
--border-color: oklch(0.305 0.018 242);
--border-light: oklch(0.255 0.016 244);
// Accent
--accent-primary: #333333;
--accent-hover: #1a1a1a;
--accent-muted: #888888;
// Accent — 霓虹青,全站唯一强调色
--accent-primary: oklch(0.805 0.148 188);
--accent-hover: oklch(0.870 0.150 188);
--accent-muted: oklch(0.520 0.060 188);
--accent-soft: oklch(0.805 0.148 188 / 0.13);
--accent-ink: oklch(0.160 0.030 200); // 强调色上的文字/图标(深色,保证对比)
// Text
--text-primary: #1a1a1a;
--text-secondary: #666666;
--text-muted: #999999;
--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); // 禁用态 / 极次要信息
// Status
--success: #2e7d32;
--error: #c62828;
--warning: #f57f17;
// Status — 语义色,不用于装饰
--success: oklch(0.760 0.140 165);
--error: oklch(0.665 0.185 22);
--warning: oklch(0.810 0.145 85);
--accent-info: oklch(0.700 0.110 245);
// Message bubbles
--msg-user-bg: #f5f5f5;
--msg-assistant-bg: #f5f5f5;
--msg-system-border: #bdbdbd;
--msg-user-bg: oklch(0.225 0.016 246);
--msg-assistant-bg: oklch(0.185 0.014 248);
--msg-system-border: oklch(0.305 0.018 242);
// Code
--code-bg: #f4f4f4;
--code-bg: oklch(0.115 0.014 250);
// Utility
--text-on-accent: #ffffff;
--text-on-overlay: #ffffff;
--accent-info: #4a90d9;
--text-on-accent: oklch(0.160 0.030 200);
--text-on-overlay: oklch(0.945 0.006 200);
// RGB components (for rgba() usage)
--accent-primary-rgb: 51, 51, 51;
--accent-hover-rgb: 26, 26, 26;
--text-primary-rgb: 26, 26, 26;
--text-muted-rgb: 153, 153, 153;
--success-rgb: 46, 125, 50;
--error-rgb: 198, 40, 40;
--warning-rgb: 245, 127, 23;
--accent-info-rgb: 74, 144, 217;
}
.dark {
// Backgrounds
--bg-primary: #1a1a1a;
--bg-secondary: #252525;
--bg-sidebar: #202020;
--bg-card: #2a2a2a;
--bg-card-hover: #333333;
--bg-input: #2a2a2a;
// Borders
--border-color: #3a3a3a;
--border-light: #333333;
// Accent
--accent-primary: #e0e0e0;
--accent-hover: #f5f5f5;
--accent-muted: #888888;
// Text
--text-primary: #e0e0e0;
--text-secondary: #a0a0a0;
--text-muted: #888888;
// Status
--success: #66bb6a;
--error: #ef5350;
--warning: #ffb74d;
// Message bubbles
--msg-user-bg: #252525;
--msg-assistant-bg: #252525;
--msg-system-border: #555555;
// Code
--code-bg: #1e1e1e;
// Utility
--text-on-accent: #1a1a1a;
--text-on-overlay: #ffffff;
--accent-info: #6ba3d6;
// RGB components
--accent-primary-rgb: 224, 224, 224;
--accent-hover-rgb: 245, 245, 245;
--text-primary-rgb: 224, 224, 224;
--text-muted-rgb: 136, 136, 136;
--success-rgb: 102, 187, 106;
--error-rgb: 239, 83, 80;
--warning-rgb: 255, 183, 77;
--accent-info-rgb: 107, 163, 214;
}
.comic {
// Borders — bold comic outlines
--border-color: #1a1a1a;
--border-light: #555555;
--msg-system-border: #1a1a1a;
// Comic-specific
--font-ui: 'Comic Neue', 'ZCOOL KuaiLe', 'Zen Maru Gothic', 'Gaegu', cursive, sans-serif;
--comic-border-width: 2.5px;
--comic-shadow: 3px 3px 0px rgba(0, 0, 0, 0.15);
}
.dark.comic {
// Borders — brighter outlines on dark
--border-color: #666666;
--border-light: #555555;
--msg-system-border: #888888;
--comic-shadow: 3px 3px 0px rgba(255, 255, 255, 0.08);
// 霓虹青 oklch(0.805 0.148 188) ≈ rgb(45, 212, 191)
--accent-primary-rgb: 45, 212, 191;
--accent-hover-rgb: 74, 226, 205;
--text-primary-rgb: 240, 246, 247;
--text-muted-rgb: 168, 180, 187;
--success-rgb: 47, 197, 138;
--error-rgb: 232, 78, 61;
--warning-rgb: 226, 175, 32;
--accent-info-rgb: 105, 160, 232;
}
// ─── SCSS Variables (delegate to CSS custom properties) ────────
@@ -157,7 +89,7 @@ $text-muted: var(--text-muted);
$success: var(--success);
$error: var(--error);
$warning: var(--warning);
$info: $accent-primary;
$info: var(--accent-info);
// Message bubbles
$msg-user-bg: var(--msg-user-bg);
@@ -168,16 +100,19 @@ $msg-system-border: var(--msg-system-border);
$code-bg: var(--code-bg);
// Typography
$font-ui: var(--font-ui, 'Inter', system-ui, -apple-system, sans-serif);
$font-code: 'JetBrains Mono', 'Fira Code', 'Consolas', monospace;
// 正文用系统无衬线,标识/数据/代码用等宽——这是 CYBER 的核心排版特征。
$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;
$font-display: $font-code;
// Layout
// Layout — 与 docs/ui-baseline.md 保持一致
$sidebar-width: 240px;
$sidebar-collapsed-width: 64px;
$header-height: 60px;
$breakpoint-mobile: 768px;
// Radius
// Radius — 发丝线 + 小圆角,硬边而非圆润
$radius-sm: 6px;
$radius-md: 8px;
$radius-lg: 8px;