Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions frontend/src/v2/__tests__/V2FeaturePageColors.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import fs from 'fs';
import path from 'path';
import { V2_COLORS } from '../components/V2FeaturePage';

// TASK-681: V2FeaturePage's MUI theme cannot read var(), so its colours stay
// literal. This pins each literal to the light --v2-* token of the same role, so
// a token change fails here instead of drifting silently. Dark mode needs its own
// decision (UX Lead, TASK-681 ruling).
const css = fs.readFileSync(path.join(__dirname, '../v2.css'), 'utf8');

const TOKEN_FOR: Record<keyof typeof V2_COLORS, string> = {
bg: 'bg-subtle',
surface: 'surface',
surfaceHover: 'surface-hover',
border: 'border',
borderSoft: 'border-soft',
borderStrong: 'border-strong',
textPrimary: 'text-primary',
textSecondary: 'text-secondary',
textMuted: 'text-muted',
accent: 'accent',
accentStrong: 'accent-strong',
accentSoft: 'accent-soft',
success: 'success',
warning: 'warning',
danger: 'danger',
info: 'info',
shadowSm: '',
shadow: '',
shadowLg: '',
};

// First declaration wins: the light block sits above any future dark scope.
const lightTokenValue = (name: string): string | null => {
const m = new RegExp(`--v2-${name}:\\s*(#[0-9a-fA-F]{6})\\s*;`).exec(css);
return m ? m[1].toLowerCase() : null;
};

describe('V2FeaturePage MUI palette matches the light --v2-* tokens', () => {
const colourKeys = (Object.keys(TOKEN_FOR) as Array<keyof typeof V2_COLORS>)
.filter((k) => TOKEN_FOR[k] !== '');

test.each(colourKeys)('%s equals its light token', (key) => {
expect(lightTokenValue(TOKEN_FOR[key])).not.toBeNull();
expect(V2_COLORS[key].toLowerCase()).toBe(lightTokenValue(TOKEN_FOR[key]));
});
});
20 changes: 11 additions & 9 deletions frontend/src/v2/components/V2FeaturePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,18 @@ const withV2Prefix = (path: string): string => {
return path.startsWith('/') ? `/v2${path}` : `/v2/${path}`;
};

const V2_COLORS = {
bg: '#f8f8fb',
// MUI's createTheme cannot read var(), so these stay literal. Each value is the
// light --v2-* token of the same role; V2FeaturePageColors.test pins them to v2.css.
export const V2_COLORS = {
bg: '#f9fafb',
surface: '#ffffff',
surfaceHover: '#f1f2f5',
border: '#e5e7eb',
borderSoft: '#eef0f6',
borderStrong: '#d7dce7',
textPrimary: '#111827',
textSecondary: '#4b5563',
textMuted: '#6b7280',
surfaceHover: '#f2f4f7',
border: '#d0d5dd',
borderSoft: '#e4e7ec',
borderStrong: '#98a2b3',
textPrimary: '#101828',
textSecondary: '#475467',
textMuted: '#667085',
accent: '#1d3fd1',
accentStrong: '#1633a8',
accentSoft: '#e9edfb',
Expand Down
Loading