From 4b921af83bf1f76e31c098d93b40e01b4bc63452 Mon Sep 17 00:00:00 2001 From: GCWing Date: Mon, 7 Sep 2026 11:01:29 +0800 Subject: [PATCH 1/3] Unify status palettes with shared design system accents --- .../src/theme/installerThemesData.ts | 32 ----- .../packages/theme-openbitfun/README.md | 4 +- .../theme-openbitfun/scripts/build.mjs | 8 +- .../scripts/resolve-status-colors.mjs | 24 ++++ .../theme-openbitfun/src/dark.tokens.json | 27 ++-- .../src/high-contrast-dark.tokens.json | 12 +- .../src/high-contrast-light.tokens.json | 13 +- .../theme-openbitfun/src/light.tokens.json | 27 ++-- .../tests/theme-contract.test.mjs | 47 ++++--- .../ui/src/components/Alert/Alert.module.css | 8 +- .../ConfirmDialog/ConfirmDialog.module.css | 8 +- .../ui/src/components/Icon/Icon.module.css | 8 +- .../IconButton/IconButton.module.css | 2 +- .../StatusPill/StatusPill.module.css | 18 +++ .../tool-cards/FlowChatToolCard.module.css | 4 +- .../tool-cards/ToolCardStatusSlot.module.css | 8 +- .../tool-cards/ToolCardStatusSlot.tsx | 2 +- docs/architecture/theme-token-optimization.md | 16 +++ ...e-color-governance-baseline.installer.json | 4 +- scripts/theme-color-governance-baseline.json | 4 +- .../desktop/src/generated/bootstrap_theme.css | 27 ++-- .../generated/default_appearance_style.html | 16 +-- .../appearance/builtins/AppearancePalette.ts | 2 + .../builtins/appearancePresetOutput.test.ts | 119 ++++++++++-------- .../builtins/buildBuiltinAppearance.ts | 4 + .../appearance/builtins/chinaNight.ts | 16 +-- .../appearance/builtins/chinaStyle.ts | 17 +-- .../appearance/builtins/cyber.ts | 17 +-- .../appearance/builtins/dark.ts | 27 +--- .../appearance/builtins/light.ts | 30 +---- .../appearance/builtins/midnight.ts | 15 +-- .../appearance/builtins/monochrome.ts | 1 + .../appearance/builtins/paletteHelpers.ts | 50 ++++---- .../appearance/builtins/slate.ts | 20 +-- .../appearance/builtins/tokyoNight.ts | 20 +-- 35 files changed, 305 insertions(+), 352 deletions(-) create mode 100644 design-system/packages/theme-openbitfun/scripts/resolve-status-colors.mjs diff --git a/OpenBitFun-Installer/src/theme/installerThemesData.ts b/OpenBitFun-Installer/src/theme/installerThemesData.ts index 80330e1e8e..c968fa6c8d 100644 --- a/OpenBitFun-Installer/src/theme/installerThemesData.ts +++ b/OpenBitFun-Installer/src/theme/installerThemesData.ts @@ -63,7 +63,6 @@ type ThemeSeed = { secondary?: string; }; accent: string; - semantic?: Partial; }; function createBackground(seed: ThemeSeed['background']): BackgroundColors { @@ -140,7 +139,6 @@ function createInstallerTheme(seed: ThemeSeed): InstallerTheme { success: tone.semantic.success, warning: tone.semantic.warning, error: tone.semantic.error, - ...seed.semantic, }, border: { ...tone.border }, element: { ...tone.element }, @@ -157,11 +155,6 @@ export const THEMES: InstallerTheme[] = [ type: 'dark', background: { primary: MIDNIGHT_CARD_BACKGROUND, secondary: DARK_CARD_SURFACE }, accent: DEFAULT_BLUE, - semantic: { - success: '#6aab73', - warning: '#e0a055', - error: '#cc7f7a', - }, }), createInstallerTheme({ id: 'openbitfun-china-style', @@ -169,11 +162,6 @@ export const THEMES: InstallerTheme[] = [ type: 'light', background: { primary: '#faf8f0', secondary: '#f5f3e8' }, accent: '#2e5e8a', - semantic: { - success: '#52ad5a', - warning: '#f0a020', - error: '#c8102e', - }, }), createInstallerTheme({ id: 'openbitfun-china-night', @@ -181,11 +169,6 @@ export const THEMES: InstallerTheme[] = [ type: 'dark', background: { primary: '#1a1814', secondary: DARK_CARD_SURFACE }, accent: '#73a5cc', - semantic: { - success: '#6bc072', - warning: '#f5b555', - error: '#e85555', - }, }), createInstallerTheme({ id: 'openbitfun-cyber', @@ -193,11 +176,6 @@ export const THEMES: InstallerTheme[] = [ type: 'dark', background: { primary: '#0e0e10', secondary: DARK_CARD_SURFACE }, accent: '#00e6ff', - semantic: { - success: '#00ff9f', - warning: '#ffcc00', - error: '#ff0055', - }, }), createInstallerTheme({ id: 'openbitfun-tokyo-night', @@ -205,11 +183,6 @@ export const THEMES: InstallerTheme[] = [ type: 'dark', background: { primary: '#1a1b26', secondary: DARK_CARD_SURFACE }, accent: '#7aa2f7', - semantic: { - success: '#9ece6a', - warning: '#e0af68', - error: '#f7768e', - }, }), createInstallerTheme({ id: 'openbitfun-slate', @@ -217,11 +190,6 @@ export const THEMES: InstallerTheme[] = [ type: 'dark', background: { primary: DARK_CARD_SURFACE }, accent: '#7ab0ee', - semantic: { - success: '#7eb09b', - warning: '#f59e0b', - error: '#c9878d', - }, }), ]; diff --git a/design-system/packages/theme-openbitfun/README.md b/design-system/packages/theme-openbitfun/README.md index 6bdbb4ac95..cb312dba2c 100644 --- a/design-system/packages/theme-openbitfun/README.md +++ b/design-system/packages/theme-openbitfun/README.md @@ -33,4 +33,6 @@ The same data is available as `@openbitfun/theme-openbitfun/reference-colors.jso - `color.surface.tertiary` is an opaque low-emphasis fill for persistent grouped content such as cards and field groups. - `color.surface.subtle` is a translucent local tint for transient feedback and small inset details. It must not define a persistent application plane. - `color.selection.surface` owns persistent neutral selection. Hover and pressed colors remain action feedback and are not substitutes for selection. -- `color.codeChange.added` and `color.codeChange.removed` own code-line and compact diff-count accents; success/danger status and Git lifecycle colors remain separate semantics. +- `color.codeChange.added` (`#1aa73e`) and `color.codeChange.removed` (`#ec221f`) also anchor success and danger emphasis. Warning emphasis uses `#ff8c00`; information uses the existing creative-action blue (`#2e7eff`). These clear hues share light tints instead of separate per-component palettes. +- `color.status.*.emphasis` colors icons and short emphasis. `content` derives a readable shade from that anchor for text; `surface` and `border` derive 10% and 30% tints. High-contrast themes may strengthen text contrast without changing the emphasis anchors. +- Status source tokens retain their `color-mix()` references. The theme build resolves these mixes to concrete hex/RGBA values so CSS, plugins, and renderer payloads consume the same palette without relying on renderer-specific CSS color support. diff --git a/design-system/packages/theme-openbitfun/scripts/build.mjs b/design-system/packages/theme-openbitfun/scripts/build.mjs index fe6ae334e9..8a3fc239df 100644 --- a/design-system/packages/theme-openbitfun/scripts/build.mjs +++ b/design-system/packages/theme-openbitfun/scripts/build.mjs @@ -10,6 +10,7 @@ import { resolveTokens, tokenNameToCssVariable, } from "@openbitfun/token-engine"; +import { resolveStatusColors } from "./resolve-status-colors.mjs"; const packageDirectory = fileURLToPath(new URL("../", import.meta.url)); const sourceDirectory = path.join(packageDirectory, "src"); @@ -90,11 +91,11 @@ function createReferenceColorArtifacts(document, tokens) { const referenceColorArtifacts = createReferenceColorArtifacts(reference, referenceTokens); function selectSemanticTokens(tokens) { - return Object.fromEntries( + return resolveStatusColors(Object.fromEntries( Object.entries(tokens).filter(([name]) => PUBLIC_THEME_TOKEN_PREFIXES.some((prefix) => name.startsWith(prefix)), ), - ); + )); } const semanticThemes = { @@ -140,13 +141,16 @@ const requiredSemanticTokens = [ "color.identity.globalSearch.newProject", "color.identity.globalSearch.openFiles", "color.status.info.content", + "color.status.info.emphasis", "color.status.info.surface", "color.status.success.content", + "color.status.success.emphasis", "color.status.success.surface", "color.status.warning.content", "color.status.warning.emphasis", "color.status.warning.surface", "color.status.danger.content", + "color.status.danger.emphasis", "color.status.danger.surface", "effect.blur.base", "opacity.disabled", diff --git a/design-system/packages/theme-openbitfun/scripts/resolve-status-colors.mjs b/design-system/packages/theme-openbitfun/scripts/resolve-status-colors.mjs new file mode 100644 index 0000000000..48f2fcca50 --- /dev/null +++ b/design-system/packages/theme-openbitfun/scripts/resolve-status-colors.mjs @@ -0,0 +1,24 @@ +// Status authoring stays linked to its semantic anchors. Publish concrete colors +// because renderer payloads (including Mermaid and plugins) also consume them. +export function resolveStatusColors(tokens) { + return Object.fromEntries(Object.entries(tokens).map(([name, token]) => { + if (!name.startsWith("color.status.") || !token.value.startsWith("color-mix(")) { + return [name, token]; + } + + const match = /^color-mix\(in srgb, (#[0-9a-f]{6}) (\d+)%, (#[0-9a-f]{6}|transparent)\)$/i.exec(token.value); + if (!match || Number(match[2]) > 100) { + throw new Error(`Unsupported status color mix for ${name}: ${token.value}`); + } + const channels = (hex) => [1, 3, 5].map((offset) => Number.parseInt(hex.slice(offset, offset + 2), 16)); + const foreground = channels(match[1]); + const weight = Number(match[2]) / 100; + const value = match[3] === "transparent" + ? `rgba(${foreground.join(", ")}, ${weight})` + : `#${channels(match[3]).map((channel, index) => + Math.round(foreground[index] * weight + channel * (1 - weight)).toString(16).padStart(2, "0"), + ).join("")}`; + + return [name, { ...token, value }]; + })); +} diff --git a/design-system/packages/theme-openbitfun/src/dark.tokens.json b/design-system/packages/theme-openbitfun/src/dark.tokens.json index 8462711907..01d68d59d9 100644 --- a/design-system/packages/theme-openbitfun/src/dark.tokens.json +++ b/design-system/packages/theme-openbitfun/src/dark.tokens.json @@ -195,29 +195,32 @@ }, "status": { "info": { - "content": { "$type": "color", "$value": "{ref.color.neutral.400}" }, - "surface": { "$type": "color", "$value": "rgba(255, 255, 255, 0.08)" }, - "border": { "$type": "color", "$value": "rgba(255, 255, 255, 0.24)" } + "emphasis": { "$description": "Clear blue status emphasis, sharing the existing creative-action blue anchor.", "$type": "color", "$value": "{ref.color.blue.550}" }, + "content": { "$type": "color", "$value": "color-mix(in srgb, {color.status.info.emphasis} 62%, {ref.color.neutral.0})" }, + "surface": { "$type": "color", "$value": "color-mix(in srgb, {color.status.info.emphasis} 10%, transparent)" }, + "border": { "$type": "color", "$value": "color-mix(in srgb, {color.status.info.emphasis} 30%, transparent)" } }, "success": { - "content": { "$type": "color", "$value": "{ref.color.green.400}" }, - "surface": { "$type": "color", "$value": "rgba(52, 211, 153, 0.1)" }, - "border": { "$type": "color", "$value": "rgba(52, 211, 153, 0.3)" } + "emphasis": { "$description": "Status icons and short emphasis share the code-change anchor; use content for readable text.", "$type": "color", "$value": "{color.codeChange.added}" }, + "content": { "$type": "color", "$value": "color-mix(in srgb, {color.status.success.emphasis} 70%, {ref.color.neutral.0})" }, + "surface": { "$type": "color", "$value": "color-mix(in srgb, {color.status.success.emphasis} 10%, transparent)" }, + "border": { "$type": "color", "$value": "color-mix(in srgb, {color.status.success.emphasis} 30%, transparent)" } }, "warning": { - "content": { "$type": "color", "$value": "{ref.color.amber.500}" }, + "content": { "$type": "color", "$value": "color-mix(in srgb, {color.status.warning.emphasis} 94%, {ref.color.neutral.0})" }, "emphasis": { "$description": "Short warning-state emphasis using the product orange anchor; use warning content for longer text.", "$type": "color", "$value": "{ref.color.amber.550}" }, - "surface": { "$type": "color", "$value": "rgba(245, 158, 11, 0.1)" }, - "border": { "$type": "color", "$value": "rgba(245, 158, 11, 0.3)" } + "surface": { "$type": "color", "$value": "color-mix(in srgb, {color.status.warning.emphasis} 10%, transparent)" }, + "border": { "$type": "color", "$value": "color-mix(in srgb, {color.status.warning.emphasis} 30%, transparent)" } }, "danger": { - "content": { "$type": "color", "$value": "{ref.color.red.500}" }, - "surface": { "$type": "color", "$value": "rgba(239, 68, 68, 0.1)" }, - "border": { "$type": "color", "$value": "rgba(239, 68, 68, 0.3)" } + "emphasis": { "$description": "Status icons and short emphasis share the code-change anchor; use content for readable text.", "$type": "color", "$value": "{color.codeChange.removed}" }, + "content": { "$type": "color", "$value": "color-mix(in srgb, {color.status.danger.emphasis} 58%, {ref.color.neutral.0})" }, + "surface": { "$type": "color", "$value": "color-mix(in srgb, {color.status.danger.emphasis} 10%, transparent)" }, + "border": { "$type": "color", "$value": "color-mix(in srgb, {color.status.danger.emphasis} 30%, transparent)" } } } }, diff --git a/design-system/packages/theme-openbitfun/src/high-contrast-dark.tokens.json b/design-system/packages/theme-openbitfun/src/high-contrast-dark.tokens.json index ce62c97d1a..65e78d2401 100644 --- a/design-system/packages/theme-openbitfun/src/high-contrast-dark.tokens.json +++ b/design-system/packages/theme-openbitfun/src/high-contrast-dark.tokens.json @@ -52,8 +52,18 @@ "ring": { "$type": "color", "$value": "{ref.color.amber.400}" } }, "status": { + "info": { + "content": { "$type": "color", "$value": "color-mix(in srgb, {color.status.info.emphasis} 40%, {ref.color.neutral.0})" } + }, + "success": { + "content": { "$type": "color", "$value": "color-mix(in srgb, {color.status.success.emphasis} 35%, {ref.color.neutral.0})" } + }, "warning": { - "emphasis": { "$type": "color", "$value": "{ref.color.amber.400}" } + "content": { "$type": "color", "$value": "color-mix(in srgb, {color.status.warning.emphasis} 75%, {ref.color.neutral.0})" }, + "surface": { "$type": "color", "$value": "color-mix(in srgb, {color.status.warning.emphasis} 4%, transparent)" } + }, + "danger": { + "content": { "$type": "color", "$value": "color-mix(in srgb, {color.status.danger.emphasis} 40%, {ref.color.neutral.0})" } } } } diff --git a/design-system/packages/theme-openbitfun/src/high-contrast-light.tokens.json b/design-system/packages/theme-openbitfun/src/high-contrast-light.tokens.json index db6708a6dc..ae860587ba 100644 --- a/design-system/packages/theme-openbitfun/src/high-contrast-light.tokens.json +++ b/design-system/packages/theme-openbitfun/src/high-contrast-light.tokens.json @@ -52,9 +52,18 @@ "ring": { "$type": "color", "$value": "{ref.color.blue.700}" } }, "status": { + "info": { + "content": { "$type": "color", "$value": "color-mix(in srgb, {color.status.info.emphasis} 60%, {ref.color.neutral.1000})" } + }, + "success": { + "content": { "$type": "color", "$value": "color-mix(in srgb, {color.status.success.emphasis} 50%, {ref.color.neutral.1000})" } + }, "warning": { - "emphasis": { "$type": "color", "$value": "{ref.color.amber.800}" }, - "surface": { "$type": "color", "$value": "rgba(154, 101, 31, 0.04)" } + "content": { "$type": "color", "$value": "color-mix(in srgb, {color.status.warning.emphasis} 40%, {ref.color.neutral.1000})" }, + "surface": { "$type": "color", "$value": "color-mix(in srgb, {color.status.warning.emphasis} 4%, transparent)" } + }, + "danger": { + "content": { "$type": "color", "$value": "color-mix(in srgb, {color.status.danger.emphasis} 60%, {ref.color.neutral.1000})" } } } } diff --git a/design-system/packages/theme-openbitfun/src/light.tokens.json b/design-system/packages/theme-openbitfun/src/light.tokens.json index 788920386d..34a882bb11 100644 --- a/design-system/packages/theme-openbitfun/src/light.tokens.json +++ b/design-system/packages/theme-openbitfun/src/light.tokens.json @@ -195,29 +195,32 @@ }, "status": { "info": { - "content": { "$type": "color", "$value": "{ref.color.neutral.750}" }, - "surface": { "$type": "color", "$value": "{ref.color.neutral.100}" }, - "border": { "$type": "color", "$value": "rgba(16, 26, 39, 0.15)" } + "emphasis": { "$description": "Clear blue status emphasis, sharing the existing creative-action blue anchor.", "$type": "color", "$value": "{ref.color.blue.550}" }, + "content": { "$type": "color", "$value": "color-mix(in srgb, {color.status.info.emphasis} 76%, {ref.color.neutral.1000})" }, + "surface": { "$type": "color", "$value": "color-mix(in srgb, {color.status.info.emphasis} 10%, transparent)" }, + "border": { "$type": "color", "$value": "color-mix(in srgb, {color.status.info.emphasis} 30%, transparent)" } }, "success": { - "content": { "$type": "color", "$value": "{ref.color.green.700}" }, - "surface": { "$type": "color", "$value": "{ref.color.green.100}" }, - "border": { "$type": "color", "$value": "{ref.color.green.700}" } + "emphasis": { "$description": "Status icons and short emphasis share the code-change anchor; use content for readable text.", "$type": "color", "$value": "{color.codeChange.added}" }, + "content": { "$type": "color", "$value": "color-mix(in srgb, {color.status.success.emphasis} 68%, {ref.color.neutral.1000})" }, + "surface": { "$type": "color", "$value": "color-mix(in srgb, {color.status.success.emphasis} 10%, transparent)" }, + "border": { "$type": "color", "$value": "color-mix(in srgb, {color.status.success.emphasis} 30%, transparent)" } }, "warning": { - "content": { "$type": "color", "$value": "{ref.color.amber.800}" }, + "content": { "$type": "color", "$value": "color-mix(in srgb, {color.status.warning.emphasis} 54%, {ref.color.neutral.1000})" }, "emphasis": { "$description": "Short warning-state emphasis using the product orange anchor; use warning content for longer text.", "$type": "color", "$value": "{ref.color.amber.550}" }, - "surface": { "$type": "color", "$value": "rgba(154, 101, 31, 0.08)" }, - "border": { "$type": "color", "$value": "rgba(154, 101, 31, 0.25)" } + "surface": { "$type": "color", "$value": "color-mix(in srgb, {color.status.warning.emphasis} 10%, transparent)" }, + "border": { "$type": "color", "$value": "color-mix(in srgb, {color.status.warning.emphasis} 30%, transparent)" } }, "danger": { - "content": { "$type": "color", "$value": "{ref.color.red.700}" }, - "surface": { "$type": "color", "$value": "rgba(167, 67, 82, 0.12)" }, - "border": { "$type": "color", "$value": "rgba(167, 67, 82, 0.36)" } + "emphasis": { "$description": "Status icons and short emphasis share the code-change anchor; use content for readable text.", "$type": "color", "$value": "{color.codeChange.removed}" }, + "content": { "$type": "color", "$value": "color-mix(in srgb, {color.status.danger.emphasis} 80%, {ref.color.neutral.1000})" }, + "surface": { "$type": "color", "$value": "color-mix(in srgb, {color.status.danger.emphasis} 10%, transparent)" }, + "border": { "$type": "color", "$value": "color-mix(in srgb, {color.status.danger.emphasis} 30%, transparent)" } } } }, diff --git a/design-system/packages/theme-openbitfun/tests/theme-contract.test.mjs b/design-system/packages/theme-openbitfun/tests/theme-contract.test.mjs index 9db6acc424..3bf4ff581a 100644 --- a/design-system/packages/theme-openbitfun/tests/theme-contract.test.mjs +++ b/design-system/packages/theme-openbitfun/tests/theme-contract.test.mjs @@ -17,6 +17,7 @@ import { themeTokenCatalog, themes, } from "../dist/index.js"; +import { resolveStatusColors } from "../scripts/resolve-status-colors.mjs"; const packageDirectory = fileURLToPath(new URL("../", import.meta.url)); @@ -115,11 +116,29 @@ test("code-change semantics retain the requested addition and removal accents", } }); -test("warning emphasis retains the product orange anchor in default themes", () => { - assert.equal(themes.light["color.status.warning.emphasis"], "#ff8c00"); - assert.equal(themes.dark["color.status.warning.emphasis"], "#ff8c00"); - assert.equal(themes.highContrastLight["color.status.warning.emphasis"], "#75501d"); - assert.equal(themes.highContrastDark["color.status.warning.emphasis"], "#ffcc00"); +test("status families derive from the code-change and product emphasis anchors", async () => { + for (const mode of themeModes) { + const values = themes[mode]; + assert.equal(values["color.status.success.emphasis"], values["color.codeChange.added"]); + assert.equal(values["color.status.danger.emphasis"], values["color.codeChange.removed"]); + assert.equal(values["color.status.info.emphasis"], values["color.identity.harness.creative"]); + } + + // Editing the canonical addition anchor must reach every derived status role. + const source = mergeTokenDocuments(await readSource("reference.tokens.json"), await readSource("light.tokens.json")); + source.color.codeChange.added.$value = "#123456"; + const updated = resolveStatusColors(resolveTokens(source)); + assert.equal(updated["color.status.success.emphasis"].value, "#123456"); + assert.equal(updated["color.status.success.content"].value, "#0c233a"); + assert.equal(updated["color.status.success.surface"].value, "rgba(18, 52, 86, 0.1)"); + assert.equal(updated["color.status.success.border"].value, "rgba(18, 52, 86, 0.3)"); + assert.equal(updated["color.status.success.content"].sourceValue, source.color.status.success.content.$value); +}); + +test("warning emphasis retains the product orange anchor in every theme", () => { + for (const mode of themeModes) { + assert.equal(themes[mode]["color.status.warning.emphasis"], "#ff8c00"); + } }); test("semantic theme documents route solid colors through reference scales", async () => { @@ -166,20 +185,10 @@ test("all theme variants expose the same semantic theme contract", async () => { } }); -test("text, action, and field focus pairs meet their contrast requirements", async () => { - const [reference, light, dark, highContrastLight, highContrastDark] = await Promise.all([ - readSource("reference.tokens.json"), - readSource("light.tokens.json"), - readSource("dark.tokens.json"), - readSource("high-contrast-light.tokens.json"), - readSource("high-contrast-dark.tokens.json"), +test("text, action, and field focus pairs meet their contrast requirements", () => { + const variants = Object.entries(themes).map(([mode, values]) => [ + mode, Object.fromEntries(Object.entries(values).map(([name, value]) => [name, { value }])), ]); - const variants = [ - ["light", resolveTokens(mergeTokenDocuments(reference, light))], - ["dark", resolveTokens(mergeTokenDocuments(reference, dark))], - ["highContrastLight", resolveTokens(mergeTokenDocuments(reference, light, highContrastLight))], - ["highContrastDark", resolveTokens(mergeTokenDocuments(reference, dark, highContrastDark))], - ]; for (const [mode, variant] of variants) { const backdrop = parseColor(variant["color.surface.canvas"].value); @@ -294,7 +303,7 @@ test("default modes preserve the built-in Appearance anchor values", () => { assert.equal(themes.light["color.identity.globalSearch.openProject"], "#059cb0"); assert.equal(themes.light["color.identity.globalSearch.newProject"], "#3271d7"); assert.equal(themes.light["color.identity.globalSearch.openFiles"], "#9e54ff"); - assert.equal(themes.light["color.status.warning.surface"], "rgba(154, 101, 31, 0.08)"); + assert.equal(themes.light["color.status.warning.surface"], "rgba(255, 140, 0, 0.1)"); assert.equal(themes.light["shadow.base"], "0 4px 8px rgba(16, 26, 39, 0.07)"); assert.equal(themes.light["shadow.composer"], "0 2px 6px rgba(0, 0, 0, 0.08)"); assert.equal(themes.light["shadow.menu"], "0 4px 10px rgba(0, 0, 0, 0.12)"); diff --git a/design-system/packages/ui/src/components/Alert/Alert.module.css b/design-system/packages/ui/src/components/Alert/Alert.module.css index 028719062d..0ae4252436 100644 --- a/design-system/packages/ui/src/components/Alert/Alert.module.css +++ b/design-system/packages/ui/src/components/Alert/Alert.module.css @@ -1,8 +1,8 @@ @layer openbitfun.components { - .root { display: flex; align-items: flex-start; gap: var(--openbitfun-space-3); padding: var(--openbitfun-space-3) var(--openbitfun-space-4); border: var(--openbitfun-border-width-default) solid var(--openbitfun-color-status-info-border); border-radius: var(--openbitfun-radius-base); color: var(--openbitfun-color-status-info-content); background: var(--openbitfun-color-status-info-surface); font-family: var(--openbitfun-type-body-sm-font-family); font-size: var(--openbitfun-type-body-sm-font-size); font-weight: var(--openbitfun-type-body-sm-font-weight); line-height: var(--openbitfun-type-body-sm-line-height); letter-spacing: var(--openbitfun-type-body-sm-letter-spacing); } - .root[data-openbitfun-tone="success"] { border-color: var(--openbitfun-color-status-success-border); color: var(--openbitfun-color-status-success-content); background: var(--openbitfun-color-status-success-surface); } - .root[data-openbitfun-tone="warning"] { border-color: var(--openbitfun-color-status-warning-border); color: var(--openbitfun-color-status-warning-content); background: var(--openbitfun-color-status-warning-surface); } - .root[data-openbitfun-tone="error"] { border-color: var(--openbitfun-color-status-danger-border); color: var(--openbitfun-color-status-danger-content); background: var(--openbitfun-color-status-danger-surface); } + .root { display: flex; align-items: flex-start; gap: var(--openbitfun-space-3); padding: var(--openbitfun-space-3) var(--openbitfun-space-4); border: var(--openbitfun-border-width-default) solid var(--openbitfun-color-status-info-border); border-radius: var(--openbitfun-radius-base); color: var(--openbitfun-color-status-info-emphasis); background: var(--openbitfun-color-status-info-surface); font-family: var(--openbitfun-type-body-sm-font-family); font-size: var(--openbitfun-type-body-sm-font-size); font-weight: var(--openbitfun-type-body-sm-font-weight); line-height: var(--openbitfun-type-body-sm-line-height); letter-spacing: var(--openbitfun-type-body-sm-letter-spacing); } + .root[data-openbitfun-tone="success"] { border-color: var(--openbitfun-color-status-success-border); color: var(--openbitfun-color-status-success-emphasis); background: var(--openbitfun-color-status-success-surface); } + .root[data-openbitfun-tone="warning"] { border-color: var(--openbitfun-color-status-warning-border); color: var(--openbitfun-color-status-warning-emphasis); background: var(--openbitfun-color-status-warning-surface); } + .root[data-openbitfun-tone="error"] { border-color: var(--openbitfun-color-status-danger-border); color: var(--openbitfun-color-status-danger-emphasis); background: var(--openbitfun-color-status-danger-surface); } .icon { display: inline-flex; flex: 0 0 auto; margin-block-start: 1px; } .content { display: flex; flex: 1 1 auto; min-inline-size: 0; flex-direction: column; gap: var(--openbitfun-space-1); } .title { color: var(--openbitfun-color-content-primary); font-family: var(--openbitfun-type-heading-card-font-family); font-size: var(--openbitfun-type-heading-card-font-size); font-weight: var(--openbitfun-type-heading-card-font-weight); line-height: var(--openbitfun-type-heading-card-line-height); letter-spacing: var(--openbitfun-type-heading-card-letter-spacing); } diff --git a/design-system/packages/ui/src/components/ConfirmDialog/ConfirmDialog.module.css b/design-system/packages/ui/src/components/ConfirmDialog/ConfirmDialog.module.css index b4d9b7018d..1f70697a22 100644 --- a/design-system/packages/ui/src/components/ConfirmDialog/ConfirmDialog.module.css +++ b/design-system/packages/ui/src/components/ConfirmDialog/ConfirmDialog.module.css @@ -29,7 +29,7 @@ inline-size: var(--openbitfun-layout-confirm-dialog-icon-size); block-size: var(--openbitfun-layout-confirm-dialog-icon-size); border-radius: var(--openbitfun-radius-pill); - color: var(--openbitfun-color-status-info-content); + color: var(--openbitfun-color-status-info-emphasis); background: var(--openbitfun-color-status-info-surface); } @@ -40,17 +40,17 @@ } .icon[data-openbitfun-status="success"] { - color: var(--openbitfun-color-status-success-content); + color: var(--openbitfun-color-status-success-emphasis); background: var(--openbitfun-color-status-success-surface); } .icon[data-openbitfun-status="warning"] { - color: var(--openbitfun-color-status-warning-content); + color: var(--openbitfun-color-status-warning-emphasis); background: var(--openbitfun-color-status-warning-surface); } .icon[data-openbitfun-status="danger"] { - color: var(--openbitfun-color-status-danger-content); + color: var(--openbitfun-color-status-danger-emphasis); background: var(--openbitfun-color-status-danger-surface); } diff --git a/design-system/packages/ui/src/components/Icon/Icon.module.css b/design-system/packages/ui/src/components/Icon/Icon.module.css index 3c1174e16e..3d106132d6 100644 --- a/design-system/packages/ui/src/components/Icon/Icon.module.css +++ b/design-system/packages/ui/src/components/Icon/Icon.module.css @@ -62,19 +62,19 @@ } .icon[data-openbitfun-tone="info"] { - color: var(--openbitfun-color-status-info-content); + color: var(--openbitfun-color-status-info-emphasis); } .icon[data-openbitfun-tone="success"] { - color: var(--openbitfun-color-status-success-content); + color: var(--openbitfun-color-status-success-emphasis); } .icon[data-openbitfun-tone="warning"] { - color: var(--openbitfun-color-status-warning-content); + color: var(--openbitfun-color-status-warning-emphasis); } .icon[data-openbitfun-tone="danger"] { - color: var(--openbitfun-color-status-danger-content); + color: var(--openbitfun-color-status-danger-emphasis); } @media (forced-colors: active) { diff --git a/design-system/packages/ui/src/components/IconButton/IconButton.module.css b/design-system/packages/ui/src/components/IconButton/IconButton.module.css index 9553635ae4..b57938e9de 100644 --- a/design-system/packages/ui/src/components/IconButton/IconButton.module.css +++ b/design-system/packages/ui/src/components/IconButton/IconButton.module.css @@ -80,7 +80,7 @@ .button[data-openbitfun-tone="danger"] { --_icon-button-background-hover: var(--openbitfun-color-status-danger-surface); --_icon-button-background-active: var(--openbitfun-color-status-danger-surface); - --_icon-button-content: var(--openbitfun-color-status-danger-content); + --_icon-button-content: var(--openbitfun-color-status-danger-emphasis); } .button[data-openbitfun-tone="danger"][data-openbitfun-variant="fill"] { diff --git a/design-system/packages/ui/src/components/StatusPill/StatusPill.module.css b/design-system/packages/ui/src/components/StatusPill/StatusPill.module.css index 1e56fbecea..ddb2143a89 100644 --- a/design-system/packages/ui/src/components/StatusPill/StatusPill.module.css +++ b/design-system/packages/ui/src/components/StatusPill/StatusPill.module.css @@ -70,7 +70,25 @@ background: var(--openbitfun-color-status-danger-surface); } + .root[data-tone="info"] .leading { + color: var(--openbitfun-color-status-info-emphasis); + } + + .root[data-tone="success"] .leading { + color: var(--openbitfun-color-status-success-emphasis); + } + + .root[data-tone="warning"] .leading { + color: var(--openbitfun-color-status-warning-emphasis); + } + + .root[data-tone="danger"] .leading { + color: var(--openbitfun-color-status-danger-emphasis); + } + @media (forced-colors: active) { + .root[data-tone] .leading { color: CanvasText; } + .root { border: var(--openbitfun-border-width-default) solid CanvasText; color: CanvasText; diff --git a/design-system/packages/ui/src/flow-chat/tool-cards/FlowChatToolCard.module.css b/design-system/packages/ui/src/flow-chat/tool-cards/FlowChatToolCard.module.css index 567085aff3..cdc1069874 100644 --- a/design-system/packages/ui/src/flow-chat/tool-cards/FlowChatToolCard.module.css +++ b/design-system/packages/ui/src/flow-chat/tool-cards/FlowChatToolCard.module.css @@ -364,11 +364,11 @@ } .prominentRoot[data-openbitfun-status="completed"] .statusIcon { - color: var(--openbitfun-color-status-success-content); + color: var(--openbitfun-color-status-success-emphasis); } .prominentRoot[data-openbitfun-status="error"] .statusIcon { - color: var(--openbitfun-color-status-danger-content); + color: var(--openbitfun-color-status-danger-emphasis); } .collapse { diff --git a/design-system/packages/ui/src/flow-chat/tool-cards/ToolCardStatusSlot.module.css b/design-system/packages/ui/src/flow-chat/tool-cards/ToolCardStatusSlot.module.css index c612c7775f..a77493ff23 100644 --- a/design-system/packages/ui/src/flow-chat/tool-cards/ToolCardStatusSlot.module.css +++ b/design-system/packages/ui/src/flow-chat/tool-cards/ToolCardStatusSlot.module.css @@ -38,11 +38,15 @@ } .success { - color: var(--openbitfun-color-status-success-content); + color: var(--openbitfun-color-status-success-emphasis); } .danger { - color: var(--openbitfun-color-status-danger-content); + color: var(--openbitfun-color-status-danger-emphasis); + } + + .statusLayer .processing { + color: var(--openbitfun-color-status-info-emphasis); } .muted { diff --git a/design-system/packages/ui/src/flow-chat/tool-cards/ToolCardStatusSlot.tsx b/design-system/packages/ui/src/flow-chat/tool-cards/ToolCardStatusSlot.tsx index 7f7af26d02..c183880128 100644 --- a/design-system/packages/ui/src/flow-chat/tool-cards/ToolCardStatusSlot.tsx +++ b/design-system/packages/ui/src/flow-chat/tool-cards/ToolCardStatusSlot.tsx @@ -41,7 +41,7 @@ function StatusGlyph({ case "waiting": return ; default: - return ; + return ; } } diff --git a/docs/architecture/theme-token-optimization.md b/docs/architecture/theme-token-optimization.md index 87b8ec5d1c..2008504d70 100644 --- a/docs/architecture/theme-token-optimization.md +++ b/docs/architecture/theme-token-optimization.md @@ -64,6 +64,22 @@ Desktop bootstrap 和产品前端也不能反向定义公共主题值。 Primitive/reference 色值只存在于主题 authoring、明确的主题 preset 或专用 renderer owner 中。普通组件 不得直接消费 reference ramp,也不得自行定义“看起来差不多”的局部颜色。 +### 状态色与增删行色 + +普通 UI 的状态色统一由设计系统定义。成功强调色引用 `color.codeChange.added`(`#1aa73e`), +错误/危险强调色引用 `color.codeChange.removed`(`#ec221f`);警告固定使用 `#ff8c00`, +信息/进行中复用已有的清亮蓝 `ref.color.blue.550`(`#2e7eff`)。这组鲜明色相搭配淡着色背景, +避免在不同页面或内置皮肤中混入灰绿、粉红和另一套橙黄色。 + +- `color.status.*.emphasis` 用于图标和短强调,与增删行等源色对齐。 +- `content` 从同一 emphasis 混入黑/白来保证长文本可读,`surface` 和 `border` 分别使用 10% 与 30% 着色。 + 高对比模式可以增强文字和底色的对比,但不改动强调色锚点。 +- 三个新增 emphasis Token(info/success/danger)由 Icon、Alert、ConfirmDialog、StatusPill 和工具卡状态图标 + 消费;它们区分图形强调与可读文本,不能用于重新建立局部色板。 +- 状态源文件保留 Token 引用和混色关系,主题构建将它们解析为 hex/RGBA,以便 CSS 与专用 renderer + 使用同一结果。内置 Appearance 和 Installer 只选取这些状态值,不再接受私有状态色覆盖;Git 增删、暂存和 + 变更状态也由相同源色派生。第三方 Appearance 的现有 Token 名称与导入格式保持可读。 + 新增颜色按以下顺序判断: 1. 语义相同,直接复用现有 semantic Token。 diff --git a/scripts/theme-color-governance-baseline.installer.json b/scripts/theme-color-governance-baseline.installer.json index b69327963d..4e3eb2fac2 100644 --- a/scripts/theme-color-governance-baseline.installer.json +++ b/scripts/theme-color-governance-baseline.installer.json @@ -43,8 +43,8 @@ "colorDomainScopes.appUi.uniqueColors": { "max": 0 }, "colorDomainNearPairs.themePreset.indistinguishableTotal": { "max": 0 }, "colorDomainNearPairs.themePreset.nearTotal": { "max": 0 }, - "colorDomainScopes.themePreset.occurrences": { "max": 29 }, - "colorDomainScopes.themePreset.uniqueColors": { "max": 29 }, + "colorDomainScopes.themePreset.occurrences": { "max": 11 }, + "colorDomainScopes.themePreset.uniqueColors": { "max": 11 }, "colorDomainScopes.tokenContract.occurrences": { "max": 0 }, "colorDomainScopes.tokenContract.uniqueColors": { "max": 0 }, "colorDomainScopes.assetMetadata.occurrences": { "max": 0 }, diff --git a/scripts/theme-color-governance-baseline.json b/scripts/theme-color-governance-baseline.json index dceb039bf0..de98a92a4a 100644 --- a/scripts/theme-color-governance-baseline.json +++ b/scripts/theme-color-governance-baseline.json @@ -258,10 +258,10 @@ "max": 0 }, "colorDomainScopes.themePreset.occurrences": { - "max": 128 + "max": 106 }, "colorDomainScopes.themePreset.uniqueColors": { - "max": 98 + "max": 78 }, "colorDomainScopes.themeRuntime.occurrences": { "max": 0 diff --git a/src/apps/desktop/src/generated/bootstrap_theme.css b/src/apps/desktop/src/generated/bootstrap_theme.css index 03403cd929..21f99392e9 100644 --- a/src/apps/desktop/src/generated/bootstrap_theme.css +++ b/src/apps/desktop/src/generated/bootstrap_theme.css @@ -85,19 +85,22 @@ --openbitfun-color-scrollbar-thumb: rgba(255, 255, 255, 0.12); --openbitfun-color-scrollbar-thumb-hover: rgba(255, 255, 255, 0.15); --openbitfun-color-selection-surface: rgba(255, 255, 255, 0.12); - --openbitfun-color-status-danger-border: rgba(239, 68, 68, 0.3); - --openbitfun-color-status-danger-content: #ef4444; - --openbitfun-color-status-danger-surface: rgba(239, 68, 68, 0.1); - --openbitfun-color-status-info-border: rgba(255, 255, 255, 0.24); - --openbitfun-color-status-info-content: #a1a1aa; - --openbitfun-color-status-info-surface: rgba(255, 255, 255, 0.08); - --openbitfun-color-status-success-border: rgba(52, 211, 153, 0.3); - --openbitfun-color-status-success-content: #34d399; - --openbitfun-color-status-success-surface: rgba(52, 211, 153, 0.1); - --openbitfun-color-status-warning-border: rgba(245, 158, 11, 0.3); - --openbitfun-color-status-warning-content: #f59e0b; + --openbitfun-color-status-danger-border: rgba(236, 34, 31, 0.3); + --openbitfun-color-status-danger-content: #f47f7d; + --openbitfun-color-status-danger-emphasis: #ec221f; + --openbitfun-color-status-danger-surface: rgba(236, 34, 31, 0.1); + --openbitfun-color-status-info-border: rgba(46, 126, 255, 0.3); + --openbitfun-color-status-info-content: #7dafff; + --openbitfun-color-status-info-emphasis: #2e7eff; + --openbitfun-color-status-info-surface: rgba(46, 126, 255, 0.1); + --openbitfun-color-status-success-border: rgba(26, 167, 62, 0.3); + --openbitfun-color-status-success-content: #5fc178; + --openbitfun-color-status-success-emphasis: #1aa73e; + --openbitfun-color-status-success-surface: rgba(26, 167, 62, 0.1); + --openbitfun-color-status-warning-border: rgba(255, 140, 0, 0.3); + --openbitfun-color-status-warning-content: #ff930f; --openbitfun-color-status-warning-emphasis: #ff8c00; - --openbitfun-color-status-warning-surface: rgba(245, 158, 11, 0.1); + --openbitfun-color-status-warning-surface: rgba(255, 140, 0, 0.1); --openbitfun-color-surface-canvas: #0e0e10; --openbitfun-color-surface-chrome: #0e0e10; --openbitfun-color-surface-panel: #1c1c1f; diff --git a/src/crates/contracts/product-domains/src/miniapp/generated/default_appearance_style.html b/src/crates/contracts/product-domains/src/miniapp/generated/default_appearance_style.html index 5c10260dde..1b9394556d 100644 --- a/src/crates/contracts/product-domains/src/miniapp/generated/default_appearance_style.html +++ b/src/crates/contracts/product-domains/src/miniapp/generated/default_appearance_style.html @@ -17,10 +17,10 @@ --openbitfun-accent: #60a5fa; --openbitfun-accent-hover: #3b82f6; --openbitfun-accent-secondary: #8b5cf6; - --openbitfun-success: #34d399; - --openbitfun-warning: #f59e0b; - --openbitfun-error: #ef4444; - --openbitfun-info: #a1a1aa; + --openbitfun-success: #5fc178; + --openbitfun-warning: #ff930f; + --openbitfun-error: #f47f7d; + --openbitfun-info: #7dafff; --openbitfun-border: rgba(255, 255, 255, 0.18); --openbitfun-border-subtle: rgba(255, 255, 255, 0.12); --openbitfun-element-bg: rgba(255, 255, 255, 0.1); @@ -53,10 +53,10 @@ --openbitfun-accent: #059cb0; --openbitfun-accent-hover: #059cb0; --openbitfun-accent-secondary: #7c6b99; - --openbitfun-success: #247344; - --openbitfun-warning: #75501d; - --openbitfun-error: #a74352; - --openbitfun-info: #555555; + --openbitfun-success: #12722a; + --openbitfun-warning: #8a4c00; + --openbitfun-error: #bd1b19; + --openbitfun-info: #2360c2; --openbitfun-border: rgba(16, 26, 39, 0.15); --openbitfun-border-subtle: rgba(16, 26, 39, 0.08); --openbitfun-element-bg: rgba(0, 0, 0, 0.05); diff --git a/src/web-ui/src/infrastructure/appearance/builtins/AppearancePalette.ts b/src/web-ui/src/infrastructure/appearance/builtins/AppearancePalette.ts index 4aea6715bc..0464fdfadf 100644 --- a/src/web-ui/src/infrastructure/appearance/builtins/AppearancePalette.ts +++ b/src/web-ui/src/infrastructure/appearance/builtins/AppearancePalette.ts @@ -84,6 +84,8 @@ export interface ScrollbarColors { * palette. Builtins that omit this slice keep today's single-surface behavior. */ export interface ChromeColors { + /** A mixed appearance can use dark chrome around a light scene. */ + type?: AppearancePaletteMode; background: BackgroundColors; text: TextColors; accent: AccentColors; diff --git a/src/web-ui/src/infrastructure/appearance/builtins/appearancePresetOutput.test.ts b/src/web-ui/src/infrastructure/appearance/builtins/appearancePresetOutput.test.ts index 739c9a36dc..418b980531 100644 --- a/src/web-ui/src/infrastructure/appearance/builtins/appearancePresetOutput.test.ts +++ b/src/web-ui/src/infrastructure/appearance/builtins/appearancePresetOutput.test.ts @@ -1,3 +1,4 @@ +import { themes } from '@openbitfun/theme-openbitfun'; import { createHash } from 'node:crypto'; import { describe, expect, it } from 'vitest'; @@ -27,6 +28,22 @@ function hashAppearance(appearance: unknown): string { .digest('hex'); } +function statusContrast(content: string, tint: string, background: string): number { + const parse = (value: string): number[] => value.startsWith('#') + ? [1, 3, 5].map(offset => Number.parseInt(value.slice(offset, offset + 2), 16)) + : value.match(/[\d.]+/g)!.map(Number); + const backdrop = parse(background); + const surface = parse(tint); + const alpha = surface[3] ?? 1; + const luminance = (rgb: number[]): number => rgb.map(channel => { + const normalized = channel / 255; + return normalized <= 0.04045 ? normalized / 12.92 : ((normalized + 0.055) / 1.055) ** 2.4; + }).reduce((sum, channel, index) => sum + channel * [0.2126, 0.7152, 0.0722][index], 0); + const first = luminance(parse(content)); + const second = luminance(backdrop.map((channel, index) => surface[index] * alpha + channel * (1 - alpha))); + return (Math.max(first, second) + 0.05) / (Math.min(first, second) + 0.05); +} + describe('builtin appearance preset output', () => { it('formats hex palette references as stable rgb strings', () => { expect(rgbFromHex('#00e6ff')).toBe('rgb(0, 230, 255)'); @@ -36,27 +53,44 @@ describe('builtin appearance preset output', () => { expect(overlayWhite(0.08)).toBe('rgba(255, 255, 255, 0.08)'); }); - it('aliases staged git colors to added colors unless an appearance overrides them', () => { - expect(createGitColors({ - branch: '#64748b', - branchBg: 'rgba(100, 116, 139, 0.1)', - changes: '#f59e0b', - added: '#22c55e', - deleted: '#ef4444', - })).toMatchObject({ - staged: '#22c55e', - }); - - expect(createGitColors({ - branch: '#64748b', - branchBg: 'rgba(100, 116, 139, 0.1)', - changes: '#f59e0b', - added: '#22c55e', - deleted: '#ef4444', - staged: '#10b981', - })).toMatchObject({ - staged: '#10b981', - }); + it('uses the shared design-system palette for every builtin status and git lifecycle', () => { + for (const appearance of builtinAppearancePalettes) { + const mode = appearance.type; + const values = themes[mode]; + const tokens = getBuiltinAppearanceThemeTokens(appearance.id); + for (const [key, tone] of [['success', 'success'], ['warning', 'warning'], ['error', 'danger'], ['info', 'info']] as const) { + expect(appearance.colors.semantic[key]).toBe(values[`color.status.${tone}.content`]); + expect(appearance.colors.semantic[`${key}Bg`]).toBe(values[`color.status.${tone}.surface`]); + expect(appearance.colors.semantic[`${key}Border`]).toBe(values[`color.status.${tone}.border`]); + for (const role of ['emphasis', 'content', 'surface', 'border'] as const) { + expect(tokens[`--openbitfun-color-status-${tone}-${role}`]).toBe(values[`color.status.${tone}.${role}`]); + } + } + expect(appearance.colors.git).toMatchObject({ + added: values['color.codeChange.added'], + staged: values['color.codeChange.added'], + deleted: values['color.codeChange.removed'], + changes: values['color.status.warning.emphasis'], + }); + expect(createGitColors(mode, { branch: 'currentColor', branchBg: 'transparent' })).toMatchObject( + { ...appearance.colors.git, branch: 'currentColor', branchBg: 'transparent' }, + ); + expect(createSemanticColors(mode)).toEqual(appearance.colors.semantic); + const chromeTokens = getBuiltinAppearance(appearance.id)?.renderers?.['theme-tokens']?.settings.scopes?.chrome; + for (const tone of ['info', 'success', 'warning', 'danger'] as const) { + const contentKey = `--openbitfun-color-status-${tone}-content` as const; + const surfaceKey = `--openbitfun-color-status-${tone}-surface` as const; + for (const background of Object.values(appearance.colors.background)) { + expect(statusContrast(tokens[contentKey], tokens[surfaceKey], background), `${appearance.id} ${tone}`).toBeGreaterThanOrEqual(4.5); + } + if (chromeTokens && appearance.colors.chrome) { + expect(chromeTokens[contentKey]).toBe(themes[appearance.colors.chrome.type ?? mode][`color.status.${tone}.content`]); + for (const background of Object.values(appearance.colors.chrome.background)) { + expect(statusContrast(chromeTokens[contentKey], chromeTokens[surfaceKey], background), `${appearance.id} chrome ${tone}`).toBeGreaterThanOrEqual(4.5); + } + } + } + } }); it('derives repeated palette families from compact authoring inputs', () => { @@ -83,20 +117,6 @@ describe('builtin appearance preset output', () => { 500: '#8b5cf6', 600: '#7c3aed', }); - - expect(createSemanticColors({ - success: '#34d399', - warning: '#f59e0b', - error: '#ef4444', - info: '#a1a1aa', - })).toMatchObject({ - successBg: 'rgba(52, 211, 153, 0.1)', - successBorder: 'rgba(52, 211, 153, 0.3)', - warningBg: 'rgba(245, 158, 11, 0.1)', - errorBorder: 'rgba(239, 68, 68, 0.3)', - infoBg: 'rgba(161, 161, 170, 0.1)', - infoBorder: 'rgba(161, 161, 170, 0.3)', - }); }); it('does not carry retired runtime-only authoring stops in builtin appearance schemas', () => { @@ -153,16 +173,7 @@ describe('builtin appearance preset output', () => { 600: '#1c1c1f', 700: '#000000', }, - semantic: { - success: '#247344', - successBg: '#e1fbe9', - successBorder: '#247344', - error: '#a74352', - errorBg: 'rgba(167, 67, 82, 0.12)', - info: '#555555', - infoBg: '#f3f3f5', - infoBorder: 'rgba(16, 26, 39, 0.15)', - }, + semantic: createSemanticColors('light'), border: { base: 'rgba(16, 26, 39, 0.15)', }, @@ -355,47 +366,47 @@ describe('builtin appearance preset output', () => { }))).toMatchInlineSnapshot(` [ { - "hash": "1fe3b2d75f26bcc2f5ba7a060798ccd4893ab0e6a243e4dbcbd1ea20b3774b05", + "hash": "7a71a12624784e4fa3ca06b77e7ad1b8386d28e05e9a478f27fd3e682463a1ca", "id": "openbitfun-light", "type": "light", }, { - "hash": "3a0a60eabad8363abaded31051a4e5a7aaeb5a22ee12fbd81f81c6f2e1ed44a9", + "hash": "84df9245dff376b4169cb0c44109d9c44e48b2312d33df71f3d7d4ca384e82bb", "id": "openbitfun-monochrome", "type": "light", }, { - "hash": "af8895255a3a21481063077505cf70d60c13105fbc446d8c6860a86041bd1e47", + "hash": "0bbe55d609c2f15b58da7d0aca7c23bc145aaadc96a9394a558c7eda8d4d4566", "id": "openbitfun-slate", "type": "dark", }, { - "hash": "bc97870416ab67aa59fa362f75b4f5bf3397112ea3d7c3ed7ec340cd031d70cb", + "hash": "1b5fb0a08134bdaaa9022f453532cffff4231df97dbcdc3a757cf2401b1cc638", "id": "openbitfun-dark", "type": "dark", }, { - "hash": "9dae2590fc72fb4e8a759eadc7b1ff7c42b9e2864027683aafadbdd4057ced5b", + "hash": "f1b0516be11dbd02eb1c3b204806e2212b3fa78d1fcf18912d2fee99f257d51d", "id": "openbitfun-midnight", "type": "dark", }, { - "hash": "9adb639858fa52ff427c5c931a21de805e5f9aa4576839a293ae4d9915baa532", + "hash": "db979037b2785c346b5fa06905aa84db43bcb39217e123f26cd6aad2231248a8", "id": "openbitfun-china-style", "type": "light", }, { - "hash": "b5adfb440ba46c1549990ce0e5ea05bf929dd7caee9b9ecc6baf8331b5c5e7f2", + "hash": "30a425ebcf4e4121e8a426c1dca981944d99b0523c21477cbe6c59b111e11b0e", "id": "openbitfun-china-night", "type": "dark", }, { - "hash": "6c450fe83517666bf4c8c99c1d0463b583e4abc8b08bc919c89e108100ea410c", + "hash": "b82c17ad7f03db017974d4a300294f4efd11bb06a56150c5217b24fa1be37614", "id": "openbitfun-cyber", "type": "dark", }, { - "hash": "279e1980c2e15258107983155b26f9a6a06001b1adbfc9f59071f603d0f9f40e", + "hash": "7016e6d424172f8ed84a4263263c09491ab905a829f26f970aad4a48d723b05d", "id": "openbitfun-tokyo-night", "type": "dark", }, diff --git a/src/web-ui/src/infrastructure/appearance/builtins/buildBuiltinAppearance.ts b/src/web-ui/src/infrastructure/appearance/builtins/buildBuiltinAppearance.ts index cd6dfef6e2..ec79df1c57 100644 --- a/src/web-ui/src/infrastructure/appearance/builtins/buildBuiltinAppearance.ts +++ b/src/web-ui/src/infrastructure/appearance/builtins/buildBuiltinAppearance.ts @@ -174,6 +174,10 @@ function createChromeThemeTokens( const chrome = palette.colors.chrome; if (!chrome) return undefined; const values = createThemeTokenValues(palette); + const statusTheme = themes[chrome.type ?? palette.type]; + for (const name of Object.keys(statusTheme) as ThemeTokenName[]) { + if (name.startsWith('color.status.')) values[name] = statusTheme[name]; + } const scrollbar = chrome.scrollbar ?? palette.colors.scrollbar ?? { thumb: palette.type === 'dark' ? 'rgba(255, 255, 255, 0.12)' : 'rgba(0, 0, 0, 0.15)', thumbHover: palette.type === 'dark' ? 'rgba(255, 255, 255, 0.24)' : 'rgba(0, 0, 0, 0.3)', diff --git a/src/web-ui/src/infrastructure/appearance/builtins/chinaNight.ts b/src/web-ui/src/infrastructure/appearance/builtins/chinaNight.ts index 87343ec15a..db49eeb0f2 100644 --- a/src/web-ui/src/infrastructure/appearance/builtins/chinaNight.ts +++ b/src/web-ui/src/infrastructure/appearance/builtins/chinaNight.ts @@ -23,9 +23,6 @@ const CHINA_NIGHT_ACCENT = '#73a5cc'; const CHINA_NIGHT_ACCENT_HOVER = '#5a8bb3'; const CHINA_NIGHT_GREEN = '#96c6b4'; const CHINA_NIGHT_GREEN_HOVER = '#7eb09b'; -const CHINA_NIGHT_SUCCESS = '#6bc072'; -const CHINA_NIGHT_WARNING = '#f5b555'; -const CHINA_NIGHT_ERROR = '#e85555'; const chinaNightText = (alpha: number | string) => rgbaFromHex(CHINA_NIGHT_TEXT_PRIMARY, alpha); const chinaNightAccent = (alpha: number | string) => rgbaFromHex(CHINA_NIGHT_ACCENT, alpha); @@ -63,13 +60,7 @@ export const openBitFunChinaNightPalette: AppearancePalette = { purple: createSecondaryAccentScale({ base: CHINA_NIGHT_GREEN, hover: CHINA_NIGHT_GREEN_HOVER }), - semantic: createSemanticColors({ - success: CHINA_NIGHT_SUCCESS, - warning: CHINA_NIGHT_WARNING, - error: CHINA_NIGHT_ERROR, - info: CHINA_NIGHT_ACCENT, - bgAlpha: 0.12, - }), + semantic: createSemanticColors('dark'), border: { subtle: chinaNightText(0.14), @@ -87,12 +78,9 @@ export const openBitFunChinaNightPalette: AppearancePalette = { strong: chinaNightText(0.2), }, - git: createGitColors({ + git: createGitColors('dark', { branch: rgbFromHex(CHINA_NIGHT_ACCENT), branchBg: chinaNightAccent(0.12), - changes: rgbFromHex(CHINA_NIGHT_WARNING), - added: rgbFromHex(CHINA_NIGHT_SUCCESS), - deleted: rgbFromHex(CHINA_NIGHT_ERROR), }), }, diff --git a/src/web-ui/src/infrastructure/appearance/builtins/chinaStyle.ts b/src/web-ui/src/infrastructure/appearance/builtins/chinaStyle.ts index c817d1d5d2..e806fb868b 100644 --- a/src/web-ui/src/infrastructure/appearance/builtins/chinaStyle.ts +++ b/src/web-ui/src/infrastructure/appearance/builtins/chinaStyle.ts @@ -24,9 +24,6 @@ const CHINA_STYLE_BLUE = '#2e5e8a'; const CHINA_STYLE_BLUE_HOVER = '#234a6d'; const CHINA_STYLE_GREEN = '#7eb09b'; const CHINA_STYLE_GREEN_HOVER = '#5a9078'; -const CHINA_STYLE_SUCCESS = '#52ad5a'; -const CHINA_STYLE_WARNING = '#f0a020'; -const CHINA_STYLE_ERROR = '#c8102e'; const CHINA_STYLE_BORDER = '#6a5c46'; const chinaStyleBlue = (alpha: number | string) => rgbaFromHex(CHINA_STYLE_BLUE, alpha); @@ -65,14 +62,7 @@ export const openBitFunChinaStylePalette: AppearancePalette = { purple: createSecondaryAccentScale({ base: CHINA_STYLE_GREEN, hover: CHINA_STYLE_GREEN_HOVER }), - semantic: createSemanticColors({ - success: CHINA_STYLE_SUCCESS, - warning: CHINA_STYLE_WARNING, - error: CHINA_STYLE_ERROR, - info: CHINA_STYLE_BLUE, - bgAlpha: 0.08, - borderAlpha: 0.25, - }), + semantic: createSemanticColors('light'), border: { subtle: chinaStyleBorder(0.12), @@ -90,12 +80,9 @@ export const openBitFunChinaStylePalette: AppearancePalette = { strong: chinaStyleBlue(0.18), }, - git: createGitColors({ + git: createGitColors('light', { branch: rgbFromHex(CHINA_STYLE_BLUE), branchBg: chinaStyleBlue(0.08), - changes: rgbFromHex(CHINA_STYLE_WARNING), - added: rgbFromHex(CHINA_STYLE_SUCCESS), - deleted: rgbFromHex(CHINA_STYLE_ERROR), }), }, diff --git a/src/web-ui/src/infrastructure/appearance/builtins/cyber.ts b/src/web-ui/src/infrastructure/appearance/builtins/cyber.ts index 0527377c0c..e7437a29b8 100644 --- a/src/web-ui/src/infrastructure/appearance/builtins/cyber.ts +++ b/src/web-ui/src/infrastructure/appearance/builtins/cyber.ts @@ -23,9 +23,6 @@ const CYBER_ACCENT = '#00e6ff'; const CYBER_ACCENT_HOVER = '#00ccff'; const CYBER_PURPLE = '#8a2be2'; const CYBER_PURPLE_HOVER = '#7928ca'; -const CYBER_SUCCESS = '#00ff9f'; -const CYBER_WARNING = '#ffcc00'; -const CYBER_ERROR = '#ff0055'; const CYBER_SURFACE_SECONDARY = '#1c1c1f'; const CYBER_SURFACE_RAISED = '#2b2d30'; @@ -70,14 +67,7 @@ export const openBitFunCyberPalette: AppearancePalette = { alpha: { 100: 0.1, 200: 0.18 }, }), - semantic: createSemanticColors({ - success: CYBER_SUCCESS, - warning: CYBER_WARNING, - error: CYBER_ERROR, - info: CYBER_ACCENT, - bgAlpha: 0.12, - borderAlpha: 0.35, - }), + semantic: createSemanticColors('dark'), border: { subtle: cyberAccent(0.14), @@ -95,12 +85,9 @@ export const openBitFunCyberPalette: AppearancePalette = { strong: cyberAccent(0.22), }, - git: createGitColors({ + git: createGitColors('dark', { branch: rgbFromHex(CYBER_ACCENT), branchBg: cyberAccent(0.12), - changes: rgbFromHex(CYBER_WARNING), - added: rgbFromHex(CYBER_SUCCESS), - deleted: rgbFromHex(CYBER_ERROR), }), }, diff --git a/src/web-ui/src/infrastructure/appearance/builtins/dark.ts b/src/web-ui/src/infrastructure/appearance/builtins/dark.ts index d9fd134b3a..bdb2a961b2 100644 --- a/src/web-ui/src/infrastructure/appearance/builtins/dark.ts +++ b/src/web-ui/src/infrastructure/appearance/builtins/dark.ts @@ -13,7 +13,6 @@ import { createStandardRadius, createStandardSpacing, overlayWhite, - rgbFromHex, STATIC_WHITE, } from './paletteHelpers'; import { @@ -29,9 +28,6 @@ const DARK_ACCENT = getDesignSystemThemeString('dark', 'color.accent.default'); const DARK_ACCENT_HOVER = getDesignSystemThemeString('dark', 'color.accent.hover'); const DARK_PURPLE = '#8b5cf6'; const DARK_PURPLE_HOVER = '#7c3aed'; -const DARK_SUCCESS = getDesignSystemThemeString('dark', 'color.status.success.content'); -const DARK_WARNING = getDesignSystemThemeString('dark', 'color.status.warning.content'); -const DARK_ERROR = getDesignSystemThemeString('dark', 'color.status.danger.content'); export const openBitFunDarkPalette: AppearancePalette = { @@ -64,22 +60,7 @@ export const openBitFunDarkPalette: AppearancePalette = { purple: createSecondaryAccentScale({ base: DARK_PURPLE, hover: DARK_PURPLE_HOVER }), - semantic: createSemanticColors({ - success: DARK_SUCCESS, - warning: DARK_WARNING, - error: DARK_ERROR, - info: '#a1a1aa', - overrides: { - successBg: getDesignSystemThemeString('dark', 'color.status.success.surface'), - successBorder: getDesignSystemThemeString('dark', 'color.status.success.border'), - warningBg: getDesignSystemThemeString('dark', 'color.status.warning.surface'), - warningBorder: getDesignSystemThemeString('dark', 'color.status.warning.border'), - errorBg: getDesignSystemThemeString('dark', 'color.status.danger.surface'), - errorBorder: getDesignSystemThemeString('dark', 'color.status.danger.border'), - infoBg: getDesignSystemThemeString('dark', 'color.status.info.surface'), - infoBorder: getDesignSystemThemeString('dark', 'color.status.info.border'), - }, - }), + semantic: createSemanticColors('dark'), border: { ...createDarkNeutralBorder(), @@ -97,12 +78,9 @@ export const openBitFunDarkPalette: AppearancePalette = { strong: getDesignSystemThemeString('dark', 'color.action.neutral.surfacePressed'), }, - git: createGitColors({ + git: createGitColors('dark', { branch: '#a1a1aa', branchBg: overlayWhite(0.06), - changes: rgbFromHex(DARK_WARNING), - added: 'rgb(34, 197, 94)', - deleted: rgbFromHex(DARK_ERROR), }), scrollbar: createDarkNeutralScrollbar(), @@ -209,4 +187,3 @@ export const openBitFunDarkPalette: AppearancePalette = { - diff --git a/src/web-ui/src/infrastructure/appearance/builtins/light.ts b/src/web-ui/src/infrastructure/appearance/builtins/light.ts index fbde0da2c1..1dd7ab38d5 100644 --- a/src/web-ui/src/infrastructure/appearance/builtins/light.ts +++ b/src/web-ui/src/infrastructure/appearance/builtins/light.ts @@ -27,12 +27,6 @@ const LIGHT_TEXT_DISABLED = getDesignSystemThemeString('light', 'color.content.d const LIGHT_NAVY_HOVER = getDesignSystemThemeString('light', 'color.action.primary.hover'); const LIGHT_PURPLE = '#7c6b99'; const LIGHT_PURPLE_HOVER = '#655680'; -const LIGHT_SUCCESS = getDesignSystemThemeString('light', 'color.status.success.content'); -const LIGHT_SUCCESS_BG = getDesignSystemThemeString('light', 'color.status.success.surface'); -const LIGHT_INFO = getDesignSystemThemeString('light', 'color.status.info.content'); -const LIGHT_WARNING = getDesignSystemThemeString('light', 'color.status.warning.content'); -const LIGHT_ERROR = getDesignSystemThemeString('light', 'color.status.danger.content'); -const LIGHT_ERROR_BG = getDesignSystemThemeString('light', 'color.status.danger.surface'); const LIGHT_BACKGROUND_PRIMARY = getDesignSystemThemeString('light', 'color.surface.canvas'); const LIGHT_SURFACE_CHROME = getDesignSystemThemeString('light', 'color.surface.chrome'); const LIGHT_SURFACE_SUBTLE = getDesignSystemThemeString('light', 'color.surface.subtle'); @@ -100,24 +94,7 @@ export const openBitFunLightPalette: AppearancePalette = { }), - semantic: createSemanticColors({ - success: LIGHT_SUCCESS, - warning: LIGHT_WARNING, - error: LIGHT_ERROR, - info: LIGHT_INFO, - bgAlpha: 0.08, - borderAlpha: 0.25, - overrides: { - successBg: LIGHT_SUCCESS_BG, - successBorder: getDesignSystemThemeString('light', 'color.status.success.border'), - warningBg: getDesignSystemThemeString('light', 'color.status.warning.surface'), - warningBorder: getDesignSystemThemeString('light', 'color.status.warning.border'), - errorBg: LIGHT_ERROR_BG, - errorBorder: getDesignSystemThemeString('light', 'color.status.danger.border'), - infoBg: getDesignSystemThemeString('light', 'color.status.info.surface'), - infoBorder: getDesignSystemThemeString('light', 'color.status.info.border'), - }, - }), + semantic: createSemanticColors('light'), border: { @@ -138,12 +115,9 @@ export const openBitFunLightPalette: AppearancePalette = { }, - git: createGitColors({ + git: createGitColors('light', { branch: rgbFromHex(LIGHT_NAVY_HOVER), branchBg: lightNavyHover(0.1), - changes: rgbFromHex(LIGHT_WARNING), - added: rgbFromHex(LIGHT_SUCCESS), - deleted: rgbFromHex(LIGHT_ERROR), }), }, diff --git a/src/web-ui/src/infrastructure/appearance/builtins/midnight.ts b/src/web-ui/src/infrastructure/appearance/builtins/midnight.ts index ae4effc438..ba019bcd2d 100644 --- a/src/web-ui/src/infrastructure/appearance/builtins/midnight.ts +++ b/src/web-ui/src/infrastructure/appearance/builtins/midnight.ts @@ -24,9 +24,6 @@ const MIDNIGHT_ACCENT = '#60a5fa'; const MIDNIGHT_ACCENT_HOVER = '#3b82f6'; const MIDNIGHT_PURPLE = '#9c78ff'; const MIDNIGHT_PURPLE_HOVER = '#8b5cf6'; -const MIDNIGHT_SUCCESS = '#6aab73'; -const MIDNIGHT_WARNING = '#e0a055'; -const MIDNIGHT_ERROR = '#cc7f7a'; const midnightText = (alpha: number | string) => rgbaFromHex(MIDNIGHT_TEXT_PRIMARY, alpha); const midnightAccent = (alpha: number | string) => rgbaFromHex(MIDNIGHT_ACCENT, alpha); @@ -64,12 +61,7 @@ export const openBitFunMidnightPalette: AppearancePalette = { purple: createSecondaryAccentScale({ base: MIDNIGHT_PURPLE, hover: MIDNIGHT_PURPLE_HOVER }), - semantic: createSemanticColors({ - success: MIDNIGHT_SUCCESS, - warning: MIDNIGHT_WARNING, - error: MIDNIGHT_ERROR, - info: MIDNIGHT_ACCENT, - }), + semantic: createSemanticColors('dark'), border: { subtle: overlayWhite(0.12), @@ -87,12 +79,9 @@ export const openBitFunMidnightPalette: AppearancePalette = { strong: overlayWhite(0.15), }, - git: createGitColors({ + git: createGitColors('dark', { branch: rgbFromHex(MIDNIGHT_ACCENT), branchBg: midnightAccent(0.1), - changes: rgbFromHex(MIDNIGHT_WARNING), - added: rgbFromHex(MIDNIGHT_SUCCESS), - deleted: rgbFromHex(MIDNIGHT_ERROR), }), }, diff --git a/src/web-ui/src/infrastructure/appearance/builtins/monochrome.ts b/src/web-ui/src/infrastructure/appearance/builtins/monochrome.ts index c09fdfc6f4..b0db2db5a3 100644 --- a/src/web-ui/src/infrastructure/appearance/builtins/monochrome.ts +++ b/src/web-ui/src/infrastructure/appearance/builtins/monochrome.ts @@ -59,6 +59,7 @@ export const openBitFunMonochromePalette: AppearancePalette = { thumbHover: content.colors.border.strong, }, chrome: { + type: chrome.type, background: { primary: chrome.colors.background.primary, secondary: chrome.colors.background.secondary, diff --git a/src/web-ui/src/infrastructure/appearance/builtins/paletteHelpers.ts b/src/web-ui/src/infrastructure/appearance/builtins/paletteHelpers.ts index 9bf3c6ce02..6971ca97e9 100644 --- a/src/web-ui/src/infrastructure/appearance/builtins/paletteHelpers.ts +++ b/src/web-ui/src/infrastructure/appearance/builtins/paletteHelpers.ts @@ -9,6 +9,7 @@ import type { SemanticColors, AppearancePalette, } from './AppearancePalette'; +import { getDesignSystemThemeString } from './designSystemThemeValues'; export const STATIC_BLACK = '#000000'; export const STATIC_WHITE = '#ffffff'; @@ -61,16 +62,6 @@ export interface SecondaryAccentScaleInput { alpha?: Partial>; } -export interface SemanticColorsInput { - success: string; - warning: string; - error: string; - info: string; - bgAlpha?: number | string; - borderAlpha?: number | string; - overrides?: Partial; -} - export function createAccentScale(input: AccentScaleInput): AccentColors { const hover = input.hover ?? input.base; const alpha = { @@ -113,24 +104,20 @@ export function createSecondaryAccentScale(input: SecondaryAccentScaleInput): Se }; } -export function createSemanticColors(input: SemanticColorsInput): SemanticColors { - const bgAlpha = input.bgAlpha ?? 0.1; - const borderAlpha = input.borderAlpha ?? 0.3; - +export function createSemanticColors(mode: AppearancePalette['type']): SemanticColors { return { - success: input.success, - successBg: rgbaFromHex(input.success, bgAlpha), - successBorder: rgbaFromHex(input.success, borderAlpha), - warning: input.warning, - warningBg: rgbaFromHex(input.warning, bgAlpha), - warningBorder: rgbaFromHex(input.warning, borderAlpha), - error: input.error, - errorBg: rgbaFromHex(input.error, bgAlpha), - errorBorder: rgbaFromHex(input.error, borderAlpha), - info: input.info, - infoBg: rgbaFromHex(input.info, bgAlpha), - infoBorder: rgbaFromHex(input.info, borderAlpha), - ...input.overrides, + success: getDesignSystemThemeString(mode, 'color.status.success.content'), + successBg: getDesignSystemThemeString(mode, 'color.status.success.surface'), + successBorder: getDesignSystemThemeString(mode, 'color.status.success.border'), + warning: getDesignSystemThemeString(mode, 'color.status.warning.content'), + warningBg: getDesignSystemThemeString(mode, 'color.status.warning.surface'), + warningBorder: getDesignSystemThemeString(mode, 'color.status.warning.border'), + error: getDesignSystemThemeString(mode, 'color.status.danger.content'), + errorBg: getDesignSystemThemeString(mode, 'color.status.danger.surface'), + errorBorder: getDesignSystemThemeString(mode, 'color.status.danger.border'), + info: getDesignSystemThemeString(mode, 'color.status.info.content'), + infoBg: getDesignSystemThemeString(mode, 'color.status.info.surface'), + infoBorder: getDesignSystemThemeString(mode, 'color.status.info.border'), }; } @@ -211,11 +198,16 @@ export function createDarkNeutralElement(): ElementBackgrounds { } export function createGitColors( - config: Omit & Partial>, + mode: AppearancePalette['type'], + config: Pick, ): GitColors { + const added = getDesignSystemThemeString(mode, 'color.codeChange.added'); return { ...config, - staged: config.staged ?? config.added, + added, + deleted: getDesignSystemThemeString(mode, 'color.codeChange.removed'), + staged: added, + changes: getDesignSystemThemeString(mode, 'color.status.warning.emphasis'), }; } diff --git a/src/web-ui/src/infrastructure/appearance/builtins/slate.ts b/src/web-ui/src/infrastructure/appearance/builtins/slate.ts index c5a1e4d237..d22c3b1849 100644 --- a/src/web-ui/src/infrastructure/appearance/builtins/slate.ts +++ b/src/web-ui/src/infrastructure/appearance/builtins/slate.ts @@ -14,7 +14,6 @@ import { createStandardSpacing, overlayBlack, overlayWhite, - rgbFromHex, rgbaFromHex, STATIC_WHITE, } from './paletteHelpers'; @@ -29,9 +28,6 @@ const SLATE_ACCENT = '#94a3b8'; const SLATE_ACCENT_HOVER = '#64748b'; const SLATE_PURPLE = '#b8c4ff'; const SLATE_PURPLE_HOVER = '#9dacf5'; -const SLATE_SUCCESS = '#7eb09b'; -const SLATE_WARNING = '#f59e0b'; -const SLATE_ERROR = '#c9878d'; export const openBitFunSlatePalette: AppearancePalette = { @@ -81,27 +77,15 @@ export const openBitFunSlatePalette: AppearancePalette = { purple: createSecondaryAccentScale({ base: SLATE_PURPLE, hover: SLATE_PURPLE_HOVER }), - semantic: createSemanticColors({ - success: SLATE_SUCCESS, - warning: SLATE_WARNING, - error: SLATE_ERROR, - info: SLATE_TEXT_MUTED, - overrides: { - infoBg: overlayWhite(0.07), - infoBorder: overlayWhite(0.2), - }, - }), + semantic: createSemanticColors('dark'), border: createDarkNeutralBorder(), element: createDarkNeutralElement(), - git: createGitColors({ + git: createGitColors('dark', { branch: SLATE_ACCENT, branchBg: overlayWhite(0.06), - changes: rgbFromHex(SLATE_WARNING), - added: rgbFromHex(SLATE_SUCCESS), - deleted: rgbFromHex(SLATE_ERROR), }), scrollbar: createDarkNeutralScrollbar(), diff --git a/src/web-ui/src/infrastructure/appearance/builtins/tokyoNight.ts b/src/web-ui/src/infrastructure/appearance/builtins/tokyoNight.ts index 4955290cb0..3dc5b818ce 100644 --- a/src/web-ui/src/infrastructure/appearance/builtins/tokyoNight.ts +++ b/src/web-ui/src/infrastructure/appearance/builtins/tokyoNight.ts @@ -25,12 +25,7 @@ const TOKYO_ACCENT = '#7aa2f7'; const TOKYO_ACCENT_HOVER = '#6183bb'; const TOKYO_PURPLE = '#bb9af7'; const TOKYO_PURPLE_HOVER = '#9d7cd8'; -const TOKYO_SUCCESS = '#9ece6a'; -const TOKYO_WARNING = '#e0af68'; -const TOKYO_ERROR = '#f7768e'; -const TOKYO_INFO = '#7dcfff'; const TOKYO_SCROLLBAR = '#868bc4'; -const TOKYO_GIT_ADDED = '#41a6b5'; const TOKYO_PRIMARY_BUTTON = '#3d59a1'; const tokyoAccent = (alpha: number | string) => rgbaFromHex(TOKYO_ACCENT, alpha); @@ -78,14 +73,7 @@ export const openBitFunTokyoNightPalette: AppearancePalette = { hover: TOKYO_PURPLE_HOVER, }), - semantic: createSemanticColors({ - success: TOKYO_SUCCESS, - warning: TOKYO_WARNING, - error: TOKYO_ERROR, - info: TOKYO_INFO, - bgAlpha: 0.12, - borderAlpha: 0.35, - }), + semantic: createSemanticColors('dark'), border: { subtle: tokyoBorder(0.18), @@ -103,13 +91,9 @@ export const openBitFunTokyoNightPalette: AppearancePalette = { strong: tokyoAccent(0.18), }, - git: createGitColors({ + git: createGitColors('dark', { branch: rgbFromHex(TOKYO_ACCENT), branchBg: tokyoAccent(0.12), - changes: rgbFromHex(TOKYO_WARNING), - added: rgbFromHex(TOKYO_GIT_ADDED), - deleted: rgbFromHex(TOKYO_ERROR), - staged: rgbFromHex(TOKYO_SUCCESS), }), scrollbar: { From 61327f73ead091c9a6b4bcd5d891ab679cbd3f2a Mon Sep 17 00:00:00 2001 From: GCWing Date: Mon, 7 Sep 2026 11:35:16 +0800 Subject: [PATCH 2/3] Use status emphasis colors for notices and indicators --- .../tool-cards/ProminentToolCards.module.css | 4 +-- .../StandardAmbientToolCards.module.css | 4 +-- .../MobileBanner/MobileBanner.module.css | 3 ++ .../src/styles/components/adaptive-shell.scss | 6 ++-- .../src/styles/components/devices.scss | 2 +- .../src/styles/components/harmony-native.scss | 2 +- .../src/styles/components/pairing.scss | 2 +- .../src/styles/components/sessions.scss | 6 ++-- .../src/styles/components/tool-card.scss | 28 +++++++-------- src/mobile-web/src/styles/global.scss | 4 +-- .../AssistantAvatar/AssistantAvatar.scss | 4 +-- .../sections/sessions/SessionsSection.scss | 18 +++++----- .../workspaces/WorkspaceListSection.scss | 20 +++++------ .../src/app/scenes/miniapps/MiniAppScene.scss | 14 ++++---- .../profile/views/AssistantDefaultsPage.scss | 10 +++--- .../src/app/scenes/settings/SettingsNav.scss | 2 +- .../relay-deploy/RelayDeployWizard.scss | 8 ++--- .../components/ChatInputApprovalBand.scss | 14 ++++---- .../flow_chat/components/ModelSelector.scss | 2 +- .../flow_chat/components/ToolApprovalBar.scss | 18 +++++----- .../BackgroundCommandOutputPanel.scss | 16 ++++++--- .../components/modern/FlowChatHeader.scss | 12 +++---- .../components/modern/SessionTreePopover.scss | 12 +++---- .../modern/TurnCompletionNoticeItem.scss | 23 +++++++----- .../modern/TurnFailureNoticeItem.scss | 12 +++---- .../components/modern/UserMessageItem.scss | 4 +-- .../thread-goal/ThreadGoalDialogs.scss | 20 +++++++---- .../components/usage/SessionUsagePanel.scss | 10 +++--- .../usage/SessionUsageReportCard.scss | 4 +-- .../components/voice/RealtimeVoiceCall.scss | 16 ++++----- .../subagent-identity/SubagentAvatar.scss | 8 ++--- .../tool-cards/ToolTimeoutIndicator.scss | 18 ++++++++++ .../components/ExternalSourcesConfig.scss | 10 +++--- .../config/components/McpToolsConfig.scss | 36 +++++++++++++------ .../config/components/ModelSettingsPage.scss | 20 ++++++----- .../components/RuntimeSettingsPages.scss | 2 +- .../config/components/SkillsConfig.scss | 22 ++++++------ .../peer-device/DeviceSurfaceSwitcher.scss | 14 ++++---- .../components/NotificationCenter.scss | 15 ++++---- .../components/NotificationItem.scss | 8 ++--- .../components/ProgressNotification.scss | 20 +++++------ 41 files changed, 268 insertions(+), 205 deletions(-) diff --git a/design-system/packages/ui/src/flow-chat/tool-cards/ProminentToolCards.module.css b/design-system/packages/ui/src/flow-chat/tool-cards/ProminentToolCards.module.css index 194ab52678..c7178d71a0 100644 --- a/design-system/packages/ui/src/flow-chat/tool-cards/ProminentToolCards.module.css +++ b/design-system/packages/ui/src/flow-chat/tool-cards/ProminentToolCards.module.css @@ -79,12 +79,12 @@ .outputGroup[data-tone="warning"] .outputBlock { color: var(--openbitfun-color-status-warning-content); - background: color-mix(in srgb, var(--openbitfun-color-status-warning-content) 7%, transparent); + background: var(--openbitfun-color-status-warning-surface); } .outputGroup[data-tone="danger"] .outputBlock { color: var(--openbitfun-color-status-danger-content); - background: color-mix(in srgb, var(--openbitfun-color-status-danger-content) 7%, transparent); + background: var(--openbitfun-color-status-danger-surface); } .footer { diff --git a/design-system/packages/ui/src/flow-chat/tool-cards/StandardAmbientToolCards.module.css b/design-system/packages/ui/src/flow-chat/tool-cards/StandardAmbientToolCards.module.css index 568eef30da..d1a5c5e918 100644 --- a/design-system/packages/ui/src/flow-chat/tool-cards/StandardAmbientToolCards.module.css +++ b/design-system/packages/ui/src/flow-chat/tool-cards/StandardAmbientToolCards.module.css @@ -204,8 +204,8 @@ [data-openbitfun-tool-card="default"][data-openbitfun-confirmation="true"] > [data-openbitfun-component="flow-chat-tool-card"][data-openbitfun-part="surface"] { border-radius: var(--openbitfun-radius-sm); - background: color-mix(in srgb, var(--openbitfun-color-status-warning-content) 6%, transparent); - box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--openbitfun-color-status-warning-content) 24%, transparent); + background: var(--openbitfun-color-status-warning-surface); + box-shadow: inset 0 0 0 1px var(--openbitfun-color-status-warning-border); } .todoCompact { diff --git a/design-system/packages/ui/src/mobile/MobileBanner/MobileBanner.module.css b/design-system/packages/ui/src/mobile/MobileBanner/MobileBanner.module.css index 09c7ea1f21..c42bd9f884 100644 --- a/design-system/packages/ui/src/mobile/MobileBanner/MobileBanner.module.css +++ b/design-system/packages/ui/src/mobile/MobileBanner/MobileBanner.module.css @@ -4,6 +4,9 @@ .root[data-tone="warning"] { border-color: var(--openbitfun-color-status-warning-border); color: var(--openbitfun-color-status-warning-content); background: var(--openbitfun-color-status-warning-surface); } .root[data-tone="danger"] { border-color: var(--openbitfun-color-status-danger-border); color: var(--openbitfun-color-status-danger-content); background: var(--openbitfun-color-status-danger-surface); } .icon { display: grid; inline-size: 20px; block-size: 20px; flex: 0 0 20px; place-items: center; } + .root[data-tone="info"] .icon { color: var(--openbitfun-color-status-info-emphasis); } + .root[data-tone="warning"] .icon { color: var(--openbitfun-color-status-warning-emphasis); } + .root[data-tone="danger"] .icon { color: var(--openbitfun-color-status-danger-emphasis); } .content { min-inline-size: 0; flex: 1; } .action { flex: 0 0 auto; } } diff --git a/src/mobile-web/src/styles/components/adaptive-shell.scss b/src/mobile-web/src/styles/components/adaptive-shell.scss index 09bb2e3fed..38a6309939 100644 --- a/src/mobile-web/src/styles/components/adaptive-shell.scss +++ b/src/mobile-web/src/styles/components/adaptive-shell.scss @@ -80,9 +80,9 @@ border: 2px solid var(--openbitfun-color-surface-panel); background: var(--openbitfun-color-content-muted); - &--connected { background: var(--openbitfun-color-status-success-content); } - &--checking { background: var(--openbitfun-color-status-warning-content); } - &--unreachable { background: var(--openbitfun-color-status-danger-content); } + &--connected { background: var(--openbitfun-color-status-success-emphasis); } + &--checking { background: var(--openbitfun-color-status-warning-emphasis); } + &--unreachable { background: var(--openbitfun-color-status-danger-emphasis); } } .remote-home__eyebrow { diff --git a/src/mobile-web/src/styles/components/devices.scss b/src/mobile-web/src/styles/components/devices.scss index 7fc3ffe8e5..cdf8274591 100644 --- a/src/mobile-web/src/styles/components/devices.scss +++ b/src/mobile-web/src/styles/components/devices.scss @@ -131,7 +131,7 @@ flex-shrink: 0; &.is-online { - background: var(--openbitfun-color-status-success-content); + background: var(--openbitfun-color-status-success-emphasis); } &.is-offline { diff --git a/src/mobile-web/src/styles/components/harmony-native.scss b/src/mobile-web/src/styles/components/harmony-native.scss index dbcbbc1e8a..b4c70d78ad 100644 --- a/src/mobile-web/src/styles/components/harmony-native.scss +++ b/src/mobile-web/src/styles/components/harmony-native.scss @@ -352,7 +352,7 @@ } .harmony-sidebar__status.is-online { - background: var(--openbitfun-color-status-success-content); + background: var(--openbitfun-color-status-success-emphasis); } .harmony-sidebar__chevron { diff --git a/src/mobile-web/src/styles/components/pairing.scss b/src/mobile-web/src/styles/components/pairing.scss index 47b6b4f0ed..95958d0691 100644 --- a/src/mobile-web/src/styles/components/pairing.scss +++ b/src/mobile-web/src/styles/components/pairing.scss @@ -226,7 +226,7 @@ width: 8px; height: 8px; border-radius: 50%; - background: var(--openbitfun-color-status-success-content); + background: var(--openbitfun-color-status-success-emphasis); box-shadow: 0 0 0 4px var(--openbitfun-color-status-success-surface); } diff --git a/src/mobile-web/src/styles/components/sessions.scss b/src/mobile-web/src/styles/components/sessions.scss index 4dce29d464..65767652bb 100644 --- a/src/mobile-web/src/styles/components/sessions.scss +++ b/src/mobile-web/src/styles/components/sessions.scss @@ -68,11 +68,11 @@ vertical-align: middle; &--connected { - background: var(--openbitfun-color-status-success-content); + background: var(--openbitfun-color-status-success-emphasis); } &--checking { - background: var(--openbitfun-color-status-warning-content); + background: var(--openbitfun-color-status-warning-emphasis); } &--unpaired { @@ -80,7 +80,7 @@ } &--unreachable { - background: var(--openbitfun-color-status-danger-content); + background: var(--openbitfun-color-status-danger-emphasis); } } diff --git a/src/mobile-web/src/styles/components/tool-card.scss b/src/mobile-web/src/styles/components/tool-card.scss index 9ae3a1f08f..fd5d8df689 100644 --- a/src/mobile-web/src/styles/components/tool-card.scss +++ b/src/mobile-web/src/styles/components/tool-card.scss @@ -62,7 +62,7 @@ } &--running { - color: var(--openbitfun-color-status-warning-content); + color: var(--openbitfun-color-status-info-content); } } @@ -83,7 +83,7 @@ } .chat-tool-card--running { - border-color: var(--openbitfun-color-status-warning-border); + border-color: var(--openbitfun-color-status-info-border); } .chat-tool-card--done { @@ -120,26 +120,26 @@ display: inline-block; width: 14px; height: 14px; - border: 2px solid var(--openbitfun-color-status-warning-border); - border-top-color: var(--openbitfun-color-status-warning-content); + border: 2px solid var(--openbitfun-color-status-info-border); + border-top-color: var(--openbitfun-color-status-info-emphasis); border-radius: 50%; animation: spin 0.7s linear infinite; } .chat-tool-card__check { - color: var(--openbitfun-color-status-success-content); + color: var(--openbitfun-color-status-success-emphasis); display: flex; align-items: center; } .chat-tool-card__error-icon { - color: var(--openbitfun-color-status-danger-content); + color: var(--openbitfun-color-status-danger-emphasis); display: flex; align-items: center; } .chat-tool-card__pending-icon { - color: var(--openbitfun-color-status-warning-content); + color: var(--openbitfun-color-status-warning-emphasis); display: flex; align-items: center; } @@ -323,7 +323,7 @@ .chat-task-card__stat--running { font-size: var(--openbitfun-type-support-font-size); - color: var(--openbitfun-color-status-warning-content); + color: var(--openbitfun-color-status-info-content); font-variant-numeric: tabular-nums; } @@ -359,8 +359,8 @@ display: inline-block; width: 10px; height: 10px; - border: 1.5px solid var(--openbitfun-color-status-warning-border); - border-top-color: var(--openbitfun-color-status-warning-content); + border: 1.5px solid var(--openbitfun-color-status-info-border); + border-top-color: var(--openbitfun-color-status-info-emphasis); border-radius: 50%; animation: spin 0.7s linear infinite; flex-shrink: 0; @@ -459,7 +459,7 @@ width: 6px; height: 6px; border-radius: 50%; - background: var(--openbitfun-color-status-warning-content); + background: var(--openbitfun-color-status-warning-emphasis); animation: pulse-dot 1.4s ease-in-out infinite; } } @@ -664,11 +664,11 @@ transition: all var(--motion-fast) var(--easing-standard); &--completed { - background: var(--openbitfun-color-status-success-content); + background: var(--openbitfun-color-status-success-emphasis); } &--in_progress { - background: var(--openbitfun-color-accent-default); + background: var(--openbitfun-color-status-info-emphasis); animation: todoPulse 1.4s ease-in-out infinite; } @@ -678,7 +678,7 @@ } &--cancelled { - background: var(--openbitfun-color-status-danger-content); + background: var(--openbitfun-color-status-danger-emphasis); opacity: 0.5; } } diff --git a/src/mobile-web/src/styles/global.scss b/src/mobile-web/src/styles/global.scss index 5326e5734c..22fa641fa7 100644 --- a/src/mobile-web/src/styles/global.scss +++ b/src/mobile-web/src/styles/global.scss @@ -222,8 +222,8 @@ html.theme-switching { justify-content: center; gap: 8px; padding: 8px 16px; - background: var(--openbitfun-color-status-warning-content); - color: var(--openbitfun-color-action-primary-content); + background: var(--openbitfun-color-status-warning-emphasis); + color: var(--openbitfun-color-content-on-light); font-size: var(--openbitfun-type-body-md-font-size); font-weight: var(--openbitfun-type-label-lg-font-weight); animation: slideDown var(--motion-fast) var(--easing-standard); diff --git a/src/web-ui/src/app/components/AssistantAvatar/AssistantAvatar.scss b/src/web-ui/src/app/components/AssistantAvatar/AssistantAvatar.scss index 8edcc8fabf..d94fa7a411 100644 --- a/src/web-ui/src/app/components/AssistantAvatar/AssistantAvatar.scss +++ b/src/web-ui/src/app/components/AssistantAvatar/AssistantAvatar.scss @@ -82,11 +82,11 @@ } &.is-attention &__status-dot { - background: var(--openbitfun-color-status-warning-content); + background: var(--openbitfun-color-status-warning-emphasis); } &.is-error &__status-dot { - background: var(--openbitfun-color-status-danger-content); + background: var(--openbitfun-color-status-danger-emphasis); } } diff --git a/src/web-ui/src/app/components/NavPanel/sections/sessions/SessionsSection.scss b/src/web-ui/src/app/components/NavPanel/sections/sessions/SessionsSection.scss index 7a76385e3e..210aff782a 100644 --- a/src/web-ui/src/app/components/NavPanel/sections/sessions/SessionsSection.scss +++ b/src/web-ui/src/app/components/NavPanel/sections/sessions/SessionsSection.scss @@ -338,9 +338,9 @@ width: 16px; height: 16px; padding: 0; - border: 1px solid color-mix(in srgb, var(--openbitfun-color-status-success-content) 36%, var(--openbitfun-color-border-subtle)); + border: 1px solid var(--openbitfun-color-status-success-border); border-radius: 999px; - background: color-mix(in srgb, var(--openbitfun-color-status-success-content) 12%, var(--openbitfun-color-action-quiet-hover)); + background: color-mix(in srgb, var(--openbitfun-color-status-success-emphasis) 12%, var(--openbitfun-color-action-quiet-hover)); color: color-mix(in srgb, var(--openbitfun-color-status-success-content) 76%, var(--openbitfun-color-content-primary)); overflow: hidden; // Kill the inline strut so the 16x16 circle stays optically centered against the title. @@ -378,9 +378,9 @@ gap: 3px; height: 14px; padding: 0 5px; - border: 1px solid color-mix(in srgb, var(--openbitfun-color-status-warning-content) 35%, var(--openbitfun-color-border-subtle)); + border: 1px solid var(--openbitfun-color-status-warning-border); border-radius: 999px; - background: color-mix(in srgb, var(--openbitfun-color-status-warning-content) 14%, transparent); + background: color-mix(in srgb, var(--openbitfun-color-status-warning-emphasis) 14%, transparent); color: color-mix(in srgb, var(--openbitfun-color-status-warning-content) 80%, var(--openbitfun-color-content-primary)); font-size: var(--openbitfun-type-micro-font-size); font-weight: var(--openbitfun-type-label-selected-font-weight); @@ -588,7 +588,7 @@ &.confirm:hover { color: var(--openbitfun-color-status-success-content); - background: color-mix(in srgb, var(--openbitfun-color-status-success-content) 12%, transparent); + background: var(--openbitfun-color-status-success-surface); } &.cancel:hover { @@ -640,13 +640,13 @@ margin-left: auto; &.is-healthy { - background: var(--openbitfun-color-status-success-content); - box-shadow: 0 0 4px color-mix(in srgb, var(--openbitfun-color-status-success-content) 40%, transparent); + background: var(--openbitfun-color-status-success-emphasis); + box-shadow: 0 0 4px color-mix(in srgb, var(--openbitfun-color-status-success-emphasis) 40%, transparent); } &.is-error { - background: var(--openbitfun-color-status-warning-content); - box-shadow: 0 0 4px color-mix(in srgb, var(--openbitfun-color-status-warning-content) 40%, transparent); + background: var(--openbitfun-color-status-warning-emphasis); + box-shadow: 0 0 4px color-mix(in srgb, var(--openbitfun-color-status-warning-emphasis) 40%, transparent); } } diff --git a/src/web-ui/src/app/components/NavPanel/sections/workspaces/WorkspaceListSection.scss b/src/web-ui/src/app/components/NavPanel/sections/workspaces/WorkspaceListSection.scss index 4a6170f684..a5c9d4f6d3 100644 --- a/src/web-ui/src/app/components/NavPanel/sections/workspaces/WorkspaceListSection.scss +++ b/src/web-ui/src/app/components/NavPanel/sections/workspaces/WorkspaceListSection.scss @@ -519,12 +519,12 @@ background: var(--openbitfun-color-content-muted); &.is-connected { - background: var(--openbitfun-color-status-success-content); + background: var(--openbitfun-color-status-success-emphasis); } &.is-error, &.is-disconnected { - background: var(--openbitfun-color-status-danger-content); + background: var(--openbitfun-color-status-danger-emphasis); } &.is-unknown { @@ -532,7 +532,7 @@ } &.is-connecting { - background: var(--openbitfun-color-status-warning-content); + background: var(--openbitfun-color-status-warning-emphasis); animation: openbitfun-status-dot-pulse 1.4s ease-in-out infinite; } } @@ -557,11 +557,11 @@ } &.is-green { - background: var(--openbitfun-color-status-success-content); + background: var(--openbitfun-color-status-success-emphasis); } &.is-yellow { - background: var(--openbitfun-color-status-warning-content); + background: var(--openbitfun-color-status-warning-emphasis); } &.is-gray { @@ -569,7 +569,7 @@ } &.is-red { - background: var(--openbitfun-color-status-danger-content); + background: var(--openbitfun-color-status-danger-emphasis); } } @@ -804,15 +804,15 @@ &.is-warning { color: color-mix(in srgb, var(--openbitfun-color-status-warning-content) 84%, var(--openbitfun-color-content-primary)); - border-color: color-mix(in srgb, var(--openbitfun-color-status-warning-content) 18%, transparent); - background: color-mix(in srgb, var(--openbitfun-color-status-warning-content) 10%, transparent); + border-color: var(--openbitfun-color-status-warning-border); + background: var(--openbitfun-color-status-warning-surface); } } &__workspace-index-tooltip-error { color: color-mix(in srgb, var(--openbitfun-color-status-danger-content) 88%, var(--openbitfun-color-content-primary)); - border-color: color-mix(in srgb, var(--openbitfun-color-status-danger-content) 22%, transparent); - background: color-mix(in srgb, var(--openbitfun-color-status-danger-content) 11%, transparent); + border-color: var(--openbitfun-color-status-danger-border); + background: var(--openbitfun-color-status-danger-surface); } &__workspace-index-tooltip-actions { diff --git a/src/web-ui/src/app/scenes/miniapps/MiniAppScene.scss b/src/web-ui/src/app/scenes/miniapps/MiniAppScene.scss index 56323e6989..23ae183c51 100644 --- a/src/web-ui/src/app/scenes/miniapps/MiniAppScene.scss +++ b/src/web-ui/src/app/scenes/miniapps/MiniAppScene.scss @@ -192,7 +192,7 @@ padding: var(--openbitfun-space-6); > svg { - color: var(--openbitfun-color-status-warning-content); + color: var(--openbitfun-color-status-warning-emphasis); } p { @@ -229,7 +229,7 @@ svg { flex: 0 0 auto; - color: var(--openbitfun-color-status-success-content); + color: var(--openbitfun-color-status-success-emphasis); } } @@ -305,7 +305,7 @@ svg { flex: 0 0 auto; margin-top: 2px; - color: var(--openbitfun-color-status-warning-content); + color: var(--openbitfun-color-status-warning-emphasis); } strong { @@ -336,8 +336,8 @@ } &--update { - border-bottom-color: color-mix(in srgb, var(--openbitfun-color-status-warning-content) 28%, var(--openbitfun-color-border-subtle)); - background: color-mix(in srgb, var(--openbitfun-color-status-warning-content) 12%, var(--openbitfun-color-surface-subtle)); + border-bottom-color: var(--openbitfun-color-status-warning-border); + background: var(--openbitfun-color-status-warning-surface); } } @@ -411,7 +411,7 @@ color: var(--openbitfun-color-content-secondary); svg { - color: var(--openbitfun-color-status-success-content); + color: var(--openbitfun-color-status-success-emphasis); } } @@ -523,7 +523,7 @@ svg { flex: 0 0 auto; - color: var(--openbitfun-color-status-warning-content); + color: var(--openbitfun-color-status-warning-emphasis); } p { diff --git a/src/web-ui/src/app/scenes/profile/views/AssistantDefaultsPage.scss b/src/web-ui/src/app/scenes/profile/views/AssistantDefaultsPage.scss index cda9ce92fe..b922f64e9d 100644 --- a/src/web-ui/src/app/scenes/profile/views/AssistantDefaultsPage.scss +++ b/src/web-ui/src/app/scenes/profile/views/AssistantDefaultsPage.scss @@ -123,15 +123,15 @@ $assistant-defaults-row-columns: gap: var(--openbitfun-space-2); margin: var(--openbitfun-space-3) 0 0; padding: var(--openbitfun-space-2) var(--openbitfun-space-3); - border: 1px solid color-mix(in srgb, var(--openbitfun-color-status-warning-content) 32%, var(--openbitfun-color-border-subtle)); + border: 1px solid var(--openbitfun-color-status-warning-border); border-radius: var(--openbitfun-radius-base); - background: color-mix(in srgb, var(--openbitfun-color-status-warning-content) 7%, transparent); + background: var(--openbitfun-color-status-warning-surface); color: var(--openbitfun-color-content-secondary); font-size: var(--openbitfun-type-label-sm-font-size); > svg { flex: 0 0 auto; - color: var(--openbitfun-color-status-warning-content); + color: var(--openbitfun-color-status-warning-emphasis); } span { @@ -504,11 +504,11 @@ $assistant-defaults-row-columns: } &--available &__dot { - background: var(--openbitfun-color-status-success-content); + background: var(--openbitfun-color-status-success-emphasis); } &--unavailable &__dot { - background: var(--openbitfun-color-status-warning-content); + background: var(--openbitfun-color-status-warning-emphasis); } } diff --git a/src/web-ui/src/app/scenes/settings/SettingsNav.scss b/src/web-ui/src/app/scenes/settings/SettingsNav.scss index 7667ebc4d8..f5931910db 100644 --- a/src/web-ui/src/app/scenes/settings/SettingsNav.scss +++ b/src/web-ui/src/app/scenes/settings/SettingsNav.scss @@ -139,6 +139,6 @@ height: 6px; flex: 0 0 auto; border-radius: 50%; - background: var(--openbitfun-color-status-warning-content); + background: var(--openbitfun-color-status-warning-emphasis); } } diff --git a/src/web-ui/src/features/relay-deploy/RelayDeployWizard.scss b/src/web-ui/src/features/relay-deploy/RelayDeployWizard.scss index 9bf15ea384..c9f451f56e 100644 --- a/src/web-ui/src/features/relay-deploy/RelayDeployWizard.scss +++ b/src/web-ui/src/features/relay-deploy/RelayDeployWizard.scss @@ -378,9 +378,9 @@ &__check-icon { flex-shrink: 0; - &--ok { color: var(--openbitfun-color-status-success-content); } - &--warn { color: var(--openbitfun-color-status-warning-content); } - &--fail { color: var(--openbitfun-color-status-danger-content); } + &--ok { color: var(--openbitfun-color-status-success-emphasis); } + &--warn { color: var(--openbitfun-color-status-warning-emphasis); } + &--fail { color: var(--openbitfun-color-status-danger-emphasis); } } &__check-label { @@ -457,7 +457,7 @@ border: 1px solid var(--openbitfun-color-status-warning-border); color: var(--openbitfun-color-content-primary); - svg { color: var(--openbitfun-color-status-warning-content); flex-shrink: 0; margin-top: 1px; } + svg { color: var(--openbitfun-color-status-warning-emphasis); flex-shrink: 0; margin-top: 1px; } } } diff --git a/src/web-ui/src/flow_chat/components/ChatInputApprovalBand.scss b/src/web-ui/src/flow_chat/components/ChatInputApprovalBand.scss index a721aa0982..ffb022f657 100644 --- a/src/web-ui/src/flow_chat/components/ChatInputApprovalBand.scss +++ b/src/web-ui/src/flow_chat/components/ChatInputApprovalBand.scss @@ -8,9 +8,9 @@ box-sizing: border-box; margin-bottom: 6px; padding: 8px 10px; - border: 1px solid color-mix(in srgb, var(--openbitfun-color-status-warning-content) 52%, var(--openbitfun-color-border-default)); + border: 1px solid var(--openbitfun-color-status-warning-border); border-radius: 12px; - background: color-mix(in srgb, var(--openbitfun-color-surface-raised) 94%, var(--openbitfun-color-status-warning-content)); + background: var(--openbitfun-color-status-warning-surface); color: var(--openbitfun-color-content-primary); font-size: var(--openbitfun-type-flow-control-font-size); animation: openbitfun-chat-input-approval-in 160ms cubic-bezier(0.23, 1, 0.32, 1); @@ -24,7 +24,7 @@ &__icon { flex: none; - color: var(--openbitfun-color-status-warning-content); + color: var(--openbitfun-color-status-warning-emphasis); } &__action { @@ -61,8 +61,8 @@ margin-left: auto; padding: 1px 6px; border-radius: 8px; - color: var(--openbitfun-color-content-on-dark); - background: var(--openbitfun-color-status-warning-content); + color: var(--openbitfun-color-content-on-light); + background: var(--openbitfun-color-status-warning-emphasis); font-size: var(--openbitfun-type-flow-support-font-size); font-weight: var(--openbitfun-type-heading-page-font-weight); cursor: default; @@ -111,11 +111,11 @@ &--active { color: var(--openbitfun-color-content-primary); - background: color-mix(in srgb, var(--openbitfun-color-status-warning-content) 18%, transparent); + background: color-mix(in srgb, var(--openbitfun-color-status-warning-emphasis) 18%, transparent); } &:focus-visible { - outline: 2px solid var(--openbitfun-color-status-warning-content); + outline: 2px solid var(--openbitfun-color-status-warning-emphasis); outline-offset: 1px; } } diff --git a/src/web-ui/src/flow_chat/components/ModelSelector.scss b/src/web-ui/src/flow_chat/components/ModelSelector.scss index 403f218a54..6fb6b0eee5 100644 --- a/src/web-ui/src/flow_chat/components/ModelSelector.scss +++ b/src/web-ui/src/flow_chat/components/ModelSelector.scss @@ -91,7 +91,7 @@ } &__fast-icon { - color: var(--openbitfun-color-status-warning-content); + color: var(--openbitfun-color-status-warning-emphasis); flex-shrink: 0; } diff --git a/src/web-ui/src/flow_chat/components/ToolApprovalBar.scss b/src/web-ui/src/flow_chat/components/ToolApprovalBar.scss index 18a8bbeaf9..562b3a5a21 100644 --- a/src/web-ui/src/flow_chat/components/ToolApprovalBar.scss +++ b/src/web-ui/src/flow_chat/components/ToolApprovalBar.scss @@ -6,10 +6,10 @@ gap: 6px; margin: 0 0 var(--openbitfun-control-flow-chat-card-gap); padding: 7px var(--openbitfun-control-tool-card-expanded-padding-inline); - border: 1px solid var(--openbitfun-color-status-warning-content); + border: 1px solid var(--openbitfun-color-status-warning-border); border-radius: var(--openbitfun-control-flow-chat-card-radius); - background: color-mix(in srgb, var(--openbitfun-color-status-warning-content) 7%, var(--openbitfun-color-surface-scene)); - box-shadow: 0 0 0 1px color-mix(in srgb, var(--openbitfun-color-status-warning-content) 12%, transparent); + background: var(--openbitfun-color-status-warning-surface); + box-shadow: 0 0 0 1px color-mix(in srgb, var(--openbitfun-color-status-warning-emphasis) 12%, transparent); box-sizing: border-box; } @@ -60,12 +60,12 @@ } .tool-approval-bar__auto-execute-button:hover:not(:disabled) { - background: color-mix(in srgb, var(--openbitfun-color-status-success-content) 18%, transparent); + background: color-mix(in srgb, var(--openbitfun-color-status-success-emphasis) 18%, transparent); color: var(--openbitfun-color-status-success-content); } .tool-approval-bar__auto-execute-button:active:not(:disabled) { - background: color-mix(in srgb, var(--openbitfun-color-status-success-content) 24%, transparent); + background: color-mix(in srgb, var(--openbitfun-color-status-success-emphasis) 24%, transparent); color: var(--openbitfun-color-status-success-content); } @@ -89,16 +89,16 @@ color: var(--openbitfun-color-content-primary); font-size: var(--openbitfun-type-flow-control-font-size); outline: none; - box-shadow: 0 0 0 2px color-mix(in srgb, var(--openbitfun-color-status-warning-content) 12%, transparent); + box-shadow: 0 0 0 2px color-mix(in srgb, var(--openbitfun-color-status-warning-emphasis) 12%, transparent); } .tool-approval-bar__instruction-submit { flex-shrink: 0; height: 28px; padding: 0 10px; - border: 1px solid color-mix(in srgb, var(--openbitfun-color-status-danger-content) 45%, transparent); + border: 1px solid var(--openbitfun-color-status-danger-border); border-radius: 6px; - background: color-mix(in srgb, var(--openbitfun-color-status-danger-content) 10%, transparent); + background: var(--openbitfun-color-status-danger-surface); color: var(--openbitfun-color-status-danger-content); font-size: var(--openbitfun-type-flow-control-font-size); cursor: pointer; @@ -106,7 +106,7 @@ } .tool-approval-bar__instruction-submit:hover { - background: color-mix(in srgb, var(--openbitfun-color-status-danger-content) 16%, transparent); + background: color-mix(in srgb, var(--openbitfun-color-status-danger-emphasis) 16%, transparent); } .tool-approval-bar__instruction-submit:active:not(:disabled), diff --git a/src/web-ui/src/flow_chat/components/background-command/BackgroundCommandOutputPanel.scss b/src/web-ui/src/flow_chat/components/background-command/BackgroundCommandOutputPanel.scss index b366afa8c6..be3ebe103a 100644 --- a/src/web-ui/src/flow_chat/components/background-command/BackgroundCommandOutputPanel.scss +++ b/src/web-ui/src/flow_chat/components/background-command/BackgroundCommandOutputPanel.scss @@ -142,15 +142,23 @@ } &__notice { - border: 1px solid color-mix(in srgb, var(--openbitfun-color-status-warning-content) 30%, transparent); - background: color-mix(in srgb, var(--openbitfun-color-status-warning-content) 10%, transparent); + border: 1px solid var(--openbitfun-color-status-warning-border); + background: var(--openbitfun-color-status-warning-surface); color: var(--openbitfun-color-content-secondary); + + > svg { + color: var(--openbitfun-color-status-warning-emphasis); + } } &__error { - border: 1px solid color-mix(in srgb, var(--openbitfun-color-status-danger-content) 30%, transparent); - background: color-mix(in srgb, var(--openbitfun-color-status-danger-content) 10%, transparent); + border: 1px solid var(--openbitfun-color-status-danger-border); + background: var(--openbitfun-color-status-danger-surface); color: var(--openbitfun-color-status-danger-content); + + > svg { + color: var(--openbitfun-color-status-danger-emphasis); + } } &__output { diff --git a/src/web-ui/src/flow_chat/components/modern/FlowChatHeader.scss b/src/web-ui/src/flow_chat/components/modern/FlowChatHeader.scss index df8433f6ac..b244c8a61b 100644 --- a/src/web-ui/src/flow_chat/components/modern/FlowChatHeader.scss +++ b/src/web-ui/src/flow_chat/components/modern/FlowChatHeader.scss @@ -71,7 +71,7 @@ &:not(:disabled):hover, &.flowchat-header__session-overview-trigger--active { color: var(--openbitfun-color-status-success-content); - background: color-mix(in srgb, var(--openbitfun-color-status-success-content) 12%, transparent); + background: var(--openbitfun-color-status-success-surface); } } } @@ -99,10 +99,10 @@ width: 4px; height: 4px; border-radius: 999px; - background: color-mix(in srgb, var(--openbitfun-color-status-success-content) 92%, var(--openbitfun-color-content-on-dark) 8%); + background: var(--openbitfun-color-status-success-emphasis); box-shadow: 0 0 0 1px var(--openbitfun-color-surface-raised), - 0 0 0 0 color-mix(in srgb, var(--openbitfun-color-status-success-content) 42%, transparent); + 0 0 0 0 color-mix(in srgb, var(--openbitfun-color-status-success-emphasis) 42%, transparent); animation: flowchat-header-session-overview-pulse 1.45s ease-out infinite; } @@ -113,7 +113,7 @@ opacity: 0.9; box-shadow: 0 0 0 1px var(--openbitfun-color-surface-raised), - 0 0 0 0 color-mix(in srgb, var(--openbitfun-color-status-success-content) 40%, transparent); + 0 0 0 0 color-mix(in srgb, var(--openbitfun-color-status-success-emphasis) 40%, transparent); } 50% { @@ -121,7 +121,7 @@ opacity: 1; box-shadow: 0 0 0 1px var(--openbitfun-color-surface-raised), - 0 0 0 5px color-mix(in srgb, var(--openbitfun-color-status-success-content) 0%, transparent); + 0 0 0 5px color-mix(in srgb, var(--openbitfun-color-status-success-emphasis) 0%, transparent); } } @@ -336,7 +336,7 @@ height: 5px; flex: 0 0 5px; border-radius: 50%; - background: var(--openbitfun-color-status-success-content); + background: var(--openbitfun-color-status-success-emphasis); } &__session-overview-section-actions { diff --git a/src/web-ui/src/flow_chat/components/modern/SessionTreePopover.scss b/src/web-ui/src/flow_chat/components/modern/SessionTreePopover.scss index bb7fe652b8..2694739b5d 100644 --- a/src/web-ui/src/flow_chat/components/modern/SessionTreePopover.scss +++ b/src/web-ui/src/flow_chat/components/modern/SessionTreePopover.scss @@ -68,7 +68,7 @@ &:not(:disabled):hover, &.session-tree-popover__trigger--active { color: var(--openbitfun-color-status-success-content); - background: color-mix(in srgb, var(--openbitfun-color-status-success-content) 12%, transparent); + background: var(--openbitfun-color-status-success-surface); } } } @@ -87,7 +87,7 @@ width: 4px; height: 4px; border-radius: 999px; - background: color-mix(in srgb, var(--openbitfun-color-status-success-content) 92%, var(--openbitfun-color-content-on-dark) 8%); + background: var(--openbitfun-color-status-success-emphasis); box-shadow: 0 0 0 1px var(--openbitfun-color-surface-raised); } @@ -287,20 +287,20 @@ &--running, &--finishing { - background: var(--openbitfun-color-status-success-content); + background: var(--openbitfun-color-status-success-emphasis); } &--waiting { - background: var(--openbitfun-color-status-warning-content); + background: var(--openbitfun-color-status-warning-emphasis); } &--error, &--cancelled { - background: var(--openbitfun-color-status-danger-content); + background: var(--openbitfun-color-status-danger-emphasis); } &--completed { - background: var(--openbitfun-color-status-info-content); + background: var(--openbitfun-color-status-info-emphasis); } } diff --git a/src/web-ui/src/flow_chat/components/modern/TurnCompletionNoticeItem.scss b/src/web-ui/src/flow_chat/components/modern/TurnCompletionNoticeItem.scss index b7d2114e6e..8fa7e50ba0 100644 --- a/src/web-ui/src/flow_chat/components/modern/TurnCompletionNoticeItem.scss +++ b/src/web-ui/src/flow_chat/components/modern/TurnCompletionNoticeItem.scss @@ -17,18 +17,18 @@ line-height: var(--openbitfun-type-flow-support-line-height); &--warning { - border-color: color-mix(in srgb, var(--openbitfun-color-status-warning-content) 45%, transparent); - background: color-mix(in srgb, var(--openbitfun-color-status-warning-content) 10%, var(--openbitfun-color-surface-panel)); + border-color: var(--openbitfun-color-status-warning-border); + background: var(--openbitfun-color-status-warning-surface); } &--error { - border-color: color-mix(in srgb, var(--openbitfun-color-status-danger-content) 45%, transparent); - background: color-mix(in srgb, var(--openbitfun-color-status-danger-content) 10%, var(--openbitfun-color-surface-panel)); + border-color: var(--openbitfun-color-status-danger-border); + background: var(--openbitfun-color-status-danger-surface); } &--info { - border-color: color-mix(in srgb, var(--openbitfun-color-accent-default) 45%, transparent); - background: color-mix(in srgb, var(--openbitfun-color-accent-default) 10%, var(--openbitfun-color-surface-panel)); + border-color: var(--openbitfun-color-status-info-border); + background: var(--openbitfun-color-status-info-surface); } } @@ -38,8 +38,15 @@ justify-content: center; flex: 0 0 auto; margin-top: 1px; - color: inherit; - opacity: 0.88; + color: var(--openbitfun-color-status-info-emphasis); + + .turn-completion-notice--warning & { + color: var(--openbitfun-color-status-warning-emphasis); + } + + .turn-completion-notice--error & { + color: var(--openbitfun-color-status-danger-emphasis); + } } .turn-completion-notice__content { diff --git a/src/web-ui/src/flow_chat/components/modern/TurnFailureNoticeItem.scss b/src/web-ui/src/flow_chat/components/modern/TurnFailureNoticeItem.scss index dba290c7bf..837dfd124c 100644 --- a/src/web-ui/src/flow_chat/components/modern/TurnFailureNoticeItem.scss +++ b/src/web-ui/src/flow_chat/components/modern/TurnFailureNoticeItem.scss @@ -8,16 +8,16 @@ calc(var(--openbitfun-control-flow-chat-turn-gap) + 0.18rem) var(--openbitfun-control-flow-chat-content-padding-inline); padding: 8px 10px; - border: 1px solid color-mix(in srgb, var(--openbitfun-color-status-danger-content) 45%, transparent); + border: 1px solid var(--openbitfun-color-status-danger-border); border-radius: 6px; - background: color-mix(in srgb, var(--openbitfun-color-status-danger-content) 10%, var(--openbitfun-color-surface-panel)); + background: var(--openbitfun-color-status-danger-surface); color: var(--openbitfun-color-content-primary); font-size: var(--openbitfun-type-label-sm-font-size); line-height: var(--openbitfun-type-flow-support-line-height); &--warning { - border-color: color-mix(in srgb, var(--openbitfun-color-status-warning-content) 45%, transparent); - background: color-mix(in srgb, var(--openbitfun-color-status-warning-content) 10%, var(--openbitfun-color-surface-panel)); + border-color: var(--openbitfun-color-status-warning-border); + background: var(--openbitfun-color-status-warning-surface); } } @@ -25,10 +25,10 @@ display: inline-flex; flex: 0 0 auto; margin-top: 4px; - color: var(--openbitfun-color-status-danger-content); + color: var(--openbitfun-color-status-danger-emphasis); .turn-failure-notice--warning & { - color: var(--openbitfun-color-status-warning-content); + color: var(--openbitfun-color-status-warning-emphasis); } } diff --git a/src/web-ui/src/flow_chat/components/modern/UserMessageItem.scss b/src/web-ui/src/flow_chat/components/modern/UserMessageItem.scss index af01b02e35..697bce8515 100644 --- a/src/web-ui/src/flow_chat/components/modern/UserMessageItem.scss +++ b/src/web-ui/src/flow_chat/components/modern/UserMessageItem.scss @@ -134,8 +134,8 @@ .user-message-item__steering-tag--pending { color: var(--openbitfun-color-status-warning-content); - background: color-mix(in srgb, var(--openbitfun-color-status-warning-content) 12%, transparent); - border: 1px solid color-mix(in srgb, var(--openbitfun-color-status-warning-content) 28%, transparent); + background: var(--openbitfun-color-status-warning-surface); + border: 1px solid var(--openbitfun-color-status-warning-border); } .user-message-item__actions { diff --git a/src/web-ui/src/flow_chat/components/thread-goal/ThreadGoalDialogs.scss b/src/web-ui/src/flow_chat/components/thread-goal/ThreadGoalDialogs.scss index 47dbe5c74e..9f90aa3eeb 100644 --- a/src/web-ui/src/flow_chat/components/thread-goal/ThreadGoalDialogs.scss +++ b/src/web-ui/src/flow_chat/components/thread-goal/ThreadGoalDialogs.scss @@ -35,8 +35,12 @@ &--paused, &--blocked { color: var(--openbitfun-color-status-warning-content); - background: color-mix(in srgb, var(--openbitfun-color-status-warning-content) 12%, transparent); - border-color: color-mix(in srgb, var(--openbitfun-color-status-warning-content) 32%, transparent); + background: var(--openbitfun-color-status-warning-surface); + border-color: var(--openbitfun-color-status-warning-border); + + > svg { + color: var(--openbitfun-color-status-warning-emphasis); + } } &--usageLimited, @@ -48,8 +52,12 @@ &--complete { color: var(--openbitfun-color-status-success-content); - background: color-mix(in srgb, var(--openbitfun-color-status-success-content) 12%, transparent); - border-color: color-mix(in srgb, var(--openbitfun-color-status-success-content) 32%, transparent); + background: var(--openbitfun-color-status-success-surface); + border-color: var(--openbitfun-color-status-success-border); + + > svg { + color: var(--openbitfun-color-status-success-emphasis); + } } } @@ -120,8 +128,8 @@ box-sizing: border-box; &--done { - background: var(--openbitfun-color-status-success-content); - box-shadow: 0 0 0 3px color-mix(in srgb, var(--openbitfun-color-status-success-content) 20%, transparent); + background: var(--openbitfun-color-status-success-emphasis); + box-shadow: 0 0 0 3px color-mix(in srgb, var(--openbitfun-color-status-success-emphasis) 20%, transparent); } &--current { diff --git a/src/web-ui/src/flow_chat/components/usage/SessionUsagePanel.scss b/src/web-ui/src/flow_chat/components/usage/SessionUsagePanel.scss index f22054208c..be6554424c 100644 --- a/src/web-ui/src/flow_chat/components/usage/SessionUsagePanel.scss +++ b/src/web-ui/src/flow_chat/components/usage/SessionUsagePanel.scss @@ -62,12 +62,12 @@ &--complete { color: var(--openbitfun-color-status-success-content); - background: color-mix(in srgb, var(--openbitfun-color-status-success-content) 12%, transparent); + background: var(--openbitfun-color-status-success-surface); } &--partial { color: var(--openbitfun-color-status-warning-content); - background: color-mix(in srgb, var(--openbitfun-color-status-warning-content) 12%, transparent); + background: var(--openbitfun-color-status-warning-surface); } &--minimal { @@ -229,14 +229,14 @@ gap: 6px; min-height: 30px; padding: 7px 8px; - border-left: 2px solid color-mix(in srgb, var(--openbitfun-color-status-warning-content) 74%, transparent); - background: color-mix(in srgb, var(--openbitfun-color-status-warning-content) 8%, transparent); + border-left: 2px solid var(--openbitfun-color-status-warning-emphasis); + background: var(--openbitfun-color-status-warning-surface); color: var(--openbitfun-color-content-secondary); font-size: var(--openbitfun-type-flow-control-font-size); svg { flex: 0 0 auto; - color: var(--openbitfun-color-status-warning-content); + color: var(--openbitfun-color-status-warning-emphasis); } } diff --git a/src/web-ui/src/flow_chat/components/usage/SessionUsageReportCard.scss b/src/web-ui/src/flow_chat/components/usage/SessionUsageReportCard.scss index a1b8770f7f..e60dcae99f 100644 --- a/src/web-ui/src/flow_chat/components/usage/SessionUsageReportCard.scss +++ b/src/web-ui/src/flow_chat/components/usage/SessionUsageReportCard.scss @@ -169,12 +169,12 @@ &--complete { color: var(--openbitfun-color-status-success-content); - background: color-mix(in srgb, var(--openbitfun-color-status-success-content) 12%, transparent); + background: var(--openbitfun-color-status-success-surface); } &--partial { color: var(--openbitfun-color-status-warning-content); - background: color-mix(in srgb, var(--openbitfun-color-status-warning-content) 12%, transparent); + background: var(--openbitfun-color-status-warning-surface); } &--minimal { diff --git a/src/web-ui/src/flow_chat/components/voice/RealtimeVoiceCall.scss b/src/web-ui/src/flow_chat/components/voice/RealtimeVoiceCall.scss index 8006ab6e4a..40207e3b29 100644 --- a/src/web-ui/src/flow_chat/components/voice/RealtimeVoiceCall.scss +++ b/src/web-ui/src/flow_chat/components/voice/RealtimeVoiceCall.scss @@ -11,7 +11,7 @@ 145deg, color-mix(in srgb, var(--openbitfun-color-surface-raised) 12%, transparent) 0%, transparent 58%, - color-mix(in srgb, var(--openbitfun-color-status-success-content) 8%, transparent) 100% + color-mix(in srgb, var(--openbitfun-color-status-success-emphasis) 8%, transparent) 100% ); color: var(--openbitfun-color-content-primary); animation: openbitfun-realtime-call-in 260ms cubic-bezier(0.18, 0.9, 0.3, 1.08) both; @@ -68,20 +68,20 @@ height: 8px; flex: 0 0 8px; border-radius: 50%; - background: var(--openbitfun-color-status-success-content); - box-shadow: 0 0 0 4px color-mix(in srgb, var(--openbitfun-color-status-success-content) 12%, transparent); + background: var(--openbitfun-color-status-success-emphasis); + box-shadow: 0 0 0 4px color-mix(in srgb, var(--openbitfun-color-status-success-emphasis) 12%, transparent); animation: openbitfun-realtime-call-live 1.8s ease-in-out infinite; } &[data-openbitfun-phase='connecting'] &__live-dot, &[data-openbitfun-phase='ending'] &__live-dot { - background: var(--openbitfun-color-status-warning-content); - box-shadow: 0 0 0 4px color-mix(in srgb, var(--openbitfun-color-status-warning-content) 12%, transparent); + background: var(--openbitfun-color-status-warning-emphasis); + box-shadow: 0 0 0 4px color-mix(in srgb, var(--openbitfun-color-status-warning-emphasis) 12%, transparent); } &[data-openbitfun-phase='error'] &__live-dot { - background: var(--openbitfun-color-status-danger-content); - box-shadow: 0 0 0 4px color-mix(in srgb, var(--openbitfun-color-status-danger-content) 12%, transparent); + background: var(--openbitfun-color-status-danger-emphasis); + box-shadow: 0 0 0 4px color-mix(in srgb, var(--openbitfun-color-status-danger-emphasis) 12%, transparent); } &__conversation { @@ -200,7 +200,7 @@ } &__control--end { - border-color: color-mix(in srgb, var(--openbitfun-color-status-danger-content) 32%, transparent); + border-color: var(--openbitfun-color-status-danger-border); background: var(--openbitfun-color-status-danger-content); color: var(--openbitfun-color-content-on-dark); diff --git a/src/web-ui/src/flow_chat/subagent-identity/SubagentAvatar.scss b/src/web-ui/src/flow_chat/subagent-identity/SubagentAvatar.scss index 6588f58e74..d2beed43be 100644 --- a/src/web-ui/src/flow_chat/subagent-identity/SubagentAvatar.scss +++ b/src/web-ui/src/flow_chat/subagent-identity/SubagentAvatar.scss @@ -40,19 +40,19 @@ &--running &__status, &--finishing &__status { - background: var(--openbitfun-color-status-success-content); + background: var(--openbitfun-color-status-success-emphasis); } &--waiting &__status { - background: var(--openbitfun-color-status-warning-content); + background: var(--openbitfun-color-status-warning-emphasis); } &--error &__status, &--cancelled &__status { - background: var(--openbitfun-color-status-danger-content); + background: var(--openbitfun-color-status-danger-emphasis); } &--completed &__status { - background: var(--openbitfun-color-status-info-content); + background: var(--openbitfun-color-status-info-emphasis); } } diff --git a/src/web-ui/src/flow_chat/tool-cards/ToolTimeoutIndicator.scss b/src/web-ui/src/flow_chat/tool-cards/ToolTimeoutIndicator.scss index 87b2a5d568..8abbacfeaf 100644 --- a/src/web-ui/src/flow_chat/tool-cards/ToolTimeoutIndicator.scss +++ b/src/web-ui/src/flow_chat/tool-cards/ToolTimeoutIndicator.scss @@ -27,15 +27,33 @@ .duration-text--warning { color: var(--openbitfun-color-status-warning-content); + + > svg, + > [data-openbitfun-component='icon'] { + color: var(--openbitfun-color-status-warning-emphasis); + opacity: 1; + } } .duration-text--completed-success { color: var(--openbitfun-color-status-success-content); + + > svg, + > [data-openbitfun-component='icon'] { + color: var(--openbitfun-color-status-success-emphasis); + opacity: 1; + } } .duration-text--completed-error, .duration-text--completed-cancelled { color: var(--openbitfun-color-status-danger-content); + + > svg, + > [data-openbitfun-component='icon'] { + color: var(--openbitfun-color-status-danger-emphasis); + opacity: 1; + } } .duration-separator { diff --git a/src/web-ui/src/infrastructure/config/components/ExternalSourcesConfig.scss b/src/web-ui/src/infrastructure/config/components/ExternalSourcesConfig.scss index 74d7c9d7c8..ba24bc6332 100644 --- a/src/web-ui/src/infrastructure/config/components/ExternalSourcesConfig.scss +++ b/src/web-ui/src/infrastructure/config/components/ExternalSourcesConfig.scss @@ -138,7 +138,7 @@ place-items: center; border: 0; border-radius: var(--openbitfun-radius-sm); - color: var(--openbitfun-color-status-warning-content); + color: var(--openbitfun-color-status-warning-emphasis); background: transparent; cursor: pointer; @@ -260,9 +260,9 @@ align-items: center; gap: 8px; padding: 8px 12px; - border-left: 2px solid var(--openbitfun-color-status-warning-content); + border-left: 2px solid var(--openbitfun-color-status-warning-emphasis); color: var(--openbitfun-color-content-primary); - background: color-mix(in srgb, var(--openbitfun-color-status-warning-content) 7%, transparent); + background: var(--openbitfun-color-status-warning-surface); font-size: var(--openbitfun-type-label-sm-font-size); > span { @@ -389,8 +389,8 @@ &__notice[role='alert'], &__notice[data-external-attention='true'] { padding: 8px 12px; - border-left: 2px solid var(--openbitfun-color-status-warning-content); - background: color-mix(in srgb, var(--openbitfun-color-status-warning-content) 7%, transparent); + border-left: 2px solid var(--openbitfun-color-status-warning-emphasis); + background: var(--openbitfun-color-status-warning-surface); } &__notice summary { diff --git a/src/web-ui/src/infrastructure/config/components/McpToolsConfig.scss b/src/web-ui/src/infrastructure/config/components/McpToolsConfig.scss index eee3051093..66b5f534d7 100644 --- a/src/web-ui/src/infrastructure/config/components/McpToolsConfig.scss +++ b/src/web-ui/src/infrastructure/config/components/McpToolsConfig.scss @@ -88,21 +88,37 @@ border: 1px solid transparent; &.is-healthy { - background: color-mix(in srgb, var(--openbitfun-color-status-success-content) 10%, transparent); + background: var(--openbitfun-color-status-success-surface); color: var(--openbitfun-color-status-success-content); - border-color: color-mix(in srgb, var(--openbitfun-color-status-success-content) 25%, transparent); + border-color: var(--openbitfun-color-status-success-border); + + > svg, + > [data-openbitfun-component='icon'] { + color: var(--openbitfun-color-status-success-emphasis); + } } &.is-pending { - background: color-mix(in srgb, var(--openbitfun-color-status-warning-content) 10%, transparent); + background: var(--openbitfun-color-status-warning-surface); color: var(--openbitfun-color-status-warning-content); - border-color: color-mix(in srgb, var(--openbitfun-color-status-warning-content) 25%, transparent); + border-color: var(--openbitfun-color-status-warning-border); + + > svg, + > [data-openbitfun-component='icon'], + > [data-openbitfun-part='processing'] { + color: var(--openbitfun-color-status-warning-emphasis); + } } &.is-error { - background: color-mix(in srgb, var(--openbitfun-color-status-danger-content) 10%, transparent); + background: var(--openbitfun-color-status-danger-surface); color: var(--openbitfun-color-status-danger-content); - border-color: color-mix(in srgb, var(--openbitfun-color-status-danger-content) 25%, transparent); + border-color: var(--openbitfun-color-status-danger-border); + + > svg, + > [data-openbitfun-component='icon'] { + color: var(--openbitfun-color-status-danger-emphasis); + } } &.is-muted { @@ -130,15 +146,15 @@ } &__runtime-badge--ok { - background: color-mix(in srgb, var(--openbitfun-color-status-success-content) 10%, transparent); + background: var(--openbitfun-color-status-success-surface); color: var(--openbitfun-color-status-success-content); - border-color: color-mix(in srgb, var(--openbitfun-color-status-success-content) 25%, transparent); + border-color: var(--openbitfun-color-status-success-border); } &__runtime-badge--error { - background: color-mix(in srgb, var(--openbitfun-color-status-danger-content) 10%, transparent); + background: var(--openbitfun-color-status-danger-surface); color: var(--openbitfun-color-status-danger-content); - border-color: color-mix(in srgb, var(--openbitfun-color-status-danger-content) 25%, transparent); + border-color: var(--openbitfun-color-status-danger-border); } &__server-details { diff --git a/src/web-ui/src/infrastructure/config/components/ModelSettingsPage.scss b/src/web-ui/src/infrastructure/config/components/ModelSettingsPage.scss index 2348693fdd..7d7a2db57a 100644 --- a/src/web-ui/src/infrastructure/config/components/ModelSettingsPage.scss +++ b/src/web-ui/src/infrastructure/config/components/ModelSettingsPage.scss @@ -316,11 +316,11 @@ background: var(--openbitfun-color-content-muted); &.is-success { - background: var(--openbitfun-color-status-success-content); + background: var(--openbitfun-color-status-success-emphasis); } &.is-error { - background: var(--openbitfun-color-status-danger-content); + background: var(--openbitfun-color-status-danger-emphasis); } } @@ -422,6 +422,7 @@ color: var(--openbitfun-color-status-warning-content); svg { + color: var(--openbitfun-color-status-warning-emphasis); flex-shrink: 0; margin-top: 1px; } @@ -802,12 +803,12 @@ } &--embedding { - background: color-mix(in srgb, var(--openbitfun-color-status-success-content) 12%, transparent); + background: var(--openbitfun-color-status-success-surface); color: var(--openbitfun-color-status-success-content); } &--search { - background: color-mix(in srgb, var(--openbitfun-color-status-warning-content) 12%, transparent); + background: var(--openbitfun-color-status-warning-surface); color: var(--openbitfun-color-status-warning-content); } @@ -903,13 +904,13 @@ &.success { - border: 1px solid var(--openbitfun-color-status-success-content); + border: 1px solid var(--openbitfun-color-status-success-emphasis); color: var(--openbitfun-color-status-success-content); } &.error { - border: 1px solid var(--openbitfun-color-status-danger-content); + border: 1px solid var(--openbitfun-color-status-danger-emphasis); color: var(--openbitfun-color-status-danger-content); } } @@ -967,7 +968,7 @@ &:hover:not(:disabled) { background: var(--openbitfun-color-surface-subtle); border-style: solid; - border-color: var(--openbitfun-color-status-danger-content); + border-color: var(--openbitfun-color-status-danger-emphasis); color: var(--openbitfun-color-status-danger-content); svg { @@ -1531,13 +1532,14 @@ padding: var(--openbitfun-space-3); background: transparent; - border: 1px dashed color-mix(in srgb, var(--openbitfun-color-status-warning-content) 40%, transparent); + border: 1px dashed var(--openbitfun-color-status-warning-border); border-radius: var(--openbitfun-radius-sm); margin-top: var(--openbitfun-space-2); color: var(--openbitfun-color-status-warning-content); font-size: var(--openbitfun-type-label-md-font-size); svg { + color: var(--openbitfun-color-status-warning-emphasis); flex-shrink: 0; margin-top: 1px; } @@ -2103,7 +2105,7 @@ background: color-mix(in srgb, var(--openbitfun-color-content-on-dark) 4%, transparent); &--failed { - border-color: var(--openbitfun-color-status-danger-content); + border-color: var(--openbitfun-color-status-danger-emphasis); } } diff --git a/src/web-ui/src/infrastructure/config/components/RuntimeSettingsPages.scss b/src/web-ui/src/infrastructure/config/components/RuntimeSettingsPages.scss index c67c7b4da7..36edc53e76 100644 --- a/src/web-ui/src/infrastructure/config/components/RuntimeSettingsPages.scss +++ b/src/web-ui/src/infrastructure/config/components/RuntimeSettingsPages.scss @@ -72,7 +72,7 @@ max-width: 100%; padding: 6px 10px; border-radius: var(--openbitfun-radius-sm); - border: 1px dashed color-mix(in srgb, var(--openbitfun-color-status-warning-content) 40%, transparent); + border: 1px dashed var(--openbitfun-color-status-warning-border); color: var(--openbitfun-color-status-warning-content); font-size: var(--openbitfun-type-label-sm-font-size); line-height: var(--openbitfun-type-body-lg-line-height); diff --git a/src/web-ui/src/infrastructure/config/components/SkillsConfig.scss b/src/web-ui/src/infrastructure/config/components/SkillsConfig.scss index 13631cd953..e80b8b1152 100644 --- a/src/web-ui/src/infrastructure/config/components/SkillsConfig.scss +++ b/src/web-ui/src/infrastructure/config/components/SkillsConfig.scss @@ -27,14 +27,14 @@ font-size: var(--openbitfun-type-label-md-font-size); &.is-valid { - background: color-mix(in srgb, var(--openbitfun-color-status-success-content) 8%, transparent); - border: 1px solid color-mix(in srgb, var(--openbitfun-color-status-success-content) 30%, transparent); + background: var(--openbitfun-color-status-success-surface); + border: 1px solid var(--openbitfun-color-status-success-border); color: var(--openbitfun-color-status-success-content); } &.is-invalid { - background: color-mix(in srgb, var(--openbitfun-color-status-danger-content) 8%, transparent); - border: 1px solid color-mix(in srgb, var(--openbitfun-color-status-danger-content) 30%, transparent); + background: var(--openbitfun-color-status-danger-surface); + border: 1px solid var(--openbitfun-color-status-danger-border); color: var(--openbitfun-color-status-danger-content); } } @@ -71,8 +71,8 @@ &__covered-badge { color: var(--openbitfun-color-status-warning-content); - border-color: color-mix(in srgb, var(--openbitfun-color-status-warning-content) 32%, var(--openbitfun-color-border-subtle)); - background: color-mix(in srgb, var(--openbitfun-color-status-warning-content) 10%, var(--openbitfun-color-action-neutral-surface-hover)); + border-color: var(--openbitfun-color-status-warning-border); + background: var(--openbitfun-color-status-warning-surface); } &__item--covered { @@ -114,7 +114,7 @@ } &__market-state--error { - border-color: color-mix(in srgb, var(--openbitfun-color-status-danger-content) 40%, transparent); + border-color: var(--openbitfun-color-status-danger-border); color: var(--openbitfun-color-status-danger-content); } @@ -158,10 +158,10 @@ } &.is-installed { - border-color: color-mix(in srgb, var(--openbitfun-color-status-success-content) 35%, transparent); + border-color: var(--openbitfun-color-status-success-border); &::before { - background: color-mix(in srgb, var(--openbitfun-color-status-success-content) 78%, transparent); + background: color-mix(in srgb, var(--openbitfun-color-status-success-emphasis) 78%, transparent); } } @@ -226,8 +226,8 @@ } &__market-item-badge--installed { - border-color: color-mix(in srgb, var(--openbitfun-color-status-success-content) 35%, transparent); - background: color-mix(in srgb, var(--openbitfun-color-status-success-content) 14%, transparent); + border-color: var(--openbitfun-color-status-success-border); + background: color-mix(in srgb, var(--openbitfun-color-status-success-emphasis) 14%, transparent); color: var(--openbitfun-color-status-success-content); } diff --git a/src/web-ui/src/infrastructure/peer-device/DeviceSurfaceSwitcher.scss b/src/web-ui/src/infrastructure/peer-device/DeviceSurfaceSwitcher.scss index 676166a28d..2301fdd770 100644 --- a/src/web-ui/src/infrastructure/peer-device/DeviceSurfaceSwitcher.scss +++ b/src/web-ui/src/infrastructure/peer-device/DeviceSurfaceSwitcher.scss @@ -34,15 +34,15 @@ } &.is-remote { - background: color-mix(in srgb, var(--openbitfun-color-status-warning-content) 14%, transparent); + background: color-mix(in srgb, var(--openbitfun-color-status-warning-emphasis) 14%, transparent); color: var(--openbitfun-color-content-primary); .openbitfun-device-switcher__icon { - color: var(--openbitfun-color-status-warning-content); + color: var(--openbitfun-color-status-warning-emphasis); } &:hover { - background: color-mix(in srgb, var(--openbitfun-color-status-warning-content) 20%, transparent); + background: color-mix(in srgb, var(--openbitfun-color-status-warning-emphasis) 20%, transparent); } } @@ -69,7 +69,7 @@ flex-shrink: 0; padding: 1px 5px; border-radius: var(--openbitfun-radius-sm); - background: color-mix(in srgb, var(--openbitfun-color-status-success-content) 18%, transparent); + background: color-mix(in srgb, var(--openbitfun-color-status-success-emphasis) 18%, transparent); color: var(--openbitfun-color-status-success-content); font-size: var(--openbitfun-type-micro-font-size); font-variant-numeric: tabular-nums; @@ -102,10 +102,10 @@ width: 7px; height: 7px; border-radius: 50%; - background: var(--openbitfun-color-status-success-content); + background: var(--openbitfun-color-status-success-emphasis); &.is-busy { - background: var(--openbitfun-color-status-warning-content); + background: var(--openbitfun-color-status-warning-emphasis); animation: openbitfun-device-switcher-pulse 1.6s var(--openbitfun-motion-easing-standard) infinite; } @@ -125,7 +125,7 @@ white-space: nowrap; &.is-busy { - background: color-mix(in srgb, var(--openbitfun-color-status-warning-content) 18%, transparent); + background: color-mix(in srgb, var(--openbitfun-color-status-warning-emphasis) 18%, transparent); color: var(--openbitfun-color-status-warning-content); } } diff --git a/src/web-ui/src/shared/notification-system/components/NotificationCenter.scss b/src/web-ui/src/shared/notification-system/components/NotificationCenter.scss index a090cf0ea9..fa128c3481 100644 --- a/src/web-ui/src/shared/notification-system/components/NotificationCenter.scss +++ b/src/web-ui/src/shared/notification-system/components/NotificationCenter.scss @@ -154,20 +154,21 @@ &--success, &--completed { - color: var(--openbitfun-color-status-success-content); + color: var(--openbitfun-color-status-success-emphasis); } &--error, &--failed { - color: var(--openbitfun-color-status-danger-content); + color: var(--openbitfun-color-status-danger-emphasis); } &--warning { - color: var(--openbitfun-color-status-warning-content); + color: var(--openbitfun-color-status-warning-emphasis); } + &--info, &--active { - color: var(--openbitfun-color-accent-default); + color: var(--openbitfun-color-status-info-emphasis); } &--cancelled { @@ -226,16 +227,16 @@ inline-size: 100%; block-size: 100%; border-radius: inherit; - background: var(--openbitfun-color-accent-default); + background: var(--openbitfun-color-status-info-emphasis); transform-origin: left center; transition: transform var(--openbitfun-motion-duration-base) var(--openbitfun-motion-easing-standard); &.is-completed { - background: var(--openbitfun-color-status-success-content); + background: var(--openbitfun-color-status-success-emphasis); } &.is-failed { - background: var(--openbitfun-color-status-danger-content); + background: var(--openbitfun-color-status-danger-emphasis); } &.is-cancelled { diff --git a/src/web-ui/src/shared/notification-system/components/NotificationItem.scss b/src/web-ui/src/shared/notification-system/components/NotificationItem.scss index b3424cf96f..e0de16839e 100644 --- a/src/web-ui/src/shared/notification-system/components/NotificationItem.scss +++ b/src/web-ui/src/shared/notification-system/components/NotificationItem.scss @@ -18,25 +18,25 @@ &--success { .notification-item__icon { - color: var(--openbitfun-color-status-success-content); + color: var(--openbitfun-color-status-success-emphasis); } } &--error { .notification-item__icon { - color: var(--openbitfun-color-status-danger-content); + color: var(--openbitfun-color-status-danger-emphasis); } } &--warning { .notification-item__icon { - color: var(--openbitfun-color-status-warning-content); + color: var(--openbitfun-color-status-warning-emphasis); } } &--info { .notification-item__icon { - color: var(--openbitfun-color-status-info-content); + color: var(--openbitfun-color-status-info-emphasis); } } diff --git a/src/web-ui/src/shared/notification-system/components/ProgressNotification.scss b/src/web-ui/src/shared/notification-system/components/ProgressNotification.scss index 2018e70de9..951e67b886 100644 --- a/src/web-ui/src/shared/notification-system/components/ProgressNotification.scss +++ b/src/web-ui/src/shared/notification-system/components/ProgressNotification.scss @@ -17,14 +17,14 @@ .progress-notification__icon { background: var(--openbitfun-color-status-success-surface); - color: var(--openbitfun-color-status-success-content); + color: var(--openbitfun-color-status-success-emphasis); } } &--failed { .progress-notification__icon { background: var(--openbitfun-color-status-danger-surface); - color: var(--openbitfun-color-status-danger-content); + color: var(--openbitfun-color-status-danger-emphasis); } } @@ -41,8 +41,8 @@ align-items: center; justify-content: center; border-radius: 50%; - background: color-mix(in srgb, var(--openbitfun-color-status-warning-content) 18%, transparent); - color: var(--openbitfun-color-status-warning-content); + background: var(--openbitfun-color-status-info-surface); + color: var(--openbitfun-color-status-info-emphasis); } &__spinner { @@ -61,12 +61,12 @@ &--success { background: var(--openbitfun-color-status-success-surface); - color: var(--openbitfun-color-status-success-content); + color: var(--openbitfun-color-status-success-emphasis); } &--error { background: var(--openbitfun-color-status-danger-surface); - color: var(--openbitfun-color-status-danger-content); + color: var(--openbitfun-color-status-danger-emphasis); } } @@ -96,7 +96,7 @@ &__percentage { font-size: var(--openbitfun-type-label-sm-font-size); font-weight: var(--openbitfun-type-label-selected-font-weight); - color: var(--openbitfun-color-status-warning-content); + color: var(--openbitfun-color-status-info-content); font-variant-numeric: tabular-nums; font-family: var(--openbitfun-type-code-md-font-family); } @@ -120,7 +120,7 @@ &__progress-fill { width: 100%; height: 100%; - background: linear-gradient(90deg, var(--openbitfun-color-accent-hover), var(--openbitfun-color-accent-secondary)); + background: var(--openbitfun-color-status-info-emphasis); border-radius: 2px; transform-origin: left center; transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1); @@ -128,12 +128,12 @@ &--completed &__progress-fill { - background: var(--openbitfun-color-status-success-content); + background: var(--openbitfun-color-status-success-emphasis); } &--failed &__progress-fill { - background: var(--openbitfun-color-status-danger-content); + background: var(--openbitfun-color-status-danger-emphasis); } From 46ae91e91b9a4520d8a448e80aac824e3f262e86 Mon Sep 17 00:00:00 2001 From: GCWing Date: Mon, 7 Sep 2026 12:18:40 +0800 Subject: [PATCH 3/3] test(web): refresh widget appearance payload contract --- .../src/tools/generative-widget/appearancePayload.test.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/web-ui/src/tools/generative-widget/appearancePayload.test.ts b/src/web-ui/src/tools/generative-widget/appearancePayload.test.ts index b1fa3f709f..1764880251 100644 --- a/src/web-ui/src/tools/generative-widget/appearancePayload.test.ts +++ b/src/web-ui/src/tools/generative-widget/appearancePayload.test.ts @@ -16,7 +16,7 @@ import { } from './appearancePayload'; const CANONICAL_THEME_VARIABLE_NAMES = Object.values(themeCssVariables); -const CANONICAL_THEME_VARIABLE_NAMES_HASH = '0c1109009e2a88adbade099e551aacecc2d18a4f6dbcf8436f0de80999c90d5d'; +const CANONICAL_THEME_VARIABLE_NAMES_HASH = 'e80ebcdf9452a0b5f8ab26d9b41cb81c4e74d75451e4402f99afc68af3c13f42'; const RETIRED_WIDGET_VARIABLE_NAMES = [ '--background-primary', '--bg-primary', @@ -65,7 +65,7 @@ describe('generated widget appearance payload contract', () => { first: WIDGET_APPEARANCE_VAR_NAMES[0], last: WIDGET_APPEARANCE_VAR_NAMES[WIDGET_APPEARANCE_VAR_NAMES.length - 1], }).toEqual({ - count: 124, + count: 127, hash: CANONICAL_THEME_VARIABLE_NAMES_HASH, first: '--openbitfun-color-accent-border', last: '--openbitfun-shadow-xs', @@ -91,6 +91,10 @@ describe('generated widget appearance payload contract', () => { '--openbitfun-color-action-primary-pressed', '--openbitfun-color-code-change-added', '--openbitfun-color-code-change-removed', + '--openbitfun-color-status-info-emphasis', + '--openbitfun-color-status-success-emphasis', + '--openbitfun-color-status-warning-emphasis', + '--openbitfun-color-status-danger-emphasis', '--openbitfun-color-status-success-content', '--openbitfun-color-status-success-surface', '--openbitfun-color-status-success-border',