diff --git a/src/services/archetypeService.js b/src/services/archetypeService.js index 6a5c080..0610211 100644 --- a/src/services/archetypeService.js +++ b/src/services/archetypeService.js @@ -25,25 +25,25 @@ const ARCHETYPES = { education: 'Torches carry a heavy shot diet, so their points props track usage closely. When they get their normal touches, points clear reliably; assists and threes swing with game script.', }, CONDUCTOR: { - legacyName: 'FLOOR GENERAL', tag: 'CONDUCTOR', sport: 'nba', color: '#4A9EFF', glyph: 'node', + legacyName: 'FLOOR GENERAL', tag: 'CONDUCTOR', sport: 'nba', color: '#6C8CFF', glyph: 'node', description: 'Assist-heavy playmaker', propDNA: { reliable: ['assists'], volatile: ['points', 'threes'] }, education: 'Conductors create for others first. Assists are their most stable prop because the offense runs through them; their scoring fluctuates with shot selection and matchup.', }, FORTRESS: { - legacyName: 'TWO-WAY ANCHOR', tag: 'FORTRESS', sport: 'nba', color: '#A78BFA', glyph: 'shield', + legacyName: 'TWO-WAY ANCHOR', tag: 'FORTRESS', sport: 'nba', color: '#4C6FA5', glyph: 'shield', description: 'Defense, rebounds, blocks', propDNA: { reliable: ['rebounds', 'blocks'], volatile: ['points', 'assists'] }, 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: '#159AAE', glyph: 'target', + legacyName: 'STRETCH BIG', tag: 'ARTILLERY', sport: 'nba', color: '#C98A5A', 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.', }, SURGE: { - legacyName: 'USAGE SPONGE', tag: 'SURGE', sport: 'nba', color: '#FFB347', glyph: 'uparrow', + legacyName: 'USAGE SPONGE', tag: 'SURGE', sport: 'nba', color: '#FFA24A', glyph: 'uparrow', description: 'Usage spikes when stars sit', propDNA: { reliable: ['points'], volatile: ['assists', 'rebounds'] }, 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.', @@ -73,7 +73,7 @@ const ARCHETYPES = { education: 'A Paint Boss operates in the paint. Points and rebounds are reliable against most fronts; perimeter props are noise.', }, LOCKDOWN: { - legacyName: 'DEFENSIVE SPECIALIST', tag: 'LOCKDOWN', sport: 'nba', color: '#6366F1', glyph: 'shieldCheck', + legacyName: 'DEFENSIVE SPECIALIST', tag: 'LOCKDOWN', sport: 'nba', color: '#5A6474', glyph: 'shieldCheck', description: 'Perimeter stopper, low usage', propDNA: { reliable: ['steals'], volatile: ['points', 'assists'] }, education: 'Lockdowns earn minutes with their on-ball defense. Steals and blocks carry their card; offensive props are low-volume and streaky.', @@ -85,25 +85,25 @@ const ARCHETYPES = { education: 'Switchboards run the offense from a wing or big body, so points, assists, and rebounds all stay live. Their three-point output is the swing factor.', }, ARCHITECT: { - legacyName: 'SLASHER', tag: 'ARCHITECT', sport: 'nba', color: '#FB923C', glyph: 'slash', + legacyName: 'SLASHER', tag: 'ARCHITECT', sport: 'nba', color: '#B07CFF', glyph: 'slash', description: 'Self-created shot maker, rim-attacking', propDNA: { reliable: ['points'], volatile: ['threes', 'assists'] }, education: 'Architects manufacture their own shot at the rim and the line. Points are stable; their three-point props are volatile because they rarely settle for jumpers.', }, PISTON: { - legacyName: 'RIM RUNNER', tag: 'PISTON', sport: 'nba', color: '#F472B6', glyph: 'arc', + legacyName: 'RIM RUNNER', tag: 'PISTON', sport: 'nba', color: '#E87B4A', glyph: 'arc', description: 'Lob and putback finisher', propDNA: { reliable: ['rebounds'], volatile: ['points', 'assists'] }, education: 'Pistons finish lobs and putbacks. Rebounds are reliable; their scoring depends entirely on feeds from creators.', }, SENTINEL: { - legacyName: '3-AND-D', tag: 'SENTINEL', sport: 'nba', color: '#818CF8', glyph: 'crosshair', + legacyName: '3-AND-D', tag: 'SENTINEL', sport: 'nba', color: '#4FA0C4', glyph: 'crosshair', description: 'Catch-and-shoot plus defense', propDNA: { reliable: ['threes'], volatile: ['points', 'assists'] }, education: 'Sentinels catch and shoot. Threes are their signature prop; total points swing with how many open looks the offense generates.', }, IGNITER: { - legacyName: 'SIXTH MAN', tag: 'IGNITER', sport: 'nba', color: '#FACC15', glyph: 'bolt', + legacyName: 'SIXTH MAN', tag: 'IGNITER', sport: 'nba', color: '#FF8A3D', glyph: 'bolt', description: 'Bench scoring spark', propDNA: { reliable: ['points'], volatile: ['rebounds', 'assists'] }, education: 'Igniters provide instant offense off the bench. Their points props depend on minutes — confirm the rotation before betting overs.', @@ -117,25 +117,25 @@ const ARCHETYPES = { education: 'Distributors orchestrate from the elbow and block. Assists and rebounds are reliable; perimeter shooting is the volatile leg.', }, SHIELD: { - legacyName: 'TWO-WAY WING', tag: 'SHIELD', sport: 'wnba', color: '#A78BFA', glyph: 'shieldCheck', + legacyName: 'TWO-WAY WING', tag: 'SHIELD', sport: 'wnba', color: '#5A8CA8', glyph: 'shieldCheck', description: 'Two-way perimeter forward', propDNA: { reliable: ['points', 'steals'], volatile: ['assists'] }, 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: '#159AAE', glyph: 'target', + legacyName: 'STRETCH FORWARD', tag: 'RANGE', sport: 'wnba', color: '#C77CE0', 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.', }, SPARK: { - legacyName: 'SLASHING GUARD', tag: 'SPARK', sport: 'wnba', color: '#FB923C', glyph: 'slash', + legacyName: 'SLASHING GUARD', tag: 'SPARK', sport: 'wnba', color: '#F0A93D', glyph: 'slash', description: 'Downhill scoring guard', propDNA: { reliable: ['points'], volatile: ['threes', 'assists'] }, education: 'Sparks attack downhill. Points are stable; three-point props are the volatile leg since they prioritize the rim.', }, ANCHOR: { - legacyName: 'INTERIOR ANCHOR', tag: 'ANCHOR', sport: 'wnba', color: '#6366F1', glyph: 'shield', + legacyName: 'INTERIOR ANCHOR', tag: 'ANCHOR', sport: 'wnba', color: '#4C86C4', glyph: 'shield', description: 'Dominant paint defender and rebounder', propDNA: { reliable: ['rebounds', 'blocks'], volatile: ['points', 'assists'] }, education: 'Anchors own the paint. Rebounds and blocks are reliable; their scoring depends on post touches.', @@ -143,7 +143,7 @@ const ARCHETYPES = { // ───────── MLB (15) ───────── BOMBER: { - legacyName: 'POWER SLUGGER', tag: 'BOMBER', sport: 'mlb', color: '#FF6B4A', glyph: 'triangle', + legacyName: 'POWER SLUGGER', tag: 'BOMBER', sport: 'mlb', color: '#FF9F45', glyph: 'triangle', description: 'Middle-of-the-order power producer', propDNA: { reliable: ['total_bases', 'home_runs'], volatile: ['hits'] }, 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.', @@ -155,13 +155,13 @@ const ARCHETYPES = { 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.', }, DRIVER: { - legacyName: 'RUN PRODUCER', tag: 'DRIVER', sport: 'mlb', color: '#4A9EFF', glyph: 'diamond', + legacyName: 'RUN PRODUCER', tag: 'DRIVER', sport: 'mlb', color: '#5A7D9A', glyph: 'diamond', description: 'RBI-dependent, lineup context', propDNA: { reliable: ['rbi'], volatile: ['hits', 'home_runs'] }, education: 'Drivers hit in the heart of the order. RBI props track lineup context — strong with runners on base; their individual hit props are more variable.', }, ALPHA: { - legacyName: 'ACE', tag: 'ALPHA', sport: 'mlb', color: '#A78BFA', glyph: 'star', + legacyName: 'ACE', tag: 'ALPHA', sport: 'mlb', color: '#7C5CFF', glyph: 'star', description: 'High K/9, low WHIP, deep games', propDNA: { reliable: ['strikeouts', 'innings_pitched'], volatile: ['earned_runs'] }, education: 'Alphas miss bats and go deep. Strikeout and innings props are their most reliable; earned-run props are noisier because one swing can change a line.', @@ -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: '#159AAE', glyph: 'chevrons', + legacyName: 'SPEED THREAT', tag: 'GHOST', sport: 'mlb', color: '#3FD8E0', 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.', @@ -191,37 +191,37 @@ const ARCHETYPES = { education: 'Flex players move around the lineup and the diamond. Their props are matchup- and slot-dependent — confirm they are starting before betting.', }, WORKHORSE: { - legacyName: 'INNINGS EATER', tag: 'WORKHORSE', sport: 'mlb', color: '#818CF8', glyph: 'clock', + legacyName: 'INNINGS EATER', tag: 'WORKHORSE', sport: 'mlb', color: '#C89B5A', glyph: 'clock', description: 'Durable, deep-start arm', propDNA: { reliable: ['innings_pitched'], volatile: ['strikeouts', 'earned_runs'] }, education: 'Workhorses pitch deep without elite stuff. Innings props are reliable; strikeout and earned-run props are more variable since they pitch to contact.', }, CATALYST: { - legacyName: 'TABLE SETTER', tag: 'CATALYST', sport: 'mlb', color: '#38BDF8', glyph: 'diamondLine', + legacyName: 'TABLE SETTER', tag: 'CATALYST', sport: 'mlb', color: '#E88AC0', glyph: 'diamondLine', description: 'On-base leadoff catalyst', propDNA: { reliable: ['hits', 'runs'], volatile: ['rbi', 'home_runs'] }, 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: '#8FC04A', glyph: 'uparrow', + legacyName: 'GAP HITTER', tag: 'MIRROR', sport: 'mlb', color: '#B0B6C8', 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.', }, HAMMER: { - legacyName: 'CLOSER', tag: 'HAMMER', sport: 'mlb', color: '#FB7185', glyph: 'lock', + legacyName: 'CLOSER', tag: 'HAMMER', sport: 'mlb', color: '#FF4D6D', glyph: 'lock', description: 'Ninth-inning save specialist', propDNA: { reliable: ['strikeouts'], volatile: ['earned_runs', 'innings_pitched'] }, education: 'Hammers throw one high-leverage inning. Strikeout props can hit in a clean save; everything else is a one-inning coin flip.', }, SINKER: { - legacyName: 'SWINGMAN', tag: 'SINKER', sport: 'mlb', color: '#FBBF24', glyph: 'swap', + legacyName: 'SWINGMAN', tag: 'SINKER', sport: 'mlb', color: '#5A9AB0', glyph: 'swap', description: 'Groundball spot-starter / long relief', propDNA: { reliable: [], volatile: ['strikeouts', 'innings_pitched', 'earned_runs'] }, education: 'Sinkers bounce between starting and relief and pitch to contact. Their workload is unpredictable, so all of their props carry role risk — confirm the assignment.', }, BRIDGE: { - legacyName: 'BULLPEN ARM', tag: 'BRIDGE', sport: 'mlb', color: '#6366F1', glyph: 'shieldCheck', + legacyName: 'BULLPEN ARM', tag: 'BRIDGE', sport: 'mlb', color: '#6C9CB0', glyph: 'shieldCheck', description: 'Setup / high-leverage middle relief', propDNA: { reliable: ['strikeouts'], volatile: ['earned_runs', 'innings_pitched'] }, education: 'Bridges throw short, high-leverage outings. Strikeout props can hit in one inning; innings and earned-run props are too small a sample to trust.', @@ -241,31 +241,31 @@ const ARCHETYPES = { education: 'Finishers score inside the box. Shots-on-target and goals are their props; they rarely create for others.', }, MAESTRO: { - legacyName: 'CREATOR', tag: 'MAESTRO', sport: 'soccer', color: '#4A9EFF', glyph: 'node', + legacyName: 'CREATOR', tag: 'MAESTRO', sport: 'soccer', color: '#D9A441', glyph: 'node', description: 'Chance-creating playmaker', propDNA: { reliable: ['assists', 'passes'], volatile: ['goals'] }, education: 'Maestros set the table. Assists and passing props are reliable; their goal output is the volatile leg.', }, TOWER: { - legacyName: 'TARGET MAN', tag: 'TOWER', sport: 'soccer', color: '#FF6B4A', glyph: 'triangle', + legacyName: 'TARGET MAN', tag: 'TOWER', sport: 'soccer', color: '#6C9CB0', glyph: 'triangle', description: 'Hold-up aerial striker', propDNA: { reliable: ['shots', 'shots_on_target'], volatile: ['goals', 'assists'] }, 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: '#1EA6D8', glyph: 'chevrons', + legacyName: 'BOX-TO-BOX', tag: 'MOTOR', sport: 'soccer', color: '#E0A03D', 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: '#159AAE', glyph: 'slash', + legacyName: 'WING WIZARD', tag: 'BLADE', sport: 'soccer', color: '#B36CFF', 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.', }, WALL: { - legacyName: 'SWEEPER KEEPER', tag: 'WALL', sport: 'soccer', color: '#A78BFA', glyph: 'shield', + legacyName: 'SWEEPER KEEPER', tag: 'WALL', sport: 'soccer', color: '#5A7D9A', glyph: 'shield', description: 'Distributing goalkeeper', propDNA: { reliable: ['saves', 'passes'], volatile: ['goals_conceded'] }, education: 'Walls distribute and defend space. Saves and passing props are reliable; goals-conceded depends on the team in front of them.', diff --git a/tests/unit/archetypeBadge.test.js b/tests/unit/archetypeBadge.test.js index a7e97f2..a30de1c 100644 --- a/tests/unit/archetypeBadge.test.js +++ b/tests/unit/archetypeBadge.test.js @@ -11,27 +11,27 @@ const svc = require('../../src/services/archetypeService'); describe('archetypes lib — badge styling', () => { it('full variant fills with the archetype color + white text', () => { const s = arch.badgeStyle('BOMBER', 'full', 'md'); - expect(s.bg).toBe('#FF6B4A'); + expect(s.bg).toBe('#FF9F45'); expect(s.textColor).toBe('#FFFFFF'); - expect(s.borderColor).toBe('#FF6B4A'); + expect(s.borderColor).toBe('#FF9F45'); }); it('ghost variant is transparent with a colored border', () => { const s = arch.badgeStyle('CONDUCTOR', 'ghost', 'sm'); expect(s.bg).toBe('transparent'); - expect(s.textColor).toBe('#4A9EFF'); - expect(s.borderColor).toBe('#4A9EFFCC'); + expect(s.textColor).toBe('#6C8CFF'); + expect(s.borderColor).toBe('#6C8CFFCC'); }); it('tint variant (default) uses a low-alpha tinted background', () => { const s = arch.badgeStyle('ALPHA'); - expect(s.bg).toBe('#A78BFA1F'); - expect(s.borderColor).toBe('#A78BFA52'); + expect(s.bg).toBe('#7C5CFF1F'); + expect(s.borderColor).toBe('#7C5CFF52'); }); it('archetypeColor matches and is case-insensitive', () => { - expect(arch.archetypeColor('ace')).toBe('#A78BFA'); - expect(arch.archetypeColor('Two-Way Anchor')).toBe('#A78BFA'); + expect(arch.archetypeColor('ace')).toBe('#7C5CFF'); + expect(arch.archetypeColor('Two-Way Anchor')).toBe('#4C6FA5'); }); it('glyphSvg returns a 16x16 svg wrapper', () => { diff --git a/web/src/lib/archetypes.js b/web/src/lib/archetypes.js index e615273..e3e7c81 100644 --- a/web/src/lib/archetypes.js +++ b/web/src/lib/archetypes.js @@ -8,6 +8,37 @@ /* Glyph SVG inner-markup keyed by name (drawn in a 0 0 16 16 viewBox). */ const GLYPHS = { + /* Design 74-mark library — real archetype marks (HANDOFF) */ + 'alpha': '', + 'anchor': '', + 'architect': '', + 'artillery': '', + 'blade': '', + 'bomber': '', + 'bridge': '', + 'catalyst': '', + 'conductor': '', + 'driver': '', + 'fortress': '', + 'ghost': '', + 'hammer': '', + 'igniter': '', + 'lockdown': '', + 'maestro': '', + 'mirror': '', + 'motor': '', + 'piston': '', + 'range': '', + 'sentinel': '', + 'shield': '', + 'sinker': '', + 'spark': '', + 'surge': '', + 'torch': '', + 'tower': '', + 'wall': '', + 'workhorse': '', + triangle: '', node: '', shield: '', @@ -38,50 +69,50 @@ const GLYPHS = { `legacy` is the old descriptive label, kept for reference (never displayed). */ const ARCHETYPE_MAP = { // NBA - TORCH: { c: '#FF6B4A', d: 'High usage, shot-dependent scorer', g: 'triangle', legacy: 'VOLUME SCORER' }, - CONDUCTOR: { c: '#4A9EFF', d: 'Assist-heavy playmaker', g: 'node', legacy: 'FLOOR GENERAL' }, - FORTRESS: { c: '#A78BFA', d: 'Defense, rebounds, blocks', g: 'shield', legacy: 'TWO-WAY ANCHOR' }, - ARTILLERY: { c: '#159AAE', d: 'Floor-spacing shooting big', g: 'target', legacy: 'STRETCH BIG' }, - SURGE: { c: '#FFB347', d: 'Usage spikes when stars sit', g: 'uparrow', legacy: 'USAGE SPONGE' }, + TORCH: { c: '#FF6B4A', d: 'High usage, shot-dependent scorer', g: 'torch', legacy: 'VOLUME SCORER' }, + CONDUCTOR: { c: '#6C8CFF', d: 'Assist-heavy playmaker', g: 'conductor', legacy: 'FLOOR GENERAL' }, + FORTRESS: { c: '#4C6FA5', d: 'Defense, rebounds, blocks', g: 'fortress', legacy: 'TWO-WAY ANCHOR' }, + ARTILLERY: { c: '#C98A5A', d: 'Floor-spacing shooting big', g: 'artillery', legacy: 'STRETCH BIG' }, + SURGE: { c: '#FFA24A', d: 'Usage spikes when stars sit', g: 'surge', legacy: 'USAGE SPONGE' }, 'DUAL THREAT': { c: '#1EA6D8', d: 'Scoring + playmaking hybrid', g: 'twin', legacy: 'COMBO GUARD' }, CONNECTOR: { c: '#9499A8', d: 'Low-usage specialist', g: 'chain', legacy: 'ROLE GLUE' }, FASTBREAK: { c: '#22D3EE', d: 'Pace-pushing fast-break threat', g: 'chevrons', legacy: 'TRANSITION ENGINE' }, 'PAINT BOSS': { c: '#FF5C5C', d: 'Back-to-basket interior scorer', g: 'postup', legacy: 'POST SCORER' }, - LOCKDOWN: { c: '#6366F1', d: 'Perimeter stopper, low usage', g: 'shieldCheck', legacy: 'DEFENSIVE SPECIALIST' }, + LOCKDOWN: { c: '#5A6474', d: 'Perimeter stopper, low usage', g: 'lockdown', legacy: 'DEFENSIVE SPECIALIST' }, SWITCHBOARD: { c: '#38BDF8', d: 'Oversized primary creator', g: 'half', legacy: 'POINT FORWARD' }, - ARCHITECT: { c: '#FB923C', d: 'Self-created shot maker, rim-attacking', g: 'slash', legacy: 'SLASHER' }, - PISTON: { c: '#F472B6', d: 'Lob and putback finisher', g: 'arc', legacy: 'RIM RUNNER' }, - SENTINEL: { c: '#818CF8', d: 'Catch-and-shoot plus defense', g: 'crosshair', legacy: '3-AND-D' }, - IGNITER: { c: '#FACC15', d: 'Bench scoring spark', g: 'bolt', legacy: 'SIXTH MAN' }, + ARCHITECT: { c: '#B07CFF', d: 'Self-created shot maker, rim-attacking', g: 'architect', legacy: 'SLASHER' }, + PISTON: { c: '#E87B4A', d: 'Lob and putback finisher', g: 'piston', legacy: 'RIM RUNNER' }, + SENTINEL: { c: '#4FA0C4', d: 'Catch-and-shoot plus defense', g: 'sentinel', legacy: '3-AND-D' }, + IGNITER: { c: '#FF8A3D', d: 'Bench scoring spark', g: 'igniter', legacy: 'SIXTH MAN' }, // WNBA-unique DISTRIBUTOR: { c: '#C084FC', d: 'Playmaking hub from the post', g: 'node', legacy: 'POST FACILITATOR' }, - SHIELD: { c: '#A78BFA', d: 'Two-way perimeter forward', g: 'shieldCheck', legacy: 'TWO-WAY WING' }, - RANGE: { c: '#159AAE', d: 'Floor-spacing forward', g: 'target', legacy: 'STRETCH FORWARD' }, - SPARK: { c: '#FB923C', d: 'Downhill scoring guard', g: 'slash', legacy: 'SLASHING GUARD' }, - ANCHOR: { c: '#6366F1', d: 'Dominant paint defender and rebounder', g: 'shield', legacy: 'INTERIOR ANCHOR' }, + SHIELD: { c: '#5A8CA8', d: 'Two-way perimeter forward', g: 'shield', legacy: 'TWO-WAY WING' }, + RANGE: { c: '#C77CE0', d: 'Floor-spacing forward', g: 'range', legacy: 'STRETCH FORWARD' }, + SPARK: { c: '#F0A93D', d: 'Downhill scoring guard', g: 'spark', legacy: 'SLASHING GUARD' }, + ANCHOR: { c: '#4C86C4', d: 'Dominant paint defender and rebounder', g: 'anchor', legacy: 'INTERIOR ANCHOR' }, // MLB - BOMBER: { c: '#FF6B4A', d: 'Middle-of-the-order power producer', g: 'triangle', legacy: 'POWER SLUGGER' }, + BOMBER: { c: '#FF9F45', d: 'Middle-of-the-order power producer', g: 'bomber', legacy: 'POWER SLUGGER' }, BRUSH: { c: '#C0C63C', d: 'High average, low strikeout', g: 'crosshair', legacy: 'CONTACT' }, - DRIVER: { c: '#4A9EFF', d: 'RBI-dependent, lineup context', g: 'diamond', legacy: 'RUN PRODUCER' }, - ALPHA: { c: '#A78BFA', d: 'High K/9, low WHIP, deep games', g: 'star', legacy: 'ACE' }, + DRIVER: { c: '#5A7D9A', d: 'RBI-dependent, lineup context', g: 'driver', legacy: 'RUN PRODUCER' }, + ALPHA: { c: '#7C5CFF', d: 'High K/9, low WHIP, deep games', g: 'alpha', legacy: 'ACE' }, WHIFF: { c: '#FFB347', d: 'Bat-missing arm, high K with traffic', g: 'bolt', legacy: 'STRIKEOUT ARTIST' }, - GHOST: { c: '#159AAE', d: 'Stolen bases, speed score', g: 'chevrons', legacy: 'SPEED THREAT' }, + GHOST: { c: '#3FD8E0', d: 'Stolen bases, speed score', g: 'ghost', legacy: 'SPEED THREAT' }, HYBRID: { c: '#F472B6', d: 'Bats and pitches at elite level', g: 'half', legacy: 'TWO-WAY PLAYER' }, FLEX: { c: '#22D3EE', d: 'Multi-position lineup flex', g: 'plus', legacy: 'UTILITY PLAYER' }, - WORKHORSE: { c: '#818CF8', d: 'Durable, deep-start arm', g: 'clock', legacy: 'INNINGS EATER' }, - CATALYST: { c: '#38BDF8', d: 'On-base leadoff catalyst', g: 'diamondLine', legacy: 'TABLE SETTER' }, - MIRROR: { c: '#8FC04A', d: 'Gap-to-gap line-drive bat', g: 'uparrow', legacy: 'GAP HITTER' }, - HAMMER: { c: '#FB7185', d: 'Ninth-inning save specialist', g: 'lock', legacy: 'CLOSER' }, - SINKER: { c: '#FBBF24', d: 'Groundball spot-starter / long relief', g: 'swap', legacy: 'SWINGMAN' }, - BRIDGE: { c: '#6366F1', d: 'Setup / high-leverage middle relief', g: 'shieldCheck', legacy: 'BULLPEN ARM' }, + WORKHORSE: { c: '#C89B5A', d: 'Durable, deep-start arm', g: 'workhorse', legacy: 'INNINGS EATER' }, + CATALYST: { c: '#E88AC0', d: 'On-base leadoff catalyst', g: 'catalyst', legacy: 'TABLE SETTER' }, + MIRROR: { c: '#B0B6C8', d: 'Gap-to-gap line-drive bat', g: 'mirror', legacy: 'GAP HITTER' }, + HAMMER: { c: '#FF4D6D', d: 'Ninth-inning save specialist', g: 'hammer', legacy: 'CLOSER' }, + SINKER: { c: '#5A9AB0', d: 'Groundball spot-starter / long relief', g: 'sinker', legacy: 'SWINGMAN' }, + BRIDGE: { c: '#6C9CB0', d: 'Setup / high-leverage middle relief', g: 'bridge', legacy: 'BULLPEN ARM' }, SWITCH: { c: '#FF5C5C', d: 'Platoon-leveraged, glove-first bat', g: 'batball', legacy: 'DEFENSIVE WIZARD' }, // Soccer FINISHER: { c: '#FF5C5C', d: 'Penalty-box finisher', g: 'crosshair', legacy: 'POACHER' }, - MAESTRO: { c: '#4A9EFF', d: 'Chance-creating playmaker', g: 'node', legacy: 'CREATOR' }, - TOWER: { c: '#FF6B4A', d: 'Hold-up aerial striker', g: 'triangle', legacy: 'TARGET MAN' }, - MOTOR: { c: '#1EA6D8', d: 'All-action central midfielder', g: 'chevrons', legacy: 'BOX-TO-BOX' }, - BLADE: { c: '#159AAE', d: 'Dribbling wide threat', g: 'slash', legacy: 'WING WIZARD' }, - WALL: { c: '#A78BFA', d: 'Distributing goalkeeper', g: 'shield', legacy: 'SWEEPER KEEPER' }, + MAESTRO: { c: '#D9A441', d: 'Chance-creating playmaker', g: 'maestro', legacy: 'CREATOR' }, + TOWER: { c: '#6C9CB0', d: 'Hold-up aerial striker', g: 'tower', legacy: 'TARGET MAN' }, + MOTOR: { c: '#E0A03D', d: 'All-action central midfielder', g: 'motor', legacy: 'BOX-TO-BOX' }, + BLADE: { c: '#B36CFF', d: 'Dribbling wide threat', g: 'blade', legacy: 'WING WIZARD' }, + WALL: { c: '#5A7D9A', d: 'Distributing goalkeeper', g: 'wall', legacy: 'SWEEPER KEEPER' }, }; /* Combat archetype visual map (Wave 6 — MMA/UFC). SEPARATE from ARCHETYPE_MAP: