Files
vyndr/web/src/lib/vyndrTokens.js
T
builtbykev a74b5dd1ed 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>
2026-06-15 22:58:57 -04:00

54 lines
1.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* ============================================================
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 80120px (§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,
};