docs: 国聘红换肤实施计划

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Claude 2026-06-25 16:56:21 +08:00
parent 16d119784e
commit 50552b563e
1 changed files with 529 additions and 0 deletions

View File

@ -0,0 +1,529 @@
# 国聘红 · 国企风格全站换肤 Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** 将 offer_frontend 前端从"黑金 + Element Plus 默认蓝"换肤为"国聘红 + 白底"国企风格,全站统一,不改任何功能/结构/接口。
**Architecture:** 在 `src/style.css` 定义全局 CSS 令牌并覆盖 Element Plus 主色变量(`--el-color-primary` 系列),使全站 `type="primary"` 组件自动变红;再逐文件把硬编码的黑/金/蓝替换为令牌引用。纯样式改造,零逻辑变更。
**Tech Stack:** Vue 3 + Vite + Element Plus 2.xCSS 变量覆盖,不引入 SCSS
## Global Constraints
- 不改任何 `.vue``<template>` 结构与 `<script>` 逻辑,只改 `<style>` 与内联 `style` 中的颜色值。
- 不改后端、路由、接口、组件 props。
- 不新增依赖,不引入 SCSS/暗色模式/主题切换。
- 主色令牌:`--brand-red:#C8161D`、`--brand-red-2:#A11218`、`--brand-red-3:#E84148`、`--brand-red-bg:#FDECED`、`--bg-page:#F7F8FA`、`--bg-card:#FFFFFF`、`--text-main:#1D2129`、`--text-muted:#86909C`、`--border:#E5E6EB`。
- DashboardView 的 echarts 分类色板(`category: [...]` 数组)保留不动——它是数据可视化分类色,非主题色。
- 前端已运行于 http://localhost:5174/Vite后端 8000 不变。
---
### Task 1: 全局令牌 + Element Plus 主色覆盖
**Files:**
- Modify: `offer_frontend/src/style.css`(整文件替换)
**Interfaces:**
- Produces: 全局 CSS 变量 `--brand-red` 等,供后续所有任务的 scoped 样式 `var(--brand-red)` 引用Element Plus `type="primary"` 组件自动变红。
- [ ] **Step 1: 用以下内容整体替换 `src/style.css`**
```css
:root {
/* 品牌色 · 国聘红 */
--brand-red: #C8161D;
--brand-red-2: #A11218;
--brand-red-3: #E84148;
--brand-red-bg: #FDECED;
/* 中性色 */
--bg-page: #F7F8FA;
--bg-card: #FFFFFF;
--text-main: #1D2129;
--text-muted: #86909C;
--border: #E5E6EB;
font-family: 'PingFang SC', 'Microsoft YaHei', 'Noto Sans SC', system-ui, -apple-system, sans-serif;
line-height: 1.5;
font-weight: 400;
color-scheme: light;
color: var(--text-main);
background-color: var(--bg-page);
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
/* Element Plus 主色覆盖 → 中国红 */
--el-color-primary: #C8161D;
--el-color-primary-light-3: #D94A50;
--el-color-primary-light-5: #E57378;
--el-color-primary-light-7: #F0A0A4;
--el-color-primary-light-8: #F5BDBF;
--el-color-primary-light-9: #FDECED;
--el-color-primary-dark-2: #A11218;
}
a {
font-weight: 500;
color: var(--brand-red);
text-decoration: inherit;
}
a:hover {
color: var(--brand-red-2);
}
body {
margin: 0;
min-width: 320px;
min-height: 100vh;
background-color: var(--bg-page);
color: var(--text-main);
}
h1 {
font-size: 3.2em;
line-height: 1.1;
}
button {
border-radius: 8px;
border: 1px solid transparent;
padding: 0.6em 1.2em;
font-size: 1em;
font-weight: 500;
font-family: inherit;
background-color: var(--bg-card);
cursor: pointer;
transition: border-color 0.25s;
}
button:hover {
border-color: var(--brand-red);
}
.card {
padding: 2em;
}
#app {
width: 100%;
}
```
- [ ] **Step 2: 验证 Vite HMR 无报错**
Run: 查看 Vite 后台输出(任务 `b6lon581k`
Expected: 无编译错误;浏览器刷新 5174 后 `type="primary"` 按钮应显示红色。
- [ ] **Step 3: Commit**
```bash
git add offer_frontend/src/style.css
git commit -m "style: 全局国聘红令牌与 Element Plus 主色覆盖"
```
---
### Task 2: PortalLayout 黑金 → 白底红
**Files:**
- Modify: `offer_frontend/src/layouts/PortalLayout.vue`(仅 `<style scoped>`
**Interfaces:**
- Consumes: Task 1 全局令牌。
- Produces: 公开页顶栏/页脚的国聘红外观。
- [ ] **Step 1: 替换 `:root` 局部变量块(约 97-103 行)**
```css
:root {
--c-red: #D4D4D4;
--c-dark: #0E1E3D;
--c-gold: #C8973A;
--c-cream: #F8F4EF;
--c-border: #E2D9D0;
}
```
替换为
```css
:root {
--c-red: var(--brand-red);
--c-dark: var(--brand-red-2);
--c-gold: var(--brand-red);
--c-cream: var(--bg-page);
--c-border: var(--border);
}
```
- [ ] **Step 2: 顶部公告条 `.top-bar` 改浅底**
`.top-bar``background: #1A1A1A;``background: #F2F3F5;`
`.top-bar``color: rgba(255,255,255,0.75);``color: var(--text-muted);`
`.top-bar-left::before``color: #C8973A;``color: var(--brand-red);`
`.top-link``color: rgba(255,255,255,0.65);``color: var(--text-muted);`
`.top-link:hover, .clickable:hover``color: #C8973A;``color: var(--brand-red);`
`.top-divider``color: rgba(255,255,255,0.25);``color: #C9CDD4;`
- [ ] **Step 3: 主导航 `.main-header` 改白底**
`.main-header``background: linear-gradient(180deg, #1A1A1A 0%, #0F0F0F 100%);``background: #FFFFFF;`
`.main-header``box-shadow` 改为 `box-shadow: 0 2px 8px rgba(0,0,0,0.06);`
- [ ] **Step 4: Logo 配色金 → 红**
`.emblem-ring``border: 2px solid #C8973A;``border: 2px solid var(--brand-red);`
`.emblem-ring``background` 渐变金色 → `background: linear-gradient(135deg, rgba(200,22,29,0.12), rgba(200,22,29,0.04));`
`.emblem-ring``box-shadow` 金色 → `box-shadow: 0 0 16px rgba(200,22,29,0.25), inset 0 0 8px rgba(200,22,29,0.08);`
`.emblem-char``color: #C8973A;``color: var(--brand-red);`
`.logo-title``color: #FFFFFF;``color: var(--text-main);`
`.logo-sub``color: rgba(200,151,58,0.7);``color: var(--brand-red);` 并加 `opacity: 0.75;`
- [ ] **Step 5: 导航链接金 → 红**
`.nav-link``color: rgba(255,255,255,0.75);``color: var(--text-muted);`
`.nav-link::after``background: #C8973A;``background: var(--brand-red);`
`.nav-link:hover``color: #fff;``color: var(--brand-red);`
`.nav-link.active``color: #C8973A;``color: var(--brand-red);`
- [ ] **Step 6: 操作区按钮适配白底**
`.btn-ghost``border: 1px solid rgba(255,255,255,0.35);``border: 1px solid var(--border);`
`.btn-ghost``color: rgba(255,255,255,0.85);``color: var(--text-main);`
`.btn-ghost:hover``border-color: #C8973A; color: #C8973A;``border-color: var(--brand-red); color: var(--brand-red);`
`.user-badge``background: rgba(255,255,255,0.08);``background: var(--brand-red-bg);`
`.user-badge``border: 1px solid rgba(255,255,255,0.15);``border: 1px solid var(--border);`
`.user-avatar``background: #D4D4D4;``background: var(--brand-red);`
`.user-name``color: rgba(255,255,255,0.85);``color: var(--text-main);`
- [ ] **Step 7: 底线与页脚金 → 红**
`.header-underline``background: #0F0F0F;``background: #FFFFFF;`
`.underline-fill``background: linear-gradient(90deg, #C8973A 0%, #D4AF37 100%);``background: var(--brand-red);`
`.portal-footer``background: #1A1A1A;``background: #1D2129;`
`.portal-footer``border-top: 3px solid #C8973A;``border-top: 3px solid var(--brand-red);`
`.f-emblem``border: 1px solid #C8973A;``color: #C8973A;``var(--brand-red)`
- [ ] **Step 8: 验证**
浏览器打开 http://localhost:5174/home确认顶栏白底、红色底线、logo 红环、导航红下划线、页脚深灰红顶边,无残留黑/金。
- [ ] **Step 9: Commit**
```bash
git add offer_frontend/src/layouts/PortalLayout.vue
git commit -m "style: PortalLayout 黑金改国聘红白底"
```
---
### Task 3: HomeView 双栏 黑金 → 红白
**Files:**
- Modify: `offer_frontend/src/views/portal/HomeView.vue`(仅 `<style scoped>`
**Interfaces:**
- Consumes: Task 1 全局令牌。
- Produces: 首页双栏(左公司列表 + 右职位)国聘红外观。
- [ ] **Step 1: 替换局部变量块(约 364-372 行)**
```css
--gold: #B8860B;
--gold-lt: #D4AF37;
--dark: #1A1A1A;
--cream: #F0F3F8;
--border: #DDE3ED;
--text: #1D2129;
--muted: #86909C;
--blue: #2B5ADE;
--blue-lt: #EBF0FB;
```
替换为
```css
--gold: var(--brand-red);
--gold-lt: var(--brand-red-3);
--dark: var(--bg-card);
--cream: var(--bg-page);
--border: #E5E6EB;
--text: var(--text-main);
--muted: var(--text-muted);
--blue: var(--brand-red);
--blue-lt: var(--brand-red-bg);
```
- [ ] **Step 2: 左栏 `.panel-left` 黑底 → 白底**
`.panel-left``background: var(--dark);`(现即白)保持,但需把 `border-right: 1px solid rgba(255,255,255,0.07);``border-right: 1px solid var(--border);`
`.left-header``border-bottom: 1px solid rgba(255,255,255,0.08);``border-bottom: 1px solid var(--border);`
`.left-title``color: rgba(255,255,255,0.9);``color: var(--text-main);`
`.left-body::-webkit-scrollbar-thumb``background: rgba(255,255,255,0.12);``background: #C9CDD4;`
- [ ] **Step 3: 公司行 文字色适配白底**
`.org-row``border-bottom: 1px solid rgba(255,255,255,0.04);``border-bottom: 1px solid var(--border);`
`.org-row:hover``background: rgba(255,255,255,0.06);``background: var(--brand-red-bg);`
`.org-row.active``background: rgba(184,134,11,0.1);``background: var(--brand-red-bg);`
`.org-name``color: rgba(255,255,255,0.88);``color: var(--text-main);`
`.child-name``color: rgba(255,255,255,0.7);``color: var(--text-muted);`
`.org-stat``color: rgba(255,255,255,0.35);``color: var(--text-muted);`
`.org-child``background: rgba(0,0,0,0.12);``background: var(--bg-page);`
`.child-line``background: rgba(184,134,11,0.35);``background: var(--border);`
- [ ] **Step 4: 头像金色渐变 → 红色渐变**
`.org-avatar``background: linear-gradient(135deg, #B8860B, #8B6407);``background: linear-gradient(135deg, #C8161D, #8B1014);`
`.child-avatar``background: linear-gradient(135deg, #A67C07, #7D5A05);``background: linear-gradient(135deg, #A11218, #6B0C10);`
- [ ] **Step 5: 学历徽章金 → 红**
`.edu-total-badge``background: #FFF8E6;``background: var(--brand-red-bg);`
`.edu-total-badge``border: 1px solid #F0D080;``border: 1px solid var(--brand-red-3);`
`.edu-total-badge``color: var(--gold);`(已是红)保持。
- [ ] **Step 6: 骨架 shimmer 暗色 → 浅灰**
`.skeleton-row``background: linear-gradient(90deg, #2A2A2A 25%, #333 50%, #2A2A2A 75%);``background: linear-gradient(90deg, #E5E6EB 25%, #F2F3F5 50%, #E5E6EB 75%);`
- [ ] **Step 7: 验证**
浏览器 http://localhost:5174/home左栏白底、选中公司红高亮、头像红渐变、学历徽章红系、搜索按钮红、薪资红无残留黑/金。
- [ ] **Step 8: Commit**
```bash
git add offer_frontend/src/views/portal/HomeView.vue
git commit -m "style: HomeView 双栏黑金改国聘红白底"
```
---
### Task 4: SplashView 暗黑金 → 红色国企风
**Files:**
- Modify: `offer_frontend/src/views/SplashView.vue`(仅 `<style scoped>`
**Interfaces:**
- Consumes: Task 1 全局令牌。
- Produces: 落地页国聘红外观。
- [ ] **Step 1: 页面底色与顶栏**
`.splash-page``background: #0a0a0a;``background: var(--bg-page);``color: #fff;` → `color: var(--text-main);`
`.splash-header``background: rgba(0, 0, 0, 0.45);``background: rgba(255,255,255,0.92);`
`.splash-header``border-bottom: 1px solid rgba(255, 255, 255, 0.08);``border-bottom: 1px solid var(--border);` 并加 `box-shadow: 0 1px 8px rgba(0,0,0,0.04);`
- [ ] **Step 2: 顶栏 logo/nav/按钮**
`.logo-icon``background: linear-gradient(135deg, #B8860B, #8B6407);``background: linear-gradient(135deg, #C8161D, #8B1014);`
`.logo-title``color: #fff;``color: var(--text-main);`
`.logo-en``color: rgba(255,255,255,0.45);``color: var(--brand-red);``opacity: 0.7;`
`.nav-item``color: rgba(255,255,255,0.8);``color: var(--text-muted);`
`.nav-item:hover``color: #D4AF37;``color: var(--brand-red);`
`.btn-outline``border: 1px solid rgba(255,255,255,0.4);``border: 1px solid var(--border);``color: rgba(255,255,255,0.85);` → `color: var(--text-main);`
`.btn-outline:hover``border-color: #D4AF37; color: #D4AF37;``border-color: var(--brand-red); color: var(--brand-red);`
`.btn-solid``background: linear-gradient(135deg, #B8860B, #8B6407);``background: var(--brand-red);`
- [ ] **Step 3: Hero 背景改红色渐变**
`.hero-bg``background: linear-gradient(160deg, #0d1b2a 0%, #1a2744 25%, #0f1f35 50%, #0d1520 75%, #060e18 100%);``background: linear-gradient(160deg, #C8161D 0%, #A11218 35%, #8B1014 70%, #6B0C10 100%);`
- [ ] **Step 4: 建筑竖线与光晕 金 → 红/白**
`.line``background` 渐变中 `rgba(184, 134, 11, 0.15)``rgba(255,255,255,0.18)``rgba(184, 134, 11, 0.08)` → `rgba(255,255,255,0.08)`
`.hero-glow``background: radial-gradient(ellipse, rgba(184, 134, 11, 0.18) 0%, rgba(184, 134, 11, 0.05) 50%, transparent 70%);``background: radial-gradient(ellipse, rgba(255,255,255,0.22) 0%, rgba(255,255,255,0.06) 50%, transparent 70%);`
- [ ] **Step 5: Hero 文案与按钮**
`.hero-badge``border: 1px solid rgba(184, 134, 11, 0.6);``border: 1px solid rgba(255,255,255,0.7);``color: #D4AF37;` → `color: #fff;``background: rgba(184, 134, 11, 0.08);` → `background: rgba(255,255,255,0.12);`
`.btn-primary-lg``background: linear-gradient(135deg, #B8860B, #D4AF37);``background: #FFFFFF;``color: #fff;` → `color: var(--brand-red);`
`.btn-primary-lg``box-shadow: 0 4px 20px rgba(184,134,11,0.4);``box-shadow: 0 4px 20px rgba(0,0,0,0.2);`
`.btn-primary-lg:hover``box-shadow: 0 8px 28px rgba(184,134,11,0.5);``box-shadow: 0 8px 28px rgba(0,0,0,0.28);`
`.hero-slogan`/`.hero-sub`/`.scroll-hint` 保持白字,因 hero 背景为红。)
- [ ] **Step 6: 数据区 暗底金字 → 白底红字**
`.stats-section``background: linear-gradient(135deg, #111 0%, #1a1a1a 100%);``background: #FFFFFF;`
`.stats-section``border-top`/`border-bottom: 1px solid rgba(184,134,11,0.25);` → `1px solid var(--border);`
`.stat-num``color: #D4AF37;``color: var(--brand-red);`
`.stat-label``color: rgba(255,255,255,0.5);``color: var(--text-muted);`
`.stat-divider``background: rgba(184,134,11,0.2);``background: var(--border);`
- [ ] **Step 7: 特色区 暗底 → 浅灰底白卡**
`.features-section``background: #0d0d0d;``background: var(--bg-page);`
`.section-label``color: #D4AF37;``color: var(--brand-red);`
`.section-title``color: #fff;``color: var(--text-main);`
`.feature-card``background: #161616;``background: var(--bg-card);``border: 1px solid rgba(184,134,11,0.15);` → `border: 1px solid var(--border);`,加 `box-shadow: 0 1px 6px rgba(0,0,0,0.04);`
`.feature-card:hover``border-color: rgba(184,134,11,0.5);``border-color: var(--brand-red);`
`.feature-card h3``color: #fff;``color: var(--text-main);`
`.feature-card p``color: rgba(255,255,255,0.45);``color: var(--text-muted);`
- [ ] **Step 8: 底部 footer 暗底 → 深灰**
`.splash-footer``background: #060606;``background: #1D2129;`
`.splash-footer``border-top: 1px solid rgba(255,255,255,0.06);``border-top: 1px solid var(--brand-red);`
`.footer-logo``color: rgba(255,255,255,0.5);``color: rgba(255,255,255,0.7);`
`.footer-copy``color: rgba(255,255,255,0.25);``color: rgba(255,255,255,0.4);`
`.footer-links span``color: rgba(255,255,255,0.35);``color: rgba(255,255,255,0.6);`
`.footer-links span:hover``color: #D4AF37;``color: var(--brand-red-3);`
- [ ] **Step 9: 验证**
浏览器 http://localhost:5174/:红色 hero、白底数据区红字、浅灰特色卡、深灰 footer 红顶边,无残留黑/金。
- [ ] **Step 10: Commit**
```bash
git add offer_frontend/src/views/SplashView.vue
git commit -m "style: SplashView 暗黑金改国聘红国企风"
```
---
### Task 5: AdminLayout 侧边栏 海军蓝 → 深红
**Files:**
- Modify: `offer_frontend/src/layouts/AdminLayout.vue`template 内联属性 + `<style scoped>`
**Interfaces:**
- Consumes: Task 1 全局令牌(`--brand-red` 等)。
- Produces: 后台侧边栏深红外观;其余 EP 组件由 Task 1 自动变红。
- [ ] **Step 1: el-menu 内联属性改色(第 19 行)**
```html
<el-menu router :default-active="$route.path" background-color="#001529" text-color="#fff" active-text-color="#409eff">
```
改为
```html
<el-menu router :default-active="$route.path" background-color="#8B1014" text-color="#fff" active-text-color="#FFD0D2">
```
- [ ] **Step 2: scoped 样式中 `#001529` → 深红**
第 65 行 `.admin-sidebar`(或对应选择器)的 `background: #001529;``background: #8B1014;`
第 92 行 同样 `background: #001529;``background: #8B1014;`
(若两处属不同选择器,均改 `#8B1014`。)
- [ ] **Step 3: 验证**
浏览器登录后台(管理员账号)访问 http://localhost:5174/admin/jobs侧边栏深红、选中项浅红文字、primary 按钮红。
- [ ] **Step 4: Commit**
```bash
git add offer_frontend/src/layouts/AdminLayout.vue
git commit -m "style: AdminLayout 侧边栏海军蓝改深红"
```
---
### Task 6: Auth 视图硬编码蓝 → 红
**Files:**
- Modify: `offer_frontend/src/views/auth/LoginView.vue`
- Modify: `offer_frontend/src/views/auth/RegisterView.vue`
- Modify: `offer_frontend/src/views/auth/ResetPasswordView.vue`
**Interfaces:**
- Consumes: Task 1 全局令牌。
- [ ] **Step 1: LoginView 替换硬编码色**
第 65 行内联 `style="color: #909399; ..."``style="color: var(--text-muted); ..."`"忘记密码"链接保持次要灰OK 保留 `#909399` 也可——此处统一为令牌)
第 155 行内联 `style="color: #409eff; ..."``style="color: var(--brand-red); ..."`
第 357 行 `color: #409eff;``color: var(--brand-red);`
第 389 行 `color: #409eff;``color: var(--brand-red);`
- [ ] **Step 2: RegisterView 替换硬编码色**
第 63 行内联 `style="color: #409eff; ..."``style="color: var(--brand-red); ..."`
- [ ] **Step 3: ResetPasswordView 替换硬编码色**
第 100 行内联 `style="color: #409eff; ..."``style="color: var(--brand-red); ..."`
- [ ] **Step 4: 验证**
浏览器访问 /login、/register、/forgot-password链接与强调色为红无蓝。
- [ ] **Step 5: Commit**
```bash
git add offer_frontend/src/views/auth/LoginView.vue offer_frontend/src/views/auth/RegisterView.vue offer_frontend/src/views/auth/ResetPasswordView.vue
git commit -m "style: Auth 视图硬编码蓝改国聘红"
```
---
### Task 7: Admin 视图硬编码蓝/灰 → 红(保留 echarts 色板)
**Files:**
- Modify: `offer_frontend/src/views/admin/DashboardView.vue`
- Modify: `offer_frontend/src/views/admin/ApplicationManageView.vue`
**Interfaces:**
- Consumes: Task 1 全局令牌。
- [ ] **Step 1: DashboardView 替换非图表硬编码色**
第 357 行 `color: #909399;``color: var(--text-muted);`
第 371 行 `.stat-value.info { color: #409eff; }``.stat-value.info { color: var(--brand-red); }`
**保留第 138 行 `category: [...]` echarts 色板与第 307 行 `itemStyle.color: '#409eff'` 不动**(数据可视化分类色,非主题;如需统一可将 307 行改为 `var(--brand-red)`,但会与色板其他色不一致——本计划选择保留)。
- [ ] **Step 2: ApplicationManageView 替换硬编码色**
第 259 行 `border-left: 3px solid #409eff;``border-left: 3px solid var(--brand-red);`
- [ ] **Step 3: 验证**
浏览器访问 /admin/dashboard、/admin/applications信息色与边框为红echarts 图表色板保持分类多色(符合预期)。
- [ ] **Step 4: Commit**
```bash
git add offer_frontend/src/views/admin/DashboardView.vue offer_frontend/src/views/admin/ApplicationManageView.vue
git commit -m "style: Admin 视图硬编码蓝灰改国聘红(保留 echarts 色板)"
```
---
### Task 8: 全站残留色兜底 + 视觉验收
**Files:**
- 无新文件;仅 grep 检查与截图核对。
- [ ] **Step 1: grep 残留黑金/默认蓝**
Run:
```bash
cd C:/code/offer/offer_frontend && grep -rniE "#409eff|#909399|#001529|#1A1A1A|#0F0F0F|#C8973A|#B8860B|#D4AF37" src
```
Expected: 仅剩 DashboardView 第 138/307 行 echarts 色板(已确认保留);其余无残留。若发现遗漏,按上述映射补改并 amend 对应任务提交。
- [ ] **Step 2: 截图核对各页面**
逐页打开并截图:`/`Splash、`/home`(首页双栏)、`/companies`(公司介绍)、`/login`、`/register`、求职者中心(登录求职者账号)、`/admin/*`(登录管理员)。
确认:全站白底 + 国聘红主色,无黑金、无默认蓝。
- [ ] **Step 3: 最终 Commit如有兜底改动**
```bash
git add -A offer_frontend/src
git commit -m "style: 国聘红换肤残留色兜底"
```
(若无兜底改动,跳过。)
---
## Self-Review 结论
- **Spec 覆盖**spec 第 2 节令牌→Task 13.1 style.css→Task 13.2 PortalLayout→Task 23.3 HomeView→Task 33.4 SplashView→Task 43.5 AdminLayout→Task 53.6 其余视图→Task 6/7第 5 节验证→Task 8。全覆盖。
- **占位符**:无 TBD/TODO每步含具体颜色映射或代码。
- **类型一致**:令牌名(`--brand-red` 等)在所有任务中一致。
- **echarts 色板**:明确保留,避免数据可视化失色。