diff --git a/packages/dashboard/app/__tests__/dashboard-component-color-tokenization.test.ts b/packages/dashboard/app/__tests__/dashboard-component-color-tokenization.test.ts index 5ba455e274..93c921ff2c 100644 --- a/packages/dashboard/app/__tests__/dashboard-component-color-tokenization.test.ts +++ b/packages/dashboard/app/__tests__/dashboard-component-color-tokenization.test.ts @@ -1,26 +1,41 @@ import { describe, expect, it } from "vitest"; -import { readFileSync } from "node:fs"; +import { existsSync, readFileSync } from "node:fs"; import { resolve } from "node:path"; const root = resolve(__dirname, "../components"); const auditedCompliant = ["ChatView.css", "MobileNavBar.css", "ListView.css", "WorkflowResultsTab.css"]; const cleanedFiles = [ - "ScriptsModal.css", - "InlineCreateCard.css", - "FileMentionPopup.css", - "BackgroundTasksIndicator.css", - "CliBinaryPanel.css", - "CliBinaryInstallBanner.css", - "GitHubImportModal.css", - "WorkspaceSelector.css", "AgentReflectionsTab.css", + "BackgroundTasksIndicator.css", + "CliBinaryInstallBanner.css", + "CliBinaryPanel.css", + "FileMentionPopup.css", + "GitHubImportModal.css", + "InlineCreateCard.css", + "LanguageSelector.css", + "PullRequestView.css", + "ScriptsModal.css", + "SettingsFieldRow.css", "SettingsSyncLog.css", + "WorkflowFieldsPanel.css", + "WorkflowNodeEditor.css", + "WorkflowSettingsPanel.css", + "WorkspaceSelector.css", ]; const bareHexCleanedFiles = ["ScriptsModal.css", "SettingsSyncLog.css"]; const hexLiteralPattern = /#[0-9a-fA-F]{3,8}\b/; +function resolveComponentCss(file: string): string { + const directPath = resolve(root, file); + if (existsSync(directPath)) { + return directPath; + } + + return resolve(root, "settings", file); +} + function stripVarCalls(line: string): string { return line.replace(/var\([^)]*\)/g, ""); } @@ -35,7 +50,7 @@ describe("dashboard component color tokenization", () => { it("keeps cleaned files free of raw rgba()", () => { for (const file of cleanedFiles) { - const source = readFileSync(resolve(root, file), "utf8"); + const source = readFileSync(resolveComponentCss(file), "utf8"); expect(source).not.toMatch(/rgba\(/); } }); diff --git a/packages/dashboard/app/components/LanguageSelector.css b/packages/dashboard/app/components/LanguageSelector.css index 3f3cab26c0..c6d8a8a92c 100644 --- a/packages/dashboard/app/components/LanguageSelector.css +++ b/packages/dashboard/app/components/LanguageSelector.css @@ -37,6 +37,6 @@ .language-option.active { border-color: var(--accent-color, #4a9eff); - background: var(--accent-color-subtle, rgba(74, 158, 255, 0.12)); + background: var(--accent-color-subtle, color-mix(in srgb, #4a9eff 12%, transparent)); font-weight: 600; } diff --git a/packages/dashboard/app/components/PullRequestView.css b/packages/dashboard/app/components/PullRequestView.css index 21663b289d..5df7ae3c5d 100644 --- a/packages/dashboard/app/components/PullRequestView.css +++ b/packages/dashboard/app/components/PullRequestView.css @@ -57,17 +57,17 @@ letter-spacing: 0.04em; padding: 2px 6px; border-radius: 4px; - background: var(--surface-2, rgba(127, 127, 127, 0.15)); + background: var(--surface-2, color-mix(in srgb, #7f7f7f 15%, transparent)); color: var(--text-muted); } .pr-identity-state--failed { - background: var(--pr-failed-bg, rgba(229, 83, 75, 0.18)); + background: var(--pr-failed-bg, color-mix(in srgb, #e5534b 18%, transparent)); color: var(--danger, #e5534b); } .pr-identity-state--merged { - background: var(--pr-merged-bg, rgba(130, 80, 223, 0.18)); + background: var(--pr-merged-bg, color-mix(in srgb, #8250df 18%, transparent)); } /* placeholders / banners / notices */ @@ -80,19 +80,19 @@ gap: var(--space-xs); padding: var(--space-sm) var(--space-md); border-radius: 6px; - background: var(--surface-2, rgba(127, 127, 127, 0.1)); + background: var(--surface-2, color-mix(in srgb, #7f7f7f 10%, transparent)); } .pr-banner--responding { - background: var(--pr-responding-bg, rgba(54, 130, 220, 0.14)); + background: var(--pr-responding-bg, color-mix(in srgb, #3682dc 14%, transparent)); } .pr-notice--unverified { - background: var(--pr-unverified-bg, rgba(220, 170, 54, 0.14)); + background: var(--pr-unverified-bg, color-mix(in srgb, #dcaa36 14%, transparent)); } .pr-error-reason { - background: var(--pr-error-bg, rgba(229, 83, 75, 0.14)); + background: var(--pr-error-bg, color-mix(in srgb, #e5534b 14%, transparent)); color: var(--danger, #e5534b); } @@ -133,7 +133,7 @@ } .pr-action--close { - border-color: var(--pr-close-border, rgba(229, 83, 75, 0.4)); + border-color: var(--pr-close-border, color-mix(in srgb, #e5534b 40%, transparent)); } .pr-automerge-toggle { @@ -148,7 +148,7 @@ .pr-automerge-gate { padding: 1px 6px; border-radius: 4px; - background: var(--surface-2, rgba(127, 127, 127, 0.15)); + background: var(--surface-2, color-mix(in srgb, #7f7f7f 15%, transparent)); } .pr-conflict-link { @@ -210,7 +210,7 @@ .pr-thread--agent-disagreement { border-left: 3px solid var(--warning, #d29922); - background: var(--pr-disagreement-bg, rgba(210, 153, 34, 0.08)); + background: var(--pr-disagreement-bg, color-mix(in srgb, #d29922 8%, transparent)); } .pr-thread--pending { diff --git a/packages/dashboard/app/components/WorkflowFieldsPanel.css b/packages/dashboard/app/components/WorkflowFieldsPanel.css index 38116b2fc9..9c130973d9 100644 --- a/packages/dashboard/app/components/WorkflowFieldsPanel.css +++ b/packages/dashboard/app/components/WorkflowFieldsPanel.css @@ -70,7 +70,7 @@ font-family: var(--font-mono, monospace); font-size: 0.7rem; color: var(--text-tertiary); - background: var(--surface-2, rgba(255, 255, 255, 0.04)); + background: var(--surface-2, color-mix(in srgb, #ffffff 4%, transparent)); padding: 1px 6px; border-radius: var(--radius-sm); } diff --git a/packages/dashboard/app/components/WorkflowNodeEditor.css b/packages/dashboard/app/components/WorkflowNodeEditor.css index 541a3ac2d4..133f5b381e 100644 --- a/packages/dashboard/app/components/WorkflowNodeEditor.css +++ b/packages/dashboard/app/components/WorkflowNodeEditor.css @@ -42,7 +42,7 @@ justify-content: space-between; gap: var(--space-sm); padding: var(--space-sm) var(--space-md); - background: var(--accent-subtle, rgba(59, 130, 246, 0.12)); + background: var(--accent-subtle, color-mix(in srgb, #3b82f6 12%, transparent)); border-bottom: 1px solid var(--border); color: var(--text); font-size: 0.85rem; @@ -484,7 +484,7 @@ .wf-templates-badge { padding: 0 var(--space-xs); - background: var(--accent-subtle, rgba(59, 130, 246, 0.12)); + background: var(--accent-subtle, color-mix(in srgb, #3b82f6 12%, transparent)); border-radius: var(--radius-sm); color: var(--text-muted); font-size: 0.7rem; diff --git a/packages/dashboard/app/components/WorkflowSettingsPanel.css b/packages/dashboard/app/components/WorkflowSettingsPanel.css index 04b6c20c00..13663ecfa9 100644 --- a/packages/dashboard/app/components/WorkflowSettingsPanel.css +++ b/packages/dashboard/app/components/WorkflowSettingsPanel.css @@ -139,7 +139,7 @@ font-family: var(--font-mono, monospace); font-size: 0.7rem; color: var(--text-muted); - background: var(--surface-2, rgba(255, 255, 255, 0.04)); + background: var(--surface-2, color-mix(in srgb, #ffffff 4%, transparent)); padding: 1px 6px; border-radius: var(--radius-sm); } diff --git a/packages/dashboard/app/components/settings/SettingsFieldRow.css b/packages/dashboard/app/components/settings/SettingsFieldRow.css index 4ace13c67c..dc549481af 100644 --- a/packages/dashboard/app/components/settings/SettingsFieldRow.css +++ b/packages/dashboard/app/components/settings/SettingsFieldRow.css @@ -33,7 +33,7 @@ text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-muted); - background: var(--surface-muted, rgba(255, 255, 255, 0.04)); + background: var(--surface-muted, color-mix(in srgb, #ffffff 4%, transparent)); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 1px 6px;