Rev 3 matchup chips: TeamChip primitive + board-row team context

Design Rev 3 anchors every matchup/context abbr with a 10-12px team tile. New
reusable TeamChip renders the real TeamLogo (licensed ESPN logo where it
resolves, team-colored monogram otherwise — the resolver is already built) at
that size + the abbr, sitting inside the row so it inherits the ranked opacity
ramp. First placement: StatStrip's player/team context (name → team-chip →
archetype). ROW-GRAMMAR identity-run test updated to the chip marker.

Remaining Rev 3 placements to thread TeamChip into (reusable, mechanical):
parlay legs, grade-shift header, pitcher "vs", /u recent-settled, other
matchup context lines. Game-card headers already carry TeamLogo (TeamLink).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Kev
2026-07-16 21:27:47 -04:00
parent 771d8b0ba4
commit f24f9412f1
4 changed files with 42 additions and 2 deletions
+1 -1
View File
@@ -55,7 +55,7 @@ describe('ROW-GRAMMAR §2 — canonical prop-row slot order (snapshot mode)', ()
expect(base).toBeGreaterThan(-1);
assertOrder(strip, [
'<PlayerName',
'{team}</span>',
'<TeamChip team={team}', // Rev 3 — team chip anchors the abbr
'<ArchetypeBadge archetype={archetype.primary}',
'<ViabilityChips lineup={lineup} injury={injury} />',
], base);
+3 -1
View File
@@ -7,6 +7,7 @@ import { nextRunLabelET } from '@/lib/pipelineSchedule';
// affiliate config flips a book on). rel MUST stay BOOK_LINK_REL.
import { buildBookLink, BOOK_LINK_REL } from '@/lib/bookLinks';
import { bookInfo } from '@/lib/books';
import TeamChip from '@/components/vyndr/TeamChip';
export interface StatCell {
label: string;
@@ -389,7 +390,8 @@ export default function StatStrip({
(never the gray silhouette). Team drives the accent color. */}
<PlayerAvatar name={player} sport={sport} playerId={playerId} espnId={espnId} headshotUrl={headshotUrl} team={team} size={30} />
<PlayerName style={{ fontWeight: 700, fontSize: 14, color: '#fff', ...nameStyle }}>{player}</PlayerName>
<span className="mono" style={{ fontSize: 11, color: 'var(--text-1)' }}>{team}</span>
{/* Rev 3 — team context anchored by a real team chip (logo / monogram). */}
<TeamChip team={team} sport={sport} size={12} />
{archetype && <ArchetypeBadge archetype={archetype.primary} size="sm" variant="full" />}
{archetype?.secondary && (
<>
+37
View File
@@ -0,0 +1,37 @@
import type { CSSProperties } from 'react';
import TeamLogo from '@/components/vyndr/TeamLogo';
/**
* TeamChip (Design Rev 3) — a small team tile anchoring an abbr on a matchup /
* context line. Design drew a 10-12px team-gradient chip before each abbr;
* per the handoff we swap in the real TeamLogo img at the same size (the
* resolver already renders the licensed ESPN logo where it resolves, and a
* team-colored monogram otherwise — never a gray box).
*
* Renders `[tile] ABBR`. Inherits the row's opacity ramp because it sits inside
* the row (no own opacity). Mono abbr, matching the matchup line.
*/
export default function TeamChip({
team,
sport,
size = 12,
showAbbr = true,
style = {},
}: {
team?: string | null;
sport?: string;
size?: number;
showAbbr?: boolean;
style?: CSSProperties;
}) {
if (!team) return null;
return (
<span
className="mono"
style={{ display: 'inline-flex', alignItems: 'center', gap: 3, fontSize: 11, color: 'var(--text-1)', ...style }}
>
<TeamLogo team={team} sport={sport} size={size} />
{showAbbr && String(team).toUpperCase()}
</span>
);
}
+1
View File
@@ -41,6 +41,7 @@ export { default as BookChip } from './BookChip';
/* DS0 (Design v2) — the Entity Layer: teams/players/books as themselves. */
export { default as TeamLogo } from './TeamLogo';
export { default as TeamChip } from './TeamChip';
export { default as PlayerAvatar } from './PlayerAvatar';
export { default as BookWordmark } from './BookWordmark';