From dab221cdb95b861e60e216391739963984e68f0a Mon Sep 17 00:00:00 2001 From: Zyy Date: Sun, 6 Sep 2026 12:48:19 +0800 Subject: [PATCH] refactor(theme): standardize container color roles Rename primary, semantic and preset background roles to container and their paired foreground roles to on-container across derivation, CSS variables, utilities, consumers and documentation. Preserve existing palette values and contrast relationships while making text on neutral surfaces distinct from content inside semantic containers. Validated with token equivalence across presets and custom seeds, frontend typecheck, lint and production build. Co-authored-by: Codex --- docs/theme.md | 39 +++++----- frontend/src/components/base/BaseButton.vue | 2 +- .../src/components/base/BaseIconButton.vue | 4 +- frontend/src/components/base/BaseMenuItem.vue | 2 +- .../src/components/base/BaseModal/index.vue | 8 +- frontend/src/components/base/BaseRange.vue | 4 +- frontend/src/components/base/BaseSelect.vue | 2 +- .../components/base/BaseToast/BaseToast.vue | 8 +- frontend/src/layout/components/AppSidebar.vue | 4 +- .../components/SystemUpdateModal/index.vue | 2 +- .../components/SystemUpdateModal/presenter.ts | 6 +- frontend/src/styles/index.css | 73 ++++++++++--------- frontend/src/theme/core/tokens.ts | 18 ++--- frontend/src/theme/derive/colors.ts | 41 ++++++----- frontend/src/theme/derive/components.ts | 12 +-- frontend/src/theme/derive/roles.ts | 40 +++++----- frontend/src/theme/types.ts | 49 +++++++------ frontend/src/views/account-groups/index.vue | 2 +- .../components/AccountOverviewCards.vue | 8 +- .../accounts/components/AccountPlanBadge.vue | 14 ++-- .../AccountQuotaPanel/ResetCredits.vue | 8 +- .../AccountQuotaSummaryCell/Entry.vue | 2 +- .../AccountStatusBadge/presenter.ts | 16 ++-- .../accounts/components/AccountUsagePanel.vue | 20 ++--- .../composables/useAccountConnectionTest.ts | 6 +- .../src/views/accounts/utils/visualTone.ts | 8 +- .../api-keys/components/ApiKeyCreateModal.vue | 4 +- .../api-keys/components/ApiKeyScopeCell.vue | 2 +- .../api-keys/components/ApiKeyStatusBadge.vue | 2 +- .../dashboard/components/WireProfileCard.vue | 10 +-- frontend/src/views/dashboard/constants.ts | 18 ++--- .../src/views/login/components/LoginPanel.vue | 2 +- frontend/src/views/login/index.vue | 4 +- .../ClientDesktopOfflineDownloads.vue | 6 +- .../theme/components/ThemeColorTokenField.vue | 2 +- .../components/ThemeComponentPreview.vue | 24 +++--- .../components/ThemeGlobalTokenPanel.vue | 2 +- .../components/ThemeNumberTokenField.vue | 2 +- .../views/usage/components/OpsErrorPanel.vue | 2 +- .../usage/components/UsageClientIpCell.vue | 2 +- .../usage/components/UsageDetailPopover.vue | 2 +- .../usage/components/UsageStatusCodeBadge.vue | 6 +- .../usage/components/UsageSummaryCards.vue | 8 +- frontend/src/views/usage/utils/records.ts | 4 +- 44 files changed, 254 insertions(+), 246 deletions(-) diff --git a/docs/theme.md b/docs/theme.md index 6b23c6e05..16b4ba6e9 100644 --- a/docs/theme.md +++ b/docs/theme.md @@ -29,8 +29,9 @@ Token 分层与十阶色板,再按项目的明暗角色规则派生;中性 S - **无边设计**:默认依靠表面色差、间距和轻阴影表达层级;边框只用于焦点、错误和必要分隔。 - **运行时可定制**:用户输入在浏览器中实时派生,因此使用 CSS Variables,不使用构建时 SCSS 变量。 - **单一事实源**:Store 只保存最小配置,所有 Map、Alias 与未覆盖的 Component Token 均由纯函数生成。 -- **行为透明**:任意自定义 Seed 都进入统一算法,页面只选择角色。功能色文字同时依据 Container 和自身背景三态做 - 对比度保护,不使用固定色相的文字锚点覆盖自定义 Seed;交互仍尊重 `prefers-reduced-motion`。 +- **行为透明**:任意自定义 Seed 都进入统一算法,页面只选择角色。功能色 `text` 与 `on-container` 分别依据中性 + Surface 和自身 Container 三态做对比度保护,不使用固定色相的文字锚点覆盖自定义 Seed;交互仍尊重 + `prefers-reduced-motion`。 ## 架构概览 @@ -120,20 +121,23 @@ interface ThemeCustomization { | 功能色 Base | P6 | P6 | | Primary / 功能色 Hover、Active | P5、P7 | P8、P6 | | Primary Text Hover、Text、Text Active | P5、P6、P7 | P8、P7、P6 | -| 功能色 Text Hover、Text、Text Active | P5、P6、P7 | P8、P9、P10 | +| Primary On Container | P6 | P7 | +| 功能色 Text Hover、Text、Text Active | P5、P7、P7 | P8、P7、P10 | +| 功能色 On Container | P6 | P9 | -弱背景由 Container 与对应 Base/Hover/Active 按 recipe 权重混合;描边同样混色,再相对 Container 保证 3:1。 -功能色 Hover/Active 相对 Container 保证 3:1,Base 不做该校正。每种文字状态都同时检查 Container、Background、 -Background Hover、Background Active,取最弱配对并校正到至少 4.5:1,兼容消费者在背景切换时保留同一文字角色。 +弱语义 Container 由中性 Container 与对应 Base/Hover/Active 按 recipe 权重混合;描边同样混色,再相对中性 +Container 保证 3:1。功能色 Hover/Active 相对中性 Container 保证 3:1,Base 不做该校正。`text` 依据页面、 +容器、浮层和交互填充等中性 Surface 校正;`on-container` 单独依据语义 Container 的默认、Hover、Active 三态 +校正到至少 4.5:1,避免为了彩色底对比度而削弱中性表面上的颜色辨识度。 `ensureContrast` 以每步 1% 的黑/白混合寻找满足所有配对的颜色;不能满足全部约束时返回最弱配对表现最好的候选, 因此不承诺任意互相矛盾的自定义前景/背景组合都能达标。 分类、图表与数据强调继续使用 Ant Design Preset Color 的角色结构。Blue、Green、Orange、Red 分别复用 `colorInfo`、`colorSuccess`、`colorWarning`、`colorError`,保证通用彩色与可编辑语义 Seed 同源;没有语义对应的 Cyan、Purple 从 `@ant-design/colors` 的 `presetPrimaryColors` 取得 Seed。 -Preset 的实心色使用 P6,弱背景、较强背景与边界按 recipe 权重混合;浅色文字取 P7,深色取 P8 并保留 HSL -最低明度 0.7。`text` 相对 Container 校正,`text-on-bg` 同时相对弱背景和较强背景校正到 4.5:1;彩色底上的文字 -应使用 `text-on-bg`,普通数值与标签不直接使用 `solid`。 +Preset 的实心色使用 P6,普通 Container、Strong Container 与边界按 recipe 权重混合;浅色文字取 P7,深色取 P8 +并保留 HSL 最低明度 0.7。`text` 相对中性 Container 校正,`on-container` 同时相对普通和 Strong Container +校正到 4.5:1;彩色容器里的文字与图标应使用 `on-container`,普通数值与标签不直接使用 `solid`。 背景与文本 Seed 进入独立的 Surface Map,生成: @@ -151,11 +155,12 @@ Input、阴影与其他 Component Token 继续从 Surface、Primary 和 Semantic 正常文字同时检查 Layout、Container、Elevated、文字交互背景与三级 Fill。正文、标题和 Secondary 至少 7:1, Tertiary 至少 5.5:1,Quaternary 至少 4.5:1;这些是相对全部上述表面的最低目标,对 Container 的实测比值通常更高。 Disabled 保留独立的弱化颜色,不承担正常信息。输入背景主要从这些 Surface 混色派生,placeholder 继续消费 -Quaternary;主按钮白字与功能色文字遵循各自的背景配对规则。 +Quaternary;主按钮白字与功能色文字遵循各自的容器配对规则。 ### Alias Token -Alias 按视觉角色命名,使用 `--cp-` 命名空间,并优先对齐 Ant Design 的公开 Token 词汇: +Alias 按视觉角色命名,使用 `--cp-` 命名空间;整体分层对齐 Ant Design,并以 Container / On Container 表达成对的 +语义表面与前景: | 角色 | CSS Token | 主要消费者 | | --- | --- | --- | @@ -167,7 +172,7 @@ Alias 按视觉角色命名,使用 `--cp-` 命名空间,并优先对齐 Ant | 选择 | `--cp-control-item-bg-active*` | Segmented、Select 和选择控件 | | 焦点 | `--cp-control-outline` | 键盘焦点和输入反馈 | | 功能色 | `--cp-color-info / success / warning / error-*` | 系统反馈与状态 | -| 预设彩色 | `--cp-color-{blue,cyan,green,orange,purple,red}-{bg,bg-strong,border,solid,text,text-on-bg}` | 分类标签与数据强调 | +| 预设彩色 | `--cp-color-{blue,cyan,green,orange,purple,red}-{container,container-strong,border,solid,text,on-container}` | 分类标签与数据强调 | Alias 不在页面中追加修色;中性与彩色文字在派生层执行各自的背景配对约束。Component Token 直接覆盖时不会自动重算同组件的其他状态;需要保持梯度关系时应修改 Seed,而不是逐个覆盖 Map Token。 @@ -201,9 +206,9 @@ Theme Editor 只开放真正由对应组件消费的 Component Token。全局 Al ### 通用颜色消费 -主题层禁止声明账号套餐、推理类型或具体页面名称。业务组件只能选择通用 Preset Color 角色,例如 Cyan 弱背景、 -Purple 强背景或 Purple 实心色;同一组颜色仍由运行时色板统一派生。`styles/tokens.css` 只保留白色、透明色与 -作用域 `color-scheme`,不保存可换肤值或业务标识色。账户活动热力图以 Success Background 为起点、Success Solid +主题层禁止声明账号套餐、推理类型或具体页面名称。业务组件只能选择通用 Preset Color 角色,例如 Cyan Container、 +Purple Strong Container 或 Purple Solid;同一组颜色仍由运行时色板统一派生。`styles/tokens.css` 只保留白色、透明色与 +作用域 `color-scheme`,不保存可换肤值或业务标识色。账户活动热力图以 Success Container 为起点、Success Solid 为终点,按 22% / 46% / 70% 生成中间密度;浅色与暗色使用同一规则,因此不会在浅色背景退化成近白方块。 图表数据系列也只引用通用 Preset Color Token。 @@ -311,7 +316,7 @@ Alias 算法,避免主题配置逐渐退化成一份无法维护的完整 CSS - 全局 Token:`--cp-color-bg-container`、`--cp-font-size`。 - Component Token:`--cp-table-row-hover-bg`、`--cp-input-active-shadow`。 -- Preset Color Token:`--cp-color-purple-bg-strong`、`--cp-color-cyan-text-on-bg`。 +- Preset Color Token:`--cp-color-purple-container-strong`、`--cp-color-cyan-on-container`。 - 主题层禁止业务域命名;套餐、模型或页面只能消费通用 Alias、Preset 或 Component Token。 - Map 与 Component 字段由 `theme/core/tokens.ts` 统一生成 CSS Token;禁止在解析器中再写平行的逐项映射表。 - 禁止继续引入 `accent`、`soft`、`current`、`subtle` 等与现有角色重叠的平行词汇。 @@ -331,7 +336,7 @@ Alias 算法,避免主题配置逐渐退化成一份无法维护的完整 CSS `@theme inline` 只注册 Tailwind 名称,不保存主题值。注册表按基础、排版、颜色、圆角、阴影、间距与尺寸排序; 颜色再按基元、表面、主色与链接、语义、预设、数据、组件分组。 -Preset 家族按字母排序,每个家族固定使用 `bg → bg-strong → border → solid → text → text-on-bg`。主题值由 +Preset 家族按字母排序,每个家族固定使用 `container → container-strong → border → solid → text → on-container`。主题值由 `initializeTheme()` 在 Vue 挂载前动态生成并提交,不增加 `theme:generate`、`theme:check` 或构建期快照。 全局元素基线统一放进 `styles/base.css` 的 `@layer base`,确保组件 utility 可以按 Tailwind 层级正常覆盖;可复用的 diff --git a/frontend/src/components/base/BaseButton.vue b/frontend/src/components/base/BaseButton.vue index 56e393a87..72c39e491 100644 --- a/frontend/src/components/base/BaseButton.vue +++ b/frontend/src/components/base/BaseButton.vue @@ -35,7 +35,7 @@ const variantClasses: Record = { 'bg-cp-fill-tertiary text-cp-text shadow-cp-tertiary hover:bg-cp-bg-text-active active:bg-cp-bg-text-active', ghost: 'bg-transparent text-cp-text-secondary shadow-none hover:bg-cp-fill-quaternary hover:text-cp-text active:bg-cp-fill-tertiary', - destructive: 'bg-cp-error-bg text-cp-error-text-on-bg shadow-none hover:bg-cp-error-bg-hover active:bg-cp-error-bg-active', + destructive: 'bg-cp-error-container text-cp-error-on-container shadow-none hover:bg-cp-error-container-hover active:bg-cp-error-container-active', } const sizeClasses: Record = { diff --git a/frontend/src/components/base/BaseIconButton.vue b/frontend/src/components/base/BaseIconButton.vue index bb4e2ee30..31eec8ab4 100644 --- a/frontend/src/components/base/BaseIconButton.vue +++ b/frontend/src/components/base/BaseIconButton.vue @@ -36,10 +36,10 @@ const variantClasses: Record = { secondary: 'bg-cp-bg-container text-cp-text-secondary shadow-cp-tertiary hover:bg-cp-bg-text-hover hover:text-cp-text active:bg-cp-bg-text-active', success: - 'bg-cp-success-bg text-cp-success-text-on-bg shadow-none hover:bg-cp-success-bg-hover active:bg-cp-success-bg-active', + 'bg-cp-success-container text-cp-success-on-container shadow-none hover:bg-cp-success-container-hover active:bg-cp-success-container-active', ghost: 'bg-transparent text-cp-text-secondary shadow-none hover:bg-cp-fill-quaternary hover:text-cp-text active:bg-cp-fill-tertiary', - destructive: 'bg-transparent text-cp-error-text shadow-none hover:bg-cp-error-bg-hover hover:text-cp-error-text-on-bg active:bg-cp-error-bg-active active:text-cp-error-text-on-bg', + destructive: 'bg-transparent text-cp-error-text shadow-none hover:bg-cp-error-container-hover hover:text-cp-error-on-container active:bg-cp-error-container-active active:text-cp-error-on-container', } const sizeClasses: Record = { diff --git a/frontend/src/components/base/BaseMenuItem.vue b/frontend/src/components/base/BaseMenuItem.vue index 6bdeb00e1..1b7f60e99 100644 --- a/frontend/src/components/base/BaseMenuItem.vue +++ b/frontend/src/components/base/BaseMenuItem.vue @@ -26,7 +26,7 @@ const classes = computed(() => [ 'focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-cp-control-outline', 'disabled:cursor-not-allowed disabled:text-cp-text-disabled', props.tone === 'destructive' - ? 'text-cp-error-text hover:bg-cp-error-bg-hover hover:text-cp-error-text-on-bg' + ? 'text-cp-error-text hover:bg-cp-error-container-hover hover:text-cp-error-on-container' : 'text-cp-text hover:bg-cp-bg-text-hover', ]) diff --git a/frontend/src/components/base/BaseModal/index.vue b/frontend/src/components/base/BaseModal/index.vue index 375145467..3491b9435 100644 --- a/frontend/src/components/base/BaseModal/index.vue +++ b/frontend/src/components/base/BaseModal/index.vue @@ -78,19 +78,19 @@ const toneClasses: Record = { icon: 'text-cp-text-secondary', }, info: { - iconBg: 'bg-cp-info-bg', + iconBg: 'bg-cp-info-container', icon: 'text-cp-info', }, warning: { - iconBg: 'bg-cp-warning-bg', + iconBg: 'bg-cp-warning-container', icon: 'text-cp-warning', }, danger: { - iconBg: 'bg-cp-error-bg', + iconBg: 'bg-cp-error-container', icon: 'text-cp-error', }, success: { - iconBg: 'bg-cp-success-bg', + iconBg: 'bg-cp-success-container', icon: 'text-cp-success', }, } diff --git a/frontend/src/components/base/BaseRange.vue b/frontend/src/components/base/BaseRange.vue index 1e11f5b8e..3c22da7a9 100644 --- a/frontend/src/components/base/BaseRange.vue +++ b/frontend/src/components/base/BaseRange.vue @@ -118,11 +118,11 @@ function updateModel(event: Event) { } .base-range:focus-visible::-webkit-slider-thumb { - box-shadow: 0 0 0 3px var(--cp-color-primary-bg-hover); + box-shadow: 0 0 0 3px var(--cp-color-primary-container-hover); } .base-range:focus-visible::-moz-range-thumb { - box-shadow: 0 0 0 3px var(--cp-color-primary-bg-hover); + box-shadow: 0 0 0 3px var(--cp-color-primary-container-hover); } .base-range:disabled { diff --git a/frontend/src/components/base/BaseSelect.vue b/frontend/src/components/base/BaseSelect.vue index a3bbe93e2..383a22a22 100644 --- a/frontend/src/components/base/BaseSelect.vue +++ b/frontend/src/components/base/BaseSelect.vue @@ -98,7 +98,7 @@ const triggerClasses = computed(() => [ props.disabled ? 'cursor-not-allowed bg-cp-bg-container-disabled text-cp-text-disabled shadow-none' : invalid.value - ? 'cursor-pointer bg-(--cp-input-error-active-bg) text-cp-error-text-on-bg shadow-cp-input-error-active' + ? 'cursor-pointer bg-(--cp-input-error-active-bg) text-cp-error-on-container shadow-cp-input-error-active' : open.value ? 'cursor-pointer bg-(--cp-input-active-bg) text-cp-text shadow-cp-input-active' : [ diff --git a/frontend/src/components/base/BaseToast/BaseToast.vue b/frontend/src/components/base/BaseToast/BaseToast.vue index de564e039..624c4a673 100644 --- a/frontend/src/components/base/BaseToast/BaseToast.vue +++ b/frontend/src/components/base/BaseToast/BaseToast.vue @@ -20,19 +20,19 @@ const titleMap = { const colorClasses = { success: { - iconBg: 'bg-cp-success-bg', + iconBg: 'bg-cp-success-container', icon: 'text-cp-success', }, error: { - iconBg: 'bg-cp-error-bg', + iconBg: 'bg-cp-error-container', icon: 'text-cp-error', }, warning: { - iconBg: 'bg-cp-warning-bg', + iconBg: 'bg-cp-warning-container', icon: 'text-cp-warning', }, info: { - iconBg: 'bg-cp-info-bg', + iconBg: 'bg-cp-info-container', icon: 'text-cp-info', }, } diff --git a/frontend/src/layout/components/AppSidebar.vue b/frontend/src/layout/components/AppSidebar.vue index 04fad0492..4b3980095 100644 --- a/frontend/src/layout/components/AppSidebar.vue +++ b/frontend/src/layout/components/AppSidebar.vue @@ -342,7 +342,7 @@ onBeforeUnmount(() => { class="inline-flex h-4.5 min-w-0 cursor-pointer items-center gap-1 rounded-cp-sm border-0 px-1.5 font-mono text-[10px] leading-none font-bold transition-colors outline-none focus-visible:ring-2 focus-visible:ring-cp-control-outline focus-visible:ring-offset-2 focus-visible:ring-offset-cp-bg-container" :class="[ hasUpdate - ? 'bg-cp-success-bg text-cp-success-text-on-bg hover:bg-cp-success-bg-hover' + ? 'bg-cp-success-container text-cp-success-on-container hover:bg-cp-success-container-hover' : 'bg-cp-fill-quaternary text-cp-text-quaternary hover:bg-cp-fill-tertiary hover:text-cp-text-secondary', ]" :title="updateButtonLabel" @@ -399,7 +399,7 @@ onBeforeUnmount(() => { > 在线 diff --git a/frontend/src/layout/components/SystemUpdateModal/index.vue b/frontend/src/layout/components/SystemUpdateModal/index.vue index cecc6a278..b241d661b 100644 --- a/frontend/src/layout/components/SystemUpdateModal/index.vue +++ b/frontend/src/layout/components/SystemUpdateModal/index.vue @@ -257,7 +257,7 @@ watch(

