feat: design token system — DS_TEXT/DS_SURFACE/DS_BORDER + 237 hex migrations
Token infrastructure (src/lib/ds.ts): - DS_TEXT: 16 semantic text color tokens (primary/secondary/muted/success/ warning/error/info/brand/signal + dark variants successDark/warningDark/ signalDark/infoDark for text on tinted surfaces) - DS_BG: page/surface/subtle/muted background tokens - DS_BORDER: default/muted/strong border tokens - DS_SURFACE: 10 bg+border surface pairs (success/warning/error/info/indigo/ purple/orange/blue/neutral/slate) - DS_MATCH_TIER: score-tier surface aliases keyed by strong/moderate/weak - DS_PRE_MARKET / DS_MARKET_SIGNAL: named aliases for futureCard tokens - DS_SHADOW: card/panel/dialog elevation tokens - BADGE_COLORS: 14 semantic presets for GenericBadge (confidenceHigh, riskMedium, preMarket, marketSignal, verified, gold, silver, bronze…) GenericBadge (src/components/shared/GenericBadge.tsx): - New semanticVariant prop (keyof BADGE_COLORS) — preferred over raw hex - color prop becomes optional (fallback), type-documented as escape hatch Priority file migrations — 237 hex literals replaced across 10 files: ScoreBreakdownPanel.tsx −22 PipelineDetailPanel.tsx −22 FutureAvailabilityCard.tsx −26 AICompareSummary.tsx −27 LocationIntelligencePanel −39 AssistantPromptSuggestions −18 UnitStructurePanel.tsx −25 BerichtDialog.tsx −24 PreMarketPanel.tsx −24 PropertyActivityLogPanel −10 ESLint (eslint.config.js): - Updated rule message to reference new tokens (DS_TEXT, DS_SURFACE, etc.) - Added 'stroke' to monitored property names - Remains 'warn' for gradual migration; use check:tokens for CI gate CI script (scripts/check-tokens.js + npm run check:tokens): - Counts hex patterns in components/ + pages/ - Fails if count > THRESHOLD (ratchet: 1958 baseline, lower per sprint) - Reports top 15 offenders for prioritizing next migration batch Results: ESLint targeted sx-prop violations: 1752 → 1030 (−41%) 0 TypeScript errors, 154 tests green Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+101
@@ -67,6 +67,107 @@ export const DS_COLORS = {
|
||||
},
|
||||
} as const
|
||||
|
||||
// ── Text color tokens ─────────────────────────────────────────────────────────
|
||||
// For sx={{ color: DS_TEXT.secondary }} instead of hardcoded '#475569'
|
||||
|
||||
export const DS_TEXT = {
|
||||
primary: '#1e293b',
|
||||
secondary: '#475569',
|
||||
muted: '#64748b',
|
||||
disabled: '#94a3b8',
|
||||
inverted: '#ffffff',
|
||||
success: '#1a7a4a',
|
||||
warning: '#d97706',
|
||||
error: '#c0392b',
|
||||
danger: '#dc2626',
|
||||
info: '#0369a1',
|
||||
brand: '#1e3a5f',
|
||||
signal: '#6d28d9',
|
||||
// Dark variants — use for text on light-tinted surface boxes
|
||||
successDark: '#166534',
|
||||
warningDark: '#92400e',
|
||||
signalDark: '#4c1d95',
|
||||
infoDark: '#0c4a6e',
|
||||
} as const
|
||||
|
||||
// ── Background tokens ─────────────────────────────────────────────────────────
|
||||
|
||||
export const DS_BG = {
|
||||
page: '#f8fafc',
|
||||
surface: '#ffffff',
|
||||
subtle: '#f1f5f9',
|
||||
muted: '#e2e8f0',
|
||||
} as const
|
||||
|
||||
// ── Border tokens ─────────────────────────────────────────────────────────────
|
||||
|
||||
export const DS_BORDER = {
|
||||
default: '#e2e8f0',
|
||||
muted: '#f1f5f9',
|
||||
strong: '#cbd5e1',
|
||||
} as const
|
||||
|
||||
// ── Surface tokens — bg + border pairs for highlighted/tinted boxes ───────────
|
||||
// Use as: sx={{ bgcolor: DS_SURFACE.success.bg, border: `1px solid ${DS_SURFACE.success.border}` }}
|
||||
|
||||
export const DS_SURFACE = {
|
||||
success: { bg: '#f0fdf4', border: '#bbf7d0' }, // green tint
|
||||
warning: { bg: '#fffbeb', border: '#fde68a' }, // amber tint
|
||||
error: { bg: '#fef2f2', border: '#fecaca' }, // red tint
|
||||
info: { bg: '#f0f9ff', border: '#bae6fd' }, // sky tint
|
||||
indigo: { bg: '#eef2ff', border: '#e0e7ff' }, // indigo tint (hard-criteria rows)
|
||||
purple: { bg: '#faf5ff', border: '#e9d5ff' }, // purple tint (pre-market / future)
|
||||
orange: { bg: '#fff7ed', border: '#fed7aa' }, // orange tint (HOT heat badge bg)
|
||||
blue: { bg: '#eff6ff', border: '#bfdbfe' }, // blue tint (market signal)
|
||||
neutral: { bg: '#f8fafc', border: '#e2e8f0' }, // neutral/slate tint (formula rows)
|
||||
slate: { bg: '#f1f5f9', border: '#e2e8f0' }, // slightly darker neutral
|
||||
} as const
|
||||
|
||||
// ── Match tier surface — bg tint keyed by score tier ─────────────────────────
|
||||
// Use with SCORE_STRONG / SCORE_MODERATE thresholds from constants.ts
|
||||
|
||||
export const DS_MATCH_TIER = {
|
||||
strong: DS_SURFACE.success,
|
||||
moderate: DS_SURFACE.warning,
|
||||
weak: DS_SURFACE.error,
|
||||
} as const
|
||||
|
||||
// ── Pre-market & market signal shorthand aliases ──────────────────────────────
|
||||
// DS_COLORS.futureCard.controlled / signal are the full token sets.
|
||||
// These aliases make imports more readable in supply-side components.
|
||||
|
||||
export const DS_PRE_MARKET = DS_COLORS.futureCard.controlled
|
||||
export const DS_MARKET_SIGNAL = DS_COLORS.futureCard.signal
|
||||
|
||||
// ── Badge color presets ───────────────────────────────────────────────────────
|
||||
// Pass to GenericBadge.color instead of raw hex strings.
|
||||
// BADGE_COLORS.confidenceHigh replaces '#1a7a4a' at call sites.
|
||||
|
||||
export const BADGE_COLORS = {
|
||||
confidenceHigh: '#1a7a4a',
|
||||
confidenceMedium: '#d97706',
|
||||
confidenceLow: '#c0392b',
|
||||
riskHigh: '#c0392b',
|
||||
riskMedium: '#d97706',
|
||||
riskLow: '#1a7a4a',
|
||||
preMarket: '#7c3aed',
|
||||
marketSignal: '#1d4ed8',
|
||||
verified: '#1e3a5f',
|
||||
info: '#0369a1',
|
||||
muted: '#64748b',
|
||||
gold: '#d97706',
|
||||
silver: '#64748b',
|
||||
bronze: '#b45309',
|
||||
} as const
|
||||
|
||||
// ── Shadow tokens ─────────────────────────────────────────────────────────────
|
||||
|
||||
export const DS_SHADOW = {
|
||||
card: '0 1px 3px 0 rgba(0,0,0,0.08), 0 1px 2px -1px rgba(0,0,0,0.04)',
|
||||
panel: '0 4px 6px -1px rgba(0,0,0,0.08), 0 2px 4px -2px rgba(0,0,0,0.04)',
|
||||
dialog: '0 20px 25px -5px rgba(0,0,0,0.10), 0 8px 10px -6px rgba(0,0,0,0.06)',
|
||||
} as const
|
||||
|
||||
// ── Inquiry status metadata ───────────────────────────────────────────────────
|
||||
|
||||
export const INQUIRY_STATUS_META: Record<string, { label: string; fg: string; bg: string }> = {
|
||||
|
||||
Reference in New Issue
Block a user