Session 33: Design system Phase A+B — tokens, fonts, glitch CSS, shared components (1792 tests)
VYNDR 2.0 design-system conversion, foundation only (pages/mobile/systems are Sessions 34+). Frontend-only; zero backend changes. Phase A: §2 token set + token-wired typography + Inter/JetBrains Mono fonts + §4 glitch keyframes (ported verbatim from the prototype's vyndr.css) + scanline texture + §10 a11y data-* layer in globals.css. Legacy alias block kept. Phase B: web/src/lib/vyndrTokens.js (CommonJS helpers) + 9 shared components under web/src/components/vyndr/ (Wordmark, GradeBadge, SportBadge, TerminalInput, SectionHead, VBtn, Card, Sparkline, Ticker). 74 new design-system tests. Backend 1718 -> 1792, 141 suites, zero regressions. Web build clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
/* ============================================================
|
||||
VYNDR 2.0 — design-system token helpers (§5).
|
||||
Plain CommonJS so the .tsx components import it AND the Jest
|
||||
suite can require it directly (no TS/Babel transform needed).
|
||||
Every value resolves to a CSS custom property from globals.css.
|
||||
============================================================ */
|
||||
|
||||
/* Grade → CSS variable (the product's core color language). */
|
||||
const GRADE_COLORS = {
|
||||
'A+': 'var(--g-ap)', A: 'var(--g-a)', 'A-': 'var(--g-a)',
|
||||
'B+': 'var(--g-b)', B: 'var(--g-b)', 'B-': 'var(--g-b)',
|
||||
C: 'var(--g-c)', D: 'var(--g-d)',
|
||||
};
|
||||
|
||||
/* Grade → raw hex (for SVG fills / contexts where a var won't resolve). */
|
||||
const GRADE_HEX = {
|
||||
'A+': '#00ffb8', A: '#00d4a0', 'A-': '#00d4a0',
|
||||
'B+': '#4a9eff', B: '#4a9eff', 'B-': '#4a9eff',
|
||||
C: '#ffb347', D: '#ff5252',
|
||||
};
|
||||
|
||||
/* Sport config map. */
|
||||
const SPORT = {
|
||||
nba: { label: 'NBA', color: 'var(--s-nba)', hex: '#e94b3c' },
|
||||
mlb: { label: 'MLB', color: 'var(--s-mlb)', hex: '#1e90ff' },
|
||||
wnba: { label: 'WNBA', color: 'var(--s-wnba)', hex: '#f7944a' },
|
||||
soccer: { label: 'SOC', color: 'var(--s-soccer)', hex: '#3ddc84' },
|
||||
};
|
||||
|
||||
/* GradeBadge size variants — hero stays 80–120px (§5: grade letter is
|
||||
always the largest, first-read element on a card). Numbers pass through. */
|
||||
const GRADE_BADGE_SIZES = { sm: 16, md: 30, lg: 48, hero: 100 };
|
||||
|
||||
function gradeColor(g) {
|
||||
return GRADE_COLORS[g] || 'var(--text-0)';
|
||||
}
|
||||
function gradeHex(g) {
|
||||
return GRADE_HEX[g] || '#e8e8f0';
|
||||
}
|
||||
function gradeBadgeSize(size) {
|
||||
if (typeof size === 'number') return size;
|
||||
return GRADE_BADGE_SIZES[size] || GRADE_BADGE_SIZES.md;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
GRADE_COLORS,
|
||||
GRADE_HEX,
|
||||
SPORT,
|
||||
GRADE_BADGE_SIZES,
|
||||
gradeColor,
|
||||
gradeHex,
|
||||
gradeBadgeSize,
|
||||
};
|
||||
Reference in New Issue
Block a user