{{ updateError || updateInfo?.warning }}

diff --git a/frontend/src/layout/components/SystemUpdateModal/presenter.ts b/frontend/src/layout/components/SystemUpdateModal/presenter.ts index 20f41cbd9..db55081ee 100644 --- a/frontend/src/layout/components/SystemUpdateModal/presenter.ts +++ b/frontend/src/layout/components/SystemUpdateModal/presenter.ts @@ -47,7 +47,7 @@ function resolveStatus(input: SystemUpdatePresentationInput) { return { label: input.restarting ? '重启中' : '更新中', icon: RefreshCw, - badge: 'bg-cp-info-bg text-cp-info-text-on-bg', + badge: 'bg-cp-info-container text-cp-info-on-container', iconClass: 'text-cp-info', } } @@ -55,7 +55,7 @@ function resolveStatus(input: SystemUpdatePresentationInput) { return { label: '异常', icon: XCircle, - badge: 'bg-cp-error-bg text-cp-error-text-on-bg', + badge: 'bg-cp-error-container text-cp-error-on-container', iconClass: 'text-cp-error', } } @@ -63,7 +63,7 @@ function resolveStatus(input: SystemUpdatePresentationInput) { return { label: input.updateSuccess ? '已更新' : input.hasUpdate ? '有新版本' : '已是最新', icon: input.hasUpdate ? ArrowUpCircle : CheckCircle2, - badge: 'bg-cp-success-bg text-cp-success-text-on-bg', + badge: 'bg-cp-success-container text-cp-success-on-container', iconClass: 'text-cp-success', } } diff --git a/frontend/src/styles/index.css b/frontend/src/styles/index.css index 3324fde42..5eb4bd3af 100644 --- a/frontend/src/styles/index.css +++ b/frontend/src/styles/index.css @@ -47,8 +47,8 @@ --color-cp-text-light-solid: var(--cp-color-text-light-solid); /* 颜色 · 主色与链接 */ - --color-cp-primary-bg: var(--cp-color-primary-bg); - --color-cp-primary-bg-hover: var(--cp-color-primary-bg-hover); + --color-cp-primary-container: var(--cp-color-primary-container); + --color-cp-primary-container-hover: var(--cp-color-primary-container-hover); --color-cp-primary-border: var(--cp-color-primary-border); --color-cp-primary-border-hover: var(--cp-color-primary-border-hover); --color-cp-primary-hover: var(--cp-color-primary-hover); @@ -56,15 +56,16 @@ --color-cp-primary-active: var(--cp-color-primary-active); --color-cp-primary-text-hover: var(--cp-color-primary-text-hover); --color-cp-primary-text: var(--cp-color-primary-text); + --color-cp-primary-on-container: var(--cp-color-primary-on-container); --color-cp-primary-text-active: var(--cp-color-primary-text-active); --color-cp-link: var(--cp-color-link); --color-cp-link-hover: var(--cp-color-link-hover); --color-cp-link-active: var(--cp-color-link-active); /* 颜色 · 语义 */ - --color-cp-info-bg: var(--cp-color-info-bg); - --color-cp-info-bg-hover: var(--cp-color-info-bg-hover); - --color-cp-info-bg-active: var(--cp-color-info-bg-active); + --color-cp-info-container: var(--cp-color-info-container); + --color-cp-info-container-hover: var(--cp-color-info-container-hover); + --color-cp-info-container-active: var(--cp-color-info-container-active); --color-cp-info-border: var(--cp-color-info-border); --color-cp-info-border-hover: var(--cp-color-info-border-hover); --color-cp-info-hover: var(--cp-color-info-hover); @@ -72,11 +73,11 @@ --color-cp-info-active: var(--cp-color-info-active); --color-cp-info-text-hover: var(--cp-color-info-text-hover); --color-cp-info-text: var(--cp-color-info-text); - --color-cp-info-text-on-bg: var(--cp-color-info-text-on-bg); + --color-cp-info-on-container: var(--cp-color-info-on-container); --color-cp-info-text-active: var(--cp-color-info-text-active); - --color-cp-success-bg: var(--cp-color-success-bg); - --color-cp-success-bg-hover: var(--cp-color-success-bg-hover); - --color-cp-success-bg-active: var(--cp-color-success-bg-active); + --color-cp-success-container: var(--cp-color-success-container); + --color-cp-success-container-hover: var(--cp-color-success-container-hover); + --color-cp-success-container-active: var(--cp-color-success-container-active); --color-cp-success-border: var(--cp-color-success-border); --color-cp-success-border-hover: var(--cp-color-success-border-hover); --color-cp-success-hover: var(--cp-color-success-hover); @@ -84,11 +85,11 @@ --color-cp-success-active: var(--cp-color-success-active); --color-cp-success-text-hover: var(--cp-color-success-text-hover); --color-cp-success-text: var(--cp-color-success-text); - --color-cp-success-text-on-bg: var(--cp-color-success-text-on-bg); + --color-cp-success-on-container: var(--cp-color-success-on-container); --color-cp-success-text-active: var(--cp-color-success-text-active); - --color-cp-warning-bg: var(--cp-color-warning-bg); - --color-cp-warning-bg-hover: var(--cp-color-warning-bg-hover); - --color-cp-warning-bg-active: var(--cp-color-warning-bg-active); + --color-cp-warning-container: var(--cp-color-warning-container); + --color-cp-warning-container-hover: var(--cp-color-warning-container-hover); + --color-cp-warning-container-active: var(--cp-color-warning-container-active); --color-cp-warning-border: var(--cp-color-warning-border); --color-cp-warning-border-hover: var(--cp-color-warning-border-hover); --color-cp-warning-hover: var(--cp-color-warning-hover); @@ -96,11 +97,11 @@ --color-cp-warning-active: var(--cp-color-warning-active); --color-cp-warning-text-hover: var(--cp-color-warning-text-hover); --color-cp-warning-text: var(--cp-color-warning-text); - --color-cp-warning-text-on-bg: var(--cp-color-warning-text-on-bg); + --color-cp-warning-on-container: var(--cp-color-warning-on-container); --color-cp-warning-text-active: var(--cp-color-warning-text-active); - --color-cp-error-bg: var(--cp-color-error-bg); - --color-cp-error-bg-hover: var(--cp-color-error-bg-hover); - --color-cp-error-bg-active: var(--cp-color-error-bg-active); + --color-cp-error-container: var(--cp-color-error-container); + --color-cp-error-container-hover: var(--cp-color-error-container-hover); + --color-cp-error-container-active: var(--cp-color-error-container-active); --color-cp-error-border: var(--cp-color-error-border); --color-cp-error-border-hover: var(--cp-color-error-border-hover); --color-cp-error-hover: var(--cp-color-error-hover); @@ -108,46 +109,46 @@ --color-cp-error-active: var(--cp-color-error-active); --color-cp-error-text-hover: var(--cp-color-error-text-hover); --color-cp-error-text: var(--cp-color-error-text); - --color-cp-error-text-on-bg: var(--cp-color-error-text-on-bg); + --color-cp-error-on-container: var(--cp-color-error-on-container); --color-cp-error-text-active: var(--cp-color-error-text-active); /* 颜色 · 预设(色系按字母排序,角色顺序固定) */ - --color-cp-blue-bg: var(--cp-color-blue-bg); - --color-cp-blue-bg-strong: var(--cp-color-blue-bg-strong); + --color-cp-blue-container: var(--cp-color-blue-container); + --color-cp-blue-container-strong: var(--cp-color-blue-container-strong); --color-cp-blue-border: var(--cp-color-blue-border); --color-cp-blue-solid: var(--cp-color-blue-solid); --color-cp-blue-text: var(--cp-color-blue-text); - --color-cp-blue-text-on-bg: var(--cp-color-blue-text-on-bg); - --color-cp-cyan-bg: var(--cp-color-cyan-bg); - --color-cp-cyan-bg-strong: var(--cp-color-cyan-bg-strong); + --color-cp-blue-on-container: var(--cp-color-blue-on-container); + --color-cp-cyan-container: var(--cp-color-cyan-container); + --color-cp-cyan-container-strong: var(--cp-color-cyan-container-strong); --color-cp-cyan-border: var(--cp-color-cyan-border); --color-cp-cyan-solid: var(--cp-color-cyan-solid); --color-cp-cyan-text: var(--cp-color-cyan-text); - --color-cp-cyan-text-on-bg: var(--cp-color-cyan-text-on-bg); - --color-cp-green-bg: var(--cp-color-green-bg); - --color-cp-green-bg-strong: var(--cp-color-green-bg-strong); + --color-cp-cyan-on-container: var(--cp-color-cyan-on-container); + --color-cp-green-container: var(--cp-color-green-container); + --color-cp-green-container-strong: var(--cp-color-green-container-strong); --color-cp-green-border: var(--cp-color-green-border); --color-cp-green-solid: var(--cp-color-green-solid); --color-cp-green-text: var(--cp-color-green-text); - --color-cp-green-text-on-bg: var(--cp-color-green-text-on-bg); - --color-cp-orange-bg: var(--cp-color-orange-bg); - --color-cp-orange-bg-strong: var(--cp-color-orange-bg-strong); + --color-cp-green-on-container: var(--cp-color-green-on-container); + --color-cp-orange-container: var(--cp-color-orange-container); + --color-cp-orange-container-strong: var(--cp-color-orange-container-strong); --color-cp-orange-border: var(--cp-color-orange-border); --color-cp-orange-solid: var(--cp-color-orange-solid); --color-cp-orange-text: var(--cp-color-orange-text); - --color-cp-orange-text-on-bg: var(--cp-color-orange-text-on-bg); - --color-cp-purple-bg: var(--cp-color-purple-bg); - --color-cp-purple-bg-strong: var(--cp-color-purple-bg-strong); + --color-cp-orange-on-container: var(--cp-color-orange-on-container); + --color-cp-purple-container: var(--cp-color-purple-container); + --color-cp-purple-container-strong: var(--cp-color-purple-container-strong); --color-cp-purple-border: var(--cp-color-purple-border); --color-cp-purple-solid: var(--cp-color-purple-solid); --color-cp-purple-text: var(--cp-color-purple-text); - --color-cp-purple-text-on-bg: var(--cp-color-purple-text-on-bg); - --color-cp-red-bg: var(--cp-color-red-bg); - --color-cp-red-bg-strong: var(--cp-color-red-bg-strong); + --color-cp-purple-on-container: var(--cp-color-purple-on-container); + --color-cp-red-container: var(--cp-color-red-container); + --color-cp-red-container-strong: var(--cp-color-red-container-strong); --color-cp-red-border: var(--cp-color-red-border); --color-cp-red-solid: var(--cp-color-red-solid); --color-cp-red-text: var(--cp-color-red-text); - --color-cp-red-text-on-bg: var(--cp-color-red-text-on-bg); + --color-cp-red-on-container: var(--cp-color-red-on-container); /* 颜色 · 数据 */ --color-cp-activity-level-0: var(--cp-activity-level-0); diff --git a/frontend/src/theme/core/tokens.ts b/frontend/src/theme/core/tokens.ts index c768c5bb3..b8a1d2d85 100644 --- a/frontend/src/theme/core/tokens.ts +++ b/frontend/src/theme/core/tokens.ts @@ -28,9 +28,9 @@ const DIRECT_THEME_MAP_KEYS = [ ] as const satisfies readonly DirectThemeMapKey[] const FUNCTIONAL_TOKEN_ROLES = [ - ['background', '-bg'], - ['backgroundHover', '-bg-hover'], - ['backgroundActive', '-bg-active'], + ['container', '-container'], + ['containerHover', '-container-hover'], + ['containerActive', '-container-active'], ['border', '-border'], ['borderHover', '-border-hover'], ['hover', '-hover'], @@ -38,22 +38,22 @@ const FUNCTIONAL_TOKEN_ROLES = [ ['active', '-active'], ['textHover', '-text-hover'], ['text', '-text'], - ['textOnBackground', '-text-on-bg'], + ['onContainer', '-on-container'], ['textActive', '-text-active'], ] as const satisfies readonly (readonly [keyof FunctionalColorMap, FunctionalTokenSuffix])[] const PRESET_TOKEN_ROLES = [ - ['background', 'bg'], - ['backgroundStrong', 'bg-strong'], + ['container', 'container'], + ['containerStrong', 'container-strong'], ['border', 'border'], ['solid', 'solid'], ['text', 'text'], - ['textOnBackground', 'text-on-bg'], + ['onContainer', 'on-container'], ] as const satisfies readonly (readonly [keyof PresetColorRoleMap, PresetTokenSuffix])[] const CONTROL_TOKEN_BINDINGS = [ - ['--cp-control-item-bg-active', 'colorPrimaryBg'], - ['--cp-control-item-bg-active-hover', 'colorPrimaryBgHover'], + ['--cp-control-item-bg-active', 'colorPrimaryContainer'], + ['--cp-control-item-bg-active-hover', 'colorPrimaryContainerHover'], ['--cp-control-outline', 'colorPrimaryBorder'], ] as const satisfies readonly (readonly [ControlTokenName, keyof ThemePrimaryMap])[] diff --git a/frontend/src/theme/derive/colors.ts b/frontend/src/theme/derive/colors.ts index 1d9b6f836..128cfce17 100644 --- a/frontend/src/theme/derive/colors.ts +++ b/frontend/src/theme/derive/colors.ts @@ -98,8 +98,8 @@ export function deriveThemePrimaryMap( ) return { - colorPrimaryBg: roles.background, - colorPrimaryBgHover: roles.backgroundHover, + colorPrimaryContainer: roles.container, + colorPrimaryContainerHover: roles.containerHover, colorPrimaryBorder: roles.border, colorPrimaryBorderHover: roles.borderHover, colorPrimaryHover: roles.hover, @@ -107,6 +107,7 @@ export function deriveThemePrimaryMap( colorPrimaryActive: roles.active, colorPrimaryTextHover: roles.textHover, colorPrimaryText: roles.text, + colorPrimaryOnContainer: roles.onContainer, colorPrimaryTextActive: roles.textActive, colorTextLightSolid: LIGHT_FOREGROUND, } @@ -210,7 +211,7 @@ export function deriveThemeDataMap( aliases: ThemeAliasMap, semantics: ThemeSemanticMap, ): ThemeDataMap { - const activityBase = semantics.success.background + const activityBase = semantics.success.container const activitySolid = semantics.success.color return { @@ -454,10 +455,10 @@ function deriveColorRoleMap( const color = resolve(recipe.color) const hover = resolve(recipe.hover) const active = resolve(recipe.active) - const background = mix(containerBg, color, recipe.backgroundMix) - const backgroundHover = mix(containerBg, hover, recipe.backgroundHoverMix) - const backgroundActive = mix(containerBg, active, recipe.backgroundActiveMix) - const semanticBackgrounds = [background, backgroundHover, backgroundActive] + const container = mix(containerBg, color, recipe.containerMix) + const containerHover = mix(containerBg, hover, recipe.containerHoverMix) + const containerActive = mix(containerBg, active, recipe.containerActiveMix) + const semanticContainers = [container, containerHover, containerActive] const resolveText = ( source: ThemePaletteSource, backgrounds: string | readonly string[] = textBackgrounds, @@ -470,9 +471,9 @@ function deriveColorRoleMap( } return { - background, - backgroundHover, - backgroundActive, + container, + containerHover, + containerActive, border: ensureContrast(mix(containerBg, color, recipe.borderMix), containerBg, 3), borderHover: ensureContrast(mix(containerBg, hover, recipe.borderHoverMix), containerBg, 3), hover: recipe.hoverContrast === undefined @@ -484,15 +485,15 @@ function deriveColorRoleMap( : ensureContrast(active, containerBg, recipe.activeContrast), textHover: resolveText(recipe.textHover), text: resolveText(recipe.text), - textOnBackground: resolveText( - recipe.textOnBackground ?? recipe.text, - semanticBackgrounds, + onContainer: resolveText( + recipe.onContainer ?? recipe.text, + semanticContainers, ), textActive: resolveText(recipe.textActive), } } -/** 背景、边框和实心色对齐 Colorful Tag;文字在当前 Surface 上保持可读。 */ +/** 容器、边框和实心色对齐 Colorful Tag;文字在当前 Surface 上保持可读。 */ function derivePresetColorRoleMap( palette: readonly string[], containerBg: string, @@ -501,20 +502,20 @@ function derivePresetColorRoleMap( const color = (step: number): string => normalizeHexColor(palette[step - 1]) ?? DEFAULT_CUSTOM_THEME_COLOR const solid = color(recipe.solid) - const background = mix(containerBg, solid, recipe.backgroundMix) - const backgroundStrong = mix(containerBg, solid, recipe.backgroundStrongMix) + const container = mix(containerBg, solid, recipe.containerMix) + const containerStrong = mix(containerBg, solid, recipe.containerStrongMix) const text = color(recipe.text) - const textOnBackground = color(recipe.textOnBackground) + const onContainer = color(recipe.onContainer) const toneText = (value: string): string => recipe.minimumTextLightness === undefined ? value : ensureLightness(value, recipe.minimumTextLightness) return { - background, - backgroundStrong, + container, + containerStrong, border: ensureContrast(mix(containerBg, solid, recipe.borderMix), containerBg, 3), solid, text: ensureContrast(toneText(text), containerBg, 4.5), - textOnBackground: ensureContrast(toneText(textOnBackground), [background, backgroundStrong], 4.5), + onContainer: ensureContrast(toneText(onContainer), [container, containerStrong], 4.5), } } diff --git a/frontend/src/theme/derive/components.ts b/frontend/src/theme/derive/components.ts index f73f578f8..d3b1a44a9 100644 --- a/frontend/src/theme/derive/components.ts +++ b/frontend/src/theme/derive/components.ts @@ -150,7 +150,7 @@ function deriveDarkComponentMap( error: FunctionalColorMap, shadowStrength: number, ): SurfaceComponentMap { - const inputOutlineColor = 'var(--cp-color-primary-bg-hover)' + const inputOutlineColor = 'var(--cp-color-primary-container-hover)' const appearanceInfluence = deriveComponentAppearanceInfluence( surfaces.colorBgContainer, DARK_CONTAINER_BASE, @@ -167,7 +167,7 @@ function deriveDarkComponentMap( mix(surfaces.colorBgContainer, surfaces.colorBgElevated, 0.4), appearanceInfluence, ), - inputErrorActiveBg: error.background, + inputErrorActiveBg: error.container, brandMarkBg: surfaces.colorBgElevated, cardBg: surfaces.colorBgContainer, modalBg: surfaces.colorBgContainer, @@ -175,7 +175,7 @@ function deriveDarkComponentMap( tableRowBg: surfaces.colorBgContainer, tableRowStripeBg: aliases.colorFillAlter, tableRowHoverBg: surfaces.colorBgTextHover, - tableRowSelectedBg: primary.colorPrimaryBg, + tableRowSelectedBg: primary.colorPrimaryContainer, progressRemainingColor: mix(surfaces.colorBgContainer, surfaces.colorBorderSecondary, 0.92), layoutSiderBg: surfaces.colorBgContainer, cardShadow: scaleShadowAlpha(`0 18px 34px -26px ${withAlpha(BLACK, 0.64)}`, shadowStrength), @@ -199,7 +199,7 @@ function deriveLightComponentMap( error: FunctionalColorMap, shadowStrength: number, ): SurfaceComponentMap { - const inputOutlineColor = 'var(--cp-color-primary-bg-hover)' + const inputOutlineColor = 'var(--cp-color-primary-container-hover)' const appearanceInfluence = deriveComponentAppearanceInfluence( surfaces.colorBgContainer, LIGHT_CONTAINER_BASE, @@ -220,7 +220,7 @@ function deriveLightComponentMap( aliases.colorFillAlter, appearanceInfluence, ), - inputErrorActiveBg: error.background, + inputErrorActiveBg: error.container, brandMarkBg: surfaces.colorBgSpotlight, cardBg: surfaces.colorBgContainer, modalBg: surfaces.colorBgContainer, @@ -228,7 +228,7 @@ function deriveLightComponentMap( tableRowBg: surfaces.colorBgContainer, tableRowStripeBg: aliases.colorFillAlter, tableRowHoverBg: surfaces.colorBgTextHover, - tableRowSelectedBg: primary.colorPrimaryBg, + tableRowSelectedBg: primary.colorPrimaryContainer, progressRemainingColor: surfaces.colorBorderSecondary, layoutSiderBg: surfaces.colorBgContainer, cardShadow: scaleShadowAlpha(`0 10px 22px -18px ${withAlpha(LIGHT_SHADOW_BASE, 0.08)}`, shadowStrength), diff --git a/frontend/src/theme/derive/roles.ts b/frontend/src/theme/derive/roles.ts index b0aac78c3..e7c29aa75 100644 --- a/frontend/src/theme/derive/roles.ts +++ b/frontend/src/theme/derive/roles.ts @@ -13,9 +13,9 @@ export const THEME_COLOR_ROLE_RECIPES = { textHover: 5, text: 6, textActive: 7, - backgroundMix: 0.09, - backgroundHoverMix: 0.14, - backgroundActiveMix: 0.18, + containerMix: 0.09, + containerHoverMix: 0.14, + containerActiveMix: 0.18, borderMix: 0.46, borderHoverMix: 0.56, }, @@ -25,11 +25,11 @@ export const THEME_COLOR_ROLE_RECIPES = { active: 7, textHover: 5, text: 7, - textOnBackground: 6, + onContainer: 6, textActive: 7, - backgroundMix: 0.08, - backgroundHoverMix: 0.12, - backgroundActiveMix: 0.18, + containerMix: 0.08, + containerHoverMix: 0.12, + containerActiveMix: 0.18, borderMix: 0.4, borderHoverMix: 0.5, hoverContrast: 3, @@ -38,9 +38,9 @@ export const THEME_COLOR_ROLE_RECIPES = { preset: { solid: 6, text: 7, - textOnBackground: 7, - backgroundMix: 0.08, - backgroundStrongMix: 0.22, + onContainer: 7, + containerMix: 0.08, + containerStrongMix: 0.22, borderMix: 0.4, }, }, @@ -52,9 +52,9 @@ export const THEME_COLOR_ROLE_RECIPES = { textHover: 8, text: 7, textActive: 6, - backgroundMix: 0.17, - backgroundHoverMix: 0.24, - backgroundActiveMix: 0.3, + containerMix: 0.17, + containerHoverMix: 0.24, + containerActiveMix: 0.3, borderMix: 0.52, borderHoverMix: 0.62, }, @@ -64,11 +64,11 @@ export const THEME_COLOR_ROLE_RECIPES = { active: 6, textHover: 8, text: 7, - textOnBackground: 9, + onContainer: 9, textActive: 10, - backgroundMix: 0.18, - backgroundHoverMix: 0.24, - backgroundActiveMix: 0.3, + containerMix: 0.18, + containerHoverMix: 0.24, + containerActiveMix: 0.3, borderMix: 0.46, borderHoverMix: 0.56, hoverContrast: 3, @@ -77,9 +77,9 @@ export const THEME_COLOR_ROLE_RECIPES = { preset: { solid: 6, text: 8, - textOnBackground: 8, - backgroundMix: 0.18, - backgroundStrongMix: 0.24, + onContainer: 8, + containerMix: 0.18, + containerStrongMix: 0.24, borderMix: 0.46, minimumTextLightness: 0.7, }, diff --git a/frontend/src/theme/types.ts b/frontend/src/theme/types.ts index 4a6229d99..7a5a30f55 100644 --- a/frontend/src/theme/types.ts +++ b/frontend/src/theme/types.ts @@ -90,11 +90,11 @@ export interface ThemeColorRoleRecipe { active: ThemePaletteSource textHover: ThemePaletteSource text: ThemePaletteSource - textOnBackground?: ThemePaletteSource + onContainer?: ThemePaletteSource textActive: ThemePaletteSource - backgroundMix: number - backgroundHoverMix: number - backgroundActiveMix: number + containerMix: number + containerHoverMix: number + containerActiveMix: number borderMix: number borderHoverMix: number hoverContrast?: number @@ -111,16 +111,16 @@ export interface ThemeColorRoleRecipes { export interface ThemePresetColorRoleRecipe { solid: ThemePaletteStep text: ThemePaletteStep - textOnBackground: ThemePaletteStep - backgroundMix: number - backgroundStrongMix: number + onContainer: ThemePaletteStep + containerMix: number + containerStrongMix: number borderMix: number minimumTextLightness?: number } export interface ThemePrimaryMap { - colorPrimaryBg: string - colorPrimaryBgHover: string + colorPrimaryContainer: string + colorPrimaryContainerHover: string colorPrimaryBorder: string colorPrimaryBorderHover: string colorPrimaryHover: string @@ -128,6 +128,7 @@ export interface ThemePrimaryMap { colorPrimaryActive: string colorPrimaryTextHover: string colorPrimaryText: string + colorPrimaryOnContainer: string colorPrimaryTextActive: string colorTextLightSolid: string } @@ -206,16 +207,16 @@ export interface FunctionalColorMap { color: string hover: string active: string - background: string - backgroundHover: string - backgroundActive: string + container: string + containerHover: string + containerActive: string border: string borderHover: string textHover: string /** 语义色在中性表面上的强调文字。 */ text: string - /** 语义色在自身背景上的高对比文字。 */ - textOnBackground: string + /** 语义色容器内文字与图标使用的高对比前景色。 */ + onContainer: string textActive: string } @@ -227,12 +228,12 @@ export interface ThemeSemanticMap { } export interface PresetColorRoleMap { - background: string - backgroundStrong: string + container: string + containerStrong: string border: string solid: string text: string - textOnBackground: string + onContainer: string } export type ThemePresetColorName @@ -305,26 +306,26 @@ export type FunctionalTokenSuffix = '' | '-hover' | '-active' - | '-bg' - | '-bg-hover' - | '-bg-active' + | '-container' + | '-container-hover' + | '-container-active' | '-border' | '-border-hover' | '-text-hover' | '-text' - | '-text-on-bg' + | '-on-container' | '-text-active' type SemanticColorName = Extract export type SemanticTokenName = `--cp-color-${SemanticColorName}${FunctionalTokenSuffix}` export type PresetTokenSuffix - = 'bg' - | 'bg-strong' + = 'container' + | 'container-strong' | 'border' | 'solid' | 'text' - | 'text-on-bg' + | 'on-container' type PresetColorName = Extract export type PresetTokenName = `--cp-color-${PresetColorName}-${PresetTokenSuffix}` diff --git a/frontend/src/views/account-groups/index.vue b/frontend/src/views/account-groups/index.vue index 19e51090e..3cc1c85d7 100644 --- a/frontend/src/views/account-groups/index.vue +++ b/frontend/src/views/account-groups/index.vue @@ -121,7 +121,7 @@ const { allSelected, indeterminate, selectedRowKeys, toggleSelection, toggleAll {{ row.enabled ? '已启用' : '已禁用' }} diff --git a/frontend/src/views/accounts/components/AccountOverviewCards.vue b/frontend/src/views/accounts/components/AccountOverviewCards.vue index faa51b67c..9d60cf8aa 100644 --- a/frontend/src/views/accounts/components/AccountOverviewCards.vue +++ b/frontend/src/views/accounts/components/AccountOverviewCards.vue @@ -44,15 +44,15 @@ const overviewItems = computed(() => [ function overviewIconClass(tone: string) { if (tone === 'success') { - return 'bg-cp-green-bg text-cp-green-text-on-bg' + return 'bg-cp-green-container text-cp-green-on-container' } if (tone === 'warning') { - return 'bg-cp-orange-bg text-cp-orange-text-on-bg' + return 'bg-cp-orange-container text-cp-orange-on-container' } if (tone === 'danger') { - return 'bg-cp-error-bg text-cp-error-text-on-bg' + return 'bg-cp-error-container text-cp-error-on-container' } - return 'bg-cp-blue-bg text-cp-blue-text-on-bg' + return 'bg-cp-blue-container text-cp-blue-on-container' } diff --git a/frontend/src/views/accounts/components/AccountPlanBadge.vue b/frontend/src/views/accounts/components/AccountPlanBadge.vue index cda354d26..9d2683a39 100644 --- a/frontend/src/views/accounts/components/AccountPlanBadge.vue +++ b/frontend/src/views/accounts/components/AccountPlanBadge.vue @@ -15,16 +15,16 @@ const props = withDefaults( ) const planPalettes: Record = { - free: 'bg-cp-cyan-bg text-cp-cyan-text-on-bg', - pro: 'bg-cp-purple-bg-strong text-cp-purple-text-on-bg', - prolite: 'bg-cp-purple-bg text-cp-purple-text-on-bg', + free: 'bg-cp-cyan-container text-cp-cyan-on-container', + pro: 'bg-cp-purple-container-strong text-cp-purple-on-container', + prolite: 'bg-cp-purple-container text-cp-purple-on-container', } const fallbackPalettes = [ - 'bg-cp-blue-bg text-cp-blue-text-on-bg', - 'bg-cp-green-bg text-cp-green-text-on-bg', - 'bg-cp-cyan-bg text-cp-cyan-text-on-bg', - 'bg-cp-orange-bg text-cp-orange-text-on-bg', + 'bg-cp-blue-container text-cp-blue-on-container', + 'bg-cp-green-container text-cp-green-on-container', + 'bg-cp-cyan-container text-cp-cyan-on-container', + 'bg-cp-orange-container text-cp-orange-on-container', ] as const const label = computed(() => props.planType?.trim() || 'Free') diff --git a/frontend/src/views/accounts/components/AccountQuotaPanel/ResetCredits.vue b/frontend/src/views/accounts/components/AccountQuotaPanel/ResetCredits.vue index d32bc75c7..106b25f1d 100644 --- a/frontend/src/views/accounts/components/AccountQuotaPanel/ResetCredits.vue +++ b/frontend/src/views/accounts/components/AccountQuotaPanel/ResetCredits.vue @@ -139,10 +139,10 @@ async function handleConfirmConsume() {
-
- +
+
-

+

上次操作结果待确认

@@ -193,7 +193,7 @@ async function handleConfirmConsume() {

{{ loadError }},请刷新重试。 diff --git a/frontend/src/views/accounts/components/AccountQuotaSummaryCell/Entry.vue b/frontend/src/views/accounts/components/AccountQuotaSummaryCell/Entry.vue index 628ce1a4f..d1697afba 100644 --- a/frontend/src/views/accounts/components/AccountQuotaSummaryCell/Entry.vue +++ b/frontend/src/views/accounts/components/AccountQuotaSummaryCell/Entry.vue @@ -114,7 +114,7 @@ function quotaWindowCode(windowSeconds: number | null, role: AccountQuotaWindow[

{{ item.code }} diff --git a/frontend/src/views/accounts/components/AccountStatusBadge/presenter.ts b/frontend/src/views/accounts/components/AccountStatusBadge/presenter.ts index 6dd7546de..37fd95a92 100644 --- a/frontend/src/views/accounts/components/AccountStatusBadge/presenter.ts +++ b/frontend/src/views/accounts/components/AccountStatusBadge/presenter.ts @@ -53,26 +53,26 @@ const statusStyles: Record = { success: { text: 'text-cp-success-text', dot: 'bg-cp-success', - badge: 'bg-cp-success-bg text-cp-success-text-on-bg', - icon: 'bg-cp-success-bg text-cp-success-text-on-bg', + badge: 'bg-cp-success-container text-cp-success-on-container', + icon: 'bg-cp-success-container text-cp-success-on-container', }, danger: { text: 'text-cp-error-text', dot: 'bg-cp-error', - badge: 'bg-cp-error-bg text-cp-error-text-on-bg', - icon: 'bg-cp-error-bg text-cp-error-text-on-bg', + badge: 'bg-cp-error-container text-cp-error-on-container', + icon: 'bg-cp-error-container text-cp-error-on-container', }, warning: { text: 'text-cp-warning-text', dot: 'bg-cp-warning', - badge: 'bg-cp-warning-bg text-cp-warning-text-on-bg', - icon: 'bg-cp-warning-bg text-cp-warning-text-on-bg', + badge: 'bg-cp-warning-container text-cp-warning-on-container', + icon: 'bg-cp-warning-container text-cp-warning-on-container', }, info: { text: 'text-cp-info-text', dot: 'bg-cp-info', - badge: 'bg-cp-info-bg text-cp-info-text-on-bg', - icon: 'bg-cp-info-bg text-cp-info-text-on-bg', + badge: 'bg-cp-info-container text-cp-info-on-container', + icon: 'bg-cp-info-container text-cp-info-on-container', }, normal: { text: 'text-cp-text-secondary', diff --git a/frontend/src/views/accounts/components/AccountUsagePanel.vue b/frontend/src/views/accounts/components/AccountUsagePanel.vue index 18f449cc8..a6626918b 100644 --- a/frontend/src/views/accounts/components/AccountUsagePanel.vue +++ b/frontend/src/views/accounts/components/AccountUsagePanel.vue @@ -40,32 +40,32 @@ const modelUsageColumns = defineTableColumns([ 当前额度窗口
-
- 输入 +
+ 输入 {{ account.usage.inputTokensDisplay }}
-
- 输出 +
+ 输出 {{ account.usage.outputTokensDisplay }}
-
- 缓存 +
+ 缓存 {{ account.usage.cachedTokensDisplay }}
-
- 推理 +
+ 推理 {{ account.usage.reasoningTokensDisplay }}
-
- 读取 +
+ 读取 {{ account.usage.readTokensDisplay }} diff --git a/frontend/src/views/accounts/composables/useAccountConnectionTest.ts b/frontend/src/views/accounts/composables/useAccountConnectionTest.ts index 06c7214fb..1f48897a6 100644 --- a/frontend/src/views/accounts/composables/useAccountConnectionTest.ts +++ b/frontend/src/views/accounts/composables/useAccountConnectionTest.ts @@ -191,7 +191,7 @@ export function useAccountConnectionTest(options: { reload: () => Promise Promise Promise export function stableVisualIndex(value: unknown, length: number): number { diff --git a/frontend/src/views/api-keys/components/ApiKeyCreateModal.vue b/frontend/src/views/api-keys/components/ApiKeyCreateModal.vue index c27381ac3..e0ce8ed62 100644 --- a/frontend/src/views/api-keys/components/ApiKeyCreateModal.vue +++ b/frontend/src/views/api-keys/components/ApiKeyCreateModal.vue @@ -110,8 +110,8 @@ const title = computed(() => props.editing ? '编辑 API Key' : '创建 API Key' size="md" >
-
-

+

+

该密钥具有网关访问权限,请仅发送给可信调用方

diff --git a/frontend/src/views/api-keys/components/ApiKeyScopeCell.vue b/frontend/src/views/api-keys/components/ApiKeyScopeCell.vue index f22ccef3e..58c9ac272 100644 --- a/frontend/src/views/api-keys/components/ApiKeyScopeCell.vue +++ b/frontend/src/views/api-keys/components/ApiKeyScopeCell.vue @@ -11,7 +11,7 @@ defineProps<{