FN-8269: replace raw white component colors with tokens

Replace component-level white literals with semantic dashboard tokens and protect the pattern with a hygiene regression scan.

- Add semantic tokens for workflow chip foregrounds and HTML preview canvases
- Apply the tokens to workflow and artifact gallery component CSS
- Extend CSS hygiene coverage and add a patch changeset

Files changed:
 .changeset/fn-8269-fff-tokens.md                     |  7 +++++++
 .../dashboard/app/__tests__/css-hygiene-scan.test.ts | 20 +++++++++++++++++++-
 .../dashboard/app/components/ArtifactsGallery.css    |  4 ++--
 .../app/components/WorkflowAddStepModal.css          |  3 ++-
 .../app/components/WorkflowSimpleCanvas.css          |  3 ++-
 packages/dashboard/app/styles.css                    | 13 +++++++++++++
 6 files changed, 45 insertions(+), 5 deletions(-)

Fusion-Task-Id: FN-8269

Fusion-Task-Lineage: 5128286d-cdcf-4c9b-b097-e7eaed7d1713

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
This commit is contained in:
gsxdsm
2026-07-18 04:44:53 -07:00
parent e436635abd
commit b3904f6405
6 changed files with 45 additions and 5 deletions

View File

@@ -0,0 +1,7 @@
---
"@runfusion/fusion": patch
---
summary: Keep workflow chips and HTML mockup previews visually consistent across themes.
category: fix
dev: Replace component-level raw white values with explicit workflow-chip and preview-page semantic tokens, protected by the dashboard CSS hygiene scan.

View File

@@ -3,6 +3,7 @@ import { readFileSync } from "node:fs";
import { join, resolve } from "node:path"; import { join, resolve } from "node:path";
const componentsDir = resolve(__dirname, "../components"); const componentsDir = resolve(__dirname, "../components");
const stylesPath = resolve(__dirname, "../styles.css");
const recentlyLandedResponsiveFiles = [ const recentlyLandedResponsiveFiles = [
"PluginManager.css", "PluginManager.css",
@@ -20,10 +21,20 @@ const recentlyLandedHygieneFiles = [
"TaskFieldsSection.css", "TaskFieldsSection.css",
]; ];
const tokenizedWhiteFiles = [
"ArtifactsGallery.css",
"WorkflowSimpleCanvas.css",
"WorkflowAddStepModal.css",
];
function readComponentCss(name: string): string { function readComponentCss(name: string): string {
return readFileSync(join(componentsDir, name), "utf-8"); return readFileSync(join(componentsDir, name), "utf-8");
} }
function readStylesCss(): string {
return readFileSync(stylesPath, "utf-8");
}
function linesWith(source: string, predicate: (line: string) => boolean): string[] { function linesWith(source: string, predicate: (line: string) => boolean): string[] {
return source return source
.split("\n") .split("\n")
@@ -90,9 +101,16 @@ describe("component CSS hygiene scan regressions", () => {
expect(findings).toEqual([]); expect(findings).toEqual([]);
}); });
it("defines semantic tokens for always-white workflow chips and preview canvases", () => {
const styles = readStylesCss();
expect(styles).toContain("--workflow-chip-foreground: #ffffff;");
expect(styles).toContain("--preview-page-bg: #ffffff;");
});
it("does not use hardcoded hex colors outside token fallback patterns in scanned recent CSS", () => { it("does not use hardcoded hex colors outside token fallback patterns in scanned recent CSS", () => {
const hexPattern = /#[0-9a-fA-F]{3,8}\b/; const hexPattern = /#[0-9a-fA-F]{3,8}\b/;
const findings = recentlyLandedHygieneFiles.flatMap((file) => const findings = [...recentlyLandedHygieneFiles, ...tokenizedWhiteFiles].flatMap((file) =>
linesWith( linesWith(
readComponentCss(file), readComponentCss(file),
(line) => hexPattern.test(line) && !line.includes("var(--") (line) => hexPattern.test(line) && !line.includes("var(--")

View File

@@ -429,14 +429,14 @@ The artifacts viewer is a headerless FloatingWindow, so this header is the deleg
background: var(--surface); background: var(--surface);
} }
/* HTML mockup live preview; white canvas because agent mockups usually assume a page background. */ /* FNXC:DashboardPreviewCanvas 2026-07-18-04:07: HTML mockup previews retain a white canvas across themes because agent mockups assume a light page background. */
.artifacts-gallery-viewer-html { .artifacts-gallery-viewer-html {
width: 100%; width: 100%;
height: 100%; height: 100%;
min-height: 20rem; min-height: 20rem;
border: thin solid var(--border); border: thin solid var(--border);
border-radius: var(--radius-lg); border-radius: var(--radius-lg);
background: #fff; background: var(--preview-page-bg);
} }
.artifacts-gallery-viewer-doc { .artifacts-gallery-viewer-doc {

View File

@@ -137,7 +137,8 @@ the same dialog serves both breakpoints.
width: 30px; width: 30px;
height: 30px; height: 30px;
border-radius: var(--radius-md); border-radius: var(--radius-md);
color: #fff; /* FNXC:DashboardTokenHygiene 2026-07-18-04:07: Colored workflow-status chips require an always-white foreground, not theme-variant --accent-text. */
color: var(--workflow-chip-foreground);
background: var(--surface-emphasis); background: var(--surface-emphasis);
} }

View File

@@ -69,7 +69,8 @@ Simplified workflow view styling. Requirements encoded here:
width: 32px; width: 32px;
height: 32px; height: 32px;
border-radius: var(--radius-md); border-radius: var(--radius-md);
color: #fff; /* FNXC:DashboardTokenHygiene 2026-07-18-04:07: Colored workflow-status chips require an always-white foreground, not theme-variant --accent-text. */
color: var(--workflow-chip-foreground);
} }
/* Node family accents (icon chip background + a subtle left accent). */ /* Node family accents (icon chip background + a subtle left accent). */

View File

@@ -497,6 +497,19 @@ svg.spinning {
/* Foreground for content rendered on `--accent` (e.g., user chat bubble, primary FAB icon). Choose a value with WCAG AA contrast against the paired `--accent` in the same block. */ /* Foreground for content rendered on `--accent` (e.g., user chat bubble, primary FAB icon). Choose a value with WCAG AA contrast against the paired `--accent` in the same block. */
--accent-text: #ffffff; --accent-text: #ffffff;
/*
* FNXC:DashboardTokenHygiene 2026-07-18-04:07:
* Workflow-status step chips use --ws-*, --color-merged, and --triage backgrounds.
* Their foreground must remain white across themes, unlike --accent-text, which only pairs with --accent and may be theme-variant.
*/
--workflow-chip-foreground: #ffffff;
/*
* FNXC:DashboardPreviewCanvas 2026-07-18-04:07:
* Agent HTML mockups assume a light page background, so this canvas stays white in every theme.
*/
--preview-page-bg: #ffffff;
/* === Log Entry Background Tokens === */ /* === Log Entry Background Tokens === */
--log-tool-bg: color-mix(in srgb, var(--accent) 8%, transparent); --log-tool-bg: color-mix(in srgb, var(--accent) 8%, transparent);
--log-success-bg: color-mix(in srgb, var(--color-success) 6%, transparent); --log-success-bg: color-mix(in srgb, var(--color-success) 6%, transparent);