replace the monochrome theme with the CYBER neon-cyan skin
The project shipped a black-and-white theme that was only half converted: the login page looked right, the message page was halfway, and the settings page had not been started. This finishes the move to the CYBER reference in prototype_reference/. Colors now come from a single token source (styles/variables.scss), where every semantic color is declared twice: once as OKLCH for the CSS, and once as an RGB triple so translucent variants can be built as rgba(var(--*-rgb), alpha). Cyan is the system itself, amber means the user has to intervene, green means the machine is working, and red only ever means something broke. The RGB triples are derived from the OKLCH values so the two declarations cannot drift apart. Pages adopt the .cy-* shell classes from the reference (view, panel, kpis, tabs, grid, table, field) instead of ad-hoc markup, which is what makes 19 of 26 views consistent. The remaining seven are deliberately bespoke: chat streams, the kanban board, the workflow canvas, the terminal, and the missing-agent screen. The chart palette and the kanban column colors move into single-source modules so they cannot drift either. A new guard test rejects raw hex colors, named colors, and literal RGB triples anywhere in the client source, with an explicit exemption list for the places that genuinely cannot read a CSS variable. The existing chat semantics spec keeps the chat chain honest. No behavior changes: no logic, no i18n keys, no data structures, and the /chat-run event contract is untouched.
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
/**
|
||||
* 看板列状态的配色 —— 全项目唯一来源。
|
||||
*
|
||||
* 看板有 9 个列状态,装不进三色语义系统的三个槽位(青=系统本体 / 橙=需要你介入 /
|
||||
* 绿=机器在动),所以这里用「分类色板」的方式处理:每个状态一个可辨的色相,
|
||||
* 用于区分列 —— 它表达的是「这是第几个阶段」,不是「状态好坏」。
|
||||
* 见 docs/ui-baseline.md §7。
|
||||
*
|
||||
* 但有三个状态要向语义系统对齐,因为它们的含义在全项目是固定的:
|
||||
* running 机器在动 → 绿
|
||||
* blocked 出错了 → 红
|
||||
* done 机器做完了 → 绿
|
||||
* 其余六个是纯粹的流程阶段分类,走分类色。
|
||||
*
|
||||
* 早先这套颜色散在 KanbanTaskCard.vue 和 KanbanTaskDrawer.vue 两处,且两处
|
||||
* 互相矛盾:卡片用 #8b5cf6(紫)表示 running,抽屉用 --accent-primary(青);
|
||||
* 同一个状态在卡片和抽屉里是两个颜色。集中到这里就是修掉这个问题。
|
||||
*/
|
||||
|
||||
/** 看板列状态的全集。顺序与 i18n locales 中的 columns 一致。 */
|
||||
export const KANBAN_STATUSES = [
|
||||
'triage',
|
||||
'todo',
|
||||
'scheduled',
|
||||
'ready',
|
||||
'running',
|
||||
'blocked',
|
||||
'review',
|
||||
'done',
|
||||
'archived',
|
||||
] as const
|
||||
|
||||
export type KanbanStatus = (typeof KANBAN_STATUSES)[number]
|
||||
|
||||
/**
|
||||
* 各状态的主色(实色,用于左边条 / 圆点 / 文字)。
|
||||
*
|
||||
* 这几个值用 CSS 变量而非硬编码色值,是为了让语义状态跟着令牌走 ——
|
||||
* 令牌改了这里自动跟着变,不用两处同步。
|
||||
*
|
||||
* 分类状态(triage/todo/scheduled/ready/review/archived)用具体色值:
|
||||
* 它们没有语义令牌可依附,而用硬编码色值反而能保证「一眼分得出是哪一列」。
|
||||
*/
|
||||
export const KANBAN_STATUS_COLORS: Record<KanbanStatus, string> = {
|
||||
// 分类阶段 —— 中性灰阶
|
||||
triage: 'var(--text-muted)',
|
||||
todo: 'var(--text-muted)',
|
||||
scheduled: 'var(--text-muted)',
|
||||
// 分类阶段 —— 蓝青族
|
||||
ready: 'var(--accent-info)',
|
||||
// 语义对齐
|
||||
running: 'var(--success)',
|
||||
blocked: 'var(--error)',
|
||||
// 分类阶段 —— 紫(review 与其它列拉开距离)
|
||||
review: 'var(--kanban-review)',
|
||||
// 语义对齐
|
||||
done: 'var(--success)',
|
||||
// 分类阶段 —— 归档即退场,用最弱的灰
|
||||
archived: 'var(--text-faint)',
|
||||
}
|
||||
|
||||
/**
|
||||
* 各状态的弱底色(用于 badge 背景)。
|
||||
*
|
||||
* 语义状态用 rgba(令牌, 0.12) 拼 alpha;分类状态用对应主色的 12% 透明度。
|
||||
* 分类色的 RGB 三元组也进了令牌(--kanban-review-rgb / --text-muted-rgb),
|
||||
* 所以这里全部走 rgba(var(--*-rgb), α),没有字面量。
|
||||
*/
|
||||
export const KANBAN_STATUS_BG: Record<KanbanStatus, string> = {
|
||||
triage: 'rgba(var(--text-muted-rgb), 0.14)',
|
||||
todo: 'rgba(var(--text-muted-rgb), 0.14)',
|
||||
scheduled: 'rgba(var(--text-muted-rgb), 0.14)',
|
||||
ready: 'rgba(var(--accent-info-rgb), 0.12)',
|
||||
running: 'rgba(var(--success-rgb), 0.12)',
|
||||
blocked: 'rgba(var(--error-rgb), 0.12)',
|
||||
review: 'rgba(var(--kanban-review-rgb), 0.14)',
|
||||
done: 'rgba(var(--success-rgb), 0.12)',
|
||||
archived: 'rgba(var(--text-muted-rgb), 0.14)',
|
||||
}
|
||||
|
||||
/** 取某状态的主色;未知状态退到最弱的中性色。 */
|
||||
export function kanbanStatusColor(status: string): string {
|
||||
return KANBAN_STATUS_COLORS[status as KanbanStatus] ?? 'var(--text-faint)'
|
||||
}
|
||||
|
||||
/** 取某状态的弱底色;未知状态退到中性灰。 */
|
||||
export function kanbanStatusBg(status: string): string {
|
||||
return KANBAN_STATUS_BG[status as KanbanStatus] ?? 'rgba(var(--text-muted-rgb), 0.14)'
|
||||
}
|
||||
Reference in New Issue
Block a user