'use strict'; /** * TEAM-GRADIENT CHIPS (D1-finish, 2026-07-31) — Rev-3 pattern from HANDOFF.md: * 10-12px chip, 135deg two-colour gradient, placed BEFORE each team abbr and * INSIDE the row, so the ranked opacity ramp (1 / .86 / .64 / .48) dims it too. * Swap for a licensed logo at the same size when assets land. * * 🔴 COVERAGE IS PARTIAL AND THAT IS DELIBERATE. The System artboard defines a * colour pair for only 10 teams; the registry (`lib/teams.js`) holds ~80. We do * NOT invent the other ~70 — a wrong team colour is a recognition error the user * reads as fact. Unknown teams render the HONEST-NEUTRAL chip (a muted border, * no colour claim), never a guessed hue and never a blank gap. * * Pairs below are lifted VERBATIM from `Vyndr System.dc.html` — no eyedropping, * no approximation. */ /** abbr -> [c1, c2], exactly as the artboard defines them. */ const TEAM_GRADIENTS = Object.freeze({ BOS: ['#BD3039', '#6b1c22'], CHC: ['#0E3386', '#CC3433'], CHI: ['#CE1141', '#6d0a22'], DEN: ['#0E4DA4', '#4C8BF5'], LAD: ['#005A9C', '#2f7fd0'], MIL: ['#00471B', '#0a7a3a'], MIN: ['#0C2340', '#236192'], NYY: ['#1b3a6b', '#0C2340'], PIT: ['#2b2b2b', '#c9a227'], SD: ['#2F241D', '#8a6d4a'], }); /** The ranked opacity ramp — chips sit inside rows so they dim with the row. */ const RANK_OPACITY = Object.freeze([1, 0.86, 0.64, 0.48]); /** Opacity for rank index i (clamped to the ramp's tail). */ function rankOpacity(i) { const n = Number(i); if (!Number.isFinite(n) || n < 0) return RANK_OPACITY[0]; return RANK_OPACITY[Math.min(Math.floor(n), RANK_OPACITY.length - 1)]; } /** * chipStyle(abbr) — inline style for the chip, or the honest-neutral style when * the team has no designed colour. Returns `{ style, known }` so a caller can * tell "we know this team" from "we are not claiming to". */ function chipStyle(abbr) { const key = String(abbr || '').trim().toUpperCase(); const pair = TEAM_GRADIENTS[key]; const base = { display: 'inline-block', width: 10, height: 10, borderRadius: 3, verticalAlign: -1.5, marginRight: 3, }; if (!pair) { // HONEST-NEUTRAL: a shape, not a colour claim. return { known: false, style: { ...base, background: 'transparent', border: '1px solid var(--border-hi)' } }; } return { known: true, style: { ...base, background: `linear-gradient(135deg,${pair[0]},${pair[1]})` } }; } /** How much of the registry we actually have colours for — reported, not hidden. */ function coverage(totalTeams) { const known = Object.keys(TEAM_GRADIENTS).length; const total = Number(totalTeams); return { known, total: Number.isFinite(total) ? total : null }; } module.exports = { TEAM_GRADIENTS, RANK_OPACITY, rankOpacity, chipStyle, coverage };