diff --git a/packages/dashboard/app/__tests__/component-css-no-raw-rgba.test.ts b/packages/dashboard/app/__tests__/component-css-no-raw-rgba.test.ts new file mode 100644 index 000000000..b3e806056 --- /dev/null +++ b/packages/dashboard/app/__tests__/component-css-no-raw-rgba.test.ts @@ -0,0 +1,34 @@ +import { readdirSync, readFileSync } from "node:fs"; +import { join, resolve } from "node:path"; +import { describe, expect, it } from "vitest"; + +const componentsDir = resolve(__dirname, "..", "components"); + +function stripVarFallbackRgba(content: string): string { + return content.replace(/var\([^()]*,\s*rgba?\([^)]*\)\s*\)/g, ""); +} + +describe("component CSS color token hygiene", () => { + it("contains no raw rgb/rgba calls outside var() fallbacks", () => { + const cssFiles = readdirSync(componentsDir) + .filter((name) => name.endsWith(".css")) + .sort(); + + const violations: string[] = []; + + for (const fileName of cssFiles) { + const filePath = join(componentsDir, fileName); + const source = readFileSync(filePath, "utf8"); + const withoutFallbacks = stripVarFallbackRgba(source); + const lines = withoutFallbacks.split(/\r?\n/); + + for (let index = 0; index < lines.length; index += 1) { + if (/rgba?\(/.test(lines[index])) { + violations.push(`${fileName}:${index + 1}:${lines[index].trim()}`); + } + } + } + + expect(violations).toEqual([]); + }); +}); diff --git a/packages/dashboard/app/components/DesktopLaunchGate.css b/packages/dashboard/app/components/DesktopLaunchGate.css index 3e3d03505..b901e3816 100644 --- a/packages/dashboard/app/components/DesktopLaunchGate.css +++ b/packages/dashboard/app/components/DesktopLaunchGate.css @@ -18,7 +18,7 @@ border: 1px solid var(--border-subtle, #2a2f3a); border-radius: 12px; padding: 2rem 1.75rem; - box-shadow: 0 10px 30px rgba(0, 0, 0, 0.35); + box-shadow: var(--shadow-lg); } .desktop-launch-gate__panel h1,