diff --git a/BitFun-Installer/src/theme/installerThemesData.ts b/BitFun-Installer/src/theme/installerThemesData.ts index 3773c78043..50f8959a56 100644 --- a/BitFun-Installer/src/theme/installerThemesData.ts +++ b/BitFun-Installer/src/theme/installerThemesData.ts @@ -47,6 +47,9 @@ const DEFAULT_RAMP_ALPHAS: RampAlphas = ['0.04', '0.08', '0.15', '0.25', '0.4']; const DEFAULT_BLUE_RGB = '96, 165, 250'; const DEFAULT_BLUE_500 = '#60a5fa'; const DEFAULT_BLUE_600 = '#3b82f6'; +const DARK_CARD_BACKGROUND = '#121214'; +const DARK_CARD_SURFACE = '#1a1c1e'; +const MIDNIGHT_CARD_BACKGROUND = '#2b2d30'; function alpha(rgb: string, opacity: string): string { return `rgba(${rgb}, ${opacity})`; @@ -167,8 +170,8 @@ export const THEMES: InstallerTheme[] = [ name: 'Dark', type: 'dark', background: { - primary: '#121214', - secondary: '#1a1c1e', + primary: DARK_CARD_BACKGROUND, + secondary: DARK_CARD_SURFACE, }, accentRgb: DEFAULT_BLUE_RGB, accent500: DEFAULT_BLUE_500, @@ -187,7 +190,7 @@ export const THEMES: InstallerTheme[] = [ id: 'bitfun-midnight', name: 'Midnight', type: 'dark', - background: { primary: '#2b2d30', secondary: '#1e1f22' }, + background: { primary: MIDNIGHT_CARD_BACKGROUND, secondary: DARK_CARD_SURFACE }, accentRgb: DEFAULT_BLUE_RGB, accent500: DEFAULT_BLUE_500, accent600: DEFAULT_BLUE_600, @@ -215,7 +218,7 @@ export const THEMES: InstallerTheme[] = [ id: 'bitfun-china-night', name: 'Ink Night', type: 'dark', - background: { primary: '#1a1814', secondary: '#212019' }, + background: { primary: '#1a1814', secondary: DARK_CARD_SURFACE }, accentRgb: '115, 165, 204', accent500: '#73a5cc', accent600: '#5a8bb3', @@ -229,7 +232,7 @@ export const THEMES: InstallerTheme[] = [ id: 'bitfun-cyber', name: 'Cyber', type: 'dark', - background: { primary: '#0e0e10', secondary: '#151515' }, + background: { primary: '#0e0e10', secondary: DARK_CARD_SURFACE }, accentRgb: '0, 230, 255', accent500: '#00e6ff', accent600: '#00ccff', @@ -243,7 +246,7 @@ export const THEMES: InstallerTheme[] = [ id: 'bitfun-tokyo-night', name: 'Tokyo Night', type: 'dark', - background: { primary: '#1a1b26', secondary: '#16161e' }, + background: { primary: '#1a1b26', secondary: DARK_CARD_SURFACE }, accentRgb: '122, 162, 247', accent500: '#7aa2f7', accent600: '#6183bb', @@ -257,7 +260,7 @@ export const THEMES: InstallerTheme[] = [ id: 'bitfun-slate', name: 'Slate', type: 'dark', - background: { primary: '#1a1c1e' }, + background: { primary: DARK_CARD_SURFACE }, accentRgb: '122, 176, 238', accent500: '#7ab0ee', accent600: '#689ad8', diff --git a/docs/architecture/theme-token-optimization.md b/docs/architecture/theme-token-optimization.md index 08de6a2b79..fd74894ae8 100644 --- a/docs/architecture/theme-token-optimization.md +++ b/docs/architecture/theme-token-optimization.md @@ -152,7 +152,7 @@ Mermaid、Monaco/editor、Prism syntax、terminal ANSI、language identity 和 U registry。Mobile Web 和 Installer 已纳入同一审计口径,但各自使用独立 baseline, 避免移动端或安装器的独立 token 被误算为 web-ui 游离 key。 -`356` 个 web-ui 唯一颜色是前端生产文件的全域审计数,不是普通 app UI 的色值预算。 +`346` 个 web-ui 唯一颜色是前端生产文件的全域审计数,不是普通 app UI 的色值预算。 其中包含主题 preset、token contract、Mermaid、Monaco/editor、terminal、syntax、 language identity 和 UI exception 等专用 palette。language identity 已收敛为 8 个大类身份色, 不再按每种语言或文件类型保留独立色值。真正需要继续压缩的是这些专用域 @@ -178,8 +178,8 @@ label、icon、扩展名或文件名之一,不允许构建只靠颜色区分 | 忽略的测试文件数 | 224 | | 忽略的构建生成文件数 | 1 | | 包含颜色字面量的文件数 | 25 | -| 颜色字面量出现次数 | 553 | -| 唯一颜色字面量数量 | 356 | +| 颜色字面量出现次数 | 538 | +| 唯一颜色字面量数量 | 346 | | 组件或非 token 文件中的颜色出现次数 | 0 | | 组件或非 token 唯一颜色数量 | 0 | | App UI 颜色出现次数 | 0 | @@ -191,15 +191,15 @@ label、icon、扩展名或文件名之一,不允许构建只靠颜色区分 | 普通组件肉眼不可区分 near color pair | 0 | | 普通组件需证据复核的 near color pair | 0 | | 专用域肉眼不可区分 near color pair | 0 | -| 专用域需证据复核的 near color pair | 26 | +| 专用域需证据复核的 near color pair | 13 | 跨 root 基线必须分别看待;这些数字不是互相累加后的单一上限: | root | 颜色出现次数 | 唯一颜色 | App UI raw | fallback var | unresolved / non-contract key | dynamic family | 说明 | | --- | ---: | ---: | ---: | ---: | ---: | ---: | --- | -| `src/web-ui/src` | 553 | 356 | 0 | 0 | 0 | 13 | 主应用完整主题、专用 palette、widget payload 和 editor/terminal/Mermaid 域;UI exception、syntax、language identity 与 boundary fallback 已收敛到小型语义 palette,未读取的 git 同义 runtime/static key 已退役。 | +| `src/web-ui/src` | 538 | 346 | 0 | 0 | 0 | 13 | 主应用完整主题、专用 palette、widget payload 和 editor/terminal/Mermaid 域;UI exception、syntax、language identity 与 boundary fallback 已收敛到小型语义 palette,未读取的 git 同义 runtime/static key 已退役。 | | `src/mobile-web/src` | 35 | 30 | 0 | 0 | 0 | 3 | mobile-web 图片缩略图关闭按钮已读取 `--color-static-white`,普通 app UI raw 归零。 | -| `BitFun-Installer/src` | 81 | 66 | 0 | 0 | 0 | 1 | 安装器主题数据保留主题卡可见的 primary/secondary background、accent、text 和状态反馈;runtime 只导出实际消费的 accent family、基础 text/border/element/status key,不复制主应用 purple/info/tooltip 等完整主题面。 | +| `BitFun-Installer/src` | 76 | 62 | 0 | 0 | 0 | 1 | 安装器主题数据保留主题卡可见的 primary/secondary background、accent、text 和状态反馈;runtime 只导出实际消费的 accent family、基础 text/border/element/status key,不复制主应用 purple/info/tooltip 等完整主题面。 | CLI/TUI 使用独立审计,不参与 CSS var root 计数: @@ -207,17 +207,17 @@ CLI/TUI 使用独立审计,不参与 CSS var root 计数: | --- | ---: | | preset 文件数 | 6 | | preset 颜色出现次数 | 306 | -| preset 唯一色数 | 122 | +| preset 唯一色数 | 118 | | runtime-consumed preset 颜色出现次数 | 114 | -| runtime-consumed preset 唯一色数 | 79 | +| runtime-consumed preset 唯一色数 | 77 | | OpenCode compatibility-declared preset 颜色出现次数 | 192 | -| OpenCode compatibility-declared preset 唯一色数 | 89 | +| OpenCode compatibility-declared preset 唯一色数 | 87 | | Rust fallback `Color::Rgb` 出现次数 | 44 | | Rust fallback 唯一色数 | 32 | -| CLI/TUI 总唯一色数 | 152 | -| CLI/TUI runtime 唯一色数 | 109 | -| preset 需证据复核 near pair | 4 | -| runtime-consumed preset 需证据复核 near pair | 2 | +| CLI/TUI 总唯一色数 | 148 | +| CLI/TUI runtime 唯一色数 | 107 | +| preset 需证据复核 near pair | 0 | +| runtime-consumed preset 需证据复核 near pair | 0 | | OpenCode compatibility-declared preset near pair | 0 | | Rust fallback near pair | 0 | @@ -251,7 +251,7 @@ CLI/TUI 使用独立审计,不参与 CSS var root 计数: | active surface token rename key | 0 | 防止 `--primary-color`、`--operation-color`、`--delay`、`--um-*` 等旧局部 key 回流 | | active surface token rename occurrences | 0 | 防止旧 key 在 SCSS、CSS 或 TSX inline style 中被重新定义或读取 | | surface token rename missing canonical | 0 | 防止 rename registry 指向不存在的 canonical key | -| generated widget payload key | 94 | widget iframe 对外主题变量 allowlist,作为外部边界单独预算,不计入内部 alias 读取;payload 只保留需要随宿主主题变化的 canonical 颜色、文本、surface、形状、间距、字体、动效和 button component token 子集,host 内部、静态黑白 overlay 或历史兼容 key 由 iframe fallback/static shell 派生 | +| generated widget payload key | 80 | widget iframe 对外主题变量 allowlist,作为外部边界单独预算,不计入内部 alias 读取;payload 只保留需要随宿主主题变化的 canonical 颜色、文本、surface、形状、间距、字体、动效和 button component token 子集,host 内部、静态黑白 overlay、派生 accent/status/border/radius key 或历史兼容 key 由 iframe fallback/static shell 派生 | | generated widget button payload | 18 | Cyber/Tokyo 等主题把 button border、shadow、transform 作为主题身份的一部分;这些 key 不能仅因 iframe static shell 存在默认值就移除,否则会让生成式 widget 内按钮失去宿主主题的高对比/发光状态。后续只有证明所有内置主题 resolved button 输出等价时才可继续缩减 | | generated widget payload compatibility alias | 0 | payload 不再直接暴露 legacy alias;历史生成内容通过 iframe 内 alias fallback 读取 canonical key | | generated widget payload compatibility family key | 0 | payload 不直接暴露旧 `--radius-*`、`--spacing-*`;必要的 canonical 尺寸值由 payload 子集或 iframe fallback 保留 | @@ -276,11 +276,11 @@ PR 通过而放宽 `appUi`、fallback、unresolved、non-contract 或 dynamic fa | 区域 | 当前出现次数 | 当前唯一色数 | 说明 | | --- | ---: | ---: | --- | -| Theme presets | 171 | 120 | 主题个性与 palette 映射;跨主题深色 neutral、弱文本、非状态浅色背景和同概念 success 色已收敛;相邻 surface、主题识别主背景、状态色和 editor lineHighlight 继续保留 | -| Token contracts | 113 | 101 | `tokens.scss` 等静态契约根;黑白 overlay alpha stop 继续保留相邻状态层级,不按数值相近强行合并 | -| Editor | 52 | 48 | Monaco/editor 专用域,不能直接泛化到 app token;被动 selection/word highlight 的重复弱高亮已收敛 | -| Mermaid | 91 | 73 | Mermaid 专用渲染域 | -| Theme runtime | 30 | 29 | `ThemeService.ts` 运行时注入;黑白 overlay alpha 与静态 token、payload shell 保持相同 stop,避免 early render 与 runtime 状态层级漂移 | +| Theme presets | 171 | 119 | 主题个性与 palette 映射;跨主题深色 neutral、弱文本、非状态浅色背景和同概念 success 色已收敛;相邻 surface、主题识别主背景、状态色和 editor lineHighlight 继续保留 | +| Token contracts | 110 | 98 | `tokens.scss` 等静态契约根;黑白 overlay alpha stop 继续保留相邻状态层级,不按数值相近强行合并 | +| Editor | 52 | 48 | Monaco/editor 专用域,不能直接泛化到 app token;被动 selection/word highlight 已收敛,但 diff text/line/gutter 继续保留用户可见层级 | +| Mermaid | 82 | 65 | Mermaid 专用渲染域;light status fallback 已改读 app semantic status token,critical/error 背景弱重复已收敛,note 文本保留专用高对比值 | +| Theme runtime | 27 | 26 | `ThemeService.ts` 运行时注入;黑白 overlay alpha 与静态 token、payload shell 保持相同 stop,避免 early render 与 runtime 状态层级漂移 | | Language identity | 8 | 8 | 语言/文件身份色,已收敛到 8 个大类色;具体识别继续由 key、label、icon 和扩展名承担 | | Terminal | 37 | 29 | terminal/ANSI 专用域;工具命令空状态已复用 `--tool-command-empty-rgb`,不再保留独立 raw 色 | | Boundary fallback | 18 | 18 | iframe/miniapp/截图兜底值,不作为普通 app token;generated widget 初始 CSS 需要覆盖 retired alias 的 canonical 目标 | @@ -296,9 +296,9 @@ theme preset 或 boundary fallback 误算成普通 app UI 债务。当前队列 | 专用域 | 肉眼不可区分 pair | 需证据复核 pair | 后续处理原则 | | --- | ---: | ---: | --- | -| Theme presets | 0 | 10 | 只剩 light/paper 相邻 surface、Ink Night/Tokyo Night 主题识别 surface 和 Monaco lineHighlight 等需视觉证据的 near pair;不按数值继续强合并 | -| Theme runtime | 0 | 8 | 黑白 overlay runtime stop 虽然数值接近,但直接服务 card、markdown、shadow 等相邻状态;后续只能在有视觉证据时继续压缩 | -| Token contracts | 0 | 8 | 静态 token 黑白 overlay stop 保留与 runtime 同步的状态层级;不能为了清零 near pair 破坏 hover/active/elevated 区分 | +| Theme presets | 0 | 9 | 只剩 light/paper 相邻 surface、Ink Night/Tokyo Night 主题识别 surface 和 Monaco lineHighlight 等需视觉证据的 near pair;不按数值继续强合并 | +| Theme runtime | 0 | 2 | 黑白 overlay runtime stop 虽然数值接近,但直接服务 card、markdown、shadow 等相邻状态;后续只能在有视觉证据时继续压缩 | +| Token contracts | 0 | 2 | 静态 token 黑白 overlay stop 保留与 runtime 同步的状态层级;不能为了清零 near pair 破坏 hover/active/elevated 区分 | | Boundary fallback | 0 | 0 | first-paint 兜底已收敛到较粗 overlay stop;后续新增必须重新说明边界理由 | | Mermaid | 0 | 0 | 节点、边、文本、错误态和 light/dark Mermaid fallback 的近似队列已清零 | | Editor | 0 | 0 | Monaco selection、diff、inline highlight 和 light/dark editor 近似队列已清零 | @@ -308,12 +308,12 @@ theme preset 或 boundary fallback 误算成普通 app UI 债务。当前队列 | 文件 | 颜色出现次数 | 后续处理策略 | | --- | ---: | --- | -| `src/web-ui/src/component-library/styles/tokens.scss` | 100 | 根 token 契约;优先处理同语义 alias,避免把状态/层级 ramp 按数值强合并 | -| `src/web-ui/src/tools/mermaid-editor/theme/mermaidThemeFallbacks.ts` | 64 | Mermaid 专用渲染兜底;需以节点、边、文本、错误态截图为依据 | -| `src/web-ui/src/tools/editor/themes/bitfun-dark.theme.ts` | 46 | Monaco theme palette;不拆散到普通 app token | -| `src/web-ui/src/infrastructure/theme/core/ThemeService.ts` | 30 | 运行时注入;需保持 early render、system theme 和 payload 导出兼容 | +| `src/web-ui/src/component-library/styles/tokens.scss` | 97 | 根 token 契约;优先处理同语义 alias,避免把状态/层级 ramp 按数值强合并 | +| `src/web-ui/src/tools/mermaid-editor/theme/mermaidThemeFallbacks.ts` | 62 | Mermaid 专用渲染兜底;需以节点、边、文本、错误态截图为依据 | +| `src/web-ui/src/tools/editor/themes/bitfun-dark.theme.ts` | 41 | Monaco theme palette;不拆散到普通 app token | +| `src/web-ui/src/infrastructure/theme/core/ThemeService.ts` | 27 | 运行时注入;需保持 early render、system theme 和 payload 导出兼容 | | `src/web-ui/src/tools/terminal/utils/xtermTheme.ts` | 36 | terminal ANSI palette;不与 app semantic color 合并 | -| `src/web-ui/src/tools/mermaid-editor/theme/_tokens.scss` | 27 | Mermaid SCSS token 兜底;只在 Mermaid owner 内治理 | +| `src/web-ui/src/tools/mermaid-editor/theme/_tokens.scss` | 20 | Mermaid SCSS token 兜底;只在 Mermaid owner 内治理 | | `src/web-ui/src/infrastructure/theme/presets/midnight-theme.ts` | 23 | theme preset palette;保留主题个性、状态色和 alpha ramp 边界 | | `src/web-ui/src/infrastructure/theme/presets/slate-theme.ts` | 22 | theme preset palette;保留主题个性、状态色和 alpha ramp 边界 | | `src/web-ui/src/shared/theme/themeBoundaryFallbacks.ts` | 18 | iframe/miniapp/截图兜底 palette;只作为边界 fallback 治理 | @@ -371,8 +371,8 @@ Phase 5 决策记录: | `#f0f2f5` -> `#eef0f3` | merge | Slate primary button default text;Slate text primary | RGB distance = 3.46,同一 Slate foreground ramp 内肉眼难区分,且不与 hover/active 的 white foreground 相邻表达不同业务状态 | | `rgba(255,255,255,0.22)` -> `rgba(255,255,255,0.24)` | merge | static token scrollbar hover、info border、ChatInput border、dark fallback scrollbar、MiniApp fallback、scrollbar mixin defaults | 同一 white overlay hover/border stop 内 0.02 alpha 差异;不用于相邻信息层级,合并到已有 `0.24`/`border-medium` 后保留语义 key | | `rgba(0,0,0,0.28)` -> `rgba(0,0,0,0.30)` | merge | light runtime scrollbar fallback、MiniApp light scrollbar fallback | 同一 light scrollbar hover fallback 内 0.02 alpha 差异;仅在主题未提供 scrollbar 值时兜底,合并到现有 black30 stop | -| dark neutral element alpha ramp | merge to canonical overlay stops | `tokens.scss`、`createDarkNeutralElement()`、theme prompt snapshot | `0.07/0.095/0.125/0.155/0.19` 收敛为 `0.06/0.10/0.12/0.15/0.20`,保留 subtle/soft/base/medium/strong/elevated key;只压缩肉眼弱差异,不删除层级角色 | -| `--color-overlay-white-05` -> `--color-overlay-white-06` | retire key | `tokens.scss`、`ThemeService.ts`、generated widget payload、内部 CSS var 读取 | 旧 key 与 canonical `0.06` 已同值,继续保留只会扩大主题扩展 surface;root/runtime/payload 不再导出,历史 generated widget 读取通过 iframe alias fallback 映射 | +| dark neutral element alpha ramp | merge to canonical overlay stops | `tokens.scss`、`createDarkNeutralElement()`、theme prompt snapshot | 非标准 neutral alpha 已收敛到 canonical overlay ramp,保留 subtle/soft/base/medium/strong/elevated key;只压缩肉眼弱差异,不删除层级角色 | +| `--color-overlay-white-05/06` -> `--color-overlay-white-08` | retire key | `tokens.scss`、`ThemeService.ts`、generated widget payload、内部 CSS var 读取 | 旧 key 只表达极弱 white overlay 微差,继续保留会扩大主题扩展 surface;root/runtime/payload 不再导出,历史 generated widget 读取通过 iframe alias fallback 映射 | | dark theme shadow alpha ramp | preserve | `src/web-ui/src/infrastructure/theme/presets/*-theme.ts` | 经独立复审,Tokyo、Slate、China Night、Cyber 等 shadow alpha 同时表达主题个性和 elevation 强度,且影响菜单、下拉、toolbar 等相邻浮层;不作为本轮压缩对象,后续只有截图证据充分时才按主题内语义合并 | | low-end overlay payload stops | retire keys | `tokens.scss`、`ThemeService.ts`、generated widget payload、内部 CSS var 读取 | `--color-overlay-white-02` 合并到 `--color-overlay-white-04`,`--color-overlay-black-06` 合并到 `--color-overlay-black-08`;二者只表达极弱 surface/shadow 透明度,不承载 status/semantic;root/runtime/payload 不再导出,历史 generated widget 读取通过 iframe alias fallback 映射 | | light slate overlay micro-stops | merge to coarse surface ramp | `tokens.scss`、Markdown/table、ChatInput、ModelSelector、ContextMenu、TiptapEditor 等浅色 surface 读取 | `--color-overlay-slate-03/06/10/14` 分别收敛到 `04/08/12/12`,保留 `04/08/12/22` 四个 stop;用途集中在浅色主题非语义 shadow、border、stripe、hover,避免为 0.01/0.02 alpha 微差扩大主题扩展 key 面 | @@ -397,14 +397,19 @@ Phase 5 决策记录: | CLI dark syntax variable `#80d4ff` -> `#7dcfff` | merge | `src/apps/cli/themes/presets/bitfun-dark.json` | 同一 dark CLI syntax palette 内 function/variable 均为 cyan 高亮,RGB distance 5.83,终端语法类别仍可通过 token role 保留;合并后不影响 diff、warning/error 或背景边界 | | web theme preset neutral compression | merge within preset namespace | `src/web-ui/src/infrastructure/theme/presets/{china-night,china-style,cyber,dark,light,midnight,slate,tokyo-night}-theme.ts` | 跨主题深色 neutral、弱文本、非状态 scene/workbench 和低透明 accent seed 收敛到已有 stops;复审后保留 Ink Night secondary/lineHighlight、Tokyo Night primary、Slate success、light surface ramp、China paper elevated ramp、Monaco lineHighlight 和 error/warning/status 色。Theme preset 唯一色数 147 -> 121,theme preset near pair 57 -> 11 | | CLI weak foreground and input preset compression | merge within CLI preset namespace | `src/apps/cli/themes/presets/bitfun-dark.json`、`bitfun-midnight.json` | Dark syntax punctuation 复用正文前景,Midnight markdown strong 复用正文前景,Midnight input background 复用 element surface;均不承担 diff body/gutter 或 border/element 相邻区分。CLI preset 唯一色数 125 -> 123,总唯一色数 155 -> 153,preset near pair 7 -> 5 | -| remaining theme/CLI near pairs | preserve | web theme preset、CLI preset | 剩余 web near 主要是 light/paper 相邻 surface 与 Monaco light lineHighlight;剩余 CLI near 是 Cyber element/border、diff added/removed body/gutter 和跨主题 text/background。它们需要截图或语义证据后才能合并,不以 RGB distance 自动处理 | +| remaining web theme near pairs | preserve | web theme preset | 剩余 web near 主要是 light/paper 相邻 surface、主题身份背景与 Monaco light lineHighlight;CLI preset/runtime near pair 已清零。后续继续合并需要截图或语义证据,不以 RGB distance 自动处理 | | web/installer dark/slate/midnight neutral text | merge | `src/web-ui/src/infrastructure/theme/presets/slate-theme.ts`、`midnight-theme.ts`、`BitFun-Installer/src/theme/installerThemesData.ts` | `#9da0a8`、`#9ea4ab` 收敛到 `#a1a1aa`,Slate branch 复用 `SLATE_ACCENT`;均为跨主题 neutral text/branch 语义,不合并 error/warning/status 色,同名安装器预览同步 | | installer preset seed compression | derive within installer namespace | `BitFun-Installer/src/theme/installerThemesData.ts`、`BitFun-Installer/src/styles/variables.css` | 安装器是简单首启/安装 surface,不应维护完整 app 级主题色板;8 套 installer 主题压缩为少量 background/accent/status seed 加 dark/light tone,theme preset 色值 160 -> 63、preset 唯一色 121 -> 60,静态变量同步用 alias 派生而不是复制色值;保留每个主题的 success/warning/error seed,避免安装进度、完成和错误反馈与最终主题状态色脱节 | | generated widget payload shell compression | move host-internal keys to iframe shell | `src/web-ui/src/tools/generative-widget/themePayload.ts`、`GenerativeWidgetFrame.tsx` | host payload allowlist 153 -> 98;只保留外部 widget 真正需要随主题变化的 canonical 子集和 `components.button` 投影,tool-card/layout/旧 overlay 与 legacy alias 由 iframe fallback/static shell 派生,避免把宿主内部 key 变成插件或主题扩展 API;accent/status/border/radius/spacing/button 等主题敏感 key 必须继续由宿主 payload 覆盖,不能固化在 iframe shell | | slate success and CLI added diff near merge | merge non-adjacent equivalent concepts | `src/web-ui/src/infrastructure/theme/presets/slate-theme.ts`、`src/apps/cli/themes/presets/bitfun-ink-night.json`、`bitfun-tokyo-night.json` | Slate success 复用已有 success green;CLI ink/tokyo added diff body 复用同一深绿非相邻 surface。保留 Cyber element/border、diff body/gutter 等相邻区分,web theme preset near 11 -> 10,CLI preset near 5 -> 4 | -| installer named dark background seed | preserve adjacent preview identity | `BitFun-Installer/src/theme/installerThemesData.ts` | 复审后保留 Ink Night、Cyber、Tokyo Night、Slate 的 primary/secondary seed;这些色值虽然接近,但在 ThemeSetup 相邻预览中承担主题识别,不作为本轮可合并收益。Installer 不再保留未读取的 tooltip seed,near pair 保持 11 | -| web overlay alpha ladder | preserve adjacent state stops | `tokens.scss`、`ThemeService.ts`、`themePayload.ts` | 复审后保留 `0.04/0.06/0.08/0.10/0.12/0.15/0.20` 等黑白 overlay stop;这些 key 被 card、markdown、shadow 等相邻状态消费,不能为了清零 near pair 折叠 hover/active/elevated 区分。生成式 widget host payload 仍不转发静态 overlay,由 iframe fallback/static shell 派生 | +| installer named dark background seed | preserve visible primary identity | `BitFun-Installer/src/theme/installerThemesData.ts` | 安装器界面简单,但 ThemeSetup 预览直接展示 primary/secondary background;Dark 复用 canonical seed,Ink Night/Cyber/Tokyo Night 保留各自 primary,secondary 复用 common dark surface。Installer theme preset 唯一色 57 -> 53,near pair 11 -> 3;剩余 near pair 是用户可见主题识别,而非内部冗余 | +| web overlay alpha ladder | preserve adjacent state stops | `tokens.scss`、`ThemeService.ts`、`themePayload.ts` | 复审后保留 `0.04/0.08/0.12/0.15/0.20` 等黑白 overlay stop;card、markdown、shadow 等相邻状态仍通过语义 key 表达,不再保留 `0.06/0.10` 微弱中间 stop。生成式 widget host payload 仍不转发静态 overlay,由 iframe fallback/static shell 派生 | | generated widget static overlay payload | move to iframe shell | `src/web-ui/src/tools/generative-widget/themePayload.ts`、`themePayload.test.ts` | 静态黑白 overlay 不再由 host payload 转发,iframe fallback/static shell 直接派生;payload allowlist 98 -> 94,历史低阶 overlay alias 继续通过 iframe fallback 映射,不影响已生成 widget | +| canonical overlay micro-stop retirement | retire keys | `tokens.scss`、`ThemeService.ts`、`themePayload.ts`、内部 CSS var 读取 | `--color-overlay-white-06` 合并到 `--color-overlay-white-08`,`--color-overlay-white-10` 合并到 `--color-overlay-white-12`,`--color-overlay-black-10` 合并到 `--color-overlay-black-12`;只处理非语义弱 overlay,历史 generated widget 读取通过 iframe alias fallback 保留 | +| Mermaid light semantic status tokens | derive fill/stroke from app semantic status, preserve readable note text | `_tokens.scss`、`mermaidThemeFallbacks.ts` | light done/crit 颜色改读 success/error semantic token,note fill/stroke 由 warning 派生;note text 保留专用深色值以满足说明文字可读性。critical/error fallback fill 共享同一弱 error 背景,Mermaid unique 73 -> 65 且 near pair 保持 0 | +| Monaco diff background strength | preserve per-layer strength | `bitfun-dark.theme.ts` | 复审后保留 inserted/removed/modified 的 text、line、gutter 背景强度阶梯;代码审查场景需要同时识别整行变更、行内片段和 gutter 定位锚点,不能只按同 change type 合并 | +| generated widget derived payload keys | move derived keys to iframe fallback/static shell | `themePayload.ts`、`themePayloadCompatibility.ts`、`themePayload.test.ts` | accent 细分 stop、status border、strong/prominent border、strong element 和 `--size-radius-md` 不再从 host payload 读取;iframe fallback/static shell 继续解析这些派生 key,payload allowlist 94 -> 80 | +| CLI preset/runtime near cleanup | merge non-semantic close surfaces | `src/apps/cli/themes/presets/*.json` | Dark/Ink/Midnight/Cyber 的非状态 surface、input、border 和极近前景值复用已有 preset stops;CLI preset unique 122 -> 118、total unique 152 -> 148,preset/runtime near pair 均降为 0。OpenCode compatibility 字段单独计数,不冒充 runtime 收益 | | mobile static overlay foreground | tokenized static color | `src/mobile-web/src/theme/presets/shared.ts`、`chat-input.scss`、`light.ts` | 图片缩略图关闭按钮必须在黑色 overlay 上保持白色前景;新增 mobile `--color-static-white` 后组件 raw `#fff` 归零,light secondary 改读该静态 token,mobile 总颜色出现次数不增加且唯一色 31 -> 30 | | CLI warm removed surface | defer | `src/apps/cli/themes/presets/*.json`、`src/apps/cli/src/ui/theme.rs` | 复审发现 `diffRemovedLineNumberBg` 当前未被 CLI renderer 消费,因此不把该类 preset 字段当作真实渲染收益压 baseline;本轮撤回 CLI preset 改动,后续应先明确 schema 消费边界再压缩 | | remaining near pairs | none in ordinary components | 无 | 审计口径下普通组件 near pair 已清零;后续只在专用 palette 自身重设计时处理 Monaco/terminal/Mermaid/syntax 内部近似色 | @@ -420,10 +425,10 @@ Phase 6 防回退约束: | `nearPairs.indistinguishableTotal` | 0 | 0 | 阻止新增普通组件肉眼不可区分 pair 未被合并或记录 | | `nearPairs.nearTotal` | 0 | 0 | 阻止新增普通组件 near color 债务;新增必须合并、归类或记录理由 | | `colorDomainNearPairs.indistinguishableTotal` | 0 | 0 | 控制专用域肉眼不可区分 pair 不继续增长,后续只能逐步降低或补充证据 | -| `colorDomainNearPairs.nearTotal` | 26 | 26 | 控制 theme preset/runtime/token/editor/Mermaid 等专用域 near 队列规模 | +| `colorDomainNearPairs.nearTotal` | 13 | 13 | 控制 theme preset/runtime/token/editor/Mermaid 等专用域 near 队列规模 | | `colorScopes.appUi.uniqueColors` | 0 | 0 | 阻止普通组件 raw color 唯一色回涨 | | `colorScopes.appUi.occurrences` | 0 | 0 | 阻止普通组件 raw color 出现次数回涨 | -| `colorScopes.exception.uniqueColors` | 190 | 190 | 控制专用域/例外域总体规模;UI exception、syntax 和 language identity 已收敛,但 Mermaid/editor/terminal 仍按各自 owner 单独治理 | +| `colorScopes.exception.uniqueColors` | 182 | 182 | 控制专用域/例外域总体规模;UI exception、syntax 和 language identity 已收敛,但 Mermaid/editor/terminal 仍按各自 owner 单独治理 | | `colorDomainScopes.syntax.occurrences` | 16 | 16 | 阻止 Prism syntax palette 回到一 token class 一色的不可扩展模式,同时保留相邻 token 可读性边界 | | `colorDomainScopes.languageIdentity.uniqueColors` | 8 | 8 | 阻止 language/file identity 回到一语言一色或一扩展一色的不可扩展模式 | | `colorDomainScopes.boundaryFallback.occurrences` | 18 | 18 | 防止 iframe/mini app/截图兜底色重新散写;导出 key 可保留语义,实际字面值必须回到 boundary fallback palette | @@ -440,7 +445,7 @@ Phase 6 防回退约束: | `surfaceTokenRenames.activeUnique` | 0 | 0 | 防止已迁移的 surface-local 旧 key 重新出现 | | `surfaceTokenRenames.activeOccurrences` | 0 | 0 | 防止旧 key 在定义和读取两侧回流 | | `surfaceTokenRenames.missingCanonicalUnique` | 0 | 0 | 防止 surface rename contract 指向不存在的 canonical key | -| `generatedWidgetPayload.varUnique` | 94 | 94 | 控制 widget 对外主题 payload allowlist 不继续膨胀;该预算只覆盖主题敏感 canonical 子集和 button component 投影,宿主内部、静态 overlay 和历史兼容 key 不计入 payload API | +| `generatedWidgetPayload.varUnique` | 80 | 80 | 控制 widget 对外主题 payload allowlist 不继续膨胀;该预算只覆盖主题敏感 canonical 子集和 button component 投影,宿主内部、静态 overlay、派生 key 和历史兼容 key 不计入 payload API | | generated widget button payload | 18 | 18 | Cyber/Tokyo 按钮 border/shadow/transform 不是低风险静态 key;除非 resolved button 输出等价,否则不从 host payload 移入 iframe shell | | `generatedWidgetPayload.compatibilityAliasUnique` | 0 | 0 | 防止 payload 重新直接导出显式 legacy alias | | `generatedWidgetPayload.compatibilityAliasFamilyUnique` | 0 | 0 | 防止 payload 重新直接导出 legacy size family 具体 key | @@ -452,12 +457,12 @@ Phase 6 防回退约束: | `mobile-web` dynamic families | 3 | 3 | `--color-accent-*`、`--color-purple-*`、`--color-pink-*` 由 mobile preset 拥有 | | `installer` app UI raw color | 0 | 0 | 安装器组件不得携带 raw app color | | `installer` dynamic families | 1 | 1 | 安装器只导出实际消费的 accent family;secondary purple family 不再作为安装器扩展面 | -| `cli` total unique colors | 152 | 152 | 控制 CLI/TUI preset 和 Rust fallback palette 不继续膨胀 | -| `cli` runtime unique colors | 109 | 109 | 只统计 BitFun CLI renderer 当前消费的 preset key 加 Rust fallback palette,避免 OpenCode 兼容声明误导实际运行时预算 | -| `cli` runtime preset unique colors | 79 | 79 | 控制 CLI 当前消费的 preset key,不包含 markdown/syntax/diff line-number background 等未消费兼容字段 | -| `cli` compatibility preset unique colors | 89 | 89 | 单独约束 OpenCode schema 兼容声明;该口径不能冒充 BitFun CLI 运行时收益 | -| `cli` preset near pairs | 4 | 4 | 记录 CLI preset 内仍需证据复核的近似色,避免无依据回涨 | -| `cli` runtime preset near pairs | 2 | 2 | 只记录当前 renderer 消费路径上的近似色;后续压缩需先确认终端相邻状态和 diff 语义不会被削弱 | +| `cli` total unique colors | 148 | 148 | 控制 CLI/TUI preset 和 Rust fallback palette 不继续膨胀 | +| `cli` runtime unique colors | 107 | 107 | 只统计 BitFun CLI renderer 当前消费的 preset key 加 Rust fallback palette,避免 OpenCode 兼容声明误导实际运行时预算 | +| `cli` runtime preset unique colors | 77 | 77 | 控制 CLI 当前消费的 preset key,不包含 markdown/syntax/diff line-number background 等未消费兼容字段 | +| `cli` compatibility preset unique colors | 87 | 87 | 单独约束 OpenCode schema 兼容声明;该口径不能冒充 BitFun CLI 运行时收益 | +| `cli` preset near pairs | 0 | 0 | 阻止 CLI preset 重新引入未解释的近似色;OpenCode compatibility 字段仍单独审计 | +| `cli` runtime preset near pairs | 0 | 0 | 阻止当前 renderer 消费路径重新引入近似色;后续压缩需先确认终端相邻状态和 diff 语义不会被削弱 | | `cli` Rust fallback near pairs | 0 | 0 | fallback palette 不再允许新增近似重复色 | | `fallbackContracts.uncontractedUnique` | 0 | 0 | 防止新增未说明边界的 `var(--token, fallback)` | | `fallbackContracts.staleRegisteredUnique` | 0 | 0 | 防止已删除 fallback 继续留在 registry 中 | @@ -604,7 +609,7 @@ editor、syntax、terminal、language identity、boundary fallback 等专用域 - 不能只按色差或 RGB 距离合并。 - 先判断语义角色、相邻关系、交互状态、主题预设和可访问性,再决定是否替换。 - 对于白/黑透明叠层,先建立精确等价的 overlay ramp,例如 - `--color-overlay-white-08` 和 `--color-overlay-white-10`。这一步只消除散落 + `--color-overlay-white-08` 和 `--color-overlay-white-12`。这一步只消除散落 硬编码,不合并不同 alpha,因为 alpha 差异经常用于表达层级和状态。 - 如果数值型 overlay key 已经实际别名到另一个 alpha stop,内部读取应迁到真实 canonical stop,并删除误导性的旧导出。 @@ -1100,14 +1105,14 @@ alpha 差异经常承担 elevation 和交互状态,不应全部压成一个值 2. 插件/主题扩展投影治理:插件侧只消费 `pluginThemeProjection.ts` 暴露的 7 个 OpenCode-compatible 语义色 key; 新增插件 UI 需求必须先证明无法复用这 7 个 key,再新增小型 surface projection。不得把 generated widget payload 或完整 runtime CSS var 表作为插件主题 schema。 -3. 专用域近似色复核:mobile-web theme preset near pair 已清零;web-ui/installer 已先处理不可感知的跨主题 neutral、tooltip 派生、runtime/static panel 值、极近 overlay fallback,以及 theme preset 的非状态 neutral/弱文本/scene/workbench 值;installer 仍保留承担主题选择识别的深色背景 near pair。 +3. 专用域近似色复核:mobile-web theme preset near pair 已清零;installer 保留 3 个承担主题选择预览识别的 dark primary near pair;web-ui 已先处理不可感知的跨主题 neutral、tooltip 派生、runtime/static panel 值、极近 overlay fallback,以及 theme preset 的非状态 neutral/弱文本/scene/workbench 值。 后续继续处理 theme preset 时必须避开按钮 hover/active、light/paper 相邻 surface ramp、Monaco lineHighlight、Mermaid、terminal、syntax 等相邻状态色,除非有截图证据证明不会损害层级。 -4. CLI/TUI palette 压缩:CLI/TUI 已纳入 `theme:color-audit:cli`,Rust fallback near pair 归零,preset near pair 保持 4;后续只处理 preset 内能证明同一终端 surface 语义且已被 CLI renderer 消费的近似色, +4. CLI/TUI palette 压缩:CLI/TUI 已纳入 `theme:color-audit:cli`,Rust fallback、preset 和 runtime-consumed preset near pair 均为 0;后续只处理 preset 内能证明同一终端 surface 语义且已被 CLI renderer 消费的近似色, 不能让 Rust/CLI 复制 web-ui palette。若要跨 surface 共享,只能先定义共享语义投影或生成链路。 5. 自定义主题扩展后续体验优化:custom theme 校验、加载、注册、导出和 preview 输入已绑定到 TS schema; 如需继续改善首屏体验,只允许由 TS schema 生成最小 bootstrap cache,不允许 Rust 直接拥有 custom theme schema。 -6. generated widget 兼容面维护:payload 已停止导出 `background/bg/text/radius/spacing` legacy key、静态黑白 overlay 转发和已归并的 - `--color-overlay-white-02`、`--color-overlay-white-05`、`--color-overlay-black-06`、`--color-overlay-black-25`;历史内容兼容通过 iframe alias fallback 保留。后续新增 widget token 必须先导出 canonical, +6. generated widget 兼容面维护:payload 已停止导出 `background/bg/text/radius/spacing` legacy key、静态黑白 overlay 转发、派生 accent/status/border/radius key 和已归并的 + `--color-overlay-white-02`、`--color-overlay-white-05`、`--color-overlay-white-06`、`--color-overlay-white-10`、`--color-overlay-black-06`、`--color-overlay-black-10`、`--color-overlay-black-25`;历史内容兼容通过 iframe alias fallback 保留。后续新增 widget token 必须先导出 canonical, 再评估是否需要 iframe-only alias。 每个 PR 应包含范围、影响 surface、before/after 指标、命中的 visual governance surface、 @@ -1136,10 +1141,14 @@ alpha 差异经常承担 elevation 和交互状态,不应全部压成一个值 generated widget iframe alias fallback 将其映射到 `--color-overlay-white-04`,避免历史内容丢失样式。 - `--color-overlay-white-02` 已从 root/runtime、内部读取和 generated widget payload 退役; generated widget iframe alias fallback 将历史读取映射到 `--color-overlay-white-04`。 -- `--color-overlay-white-05` 已从 root/runtime、内部读取和 generated widget payload 退役; - generated widget iframe alias fallback 将历史读取映射到 `--color-overlay-white-06`。 +- `--color-overlay-white-05` 和 `--color-overlay-white-06` 已从 root/runtime、内部读取和 generated widget payload 退役; + generated widget iframe alias fallback 将历史读取映射到 `--color-overlay-white-08`。 +- `--color-overlay-white-10` 已从 root/runtime、内部读取和 generated widget payload 退役; + generated widget iframe alias fallback 将历史读取映射到 `--color-overlay-white-12`。 - `--color-overlay-black-06` 已从 root/runtime、内部读取和 generated widget payload 退役; generated widget iframe alias fallback 将历史读取映射到 `--color-overlay-black-08`。 +- `--color-overlay-black-10` 已从 root/runtime、内部读取和 generated widget payload 退役; + generated widget iframe alias fallback 将历史读取映射到 `--color-overlay-black-12`。 - `--color-overlay-black-25` 已从 root/runtime、内部读取和 generated widget payload 退役; generated widget iframe alias fallback 将历史读取映射到 `--color-overlay-black-30`。 - generated widget payload 不导出宿主 FlowChat、navigation、z-index 和 tool-card 内部 key;iframe 内容保留独立布局和 diff --git a/scripts/theme-color-governance-baseline.cli.json b/scripts/theme-color-governance-baseline.cli.json index cc43b67a9e..aa67896602 100644 --- a/scripts/theme-color-governance-baseline.cli.json +++ b/scripts/theme-color-governance-baseline.cli.json @@ -6,19 +6,19 @@ "max": 306 }, "presetUniqueColors": { - "max": 122 + "max": 118 }, "runtimePresetColorOccurrences": { "max": 114 }, "runtimePresetUniqueColors": { - "max": 79 + "max": 77 }, "compatibilityPresetColorOccurrences": { "max": 192 }, "compatibilityPresetUniqueColors": { - "max": 89 + "max": 87 }, "rustFallbackColorOccurrences": { "max": 44 @@ -27,16 +27,16 @@ "max": 32 }, "totalUniqueColors": { - "max": 152 + "max": 148 }, "runtimeTotalUniqueColors": { - "max": 109 + "max": 107 }, "presetNearPairs.nearTotal": { - "max": 4 + "max": 0 }, "runtimePresetNearPairs.nearTotal": { - "max": 2 + "max": 0 }, "compatibilityPresetNearPairs.nearTotal": { "max": 0 diff --git a/scripts/theme-color-governance-baseline.installer.json b/scripts/theme-color-governance-baseline.installer.json index 4df99a0a7b..51ec345aea 100644 --- a/scripts/theme-color-governance-baseline.installer.json +++ b/scripts/theme-color-governance-baseline.installer.json @@ -81,7 +81,7 @@ "max": 0 }, "colorDomainNearPairs.themePreset.nearTotal": { - "max": 11 + "max": 3 }, "colorDomainNearPairs.tokenContract.indistinguishableTotal": { "max": 0 @@ -96,10 +96,10 @@ "max": 0 }, "colorDomainScopes.themePreset.occurrences": { - "max": 59 + "max": 54 }, "colorDomainScopes.themePreset.uniqueColors": { - "max": 57 + "max": 53 }, "colorDomainScopes.tokenContract.occurrences": { "max": 22 diff --git a/scripts/theme-color-governance-baseline.json b/scripts/theme-color-governance-baseline.json index c195574c89..5c42491f0b 100644 --- a/scripts/theme-color-governance-baseline.json +++ b/scripts/theme-color-governance-baseline.json @@ -54,10 +54,10 @@ "max": 0 }, "generatedWidgetPayload.varUnique": { - "max": 94 + "max": 80 }, "generatedWidgetPayload.occurrences": { - "max": 94 + "max": 80 }, "generatedWidgetPayload.undefinedUnique": { "max": 0 @@ -105,10 +105,10 @@ "max": 0 }, "colorScopes.token.uniqueColors": { - "max": 205 + "max": 201 }, "colorScopes.exception.uniqueColors": { - "max": 190 + "max": 182 }, "cssVarDefinitions.unresolvedRequiredUnique": { "max": 0 @@ -153,25 +153,25 @@ "max": 0 }, "colorDomainNearPairs.nearTotal": { - "max": 26 + "max": 13 }, "colorDomainNearPairs.themePreset.indistinguishableTotal": { "max": 0 }, "colorDomainNearPairs.themePreset.nearTotal": { - "max": 10 + "max": 9 }, "colorDomainNearPairs.themeRuntime.indistinguishableTotal": { "max": 0 }, "colorDomainNearPairs.themeRuntime.nearTotal": { - "max": 8 + "max": 2 }, "colorDomainNearPairs.tokenContract.indistinguishableTotal": { "max": 0 }, "colorDomainNearPairs.tokenContract.nearTotal": { - "max": 8 + "max": 2 }, "colorDomainNearPairs.generatedWidget.indistinguishableTotal": { "max": 0 @@ -243,13 +243,13 @@ "max": 171 }, "colorDomainScopes.themePreset.uniqueColors": { - "max": 120 + "max": 119 }, "colorDomainScopes.themeRuntime.occurrences": { - "max": 30 + "max": 27 }, "colorDomainScopes.tokenContract.occurrences": { - "max": 113 + "max": 110 }, "colorDomainScopes.generatedWidget.occurrences": { "max": 0 @@ -297,10 +297,10 @@ "max": 0 }, "colorDomainScopes.mermaid.occurrences": { - "max": 91 + "max": 82 }, "colorDomainScopes.mermaid.uniqueColors": { - "max": 73 + "max": 65 } } } diff --git a/src/apps/cli/themes/presets/bitfun-cyber.json b/src/apps/cli/themes/presets/bitfun-cyber.json index 5826a48983..2ea774592c 100644 --- a/src/apps/cli/themes/presets/bitfun-cyber.json +++ b/src/apps/cli/themes/presets/bitfun-cyber.json @@ -16,7 +16,7 @@ "inputBackground": "#003f46", "border": "#16404a", "borderActive": "#00e6ff", - "borderSubtle": "#102b32", + "borderSubtle": "#16404a", "diffAdded": "#00ff9f", "diffRemoved": "#ff0055", "diffContext": "#7fadcc", diff --git a/src/apps/cli/themes/presets/bitfun-dark.json b/src/apps/cli/themes/presets/bitfun-dark.json index 68f62e3ca2..ecdee9ce57 100644 --- a/src/apps/cli/themes/presets/bitfun-dark.json +++ b/src/apps/cli/themes/presets/bitfun-dark.json @@ -8,7 +8,7 @@ "warning": "#f59e0b", "success": "#34d399", "info": "#a1a1aa", - "text": "#e8e8e8", + "text": "#e7ecf3", "textMuted": "#858585", "background": "#0e0e10", "backgroundPanel": "#1c1c1f", @@ -27,22 +27,22 @@ "diffRemovedBg": "#3e221c", "diffContextBg": "#1c1c1f", "diffLineNumber": "#66666d", - "diffAddedLineNumberBg": "#163c32", + "diffAddedLineNumberBg": "#1b3328", "diffRemovedLineNumberBg": "#432329", - "markdownText": "#e8e8e8", + "markdownText": "#e7ecf3", "markdownHeading": "#60a5fa", "markdownLink": "#60a5fa", "markdownLinkText": "#8b5cf6", "markdownCode": "#34d399", "markdownBlockQuote": "#858585", "markdownEmph": "#f59e0b", - "markdownStrong": "#e8e8e8", + "markdownStrong": "#e7ecf3", "markdownHorizontalRule": "#3b3b40", "markdownListItem": "#60a5fa", "markdownListEnumeration": "#8b5cf6", "markdownImage": "#60a5fa", "markdownImageText": "#8b5cf6", - "markdownCodeBlock": "#e8e8e8", + "markdownCodeBlock": "#e7ecf3", "syntaxComment": "#6a737d", "syntaxKeyword": "#c792ea", "syntaxFunction": "#7dcfff", @@ -51,6 +51,6 @@ "syntaxNumber": "#f78c6c", "syntaxType": "#ffc777", "syntaxOperator": "#c792ea", - "syntaxPunctuation": "#e8e8e8" + "syntaxPunctuation": "#e7ecf3" } } diff --git a/src/apps/cli/themes/presets/bitfun-ink-night.json b/src/apps/cli/themes/presets/bitfun-ink-night.json index a80046b3aa..e63feb303c 100644 --- a/src/apps/cli/themes/presets/bitfun-ink-night.json +++ b/src/apps/cli/themes/presets/bitfun-ink-night.json @@ -12,7 +12,7 @@ "textMuted": "#a79b83", "background": "#17110c", "backgroundPanel": "#241b12", - "backgroundElement": "#3a2817", + "backgroundElement": "#4a2d15", "inputBackground": "#4a2d15", "border": "#5a472b", "borderActive": "#d7b56d", diff --git a/src/apps/cli/themes/presets/bitfun-midnight.json b/src/apps/cli/themes/presets/bitfun-midnight.json index af5c7d7202..31bdc0c59f 100644 --- a/src/apps/cli/themes/presets/bitfun-midnight.json +++ b/src/apps/cli/themes/presets/bitfun-midnight.json @@ -13,7 +13,7 @@ "background": "#0e0e10", "backgroundPanel": "#151515", "backgroundElement": "#1b3328", - "inputBackground": "#163c32", + "inputBackground": "#1b3328", "border": "#32403b", "borderActive": "#8fbc9f", "borderSubtle": "#2b2b30", diff --git a/src/web-ui/src/app/components/GalleryLayout/GalleryLayout.scss b/src/web-ui/src/app/components/GalleryLayout/GalleryLayout.scss index ae81914a05..6771f0d6b5 100644 --- a/src/web-ui/src/app/components/GalleryLayout/GalleryLayout.scss +++ b/src/web-ui/src/app/components/GalleryLayout/GalleryLayout.scss @@ -159,7 +159,7 @@ $content-max: 1480px; &--skeleton { --skeleton-shimmer-0: rgba(var(--color-static-white-rgb), 0); - --skeleton-shimmer-peak: var(--color-overlay-white-10); + --skeleton-shimmer-peak: var(--color-overlay-white-12); pointer-events: none; } } diff --git a/src/web-ui/src/app/components/RemoteConnectDialog/RemoteConnectDialog.scss b/src/web-ui/src/app/components/RemoteConnectDialog/RemoteConnectDialog.scss index e0c73a49db..d80db70734 100644 --- a/src/web-ui/src/app/components/RemoteConnectDialog/RemoteConnectDialog.scss +++ b/src/web-ui/src/app/components/RemoteConnectDialog/RemoteConnectDialog.scss @@ -172,7 +172,7 @@ transition: transform 0.15s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.15s ease; &:hover { - box-shadow: 0 2px 8px var(--color-overlay-black-10); + box-shadow: 0 2px 8px var(--color-overlay-black-12); } &:active { diff --git a/src/web-ui/src/app/components/panels/DiffFullscreenViewer.css b/src/web-ui/src/app/components/panels/DiffFullscreenViewer.css index 69123a7fc9..1f0baceb6b 100644 --- a/src/web-ui/src/app/components/panels/DiffFullscreenViewer.css +++ b/src/web-ui/src/app/components/panels/DiffFullscreenViewer.css @@ -56,7 +56,7 @@ justify-content: space-between; padding: 12px 20px; background: var(--diff-fullscreen-overlay-bg); - border-bottom: 1px solid var(--color-overlay-white-10); + border-bottom: 1px solid var(--color-overlay-white-12); backdrop-filter: blur(8px); flex-shrink: 0; z-index: 2; @@ -116,9 +116,9 @@ font-weight: 500; cursor: pointer; transition: all 0.2s ease; - background: var(--color-overlay-white-06); + background: var(--color-overlay-white-08); color: var(--color-overlay-white-80); - border: 1px solid var(--color-overlay-white-10); + border: 1px solid var(--color-overlay-white-12); } .header-btn:hover:not(:disabled) { @@ -165,7 +165,7 @@ .header-divider { width: 1px; height: 20px; - background: var(--color-overlay-white-10); + background: var(--color-overlay-white-12); margin: 0 4px; } diff --git a/src/web-ui/src/app/layout/FloatingMiniChat.scss b/src/web-ui/src/app/layout/FloatingMiniChat.scss index 2e347e0b2e..c2b9c78a54 100644 --- a/src/web-ui/src/app/layout/FloatingMiniChat.scss +++ b/src/web-ui/src/app/layout/FloatingMiniChat.scss @@ -103,7 +103,7 @@ $panel-height: 620px; border-radius: 8px; box-shadow: 0 4px 12px var(--color-overlay-black-30), - 0 0 1px var(--color-overlay-white-06); + 0 0 1px var(--color-overlay-white-08); overflow: hidden; display: flex; flex-direction: column; diff --git a/src/web-ui/src/app/scenes/miniapps/components/MiniAppCard.scss b/src/web-ui/src/app/scenes/miniapps/components/MiniAppCard.scss index 852e2687eb..465bc5797e 100644 --- a/src/web-ui/src/app/scenes/miniapps/components/MiniAppCard.scss +++ b/src/web-ui/src/app/scenes/miniapps/components/MiniAppCard.scss @@ -189,7 +189,7 @@ border-radius: $size-radius-full; font-size: 10px; color: var(--color-text-secondary); - background: var(--color-overlay-white-06); + background: var(--color-overlay-white-08); border: 1px solid var(--color-overlay-white-08); white-space: nowrap; } diff --git a/src/web-ui/src/app/scenes/skills/SkillsScene.scss b/src/web-ui/src/app/scenes/skills/SkillsScene.scss index aaddefd028..d664df6144 100644 --- a/src/web-ui/src/app/scenes/skills/SkillsScene.scss +++ b/src/web-ui/src/app/scenes/skills/SkillsScene.scss @@ -960,7 +960,7 @@ } &.search--focused:not(.search--disabled) .search__wrapper { - box-shadow: 0 4px 20px var(--color-overlay-black-10), 0 0 0 3px color-mix(in srgb, var(--color-accent-500) 15%, transparent); + box-shadow: 0 4px 20px var(--color-overlay-black-12), 0 0 0 3px color-mix(in srgb, var(--color-accent-500) 15%, transparent); border-color: var(--color-accent-500); } } diff --git a/src/web-ui/src/app/scenes/skills/components/SkillCard.scss b/src/web-ui/src/app/scenes/skills/components/SkillCard.scss index c38886f6fc..95a0557b6f 100644 --- a/src/web-ui/src/app/scenes/skills/components/SkillCard.scss +++ b/src/web-ui/src/app/scenes/skills/components/SkillCard.scss @@ -210,7 +210,7 @@ color 0.25s ease; &:not(:last-child) { - border-right: 1px solid var(--color-overlay-white-06); + border-right: 1px solid var(--color-overlay-white-08); } &:disabled { diff --git a/src/web-ui/src/app/styles/components/forms.css b/src/web-ui/src/app/styles/components/forms.css index c2b7531316..80a748dba5 100644 --- a/src/web-ui/src/app/styles/components/forms.css +++ b/src/web-ui/src/app/styles/components/forms.css @@ -111,7 +111,7 @@ 0 4px 16px var(--color-accent-200), 0 2px 8px var(--color-overlay-black-08), 0 0 0 2px var(--color-accent-300), - inset 0 1px 0 var(--color-overlay-white-10); + inset 0 1px 0 var(--color-overlay-white-12); transform: translateY(-1px); } diff --git a/src/web-ui/src/app/styles/utilities/floating-input.css b/src/web-ui/src/app/styles/utilities/floating-input.css index 9fcb8be16a..da1882ae52 100644 --- a/src/web-ui/src/app/styles/utilities/floating-input.css +++ b/src/web-ui/src/app/styles/utilities/floating-input.css @@ -16,7 +16,7 @@ box-shadow: var(--shadow-xl), 0 4px 15px color-mix(in srgb, var(--color-accent-600) 10%, transparent), - inset 0 1px 0 var(--color-overlay-white-06); + inset 0 1px 0 var(--color-overlay-white-08); padding: var(--size-gap-3) var(--size-gap-4); z-index: var(--z-overlay); transition: all var(--motion-base) var(--easing-standard); @@ -33,7 +33,7 @@ box-shadow: 0 12px 40px var(--color-overlay-black-40), 0 6px 20px var(--border-accent-subtle), - inset 0 1px 0 var(--color-overlay-white-10); + inset 0 1px 0 var(--color-overlay-white-12); transform: translateX(-50%) translateY(-1px); } diff --git a/src/web-ui/src/app/styles/utilities/resizer.css b/src/web-ui/src/app/styles/utilities/resizer.css index a2a46b32a7..35d2b5eff7 100644 --- a/src/web-ui/src/app/styles/utilities/resizer.css +++ b/src/web-ui/src/app/styles/utilities/resizer.css @@ -44,14 +44,14 @@ box-shadow: 0 0 12px color-mix(in srgb, var(--color-accent-500) 20%, transparent), 0 0 24px var(--color-purple-200), - inset 0 0 6px var(--color-overlay-white-06); + inset 0 0 6px var(--color-overlay-white-08); transform: scaleY(1.15); } .u-resizer-line { width: 1px; height: 20px; - background: var(--color-overlay-white-10); + background: var(--color-overlay-white-12); border-radius: var(--size-radius-sm); transition: all var(--motion-base); opacity: 0.2; diff --git a/src/web-ui/src/component-library/components/CodeEditor/CodeEditor.scss b/src/web-ui/src/component-library/components/CodeEditor/CodeEditor.scss index a78ddcbedb..bc6f50e224 100644 --- a/src/web-ui/src/component-library/components/CodeEditor/CodeEditor.scss +++ b/src/web-ui/src/component-library/components/CodeEditor/CodeEditor.scss @@ -363,7 +363,7 @@ .indent-guides { .indent-guide { - border-left: 1px solid var(--color-overlay-white-06); + border-left: 1px solid var(--color-overlay-white-08); &.indent-guide-active { border-left: 1px solid rgba(var(--code-editor-blue-rgb), 0.6); diff --git a/src/web-ui/src/component-library/components/FlowChatCards/ContextCompressionCard/ContextCompressionCard.scss b/src/web-ui/src/component-library/components/FlowChatCards/ContextCompressionCard/ContextCompressionCard.scss index ad158427e5..dc9a2edb86 100644 --- a/src/web-ui/src/component-library/components/FlowChatCards/ContextCompressionCard/ContextCompressionCard.scss +++ b/src/web-ui/src/component-library/components/FlowChatCards/ContextCompressionCard/ContextCompressionCard.scss @@ -41,7 +41,7 @@ background: linear-gradient( 90deg, transparent 0%, - var(--color-overlay-white-10) 50%, + var(--color-overlay-white-12) 50%, transparent 100% ); transition: left 0.5s ease; @@ -57,7 +57,7 @@ border-color: color-mix(in srgb, var(--context-compression-accent) 90%, transparent); box-shadow: 0 4px 16px color-mix(in srgb, var(--context-compression-accent) 30%, transparent), 0 2px 8px color-mix(in srgb, var(--context-compression-accent) 20%, transparent), - inset 0 1px 0 var(--color-overlay-white-10); + inset 0 1px 0 var(--color-overlay-white-12); background: linear-gradient( 135deg, rgba(var(--context-compression-hover-bg-start-rgb), 0.98), diff --git a/src/web-ui/src/component-library/components/FlowChatCards/SnapshotCard/SnapshotCard.scss b/src/web-ui/src/component-library/components/FlowChatCards/SnapshotCard/SnapshotCard.scss index dc663a1dd4..d02786ee2b 100644 --- a/src/web-ui/src/component-library/components/FlowChatCards/SnapshotCard/SnapshotCard.scss +++ b/src/web-ui/src/component-library/components/FlowChatCards/SnapshotCard/SnapshotCard.scss @@ -194,7 +194,7 @@ } &:hover:not(:disabled) { - background: var(--color-overlay-white-10); + background: var(--color-overlay-white-12); } } diff --git a/src/web-ui/src/component-library/components/FlowChatCards/TodoCard/TodoCard.scss b/src/web-ui/src/component-library/components/FlowChatCards/TodoCard/TodoCard.scss index 654dfbd83e..aaaa752a63 100644 --- a/src/web-ui/src/component-library/components/FlowChatCards/TodoCard/TodoCard.scss +++ b/src/web-ui/src/component-library/components/FlowChatCards/TodoCard/TodoCard.scss @@ -106,7 +106,7 @@ } &:hover { - background: var(--color-overlay-white-06); + background: var(--color-overlay-white-08); } diff --git a/src/web-ui/src/component-library/components/FlowChatCards/_shared-styles.scss b/src/web-ui/src/component-library/components/FlowChatCards/_shared-styles.scss index af869bc86a..39d75fe404 100644 --- a/src/web-ui/src/component-library/components/FlowChatCards/_shared-styles.scss +++ b/src/web-ui/src/component-library/components/FlowChatCards/_shared-styles.scss @@ -56,7 +56,7 @@ } &:hover { - background: var(--color-overlay-white-10); + background: var(--color-overlay-white-12); border-color: color-mix(in srgb, var(--color-static-white) 35%, transparent); svg { diff --git a/src/web-ui/src/component-library/components/IconButton/IconButton.example.tsx b/src/web-ui/src/component-library/components/IconButton/IconButton.example.tsx index 36d35c9be8..37a2006b2a 100644 --- a/src/web-ui/src/component-library/components/IconButton/IconButton.example.tsx +++ b/src/web-ui/src/component-library/components/IconButton/IconButton.example.tsx @@ -119,7 +119,7 @@ export const IconButtonExample: React.FC = () => { -
+

{t('componentLibrary.iconButtonExample.sections.usage')}

diff --git a/src/web-ui/src/component-library/components/IconButton/IconButton.scss b/src/web-ui/src/component-library/components/IconButton/IconButton.scss index 9ae97b335b..ab20dc34d9 100644 --- a/src/web-ui/src/component-library/components/IconButton/IconButton.scss +++ b/src/web-ui/src/component-library/components/IconButton/IconButton.scss @@ -30,7 +30,7 @@ &:active:not(:disabled) { transform: scale(1.02); - background: var(--color-overlay-white-06); + background: var(--color-overlay-white-08); } svg { diff --git a/src/web-ui/src/component-library/components/Markdown/Markdown.scss b/src/web-ui/src/component-library/components/Markdown/Markdown.scss index 293976721c..ac2c448a39 100644 --- a/src/web-ui/src/component-library/components/Markdown/Markdown.scss +++ b/src/web-ui/src/component-library/components/Markdown/Markdown.scss @@ -345,7 +345,7 @@ } .markdown-renderer .copy-button:hover { - background: var(--color-overlay-white-06); + background: var(--color-overlay-white-08); color: var(--markdown-primary-color); } diff --git a/src/web-ui/src/component-library/components/registry.tsx b/src/web-ui/src/component-library/components/registry.tsx index a732049a4a..c9e145f5a4 100644 --- a/src/web-ui/src/component-library/components/registry.tsx +++ b/src/web-ui/src/component-library/components/registry.tsx @@ -362,7 +362,7 @@ export const componentRegistry: ComponentCategory[] = [ padding: '20px', background: 'var(--color-overlay-white-04)', borderRadius: '8px', - border: '1px solid var(--color-overlay-white-10)', + border: '1px solid var(--color-overlay-white-12)', maxWidth: '700px' }}> span[style] { &:hover { - background-color: var(--color-overlay-white-06) !important; + background-color: var(--color-overlay-white-08) !important; } } @@ -94,7 +94,7 @@ transition: background-color 0.15s ease, border-color 0.15s ease; &:hover { - background-color: var(--color-overlay-white-06); + background-color: var(--color-overlay-white-08); } &--highlighted { diff --git a/src/web-ui/src/flow_chat/components/FileMentionPicker.scss b/src/web-ui/src/flow_chat/components/FileMentionPicker.scss index e455805838..e3950c3651 100644 --- a/src/web-ui/src/flow_chat/components/FileMentionPicker.scss +++ b/src/web-ui/src/flow_chat/components/FileMentionPicker.scss @@ -23,7 +23,7 @@ 0 8px 32px rgba(var(--color-static-black-rgb), 0.35), 0 4px 16px var(--color-overlay-black-20), 0 0 1px color-mix(in srgb, var(--color-accent-500) 30%, transparent), - inset 0 1px 0 var(--color-overlay-white-06); + inset 0 1px 0 var(--color-overlay-white-08); overflow: hidden; z-index: 1100; display: flex; @@ -69,7 +69,7 @@ height: 18px; padding: 0; background: var(--color-overlay-white-08); - border: 1px solid var(--color-overlay-white-10); + border: 1px solid var(--color-overlay-white-12); border-radius: 4px; cursor: pointer; transition: all 0.15s ease; @@ -137,7 +137,7 @@ transition: all 0.12s ease; &:hover { - background: var(--color-overlay-white-06); + background: var(--color-overlay-white-08); .file-mention-picker__expand-icon { opacity: 1; diff --git a/src/web-ui/src/flow_chat/components/ModelSelector.scss b/src/web-ui/src/flow_chat/components/ModelSelector.scss index d9a0619f79..bc0117510b 100644 --- a/src/web-ui/src/flow_chat/components/ModelSelector.scss +++ b/src/web-ui/src/flow_chat/components/ModelSelector.scss @@ -141,15 +141,15 @@ min-width: 220px; max-width: 280px; background: var(--color-bg-elevated); - border: 1px solid var(--color-overlay-white-10); + border: 1px solid var(--color-overlay-white-12); border-radius: 6px; overflow: hidden; backdrop-filter: blur(20px) saturate(1.2); -webkit-backdrop-filter: blur(20px) saturate(1.2); box-shadow: 0 8px 32px var(--color-overlay-black-50), - 0 0 1px var(--color-overlay-white-10), - inset 0 1px 0 var(--color-overlay-white-06); + 0 0 1px var(--color-overlay-white-12), + inset 0 1px 0 var(--color-overlay-white-08); z-index: $z-dropdown; animation: bitfun-model-dropdown-fade-in 0.15s ease-out; } @@ -159,7 +159,7 @@ align-items: center; justify-content: space-between; padding: 8px 12px; - border-bottom: 1px solid var(--color-overlay-white-06); + border-bottom: 1px solid var(--color-overlay-white-08); font-size: var(--flowchat-font-size-xxs); font-weight: 500; color: var(--color-text-muted); diff --git a/src/web-ui/src/flow_chat/components/PlannerButton.scss b/src/web-ui/src/flow_chat/components/PlannerButton.scss index 5c24cfec6d..db6bc00814 100644 --- a/src/web-ui/src/flow_chat/components/PlannerButton.scss +++ b/src/web-ui/src/flow_chat/components/PlannerButton.scss @@ -44,9 +44,9 @@ height: 100%; background: linear-gradient(90deg, transparent, - var(--color-overlay-white-06), var(--color-overlay-white-08), - var(--color-overlay-white-06), + var(--color-overlay-white-08), + var(--color-overlay-white-08), transparent ); transition: left 0.6s cubic-bezier(0.4, 0, 0.2, 1); diff --git a/src/web-ui/src/flow_chat/components/SnapshotRollbackButton.scss b/src/web-ui/src/flow_chat/components/SnapshotRollbackButton.scss index 03d10655ea..1e68f2ca2b 100644 --- a/src/web-ui/src/flow_chat/components/SnapshotRollbackButton.scss +++ b/src/web-ui/src/flow_chat/components/SnapshotRollbackButton.scss @@ -27,12 +27,12 @@ background: var(--color-accent-100); color: var(--color-accent-500); transform: translateY(-1px); - box-shadow: 0 2px 4px var(--color-overlay-black-10); + box-shadow: 0 2px 4px var(--color-overlay-black-12); } &:active:not(:disabled) { transform: translateY(0); - box-shadow: 0 1px 2px var(--color-overlay-black-10); + box-shadow: 0 1px 2px var(--color-overlay-black-12); } &:disabled { diff --git a/src/web-ui/src/flow_chat/components/TaskDetailPanel/TaskDetailPanel.scss b/src/web-ui/src/flow_chat/components/TaskDetailPanel/TaskDetailPanel.scss index dc3402b50b..f3939446e9 100644 --- a/src/web-ui/src/flow_chat/components/TaskDetailPanel/TaskDetailPanel.scss +++ b/src/web-ui/src/flow_chat/components/TaskDetailPanel/TaskDetailPanel.scss @@ -179,7 +179,7 @@ background: transparent; } &::-webkit-scrollbar-thumb { - background: var(--color-overlay-white-10); + background: var(--color-overlay-white-12); border-radius: 2px; &:hover { diff --git a/src/web-ui/src/flow_chat/components/TokenUsageIndicator.scss b/src/web-ui/src/flow_chat/components/TokenUsageIndicator.scss index 999b92cfec..fdd4c14c71 100644 --- a/src/web-ui/src/flow_chat/components/TokenUsageIndicator.scss +++ b/src/web-ui/src/flow_chat/components/TokenUsageIndicator.scss @@ -35,7 +35,7 @@ left: 0; right: 0; bottom: 0; - background: var(--color-overlay-white-06); + background: var(--color-overlay-white-08); border-radius: 8px; overflow: hidden; } diff --git a/src/web-ui/src/flow_chat/components/UserMessage.scss b/src/web-ui/src/flow_chat/components/UserMessage.scss index 0bc71dd341..fcc008814a 100644 --- a/src/web-ui/src/flow_chat/components/UserMessage.scss +++ b/src/web-ui/src/flow_chat/components/UserMessage.scss @@ -109,7 +109,7 @@ &:hover { transform: translateY(-1px); - box-shadow: 0 2px 4px var(--color-overlay-black-10); + box-shadow: 0 2px 4px var(--color-overlay-black-12); } } diff --git a/src/web-ui/src/flow_chat/components/btw/BtwSessionPanel.scss b/src/web-ui/src/flow_chat/components/btw/BtwSessionPanel.scss index 538c19b4fe..d35589f65e 100644 --- a/src/web-ui/src/flow_chat/components/btw/BtwSessionPanel.scss +++ b/src/web-ui/src/flow_chat/components/btw/BtwSessionPanel.scss @@ -207,7 +207,7 @@ font-size: var(--tool-card-action-font-size); font-weight: 500; cursor: pointer; - box-shadow: 0 2px 12px var(--color-overlay-black-10); + box-shadow: 0 2px 12px var(--color-overlay-black-12); transition: transform 0.2s ease, box-shadow 0.2s ease; &:hover { diff --git a/src/web-ui/src/flow_chat/components/btw/DeepReviewActionBar.scss b/src/web-ui/src/flow_chat/components/btw/DeepReviewActionBar.scss index fb1f022a36..3e63701522 100644 --- a/src/web-ui/src/flow_chat/components/btw/DeepReviewActionBar.scss +++ b/src/web-ui/src/flow_chat/components/btw/DeepReviewActionBar.scss @@ -16,7 +16,7 @@ line-height: var(--flowchat-support-line-height); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); - box-shadow: 0 4px 24px var(--color-overlay-black-15), 0 0 0 1px var(--color-overlay-white-06); + box-shadow: 0 4px 24px var(--color-overlay-black-15), 0 0 0 1px var(--color-overlay-white-08); overflow-x: hidden; overflow-y: auto; overscroll-behavior: contain; diff --git a/src/web-ui/src/flow_chat/components/modern/ModernFlowChatContainer.scss b/src/web-ui/src/flow_chat/components/modern/ModernFlowChatContainer.scss index fbcd7cc6f9..2f830cf349 100644 --- a/src/web-ui/src/flow_chat/components/modern/ModernFlowChatContainer.scss +++ b/src/web-ui/src/flow_chat/components/modern/ModernFlowChatContainer.scss @@ -125,7 +125,7 @@ } .history-session-placeholder__retry:hover { - background: var(--color-overlay-white-10); + background: var(--color-overlay-white-12); } .modern-flowchat-container__history-overlay { diff --git a/src/web-ui/src/flow_chat/components/smart-recommendations/SmartRecommendations.scss b/src/web-ui/src/flow_chat/components/smart-recommendations/SmartRecommendations.scss index 60e46ef026..e537180efe 100644 --- a/src/web-ui/src/flow_chat/components/smart-recommendations/SmartRecommendations.scss +++ b/src/web-ui/src/flow_chat/components/smart-recommendations/SmartRecommendations.scss @@ -70,7 +70,7 @@ background: var(--element-bg-hover); border-color: var(--color-accent-500); transform: translateY(-1px); - box-shadow: 0 2px 4px var(--color-overlay-black-10); + box-shadow: 0 2px 4px var(--color-overlay-black-12); } &:active:not(:disabled) { diff --git a/src/web-ui/src/flow_chat/tool-cards/BaseToolCard.scss b/src/web-ui/src/flow_chat/tool-cards/BaseToolCard.scss index e780aaa82b..73a912dbf2 100644 --- a/src/web-ui/src/flow_chat/tool-cards/BaseToolCard.scss +++ b/src/web-ui/src/flow_chat/tool-cards/BaseToolCard.scss @@ -25,7 +25,7 @@ border-color: var(--border-medium); box-shadow: 0 2px 8px var(--color-overlay-black-15), - 0 1px 4px var(--color-overlay-black-10), + 0 1px 4px var(--color-overlay-black-12), inset 0 1px 0 var(--color-overlay-white-04); } diff --git a/src/web-ui/src/flow_chat/tool-cards/CreatePlanDisplay.scss b/src/web-ui/src/flow_chat/tool-cards/CreatePlanDisplay.scss index 7fd290082d..cbfe998e1e 100644 --- a/src/web-ui/src/flow_chat/tool-cards/CreatePlanDisplay.scss +++ b/src/web-ui/src/flow_chat/tool-cards/CreatePlanDisplay.scss @@ -386,7 +386,7 @@ border-radius: 4px; cursor: pointer; transition: all 0.15s ease; - box-shadow: 0 1px 2px var(--color-overlay-black-10); + box-shadow: 0 1px 2px var(--color-overlay-black-12); &:hover:not(:disabled) { background: linear-gradient( @@ -434,7 +434,7 @@ var(--color-success) 0%, color-mix(in srgb, var(--color-success) 82%, var(--color-text-primary)) 100% ); - box-shadow: 0 1px 2px var(--color-overlay-black-10); + box-shadow: 0 1px 2px var(--color-overlay-black-12); } } } diff --git a/src/web-ui/src/flow_chat/tool-cards/DefaultToolCard.scss b/src/web-ui/src/flow_chat/tool-cards/DefaultToolCard.scss index 9fcb53f8df..b7b11ec913 100644 --- a/src/web-ui/src/flow_chat/tool-cards/DefaultToolCard.scss +++ b/src/web-ui/src/flow_chat/tool-cards/DefaultToolCard.scss @@ -182,7 +182,7 @@ } .default-tool-card__button--reject:hover:not(:disabled) { - background: var(--color-overlay-white-06); + background: var(--color-overlay-white-08); color: var(--color-text-primary); } diff --git a/src/web-ui/src/flow_chat/tool-cards/FileOperationToolCard.scss b/src/web-ui/src/flow_chat/tool-cards/FileOperationToolCard.scss index 25bef29437..5494ad1825 100644 --- a/src/web-ui/src/flow_chat/tool-cards/FileOperationToolCard.scss +++ b/src/web-ui/src/flow_chat/tool-cards/FileOperationToolCard.scss @@ -20,7 +20,7 @@ &.non-clickable { cursor: default; - border-color: var(--color-overlay-white-06); + border-color: var(--color-overlay-white-08); opacity: 0.85; &:hover { diff --git a/src/web-ui/src/flow_chat/tool-cards/MCPToolDisplay.scss b/src/web-ui/src/flow_chat/tool-cards/MCPToolDisplay.scss index 1b89f2c0ff..2f6c656e0d 100644 --- a/src/web-ui/src/flow_chat/tool-cards/MCPToolDisplay.scss +++ b/src/web-ui/src/flow_chat/tool-cards/MCPToolDisplay.scss @@ -64,7 +64,7 @@ &:not(:last-child) { margin-bottom: var(--flowchat-card-gap); padding-bottom: var(--flowchat-card-gap); - border-bottom: 1px solid var(--color-overlay-white-06); + border-bottom: 1px solid var(--color-overlay-white-08); } } diff --git a/src/web-ui/src/flow_chat/tool-cards/SnapshotFullscreenDiffViewer.css b/src/web-ui/src/flow_chat/tool-cards/SnapshotFullscreenDiffViewer.css index 23cff9076e..e45075ee5e 100644 --- a/src/web-ui/src/flow_chat/tool-cards/SnapshotFullscreenDiffViewer.css +++ b/src/web-ui/src/flow_chat/tool-cards/SnapshotFullscreenDiffViewer.css @@ -24,7 +24,7 @@ display: flex; flex-direction: column; overflow: hidden; - border: 1px solid var(--color-overlay-white-10); + border: 1px solid var(--color-overlay-white-12); box-shadow: 0 20px 60px var(--color-overlay-black-80); } @@ -35,7 +35,7 @@ justify-content: space-between; padding: 16px 20px; background: var(--color-bg-primary); - border-bottom: 1px solid var(--color-overlay-white-10); + border-bottom: 1px solid var(--color-overlay-white-12); flex-shrink: 0; } @@ -133,20 +133,20 @@ } .header-btn.close-btn { - background: var(--color-overlay-white-06); + background: var(--color-overlay-white-08); color: var(--color-overlay-white-70); - border: 1px solid var(--color-overlay-white-10); + border: 1px solid var(--color-overlay-white-12); } .header-btn.close-btn:hover { - background: var(--color-overlay-white-10); + background: var(--color-overlay-white-12); color: var(--color-overlay-white-90); } .header-divider { width: 1px; height: 24px; - background: var(--color-overlay-white-10); + background: var(--color-overlay-white-12); margin: 0 4px; } @@ -157,7 +157,7 @@ gap: 8px; padding: 12px 20px; background: var(--diff-fullscreen-nav-bg); - border-bottom: 1px solid var(--color-overlay-white-06); + border-bottom: 1px solid var(--color-overlay-white-08); flex-shrink: 0; overflow: hidden; } @@ -170,7 +170,7 @@ height: 28px; border: none; border-radius: 4px; - background: var(--color-overlay-white-06); + background: var(--color-overlay-white-08); color: var(--color-overlay-white-70); cursor: pointer; transition: all 0.2s ease; @@ -178,7 +178,7 @@ } .nav-btn:hover:not(:disabled) { - background: var(--color-overlay-white-10); + background: var(--color-overlay-white-12); color: var(--color-overlay-white-90); } @@ -219,7 +219,7 @@ } .file-tab:hover { - background: var(--color-overlay-white-06); + background: var(--color-overlay-white-08); color: var(--color-overlay-white-80); } @@ -261,7 +261,7 @@ justify-content: space-between; padding: 12px 20px; background: var(--diff-fullscreen-surface-bg); - border-bottom: 1px solid var(--color-overlay-white-06); + border-bottom: 1px solid var(--color-overlay-white-08); flex-shrink: 0; } diff --git a/src/web-ui/src/flow_chat/tool-cards/TaskToolDisplay.scss b/src/web-ui/src/flow_chat/tool-cards/TaskToolDisplay.scss index 9f1358ddc0..2ac818c486 100644 --- a/src/web-ui/src/flow_chat/tool-cards/TaskToolDisplay.scss +++ b/src/web-ui/src/flow_chat/tool-cards/TaskToolDisplay.scss @@ -248,7 +248,7 @@ font-weight: 500; flex-shrink: 0; color: var(--color-text-secondary); - background: var(--color-overlay-white-10); + background: var(--color-overlay-white-12); letter-spacing: 0.02em; } @@ -507,7 +507,7 @@ overflow: hidden; box-shadow: 0 2px 6px var(--color-overlay-black-15), - 0 1px 3px var(--color-overlay-black-10); + 0 1px 3px var(--color-overlay-black-12); // Strip the BaseToolCard's own border/background/shadow so it merges // into the wrapper; the wrapper provides the unified card chrome. diff --git a/src/web-ui/src/flow_chat/tool-cards/TerminalToolCard.scss b/src/web-ui/src/flow_chat/tool-cards/TerminalToolCard.scss index 34480f005a..0a49328ad7 100644 --- a/src/web-ui/src/flow_chat/tool-cards/TerminalToolCard.scss +++ b/src/web-ui/src/flow_chat/tool-cards/TerminalToolCard.scss @@ -319,14 +319,14 @@ left: 0; right: 0; bottom: 0; - background: linear-gradient(135deg, var(--color-overlay-white-10), transparent); + background: linear-gradient(135deg, var(--color-overlay-white-12), transparent); opacity: 0; transition: opacity 0.2s ease; z-index: 0; } &:hover:not(:disabled) { - background: var(--color-overlay-white-10); + background: var(--color-overlay-white-12); transform: scale(1.05); } @@ -379,7 +379,7 @@ color: var(--color-text-muted); &:hover:not(:disabled) { - background: var(--color-overlay-white-10); + background: var(--color-overlay-white-12); color: var(--color-text-secondary); box-shadow: none; } diff --git a/src/web-ui/src/infrastructure/config/components/SkillsConfig.scss b/src/web-ui/src/infrastructure/config/components/SkillsConfig.scss index 11dfee1aa7..2895e541cc 100644 --- a/src/web-ui/src/infrastructure/config/components/SkillsConfig.scss +++ b/src/web-ui/src/infrastructure/config/components/SkillsConfig.scss @@ -73,7 +73,7 @@ .search__wrapper { background: linear-gradient( 180deg, - var(--color-overlay-white-06) 0%, + var(--color-overlay-white-08) 0%, var(--color-overlay-white-04) 100% ); border: 1px solid var(--border-subtle); @@ -113,7 +113,7 @@ border-radius: $size-radius-lg; background: linear-gradient( 180deg, - var(--color-overlay-white-06) 0%, + var(--color-overlay-white-08) 0%, var(--color-overlay-white-04) 100% ); box-shadow: $shadow-xs; @@ -265,7 +265,7 @@ font-weight: $font-weight-medium; color: var(--color-text-muted); border: 1px solid var(--border-subtle); - background: var(--color-overlay-white-06); + background: var(--color-overlay-white-08); } &__market-item-action { diff --git a/src/web-ui/src/infrastructure/theme/core/ThemeService.test.ts b/src/web-ui/src/infrastructure/theme/core/ThemeService.test.ts index 44f53e13b3..27f5c442ef 100644 --- a/src/web-ui/src/infrastructure/theme/core/ThemeService.test.ts +++ b/src/web-ui/src/infrastructure/theme/core/ThemeService.test.ts @@ -103,17 +103,17 @@ describe('ThemeService runtime theme tokens', () => { expect(document.documentElement.style.getPropertyValue('--card-bg-default')).toBe('rgba(255, 255, 255, 0.04)'); expect(document.documentElement.style.getPropertyValue('--card-bg-subtle')).toBe('transparent'); - expect(document.documentElement.style.getPropertyValue('--card-bg-elevated')).toBe('rgba(255, 255, 255, 0.06)'); + expect(document.documentElement.style.getPropertyValue('--card-bg-elevated')).toBe('rgba(255, 255, 255, 0.08)'); expect(document.documentElement.style.getPropertyValue('--card-bg-hover')).toBe('rgba(255, 255, 255, 0.08)'); - expect(document.documentElement.style.getPropertyValue('--card-bg-active')).toBe('rgba(255, 255, 255, 0.1)'); + expect(document.documentElement.style.getPropertyValue('--card-bg-active')).toBe('rgba(255, 255, 255, 0.12)'); await service.applyTheme('bitfun-light'); expect(document.documentElement.style.getPropertyValue('--card-bg-default')).toBe('rgba(0, 0, 0, 0.08)'); - expect(document.documentElement.style.getPropertyValue('--card-bg-elevated')).toBe('rgba(0, 0, 0, 0.1)'); + expect(document.documentElement.style.getPropertyValue('--card-bg-elevated')).toBe('rgba(0, 0, 0, 0.12)'); expect(document.documentElement.style.getPropertyValue('--card-bg-subtle')).toBe('transparent'); - expect(document.documentElement.style.getPropertyValue('--card-bg-hover')).toBe('rgba(0, 0, 0, 0.1)'); - expect(document.documentElement.style.getPropertyValue('--card-bg-active')).toBe('rgba(0, 0, 0, 0.12)'); + expect(document.documentElement.style.getPropertyValue('--card-bg-hover')).toBe('rgba(0, 0, 0, 0.12)'); + expect(document.documentElement.style.getPropertyValue('--card-bg-active')).toBe('rgba(0, 0, 0, 0.15)'); }); it('keeps dark info border aligned with the canonical medium overlay stop', async () => { @@ -160,13 +160,18 @@ describe('ThemeService runtime theme tokens', () => { expect(document.documentElement.style.getPropertyValue('--scrollbar-thumb-hover')).toBe('rgba(255, 255, 255, 0.24)'); }); - it('exports canonical low-risk shadow overlay stops', async () => { + it('exports only the compact low-risk shadow overlay stops', async () => { const service = new ThemeService(); await service.applyTheme('bitfun-dark'); const rootStyle = document.documentElement.style; - expect(rootStyle.getPropertyValue('--color-overlay-white-06')).toBe('rgba(255, 255, 255, 0.06)'); + for (const [tone, stop] of [['white', '06'], ['white', '10'], ['black', '10']] as const) { + expect(rootStyle.getPropertyValue(`--color-overlay-${tone}-${stop}`)).toBe(''); + } + expect(rootStyle.getPropertyValue('--color-overlay-white-08')).toBe('rgba(255, 255, 255, 0.08)'); + expect(rootStyle.getPropertyValue('--color-overlay-white-12')).toBe('rgba(255, 255, 255, 0.12)'); + expect(rootStyle.getPropertyValue('--color-overlay-black-12')).toBe('rgba(0, 0, 0, 0.12)'); expect(rootStyle.getPropertyValue('--color-overlay-black-30')).toBe('rgba(0, 0, 0, 0.3)'); }); diff --git a/src/web-ui/src/infrastructure/theme/core/ThemeService.ts b/src/web-ui/src/infrastructure/theme/core/ThemeService.ts index a22764d9d0..35ad2e666b 100644 --- a/src/web-ui/src/infrastructure/theme/core/ThemeService.ts +++ b/src/web-ui/src/infrastructure/theme/core/ThemeService.ts @@ -51,16 +51,13 @@ const LINE_HEIGHT_TOKENS = ['tight', 'base', 'relaxed'] as const; const THEME_OVERLAYS = { white04: 'rgba(255, 255, 255, 0.04)', - white06: 'rgba(255, 255, 255, 0.06)', white08: 'rgba(255, 255, 255, 0.08)', - white10: 'rgba(255, 255, 255, 0.1)', white12: 'rgba(255, 255, 255, 0.12)', white15: 'rgba(255, 255, 255, 0.15)', white20: 'rgba(255, 255, 255, 0.2)', white24: 'rgba(255, 255, 255, 0.24)', white60: 'rgba(255, 255, 255, 0.6)', black08: 'rgba(0, 0, 0, 0.08)', - black10: 'rgba(0, 0, 0, 0.1)', black12: 'rgba(0, 0, 0, 0.12)', black15: 'rgba(0, 0, 0, 0.15)', black20: 'rgba(0, 0, 0, 0.2)', @@ -72,15 +69,12 @@ const THEME_OVERLAYS = { const THEME_OVERLAY_TOKEN_VALUES = [ ['--color-overlay-white-04', THEME_OVERLAYS.white04], - ['--color-overlay-white-06', THEME_OVERLAYS.white06], ['--color-overlay-white-08', THEME_OVERLAYS.white08], - ['--color-overlay-white-10', THEME_OVERLAYS.white10], ['--color-overlay-white-12', THEME_OVERLAYS.white12], ['--color-overlay-white-15', THEME_OVERLAYS.white15], ['--color-overlay-white-20', THEME_OVERLAYS.white20], ['--color-overlay-white-60', THEME_OVERLAYS.white60], ['--color-overlay-black-08', THEME_OVERLAYS.black08], - ['--color-overlay-black-10', THEME_OVERLAYS.black10], ['--color-overlay-black-12', THEME_OVERLAYS.black12], ['--color-overlay-black-15', THEME_OVERLAYS.black15], ['--color-overlay-black-20', THEME_OVERLAYS.black20], @@ -842,10 +836,10 @@ export class ThemeService { if (theme.type === 'dark') { root.style.setProperty('--card-bg-default', THEME_OVERLAYS.white04); - root.style.setProperty('--card-bg-elevated', THEME_OVERLAYS.white06); + root.style.setProperty('--card-bg-elevated', THEME_OVERLAYS.white08); root.style.setProperty('--card-bg-subtle', 'transparent'); root.style.setProperty('--card-bg-hover', THEME_OVERLAYS.white08); - root.style.setProperty('--card-bg-active', THEME_OVERLAYS.white10); + root.style.setProperty('--card-bg-active', THEME_OVERLAYS.white12); root.style.setProperty('--card-bg-accent', THEME_OVERLAYS.white08); root.style.setProperty('--card-bg-accent-hover', THEME_OVERLAYS.white12); root.style.setProperty('--card-bg-purple', 'rgba(139, 92, 246, 0.08)'); @@ -853,10 +847,10 @@ export class ThemeService { } else { root.style.setProperty('--card-bg-default', THEME_OVERLAYS.black08); - root.style.setProperty('--card-bg-elevated', THEME_OVERLAYS.black10); + root.style.setProperty('--card-bg-elevated', THEME_OVERLAYS.black12); root.style.setProperty('--card-bg-subtle', 'transparent'); - root.style.setProperty('--card-bg-hover', THEME_OVERLAYS.black10); - root.style.setProperty('--card-bg-active', THEME_OVERLAYS.black12); + root.style.setProperty('--card-bg-hover', THEME_OVERLAYS.black12); + root.style.setProperty('--card-bg-active', THEME_OVERLAYS.black15); root.style.setProperty('--card-bg-accent', 'rgba(15, 23, 42, 0.08)'); root.style.setProperty('--card-bg-accent-hover', 'rgba(15, 23, 42, 0.12)'); root.style.setProperty('--card-bg-purple', 'rgba(124, 58, 237, 0.12)'); diff --git a/src/web-ui/src/infrastructure/theme/presets/light-theme.ts b/src/web-ui/src/infrastructure/theme/presets/light-theme.ts index e7db7a0da8..fae0e016d7 100644 --- a/src/web-ui/src/infrastructure/theme/presets/light-theme.ts +++ b/src/web-ui/src/infrastructure/theme/presets/light-theme.ts @@ -53,10 +53,10 @@ export const bitfunLightTheme: ThemeConfig = { background: { primary: '#f3f3f5', secondary: STATIC_WHITE, - tertiary: '#e8eaee', + tertiary: '#e8e8e8', quaternary: '#e0e3e8', elevated: STATIC_WHITE, - workbench: '#e8eaee', + workbench: '#e8e8e8', scene: STATIC_WHITE, tooltip: rgbaFromHex(STATIC_WHITE, 0.98), }, diff --git a/src/web-ui/src/infrastructure/theme/presets/themePresetOutput.test.ts b/src/web-ui/src/infrastructure/theme/presets/themePresetOutput.test.ts index 6105b0fea3..a18eaf93ff 100644 --- a/src/web-ui/src/infrastructure/theme/presets/themePresetOutput.test.ts +++ b/src/web-ui/src/infrastructure/theme/presets/themePresetOutput.test.ts @@ -149,7 +149,7 @@ describe('builtin theme preset output', () => { }))).toMatchInlineSnapshot(` [ { - "hash": "816125c276e4ab9882815ddf1f79156418b426569c89737db39085054789041e", + "hash": "44f230d2565fcdfed0e47fc5ea7d3253fc0bdcf0550c6bdcde16fb18f580467a", "id": "bitfun-light", "type": "light", }, diff --git a/src/web-ui/src/shared/context-system/components/ContextCard/ContextCard.scss b/src/web-ui/src/shared/context-system/components/ContextCard/ContextCard.scss index b4b4185ba9..0c06ba729b 100644 --- a/src/web-ui/src/shared/context-system/components/ContextCard/ContextCard.scss +++ b/src/web-ui/src/shared/context-system/components/ContextCard/ContextCard.scss @@ -13,8 +13,8 @@ background: linear-gradient(135deg, var(--color-overlay-white-08) 0%, - var(--color-overlay-white-06) 50%, - var(--color-overlay-white-10) 100% + var(--color-overlay-white-08) 50%, + var(--color-overlay-white-12) 100% ); border: 1px solid var(--border-base); border-radius: $size-radius-base; @@ -305,7 +305,7 @@ transform: translateY(-2px); box-shadow: 0 8px 24px var(--color-accent-200), - 0 4px 12px var(--color-overlay-black-10); + 0 4px 12px var(--color-overlay-black-12); } &:active { diff --git a/src/web-ui/src/shared/theme/themeBoundaryFallbacks.ts b/src/web-ui/src/shared/theme/themeBoundaryFallbacks.ts index da682b8f91..9d29225cd2 100644 --- a/src/web-ui/src/shared/theme/themeBoundaryFallbacks.ts +++ b/src/web-ui/src/shared/theme/themeBoundaryFallbacks.ts @@ -12,7 +12,7 @@ const BOUNDARY_FALLBACK_COLOR = { error: '#ef4444', staticWhite: '#ffffff', staticBlack: '#000000', - overlayWhite06: 'rgba(255, 255, 255, 0.06)', + overlayWhite08: 'rgba(255, 255, 255, 0.08)', overlayWhite12: 'rgba(255, 255, 255, 0.12)', overlayWhite24: 'rgba(255, 255, 255, 0.24)', overlayBlack15: 'rgba(0, 0, 0, 0.15)', @@ -36,7 +36,7 @@ export const WIDGET_IFRAME_FALLBACK_COLOR = { borderSubtle: BOUNDARY_FALLBACK_COLOR.overlayWhite12, borderBase: BOUNDARY_FALLBACK_COLOR.overlayWhite12, borderMedium: BOUNDARY_FALLBACK_COLOR.overlayWhite24, - elementBgSubtle: BOUNDARY_FALLBACK_COLOR.overlayWhite06, + elementBgSubtle: BOUNDARY_FALLBACK_COLOR.overlayWhite08, elementBgBase: BOUNDARY_FALLBACK_COLOR.overlayWhite12, elementBgMedium: BOUNDARY_FALLBACK_COLOR.overlayWhite12, shadowBase: BOUNDARY_FALLBACK_COLOR.shadowBase, diff --git a/src/web-ui/src/tools/editor/components/DiffEditor.scss b/src/web-ui/src/tools/editor/components/DiffEditor.scss index c0fc89fc6c..77d85302bc 100644 --- a/src/web-ui/src/tools/editor/components/DiffEditor.scss +++ b/src/web-ui/src/tools/editor/components/DiffEditor.scss @@ -362,7 +362,7 @@ $_diff-error-max-width: 400px; transition: all 0.2s ease; &:hover { - background-color: var(--color-overlay-white-06) !important; + background-color: var(--color-overlay-white-08) !important; border-left-style: solid !important; border-right-style: solid !important; } diff --git a/src/web-ui/src/tools/editor/components/PlanViewer.scss b/src/web-ui/src/tools/editor/components/PlanViewer.scss index 079c3db0df..14dde6da07 100644 --- a/src/web-ui/src/tools/editor/components/PlanViewer.scss +++ b/src/web-ui/src/tools/editor/components/PlanViewer.scss @@ -201,7 +201,7 @@ border-radius: 4px; cursor: pointer; transition: all 0.15s ease; - box-shadow: 0 1px 2px var(--color-overlay-black-10); + box-shadow: 0 1px 2px var(--color-overlay-black-12); &:hover:not(:disabled) { background: linear-gradient(135deg, var(--color-warning) 0%, var(--color-warning) 100%); @@ -233,7 +233,7 @@ &:hover { background: linear-gradient(135deg, var(--color-success) 0%, var(--color-success) 100%); - box-shadow: 0 1px 2px var(--color-overlay-black-10); + box-shadow: 0 1px 2px var(--color-overlay-black-12); } } } diff --git a/src/web-ui/src/tools/editor/components/StatusBarPopovers/StatusBarPopovers.scss b/src/web-ui/src/tools/editor/components/StatusBarPopovers/StatusBarPopovers.scss index be269d1c60..104fd1fa94 100644 --- a/src/web-ui/src/tools/editor/components/StatusBarPopovers/StatusBarPopovers.scss +++ b/src/web-ui/src/tools/editor/components/StatusBarPopovers/StatusBarPopovers.scss @@ -74,7 +74,7 @@ &:focus-visible { outline: none; - background: var(--color-overlay-white-10); + background: var(--color-overlay-white-12); } &--active { diff --git a/src/web-ui/src/tools/editor/meditor/components/TiptapEditor.scss b/src/web-ui/src/tools/editor/meditor/components/TiptapEditor.scss index 0e95577245..00a165a810 100644 --- a/src/web-ui/src/tools/editor/meditor/components/TiptapEditor.scss +++ b/src/web-ui/src/tools/editor/meditor/components/TiptapEditor.scss @@ -464,7 +464,7 @@ .m-editor-inline-ai__panel { width: min(26rem, calc(100vw - #{$size-gap-8})); padding: 10px 10px 8px; - border: 1px solid var(--color-overlay-white-10); + border: 1px solid var(--color-overlay-white-12); border-radius: 12px; background: var(--color-bg-tertiary); backdrop-filter: blur(16px) saturate(1.2); diff --git a/src/web-ui/src/tools/editor/themes/bitfun-dark.theme.test.ts b/src/web-ui/src/tools/editor/themes/bitfun-dark.theme.test.ts index 73c0f54128..5f2c1c7d5d 100644 --- a/src/web-ui/src/tools/editor/themes/bitfun-dark.theme.test.ts +++ b/src/web-ui/src/tools/editor/themes/bitfun-dark.theme.test.ts @@ -29,4 +29,15 @@ describe('BitFunDarkTheme color roles', () => { expect(colors['editorWarning.foreground']).toBe(colors['minimap.warningHighlight']); expect(colors['editorLink.activeForeground']).toBe('#7DCFFF'); }); + + it('keeps diff text, line, and gutter strengths visually ordered', () => { + expect(colors['diffEditor.insertedTextBackground']).toBe('#23863625'); + expect(colors['diffEditor.insertedLineBackground']).toBe('#23863630'); + expect(colors['diffEditorGutter.insertedLineBackground']).toBe('#23863638'); + expect(colors['diffEditor.removedTextBackground']).toBe('#DA363325'); + expect(colors['diffEditor.removedLineBackground']).toBe('#DA363330'); + expect(colors['diffEditorGutter.removedLineBackground']).toBe('#DA363338'); + expect(colors['diffEditor.modifiedTextBackground']).toBe('#1F6FEB20'); + expect(colors['diffEditor.modifiedLineBackground']).toBe('#1F6FEB28'); + }); }); diff --git a/src/web-ui/src/tools/editor/themes/bitfun-dark.theme.ts b/src/web-ui/src/tools/editor/themes/bitfun-dark.theme.ts index 0331d1dded..ec268ca2f7 100644 --- a/src/web-ui/src/tools/editor/themes/bitfun-dark.theme.ts +++ b/src/web-ui/src/tools/editor/themes/bitfun-dark.theme.ts @@ -48,6 +48,17 @@ const MONACO_STATUS_COLOR = { link: '#7DCFFF', } as const; +const MONACO_DIFF_COLOR = { + insertedTextBackground: '#23863625', + insertedLineBackground: '#23863630', + insertedGutterBackground: '#23863638', + removedTextBackground: '#DA363325', + removedLineBackground: '#DA363330', + removedGutterBackground: '#DA363338', + modifiedTextBackground: '#1F6FEB20', + modifiedLineBackground: '#1F6FEB28', +} as const; + /** * BitFun Dark Theme Configuration * Follows Monaco Editor official theme format @@ -392,18 +403,18 @@ export const BitFunDarkTheme: editor.IStandaloneThemeData = { 'editorOverviewRuler.infoForeground': MONACO_BRAND_ACCENT.base, // Diff Editor (GitHub Dark style) - 'diffEditor.insertedTextBackground': '#23863625', - 'diffEditor.insertedLineBackground': '#23863630', + 'diffEditor.insertedTextBackground': MONACO_DIFF_COLOR.insertedTextBackground, + 'diffEditor.insertedLineBackground': MONACO_DIFF_COLOR.insertedLineBackground, 'diffEditor.insertedTextBorder': TRANSPARENT_MONACO_BORDER, - 'diffEditorGutter.insertedLineBackground': '#23863638', + 'diffEditorGutter.insertedLineBackground': MONACO_DIFF_COLOR.insertedGutterBackground, - 'diffEditor.removedTextBackground': '#DA363325', - 'diffEditor.removedLineBackground': '#DA363330', + 'diffEditor.removedTextBackground': MONACO_DIFF_COLOR.removedTextBackground, + 'diffEditor.removedLineBackground': MONACO_DIFF_COLOR.removedLineBackground, 'diffEditor.removedTextBorder': TRANSPARENT_MONACO_BORDER, - 'diffEditorGutter.removedLineBackground': '#DA363338', + 'diffEditorGutter.removedLineBackground': MONACO_DIFF_COLOR.removedGutterBackground, - 'diffEditor.modifiedTextBackground': '#1F6FEB20', - 'diffEditor.modifiedLineBackground': '#1F6FEB28', + 'diffEditor.modifiedTextBackground': MONACO_DIFF_COLOR.modifiedTextBackground, + 'diffEditor.modifiedLineBackground': MONACO_DIFF_COLOR.modifiedLineBackground, 'diffEditor.border': '#2A2D35', 'diffEditor.diagonalFill': MONACO_DARK_SURFACE.elevated, diff --git a/src/web-ui/src/tools/generative-widget/themePayload.test.ts b/src/web-ui/src/tools/generative-widget/themePayload.test.ts index 2c3faf9181..bd819785f2 100644 --- a/src/web-ui/src/tools/generative-widget/themePayload.test.ts +++ b/src/web-ui/src/tools/generative-widget/themePayload.test.ts @@ -10,8 +10,8 @@ import { } from './themePayload'; import { createWidgetThemeCompatibilityAliasCss } from './themePayloadCompatibility'; -const WIDGET_THEME_VAR_NAMES_HASH = 'fa725e4c7099958cc37c5e54214d3a07579d1f5dbf0e19dda129e77c57e7d16e'; -const WIDGET_THEME_STATIC_SHELL_VAR_NAMES_HASH = '2ba8869e0611a03f360347f93d39fc6427fe8006f9ae6513b7cd67472febd8e7'; +const WIDGET_THEME_VAR_NAMES_HASH = '3c69b6767d5c5aa2752af7eab4c68596f1ab6014397dac02fa2b70343c771981'; +const WIDGET_THEME_STATIC_SHELL_VAR_NAMES_HASH = '7c53d90b3bc30c9d1c8494bb3865f42108e10e747841bae493ad26bcb30bf9b8'; const RETIRED_WIDGET_THEME_COMPAT_KEYS = [ '--background-primary', '--background-secondary', @@ -49,7 +49,10 @@ const RETIRED_WIDGET_THEME_COMPAT_KEYS = [ '--color-overlay-white-02', '--color-overlay-white-03', '--color-overlay-white-05', + '--color-overlay-white-06', + '--color-overlay-white-10', '--color-overlay-black-06', + '--color-overlay-black-10', '--color-overlay-black-25', '--color-accent', '--color-accent-primary', @@ -121,6 +124,22 @@ const RETIRED_WIDGET_THEME_INTERNAL_KEYS = [ '--btn-ghost-active-shadow', '--btn-ghost-active-transform', ] as const; +const DERIVED_WIDGET_THEME_PAYLOAD_KEYS = [ + '--color-accent-50', + '--color-accent-100', + '--color-accent-200', + '--color-accent-300', + '--color-accent-400', + '--color-accent-700', + '--color-accent-800', + '--color-success-border', + '--color-warning-border', + '--color-error-border', + '--border-strong', + '--border-prominent', + '--element-bg-strong', + '--size-radius-md', +] as const; const STATIC_WIDGET_SHELL_THEME_VARS = new Set([ ...WIDGET_THEME_STATIC_SHELL_VAR_NAMES, '--font-family-mono', @@ -129,7 +148,7 @@ const STATIC_WIDGET_SHELL_THEME_VARS = new Set([ const LOCAL_ONLY_WIDGET_SHELL_KEYS = [ '--color-bg-workbench', '--color-overlay-white-08', - '--color-overlay-black-10', + '--color-overlay-black-12', '--glass-base', '--tool-card-header-pad-y', '--tool-card-action-line-height', @@ -195,7 +214,7 @@ describe('generated widget theme payload contract', () => { first: requestedNames[0], last: requestedNames[requestedNames.length - 1], }).toEqual({ - count: 94, + count: 80, hash: WIDGET_THEME_VAR_NAMES_HASH, first: '--color-bg-primary', last: '--btn-ghost-hover-border', @@ -216,28 +235,17 @@ describe('generated widget theme payload contract', () => { expect(requestedNames).not.toEqual(expect.arrayContaining(RETIRED_WIDGET_THEME_COMPAT_KEYS)); expect(requestedNames).not.toEqual(expect.arrayContaining(RETIRED_WIDGET_THEME_INTERNAL_KEYS)); + expect(requestedNames).not.toEqual(expect.arrayContaining(DERIVED_WIDGET_THEME_PAYLOAD_KEYS)); expect(requestedNames).toEqual( expect.arrayContaining([ - '--color-accent-50', - '--color-accent-100', - '--color-accent-200', - '--color-accent-300', - '--color-accent-400', '--color-accent-500', '--color-accent-500-rgb', '--color-accent-600', - '--color-accent-700', - '--color-accent-800', '--color-error', '--color-error-bg', - '--color-error-border', '--color-info', '--color-info-bg', '--color-info-border', - '--color-success-border', - '--color-warning-border', - '--border-strong', - '--border-prominent', '--size-radius-xl', '--size-gap-16', '--btn-primary-bg', @@ -290,6 +298,15 @@ describe('generated widget theme payload contract', () => { } }); + it('keeps derived widget keys resolvable without host payload reads', () => { + const { requestedNames } = readPayloadWithHostValues(); + + for (const name of DERIVED_WIDGET_THEME_PAYLOAD_KEYS) { + expect(requestedNames).not.toContain(name); + expect(name in WIDGET_THEME_FALLBACK_VARS || STATIC_WIDGET_SHELL_THEME_VARS.has(name)).toBe(true); + } + }); + it('renders fallback CSS from the same reviewed fallback map', () => { const css = createWidgetThemeFallbackCss(); @@ -317,7 +334,7 @@ describe('generated widget theme payload contract', () => { first: WIDGET_THEME_STATIC_SHELL_VAR_NAMES[0], last: WIDGET_THEME_STATIC_SHELL_VAR_NAMES[WIDGET_THEME_STATIC_SHELL_VAR_NAMES.length - 1], }).toEqual({ - count: 85, + count: 83, hash: WIDGET_THEME_STATIC_SHELL_VAR_NAMES_HASH, first: '--color-bg-quaternary', last: '--tool-card-action-font-weight', diff --git a/src/web-ui/src/tools/generative-widget/themePayload.ts b/src/web-ui/src/tools/generative-widget/themePayload.ts index a48cab3d0d..177b0ed987 100644 --- a/src/web-ui/src/tools/generative-widget/themePayload.ts +++ b/src/web-ui/src/tools/generative-widget/themePayload.ts @@ -32,7 +32,6 @@ const FALLBACK_VAR = { staticWhite: '--color-static-white', staticBlack: '--color-static-black', overlayWhite04: '--color-overlay-white-04', - overlayWhite06: '--color-overlay-white-06', overlayBlack08: '--color-overlay-black-08', overlayBlack30: '--color-overlay-black-30', borderSubtle: '--border-subtle', @@ -97,7 +96,6 @@ export const WIDGET_THEME_FALLBACK_VARS = { [FALLBACK_VAR.staticWhite]: WIDGET_IFRAME_FALLBACK_COLOR.staticWhite, [FALLBACK_VAR.staticBlack]: WIDGET_IFRAME_FALLBACK_COLOR.staticBlack, [FALLBACK_VAR.overlayWhite04]: `color-mix(in srgb, ${widgetVar(FALLBACK_VAR.staticWhite)} 4%, transparent)`, - [FALLBACK_VAR.overlayWhite06]: `color-mix(in srgb, ${widgetVar(FALLBACK_VAR.staticWhite)} 6%, transparent)`, [FALLBACK_VAR.overlayBlack08]: `color-mix(in srgb, ${widgetVar(FALLBACK_VAR.staticBlack)} 8%, transparent)`, [FALLBACK_VAR.overlayBlack30]: `color-mix(in srgb, ${widgetVar(FALLBACK_VAR.staticBlack)} 30%, transparent)`, [FALLBACK_VAR.borderSubtle]: WIDGET_IFRAME_FALLBACK_COLOR.borderSubtle, @@ -114,7 +112,7 @@ export const WIDGET_THEME_FALLBACK_VARS = { [FALLBACK_VAR.shadowSm]: `0 2px 4px ${WIDGET_IFRAME_FALLBACK_COLOR.shadowBase}`, [FALLBACK_VAR.sizeRadiusSm]: '6px', [FALLBACK_VAR.sizeRadiusBase]: '8px', - [FALLBACK_VAR.sizeRadiusMd]: '8px', + [FALLBACK_VAR.sizeRadiusMd]: widgetVar(FALLBACK_VAR.sizeRadiusBase), [FALLBACK_VAR.sizeRadiusLg]: '12px', [FALLBACK_VAR.sizeRadiusXl]: '16px', [FALLBACK_VAR.sizeRadius2xl]: '20px', @@ -142,12 +140,10 @@ const WIDGET_THEME_STATIC_SHELL_VARS = { '--color-bg-workbench': widgetVar(FALLBACK_VAR.bgPrimary), '--color-bg-tooltip': widgetVar(FALLBACK_VAR.bgElevated), '--color-overlay-white-08': `color-mix(in srgb, ${widgetVar(FALLBACK_VAR.staticWhite)} 8%, transparent)`, - '--color-overlay-white-10': `color-mix(in srgb, ${widgetVar(FALLBACK_VAR.staticWhite)} 10%, transparent)`, '--color-overlay-white-12': `color-mix(in srgb, ${widgetVar(FALLBACK_VAR.staticWhite)} 12%, transparent)`, '--color-overlay-white-15': `color-mix(in srgb, ${widgetVar(FALLBACK_VAR.staticWhite)} 15%, transparent)`, '--color-overlay-white-20': `color-mix(in srgb, ${widgetVar(FALLBACK_VAR.staticWhite)} 20%, transparent)`, '--color-overlay-white-60': `color-mix(in srgb, ${widgetVar(FALLBACK_VAR.staticWhite)} 60%, transparent)`, - '--color-overlay-black-10': `color-mix(in srgb, ${widgetVar(FALLBACK_VAR.staticBlack)} 10%, transparent)`, '--color-overlay-black-12': `color-mix(in srgb, ${widgetVar(FALLBACK_VAR.staticBlack)} 12%, transparent)`, '--color-overlay-black-15': `color-mix(in srgb, ${widgetVar(FALLBACK_VAR.staticBlack)} 15%, transparent)`, '--color-overlay-black-20': `color-mix(in srgb, ${widgetVar(FALLBACK_VAR.staticBlack)} 20%, transparent)`, @@ -256,27 +252,17 @@ const WIDGET_THEME_VAR_GROUPS = { FALLBACK_VAR.textDisabled, ], accent: [ - FALLBACK_VAR.accent50, - FALLBACK_VAR.accent100, - '--color-accent-200', - '--color-accent-300', - FALLBACK_VAR.accent400, FALLBACK_VAR.accent500, FALLBACK_VAR.accent500Rgb, FALLBACK_VAR.accent600, - '--color-accent-700', - '--color-accent-800', ], semantic: [ FALLBACK_VAR.success, FALLBACK_VAR.successBg, - '--color-success-border', FALLBACK_VAR.warning, FALLBACK_VAR.warningBg, - '--color-warning-border', FALLBACK_VAR.error, FALLBACK_VAR.errorBg, - FALLBACK_VAR.errorBorder, '--color-info', '--color-info-bg', '--color-info-border', @@ -285,15 +271,12 @@ const WIDGET_THEME_VAR_GROUPS = { FALLBACK_VAR.borderSubtle, FALLBACK_VAR.borderBase, FALLBACK_VAR.borderMedium, - '--border-strong', - '--border-prominent', ], elementGlassShadow: [ FALLBACK_VAR.elementBgSubtle, FALLBACK_VAR.elementBgSoft, FALLBACK_VAR.elementBgBase, FALLBACK_VAR.elementBgMedium, - '--element-bg-strong', FALLBACK_VAR.elementBgElevated, FALLBACK_VAR.elementBgHover, FALLBACK_VAR.shadowXs, @@ -302,7 +285,6 @@ const WIDGET_THEME_VAR_GROUPS = { shapeSpacingTypography: [ FALLBACK_VAR.sizeRadiusSm, FALLBACK_VAR.sizeRadiusBase, - FALLBACK_VAR.sizeRadiusMd, FALLBACK_VAR.sizeRadiusLg, FALLBACK_VAR.sizeRadiusXl, FALLBACK_VAR.sizeRadius2xl, diff --git a/src/web-ui/src/tools/generative-widget/themePayloadCompatibility.ts b/src/web-ui/src/tools/generative-widget/themePayloadCompatibility.ts index 794d10d501..cb0e6b9f87 100644 --- a/src/web-ui/src/tools/generative-widget/themePayloadCompatibility.ts +++ b/src/web-ui/src/tools/generative-widget/themePayloadCompatibility.ts @@ -38,8 +38,11 @@ const WIDGET_THEME_COMPAT_ALIAS_FALLBACKS = { '--color-warning-700': '--color-warning', '--color-overlay-white-02': '--color-overlay-white-04', '--color-overlay-white-03': '--color-overlay-white-04', - '--color-overlay-white-05': '--color-overlay-white-06', + '--color-overlay-white-05': '--color-overlay-white-08', + '--color-overlay-white-06': '--color-overlay-white-08', + '--color-overlay-white-10': '--color-overlay-white-12', '--color-overlay-black-06': '--color-overlay-black-08', + '--color-overlay-black-10': '--color-overlay-black-12', '--color-overlay-black-25': '--color-overlay-black-30', '--color-accent': '--color-accent-500', '--color-accent-primary': '--color-accent-500', diff --git a/src/web-ui/src/tools/git/components/GitDiffEditor/GitDiffEditor.scss b/src/web-ui/src/tools/git/components/GitDiffEditor/GitDiffEditor.scss index dbfb2c011f..6e73ac8ca4 100644 --- a/src/web-ui/src/tools/git/components/GitDiffEditor/GitDiffEditor.scss +++ b/src/web-ui/src/tools/git/components/GitDiffEditor/GitDiffEditor.scss @@ -216,7 +216,7 @@ $_diff-padding-desktop: 32px; right: $size-gap-3; padding: $size-gap-2 $size-gap-4; background: var(--color-overlay-black-80); - border: 1px solid var(--color-overlay-white-10); + border: 1px solid var(--color-overlay-white-12); border-radius: $size-radius-base; color: var(--color-text-secondary); font-size: var(--font-size-sm); diff --git a/src/web-ui/src/tools/git/components/GitDiffView/GitDiffView.scss b/src/web-ui/src/tools/git/components/GitDiffView/GitDiffView.scss index 070e637393..f08610e371 100644 --- a/src/web-ui/src/tools/git/components/GitDiffView/GitDiffView.scss +++ b/src/web-ui/src/tools/git/components/GitDiffView/GitDiffView.scss @@ -533,7 +533,7 @@ $opacity-high: 0.8 !default; &__ai-confidence-bar { width: 60px; height: 4px; - background: var(--color-overlay-white-10); + background: var(--color-overlay-white-12); border-radius: 2px; overflow: hidden; } diff --git a/src/web-ui/src/tools/git/components/GitGraphView/GitGraphView.scss b/src/web-ui/src/tools/git/components/GitGraphView/GitGraphView.scss index 7425e33089..a7d516e252 100644 --- a/src/web-ui/src/tools/git/components/GitGraphView/GitGraphView.scss +++ b/src/web-ui/src/tools/git/components/GitGraphView/GitGraphView.scss @@ -45,7 +45,7 @@ &__spinner { width: 32px; height: 32px; - border: 3px solid var(--color-overlay-white-10); + border: 3px solid var(--color-overlay-white-12); border-top-color: var(--color-accent-500); border-radius: 50%; animation: spin 0.8s linear infinite; @@ -224,7 +224,7 @@ &:hover { background: var(--element-bg-hover); - box-shadow: 0 1px 3px var(--color-overlay-black-10); + box-shadow: 0 1px 3px var(--color-overlay-black-12); z-index: 1; } diff --git a/src/web-ui/src/tools/git/components/GitSettingsView/GitSettingsView.scss b/src/web-ui/src/tools/git/components/GitSettingsView/GitSettingsView.scss index c0fecbd2e9..b05be42c24 100644 --- a/src/web-ui/src/tools/git/components/GitSettingsView/GitSettingsView.scss +++ b/src/web-ui/src/tools/git/components/GitSettingsView/GitSettingsView.scss @@ -201,7 +201,7 @@ $opacity-high: 0.8 !default; gap: $size-gap-2; margin-bottom: $size-gap-4; padding-bottom: $size-gap-2; - border-bottom: 1px solid var(--color-overlay-white-06); + border-bottom: 1px solid var(--color-overlay-white-08); } &__section-title { diff --git a/src/web-ui/src/tools/git/components/PushButton/PushButton.scss b/src/web-ui/src/tools/git/components/PushButton/PushButton.scss index 4cc1f224d1..7825c13bb6 100644 --- a/src/web-ui/src/tools/git/components/PushButton/PushButton.scss +++ b/src/web-ui/src/tools/git/components/PushButton/PushButton.scss @@ -16,7 +16,7 @@ &__main { border-top-right-radius: 0 !important; border-bottom-right-radius: 0 !important; - border-right: 1px solid var(--color-overlay-white-10) !important; + border-right: 1px solid var(--color-overlay-white-12) !important; padding-right: 8px !important; display: flex; @@ -76,8 +76,8 @@ white-space: nowrap; background: linear-gradient(135deg, var(--color-overlay-white-08) 0%, - var(--color-overlay-white-06) 50%, - var(--color-overlay-white-10) 100%); + var(--color-overlay-white-08) 50%, + var(--color-overlay-white-12) 100%); border: 1px solid var(--color-overlay-white-15); border-radius: 6px; cursor: pointer; @@ -93,7 +93,7 @@ box-shadow: 0 2px 8px var(--color-overlay-black-20), inset 0 1px 0 var(--color-overlay-white-15), - inset 0 -1px 0 var(--color-overlay-white-06); + inset 0 -1px 0 var(--color-overlay-white-08); &:last-child { margin-bottom: 0; @@ -182,7 +182,7 @@ &__menu-divider { height: 1px; - background: var(--color-overlay-white-10); + background: var(--color-overlay-white-12); margin: 4px 0; } } diff --git a/src/web-ui/src/tools/mermaid-editor/theme/_tokens.scss b/src/web-ui/src/tools/mermaid-editor/theme/_tokens.scss index 67a1701201..c0a5c44036 100644 --- a/src/web-ui/src/tools/mermaid-editor/theme/_tokens.scss +++ b/src/web-ui/src/tools/mermaid-editor/theme/_tokens.scss @@ -20,6 +20,7 @@ $mermaid-light-text-secondary: #475569; $mermaid-light-surface: #f3f4f6; $mermaid-light-section-alt-fill: #e8eaef; $mermaid-light-highlight-stroke: #334155; +$mermaid-light-note-text: #92400e; // ==================== Mermaid CSS variables ==================== // Define dark theme defaults in :root @@ -146,23 +147,23 @@ $mermaid-light-highlight-stroke: #334155; --mermaid-actor-text: #{$mermaid-light-text-primary}; --mermaid-signal-stroke: #{$mermaid-light-node-stroke}; --mermaid-signal-text: #{$mermaid-light-text-primary}; - --mermaid-note-fill: rgba(184, 134, 58, 0.12); - --mermaid-note-stroke: rgba(192, 140, 66, 0.4); - --mermaid-note-text: #92400e; + --mermaid-note-fill: color-mix(in srgb, var(--color-warning) 12%, transparent); + --mermaid-note-stroke: color-mix(in srgb, var(--color-warning) 40%, transparent); + --mermaid-note-text: #{$mermaid-light-note-text}; --mermaid-activation-fill: #{$mermaid-light-node-fill-hover}; --mermaid-activation-stroke: rgba(51, 65, 85, 0.35); // Gantt chart --mermaid-section-fill: #{$mermaid-light-surface}; --mermaid-section-alt-fill: #{$mermaid-light-section-alt-fill}; - --mermaid-grid-stroke: rgba(100, 116, 139, 0.15); + --mermaid-grid-stroke: color-mix(in srgb, var(--color-text-muted) 15%, transparent); --mermaid-task-text: #{$mermaid-light-text-primary}; - --mermaid-done-fill: rgba(91, 154, 111, 0.15); - --mermaid-done-stroke: #5b9a6f; + --mermaid-done-fill: var(--color-success-bg); + --mermaid-done-stroke: var(--color-success); --mermaid-active-fill: #{$mermaid-light-node-fill-hover}; --mermaid-active-stroke: #{$mermaid-light-highlight-stroke}; - --mermaid-crit-fill: rgba(194, 101, 101, 0.15); - --mermaid-crit-stroke: #c26565; + --mermaid-crit-fill: var(--color-error-bg); + --mermaid-crit-stroke: var(--color-error); // Pie chart - cohesive colors. --mermaid-pie-stroke: #{$mermaid-light-surface}; diff --git a/src/web-ui/src/tools/mermaid-editor/theme/mermaidThemeFallbacks.ts b/src/web-ui/src/tools/mermaid-editor/theme/mermaidThemeFallbacks.ts index 8002702d41..bed6885ef2 100644 --- a/src/web-ui/src/tools/mermaid-editor/theme/mermaidThemeFallbacks.ts +++ b/src/web-ui/src/tools/mermaid-editor/theme/mermaidThemeFallbacks.ts @@ -12,6 +12,7 @@ const DARK_NODE_STROKE_HOVER = '#6a6e7a'; const DARK_CLUSTER_TEXT = '#9ca3af'; const DARK_INFO = '#78a8d8'; const DARK_ERROR = '#e87878'; +const DARK_ERROR_FILL = 'rgba(232, 120, 120, 0.15)'; const LIGHT_NODE_FILL = '#e8eaef'; const LIGHT_NODE_FILL_HOVER = '#e0e2e8'; @@ -26,6 +27,7 @@ const LIGHT_HIGHLIGHT_STROKE = '#334155'; const LIGHT_ERROR = '#dc2626'; const LIGHT_WARNING = '#f59e0b'; const LIGHT_CLUSTER_FILL = 'rgba(229, 231, 235, 0.7)'; +const LIGHT_ERROR_FILL = 'rgba(239, 68, 68, 0.15)'; export const MERMAID_THEME_FALLBACKS = { dark: { @@ -65,7 +67,7 @@ export const MERMAID_THEME_FALLBACKS = { doneStroke: '#6dd4a0', activeFill: 'rgba(120, 168, 216, 0.15)', activeStroke: DARK_INFO, - critFill: 'rgba(232, 120, 120, 0.15)', + critFill: DARK_ERROR_FILL, critStroke: DARK_ERROR, warning: '#e8b060', info: DARK_INFO, @@ -77,7 +79,7 @@ export const MERMAID_THEME_FALLBACKS = { pieTitleText: DARK_NODE_TEXT, pieLegendText: DARK_CLUSTER_TEXT, pieStroke: DARK_NODE_FILL, - errorFill: 'rgba(232, 120, 120, 0.15)', + errorFill: DARK_ERROR_FILL, error: DARK_ERROR, highlightStroke: '#a8acb8', highlightGlow: 'drop-shadow(0 0 6px rgba(168, 172, 184, 0.4))', @@ -120,7 +122,7 @@ export const MERMAID_THEME_FALLBACKS = { doneStroke: '#16a34a', activeFill: 'rgba(15, 23, 42, 0.1)', activeStroke: LIGHT_HIGHLIGHT_STROKE, - critFill: 'rgba(239, 68, 68, 0.2)', + critFill: LIGHT_ERROR_FILL, critStroke: LIGHT_ERROR, warning: LIGHT_WARNING, info: '#64748b', @@ -132,7 +134,7 @@ export const MERMAID_THEME_FALLBACKS = { pieTitleText: LIGHT_TITLE_TEXT, pieLegendText: LIGHT_HIGHLIGHT_STROKE, pieStroke: MERMAID_SOFT_LIGHT_SURFACE, - errorFill: 'rgba(239, 68, 68, 0.15)', + errorFill: LIGHT_ERROR_FILL, error: LIGHT_ERROR, highlightStroke: LIGHT_HIGHLIGHT_STROKE, highlightGlow: 'drop-shadow(0 0 6px rgba(15, 23, 42, 0.18))', diff --git a/src/web-ui/src/tools/workspace/components/WorkspaceManager.css b/src/web-ui/src/tools/workspace/components/WorkspaceManager.css index 5698f40d66..7278315d02 100644 --- a/src/web-ui/src/tools/workspace/components/WorkspaceManager.css +++ b/src/web-ui/src/tools/workspace/components/WorkspaceManager.css @@ -21,7 +21,7 @@ box-shadow: 0 8px 32px color-mix(in srgb, var(--color-error) 12%, transparent), 0 4px 16px var(--color-overlay-black-08), - inset 0 1px 0 var(--color-overlay-white-10); + inset 0 1px 0 var(--color-overlay-white-12); } /* Section headings */ @@ -50,8 +50,8 @@ box-shadow: 0 8px 32px color-mix(in srgb, var(--color-accent-500) 12%, transparent), 0 4px 16px var(--color-overlay-black-08), - inset 0 1px 0 var(--color-overlay-white-10), - inset 0 -1px 0 var(--color-overlay-white-06); + inset 0 1px 0 var(--color-overlay-white-12), + inset 0 -1px 0 var(--color-overlay-white-08); transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); animation: slideInUp 0.4s ease-out; }