
# 管理端主题系统
**基于 Seed、Map、Alias 与 Component Token 的运行时主题架构**
[设计原则](#设计原则) · [Token 模型](#token-模型) · [运行时架构](#运行时架构) · [主题编辑器](#主题编辑器) · [扩展指南](#扩展指南)
主题系统为 Codex Proxy RS 管理端提供浅色、深色、预置配色与自定义配色能力。颜色 Map 复用 Ant Design 的
Token 分层、十阶色板与明暗角色映射,中性 Surface 由背景和文字 Seed 统一派生;不引入 `antd`、React、`ConfigProvider`
或 CSS-in-JS,Vue 组件继续通过 CSS Variables 与 Tailwind CSS 4 utilities 消费主题。
> [!IMPORTANT]
> 主题的目标是调整颜色、密度、圆角与层级,不改变现有页面结构和产品语义。默认主题必须保持既有视觉基线,
> 成功、警告、错误和业务数据色不会因为品牌色变化而失去原有含义。
## 设计原则
- **Seed 与 Map 可追踪**:主色和功能色均按 Ant Design 从 Seed 派生 P1-P10;浅色 P6 等于 Seed,深色 P6
经过暗色色板适配。编辑器同时展示 Seed 与最终 Map,不在中途隐式改色。
- **主色与表面分离**:品牌色负责交互和强调,页面、容器、浮层与文字由独立的背景和文本 Seed 派生。
- **语义独立**:`success`、`warning`、`error`、`info` 与 `link` 不随品牌色隐式改变;未显式配置 `link`
时按 Ant Design 回退到 `info`。
- **无边设计**:默认依靠表面色差、间距和轻阴影表达层级;边框只用于焦点、错误和必要分隔。
- **运行时可定制**:用户输入在浏览器中实时派生,因此使用 CSS Variables,不使用构建时 SCSS 变量。
- **单一事实源**:Store 只保存最小配置,所有 Map、Alias 与未覆盖的 Component Token 均由纯函数生成。
- **行为透明**:任意自定义 Seed 都直接进入公开算法,不追加页面或组件级修色;彩色文字 Alias 统一依据当前
Container Surface 做对比度保护,交互仍尊重 `prefers-reduced-motion`。
## 架构概览
```mermaid
flowchart LR
A[Pinia 持久化配置] --> B[resolveTheme]
B --> C[Seed Token]
C --> D[Map Token]
D --> E[Alias Token]
E --> F[Component Token]
F --> G[#cp-runtime-theme]
G --> H[Vue / Tailwind / ECharts]
B --> I[Theme Editor 草稿]
I --> J[Shadow DOM 预览]
J --> K[首页画板 / 组件概览]
```
核心职责保持分离:
| 层 | 文件 | 职责 |
| --- | --- | --- |
| 公开入口 | [`theme/index.ts`](../frontend/src/theme/index.ts) | 只汇总稳定的外部 API,不承载实现 |
| 领域类型 | [`theme/types.ts`](../frontend/src/theme/types.ts) | 唯一类型文件,包含持久化模型、解析结果与内部 Map 契约 |
| 设计输入 | [`theme/core/constants.ts`](../frontend/src/theme/core/constants.ts) | 默认 Seed、预置主题元数据、尺寸与可编辑白名单 |
| 颜色算法 | [`theme/core/color.ts`](../frontend/src/theme/core/color.ts) | Ant Design 色板角色、色调混合、透明度与对比度 |
| Map 派生 | [`theme/derive/colors.ts`](../frontend/src/theme/derive/colors.ts) | Surface、Primary、Semantic、Preset 与数据色 Map |
| Component 派生 | [`theme/derive/components.ts`](../frontend/src/theme/derive/components.ts) | 尺寸、阴影和 Component Token Map |
| 输入边界 | [`theme/core/normalize.ts`](../frontend/src/theme/core/normalize.ts) | 持久化配置与直接覆盖值的规范化 |
| 解析编排 | [`theme/core/resolve.ts`](../frontend/src/theme/core/resolve.ts) | 串联 Seed → Map → Alias → Component |
| Token 编译 | [`theme/core/tokens.ts`](../frontend/src/theme/core/tokens.ts) | 从类型化 Map 和短角色表生成 CSS Variables |
| 浏览器适配 | [`theme/runtime/browser.ts`](../frontend/src/theme/runtime/browser.ts) | 将解析结果提交为根作用域运行时样式表 |
| 状态 | [`stores/modules/theme.ts`](../frontend/src/stores/modules/theme.ts) | 持久化配置、系统明暗偏好、切换动作与动画 |
| 编辑器状态 | [`useThemeEditor.ts`](../frontend/src/views/theme/composables/useThemeEditor.ts) | 草稿、修改计数、恢复与保存 |
| 样式桥接 | [`styles/index.css`](../frontend/src/styles/index.css) | 将 CSS Token 暴露为 Tailwind CSS 4 utilities |
| 样式基线 | [`styles/base.css`](../frontend/src/styles/base.css) | 通过 `@layer base` 提供浏览器基线,通过 `@utility` 提供通用原生滚动条 |
| 静态基元 | [`styles/tokens.css`](../frontend/src/styles/tokens.css) | 只保留白色、透明色和作用域 `color-scheme` |
`theme/` 根目录只保留公开入口 `index.ts` 和唯一类型文件 `types.ts`;内部实现按 `core/`、`derive/`、`runtime/` 分层,不增加嵌套 barrel。
纯派生模块不访问 DOM,`theme/runtime/browser.ts` 不包含派生规则,Theme Store 不复制算法。
普通 Map 字段按 camelCase → kebab-case 统一生成 `--cp-*`;Semantic 与 Preset Color 仅维护各自的短角色表。
`ThemeTokenName` 在 `types.ts` 中由 Map 契约推导,新增字段不再要求同步手写大段联合类型和对象映射。
## Token 模型
主题采用四层模型:
```text
Seed Token → Map Token → Alias Token → Component Token
```
### Seed Token
Seed 是用户配置与持久化的最小事实:
```ts
type ThemeMode = 'system' | 'light' | 'dark'
type ThemeColorId = 'relay-blue' | 'deep-teal' | 'signal-violet' | 'graphite' | 'custom'
interface ThemeCustomization {
seed?: Partial