DS3 (design): the color contract — one meaning, enforced by tests
Signal-green #00D4A0 now means exactly ONE thing (edge/active/A-tier/CTA), locked by tests that fail on violation. Part 1 of DESIGN-SPEC v2. - web/src/lib/colorContract.js — pure CommonJS helpers: edgeColor(value) colors edge/CLV/delta by SIGN (neg=var(--miss), pos=var(--g-a), 0=neutral); gradeTierColor() (A/A+ green, B blue, C amber, D/F red, in lockstep with vyndrTokens.gradeColor); gradeGlows() (A/A+ only); deltaE()/isSignalGreen() CIE76 gate so no archetype hue dilutes the signal. - GradeResultCard: edge confidence-strip + EDGE row route through edgeColor (a -33.3% edge was rendering GREEN — audit #3); grade-hero glow gated to A/A+ via gradeGlows (a glowing C devalued the cue); VYNDR INTELLIGENCE panel de-flooded (neutral border, Form/Rest neutral not green — #15). - LiveHeroProp: negative edge now muted red, not neutral (sign completeness). - Archetype dedup off signal-green (both archetypes.js + archetypeService.js, kept matched): DUAL THREAT/MOTOR #00D4A0, MIRROR #34D399, ARTILLERY/RANGE/ GHOST/BLADE #2DD4BF, BRUSH #3DDC84 shifted to distinct non-green hues (all ΔE>=44 from #00D4A0). Within-sport uniqueness preserved. - tests/unit/colorContract.test.js — 21 tests: helper units + source-grep violation locks + archetype-green-dedup. QA.20-22 kept green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -37,7 +37,7 @@ const ARCHETYPES = {
|
||||
education: 'A Fortress generates value on the defensive glass and at the rim. Rebounds and blocks are matchup-resilient; their scoring depends on how much offense flows their way.',
|
||||
},
|
||||
ARTILLERY: {
|
||||
legacyName: 'STRETCH BIG', tag: 'ARTILLERY', sport: 'nba', color: '#2DD4BF', glyph: 'target',
|
||||
legacyName: 'STRETCH BIG', tag: 'ARTILLERY', sport: 'nba', color: '#159AAE', glyph: 'target',
|
||||
description: 'Floor-spacing shooting big',
|
||||
propDNA: { reliable: ['threes', 'rebounds'], volatile: ['assists', 'blocks'] },
|
||||
education: 'Artillery bigs space the floor and crash the glass. Threes and rebounds are their bread and butter; assists and blocks are situational.',
|
||||
@@ -49,7 +49,7 @@ const ARCHETYPES = {
|
||||
education: 'A Surge soaks up shots when a star sits or is injured. Their points props spike on cascade nights — read the injury report before trusting the baseline.',
|
||||
},
|
||||
'DUAL THREAT': {
|
||||
legacyName: 'COMBO GUARD', tag: 'DUAL THREAT', sport: 'nba', color: '#00D4A0', glyph: 'twin',
|
||||
legacyName: 'COMBO GUARD', tag: 'DUAL THREAT', sport: 'nba', color: '#1EA6D8', glyph: 'twin',
|
||||
description: 'Scoring + playmaking hybrid',
|
||||
propDNA: { reliable: ['points', 'assists'], volatile: ['rebounds'] },
|
||||
education: 'Dual Threats score and create in equal measure, so points and assists both stay in play. Rebounds are the volatile leg for their size.',
|
||||
@@ -123,7 +123,7 @@ const ARCHETYPES = {
|
||||
education: 'Shields contribute on both ends. Points and defensive stats stay live; their playmaking is secondary.',
|
||||
},
|
||||
RANGE: {
|
||||
legacyName: 'STRETCH FORWARD', tag: 'RANGE', sport: 'wnba', color: '#2DD4BF', glyph: 'target',
|
||||
legacyName: 'STRETCH FORWARD', tag: 'RANGE', sport: 'wnba', color: '#159AAE', glyph: 'target',
|
||||
description: 'Floor-spacing forward',
|
||||
propDNA: { reliable: ['threes', 'points'], volatile: ['assists', 'blocks'] },
|
||||
education: 'Range forwards space the floor from the four. Threes and points are reliable; interior props are matchup-dependent.',
|
||||
@@ -149,7 +149,7 @@ const ARCHETYPES = {
|
||||
education: 'Bombers drive the ball over the fence. Total bases and home-run props carry their value; their batting-average-driven props (hits) are the volatile leg from strikeout risk.',
|
||||
},
|
||||
BRUSH: {
|
||||
legacyName: 'CONTACT', tag: 'BRUSH', sport: 'mlb', color: '#3DDC84', glyph: 'crosshair',
|
||||
legacyName: 'CONTACT', tag: 'BRUSH', sport: 'mlb', color: '#C0C63C', glyph: 'crosshair',
|
||||
description: 'High average, low strikeout',
|
||||
propDNA: { reliable: ['hits'], volatile: ['home_runs', 'total_bases'] },
|
||||
education: 'Brush hitters rarely strike out, so their hits props are among the most reliable in baseball. Power props (HR, TB) are the volatile leg.',
|
||||
@@ -173,7 +173,7 @@ const ARCHETYPES = {
|
||||
education: 'Whiffs rack up strikeouts but allow more baserunners than an Alpha. The strikeout prop is reliable; earned-run and innings props swing with their traffic.',
|
||||
},
|
||||
GHOST: {
|
||||
legacyName: 'SPEED THREAT', tag: 'GHOST', sport: 'mlb', color: '#2DD4BF', glyph: 'chevrons',
|
||||
legacyName: 'SPEED THREAT', tag: 'GHOST', sport: 'mlb', color: '#159AAE', glyph: 'chevrons',
|
||||
description: 'Stolen bases, speed score',
|
||||
propDNA: { reliable: ['stolen_bases', 'runs'], volatile: ['home_runs'] },
|
||||
education: 'Ghosts turn singles into runs. Stolen-base and runs props are their lane; power props rarely clear.',
|
||||
@@ -203,7 +203,7 @@ const ARCHETYPES = {
|
||||
education: 'Catalysts get on base and score. Hits and runs props are their lane; RBI and power props sit lower in their profile.',
|
||||
},
|
||||
MIRROR: {
|
||||
legacyName: 'GAP HITTER', tag: 'MIRROR', sport: 'mlb', color: '#34D399', glyph: 'uparrow',
|
||||
legacyName: 'GAP HITTER', tag: 'MIRROR', sport: 'mlb', color: '#8FC04A', glyph: 'uparrow',
|
||||
description: 'Gap-to-gap line-drive bat',
|
||||
propDNA: { reliable: ['total_bases', 'hits'], volatile: ['home_runs'] },
|
||||
education: 'Mirror hitters spray doubles to both gaps. Total bases and hits are reliable; home-run props are the volatile leg of their extra-base profile.',
|
||||
@@ -253,13 +253,13 @@ const ARCHETYPES = {
|
||||
education: 'Towers win aerial duels and hold the ball up. Shot props are reliable; conversion to goals is variable.',
|
||||
},
|
||||
MOTOR: {
|
||||
legacyName: 'BOX-TO-BOX', tag: 'MOTOR', sport: 'soccer', color: '#00D4A0', glyph: 'chevrons',
|
||||
legacyName: 'BOX-TO-BOX', tag: 'MOTOR', sport: 'soccer', color: '#1EA6D8', glyph: 'chevrons',
|
||||
description: 'All-action central midfielder',
|
||||
propDNA: { reliable: ['tackles', 'passes'], volatile: ['goals', 'shots'] },
|
||||
education: 'Motors cover every blade of grass. Tackles and passing props are reliable; their attacking output swings by role.',
|
||||
},
|
||||
BLADE: {
|
||||
legacyName: 'WING WIZARD', tag: 'BLADE', sport: 'soccer', color: '#2DD4BF', glyph: 'slash',
|
||||
legacyName: 'WING WIZARD', tag: 'BLADE', sport: 'soccer', color: '#159AAE', glyph: 'slash',
|
||||
description: 'Dribbling wide threat',
|
||||
propDNA: { reliable: ['shots', 'assists'], volatile: ['goals'] },
|
||||
education: 'Blades beat defenders wide. Shots and assists are their lane; goals come in streaks.',
|
||||
|
||||
Reference in New Issue
Block a user