From ae3cff9dbdbb9a009d380f84dc7fd8f1b2f7166f Mon Sep 17 00:00:00 2001 From: Kev Date: Sat, 18 Jul 2026 13:55:39 -0400 Subject: [PATCH] =?UTF-8?q?Item=207=20=E2=80=94=20book=20roster:=20ESPN=20?= =?UTF-8?q?BET=20=E2=86=92=20theScore=20Bet=20(PENN)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ESPN BET is defunct — PENN/ESPN terminated the deal; PENN rebranded it to theScore Bet (Dec 1 2025) and ESPN is now exclusive with DraftKings. Removed the ESPN BET entries from the BookChip map (web/src/lib/books.js) and added theScore Bet (mono TS, slug thescore) as the successor. Added 'thescore' to the backend oddsNormalizer ALLOWED_BOOKS so the feed's lines are accepted; synced the bookWordmark test list. The ESPN references in src/config/sports.js are ESPN's STATS API (data provider, unrelated to the sportsbook) — left untouched. Flagged in specs/design-reference/HANDOFF.md that the design mockups' BookChip row still shows ESPN BET and needs the same one-swap on the next refresh. Co-Authored-By: Claude Opus 4.8 (1M context) --- specs/design-reference/HANDOFF.md | 2 ++ src/utils/oddsNormalizer.js | 3 ++- tests/unit/bookWordmark.test.js | 3 ++- web/src/lib/books.js | 8 ++++++-- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/specs/design-reference/HANDOFF.md b/specs/design-reference/HANDOFF.md index 2e1221a..48bdc87 100644 --- a/specs/design-reference/HANDOFF.md +++ b/specs/design-reference/HANDOFF.md @@ -13,6 +13,8 @@ Two design components, both open directly in a browser. All styling is inline (n Desktop /u profile also carries the TIER RECORD calibration strip (matches mobile screen 10 and the landing band). +> **BOOK ROSTER NOTE (2026-07, security follow-up item 7):** ESPN BET is defunct — PENN rebranded it to **theScore Bet** (Dec 1 2025); ESPN is now exclusive with DraftKings. The product BookChip set (`web/src/lib/books.js`) was updated (ESPN BET removed, theScore Bet added). The **design mockups' BookChip row still shows ESPN BET** — it needs the same one-swap to theScore Bet (mono `TS`) whenever the design files are refreshed. + ## Tokens (exact) - Surfaces: `#06060B` void · `#0E0E14` card · `#14141E` elevated · row hairline `#101018` · deep panel `#0A0A10` - Signal green `#00D4A0` — ONE meaning: edge / active / A-tier / primary CTA. Never decorative. diff --git a/src/utils/oddsNormalizer.js b/src/utils/oddsNormalizer.js index ae3d99f..d65c46a 100644 --- a/src/utils/oddsNormalizer.js +++ b/src/utils/oddsNormalizer.js @@ -5,7 +5,8 @@ const { getAbbreviation } = require('./teamMap'); // prop data through Pinnacle survives normalization. (bovada deliberately // left OUT — it's the canonical "not-allowed" example in the tests, and // VYNDR surfaces regulated US books.) -const ALLOWED_BOOKS = new Set(['draftkings', 'fanduel', 'betmgm', 'caesars', 'fanatics', 'bet365', 'hardrockbet', 'pointsbet', 'betrivers', 'pinnacle']); +// 'thescore' = theScore Bet (PENN), successor to the defunct ESPN BET (item 7). +const ALLOWED_BOOKS = new Set(['draftkings', 'fanduel', 'betmgm', 'caesars', 'fanatics', 'bet365', 'hardrockbet', 'pointsbet', 'betrivers', 'pinnacle', 'thescore']); const MARKET_MAP = { // NBA / WNBA props diff --git a/tests/unit/bookWordmark.test.js b/tests/unit/bookWordmark.test.js index 416b74a..95dd82f 100644 --- a/tests/unit/bookWordmark.test.js +++ b/tests/unit/bookWordmark.test.js @@ -9,7 +9,8 @@ const path = require('path'); const { bookInfo, bookSlug, hasBookSvg, BUNDLED_BOOK_SVGS } = require('../../web/src/lib/books'); // The exact keys oddsNormalizer.ALLOWED_BOOKS emits into the pipeline. -const ALLOWED_BOOKS = ['draftkings', 'fanduel', 'betmgm', 'caesars', 'fanatics', 'bet365', 'hardrockbet', 'pointsbet', 'betrivers', 'pinnacle']; +// 'thescore' = theScore Bet (PENN), successor to the defunct ESPN BET (item 7). +const ALLOWED_BOOKS = ['draftkings', 'fanduel', 'betmgm', 'caesars', 'fanatics', 'bet365', 'hardrockbet', 'pointsbet', 'betrivers', 'pinnacle', 'thescore']; const DEFAULT_FG = '#B8BCC8'; const REPO = path.resolve(__dirname, '../..'); diff --git a/web/src/lib/books.js b/web/src/lib/books.js index 4e5f2d1..fde7a6a 100644 --- a/web/src/lib/books.js +++ b/web/src/lib/books.js @@ -19,8 +19,12 @@ const BOOKS = { BETMGM: { name: 'BetMGM', mono: 'MGM', slug: 'betmgm', bg: '#1A1405', fg: '#C8A24B', bd: '#C8A24B55' }, CZR: { name: 'Caesars', mono: 'CZR', slug: 'caesars', bg: '#0C1A14', fg: '#1A7F5A', bd: '#1A7F5A66' }, CAESARS: { name: 'Caesars', mono: 'CZR', slug: 'caesars', bg: '#0C1A14', fg: '#1A7F5A', bd: '#1A7F5A66' }, - ESPN: { name: 'ESPN BET', mono: 'EB', bg: '#2A0A0A', fg: '#FF4A4A', bd: '#FF4A4A55' }, - 'ESPN BET': { name: 'ESPN BET', mono: 'EB', bg: '#2A0A0A', fg: '#FF4A4A', bd: '#FF4A4A55' }, + // Book roster update (security follow-up item 7): ESPN BET is defunct — PENN + // rebranded it to theScore Bet (Dec 1 2025); ESPN is now exclusive with + // DraftKings. theScore Bet (PENN) is the successor. + TS: { name: 'theScore Bet', mono: 'TS', slug: 'thescore', bg: '#08150F', fg: '#2FBF71', bd: '#2FBF7155' }, + THESCORE: { name: 'theScore Bet', mono: 'TS', slug: 'thescore', bg: '#08150F', fg: '#2FBF71', bd: '#2FBF7155' }, + 'THESCORE BET': { name: 'theScore Bet', mono: 'TS', slug: 'thescore', bg: '#08150F', fg: '#2FBF71', bd: '#2FBF7155' }, // BetRivers is a blue book (its logo is blue "BetRivers"), not purple. BR: { name: 'BetRivers', mono: 'BR', slug: 'betrivers', bg: '#08121F', fg: '#3E8FD6', bd: '#3E8FD655' }, BETRIVERS: { name: 'BetRivers', mono: 'BR', slug: 'betrivers', bg: '#08121F', fg: '#3E8FD6', bd: '#3E8FD655' },