@sensiblestats/widget-react 0.48.10 → 0.50.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/StatsWidget.tsx
2
- import { useCallback as useCallback6, useEffect as useEffect12, useMemo as useMemo3, useRef as useRef9, useState as useState20 } from "react";
2
+ import { useCallback as useCallback9, useEffect as useEffect15, useMemo as useMemo3, useRef as useRef13, useState as useState33 } from "react";
3
3
  import { StatsWidgetClient } from "@sensiblestats/widget-sdk";
4
4
 
5
5
  // src/kickoff.ts
@@ -83,6 +83,7 @@ var STRINGS = {
83
83
  graceNote: "Unpins on next open \xB7 or in 4 h",
84
84
  suspendedLabel: "Suspended",
85
85
  fullTimeLabel: "Full time",
86
+ ownGoalLabel: "OG",
86
87
  inSlipLabel: "In slip",
87
88
  oddsUnavailable: "Odds unavailable right now",
88
89
  momentumLabel: "Momentum",
@@ -92,7 +93,18 @@ var STRINGS = {
92
93
  tabToday: "Today",
93
94
  sectionLive: "Live",
94
95
  halfTime: "HT",
95
- staleStates: "Live scores can't be updated \u2014 showing the last known state."
96
+ staleStates: "Live scores can't be updated \u2014 showing the last known state.",
97
+ tabGames: "Games",
98
+ tabLeaderboard: "Leaderboard",
99
+ gamesLoginRequired: "Sign in to play and climb the leaderboard",
100
+ back: "Back",
101
+ leaderboardOffBoard: "Outside top 50",
102
+ leaderboardThisWeek: "This week",
103
+ leaderboardAllTime: "All time",
104
+ gamePlay: "Play",
105
+ gameResume: "Resume",
106
+ gameLocked: "Locked",
107
+ gameVoided: "Voided"
96
108
  },
97
109
  tr: {
98
110
  launcherLabel: "SensibleStats ile sohbet et",
@@ -161,6 +173,7 @@ var STRINGS = {
161
173
  graceNote: "Bir sonraki a\xE7\u0131l\u0131\u015Fta kald\u0131r\u0131l\u0131r \xB7 en ge\xE7 4 saat",
162
174
  suspendedLabel: "Ask\u0131da",
163
175
  fullTimeLabel: "Ma\xE7 sonu",
176
+ ownGoalLabel: "KK",
164
177
  inSlipLabel: "Kuponda",
165
178
  oddsUnavailable: "Oranlar \u015Fu anda kullan\u0131lam\u0131yor",
166
179
  momentumLabel: "Momentum",
@@ -170,7 +183,18 @@ var STRINGS = {
170
183
  tabToday: "Bug\xFCn",
171
184
  sectionLive: "Canl\u0131",
172
185
  halfTime: "\u0130Y",
173
- staleStates: "Canl\u0131 skorlar g\xFCncellenemiyor \u2014 son bilinen durum g\xF6steriliyor."
186
+ staleStates: "Canl\u0131 skorlar g\xFCncellenemiyor \u2014 son bilinen durum g\xF6steriliyor.",
187
+ tabGames: "Oyunlar",
188
+ tabLeaderboard: "Lider Tablosu",
189
+ gamesLoginRequired: "Oynamak ve lider tablosuna girmek i\xE7in giri\u015F yap\u0131n",
190
+ back: "Geri",
191
+ leaderboardOffBoard: "\u0130lk 50 d\u0131\u015F\u0131nda",
192
+ leaderboardThisWeek: "Bu hafta",
193
+ leaderboardAllTime: "T\xFCm zamanlar",
194
+ gamePlay: "Oyna",
195
+ gameResume: "Devam et",
196
+ gameLocked: "Kilitli",
197
+ gameVoided: "\u0130ptal edildi"
174
198
  }
175
199
  };
176
200
  function resolveLocaleStrings(locale) {
@@ -262,12 +286,24 @@ function normalizeUi(cfg) {
262
286
  graceNote: strings.graceNote,
263
287
  suspendedLabel: strings.suspendedLabel,
264
288
  fullTimeLabel: strings.fullTimeLabel,
289
+ ownGoalLabel: strings.ownGoalLabel,
265
290
  inSlipLabel: strings.inSlipLabel,
266
291
  oddsUnavailable: strings.oddsUnavailable,
267
292
  momentumLabel: strings.momentumLabel,
268
293
  accordionValueLabel: strings.accordionValueLabel,
269
294
  accordionRetry: strings.accordionRetry,
270
- accordionSuspended: strings.accordionSuspended
295
+ accordionSuspended: strings.accordionSuspended,
296
+ tabGames: strings.tabGames,
297
+ tabLeaderboard: strings.tabLeaderboard,
298
+ gamesLoginRequired: strings.gamesLoginRequired,
299
+ back: strings.back,
300
+ leaderboardOffBoard: strings.leaderboardOffBoard,
301
+ leaderboardThisWeek: strings.leaderboardThisWeek,
302
+ leaderboardAllTime: strings.leaderboardAllTime,
303
+ gamePlay: strings.gamePlay,
304
+ gameResume: strings.gameResume,
305
+ gameLocked: strings.gameLocked,
306
+ gameVoided: strings.gameVoided
271
307
  };
272
308
  }
273
309
  function toClientOptions(cfg) {
@@ -1102,7 +1138,7 @@ function useChatStream(conversation, starterTexts, greetingMessage, storageKey)
1102
1138
  }
1103
1139
 
1104
1140
  // src/useLiveMonitor.ts
1105
- import { useCallback as useCallback2, useEffect as useEffect3, useRef as useRef3, useState } from "react";
1141
+ import { useCallback as useCallback2, useEffect as useEffect3, useRef as useRef3, useState as useState2 } from "react";
1106
1142
 
1107
1143
  // src/pinStore.ts
1108
1144
  var MAX_MATCH_PINS = 5;
@@ -1164,6 +1200,13 @@ function createPinStore(storageKey, sessionId, onChange) {
1164
1200
  };
1165
1201
  }
1166
1202
 
1203
+ // src/useTabs.ts
1204
+ import { useState } from "react";
1205
+ function useTabs(initial = "chat") {
1206
+ const [activeTab, setActiveTab] = useState(initial);
1207
+ return { activeTab, setActiveTab };
1208
+ }
1209
+
1167
1210
  // src/useLiveMonitor.ts
1168
1211
  var GOAL_OR_RED = /* @__PURE__ */ new Set(["goal", "red"]);
1169
1212
  var MIN_POLL_MS = 5e3;
@@ -1185,19 +1228,19 @@ function phaseForPin(snapshot, pin) {
1185
1228
  }
1186
1229
  function useLiveMonitor(opts) {
1187
1230
  const sessionIdRef = useRef3(crypto.randomUUID());
1188
- const [pins, setPins] = useState([]);
1189
- const [store] = useState(() => createPinStore(opts.storageKey, sessionIdRef.current, setPins));
1190
- const [enabled, setEnabled] = useState(true);
1191
- const [snapshot, setSnapshotState] = useState(null);
1192
- const [activeTab, setActiveTabState] = useState("chat");
1193
- const [chatDot, setChatDot] = useState(false);
1194
- const [matchesDot, setMatchesDot] = useState(false);
1195
- const [oddsDot, setOddsDot] = useState(false);
1196
- const [todayDot, setTodayDot] = useState(false);
1197
- const [lastViewedPrices, setLastViewedPrices] = useState({});
1198
- const [inSlip, setInSlip] = useState({});
1199
- const [openMarket, setOpenMarket] = useState({});
1200
- const [marketOdds, setMarketOdds] = useState({});
1231
+ const [pins, setPins] = useState2([]);
1232
+ const [store] = useState2(() => createPinStore(opts.storageKey, sessionIdRef.current, setPins));
1233
+ const [enabled, setEnabled] = useState2(true);
1234
+ const [snapshot, setSnapshotState] = useState2(null);
1235
+ const { activeTab, setActiveTab: setActiveTabState } = useTabs("chat");
1236
+ const [chatDot, setChatDot] = useState2(false);
1237
+ const [matchesDot, setMatchesDot] = useState2(false);
1238
+ const [oddsDot, setOddsDot] = useState2(false);
1239
+ const [todayDot, setTodayDot] = useState2(false);
1240
+ const [lastViewedPrices, setLastViewedPrices] = useState2({});
1241
+ const [inSlip, setInSlip] = useState2({});
1242
+ const [openMarket, setOpenMarket] = useState2({});
1243
+ const [marketOdds, setMarketOdds] = useState2({});
1201
1244
  const pinsRef = useRef3(pins);
1202
1245
  pinsRef.current = pins;
1203
1246
  const activeTabRef = useRef3(activeTab);
@@ -1435,7 +1478,7 @@ function useLiveMonitor(opts) {
1435
1478
  }
1436
1479
 
1437
1480
  // src/useMatchDiscovery.ts
1438
- import { useCallback as useCallback3, useEffect as useEffect4, useMemo as useMemo2, useRef as useRef4, useState as useState2 } from "react";
1481
+ import { useCallback as useCallback3, useEffect as useEffect4, useMemo as useMemo2, useRef as useRef4, useState as useState3 } from "react";
1439
1482
 
1440
1483
  // src/scheduleCache.ts
1441
1484
  var PREFIX = "ss-w-schedule:";
@@ -1523,11 +1566,11 @@ function localDateOf(now) {
1523
1566
  return `${y}-${m}-${d}`;
1524
1567
  }
1525
1568
  function useMatchDiscovery(opts) {
1526
- const [groups, setGroups] = useState2([]);
1527
- const [states, setStates] = useState2({});
1528
- const [failures, setFailures] = useState2(0);
1529
- const [expanded, setExpanded] = useState2({});
1530
- const [touched, setTouched] = useState2({});
1569
+ const [groups, setGroups] = useState3([]);
1570
+ const [states, setStates] = useState3({});
1571
+ const [failures, setFailures] = useState3(0);
1572
+ const [expanded, setExpanded] = useState3({});
1573
+ const [touched, setTouched] = useState3({});
1531
1574
  const groupsRef = useRef4(groups);
1532
1575
  groupsRef.current = groups;
1533
1576
  const statesRef = useRef4(states);
@@ -1535,7 +1578,7 @@ function useMatchDiscovery(opts) {
1535
1578
  const getStatesRef = useRef4(opts.getStates);
1536
1579
  getStatesRef.current = opts.getStates;
1537
1580
  const pinnedKey = opts.pinnedMatchIds.join(",");
1538
- const [localDate, setLocalDate] = useState2(() => localDateOf(/* @__PURE__ */ new Date()));
1581
+ const [localDate, setLocalDate] = useState3(() => localDateOf(/* @__PURE__ */ new Date()));
1539
1582
  useEffect4(() => {
1540
1583
  const id = setInterval(() => {
1541
1584
  const next = localDateOf(/* @__PURE__ */ new Date());
@@ -1615,6 +1658,107 @@ function useMatchDiscovery(opts) {
1615
1658
  return { groups, states, liveCount, stale, expanded, toggleGroup, _tick: tick };
1616
1659
  }
1617
1660
 
1661
+ // src/useGames.ts
1662
+ import { useCallback as useCallback4, useEffect as useEffect5, useRef as useRef5, useState as useState4 } from "react";
1663
+ var GAMES_POLL_MS = 6e4;
1664
+ var DEFAULT_TZ = "Europe/London";
1665
+ function computeGameDay(timezone) {
1666
+ return new Intl.DateTimeFormat("en-CA", { timeZone: timezone }).format(/* @__PURE__ */ new Date());
1667
+ }
1668
+ function useGames(conversation, { activeTab, operatorTimezone }) {
1669
+ const [enabled, setEnabled] = useState4(true);
1670
+ const [games, setGames] = useState4([]);
1671
+ const [loading, setLoading] = useState4(false);
1672
+ const [refreshCount, setRefreshCount] = useState4(0);
1673
+ const inFlightRef = useRef5(false);
1674
+ const enabledRef = useRef5(true);
1675
+ const conversationRef = useRef5(conversation);
1676
+ conversationRef.current = conversation;
1677
+ const tzRef = useRef5(operatorTimezone ?? DEFAULT_TZ);
1678
+ tzRef.current = operatorTimezone ?? DEFAULT_TZ;
1679
+ useEffect5(() => {
1680
+ if (!enabledRef.current) return;
1681
+ let active = true;
1682
+ const doFetch = async () => {
1683
+ const conv = conversationRef.current;
1684
+ if (!conv || inFlightRef.current || !active) return;
1685
+ inFlightRef.current = true;
1686
+ setLoading(true);
1687
+ try {
1688
+ const gameDay = computeGameDay(tzRef.current);
1689
+ const result = await conv.getGames(gameDay);
1690
+ if (!active) return;
1691
+ if (result === null) {
1692
+ enabledRef.current = false;
1693
+ setEnabled(false);
1694
+ } else {
1695
+ setGames(result.games);
1696
+ }
1697
+ } catch {
1698
+ } finally {
1699
+ inFlightRef.current = false;
1700
+ if (active) setLoading(false);
1701
+ }
1702
+ };
1703
+ void doFetch();
1704
+ let intervalId;
1705
+ if (activeTab === "games") {
1706
+ intervalId = window.setInterval(() => {
1707
+ if (!enabledRef.current) {
1708
+ window.clearInterval(intervalId);
1709
+ return;
1710
+ }
1711
+ void doFetch();
1712
+ }, GAMES_POLL_MS);
1713
+ }
1714
+ return () => {
1715
+ active = false;
1716
+ if (intervalId !== void 0) window.clearInterval(intervalId);
1717
+ };
1718
+ }, [activeTab, refreshCount]);
1719
+ const refresh = useCallback4(() => {
1720
+ setRefreshCount((c) => c + 1);
1721
+ }, []);
1722
+ return { enabled, games, loading, refresh };
1723
+ }
1724
+
1725
+ // src/useLeaderboard.ts
1726
+ import { useCallback as useCallback5, useEffect as useEffect6, useRef as useRef6, useState as useState5 } from "react";
1727
+ function useLeaderboard(conversation, { activeTab }) {
1728
+ const [data, setData] = useState5(null);
1729
+ const [loading, setLoading] = useState5(false);
1730
+ const [refreshCount, setRefreshCount] = useState5(0);
1731
+ const inFlightRef = useRef6(false);
1732
+ const conversationRef = useRef6(conversation);
1733
+ conversationRef.current = conversation;
1734
+ useEffect6(() => {
1735
+ if (activeTab !== "leaderboard") return;
1736
+ let active = true;
1737
+ const doFetch = async () => {
1738
+ const conv = conversationRef.current;
1739
+ if (!conv || inFlightRef.current) return;
1740
+ inFlightRef.current = true;
1741
+ setLoading(true);
1742
+ try {
1743
+ const result = await conv.getLeaderboard();
1744
+ if (active) setData(result);
1745
+ } catch {
1746
+ } finally {
1747
+ inFlightRef.current = false;
1748
+ if (active) setLoading(false);
1749
+ }
1750
+ };
1751
+ void doFetch();
1752
+ return () => {
1753
+ active = false;
1754
+ };
1755
+ }, [activeTab, refreshCount]);
1756
+ const refresh = useCallback5(() => {
1757
+ setRefreshCount((c) => c + 1);
1758
+ }, []);
1759
+ return { data, loading, refresh };
1760
+ }
1761
+
1618
1762
  // src/liveClock.ts
1619
1763
  function isTreatedLive(state, pollStale) {
1620
1764
  return state?.phase === "live" && !pollStale;
@@ -1634,10 +1778,10 @@ function useEventLog() {
1634
1778
  }
1635
1779
 
1636
1780
  // src/components/ChatFab.tsx
1637
- import { useEffect as useEffect5, useRef as useRef5, useState as useState4 } from "react";
1781
+ import { useEffect as useEffect7, useRef as useRef7, useState as useState7 } from "react";
1638
1782
 
1639
1783
  // src/components/BrandMark.tsx
1640
- import { useState as useState3 } from "react";
1784
+ import { useState as useState6 } from "react";
1641
1785
 
1642
1786
  // src/assets/logo.ts
1643
1787
  var SS_LOGO_DATA_URI = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAjoAAAI6CAYAAAAuSOLAAAAAAXNSR0IArs4c6QAAAJplWElmTU0AKgAAAAgAAwESAAMAAAABAAEAAAExAAIAAAA9AAAAModpAAQAAAABAAAAcAAAAABBZG9iZSBQaG90b3Nob3AgMjYuMTAgKDIwMjUwNzMwLm0uMzE2NiAwN2IxMjM0KSAgKE1hY2ludG9zaCkAAAADoAEAAwAAAAEAAQAAoAIABAAAAAEAAAI6oAMABAAAAAEAAAI6AAAAACwGtVwAAAQwaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJYTVAgQ29yZSA2LjAuMCI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIgogICAgICAgICAgICB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIKICAgICAgICAgICAgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyI+CiAgICAgICAgIDx4bXBNTTpEb2N1bWVudElEPnhtcC5kaWQ6QzBGRTM5NjM5NEJEMTFGMEJGNjZEMjUyN0U0MzU5RUM8L3htcE1NOkRvY3VtZW50SUQ+CiAgICAgICAgIDx4bXBNTTpJbnN0YW5jZUlEPnhtcC5paWQ6QzBGRTM5NjI5NEJEMTFGMEJGNjZEMjUyN0U0MzU5RUM8L3htcE1NOkluc3RhbmNlSUQ+CiAgICAgICAgIDx4bXBNTTpEZXJpdmVkRnJvbSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgIDxzdFJlZjppbnN0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";
@@ -1686,7 +1830,7 @@ function DashboardIcon({ name }) {
1686
1830
  // src/components/BrandMark.tsx
1687
1831
  import { jsx as jsx2 } from "react/jsx-runtime";
1688
1832
  function BrandMark({ logoUrl, className }) {
1689
- const [failed, setFailed] = useState3(false);
1833
+ const [failed, setFailed] = useState6(false);
1690
1834
  if (!logoUrl || failed) return /* @__PURE__ */ jsx2(SsMark, { className });
1691
1835
  return /* @__PURE__ */ jsx2("img", { className, src: logoUrl, alt: "", "aria-hidden": "true", onError: () => setFailed(true) });
1692
1836
  }
@@ -1711,9 +1855,9 @@ function GreetingBubble({ text, onOpen, onDismiss, dismissLabel = "Dismiss" }) {
1711
1855
  import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
1712
1856
  function ChatFab({ label, greeting, popupText, logoUrl, onOpen, onDismissPopup, dismissLabel = "Dismiss", introAllowed = false, onIntroStart }) {
1713
1857
  const bubble = popupText ?? greeting;
1714
- const [intro, setIntro] = useState4(false);
1715
- const armedRef = useRef5(introAllowed);
1716
- useEffect5(() => {
1858
+ const [intro, setIntro] = useState7(false);
1859
+ const armedRef = useRef7(introAllowed);
1860
+ useEffect7(() => {
1717
1861
  if (armedRef.current && bubble) {
1718
1862
  armedRef.current = false;
1719
1863
  setIntro(true);
@@ -1727,10 +1871,10 @@ function ChatFab({ label, greeting, popupText, logoUrl, onOpen, onDismissPopup,
1727
1871
  }
1728
1872
 
1729
1873
  // src/components/ChatPanel.tsx
1730
- import { useEffect as useEffect11, useState as useState19 } from "react";
1874
+ import { useEffect as useEffect14, useState as useState32 } from "react";
1731
1875
 
1732
1876
  // src/components/ChatHeader.tsx
1733
- import { useEffect as useEffect6, useRef as useRef6, useState as useState5 } from "react";
1877
+ import { useEffect as useEffect8, useRef as useRef8, useState as useState8 } from "react";
1734
1878
  import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
1735
1879
  function ChatHeader({
1736
1880
  onClose,
@@ -1742,15 +1886,15 @@ function ChatHeader({
1742
1886
  newConversationLabel = "New conversation",
1743
1887
  moreOptionsLabel = "More options"
1744
1888
  }) {
1745
- const [menuOpen, setMenuOpen] = useState5(false);
1746
- const wrapRef = useRef6(null);
1747
- const kebabRef = useRef6(null);
1748
- const firstItemRef = useRef6(null);
1889
+ const [menuOpen, setMenuOpen] = useState8(false);
1890
+ const wrapRef = useRef8(null);
1891
+ const kebabRef = useRef8(null);
1892
+ const firstItemRef = useRef8(null);
1749
1893
  const hasMenu = !!(canReset && onNewConversation);
1750
- useEffect6(() => {
1894
+ useEffect8(() => {
1751
1895
  if (menuOpen) firstItemRef.current?.focus();
1752
1896
  }, [menuOpen]);
1753
- useEffect6(() => {
1897
+ useEffect8(() => {
1754
1898
  if (!menuOpen) return;
1755
1899
  const onPointer = (e) => {
1756
1900
  if (!wrapRef.current?.contains(e.target)) setMenuOpen(false);
@@ -1806,7 +1950,7 @@ function ChatHeader({
1806
1950
  }
1807
1951
 
1808
1952
  // src/components/MessageList.tsx
1809
- import { useEffect as useEffect10, useRef as useRef8 } from "react";
1953
+ import { useEffect as useEffect12, useRef as useRef10 } from "react";
1810
1954
 
1811
1955
  // src/components/Markdown.tsx
1812
1956
  import ReactMarkdown from "react-markdown";
@@ -1824,7 +1968,7 @@ function Markdown({ text }) {
1824
1968
  }
1825
1969
 
1826
1970
  // src/components/EntityCardList.tsx
1827
- import { useState as useState6 } from "react";
1971
+ import { useState as useState9 } from "react";
1828
1972
  import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
1829
1973
  var MAX_VISIBLE = 3;
1830
1974
  var RECORD_RE = /^(\d+)-(\d+)-(\d+)$/;
@@ -1908,7 +2052,7 @@ function ScopeTabs({ scopes, active, onSelect }) {
1908
2052
  )) });
1909
2053
  }
1910
2054
  function EntityCardItem({ c }) {
1911
- const [active, setActive] = useState6(0);
2055
+ const [active, setActive] = useState9(0);
1912
2056
  const hasBody = c.scopes.length > 0;
1913
2057
  if (!hasBody) {
1914
2058
  return /* @__PURE__ */ jsx7("div", { className: "ss-w-ecard ss-w-ecard-bare", "data-kind": c.kind, children: /* @__PURE__ */ jsx7(CardHeader, { c, showScopeCrest: false }) });
@@ -1922,7 +2066,7 @@ function EntityCardItem({ c }) {
1922
2066
  ] });
1923
2067
  }
1924
2068
  function EntityCardList({ cards, disabled, showLessLabel = "Show less", showMoreLabel = (n) => `Show ${n} more` }) {
1925
- const [expanded, setExpanded] = useState6(false);
2069
+ const [expanded, setExpanded] = useState9(false);
1926
2070
  if (cards.length === 0) return null;
1927
2071
  const visible = expanded ? cards : cards.slice(0, MAX_VISIBLE);
1928
2072
  const overflow = cards.length - MAX_VISIBLE;
@@ -1933,18 +2077,18 @@ function EntityCardList({ cards, disabled, showLessLabel = "Show less", showMore
1933
2077
  }
1934
2078
 
1935
2079
  // src/components/BettingInsightList.tsx
1936
- import { useState as useState10 } from "react";
2080
+ import { useState as useState13 } from "react";
1937
2081
 
1938
2082
  // src/components/AddToSlipButton.tsx
1939
- import { useCallback as useCallback4, useState as useState7 } from "react";
2083
+ import { useCallback as useCallback6, useState as useState10 } from "react";
1940
2084
  import { isAddToSlipResult } from "@sensiblestats/widget-sdk";
1941
2085
 
1942
2086
  // src/components/Toast.tsx
1943
- import { useEffect as useEffect7 } from "react";
2087
+ import { useEffect as useEffect9 } from "react";
1944
2088
  import { jsx as jsx8 } from "react/jsx-runtime";
1945
2089
  var DISMISS_MS = 4e3;
1946
2090
  function Toast({ toast, onDismiss }) {
1947
- useEffect7(() => {
2091
+ useEffect9(() => {
1948
2092
  if (!toast) return;
1949
2093
  const timer = setTimeout(onDismiss, DISMISS_MS);
1950
2094
  return () => clearTimeout(timer);
@@ -1962,10 +2106,10 @@ function withTimeout(value) {
1962
2106
  ]);
1963
2107
  }
1964
2108
  function SlipButton({ selection, shownOdds, marketName, marketDeveloperName, slip, ui }) {
1965
- const [pending, setPending] = useState7(false);
1966
- const [settled, setSettled] = useState7(false);
1967
- const [toast, setToast] = useState7(null);
1968
- const dismiss = useCallback4(() => setToast(null), []);
2109
+ const [pending, setPending] = useState10(false);
2110
+ const [settled, setSettled] = useState10(false);
2111
+ const [toast, setToast] = useState10(null);
2112
+ const dismiss = useCallback6(() => setToast(null), []);
1969
2113
  const log = useEventLog();
1970
2114
  const handler = slip.onAddToSlip;
1971
2115
  if (!ui || !handler || !selection) return null;
@@ -2055,14 +2199,14 @@ function OddsMovementBadge({
2055
2199
  }
2056
2200
 
2057
2201
  // src/components/Crest.tsx
2058
- import { useState as useState8 } from "react";
2202
+ import { useState as useState11 } from "react";
2059
2203
  import { jsx as jsx11 } from "react/jsx-runtime";
2060
2204
  function initials2(name) {
2061
2205
  return (name ?? "").trim().slice(0, 1).toUpperCase() || "?";
2062
2206
  }
2063
2207
  function Crest2({ url, name, kind }) {
2064
2208
  const cls = kind === "comp" ? "ss-w-bi-comp-logo" : "ss-w-bi-crest";
2065
- const [failed, setFailed] = useState8(false);
2209
+ const [failed, setFailed] = useState11(false);
2066
2210
  if (url && !failed) {
2067
2211
  return /* @__PURE__ */ jsx11("img", { className: cls, src: url, alt: "", "aria-hidden": "true", onError: () => setFailed(true) });
2068
2212
  }
@@ -2070,7 +2214,7 @@ function Crest2({ url, name, kind }) {
2070
2214
  }
2071
2215
 
2072
2216
  // src/components/PinToggle.tsx
2073
- import { useCallback as useCallback5, useState as useState9 } from "react";
2217
+ import { useCallback as useCallback7, useState as useState12 } from "react";
2074
2218
  import { jsx as jsx12, jsxs as jsxs8 } from "react/jsx-runtime";
2075
2219
  var PIN_GLYPHS = {
2076
2220
  pin: { viewBox: "0 0 24 24", strokeWidth: 1.4, transform: "scale(1.5)", d: "M9.5 1.5 14.5 6.5 13 8l-.5-.5-3 3 .3 2.2-1.4 1.4L5.6 11.3l-3.3 3.3-1-1 3.3-3.3L1.9 7.5l1.4-1.4 2.2.3 3-3L8 2.9z" },
@@ -2078,8 +2222,8 @@ var PIN_GLYPHS = {
2078
2222
  bookmark: { viewBox: "0 0 24 24", strokeWidth: 2, d: "M7 3h10a1.5 1.5 0 0 1 1.5 1.5V21l-6.5-3.6L5.5 21V4.5A1.5 1.5 0 0 1 7 3z" }
2079
2223
  };
2080
2224
  function PinToggle({ pin, monitor, ui }) {
2081
- const [toast, setToast] = useState9(null);
2082
- const dismiss = useCallback5(() => setToast(null), []);
2225
+ const [toast, setToast] = useState12(null);
2226
+ const dismiss = useCallback7(() => setToast(null), []);
2083
2227
  const log = useEventLog();
2084
2228
  if (!monitor || !monitor.enabled) return null;
2085
2229
  const key = pinKey(pin);
@@ -2139,7 +2283,7 @@ function StatRows({ stats }) {
2139
2283
  ] }, `${s.label}:${s.value}`)) });
2140
2284
  }
2141
2285
  function ScopedStats({ scopes }) {
2142
- const [active, setActive] = useState10(0);
2286
+ const [active, setActive] = useState13(0);
2143
2287
  const current = scopes[active] ?? scopes[0] ?? { key: "", label: "", stats: [] };
2144
2288
  return /* @__PURE__ */ jsxs9("div", { className: "ss-w-bi-scoped", children: [
2145
2289
  /* @__PURE__ */ jsx13("div", { className: "ss-w-bi-scopes", role: "group", children: scopes.map((s, i) => /* @__PURE__ */ jsx13("button", { type: "button", className: "ss-w-bi-chip", "aria-pressed": i === active, onClick: () => setActive(i), children: s.label }, s.key)) }),
@@ -2150,7 +2294,7 @@ function hasStatsContent(it) {
2150
2294
  return !!it.scopes && it.scopes.length >= 2 || it.stats.length > 0;
2151
2295
  }
2152
2296
  function ReasonStrip({ it, ui }) {
2153
- const [open, setOpen] = useState10(false);
2297
+ const [open, setOpen] = useState13(false);
2154
2298
  const log = useEventLog();
2155
2299
  const hasScopes = !!it.scopes && it.scopes.length >= 2;
2156
2300
  const hasStats = hasStatsContent(it);
@@ -2270,7 +2414,7 @@ function BettingInsightList({ insights, ui, slip, monitor }) {
2270
2414
  }
2271
2415
 
2272
2416
  // src/components/MarketOddsCardList.tsx
2273
- import { useState as useState11 } from "react";
2417
+ import { useState as useState14 } from "react";
2274
2418
  import { Fragment as Fragment2, jsx as jsx14, jsxs as jsxs10 } from "react/jsx-runtime";
2275
2419
  function OddsRow({ vm, row, ui, slip, inSlipIds }) {
2276
2420
  const selection = vm.addToSlipEnabled ? marketOddsRowToSlipSelection(vm, row, slip.conversationId) : null;
@@ -2287,7 +2431,7 @@ function OddsRow({ vm, row, ui, slip, inSlipIds }) {
2287
2431
  ] });
2288
2432
  }
2289
2433
  function MarketOddsCard({ vm, ui, slip, monitor, inSlipIds, hideHeader, pinRef }) {
2290
- const [open, setOpen] = useState11(false);
2434
+ const [open, setOpen] = useState14(false);
2291
2435
  const kickoffFallback = vm.kickoffUtc && ui?.bettingKickoff ? ui.bettingKickoff(vm.kickoffUtc) : void 0;
2292
2436
  const kickoff = vm.kickoffLabel ?? (kickoffFallback ? `${kickoffFallback.dayLabel} ${kickoffFallback.time}` : void 0);
2293
2437
  const hasNamedTeams = !!vm.homeTeamName && !!vm.awayTeamName;
@@ -2590,7 +2734,7 @@ function FixtureCard({ card }) {
2590
2734
  }
2591
2735
 
2592
2736
  // src/components/dashboard/CountdownCard.tsx
2593
- import { Fragment as Fragment6, useEffect as useEffect8, useState as useState12 } from "react";
2737
+ import { Fragment as Fragment6, useEffect as useEffect10, useState as useState15 } from "react";
2594
2738
  import { jsx as jsx20, jsxs as jsxs16 } from "react/jsx-runtime";
2595
2739
  var DAY_MS = 864e5;
2596
2740
  function remainingSegments(kickoffUnix, nowMs, withSeconds) {
@@ -2609,12 +2753,12 @@ function remainingSegments(kickoffUnix, nowMs, withSeconds) {
2609
2753
  function CountdownCard({ card }) {
2610
2754
  const { data } = card;
2611
2755
  const unitLabel = { d: data.daysUnit, h: data.hoursUnit, m: data.minutesUnit, s: data.secondsUnit };
2612
- const [nowMs, setNowMs] = useState12(() => Date.now());
2613
- const [reduced] = useState12(
2756
+ const [nowMs, setNowMs] = useState15(() => Date.now());
2757
+ const [reduced] = useState15(
2614
2758
  () => typeof window !== "undefined" && window.matchMedia("(prefers-reduced-motion: reduce)").matches
2615
2759
  );
2616
2760
  const withinDay = data.kickoffUnix * 1e3 - nowMs < DAY_MS;
2617
- useEffect8(() => {
2761
+ useEffect10(() => {
2618
2762
  if (reduced) return;
2619
2763
  const id = window.setInterval(() => setNowMs(Date.now()), withinDay ? 1e3 : 6e4);
2620
2764
  return () => window.clearInterval(id);
@@ -2633,7 +2777,7 @@ function CountdownCard({ card }) {
2633
2777
  }
2634
2778
 
2635
2779
  // src/components/dashboard/InjuriesCard.tsx
2636
- import { useState as useState13 } from "react";
2780
+ import { useState as useState16 } from "react";
2637
2781
  import { jsx as jsx21, jsxs as jsxs17 } from "react/jsx-runtime";
2638
2782
  var SHOWN = 3;
2639
2783
  function ColHead({ name, crestUrl }) {
@@ -2656,7 +2800,7 @@ function InjuryList({ rows, emptyLabel, limit }) {
2656
2800
  }
2657
2801
  function InjuriesCard({ card, ui }) {
2658
2802
  const { data } = card;
2659
- const [expanded, setExpanded] = useState13(false);
2803
+ const [expanded, setExpanded] = useState16(false);
2660
2804
  const hidden = Math.max(0, data.ours.length - SHOWN) + Math.max(0, data.theirs.length - SHOWN);
2661
2805
  const limit = expanded ? void 0 : SHOWN;
2662
2806
  const showMore = ui?.showMore ?? ((n) => `Show ${n} more`);
@@ -2762,7 +2906,7 @@ function LinksCard({ card }) {
2762
2906
  }
2763
2907
 
2764
2908
  // src/components/dashboard/PostMatchResultCard.tsx
2765
- import { useState as useState14 } from "react";
2909
+ import { useState as useState17 } from "react";
2766
2910
  import { jsx as jsx27, jsxs as jsxs23 } from "react/jsx-runtime";
2767
2911
  function initials3(name) {
2768
2912
  return name.trim().slice(0, 3).toUpperCase();
@@ -2772,7 +2916,7 @@ function PostMatchCrest({
2772
2916
  name,
2773
2917
  side
2774
2918
  }) {
2775
- const [failed, setFailed] = useState14(false);
2919
+ const [failed, setFailed] = useState17(false);
2776
2920
  const cls = `ss-w-fandash-postmatch-crest ss-w-fandash-postmatch-crest--${side}`;
2777
2921
  if (url && !failed) {
2778
2922
  return /* @__PURE__ */ jsx27("img", { className: cls, src: url, alt: "", "aria-hidden": "true", onError: () => setFailed(true) });
@@ -2971,10 +3115,10 @@ function RestingFormCard({ card }) {
2971
3115
  }
2972
3116
 
2973
3117
  // src/components/dashboard/LiveScoreCard.tsx
2974
- import { useRef as useRef7, useState as useState16 } from "react";
3118
+ import { useRef as useRef9, useState as useState19 } from "react";
2975
3119
 
2976
3120
  // src/useLiveClock.ts
2977
- import { useEffect as useEffect9, useState as useState15 } from "react";
3121
+ import { useEffect as useEffect11, useState as useState18 } from "react";
2978
3122
  var TICK_MS = 6e4;
2979
3123
  var MAX_LIVE_TICK_MINUTES = 15;
2980
3124
  function computeDisplayMinute(minute, clockRunning, receivedAtMs) {
@@ -2983,10 +3127,10 @@ function computeDisplayMinute(minute, clockRunning, receivedAtMs) {
2983
3127
  return minute + Math.min(Math.max(0, elapsedMinutes), MAX_LIVE_TICK_MINUTES);
2984
3128
  }
2985
3129
  function useLiveClock(minute, clockRunning, receivedAtMs) {
2986
- const [displayMinute, setDisplayMinute] = useState15(
3130
+ const [displayMinute, setDisplayMinute] = useState18(
2987
3131
  () => computeDisplayMinute(minute, clockRunning, receivedAtMs)
2988
3132
  );
2989
- useEffect9(() => {
3133
+ useEffect11(() => {
2990
3134
  setDisplayMinute(computeDisplayMinute(minute, clockRunning, receivedAtMs));
2991
3135
  if (!clockRunning) return;
2992
3136
  const id = window.setInterval(() => {
@@ -3003,7 +3147,7 @@ function initials5(name) {
3003
3147
  return name.trim().slice(0, 3).toUpperCase();
3004
3148
  }
3005
3149
  function LiveCrest({ url, name, side }) {
3006
- const [failed, setFailed] = useState16(false);
3150
+ const [failed, setFailed] = useState19(false);
3007
3151
  const cls = `ss-w-fandash-live-crest ss-w-fandash-live-crest--${side}`;
3008
3152
  if (url && !failed) {
3009
3153
  return /* @__PURE__ */ jsx36("img", { className: cls, src: url, alt: "", "aria-hidden": "true", onError: () => setFailed(true) });
@@ -3022,7 +3166,7 @@ function LiveScoreCard({
3022
3166
  }) {
3023
3167
  const { data } = card;
3024
3168
  const seedKey = `${data.minute}:${data.homeScore}:${data.awayScore}`;
3025
- const seedRef = useRef7(null);
3169
+ const seedRef = useRef9(null);
3026
3170
  if (!seedRef.current || seedRef.current.key !== seedKey) {
3027
3171
  seedRef.current = { key: seedKey, receivedAtMs: Date.now() };
3028
3172
  }
@@ -3062,7 +3206,7 @@ function LiveScoreCard({
3062
3206
  }
3063
3207
 
3064
3208
  // src/components/dashboard/LiveTimelineCard.tsx
3065
- import { useState as useState17 } from "react";
3209
+ import { useState as useState20 } from "react";
3066
3210
  import { jsx as jsx37, jsxs as jsxs33 } from "react/jsx-runtime";
3067
3211
  var SHOWN2 = 3;
3068
3212
  function EventIcon({ type }) {
@@ -3104,7 +3248,7 @@ function EventRow({ e }) {
3104
3248
  ] });
3105
3249
  }
3106
3250
  function LiveTimelineCard({ card, ui }) {
3107
- const [expanded, setExpanded] = useState17(false);
3251
+ const [expanded, setExpanded] = useState20(false);
3108
3252
  const events = card.data.events;
3109
3253
  if (!events || events.length === 0) return null;
3110
3254
  const sorted = [...events].sort((a, b) => b.minute - a.minute);
@@ -3344,11 +3488,11 @@ function turnAnchor(messages) {
3344
3488
  }
3345
3489
  function MessageList({ controller, ui, slip, onDashboardTap, monitor }) {
3346
3490
  const { state, send } = controller;
3347
- const listRef = useRef8(null);
3348
- const endRef = useRef8(null);
3349
- const pinnedRef = useRef8(true);
3350
- const anchoredTurnRef = useRef8(null);
3351
- useEffect10(() => {
3491
+ const listRef = useRef10(null);
3492
+ const endRef = useRef10(null);
3493
+ const pinnedRef = useRef10(true);
3494
+ const anchoredTurnRef = useRef10(null);
3495
+ useEffect12(() => {
3352
3496
  const anchor = turnAnchor(state.messages);
3353
3497
  const list = listRef.current;
3354
3498
  if (anchor && anchor.turnId !== anchoredTurnRef.current) {
@@ -3404,10 +3548,10 @@ function MessageList({ controller, ui, slip, onDashboardTap, monitor }) {
3404
3548
  }
3405
3549
 
3406
3550
  // src/components/ChatInput.tsx
3407
- import { useState as useState18 } from "react";
3551
+ import { useState as useState21 } from "react";
3408
3552
  import { jsx as jsx44, jsxs as jsxs39 } from "react/jsx-runtime";
3409
3553
  function ChatInput({ placeholder, streaming, onSend, onStop, stopLabel = "Stop response", sendLabel = "Send message" }) {
3410
- const [value, setValue] = useState18("");
3554
+ const [value, setValue] = useState21("");
3411
3555
  const submit = () => {
3412
3556
  const t = value.trim();
3413
3557
  if (!t) return;
@@ -3428,12 +3572,16 @@ function ChatInput({ placeholder, streaming, onSend, onStop, stopLabel = "Stop r
3428
3572
 
3429
3573
  // src/components/TabBar.tsx
3430
3574
  import { jsx as jsx45, jsxs as jsxs40 } from "react/jsx-runtime";
3431
- function TabBar({ monitor, ui, matchCount, oddsCount, todayCount, hasToday }) {
3575
+ function TabBar({ monitor, ui, matchCount, oddsCount, todayCount, hasToday, gamesEnabled }) {
3432
3576
  const tabs = [
3433
3577
  { tab: "chat", label: ui.tabChat, count: 0, dot: monitor.chatDot },
3434
3578
  ...hasToday ? [{ tab: "today", label: ui.tabToday, count: todayCount, dot: monitor.todayDot }] : [],
3435
3579
  ...matchCount > 0 ? [{ tab: "following", label: ui.tabFollowing, count: matchCount, dot: monitor.matchesDot }] : [],
3436
- ...oddsCount > 0 ? [{ tab: "odds", label: ui.tabOdds, count: oddsCount, dot: monitor.oddsDot }] : []
3580
+ ...oddsCount > 0 ? [{ tab: "odds", label: ui.tabOdds, count: oddsCount, dot: monitor.oddsDot }] : [],
3581
+ ...gamesEnabled ? [
3582
+ { tab: "games", label: ui.tabGames, count: 0, dot: false },
3583
+ { tab: "leaderboard", label: ui.tabLeaderboard, count: 0, dot: false }
3584
+ ] : []
3437
3585
  ];
3438
3586
  if (tabs.length < 2) return null;
3439
3587
  return /* @__PURE__ */ jsx45("div", { className: "ss-w-tabs", role: "tablist", children: tabs.map(({ tab, label, count, dot }) => {
@@ -3542,9 +3690,28 @@ function isPromoted(row, promotedPins) {
3542
3690
  function formatTime(iso) {
3543
3691
  return new Date(iso).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
3544
3692
  }
3693
+ function groupScorers(goals, ownGoalLabel) {
3694
+ const order = [];
3695
+ const minutesByPlayer = /* @__PURE__ */ new Map();
3696
+ for (const g of goals) {
3697
+ const name = g.player ?? "";
3698
+ const minute = g.ownGoal ? `${g.minuteLabel} (${ownGoalLabel})` : g.minuteLabel;
3699
+ if (!minutesByPlayer.has(name)) {
3700
+ minutesByPlayer.set(name, []);
3701
+ order.push(name);
3702
+ }
3703
+ minutesByPlayer.get(name).push(minute);
3704
+ }
3705
+ return order.map((name) => {
3706
+ const minutes = minutesByPlayer.get(name).join(", ");
3707
+ return { player: name, label: name ? `${name} ${minutes}` : minutes };
3708
+ });
3709
+ }
3545
3710
  function MonitorMatchCard({ match, promotedPins, monitor, ui, slip }) {
3546
3711
  const live = match.phase === "live";
3547
- const scorers = match.events.filter((e) => e.type === "goal");
3712
+ const goals = match.events.filter((e) => e.type === "goal");
3713
+ const homeScorers = groupScorers(goals.filter((e) => e.side === "home"), ui.ownGoalLabel);
3714
+ const awayScorers = groupScorers(goals.filter((e) => e.side === "away"), ui.ownGoalLabel);
3548
3715
  const promotedRows = match.statRows.filter((row) => isPromoted(row, promotedPins));
3549
3716
  const otherRows = match.statRows.filter((row) => !isPromoted(row, promotedPins));
3550
3717
  const orderedRows = [...promotedRows, ...otherRows];
@@ -3580,7 +3747,11 @@ function MonitorMatchCard({ match, promotedPins, monitor, ui, slip }) {
3580
3747
  /* @__PURE__ */ jsx47("span", { className: "ss-w-mon-name", children: match.awayTeamName })
3581
3748
  ] })
3582
3749
  ] }),
3583
- scorers.length > 0 && /* @__PURE__ */ jsx47("div", { className: "ss-w-mon-scorers", children: scorers.map((e) => `${e.player ?? ""} ${e.minuteLabel}`).join(", ") }),
3750
+ (homeScorers.length > 0 || awayScorers.length > 0) && /* @__PURE__ */ jsxs42("div", { className: "ss-w-mon-scorers", children: [
3751
+ /* @__PURE__ */ jsx47("ul", { className: "ss-w-mon-scorers-col ss-w-mon-scorers-home", children: homeScorers.map((s, i) => /* @__PURE__ */ jsx47("li", { children: s.label }, `${s.player}-${i}`)) }),
3752
+ /* @__PURE__ */ jsx47("span", { className: "ss-w-mon-scorers-ball", "aria-hidden": "true", children: "\u26BD" }),
3753
+ /* @__PURE__ */ jsx47("ul", { className: "ss-w-mon-scorers-col ss-w-mon-scorers-away", children: awayScorers.map((s, i) => /* @__PURE__ */ jsx47("li", { children: s.label }, `${s.player}-${i}`)) })
3754
+ ] }),
3584
3755
  /* @__PURE__ */ jsx47("div", { className: "ss-w-mon-stats", children: orderedRows.map((row) => {
3585
3756
  const total = row.homeNum + row.awayNum;
3586
3757
  const homePct = total > 0 ? row.homeNum / total * 75 : 0;
@@ -3802,12 +3973,1604 @@ function TodayPanel({ discovery, ui, monitor }) {
3802
3973
  ] });
3803
3974
  }
3804
3975
 
3976
+ // src/components/GamesPanel.tsx
3977
+ import { useState as useState30 } from "react";
3978
+
3979
+ // src/components/GamesLoginWall.tsx
3980
+ import { jsx as jsx52 } from "react/jsx-runtime";
3981
+ function GamesLoginWall({ ui }) {
3982
+ return /* @__PURE__ */ jsx52("div", { className: "ss-w-mon-list", children: /* @__PURE__ */ jsx52("div", { className: "ss-w-games-wall", children: /* @__PURE__ */ jsx52("p", { children: ui.gamesLoginRequired }) }) });
3983
+ }
3984
+
3985
+ // src/components/GameTile.tsx
3986
+ import { Fragment as Fragment8, jsx as jsx53, jsxs as jsxs47 } from "react/jsx-runtime";
3987
+ var GAME_ICONS = {
3988
+ "mystery-tiger": "\u{1F42F}",
3989
+ "daily-quiz": "\u{1F9E0}",
3990
+ "career-path": "\u26BD",
3991
+ "beat-the-grid": "\u{1F3AF}",
3992
+ "guess-xi": "\u{1F4CB}",
3993
+ "head-of-league": "\u{1F3C6}"
3994
+ };
3995
+ function gameIcon(game) {
3996
+ return GAME_ICONS[game.gameId] ?? (game.kind === "fixture" ? "\u{1F4C5}" : "\u{1F3AE}");
3997
+ }
3998
+ function formatCountdown(lockAtUtc) {
3999
+ const diff = new Date(lockAtUtc).getTime() - Date.now();
4000
+ if (diff <= 0) return null;
4001
+ const totalMins = Math.floor(diff / 6e4);
4002
+ const hours = Math.floor(totalMins / 60);
4003
+ const mins = totalMins % 60;
4004
+ if (hours > 0) return `${hours}h ${mins}m`;
4005
+ return `${mins}m`;
4006
+ }
4007
+ function tileStatusLabel(game, ui) {
4008
+ switch (game.status) {
4009
+ case "available":
4010
+ return ui.gamePlay;
4011
+ case "in_progress":
4012
+ return ui.gameResume;
4013
+ case "played":
4014
+ case "graded": {
4015
+ const pts = game.score ?? 0;
4016
+ return `+${pts.toLocaleString("en")}`;
4017
+ }
4018
+ case "locked":
4019
+ return ui.gameLocked;
4020
+ case "voided":
4021
+ return ui.gameVoided;
4022
+ default:
4023
+ return "";
4024
+ }
4025
+ }
4026
+ var DISABLED_STATUSES = /* @__PURE__ */ new Set(["locked", "voided"]);
4027
+ function GameTile({
4028
+ game,
4029
+ onOpen,
4030
+ ui
4031
+ }) {
4032
+ const disabled = DISABLED_STATUSES.has(game.status);
4033
+ const statusLabel = tileStatusLabel(game, ui);
4034
+ const countdown = game.kind === "fixture" && game.lockAtUtc ? formatCountdown(game.lockAtUtc) : null;
4035
+ const statusClass = `ss-w-tile-status ss-w-tile-status--${game.status}`;
4036
+ const inner = /* @__PURE__ */ jsxs47(Fragment8, { children: [
4037
+ /* @__PURE__ */ jsx53("span", { className: "ss-w-tile-icon", children: gameIcon(game) }),
4038
+ /* @__PURE__ */ jsx53("span", { className: "ss-w-tile-title", children: game.title ?? game.gameId }),
4039
+ countdown !== null ? /* @__PURE__ */ jsx53("span", { className: statusClass, "data-testid": "tile-countdown", children: countdown }) : /* @__PURE__ */ jsx53("span", { className: statusClass, children: statusLabel }),
4040
+ /* @__PURE__ */ jsx53("span", { className: `ss-w-tile-chip ss-w-tile-chip--${game.ranked ? "skill" : "fun"}`, children: game.ranked ? "Skill" : "For fun" })
4041
+ ] });
4042
+ if (disabled) {
4043
+ return /* @__PURE__ */ jsx53("div", { className: "ss-w-tile", "data-disabled": true, children: inner });
4044
+ }
4045
+ return /* @__PURE__ */ jsx53(
4046
+ "button",
4047
+ {
4048
+ type: "button",
4049
+ className: "ss-w-tile",
4050
+ onClick: () => onOpen(game),
4051
+ children: inner
4052
+ }
4053
+ );
4054
+ }
4055
+
4056
+ // src/components/GamesHub.tsx
4057
+ import { jsx as jsx54, jsxs as jsxs48 } from "react/jsx-runtime";
4058
+ function GamesHub({
4059
+ games,
4060
+ weeklyPrize,
4061
+ streak,
4062
+ weeklyRank,
4063
+ onOpen,
4064
+ ui
4065
+ }) {
4066
+ const showPrize = weeklyPrize || streak !== void 0 || weeklyRank !== void 0;
4067
+ return /* @__PURE__ */ jsxs48("div", { className: "ss-w-games-hub", children: [
4068
+ showPrize && /* @__PURE__ */ jsxs48("div", { className: "ss-w-prize", children: [
4069
+ /* @__PURE__ */ jsx54("span", { className: "ss-w-prize-icon", children: "\u{1F3C6}" }),
4070
+ /* @__PURE__ */ jsxs48("div", { className: "ss-w-prize-body", children: [
4071
+ weeklyPrize && /* @__PURE__ */ jsx54("span", { className: "ss-w-prize-text", children: weeklyPrize }),
4072
+ (streak !== void 0 || weeklyRank !== void 0) && /* @__PURE__ */ jsxs48("div", { className: "ss-w-g-chips", children: [
4073
+ streak !== void 0 && /* @__PURE__ */ jsxs48("span", { className: "ss-w-g-chip ss-w-g-chip--streak", children: [
4074
+ "\u{1F525} ",
4075
+ streak
4076
+ ] }),
4077
+ weeklyRank !== void 0 && /* @__PURE__ */ jsxs48("span", { className: "ss-w-g-chip ss-w-g-chip--rank", children: [
4078
+ "#",
4079
+ weeklyRank
4080
+ ] })
4081
+ ] })
4082
+ ] })
4083
+ ] }),
4084
+ /* @__PURE__ */ jsx54("div", { className: "ss-w-gmatrix", children: games.map((g) => /* @__PURE__ */ jsx54(GameTile, { game: g, onOpen, ui }, `${g.gameId}-${g.gameDay}`)) })
4085
+ ] });
4086
+ }
4087
+
4088
+ // src/components/GameScreenHost.tsx
4089
+ import { useEffect as useEffect13, useRef as useRef12, useState as useState29 } from "react";
4090
+
4091
+ // src/useGamePlay.ts
4092
+ import { useCallback as useCallback8, useRef as useRef11, useState as useState22 } from "react";
4093
+ function toSubmitResult(payload) {
4094
+ return {
4095
+ // 'pending' means the play is recorded but awaiting resolution (fixture games)
4096
+ alreadyPlayed: payload.status === "played" || payload.status === "graded" || payload.status === "pending",
4097
+ score: payload.score,
4098
+ isCorrect: payload.isCorrect,
4099
+ clientStateJson: payload.clientStateJson,
4100
+ attemptsUsed: payload.attemptsUsed
4101
+ };
4102
+ }
4103
+ function useGamePlay(conversation, { gameId, gameDay, fixtureId, refresh }) {
4104
+ const [result, setResult] = useState22(null);
4105
+ const [submitting, setSubmitting] = useState22(false);
4106
+ const [rawStatus, setRawStatus] = useState22(null);
4107
+ const inFlightRef = useRef11(false);
4108
+ const convRef = useRef11(conversation);
4109
+ convRef.current = conversation;
4110
+ const optsRef = useRef11({ gameId, gameDay, fixtureId, refresh });
4111
+ optsRef.current = { gameId, gameDay, fixtureId, refresh };
4112
+ const submit = useCallback8(async (answerJson) => {
4113
+ const conv = convRef.current;
4114
+ if (!conv || inFlightRef.current) return;
4115
+ inFlightRef.current = true;
4116
+ setSubmitting(true);
4117
+ try {
4118
+ const opts = optsRef.current;
4119
+ const playResult = await conv.postPlay(opts.gameId, answerJson, opts.gameDay, opts.fixtureId);
4120
+ if (playResult !== null) {
4121
+ setResult(playResult);
4122
+ if (playResult.pointsDelta != null) {
4123
+ opts.refresh?.();
4124
+ }
4125
+ }
4126
+ } catch {
4127
+ } finally {
4128
+ inFlightRef.current = false;
4129
+ setSubmitting(false);
4130
+ }
4131
+ }, []);
4132
+ const hydrate = useCallback8(() => {
4133
+ const conv = convRef.current;
4134
+ if (!conv) return;
4135
+ const opts = optsRef.current;
4136
+ void (async () => {
4137
+ try {
4138
+ const payload = await conv.getGameResult(opts.gameId, opts.fixtureId, opts.gameDay);
4139
+ if (payload !== null) {
4140
+ setResult(toSubmitResult(payload));
4141
+ setRawStatus(payload.status);
4142
+ }
4143
+ } catch {
4144
+ }
4145
+ })();
4146
+ }, []);
4147
+ return { result, submitting, submit, hydrate, rawStatus };
4148
+ }
4149
+
4150
+ // src/components/games/MysteryTigerGame.tsx
4151
+ import { useState as useState23, useId as useId2 } from "react";
4152
+ import { Fragment as Fragment9, jsx as jsx55, jsxs as jsxs49 } from "react/jsx-runtime";
4153
+ function parseClientState(json) {
4154
+ if (!json) return null;
4155
+ try {
4156
+ return JSON.parse(json);
4157
+ } catch {
4158
+ return null;
4159
+ }
4160
+ }
4161
+ var ATTR_LABELS = {
4162
+ position: "Pos",
4163
+ nationality: "Nat",
4164
+ age: "Age",
4165
+ shirtNumber: "Kit",
4166
+ apps: "Apps"
4167
+ };
4168
+ var ATTR_KEYS = [
4169
+ "position",
4170
+ "nationality",
4171
+ "age",
4172
+ "shirtNumber",
4173
+ "apps"
4174
+ ];
4175
+ function MysteryTigerGame({
4176
+ config,
4177
+ result,
4178
+ submitting,
4179
+ onSubmit
4180
+ }) {
4181
+ const [query, setQuery] = useState23("");
4182
+ const inputId = useId2();
4183
+ const clientState = parseClientState(result?.clientStateJson);
4184
+ const alreadyGuessedIds = new Set(
4185
+ clientState?.guessResults.map((g) => g.playerId) ?? []
4186
+ );
4187
+ const isOver = result?.alreadyPlayed === true || clientState?.solved === true || clientState?.failed === true;
4188
+ const filtered = config && !isOver ? config.squadPlayers.filter(
4189
+ (p) => !alreadyGuessedIds.has(p.id) && p.name.toLowerCase().includes(query.toLowerCase())
4190
+ ) : [];
4191
+ function handleSelect(playerId) {
4192
+ if (!config || isOver || submitting) return;
4193
+ const prevGuesses = clientState?.guessResults.map((g) => g.playerId) ?? [];
4194
+ const newGuesses = [...prevGuesses, playerId];
4195
+ setQuery("");
4196
+ onSubmit(JSON.stringify({ guesses: newGuesses }));
4197
+ }
4198
+ return /* @__PURE__ */ jsxs49("div", { className: "ss-w-gt", "data-testid": "game-screen-mystery-tiger", children: [
4199
+ !config && /* @__PURE__ */ jsx55("div", { className: "ss-w-gscreen-body", children: "Loading\u2026" }),
4200
+ config && /* @__PURE__ */ jsxs49(Fragment9, { children: [
4201
+ isOver && clientState && /* @__PURE__ */ jsxs49("div", { className: `ss-w-gt-banner ss-w-gt-banner--${clientState.solved ? "solved" : "failed"}`, children: [
4202
+ /* @__PURE__ */ jsx55("div", { className: "ss-w-gt-banner-label", children: clientState.solved ? "\u{1F42F} You found them!" : "\u{1F614} Better luck tomorrow" }),
4203
+ clientState.revealedPlayerName && /* @__PURE__ */ jsx55("div", { className: "ss-w-gt-banner-name", children: clientState.revealedPlayerName })
4204
+ ] }),
4205
+ !isOver && /* @__PURE__ */ jsxs49("div", { className: "ss-w-gtta", children: [
4206
+ /* @__PURE__ */ jsx55(
4207
+ "input",
4208
+ {
4209
+ id: inputId,
4210
+ type: "text",
4211
+ role: "textbox",
4212
+ className: "ss-w-gtta-i",
4213
+ placeholder: "Search squad players\u2026",
4214
+ value: query,
4215
+ disabled: submitting || isOver,
4216
+ onChange: (e) => setQuery(e.target.value),
4217
+ autoComplete: "off",
4218
+ "aria-label": "Search for a player",
4219
+ "aria-autocomplete": "list"
4220
+ }
4221
+ ),
4222
+ query.length > 0 && filtered.length > 0 && /* @__PURE__ */ jsx55("div", { className: "ss-w-gtta-drop", role: "listbox", children: filtered.map((p) => /* @__PURE__ */ jsx55(
4223
+ "div",
4224
+ {
4225
+ className: "ss-w-gtta-opt",
4226
+ role: "option",
4227
+ "aria-selected": false,
4228
+ onClick: () => handleSelect(p.id),
4229
+ onKeyDown: (e) => {
4230
+ if (e.key === "Enter") handleSelect(p.id);
4231
+ },
4232
+ tabIndex: 0,
4233
+ children: p.name
4234
+ },
4235
+ p.id
4236
+ )) })
4237
+ ] }),
4238
+ clientState && clientState.guessResults.length > 0 && /* @__PURE__ */ jsxs49("div", { children: [
4239
+ /* @__PURE__ */ jsxs49("div", { className: "ss-w-gthdr", children: [
4240
+ /* @__PURE__ */ jsx55("div", { className: "ss-w-gthdr-c ss-w-gthdr-c--name", children: "Player" }),
4241
+ ATTR_KEYS.map((key) => /* @__PURE__ */ jsx55("div", { className: "ss-w-gthdr-c", children: ATTR_LABELS[key] }, key))
4242
+ ] }),
4243
+ /* @__PURE__ */ jsx55("div", { className: "ss-w-gtrows", children: clientState.guessResults.map((gr, i) => {
4244
+ const player = config.squadPlayers.find((p) => p.id === gr.playerId);
4245
+ return /* @__PURE__ */ jsxs49("div", { className: "ss-w-gtrow", children: [
4246
+ /* @__PURE__ */ jsx55("div", { className: "ss-w-gtrow-nm", children: player?.name ?? `#${gr.playerId}` }),
4247
+ ATTR_KEYS.map((key) => {
4248
+ const v = gr[key];
4249
+ return /* @__PURE__ */ jsx55(
4250
+ "div",
4251
+ {
4252
+ className: `ss-w-gtile ss-w-gtile--${v.verdict}`,
4253
+ "data-testid": `verdict-${key}-${i}`,
4254
+ "data-verdict": v.verdict,
4255
+ "aria-label": `${ATTR_LABELS[key]}: ${v.verdict}${v.direction ? ` ${v.direction}` : ""}`,
4256
+ children: v.direction && /* @__PURE__ */ jsx55("span", { className: "ss-w-gtile-dir", "aria-hidden": "true", children: v.direction === "up" ? "\u2191" : "\u2193" })
4257
+ },
4258
+ key
4259
+ );
4260
+ })
4261
+ ] }, gr.playerId);
4262
+ }) })
4263
+ ] }),
4264
+ clientState?.hintLine && !isOver && /* @__PURE__ */ jsx55("div", { className: "ss-w-gt-hint", children: clientState.hintLine }),
4265
+ !isOver && clientState && /* @__PURE__ */ jsxs49("div", { className: "ss-w-gt-hint", children: [
4266
+ clientState.guessesRemaining,
4267
+ " guess",
4268
+ clientState.guessesRemaining !== 1 ? "es" : "",
4269
+ " remaining"
4270
+ ] })
4271
+ ] })
4272
+ ] });
4273
+ }
4274
+
4275
+ // src/components/games/HigherOrLowerGame.tsx
4276
+ import { Fragment as Fragment10, jsx as jsx56, jsxs as jsxs50 } from "react/jsx-runtime";
4277
+ function parseClientState2(json) {
4278
+ if (!json) return null;
4279
+ try {
4280
+ return JSON.parse(json);
4281
+ } catch {
4282
+ return null;
4283
+ }
4284
+ }
4285
+ function AnsweredRow({
4286
+ answered,
4287
+ pair
4288
+ }) {
4289
+ const cls = `ss-w-hlrrow ss-w-hlrrow--${answered.wasCorrect ? "correct" : "wrong"}`;
4290
+ const icon = answered.wasCorrect ? "\u2713" : "\u2717";
4291
+ return /* @__PURE__ */ jsxs50("div", { className: cls, children: [
4292
+ /* @__PURE__ */ jsxs50("span", { className: "ss-w-hlrrow-names", children: [
4293
+ pair?.playerAName ?? "?",
4294
+ " vs ",
4295
+ pair?.playerBName ?? "?"
4296
+ ] }),
4297
+ /* @__PURE__ */ jsx56("span", { className: "ss-w-hlrrow-pick", children: answered.pick }),
4298
+ /* @__PURE__ */ jsx56("span", { className: "ss-w-hlrrow-icon", children: icon })
4299
+ ] });
4300
+ }
4301
+ function HigherOrLowerGame({
4302
+ config,
4303
+ result,
4304
+ submitting,
4305
+ onSubmit
4306
+ }) {
4307
+ const clientState = parseClientState2(result?.clientStateJson);
4308
+ const answeredCount = clientState?.answeredPairs.length ?? 0;
4309
+ const runEndedWrong = clientState?.answeredPairs.some((p) => !p.wasCorrect) ?? false;
4310
+ const allPairsAnswered = config != null && answeredCount >= config.pairs.length;
4311
+ const isOver = result?.alreadyPlayed === true || runEndedWrong || allPairsAnswered;
4312
+ const currentPair = config && !isOver ? config.pairs[answeredCount] ?? null : null;
4313
+ function handlePick(pick) {
4314
+ if (!config || isOver || submitting || !currentPair) return;
4315
+ const prevAnswers = clientState?.answeredPairs.map((p) => ({ pairIndex: p.pairIndex, pick: p.pick })) ?? [];
4316
+ const newAnswers = [...prevAnswers, { pairIndex: currentPair.pairIndex, pick }];
4317
+ onSubmit(JSON.stringify({ answers: newAnswers }));
4318
+ }
4319
+ return /* @__PURE__ */ jsxs50("div", { className: "ss-w-hl", "data-testid": "game-screen-higher-or-lower", children: [
4320
+ !config && /* @__PURE__ */ jsx56("div", { className: "ss-w-gscreen-body", children: "Loading\u2026" }),
4321
+ config && /* @__PURE__ */ jsxs50(Fragment10, { children: [
4322
+ /* @__PURE__ */ jsxs50("div", { className: "ss-w-hlctx", children: [
4323
+ /* @__PURE__ */ jsx56("span", { className: "ss-w-hlctx-fam", children: config.statLabel }),
4324
+ /* @__PURE__ */ jsx56("span", { className: "ss-w-hlctx-szn", children: config.seasonLabel })
4325
+ ] }),
4326
+ currentPair && /* @__PURE__ */ jsxs50("div", { className: "ss-w-hlpair", children: [
4327
+ /* @__PURE__ */ jsxs50("div", { className: "ss-w-hlpc", children: [
4328
+ /* @__PURE__ */ jsx56("div", { className: "ss-w-hlpc-name", children: currentPair.playerAName }),
4329
+ /* @__PURE__ */ jsx56("div", { className: "ss-w-hlpc-val", children: currentPair.playerAValue })
4330
+ ] }),
4331
+ /* @__PURE__ */ jsxs50("div", { className: "ss-w-hlpc ss-w-hlpc--b", children: [
4332
+ /* @__PURE__ */ jsx56("div", { className: "ss-w-hlpc-name", children: currentPair.playerBName }),
4333
+ /* @__PURE__ */ jsx56("div", { className: "ss-w-hlpc-val ss-w-hlpc-val--hidden", children: "?" })
4334
+ ] })
4335
+ ] }),
4336
+ !isOver && currentPair && /* @__PURE__ */ jsxs50("div", { className: "ss-w-hlbtns", children: [
4337
+ /* @__PURE__ */ jsx56(
4338
+ "button",
4339
+ {
4340
+ type: "button",
4341
+ className: "ss-w-hlbtn",
4342
+ disabled: submitting,
4343
+ onClick: () => handlePick("higher"),
4344
+ children: "Higher"
4345
+ }
4346
+ ),
4347
+ /* @__PURE__ */ jsx56(
4348
+ "button",
4349
+ {
4350
+ type: "button",
4351
+ className: "ss-w-hlbtn",
4352
+ disabled: submitting,
4353
+ onClick: () => handlePick("lower"),
4354
+ children: "Lower"
4355
+ }
4356
+ )
4357
+ ] }),
4358
+ clientState && clientState.answeredPairs.length > 0 && /* @__PURE__ */ jsx56("div", { className: "ss-w-hlresults", children: clientState.answeredPairs.map((answered) => {
4359
+ const pair = config.pairs.find((p) => p.pairIndex === answered.pairIndex);
4360
+ const vCls = `ss-w-hlpc-val ss-w-hlpc-val--${answered.wasCorrect ? "correct" : "wrong"}`;
4361
+ const badgeCls = `ss-w-hlpc-badge ss-w-hlpc-badge--${answered.wasCorrect ? "correct" : "wrong"}`;
4362
+ return /* @__PURE__ */ jsxs50("div", { className: "ss-w-hlrrow", children: [
4363
+ /* @__PURE__ */ jsxs50("div", { className: "ss-w-hlpair", children: [
4364
+ /* @__PURE__ */ jsxs50("div", { className: "ss-w-hlpc", children: [
4365
+ /* @__PURE__ */ jsx56("div", { className: "ss-w-hlpc-name", children: pair?.playerAName ?? "?" }),
4366
+ /* @__PURE__ */ jsx56("div", { className: "ss-w-hlpc-val", children: pair?.playerAValue })
4367
+ ] }),
4368
+ /* @__PURE__ */ jsxs50("div", { className: "ss-w-hlpc ss-w-hlpc--b", children: [
4369
+ /* @__PURE__ */ jsx56("div", { className: "ss-w-hlpc-name", children: pair?.playerBName ?? "?" }),
4370
+ /* @__PURE__ */ jsx56("div", { className: vCls, children: answered.playerBValue }),
4371
+ /* @__PURE__ */ jsx56("div", { className: badgeCls, children: answered.wasCorrect ? "\u2713" : "\u2717" })
4372
+ ] })
4373
+ ] }),
4374
+ /* @__PURE__ */ jsx56(AnsweredRow, { answered, pair })
4375
+ ] }, answered.pairIndex);
4376
+ }) })
4377
+ ] })
4378
+ ] });
4379
+ }
4380
+
4381
+ // src/components/games/CareerPathGame.tsx
4382
+ import { useState as useState24, useId as useId3 } from "react";
4383
+ import { Fragment as Fragment11, jsx as jsx57, jsxs as jsxs51 } from "react/jsx-runtime";
4384
+ function parseClientState3(json) {
4385
+ if (!json) return null;
4386
+ try {
4387
+ return JSON.parse(json);
4388
+ } catch {
4389
+ return null;
4390
+ }
4391
+ }
4392
+ function SpellYear({ spell }) {
4393
+ const parts = [];
4394
+ if (spell.startYear) parts.push(String(spell.startYear));
4395
+ if (spell.endYear) parts.push(String(spell.endYear));
4396
+ if (parts.length === 0) return null;
4397
+ return /* @__PURE__ */ jsx57("span", { className: "ss-w-cpath-spell-yr", children: parts.join(" \u2013 ") });
4398
+ }
4399
+ function ClubSpellCard({ spell }) {
4400
+ return /* @__PURE__ */ jsxs51("div", { className: `ss-w-cpath-club${spell.isLoan ? " ss-w-cpath-club--loan" : ""}`, children: [
4401
+ spell.crestUrl ? /* @__PURE__ */ jsx57(
4402
+ "img",
4403
+ {
4404
+ src: spell.crestUrl,
4405
+ alt: spell.clubName,
4406
+ className: "ss-w-cpath-crest",
4407
+ loading: "lazy"
4408
+ }
4409
+ ) : /* @__PURE__ */ jsx57("div", { className: "ss-w-cpath-crest ss-w-cpath-crest--fallback", "aria-hidden": "true" }),
4410
+ /* @__PURE__ */ jsxs51("div", { className: "ss-w-cpath-club-info", children: [
4411
+ /* @__PURE__ */ jsx57("span", { className: "ss-w-cpath-club-name", children: spell.clubName }),
4412
+ /* @__PURE__ */ jsx57(SpellYear, { spell }),
4413
+ spell.isLoan && /* @__PURE__ */ jsx57("span", { className: "ss-w-cpath-loan-badge", children: "Loan" })
4414
+ ] })
4415
+ ] });
4416
+ }
4417
+ function CareerPathGame({
4418
+ config,
4419
+ result,
4420
+ submitting,
4421
+ onSubmit
4422
+ }) {
4423
+ const [query, setQuery] = useState24("");
4424
+ const inputId = useId3();
4425
+ const clientState = parseClientState3(result?.clientStateJson);
4426
+ const alreadyGuessedIds = new Set(
4427
+ clientState?.guessResults.map((g) => g.playerId) ?? []
4428
+ );
4429
+ const isOver = result?.alreadyPlayed === true || clientState?.solved === true || clientState?.failed === true;
4430
+ const visiblePath = clientState?.visiblePath ?? config?.initialPath ?? [];
4431
+ const filtered = config && !isOver ? config.typeaheadPool.filter(
4432
+ (p) => !alreadyGuessedIds.has(p.id) && p.name.toLowerCase().includes(query.toLowerCase())
4433
+ ) : [];
4434
+ function handleSelect(playerId) {
4435
+ if (!config || isOver || submitting) return;
4436
+ const prevGuesses = clientState?.guessResults.map((g) => g.playerId) ?? [];
4437
+ const newGuesses = [...prevGuesses, playerId];
4438
+ setQuery("");
4439
+ onSubmit(JSON.stringify({ guesses: newGuesses }));
4440
+ }
4441
+ return /* @__PURE__ */ jsxs51("div", { className: "ss-w-cpath", "data-testid": "game-screen-career-path", children: [
4442
+ !config && /* @__PURE__ */ jsx57("div", { className: "ss-w-gscreen-body", children: "Loading\u2026" }),
4443
+ config && /* @__PURE__ */ jsxs51(Fragment11, { children: [
4444
+ /* @__PURE__ */ jsxs51("div", { className: "ss-w-cpath-ctx", children: [
4445
+ /* @__PURE__ */ jsx57("span", { className: "ss-w-cpath-ctx-label", children: "Career clubs" }),
4446
+ /* @__PURE__ */ jsxs51("span", { className: "ss-w-cpath-ctx-count", children: [
4447
+ config.totalClubs,
4448
+ " clubs total"
4449
+ ] })
4450
+ ] }),
4451
+ /* @__PURE__ */ jsxs51("div", { className: "ss-w-cpath-path", children: [
4452
+ visiblePath.map((spell, i) => /* @__PURE__ */ jsx57(ClubSpellCard, { spell }, `${spell.clubName}-${i}`)),
4453
+ (clientState?.totalClubs ?? config.totalClubs) > visiblePath.length && /* @__PURE__ */ jsxs51("div", { className: "ss-w-cpath-hidden", children: [
4454
+ "+",
4455
+ (clientState?.totalClubs ?? config.totalClubs) - visiblePath.length,
4456
+ " more clubs hidden"
4457
+ ] })
4458
+ ] }),
4459
+ isOver && clientState && /* @__PURE__ */ jsxs51("div", { className: `ss-w-cpath-banner ss-w-cpath-banner--${clientState.solved ? "solved" : "failed"}`, children: [
4460
+ /* @__PURE__ */ jsx57("div", { className: "ss-w-cpath-banner-label", children: clientState.solved ? "Career traced!" : "Better luck tomorrow" }),
4461
+ clientState.revealedPlayerName && /* @__PURE__ */ jsx57("div", { className: "ss-w-cpath-banner-name", children: clientState.revealedPlayerName })
4462
+ ] }),
4463
+ !isOver && /* @__PURE__ */ jsxs51("div", { className: "ss-w-gtta", children: [
4464
+ /* @__PURE__ */ jsx57(
4465
+ "input",
4466
+ {
4467
+ id: inputId,
4468
+ type: "text",
4469
+ role: "textbox",
4470
+ className: "ss-w-gtta-i",
4471
+ placeholder: "Search players\u2026",
4472
+ value: query,
4473
+ disabled: submitting || isOver,
4474
+ onChange: (e) => setQuery(e.target.value),
4475
+ autoComplete: "off",
4476
+ "aria-label": "Search for a player",
4477
+ "aria-autocomplete": "list"
4478
+ }
4479
+ ),
4480
+ query.length > 0 && filtered.length > 0 && /* @__PURE__ */ jsx57("div", { className: "ss-w-gtta-drop", role: "listbox", children: filtered.map((p) => /* @__PURE__ */ jsx57(
4481
+ "div",
4482
+ {
4483
+ className: "ss-w-gtta-opt",
4484
+ role: "option",
4485
+ "aria-selected": false,
4486
+ onClick: () => handleSelect(p.id),
4487
+ onKeyDown: (e) => {
4488
+ if (e.key === "Enter") handleSelect(p.id);
4489
+ },
4490
+ tabIndex: 0,
4491
+ children: p.name
4492
+ },
4493
+ p.id
4494
+ )) })
4495
+ ] }),
4496
+ clientState?.hintLine && !isOver && /* @__PURE__ */ jsx57("div", { className: "ss-w-cpath-hint", children: clientState.hintLine }),
4497
+ !isOver && clientState && /* @__PURE__ */ jsxs51("div", { className: "ss-w-cpath-hint", children: [
4498
+ clientState.guessesRemaining,
4499
+ " guess",
4500
+ clientState.guessesRemaining !== 1 ? "es" : "",
4501
+ " remaining"
4502
+ ] })
4503
+ ] })
4504
+ ] });
4505
+ }
4506
+
4507
+ // src/components/games/BeatTheGridGame.tsx
4508
+ import React, { useState as useState25, useId as useId4 } from "react";
4509
+ import { Fragment as Fragment12, jsx as jsx58, jsxs as jsxs52 } from "react/jsx-runtime";
4510
+ function parseClientState4(json) {
4511
+ if (!json) return null;
4512
+ try {
4513
+ return JSON.parse(json);
4514
+ } catch {
4515
+ return null;
4516
+ }
4517
+ }
4518
+ function findCellResult(cells, row, col) {
4519
+ return cells.find((c) => c.row === row && c.col === col);
4520
+ }
4521
+ function SearchSheet({
4522
+ row,
4523
+ col,
4524
+ rowLabel,
4525
+ colLabel,
4526
+ playerPool,
4527
+ alreadyFilledIds,
4528
+ onPick,
4529
+ onDismiss
4530
+ }) {
4531
+ const [query, setQuery] = useState25("");
4532
+ const inputId = useId4();
4533
+ const filtered = playerPool.filter(
4534
+ (p) => !alreadyFilledIds.has(p.id) && p.name.toLowerCase().includes(query.toLowerCase())
4535
+ );
4536
+ return /* @__PURE__ */ jsxs52("div", { className: "ss-w-btg-sheet", "data-testid": "btg-search-sheet", children: [
4537
+ /* @__PURE__ */ jsxs52("div", { className: "ss-w-btg-sheet-hdr", children: [
4538
+ /* @__PURE__ */ jsxs52("div", { className: "ss-w-btg-sheet-ctx", children: [
4539
+ /* @__PURE__ */ jsx58("span", { className: "ss-w-btg-sheet-row", children: rowLabel }),
4540
+ /* @__PURE__ */ jsx58("span", { className: "ss-w-btg-sheet-sep", children: "\xD7" }),
4541
+ /* @__PURE__ */ jsx58("span", { className: "ss-w-btg-sheet-col", children: colLabel })
4542
+ ] }),
4543
+ /* @__PURE__ */ jsx58(
4544
+ "button",
4545
+ {
4546
+ type: "button",
4547
+ className: "ss-w-btg-sheet-close",
4548
+ "data-testid": "btg-sheet-dismiss",
4549
+ "aria-label": "Dismiss",
4550
+ onClick: onDismiss,
4551
+ children: "\u2715"
4552
+ }
4553
+ )
4554
+ ] }),
4555
+ /* @__PURE__ */ jsxs52("div", { className: "ss-w-gtta", children: [
4556
+ /* @__PURE__ */ jsx58(
4557
+ "input",
4558
+ {
4559
+ id: inputId,
4560
+ type: "text",
4561
+ role: "textbox",
4562
+ className: "ss-w-gtta-i",
4563
+ placeholder: "Search players\u2026",
4564
+ value: query,
4565
+ onChange: (e) => setQuery(e.target.value),
4566
+ autoComplete: "off",
4567
+ "aria-label": `Search player for ${rowLabel} \xD7 ${colLabel}`,
4568
+ "aria-autocomplete": "list",
4569
+ autoFocus: true
4570
+ }
4571
+ ),
4572
+ query.length > 0 && filtered.length > 0 && /* @__PURE__ */ jsx58("div", { className: "ss-w-gtta-drop ss-w-btg-ta-list", role: "listbox", children: filtered.map((p) => /* @__PURE__ */ jsx58(
4573
+ "div",
4574
+ {
4575
+ className: "ss-w-gtta-opt",
4576
+ role: "option",
4577
+ "aria-selected": false,
4578
+ onClick: () => onPick(row, col, p.id),
4579
+ onKeyDown: (e) => {
4580
+ if (e.key === "Enter") onPick(row, col, p.id);
4581
+ },
4582
+ tabIndex: 0,
4583
+ children: p.name
4584
+ },
4585
+ p.id
4586
+ )) })
4587
+ ] })
4588
+ ] });
4589
+ }
4590
+ function BeatTheGridGame({
4591
+ config,
4592
+ result,
4593
+ submitting,
4594
+ onSubmit,
4595
+ playerPool
4596
+ }) {
4597
+ const [activeCell, setActiveCell] = useState25(null);
4598
+ const clientState = parseClientState4(result?.clientStateJson);
4599
+ const filledCells = clientState?.cells ?? [];
4600
+ const isLocked2 = result?.alreadyPlayed === true || clientState?.isComplete === true;
4601
+ const alreadyFilledIds = new Set(filledCells.map((c) => c.playerId));
4602
+ function handleCellClick(row, col) {
4603
+ if (isLocked2 || submitting) return;
4604
+ const alreadyFilled = findCellResult(filledCells, row, col);
4605
+ if (alreadyFilled) return;
4606
+ setActiveCell({ row, col });
4607
+ }
4608
+ function handlePick(row, col, playerId) {
4609
+ setActiveCell(null);
4610
+ const prevCells = filledCells.map((c) => ({ row: c.row, col: c.col, playerId: c.playerId }));
4611
+ const newCells = [...prevCells, { row, col, playerId }];
4612
+ onSubmit(JSON.stringify({ cells: newCells }));
4613
+ }
4614
+ if (!config) {
4615
+ return /* @__PURE__ */ jsx58("div", { className: "ss-w-btg", "data-testid": "game-screen-beat-the-grid", children: /* @__PURE__ */ jsx58("div", { className: "ss-w-gscreen-body", children: "Loading\u2026" }) });
4616
+ }
4617
+ const rows = config.rows;
4618
+ const cols = config.cols;
4619
+ return /* @__PURE__ */ jsxs52("div", { className: "ss-w-btg", "data-testid": "game-screen-beat-the-grid", children: [
4620
+ /* @__PURE__ */ jsxs52("div", { className: "ss-w-btg-ctx", children: [
4621
+ /* @__PURE__ */ jsxs52("span", { className: "ss-w-btg-ctx-score", children: [
4622
+ "Score: ",
4623
+ clientState?.totalScore ?? 0
4624
+ ] }),
4625
+ !isLocked2 && /* @__PURE__ */ jsxs52("span", { className: "ss-w-btg-ctx-left", children: [
4626
+ config.maxGuesses - filledCells.length,
4627
+ " cell",
4628
+ config.maxGuesses - filledCells.length !== 1 ? "s" : "",
4629
+ " left"
4630
+ ] }),
4631
+ isLocked2 && /* @__PURE__ */ jsx58("span", { className: "ss-w-btg-ctx-done", children: "Complete" })
4632
+ ] }),
4633
+ /* @__PURE__ */ jsxs52(
4634
+ "div",
4635
+ {
4636
+ className: "ss-w-btg-grid",
4637
+ style: { gridTemplateColumns: `auto repeat(${cols.length}, 1fr)` },
4638
+ role: "grid",
4639
+ children: [
4640
+ /* @__PURE__ */ jsx58("div", { className: "ss-w-btg-gc ss-w-btg-gc--corner" }),
4641
+ cols.map((col) => /* @__PURE__ */ jsx58("div", { className: "ss-w-btg-gc ss-w-btg-gc--colhdr", children: col }, col)),
4642
+ rows.map((rowLabel, rowIdx) => /* @__PURE__ */ jsxs52(React.Fragment, { children: [
4643
+ /* @__PURE__ */ jsx58("div", { className: "ss-w-btg-gc ss-w-btg-gc--rowhdr", children: rowLabel }),
4644
+ cols.map((colLabel, colIdx) => {
4645
+ const filled = findCellResult(filledCells, rowIdx, colIdx);
4646
+ const isActive = activeCell?.row === rowIdx && activeCell?.col === colIdx;
4647
+ return /* @__PURE__ */ jsx58(
4648
+ "button",
4649
+ {
4650
+ type: "button",
4651
+ "data-testid": `btg-cell-${rowIdx}-${colIdx}`,
4652
+ "aria-label": `${rowLabel} ${colLabel}`,
4653
+ className: [
4654
+ "ss-w-btg-gc ss-w-btg-cell",
4655
+ filled ? filled.isCorrect ? "ss-w-btg-cell--correct" : "ss-w-btg-cell--wrong" : "",
4656
+ isActive ? "ss-w-btg-cell--active" : ""
4657
+ ].filter(Boolean).join(" "),
4658
+ disabled: isLocked2 || submitting,
4659
+ onClick: () => handleCellClick(rowIdx, colIdx),
4660
+ children: filled ? /* @__PURE__ */ jsxs52(Fragment12, { children: [
4661
+ /* @__PURE__ */ jsx58("span", { className: "ss-w-btg-cell-score", children: filled.rarityScore }),
4662
+ filled.isCorrect && /* @__PURE__ */ jsx58("span", { className: "ss-w-btg-cell-check", "aria-hidden": "true", children: "\u2713" })
4663
+ ] }) : /* @__PURE__ */ jsx58("span", { className: "ss-w-btg-cell-empty", "aria-hidden": "true", children: "+" })
4664
+ },
4665
+ `cell-${rowIdx}-${colIdx}`
4666
+ );
4667
+ })
4668
+ ] }, rowIdx))
4669
+ ]
4670
+ }
4671
+ ),
4672
+ activeCell !== null && /* @__PURE__ */ jsx58(
4673
+ SearchSheet,
4674
+ {
4675
+ row: activeCell.row,
4676
+ col: activeCell.col,
4677
+ rowLabel: rows[activeCell.row] ?? "",
4678
+ colLabel: cols[activeCell.col] ?? "",
4679
+ playerPool,
4680
+ alreadyFilledIds,
4681
+ onPick: handlePick,
4682
+ onDismiss: () => setActiveCell(null)
4683
+ }
4684
+ )
4685
+ ] });
4686
+ }
4687
+
4688
+ // src/components/games/GuessTheXiGame.tsx
4689
+ import { Fragment as Fragment13, jsx as jsx59, jsxs as jsxs53 } from "react/jsx-runtime";
4690
+ function parseClientState5(json) {
4691
+ if (!json) return null;
4692
+ try {
4693
+ return JSON.parse(json);
4694
+ } catch {
4695
+ return null;
4696
+ }
4697
+ }
4698
+ function RevealCard({ reveal }) {
4699
+ return /* @__PURE__ */ jsxs53("div", { className: "ss-w-gxi-reveal", "data-reveal-type": reveal.type ?? "", children: [
4700
+ reveal.slot && /* @__PURE__ */ jsx59("span", { className: "ss-w-gxi-reveal-slot", children: reveal.slot }),
4701
+ /* @__PURE__ */ jsx59("span", { className: "ss-w-gxi-reveal-val", children: reveal.value })
4702
+ ] });
4703
+ }
4704
+ function GuessTheXiGame({
4705
+ config,
4706
+ result,
4707
+ submitting,
4708
+ onSubmit
4709
+ }) {
4710
+ const clientState = parseClientState5(result?.clientStateJson);
4711
+ const isOver = result?.alreadyPlayed === true || clientState?.status === "solved" || clientState?.status === "failed";
4712
+ function handlePick(teamId) {
4713
+ if (!config || isOver || submitting) return;
4714
+ const prevGuesses = clientState?.guessHistory.map((g) => ({ teamId: g.teamId })) ?? [];
4715
+ const newGuesses = [...prevGuesses, { teamId }];
4716
+ onSubmit(JSON.stringify({ guesses: newGuesses }));
4717
+ }
4718
+ return /* @__PURE__ */ jsxs53("div", { className: "ss-w-gxi", "data-testid": "game-screen-guess-the-xi", children: [
4719
+ !config && /* @__PURE__ */ jsx59("div", { className: "ss-w-gscreen-body", children: "Loading\u2026" }),
4720
+ config && /* @__PURE__ */ jsxs53(Fragment13, { children: [
4721
+ /* @__PURE__ */ jsx59("div", { className: "ss-w-gxi-ctx", children: /* @__PURE__ */ jsx59("span", { className: "ss-w-gxi-ctx-label", children: config.poolLabel }) }),
4722
+ config.positions.length > 0 && /* @__PURE__ */ jsx59("div", { className: "ss-w-gxi-pitch", children: config.positions.map((pos) => /* @__PURE__ */ jsxs53("div", { className: "ss-w-gxi-pslot", children: [
4723
+ /* @__PURE__ */ jsx59("span", { className: "ss-w-gxi-pslot-pos", children: pos.slot }),
4724
+ /* @__PURE__ */ jsx59("span", { className: "ss-w-gxi-pslot-nat", children: pos.nationality })
4725
+ ] }, pos.slot)) }),
4726
+ clientState && clientState.earnedReveals.length > 0 && /* @__PURE__ */ jsx59("div", { className: "ss-w-gxi-reveals", children: clientState.earnedReveals.map((r, i) => /* @__PURE__ */ jsx59(RevealCard, { reveal: r }, i)) }),
4727
+ isOver && clientState && /* @__PURE__ */ jsx59("div", { className: `ss-w-gxi-banner ss-w-gxi-banner--${clientState.status}`, children: /* @__PURE__ */ jsx59("span", { className: "ss-w-gxi-banner-label", children: clientState.status === "solved" ? `Solved! ${clientState.score} pts` : "Better luck tomorrow" }) }),
4728
+ /* @__PURE__ */ jsx59("div", { className: "ss-w-gxi-pool", children: config.teamPool.map((team) => {
4729
+ const guessRecord = clientState?.guessHistory.find((g) => g.teamId === team.teamId);
4730
+ return /* @__PURE__ */ jsx59(
4731
+ "button",
4732
+ {
4733
+ type: "button",
4734
+ className: [
4735
+ "ss-w-gxi-team-btn",
4736
+ guessRecord ? guessRecord.wasCorrect ? "ss-w-gxi-team-btn--correct" : "ss-w-gxi-team-btn--wrong" : ""
4737
+ ].filter(Boolean).join(" "),
4738
+ disabled: isOver || submitting,
4739
+ onClick: () => handlePick(team.teamId),
4740
+ children: team.teamName
4741
+ },
4742
+ team.teamId
4743
+ );
4744
+ }) }),
4745
+ !isOver && clientState && /* @__PURE__ */ jsxs53("div", { className: "ss-w-gxi-hint", children: [
4746
+ "Guess ",
4747
+ clientState.guessesUsed + 1,
4748
+ " of 6"
4749
+ ] })
4750
+ ] })
4751
+ ] });
4752
+ }
4753
+
4754
+ // src/components/games/DailyQuizGame.tsx
4755
+ import { useState as useState26 } from "react";
4756
+ import { Fragment as Fragment14, jsx as jsx60, jsxs as jsxs54 } from "react/jsx-runtime";
4757
+ function parseClientState6(json) {
4758
+ if (!json) return null;
4759
+ try {
4760
+ return JSON.parse(json);
4761
+ } catch {
4762
+ return null;
4763
+ }
4764
+ }
4765
+ function findResult(results, index) {
4766
+ return results.find((r) => r.index === index);
4767
+ }
4768
+ function DailyQuizGame({
4769
+ config,
4770
+ result,
4771
+ submitting,
4772
+ onSubmit
4773
+ }) {
4774
+ const [selections, setSelections] = useState26(/* @__PURE__ */ new Map());
4775
+ const clientState = parseClientState6(result?.clientStateJson);
4776
+ const isRevealed = (clientState?.results.length ?? 0) > 0 || result?.alreadyPlayed === true;
4777
+ const allAnswered = config != null && selections.size === config.questions.length;
4778
+ function handleSelect(questionIndex, optionIndex) {
4779
+ if (isRevealed || submitting) return;
4780
+ setSelections((prev) => new Map(prev).set(questionIndex, optionIndex));
4781
+ }
4782
+ function handleSubmit() {
4783
+ if (!config || !allAnswered || isRevealed || submitting) return;
4784
+ const answers = config.questions.map((q) => ({
4785
+ index: q.index,
4786
+ selectedOptionIndex: selections.get(q.index) ?? 0
4787
+ }));
4788
+ onSubmit(JSON.stringify({ answers }));
4789
+ }
4790
+ return /* @__PURE__ */ jsxs54("div", { className: "ss-w-dq", "data-testid": "game-screen-daily-quiz", children: [
4791
+ !config && /* @__PURE__ */ jsx60("div", { className: "ss-w-gscreen-body", children: "Loading\u2026" }),
4792
+ config && /* @__PURE__ */ jsxs54(Fragment14, { children: [
4793
+ isRevealed && result?.score != null && /* @__PURE__ */ jsxs54("div", { className: "ss-w-dq-score", children: [
4794
+ /* @__PURE__ */ jsx60("span", { className: "ss-w-dq-score-val", children: result.score }),
4795
+ /* @__PURE__ */ jsx60("span", { className: "ss-w-dq-score-label", children: "pts" })
4796
+ ] }),
4797
+ !isRevealed && /* @__PURE__ */ jsx60("div", { className: "ss-w-dq-prog", children: /* @__PURE__ */ jsx60(
4798
+ "div",
4799
+ {
4800
+ className: "ss-w-dq-prog-fill",
4801
+ style: { width: `${Math.round(selections.size / config.questions.length * 100)}%` }
4802
+ }
4803
+ ) }),
4804
+ /* @__PURE__ */ jsx60("div", { className: "ss-w-dq-questions", children: config.questions.map((q) => {
4805
+ const qResult = clientState ? findResult(clientState.results, q.index) : void 0;
4806
+ const selectedIdx = selections.get(q.index);
4807
+ return /* @__PURE__ */ jsxs54("div", { className: "ss-w-dq-q", children: [
4808
+ /* @__PURE__ */ jsx60("div", { className: "ss-w-dq-qstem", children: q.stem }),
4809
+ /* @__PURE__ */ jsx60("div", { className: "ss-w-dq-opts", children: q.options.map((opt, optIdx) => {
4810
+ let optCls = "ss-w-dq-qopt";
4811
+ if (qResult) {
4812
+ if (optIdx === qResult.correctOptionIndex) {
4813
+ optCls += " ss-w-dq-qopt--correct";
4814
+ } else if (optIdx === selectedIdx && !qResult.isCorrect) {
4815
+ optCls += " ss-w-dq-qopt--wrong";
4816
+ }
4817
+ } else if (optIdx === selectedIdx) {
4818
+ optCls += " ss-w-dq-qopt--selected";
4819
+ }
4820
+ return /* @__PURE__ */ jsxs54(
4821
+ "button",
4822
+ {
4823
+ type: "button",
4824
+ className: optCls,
4825
+ disabled: isRevealed || submitting,
4826
+ onClick: () => handleSelect(q.index, optIdx),
4827
+ children: [
4828
+ /* @__PURE__ */ jsx60("span", { className: "ss-w-dq-qopt-letter", children: String.fromCharCode(65 + optIdx) }),
4829
+ /* @__PURE__ */ jsx60("span", { className: "ss-w-dq-qopt-text", children: opt })
4830
+ ]
4831
+ },
4832
+ optIdx
4833
+ );
4834
+ }) }),
4835
+ qResult?.revealText && /* @__PURE__ */ jsx60("div", { className: `ss-w-dq-qwhy ss-w-dq-qwhy--${qResult.isCorrect ? "correct" : "wrong"}`, children: qResult.revealText })
4836
+ ] }, q.index);
4837
+ }) }),
4838
+ !isRevealed && /* @__PURE__ */ jsx60(
4839
+ "button",
4840
+ {
4841
+ type: "button",
4842
+ className: "ss-w-dq-submit",
4843
+ disabled: !allAnswered || submitting,
4844
+ onClick: handleSubmit,
4845
+ "aria-label": "Submit answers",
4846
+ children: submitting ? "Submitting\u2026" : "Submit"
4847
+ }
4848
+ )
4849
+ ] })
4850
+ ] });
4851
+ }
4852
+
4853
+ // src/components/games/MatchdayPredictorGame.tsx
4854
+ import { useState as useState27 } from "react";
4855
+ import { jsx as jsx61, jsxs as jsxs55 } from "react/jsx-runtime";
4856
+ function parseClientState7(json) {
4857
+ if (!json) return null;
4858
+ try {
4859
+ return JSON.parse(json);
4860
+ } catch {
4861
+ return null;
4862
+ }
4863
+ }
4864
+ function isLocked(kickoffUtc) {
4865
+ try {
4866
+ return new Date(kickoffUtc).getTime() <= Date.now();
4867
+ } catch {
4868
+ return true;
4869
+ }
4870
+ }
4871
+ function MatchdayPredictorGame({
4872
+ config,
4873
+ result,
4874
+ submitting,
4875
+ onSubmit
4876
+ }) {
4877
+ const [homeScore, setHomeScore] = useState27(0);
4878
+ const [awayScore, setAwayScore] = useState27(0);
4879
+ const [firstScorerPlayerId, setFirstScorerPlayerId] = useState27(null);
4880
+ const clientState = parseClientState7(result?.clientStateJson);
4881
+ const alreadyPlayed = result?.alreadyPlayed === true;
4882
+ if (alreadyPlayed && clientState) {
4883
+ if (!clientState.graded) {
4884
+ return /* @__PURE__ */ jsxs55("div", { className: "ss-w-mp", "data-testid": "game-screen-matchday-predictor", children: [
4885
+ /* @__PURE__ */ jsxs55("div", { className: "ss-w-mp-live", children: [
4886
+ /* @__PURE__ */ jsxs55("div", { className: "ss-w-mp-live-score", children: [
4887
+ clientState.predictedHomeScore,
4888
+ " \u2013 ",
4889
+ clientState.predictedAwayScore
4890
+ ] }),
4891
+ /* @__PURE__ */ jsx61("div", { className: "ss-w-mp-live-label", children: "Locked in \u2014 awaiting result" })
4892
+ ] }),
4893
+ /* @__PURE__ */ jsx61("div", { className: "ss-w-mp-fun", children: "For fun \u2014 not in the leaderboard" })
4894
+ ] });
4895
+ }
4896
+ const r = clientState.result;
4897
+ const actualScore = `${r.homeScore} \u2013 ${r.awayScore}`;
4898
+ return /* @__PURE__ */ jsxs55("div", { className: "ss-w-mp", "data-testid": "game-screen-matchday-predictor", children: [
4899
+ /* @__PURE__ */ jsxs55("div", { className: "ss-w-mp-live", children: [
4900
+ /* @__PURE__ */ jsx61("div", { className: "ss-w-mp-live-score", children: actualScore }),
4901
+ /* @__PURE__ */ jsx61("div", { className: "ss-w-mp-live-label", children: "Full-time result" }),
4902
+ /* @__PURE__ */ jsxs55("div", { className: "ss-w-mp-live-outcome", children: [
4903
+ /* @__PURE__ */ jsxs55("div", { className: `ss-w-mp-live-row${clientState.exactScoreCorrect ? " ss-w-mp-live-row--correct" : ""}`, children: [
4904
+ /* @__PURE__ */ jsx61("span", { className: "ss-w-mp-live-row-key", children: "Exact score" }),
4905
+ /* @__PURE__ */ jsx61("span", { className: "ss-w-mp-live-row-val", children: clientState.exactScoreCorrect ? "\u2713" : "\u2717" })
4906
+ ] }),
4907
+ /* @__PURE__ */ jsxs55("div", { className: `ss-w-mp-live-row${clientState.outcomeCorrect ? " ss-w-mp-live-row--correct" : ""}`, children: [
4908
+ /* @__PURE__ */ jsx61("span", { className: "ss-w-mp-live-row-key", children: "Result (W/D/L)" }),
4909
+ /* @__PURE__ */ jsx61("span", { className: "ss-w-mp-live-row-val", children: clientState.outcomeCorrect ? "\u2713" : "\u2717" })
4910
+ ] }),
4911
+ !clientState.firstScorerVoid && /* @__PURE__ */ jsxs55("div", { className: `ss-w-mp-live-row${clientState.firstScorerCorrect ? " ss-w-mp-live-row--correct" : ""}`, children: [
4912
+ /* @__PURE__ */ jsx61("span", { className: "ss-w-mp-live-row-key", children: "First scorer" }),
4913
+ /* @__PURE__ */ jsxs55("span", { className: "ss-w-mp-live-row-val", children: [
4914
+ clientState.firstScorerCorrect ? "\u2713" : "\u2717",
4915
+ r.firstScorerName ? ` ${r.firstScorerName}` : ""
4916
+ ] })
4917
+ ] })
4918
+ ] })
4919
+ ] }),
4920
+ /* @__PURE__ */ jsx61("div", { className: "ss-w-mp-fun", children: "For fun \u2014 not in the leaderboard" })
4921
+ ] });
4922
+ }
4923
+ if (!config) {
4924
+ return /* @__PURE__ */ jsx61("div", { className: "ss-w-mp", "data-testid": "game-screen-matchday-predictor", children: /* @__PURE__ */ jsx61("div", { className: "ss-w-gscreen-body", children: "Loading\u2026" }) });
4925
+ }
4926
+ const locked = isLocked(config.kickoffUtc);
4927
+ const disabled = locked || submitting;
4928
+ function handleSubmit() {
4929
+ if (disabled || !config) return;
4930
+ onSubmit(
4931
+ JSON.stringify({
4932
+ homeScore,
4933
+ awayScore,
4934
+ ...firstScorerPlayerId !== null ? { firstScorerPlayerId } : {}
4935
+ })
4936
+ );
4937
+ }
4938
+ return /* @__PURE__ */ jsxs55("div", { className: "ss-w-mp", "data-testid": "game-screen-matchday-predictor", children: [
4939
+ /* @__PURE__ */ jsxs55("div", { className: "ss-w-mp-pred-score", children: [
4940
+ /* @__PURE__ */ jsxs55("div", { className: "ss-w-mp-team", children: [
4941
+ /* @__PURE__ */ jsx61("div", { className: "ss-w-mp-team-name", children: config.homeTeam.name }),
4942
+ /* @__PURE__ */ jsxs55("div", { className: "ss-w-mp-stepper", children: [
4943
+ /* @__PURE__ */ jsx61(
4944
+ "button",
4945
+ {
4946
+ type: "button",
4947
+ className: "ss-w-mp-stepper-btn",
4948
+ "aria-label": "-",
4949
+ disabled: disabled || homeScore <= 0,
4950
+ onClick: () => setHomeScore((s) => Math.max(0, s - 1)),
4951
+ children: "\u2212"
4952
+ }
4953
+ ),
4954
+ /* @__PURE__ */ jsx61("span", { className: "ss-w-mp-stepper-val", children: homeScore }),
4955
+ /* @__PURE__ */ jsx61(
4956
+ "button",
4957
+ {
4958
+ type: "button",
4959
+ className: "ss-w-mp-stepper-btn",
4960
+ "aria-label": "+",
4961
+ disabled,
4962
+ onClick: () => setHomeScore((s) => s + 1),
4963
+ children: "+"
4964
+ }
4965
+ )
4966
+ ] })
4967
+ ] }),
4968
+ /* @__PURE__ */ jsx61("span", { className: "ss-w-mp-sep", children: "\u2013" }),
4969
+ /* @__PURE__ */ jsxs55("div", { className: "ss-w-mp-team", children: [
4970
+ /* @__PURE__ */ jsx61("div", { className: "ss-w-mp-team-name", children: config.awayTeam.name }),
4971
+ /* @__PURE__ */ jsxs55("div", { className: "ss-w-mp-stepper", children: [
4972
+ /* @__PURE__ */ jsx61(
4973
+ "button",
4974
+ {
4975
+ type: "button",
4976
+ className: "ss-w-mp-stepper-btn",
4977
+ "aria-label": "-",
4978
+ disabled: disabled || awayScore <= 0,
4979
+ onClick: () => setAwayScore((s) => Math.max(0, s - 1)),
4980
+ children: "\u2212"
4981
+ }
4982
+ ),
4983
+ /* @__PURE__ */ jsx61("span", { className: "ss-w-mp-stepper-val", children: awayScore }),
4984
+ /* @__PURE__ */ jsx61(
4985
+ "button",
4986
+ {
4987
+ type: "button",
4988
+ className: "ss-w-mp-stepper-btn",
4989
+ "aria-label": "+",
4990
+ disabled,
4991
+ onClick: () => setAwayScore((s) => s + 1),
4992
+ children: "+"
4993
+ }
4994
+ )
4995
+ ] })
4996
+ ] })
4997
+ ] }),
4998
+ config.scorerPool.length > 0 && /* @__PURE__ */ jsxs55("div", { className: "ss-w-mp-scorer", children: [
4999
+ /* @__PURE__ */ jsx61("div", { className: "ss-w-mp-scorer-label", children: "First scorer (optional)" }),
5000
+ /* @__PURE__ */ jsx61("div", { className: "ss-w-mp-scorer-list", children: config.scorerPool.map((p) => /* @__PURE__ */ jsx61(
5001
+ "button",
5002
+ {
5003
+ type: "button",
5004
+ className: `ss-w-mp-scorer-opt${firstScorerPlayerId === p.playerId ? " ss-w-mp-scorer-opt--selected" : ""}`,
5005
+ disabled,
5006
+ onClick: () => setFirstScorerPlayerId((id) => id === p.playerId ? null : p.playerId),
5007
+ children: p.playerName
5008
+ },
5009
+ p.playerId
5010
+ )) })
5011
+ ] }),
5012
+ locked && /* @__PURE__ */ jsx61("div", { className: "ss-w-mp-live-label", children: "Submissions are now closed" }),
5013
+ /* @__PURE__ */ jsx61(
5014
+ "button",
5015
+ {
5016
+ type: "button",
5017
+ className: "ss-w-mp-savebtn",
5018
+ disabled,
5019
+ onClick: handleSubmit,
5020
+ "aria-label": "Save prediction",
5021
+ children: submitting ? "Saving\u2026" : "Save prediction"
5022
+ }
5023
+ ),
5024
+ /* @__PURE__ */ jsx61("div", { className: "ss-w-mp-fun", children: "For fun \u2014 not in the leaderboard" })
5025
+ ] });
5026
+ }
5027
+
5028
+ // src/components/games/StartingXiGame.tsx
5029
+ import { useState as useState28 } from "react";
5030
+ import { jsx as jsx62, jsxs as jsxs56 } from "react/jsx-runtime";
5031
+ function parseClientState8(json) {
5032
+ if (!json) return null;
5033
+ try {
5034
+ return JSON.parse(json);
5035
+ } catch {
5036
+ return null;
5037
+ }
5038
+ }
5039
+ function parseFormationRows(formation) {
5040
+ const parts = formation.split("-").map(Number).filter((n) => n > 0);
5041
+ if (parts.length === 0) return [1, 4, 3, 3];
5042
+ return [1, ...parts];
5043
+ }
5044
+ function StartingXiGame({
5045
+ config,
5046
+ result,
5047
+ submitting,
5048
+ onSubmit
5049
+ }) {
5050
+ const [picked, setPicked] = useState28([]);
5051
+ const clientState = parseClientState8(result?.clientStateJson);
5052
+ const alreadyPlayed = result?.alreadyPlayed === true;
5053
+ if (alreadyPlayed) {
5054
+ if (!clientState) {
5055
+ return /* @__PURE__ */ jsx62("div", { className: "ss-w-sxi", "data-testid": "game-screen-starting-xi", children: /* @__PURE__ */ jsx62("div", { className: "ss-w-sxi-status", children: /* @__PURE__ */ jsx62("div", { className: "ss-w-sxi-status-label", children: "This game has been voided" }) }) });
5056
+ }
5057
+ if (clientState.status === "pending") {
5058
+ return /* @__PURE__ */ jsx62("div", { className: "ss-w-sxi", "data-testid": "game-screen-starting-xi", children: /* @__PURE__ */ jsx62("div", { className: "ss-w-sxi-status", children: /* @__PURE__ */ jsxs56("div", { className: "ss-w-sxi-status-label", children: [
5059
+ "Prediction locked in (",
5060
+ clientState.predictedCount,
5061
+ " players) \u2014 awaiting result"
5062
+ ] }) }) });
5063
+ }
5064
+ if (clientState.status === "graded") {
5065
+ return /* @__PURE__ */ jsx62("div", { className: "ss-w-sxi", "data-testid": "game-screen-starting-xi", children: /* @__PURE__ */ jsxs56("div", { className: "ss-w-sxi-status ss-w-sxi-status--graded", children: [
5066
+ /* @__PURE__ */ jsx62("div", { className: "ss-w-sxi-status-score", children: clientState.score }),
5067
+ /* @__PURE__ */ jsxs56("div", { className: "ss-w-sxi-status-label", children: [
5068
+ clientState.correctCount,
5069
+ " correct starters"
5070
+ ] })
5071
+ ] }) });
5072
+ }
5073
+ }
5074
+ if (!config) {
5075
+ return /* @__PURE__ */ jsx62("div", { className: "ss-w-sxi", "data-testid": "game-screen-starting-xi", children: /* @__PURE__ */ jsx62("div", { className: "ss-w-gscreen-body", children: "Loading\u2026" }) });
5076
+ }
5077
+ const formationRows = parseFormationRows(config.formation);
5078
+ const pickedSet = new Set(picked);
5079
+ const canSubmit = picked.length === 11 && !submitting;
5080
+ function togglePlayer(playerId) {
5081
+ if (submitting) return;
5082
+ setPicked((prev) => {
5083
+ if (prev.includes(playerId)) {
5084
+ return prev.filter((id) => id !== playerId);
5085
+ }
5086
+ if (prev.length >= 11) return prev;
5087
+ return [...prev, playerId];
5088
+ });
5089
+ }
5090
+ function handleSubmit() {
5091
+ if (!canSubmit) return;
5092
+ onSubmit(JSON.stringify({ predictedPlayerIds: picked }));
5093
+ }
5094
+ let slotIndex = 0;
5095
+ const pitchRows = formationRows.map((count, rowIdx) => {
5096
+ const rowSlots = picked.slice(slotIndex, slotIndex + count);
5097
+ slotIndex += count;
5098
+ return { rowIdx, count, rowSlots };
5099
+ });
5100
+ return /* @__PURE__ */ jsxs56("div", { className: "ss-w-sxi", "data-testid": "game-screen-starting-xi", children: [
5101
+ /* @__PURE__ */ jsx62("div", { className: "ss-w-sxi-formation", children: config.formation }),
5102
+ /* @__PURE__ */ jsx62("div", { className: "ss-w-sxi-pitch", children: pitchRows.map(({ rowIdx, count, rowSlots }) => /* @__PURE__ */ jsx62("div", { className: "ss-w-sxi-pitch-row", children: Array.from({ length: count }).map((_, i) => {
5103
+ const playerId = rowSlots[i];
5104
+ const player = playerId != null ? config.squadSheet.find((p) => p.playerId === playerId) : void 0;
5105
+ return /* @__PURE__ */ jsxs56(
5106
+ "div",
5107
+ {
5108
+ className: `ss-w-sxi-pslot${player ? " ss-w-sxi-pslot--filled" : ""}`,
5109
+ onClick: () => {
5110
+ if (player) togglePlayer(player.playerId);
5111
+ },
5112
+ onKeyDown: (e) => {
5113
+ if (e.key === "Enter" && player) togglePlayer(player.playerId);
5114
+ },
5115
+ tabIndex: player ? 0 : -1,
5116
+ role: player ? "button" : void 0,
5117
+ "aria-label": player ? `Remove ${player.playerName ?? ""}` : void 0,
5118
+ children: [
5119
+ /* @__PURE__ */ jsx62("div", { className: "ss-w-sxi-pslot-num", children: player?.jerseyNumber ?? (rowIdx === 0 ? "GK" : "?") }),
5120
+ /* @__PURE__ */ jsx62("div", { className: "ss-w-sxi-pslot-name", children: player?.playerName ?? "" })
5121
+ ]
5122
+ },
5123
+ i
5124
+ );
5125
+ }) }, rowIdx)) }),
5126
+ /* @__PURE__ */ jsx62("div", { className: "ss-w-sxi-squad", children: config.squadSheet.map((p) => {
5127
+ const isPicked = pickedSet.has(p.playerId);
5128
+ return /* @__PURE__ */ jsxs56(
5129
+ "div",
5130
+ {
5131
+ className: `ss-w-sxi-squad-row${isPicked ? " ss-w-sxi-squad-row--picked" : ""}`,
5132
+ onClick: () => togglePlayer(p.playerId),
5133
+ onKeyDown: (e) => {
5134
+ if (e.key === "Enter") togglePlayer(p.playerId);
5135
+ },
5136
+ tabIndex: 0,
5137
+ role: "button",
5138
+ "aria-pressed": isPicked,
5139
+ children: [
5140
+ /* @__PURE__ */ jsx62("span", { className: "ss-w-sxi-squad-name", children: p.playerName }),
5141
+ /* @__PURE__ */ jsx62("span", { className: "ss-w-sxi-squad-pos", children: p.positionName })
5142
+ ]
5143
+ },
5144
+ p.playerId
5145
+ );
5146
+ }) }),
5147
+ /* @__PURE__ */ jsx62(
5148
+ "button",
5149
+ {
5150
+ type: "button",
5151
+ className: "ss-w-sxi-savebtn",
5152
+ disabled: !canSubmit,
5153
+ onClick: handleSubmit,
5154
+ "aria-label": "Predict XI",
5155
+ children: submitting ? "Submitting\u2026" : `Predict XI (${picked.length}/11)`
5156
+ }
5157
+ )
5158
+ ] });
5159
+ }
5160
+
5161
+ // src/components/games/StatLadderGame.tsx
5162
+ import { jsx as jsx63, jsxs as jsxs57 } from "react/jsx-runtime";
5163
+ function parseClientState9(json) {
5164
+ if (!json) return null;
5165
+ try {
5166
+ return JSON.parse(json);
5167
+ } catch {
5168
+ return null;
5169
+ }
5170
+ }
5171
+ function StatLadderGame({
5172
+ config,
5173
+ result,
5174
+ submitting,
5175
+ onSubmit
5176
+ }) {
5177
+ const clientState = parseClientState9(result?.clientStateJson);
5178
+ const revealed = clientState != null;
5179
+ if (!config) {
5180
+ return /* @__PURE__ */ jsx63("div", { className: "ss-w-sl", "data-testid": "game-screen-stat-ladder", children: /* @__PURE__ */ jsx63("div", { className: "ss-w-gscreen-body", children: "Loading\u2026" }) });
5181
+ }
5182
+ const mysteryName = revealed ? clientState.revealedRank2.playerName : null;
5183
+ return /* @__PURE__ */ jsxs57("div", { className: "ss-w-sl", "data-testid": "game-screen-stat-ladder", children: [
5184
+ /* @__PURE__ */ jsx63("div", { className: "ss-w-sl-title", children: config.statLabel }),
5185
+ /* @__PURE__ */ jsx63("div", { className: "ss-w-sl-ladder", children: config.ladder.map((rung) => {
5186
+ const isMystery = rung.rank === 2;
5187
+ let rowCls = "ss-w-sl-lrow";
5188
+ if (isMystery) rowCls += " ss-w-sl-mystery";
5189
+ if (isMystery && revealed) {
5190
+ rowCls = rowCls.replace(" ss-w-sl-mystery", "");
5191
+ rowCls += clientState.isCorrect ? " ss-w-sl-lrow--correct" : " ss-w-sl-lrow--wrong";
5192
+ }
5193
+ const displayName = isMystery ? revealed ? mysteryName : "?" : rung.playerName ?? "?";
5194
+ return /* @__PURE__ */ jsxs57("div", { className: rowCls, children: [
5195
+ /* @__PURE__ */ jsxs57("div", { className: "ss-w-sl-lrow-rank", children: [
5196
+ "#",
5197
+ rung.rank
5198
+ ] }),
5199
+ /* @__PURE__ */ jsx63("div", { className: "ss-w-sl-lrow-name", children: displayName }),
5200
+ /* @__PURE__ */ jsx63("div", { className: "ss-w-sl-lrow-stat", children: rung.statValue })
5201
+ ] }, rung.rank);
5202
+ }) }),
5203
+ revealed && /* @__PURE__ */ jsx63("div", { className: `ss-w-sl-reveal ss-w-sl-reveal--${clientState.isCorrect ? "correct" : "wrong"}`, children: clientState.isCorrect ? "Correct!" : `Wrong \u2014 it was ${clientState.revealedRank2.playerName}` }),
5204
+ !revealed && /* @__PURE__ */ jsx63("div", { className: "ss-w-sl-picker", children: config.playerPool.map((p) => /* @__PURE__ */ jsx63(
5205
+ "button",
5206
+ {
5207
+ type: "button",
5208
+ className: "ss-w-sl-picker-opt",
5209
+ disabled: submitting,
5210
+ "aria-label": p.playerName,
5211
+ onClick: () => onSubmit(JSON.stringify({ guessedPlayerId: p.playerId })),
5212
+ children: p.playerName
5213
+ },
5214
+ p.playerId
5215
+ )) })
5216
+ ] });
5217
+ }
5218
+
5219
+ // src/components/games/FanMotmGame.tsx
5220
+ import { jsx as jsx64, jsxs as jsxs58 } from "react/jsx-runtime";
5221
+ function parseClientState10(json) {
5222
+ if (!json) return null;
5223
+ try {
5224
+ return JSON.parse(json);
5225
+ } catch {
5226
+ return null;
5227
+ }
5228
+ }
5229
+ function FanMotmGame({
5230
+ config,
5231
+ result,
5232
+ submitting,
5233
+ onSubmit
5234
+ }) {
5235
+ const clientState = parseClientState10(result?.clientStateJson);
5236
+ const alreadyVoted = result?.alreadyPlayed === true;
5237
+ if (!config) {
5238
+ return /* @__PURE__ */ jsx64("div", { className: "ss-w-motm", "data-testid": "game-screen-fan-motm", children: /* @__PURE__ */ jsx64("div", { className: "ss-w-gscreen-body", children: "Loading\u2026" }) });
5239
+ }
5240
+ const pickedId = clientState?.pickedPlayerId ?? null;
5241
+ function handleVote(candidateId) {
5242
+ if (alreadyVoted || submitting) return;
5243
+ onSubmit(JSON.stringify({ pickedPlayerId: candidateId }));
5244
+ }
5245
+ return /* @__PURE__ */ jsxs58("div", { className: "ss-w-motm", "data-testid": "game-screen-fan-motm", children: [
5246
+ /* @__PURE__ */ jsx64("div", { className: "ss-w-motm-title", children: "Man of the Match \u2014 your vote" }),
5247
+ /* @__PURE__ */ jsx64("div", { className: "ss-w-motm-votes", children: config.candidates.map((c) => {
5248
+ const isVoted = alreadyVoted && pickedId === c.playerId;
5249
+ const rowCls = `ss-w-motm-vrow${isVoted ? " ss-w-motm-vrow--voted" : ""}${alreadyVoted ? " ss-w-motm-vrow--result" : ""}`;
5250
+ return /* @__PURE__ */ jsxs58(
5251
+ "button",
5252
+ {
5253
+ type: "button",
5254
+ className: rowCls,
5255
+ "data-testid": `motm-candidate-${c.playerId}`,
5256
+ disabled: alreadyVoted || submitting,
5257
+ onClick: () => handleVote(c.playerId),
5258
+ children: [
5259
+ /* @__PURE__ */ jsx64("div", { className: "ss-w-motm-vfill", style: { width: isVoted ? "100%" : "0%" } }),
5260
+ /* @__PURE__ */ jsx64("span", { className: "ss-w-motm-vrow-name", children: c.playerName })
5261
+ ]
5262
+ },
5263
+ c.playerId
5264
+ );
5265
+ }) }),
5266
+ /* @__PURE__ */ jsx64("div", { className: "ss-w-motm-fun", children: "For fun \u2014 unranked community vote" })
5267
+ ] });
5268
+ }
5269
+
5270
+ // src/components/GameScreenHost.tsx
5271
+ import { jsx as jsx65, jsxs as jsxs59 } from "react/jsx-runtime";
5272
+ var FIXTURE_GAME_IDS = /* @__PURE__ */ new Set([
5273
+ "matchday-predictor",
5274
+ "starting-xi",
5275
+ "stat-ladder",
5276
+ "fan-motm"
5277
+ ]);
5278
+ var PENDING_POLL_INTERVAL_MS = 3e4;
5279
+ function safeParseConfig(json) {
5280
+ if (!json) return null;
5281
+ try {
5282
+ return JSON.parse(json);
5283
+ } catch {
5284
+ return null;
5285
+ }
5286
+ }
5287
+ function GameScreenHost({
5288
+ selected,
5289
+ onBack,
5290
+ conversation,
5291
+ ui
5292
+ }) {
5293
+ const { gameId, fixtureId, gameDay = "" } = selected;
5294
+ const [configJson, setConfigJson] = useState29(null);
5295
+ useEffect13(() => {
5296
+ setConfigJson(null);
5297
+ if (!conversation) return;
5298
+ let cancelled = false;
5299
+ void (async () => {
5300
+ try {
5301
+ const payload = await conversation.getGameConfig(gameId, fixtureId, gameDay || void 0);
5302
+ if (!cancelled && payload?.configJson) {
5303
+ setConfigJson(payload.configJson);
5304
+ }
5305
+ } catch {
5306
+ }
5307
+ })();
5308
+ return () => {
5309
+ cancelled = true;
5310
+ };
5311
+ }, [conversation, gameId, fixtureId, gameDay]);
5312
+ const { result, submitting, submit, hydrate, rawStatus } = useGamePlay(conversation, {
5313
+ gameId,
5314
+ gameDay,
5315
+ fixtureId: fixtureId || void 0
5316
+ });
5317
+ useEffect13(() => {
5318
+ if (conversation) hydrate();
5319
+ }, [conversation, gameId]);
5320
+ const hydrateRef = useRef12(hydrate);
5321
+ hydrateRef.current = hydrate;
5322
+ useEffect13(() => {
5323
+ if (!FIXTURE_GAME_IDS.has(gameId)) return;
5324
+ if (rawStatus !== "pending") return;
5325
+ const timerId = setInterval(() => {
5326
+ hydrateRef.current();
5327
+ }, PENDING_POLL_INTERVAL_MS);
5328
+ return () => clearInterval(timerId);
5329
+ }, [gameId, rawStatus]);
5330
+ const sharedProps = {
5331
+ result,
5332
+ submitting,
5333
+ onSubmit: submit,
5334
+ ui
5335
+ };
5336
+ function renderScreen() {
5337
+ switch (gameId) {
5338
+ case "mystery-tiger":
5339
+ return /* @__PURE__ */ jsx65(
5340
+ MysteryTigerGame,
5341
+ {
5342
+ ...sharedProps,
5343
+ config: safeParseConfig(configJson)
5344
+ }
5345
+ );
5346
+ case "higher-or-lower":
5347
+ return /* @__PURE__ */ jsx65(
5348
+ HigherOrLowerGame,
5349
+ {
5350
+ ...sharedProps,
5351
+ config: safeParseConfig(configJson)
5352
+ }
5353
+ );
5354
+ case "career-path":
5355
+ return /* @__PURE__ */ jsx65(
5356
+ CareerPathGame,
5357
+ {
5358
+ ...sharedProps,
5359
+ config: safeParseConfig(configJson)
5360
+ }
5361
+ );
5362
+ case "beat-the-grid":
5363
+ return /* @__PURE__ */ jsx65(
5364
+ BeatTheGridGame,
5365
+ {
5366
+ ...sharedProps,
5367
+ config: safeParseConfig(configJson),
5368
+ playerPool: []
5369
+ }
5370
+ );
5371
+ case "guess-the-xi":
5372
+ return /* @__PURE__ */ jsx65(
5373
+ GuessTheXiGame,
5374
+ {
5375
+ ...sharedProps,
5376
+ config: safeParseConfig(configJson)
5377
+ }
5378
+ );
5379
+ case "daily-quiz":
5380
+ return /* @__PURE__ */ jsx65(
5381
+ DailyQuizGame,
5382
+ {
5383
+ ...sharedProps,
5384
+ config: safeParseConfig(configJson)
5385
+ }
5386
+ );
5387
+ case "matchday-predictor":
5388
+ return /* @__PURE__ */ jsx65(
5389
+ MatchdayPredictorGame,
5390
+ {
5391
+ ...sharedProps,
5392
+ config: safeParseConfig(configJson)
5393
+ }
5394
+ );
5395
+ case "starting-xi":
5396
+ return /* @__PURE__ */ jsx65(
5397
+ StartingXiGame,
5398
+ {
5399
+ ...sharedProps,
5400
+ config: safeParseConfig(configJson)
5401
+ }
5402
+ );
5403
+ case "stat-ladder":
5404
+ return /* @__PURE__ */ jsx65(
5405
+ StatLadderGame,
5406
+ {
5407
+ ...sharedProps,
5408
+ config: safeParseConfig(configJson)
5409
+ }
5410
+ );
5411
+ case "fan-motm":
5412
+ return /* @__PURE__ */ jsx65(
5413
+ FanMotmGame,
5414
+ {
5415
+ ...sharedProps,
5416
+ config: safeParseConfig(configJson)
5417
+ }
5418
+ );
5419
+ default:
5420
+ return /* @__PURE__ */ jsx65("div", { className: "ss-w-gscreen-body", "data-testid": `game-screen-${gameId}`, children: gameId });
5421
+ }
5422
+ }
5423
+ return /* @__PURE__ */ jsxs59("div", { className: "ss-w-gscreen", children: [
5424
+ /* @__PURE__ */ jsxs59("button", { type: "button", className: "ss-w-gscreen-back", onClick: onBack, children: [
5425
+ /* @__PURE__ */ jsx65("span", { className: "ss-w-gscreen-back-arrow", "aria-hidden": "true", children: "\u2039" }),
5426
+ ui.back
5427
+ ] }),
5428
+ renderScreen()
5429
+ ] });
5430
+ }
5431
+
5432
+ // src/components/GamesPanel.tsx
5433
+ import { jsx as jsx66 } from "react/jsx-runtime";
5434
+ function GamesPanel({
5435
+ loggedIn,
5436
+ games,
5437
+ ui,
5438
+ conversation
5439
+ }) {
5440
+ const [selected, setSelected] = useState30(null);
5441
+ if (!loggedIn) return /* @__PURE__ */ jsx66(GamesLoginWall, { ui });
5442
+ if (selected !== null) {
5443
+ return /* @__PURE__ */ jsx66("div", { className: "ss-w-mon-list", children: /* @__PURE__ */ jsx66(
5444
+ GameScreenHost,
5445
+ {
5446
+ selected,
5447
+ onBack: () => setSelected(null),
5448
+ conversation: conversation ?? null,
5449
+ ui
5450
+ }
5451
+ ) });
5452
+ }
5453
+ return /* @__PURE__ */ jsx66("div", { className: "ss-w-mon-list", "data-testid": "games-hub", children: /* @__PURE__ */ jsx66(
5454
+ GamesHub,
5455
+ {
5456
+ games,
5457
+ onOpen: (g) => setSelected({ gameId: g.gameId, fixtureId: g.fixtureId, gameDay: g.gameDay }),
5458
+ ui
5459
+ }
5460
+ ) });
5461
+ }
5462
+
5463
+ // src/components/Leaderboard.tsx
5464
+ import { useState as useState31 } from "react";
5465
+
5466
+ // src/components/LeaderboardRow.tsx
5467
+ import { jsx as jsx67, jsxs as jsxs60 } from "react/jsx-runtime";
5468
+ function formatPoints(n) {
5469
+ return n.toLocaleString("en");
5470
+ }
5471
+ function LeaderboardWeeklyRow({
5472
+ row,
5473
+ isMe
5474
+ }) {
5475
+ const rankClass = `ss-w-lb2-rank${row.rank <= 3 ? " ss-w-lb2-rank--top3" : ""}`;
5476
+ return /* @__PURE__ */ jsxs60("div", { className: `ss-w-lb2-row${isMe ? " ss-w-lb2-row--you" : ""}`, children: [
5477
+ /* @__PURE__ */ jsxs60("span", { className: rankClass, children: [
5478
+ "#",
5479
+ row.rank
5480
+ ] }),
5481
+ /* @__PURE__ */ jsx67("span", { className: "ss-w-lb2-handle", children: row.handle }),
5482
+ /* @__PURE__ */ jsx67("span", { className: "ss-w-lb2-points", children: formatPoints(row.points) }),
5483
+ row.currentStreak > 0 && /* @__PURE__ */ jsxs60("span", { className: "ss-w-lb2-streak", children: [
5484
+ "\u{1F525} ",
5485
+ row.currentStreak
5486
+ ] })
5487
+ ] });
5488
+ }
5489
+ function LeaderboardAllTimeRow({
5490
+ row,
5491
+ isMe
5492
+ }) {
5493
+ const rankClass = `ss-w-lb2-rank${row.rank <= 3 ? " ss-w-lb2-rank--top3" : ""}`;
5494
+ return /* @__PURE__ */ jsxs60("div", { className: `ss-w-lb2-row${isMe ? " ss-w-lb2-row--you" : ""}`, children: [
5495
+ /* @__PURE__ */ jsxs60("span", { className: rankClass, children: [
5496
+ "#",
5497
+ row.rank
5498
+ ] }),
5499
+ /* @__PURE__ */ jsx67("span", { className: "ss-w-lb2-handle", children: row.handle }),
5500
+ /* @__PURE__ */ jsx67("span", { className: "ss-w-lb2-points", children: formatPoints(row.allTimePoints) })
5501
+ ] });
5502
+ }
5503
+
5504
+ // src/components/Leaderboard.tsx
5505
+ import { jsx as jsx68, jsxs as jsxs61 } from "react/jsx-runtime";
5506
+ function Leaderboard({
5507
+ data,
5508
+ ui
5509
+ }) {
5510
+ const [segment, setSegment] = useState31("weekly");
5511
+ const myRow = segment === "weekly" ? data.myWeeklyRow : data.myAllTimeRow;
5512
+ const offBoard = myRow !== null && myRow !== void 0 && myRow.rank === -1;
5513
+ return /* @__PURE__ */ jsxs61("div", { className: "ss-w-lb2", children: [
5514
+ /* @__PURE__ */ jsxs61("div", { className: "ss-w-seg", children: [
5515
+ /* @__PURE__ */ jsx68(
5516
+ "button",
5517
+ {
5518
+ type: "button",
5519
+ className: "ss-w-seg-btn",
5520
+ ...segment === "weekly" ? { "data-on": "" } : {},
5521
+ onClick: () => setSegment("weekly"),
5522
+ children: ui.leaderboardThisWeek
5523
+ }
5524
+ ),
5525
+ /* @__PURE__ */ jsx68(
5526
+ "button",
5527
+ {
5528
+ type: "button",
5529
+ className: "ss-w-seg-btn",
5530
+ ...segment === "alltime" ? { "data-on": "" } : {},
5531
+ onClick: () => setSegment("alltime"),
5532
+ children: ui.leaderboardAllTime
5533
+ }
5534
+ )
5535
+ ] }),
5536
+ /* @__PURE__ */ jsx68("div", { className: "ss-w-lb2-rows", children: segment === "weekly" ? data.weeklyTop.map((row) => /* @__PURE__ */ jsx68(
5537
+ LeaderboardWeeklyRow,
5538
+ {
5539
+ row,
5540
+ isMe: row.operatorUserId === data.myWeeklyRow?.operatorUserId
5541
+ },
5542
+ row.operatorUserId
5543
+ )) : data.allTimeTop.map((row) => /* @__PURE__ */ jsx68(
5544
+ LeaderboardAllTimeRow,
5545
+ {
5546
+ row,
5547
+ isMe: row.operatorUserId === data.myAllTimeRow?.operatorUserId
5548
+ },
5549
+ row.operatorUserId
5550
+ )) }),
5551
+ /* @__PURE__ */ jsx68("div", { className: "ss-w-kitline", children: "\u{1F3BD}" }),
5552
+ myRow != null && (offBoard ? /* @__PURE__ */ jsx68("div", { className: "ss-w-lbgap", children: ui.leaderboardOffBoard }) : /* @__PURE__ */ jsxs61("div", { className: "ss-w-lb2-rows", children: [
5553
+ segment === "weekly" && data.myWeeklyRow && /* @__PURE__ */ jsx68(LeaderboardWeeklyRow, { row: data.myWeeklyRow, isMe: true }),
5554
+ segment === "alltime" && data.myAllTimeRow && /* @__PURE__ */ jsx68(LeaderboardAllTimeRow, { row: data.myAllTimeRow, isMe: true })
5555
+ ] })),
5556
+ segment === "alltime" && data.myAllTimeRow && !offBoard && /* @__PURE__ */ jsx68("div", { className: "ss-w-lb2-rows", children: /* @__PURE__ */ jsx68("div", { className: "ss-w-lb2-row", children: /* @__PURE__ */ jsx68("span", { className: "ss-w-lb2-handle", children: formatPoints(data.allTimeTop.reduce((s, r) => s + r.allTimePoints, 0)) }) }) })
5557
+ ] });
5558
+ }
5559
+
5560
+ // src/components/LeaderboardPanel.tsx
5561
+ import { jsx as jsx69 } from "react/jsx-runtime";
5562
+ function LeaderboardPanel({ loggedIn, data, ui }) {
5563
+ if (!loggedIn) return /* @__PURE__ */ jsx69(GamesLoginWall, { ui });
5564
+ if (data === null) return /* @__PURE__ */ jsx69("div", { className: "ss-w-mon-list" });
5565
+ return /* @__PURE__ */ jsx69("div", { className: "ss-w-mon-list", children: /* @__PURE__ */ jsx69(Leaderboard, { data, ui }) });
5566
+ }
5567
+
3805
5568
  // src/components/ChatPanel.tsx
3806
- import { jsx as jsx52, jsxs as jsxs47 } from "react/jsx-runtime";
5569
+ import { jsx as jsx70, jsxs as jsxs62 } from "react/jsx-runtime";
3807
5570
  var FULLSCREEN_QUERY = "(max-width: 639px)";
3808
5571
  function useIsModal() {
3809
- const [modal, setModal] = useState19(false);
3810
- useEffect11(() => {
5572
+ const [modal, setModal] = useState32(false);
5573
+ useEffect14(() => {
3811
5574
  if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
3812
5575
  const mql = window.matchMedia(FULLSCREEN_QUERY);
3813
5576
  const sync = () => setModal(mql.matches);
@@ -3817,10 +5580,10 @@ function useIsModal() {
3817
5580
  }, []);
3818
5581
  return modal;
3819
5582
  }
3820
- function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery }) {
5583
+ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, gamesResult, leaderboardResult, loggedIn, conversation }) {
3821
5584
  const { state, close, stop, send, reset } = controller;
3822
5585
  const isModal = useIsModal();
3823
- useEffect11(() => {
5586
+ useEffect14(() => {
3824
5587
  const onKey = (e) => {
3825
5588
  if (e.key === "Escape") close();
3826
5589
  };
@@ -3831,11 +5594,11 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery })
3831
5594
  monitor?.setActiveTab("chat");
3832
5595
  send(text);
3833
5596
  };
3834
- useEffect11(() => {
5597
+ useEffect14(() => {
3835
5598
  if (monitor && monitor.activeTab !== "chat" && state.isStreaming) monitor.markChatActivity();
3836
5599
  }, [monitor, state.isStreaming, state.messages.length]);
3837
- return /* @__PURE__ */ jsxs47("div", { className: "ss-w-panel", role: "dialog", "aria-modal": isModal, "aria-label": ui.chatDialogLabel, children: [
3838
- /* @__PURE__ */ jsx52(
5600
+ return /* @__PURE__ */ jsxs62("div", { className: "ss-w-panel", role: "dialog", "aria-modal": isModal, "aria-label": ui.chatDialogLabel, children: [
5601
+ /* @__PURE__ */ jsx70(
3839
5602
  ChatHeader,
3840
5603
  {
3841
5604
  onClose: close,
@@ -3848,7 +5611,7 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery })
3848
5611
  moreOptionsLabel: ui.moreOptions
3849
5612
  }
3850
5613
  ),
3851
- monitor && /* @__PURE__ */ jsx52(
5614
+ monitor && /* @__PURE__ */ jsx70(
3852
5615
  TabBar,
3853
5616
  {
3854
5617
  monitor,
@@ -3856,20 +5619,23 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery })
3856
5619
  matchCount: monitor.pins.filter((p) => p.kind === "match").length,
3857
5620
  oddsCount: monitor.pins.filter((p) => p.kind !== "match").length,
3858
5621
  todayCount: discovery?.liveCount ?? 0,
3859
- hasToday: discovery ? visibleGroupsOf(discovery.groups, discovery.states).length > 0 : false
5622
+ hasToday: discovery ? visibleGroupsOf(discovery.groups, discovery.states).length > 0 : false,
5623
+ gamesEnabled: gamesResult?.enabled ?? false
3860
5624
  }
3861
5625
  ),
3862
- /* @__PURE__ */ jsx52(
5626
+ /* @__PURE__ */ jsx70(
3863
5627
  "div",
3864
5628
  {
3865
5629
  style: !monitor || monitor.activeTab === "chat" ? { display: "contents" } : { position: "absolute", inset: 0, visibility: "hidden", display: "flex", flexDirection: "column" },
3866
- children: /* @__PURE__ */ jsx52(MessageList, { controller, ui, slip, onDashboardTap, monitor })
5630
+ children: /* @__PURE__ */ jsx70(MessageList, { controller, ui, slip, onDashboardTap, monitor })
3867
5631
  }
3868
5632
  ),
3869
- monitor && discovery && monitor.activeTab === "today" && /* @__PURE__ */ jsx52(TodayPanel, { discovery, ui, monitor }),
3870
- monitor && monitor.activeTab === "following" && /* @__PURE__ */ jsx52(MatchesPanel, { monitor, ui, slip }),
3871
- monitor && monitor.activeTab === "odds" && /* @__PURE__ */ jsx52(OddsPanel, { monitor, ui, slip }),
3872
- /* @__PURE__ */ jsx52(ChatInput, { placeholder: ui.placeholder, streaming: state.isStreaming, onSend: handleSend, onStop: stop, stopLabel: ui.stopResponse, sendLabel: ui.sendMessage })
5633
+ monitor && discovery && monitor.activeTab === "today" && /* @__PURE__ */ jsx70(TodayPanel, { discovery, ui, monitor }),
5634
+ monitor && monitor.activeTab === "following" && /* @__PURE__ */ jsx70(MatchesPanel, { monitor, ui, slip }),
5635
+ monitor && monitor.activeTab === "odds" && /* @__PURE__ */ jsx70(OddsPanel, { monitor, ui, slip }),
5636
+ monitor && monitor.activeTab === "games" && gamesResult && /* @__PURE__ */ jsx70(GamesPanel, { loggedIn: !!loggedIn, games: gamesResult.games, ui, conversation }),
5637
+ monitor && monitor.activeTab === "leaderboard" && leaderboardResult && /* @__PURE__ */ jsx70(LeaderboardPanel, { loggedIn: !!loggedIn, data: leaderboardResult.data, ui }),
5638
+ /* @__PURE__ */ jsx70(ChatInput, { placeholder: ui.placeholder, streaming: state.isStreaming, onSend: handleSend, onStop: stop, stopLabel: ui.stopResponse, sendLabel: ui.sendMessage })
3873
5639
  ] });
3874
5640
  }
3875
5641
 
@@ -3883,6 +5649,7 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
3883
5649
  --ss-w-panel: #ffffff; --ss-w-bubble: #f3f5f7; --ss-w-nav: #0e1622;
3884
5650
  --ss-w-pos: #1aa563; --ss-w-neg: #e0524b;
3885
5651
  --ss-w-home: #3a63a8; --ss-w-away: #c8102e; --ss-w-track: #e9edf1;
5652
+ --ss-w-correct: #1f9d55; --ss-w-wrong: #b9bbc2;
3886
5653
  --ss-w-radius: 16px; --ss-w-offset-x: 20px; --ss-w-offset-y: 20px;
3887
5654
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
3888
5655
  font-size: 13px; line-height: 1.5; color: var(--ss-w-ink);
@@ -3894,6 +5661,7 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
3894
5661
  --ss-w-line: #2a3441; --ss-w-panel: #141b24; --ss-w-bubble: #1e2732; --ss-w-nav: #0a0f16;
3895
5662
  --ss-w-pos: #37c891; --ss-w-neg: #f0655d;
3896
5663
  --ss-w-home: #5b83c8; --ss-w-away: #e8384f; --ss-w-track: #232d3a;
5664
+ --ss-w-correct: #37c86b; --ss-w-wrong: #3a3a41;
3897
5665
  }
3898
5666
  }
3899
5667
  .ss-w-root[data-ss-w-theme="dark"] {
@@ -3902,12 +5670,14 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
3902
5670
  --ss-w-line: #2a3441; --ss-w-panel: #141b24; --ss-w-bubble: #1e2732; --ss-w-nav: #0a0f16;
3903
5671
  --ss-w-pos: #37c891; --ss-w-neg: #f0655d;
3904
5672
  --ss-w-home: #5b83c8; --ss-w-away: #e8384f; --ss-w-track: #232d3a;
5673
+ --ss-w-correct: #37c86b; --ss-w-wrong: #3a3a41;
3905
5674
  }
3906
5675
  .ss-w-root[data-ss-w-theme="light"] {
3907
5676
  --ss-w-accent: #17936a; --ss-w-cta: #f5a623; --ss-w-cta-ink: #1b1300;
3908
5677
  --ss-w-ink: #14181d; --ss-w-faint: #6b7580;
3909
5678
  --ss-w-line: #e4e8ec; --ss-w-panel: #ffffff; --ss-w-bubble: #f3f5f7; --ss-w-nav: #0e1622;
3910
5679
  --ss-w-home: #3a63a8; --ss-w-away: #c8102e; --ss-w-track: #e9edf1;
5680
+ --ss-w-correct: #1f9d55; --ss-w-wrong: #b9bbc2;
3911
5681
  }
3912
5682
 
3913
5683
  /* launcher */
@@ -4642,7 +6412,12 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
4642
6412
  .ss-w-mon-vs { font-size: 12px; font-weight: 700; color: var(--ss-w-faint); text-transform: uppercase; }
4643
6413
  .ss-w-mon-score { display: flex; align-items: baseline; justify-content: center; font-size: 26px; font-weight: 850; font-variant-numeric: tabular-nums; line-height: 1; white-space: nowrap; color: var(--ss-w-ink); }
4644
6414
  .ss-w-mon-score i { font-style: normal; color: var(--ss-w-faint); font-weight: 500; margin: 0 4px; }
4645
- .ss-w-mon-scorers { font-size: 11.5px; color: var(--ss-w-faint); overflow-wrap: anywhere; }
6415
+ .ss-w-mon-scorers { display: grid; grid-template-columns: 1fr auto 1fr; align-items: start; column-gap: 10px; font-size: 11.5px; color: var(--ss-w-faint); }
6416
+ .ss-w-mon-scorers-col { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; min-width: 0; }
6417
+ .ss-w-mon-scorers-col li { overflow-wrap: anywhere; }
6418
+ .ss-w-mon-scorers-home { text-align: right; }
6419
+ .ss-w-mon-scorers-away { text-align: left; }
6420
+ .ss-w-mon-scorers-ball { flex: none; align-self: start; line-height: 1.35; }
4646
6421
  .ss-w-mon-stats { display: flex; flex-direction: column; gap: 10px; }
4647
6422
  .ss-w-mon-stat { display: flex; flex-direction: column; gap: 5px; }
4648
6423
  .ss-w-mon-pstrip { padding: 6px 8px; border-radius: 8px; background: color-mix(in srgb, var(--ss-w-accent) 8%, transparent); }
@@ -4744,10 +6519,384 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
4744
6519
  .ss-w-drow-crest { width: 16px; height: 16px; flex: none; border-radius: 50%; object-fit: contain; background: var(--ss-w-bubble); }
4745
6520
 
4746
6521
  .ss-w-stale { font-size: 11px; font-weight: 600; color: var(--ss-w-cta); background: color-mix(in srgb, var(--ss-w-cta) 12%, var(--ss-w-panel)); border-radius: 8px; padding: 6px 9px; }
6522
+
6523
+ /* ---- Games hub (D2) ---- */
6524
+ /* Hub shell: prize banner \u2192 chips \u2192 game matrix, all in a single column */
6525
+ .ss-w-games-hub { display: flex; flex-direction: column; gap: 12px; }
6526
+
6527
+ /* Prize banner: CTA-tinted card with icon + body column (label + chips) */
6528
+ .ss-w-prize { display: flex; align-items: flex-start; gap: 10px; padding: 11px 13px; border-radius: 12px; background: color-mix(in srgb, var(--ss-w-cta) 10%, var(--ss-w-panel)); border: 1px solid color-mix(in srgb, var(--ss-w-cta) 22%, var(--ss-w-line)); }
6529
+ .ss-w-prize-icon { flex: none; font-size: 20px; line-height: 1; padding-top: 1px; }
6530
+ .ss-w-prize-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 6px; }
6531
+ .ss-w-prize-text { font-size: 12.5px; font-weight: 650; color: var(--ss-w-ink); line-height: 1.35; overflow-wrap: anywhere; }
6532
+
6533
+ /* Hub chips (streak / rank) \u2014 NOT .ss-w-chip which belongs to intent chips */
6534
+ .ss-w-g-chips { display: flex; gap: 6px; flex-wrap: wrap; }
6535
+ .ss-w-g-chip { display: inline-flex; align-items: center; font-size: 11px; font-weight: 700; border-radius: 999px; padding: 3px 10px; border: 1px solid transparent; white-space: nowrap; }
6536
+ .ss-w-g-chip--streak { color: var(--ss-w-cta-ink); background: var(--ss-w-cta); border-color: var(--ss-w-cta); }
6537
+ .ss-w-g-chip--rank { color: var(--ss-w-accent); background: color-mix(in srgb, var(--ss-w-accent) 13%, var(--ss-w-panel)); border-color: color-mix(in srgb, var(--ss-w-accent) 24%, var(--ss-w-line)); }
6538
+
6539
+ /* Game matrix: 2-column grid of tiles */
6540
+ .ss-w-gmatrix { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
6541
+
6542
+ /* Game tile: a tappable card with status-driven visual state */
6543
+ .ss-w-tile { display: flex; flex-direction: column; gap: 6px; padding: 12px; border-radius: 14px; border: 1px solid var(--ss-w-line); background: var(--ss-w-panel); cursor: pointer; text-align: left; font: inherit; color: inherit; width: 100%; min-width: 0; transition: background .12s ease; }
6544
+ .ss-w-tile:not([data-disabled]):hover { background: var(--ss-w-bubble); }
6545
+ .ss-w-tile[data-disabled] { opacity: .6; cursor: default; pointer-events: none; }
6546
+ .ss-w-tile-icon { font-size: 22px; line-height: 1; }
6547
+ .ss-w-tile-title { font-size: 13px; font-weight: 650; color: var(--ss-w-ink); line-height: 1.25; overflow-wrap: anywhere; }
6548
+ .ss-w-tile-status { font-size: 11px; color: var(--ss-w-faint); font-weight: 500; }
6549
+ .ss-w-tile-status--available { color: var(--ss-w-accent); font-weight: 600; }
6550
+ .ss-w-tile-status--in_progress { color: var(--ss-w-accent); font-weight: 600; }
6551
+ .ss-w-tile-status--played { color: var(--ss-w-correct); font-weight: 700; font-variant-numeric: tabular-nums; }
6552
+ .ss-w-tile-status--graded { color: var(--ss-w-correct); font-weight: 700; font-variant-numeric: tabular-nums; }
6553
+ /* Skill / For-fun kind chip */
6554
+ .ss-w-tile-chip { display: inline-flex; align-self: flex-start; font-size: 9.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; border-radius: 999px; padding: 2px 7px; margin-top: 2px; }
6555
+ .ss-w-tile-chip--skill { color: var(--ss-w-accent); background: color-mix(in srgb, var(--ss-w-accent) 13%, var(--ss-w-panel)); }
6556
+ .ss-w-tile-chip--fun { color: var(--ss-w-faint); background: var(--ss-w-bubble); border: 1px solid var(--ss-w-line); }
6557
+
6558
+ /* Game screen host: back-row + placeholder body */
6559
+ .ss-w-gscreen { display: flex; flex-direction: column; gap: 0; }
6560
+ .ss-w-gscreen-back { display: inline-flex; align-items: center; gap: 5px; background: none; border: none; color: var(--ss-w-accent); font: inherit; font-size: 13px; font-weight: 600; cursor: pointer; padding: 6px 0 10px; align-self: flex-start; }
6561
+ .ss-w-gscreen-back-arrow { font-size: 11px; font-weight: 700; }
6562
+ .ss-w-gscreen-body { flex: 1; display: flex; align-items: center; justify-content: center; padding: 40px 16px; color: var(--ss-w-faint); font-size: 13px; text-align: center; }
6563
+
6564
+ /* ---- Leaderboard (D2) ---- */
6565
+ /* Outer shell */
6566
+ .ss-w-lb2 { display: flex; flex-direction: column; gap: 12px; }
6567
+
6568
+ /* Segmented control: This week / All time */
6569
+ .ss-w-seg { display: inline-flex; gap: 2px; align-self: flex-start; background: var(--ss-w-bubble); border: 1px solid var(--ss-w-line); border-radius: 9px; padding: 2px; }
6570
+ .ss-w-seg-btn { font-size: 12px; font-weight: 600; border: none; border-radius: 7px; padding: 5px 12px; color: var(--ss-w-faint); background: none; cursor: pointer; font: inherit; white-space: nowrap; }
6571
+ .ss-w-seg-btn[data-on] { color: var(--ss-w-ink); background: var(--ss-w-panel); box-shadow: 0 1px 3px rgba(0,0,0,.09); }
6572
+
6573
+ /* Row list */
6574
+ .ss-w-lb2-rows { display: flex; flex-direction: column; border: 1px solid var(--ss-w-line); border-radius: 12px; overflow: hidden; background: var(--ss-w-panel); }
6575
+ .ss-w-lb2-row { display: flex; align-items: center; gap: 10px; padding: 9px 12px; border-bottom: 1px solid var(--ss-w-line); }
6576
+ .ss-w-lb2-row:last-child { border-bottom: none; }
6577
+ /* Highlighted "you" row: full-width tint via negative margin trick, contained by border-radius above */
6578
+ .ss-w-lb2-row--you { background: color-mix(in srgb, var(--ss-w-accent) 9%, var(--ss-w-panel)); }
6579
+ .ss-w-lb2-rank { flex: none; min-width: 30px; font-size: 12.5px; font-weight: 750; font-variant-numeric: tabular-nums; color: var(--ss-w-faint); }
6580
+ .ss-w-lb2-rank--top3 { color: var(--ss-w-cta); }
6581
+ .ss-w-lb2-handle { flex: 1; min-width: 0; font-size: 13px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--ss-w-ink); }
6582
+ .ss-w-lb2-points { flex: none; font-size: 13px; font-weight: 750; font-variant-numeric: tabular-nums; color: var(--ss-w-ink); }
6583
+ .ss-w-lb2-streak { flex: none; font-size: 11px; font-weight: 700; color: var(--ss-w-accent); padding-left: 4px; }
6584
+
6585
+ /* Kit-prize separator: a labelled hairline (eyebrow + two growing lines) */
6586
+ .ss-w-kitline { display: flex; align-items: center; gap: 8px; font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--ss-w-faint); }
6587
+ .ss-w-kitline::before, .ss-w-kitline::after { content: ""; flex: 1; height: 1px; background: var(--ss-w-line); }
6588
+
6589
+ /* Off-board treatment: dashed pill indicating rank is outside top N */
6590
+ .ss-w-lbgap { display: flex; align-items: center; justify-content: center; gap: 6px; padding: 8px 12px; font-size: 11.5px; color: var(--ss-w-faint); border: 1px dashed var(--ss-w-line); border-radius: 10px; }
6591
+
6592
+ /* ---- Mystery Tiger game screen (D3) ---- */
6593
+ .ss-w-gt { display: flex; flex-direction: column; gap: 10px; }
6594
+ /* Typeahead wrapper: relative so the dropdown can position under it */
6595
+ .ss-w-gtta { position: relative; }
6596
+ .ss-w-gtta-i { width: 100%; box-sizing: border-box; padding: 9px 12px; border-radius: 10px; border: 1.5px solid var(--ss-w-line); background: var(--ss-w-panel); color: var(--ss-w-ink); font: inherit; font-size: 13px; outline: none; transition: border-color .12s; }
6597
+ .ss-w-gtta-i:focus { border-color: var(--ss-w-accent); }
6598
+ .ss-w-gtta-i:disabled { opacity: .5; cursor: not-allowed; }
6599
+ .ss-w-gtta-drop { position: absolute; left: 0; right: 0; top: calc(100% + 4px); z-index: 10; background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); border-radius: 10px; max-height: 180px; overflow-y: auto; box-shadow: 0 4px 16px rgba(0,0,0,.12); }
6600
+ .ss-w-gtta-opt { padding: 9px 12px; font-size: 13px; cursor: pointer; color: var(--ss-w-ink); border-bottom: 1px solid var(--ss-w-line); }
6601
+ .ss-w-gtta-opt:last-child { border-bottom: none; }
6602
+ .ss-w-gtta-opt:hover { background: var(--ss-w-bubble); }
6603
+ /* Column header labels: one cell per attribute */
6604
+ .ss-w-gthdr { display: grid; grid-template-columns: 1fr repeat(5, 36px); gap: 4px; padding: 0 2px; }
6605
+ .ss-w-gthdr-c { font-size: 9px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--ss-w-faint); text-align: center; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
6606
+ .ss-w-gthdr-c--name { text-align: left; }
6607
+ /* Guess rows */
6608
+ .ss-w-gtrows { display: flex; flex-direction: column; gap: 4px; }
6609
+ .ss-w-gtrow { display: grid; grid-template-columns: 1fr repeat(5, 36px); gap: 4px; align-items: center; }
6610
+ .ss-w-gtrow-nm { font-size: 12px; font-weight: 600; color: var(--ss-w-ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding-right: 4px; }
6611
+ /* Verdict tiles */
6612
+ .ss-w-gtile { display: flex; flex-direction: column; align-items: center; justify-content: center; height: 36px; border-radius: 8px; font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; gap: 1px; transition: transform .1s; }
6613
+ .ss-w-gtile--exact { background: var(--ss-w-correct); color: #fff; }
6614
+ .ss-w-gtile--near { background: var(--ss-w-cta); color: var(--ss-w-cta-ink, #fff); }
6615
+ .ss-w-gtile--miss { background: var(--ss-w-bubble); color: var(--ss-w-faint); border: 1px solid var(--ss-w-line); }
6616
+ .ss-w-gtile-dir { font-size: 11px; line-height: 1; }
6617
+ /* Hint line */
6618
+ .ss-w-gt-hint { font-size: 11.5px; color: var(--ss-w-faint); text-align: center; padding: 2px 0; font-style: italic; }
6619
+ /* Outcome banner: shown when solved or failed */
6620
+ .ss-w-gt-banner { display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 14px 12px; border-radius: 12px; text-align: center; }
6621
+ .ss-w-gt-banner--solved { background: color-mix(in srgb, var(--ss-w-correct) 12%, var(--ss-w-panel)); border: 1px solid color-mix(in srgb, var(--ss-w-correct) 28%, var(--ss-w-line)); }
6622
+ .ss-w-gt-banner--failed { background: color-mix(in srgb, var(--ss-w-wrong) 8%, var(--ss-w-panel)); border: 1px solid var(--ss-w-line); }
6623
+ .ss-w-gt-banner-name { font-size: 16px; font-weight: 750; color: var(--ss-w-ink); }
6624
+ .ss-w-gt-banner-label { font-size: 12px; color: var(--ss-w-faint); }
6625
+
6626
+ /* ---- Higher or Lower game screen (D3) ---- */
6627
+ .ss-w-hl { display: flex; flex-direction: column; gap: 12px; }
6628
+ /* Stat context header: family name + season */
6629
+ .ss-w-hlctx { display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; }
6630
+ .ss-w-hlctx-fam { font-size: 14px; font-weight: 750; color: var(--ss-w-ink); }
6631
+ .ss-w-hlctx-szn { font-size: 11.5px; color: var(--ss-w-faint); font-weight: 500; }
6632
+ /* Score chip */
6633
+ .ss-w-hl-score { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; font-weight: 700; color: var(--ss-w-accent); background: color-mix(in srgb, var(--ss-w-accent) 11%, var(--ss-w-panel)); border: 1px solid color-mix(in srgb, var(--ss-w-accent) 22%, var(--ss-w-line)); border-radius: 999px; padding: 3px 10px; }
6634
+ /* Pair card: two player cards + divider */
6635
+ .ss-w-hlpair { display: flex; align-items: stretch; gap: 0; border-radius: 14px; border: 1.5px solid var(--ss-w-line); overflow: hidden; background: var(--ss-w-panel); }
6636
+ /* Player card */
6637
+ .ss-w-hlpc { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 14px 10px; text-align: center; }
6638
+ .ss-w-hlpc--b { border-left: 1px solid var(--ss-w-line); }
6639
+ .ss-w-hlpc-name { font-size: 12.5px; font-weight: 650; color: var(--ss-w-ink); line-height: 1.25; word-break: break-word; min-width: 0; }
6640
+ .ss-w-hlpc-val { font-size: 22px; font-weight: 800; color: var(--ss-w-accent); font-variant-numeric: tabular-nums; line-height: 1; }
6641
+ .ss-w-hlpc-val--hidden { color: var(--ss-w-faint); font-size: 26px; }
6642
+ .ss-w-hlpc-val--correct { color: var(--ss-w-correct); }
6643
+ .ss-w-hlpc-val--wrong { color: var(--ss-w-cta); }
6644
+ .ss-w-hlpc-badge { font-size: 9.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; border-radius: 999px; padding: 2px 8px; }
6645
+ .ss-w-hlpc-badge--correct { color: #fff; background: var(--ss-w-correct); }
6646
+ .ss-w-hlpc-badge--wrong { color: var(--ss-w-cta-ink, #fff); background: var(--ss-w-cta); }
6647
+ /* Higher / Lower buttons */
6648
+ .ss-w-hlbtns { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
6649
+ .ss-w-hlbtn { padding: 11px; border-radius: 10px; border: 1.5px solid var(--ss-w-line); background: var(--ss-w-panel); color: var(--ss-w-ink); font: inherit; font-size: 13px; font-weight: 700; cursor: pointer; transition: background .1s, border-color .1s, color .1s; }
6650
+ .ss-w-hlbtn:hover:not(:disabled) { background: var(--ss-w-bubble); border-color: var(--ss-w-accent); color: var(--ss-w-accent); }
6651
+ .ss-w-hlbtn:disabled { opacity: .5; cursor: not-allowed; }
6652
+ /* Answered pair result rows */
6653
+ .ss-w-hlresults { display: flex; flex-direction: column; gap: 4px; }
6654
+ .ss-w-hlrrow { display: flex; align-items: center; gap: 8px; padding: 7px 10px; border-radius: 8px; font-size: 12px; background: var(--ss-w-bubble); }
6655
+ .ss-w-hlrrow--correct { background: color-mix(in srgb, var(--ss-w-correct) 8%, var(--ss-w-panel)); }
6656
+ .ss-w-hlrrow--wrong { background: color-mix(in srgb, var(--ss-w-cta) 8%, var(--ss-w-panel)); }
6657
+ .ss-w-hlrrow-names { flex: 1; min-width: 0; font-weight: 600; color: var(--ss-w-ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
6658
+ .ss-w-hlrrow-pick { font-size: 11px; font-weight: 700; text-transform: uppercase; color: var(--ss-w-faint); }
6659
+ .ss-w-hlrrow-icon { font-size: 14px; flex: none; }
6660
+
6661
+ /* ---- Career Path game screen (D3) ---- */
6662
+ .ss-w-cpath { display: flex; flex-direction: column; gap: 12px; }
6663
+ /* Context header */
6664
+ .ss-w-cpath-ctx { display: flex; align-items: baseline; justify-content: space-between; flex-wrap: wrap; gap: 4px; }
6665
+ .ss-w-cpath-ctx-label { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--ss-w-faint); }
6666
+ .ss-w-cpath-ctx-count { font-size: 12px; font-weight: 600; color: var(--ss-w-accent); }
6667
+ /* Career path: vertical timeline of club spells */
6668
+ .ss-w-cpath-path { display: flex; flex-direction: column; gap: 4px; }
6669
+ /* Single club card */
6670
+ .ss-w-cpath-club { display: flex; align-items: center; gap: 10px; padding: 9px 12px; border-radius: 10px; background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); }
6671
+ .ss-w-cpath-club--loan { border-style: dashed; }
6672
+ /* Crest image / fallback */
6673
+ .ss-w-cpath-crest { width: 30px; height: 30px; object-fit: contain; flex: none; border-radius: 4px; }
6674
+ .ss-w-cpath-crest--fallback { background: var(--ss-w-bubble); border: 1px solid var(--ss-w-line); border-radius: 4px; }
6675
+ /* Club info: name + years */
6676
+ .ss-w-cpath-club-info { display: flex; flex: 1; min-width: 0; align-items: center; gap: 6px; flex-wrap: wrap; }
6677
+ .ss-w-cpath-club-name { font-size: 13px; font-weight: 650; color: var(--ss-w-ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
6678
+ .ss-w-cpath-spell-yr { font-size: 11px; color: var(--ss-w-faint); font-weight: 500; white-space: nowrap; }
6679
+ .ss-w-cpath-loan-badge { font-size: 9.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; padding: 1px 7px; border-radius: 999px; background: color-mix(in srgb, var(--ss-w-cta) 15%, var(--ss-w-panel)); color: var(--ss-w-cta-ink, #1b1300); border: 1px solid color-mix(in srgb, var(--ss-w-cta) 30%, var(--ss-w-line)); flex: none; }
6680
+ /* Hidden clubs indicator */
6681
+ .ss-w-cpath-hidden { font-size: 11.5px; color: var(--ss-w-faint); font-style: italic; text-align: center; padding: 6px 0 2px; }
6682
+ /* Hint line */
6683
+ .ss-w-cpath-hint { font-size: 11.5px; color: var(--ss-w-faint); text-align: center; padding: 2px 0; font-style: italic; }
6684
+ /* Outcome banner */
6685
+ .ss-w-cpath-banner { display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 14px 12px; border-radius: 12px; text-align: center; }
6686
+ .ss-w-cpath-banner--solved { background: color-mix(in srgb, var(--ss-w-correct) 12%, var(--ss-w-panel)); border: 1px solid color-mix(in srgb, var(--ss-w-correct) 28%, var(--ss-w-line)); }
6687
+ .ss-w-cpath-banner--failed { background: color-mix(in srgb, var(--ss-w-wrong) 8%, var(--ss-w-panel)); border: 1px solid var(--ss-w-line); }
6688
+ .ss-w-cpath-banner-name { font-size: 16px; font-weight: 750; color: var(--ss-w-ink); }
6689
+ .ss-w-cpath-banner-label { font-size: 12px; color: var(--ss-w-faint); }
6690
+
6691
+ /* ---- Beat the Grid game screen (D3) ---- */
6692
+ .ss-w-btg { display: flex; flex-direction: column; gap: 10px; }
6693
+ /* Score/context row */
6694
+ .ss-w-btg-ctx { display: flex; align-items: center; justify-content: space-between; gap: 6px; }
6695
+ .ss-w-btg-ctx-score { font-size: 13px; font-weight: 700; color: var(--ss-w-ink); }
6696
+ .ss-w-btg-ctx-left { font-size: 12px; color: var(--ss-w-faint); font-weight: 500; }
6697
+ .ss-w-btg-ctx-done { font-size: 12px; font-weight: 700; color: var(--ss-w-correct); }
6698
+ /* Grid layout \u2014 col count driven inline via style */
6699
+ .ss-w-btg-grid { display: grid; gap: 4px; width: 100%; }
6700
+ /* Generic grid cell */
6701
+ .ss-w-btg-gc { display: flex; align-items: center; justify-content: center; text-align: center; border-radius: 8px; min-height: 42px; padding: 4px; font-size: 11px; word-break: break-word; line-height: 1.2; }
6702
+ /* Corner placeholder */
6703
+ .ss-w-btg-gc--corner { background: none; }
6704
+ /* Column header */
6705
+ .ss-w-btg-gc--colhdr { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--ss-w-faint); background: var(--ss-w-bubble); border: 1px solid var(--ss-w-line); }
6706
+ /* Row header */
6707
+ .ss-w-btg-gc--rowhdr { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--ss-w-faint); background: var(--ss-w-bubble); border: 1px solid var(--ss-w-line); writing-mode: horizontal-tb; }
6708
+ /* Interactive cells */
6709
+ .ss-w-btg-cell { flex-direction: column; gap: 2px; cursor: pointer; background: var(--ss-w-panel); border: 1.5px solid var(--ss-w-line); transition: border-color .12s, background .12s; }
6710
+ .ss-w-btg-cell:hover:not(:disabled) { border-color: var(--ss-w-accent); background: var(--ss-w-bubble); }
6711
+ .ss-w-btg-cell:disabled { cursor: not-allowed; opacity: .75; }
6712
+ .ss-w-btg-cell--correct { background: color-mix(in srgb, var(--ss-w-correct) 14%, var(--ss-w-panel)); border-color: color-mix(in srgb, var(--ss-w-correct) 35%, var(--ss-w-line)); }
6713
+ .ss-w-btg-cell--wrong { background: color-mix(in srgb, var(--ss-w-wrong) 10%, var(--ss-w-panel)); }
6714
+ .ss-w-btg-cell--active { border-color: var(--ss-w-accent); }
6715
+ .ss-w-btg-cell-score { font-size: 14px; font-weight: 800; color: var(--ss-w-ink); font-variant-numeric: tabular-nums; }
6716
+ .ss-w-btg-cell-check { font-size: 12px; color: var(--ss-w-correct); line-height: 1; }
6717
+ .ss-w-btg-cell-empty { font-size: 16px; color: var(--ss-w-faint); }
6718
+ /* Scoped search sheet: slides up over the grid */
6719
+ .ss-w-btg-sheet { display: flex; flex-direction: column; gap: 10px; padding: 12px; background: var(--ss-w-panel); border: 1.5px solid var(--ss-w-line); border-radius: 14px; box-shadow: 0 4px 20px rgba(0,0,0,.1); }
6720
+ .ss-w-btg-sheet-hdr { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
6721
+ .ss-w-btg-sheet-ctx { display: flex; align-items: center; gap: 5px; flex-wrap: wrap; }
6722
+ .ss-w-btg-sheet-row { font-size: 12.5px; font-weight: 700; color: var(--ss-w-ink); }
6723
+ .ss-w-btg-sheet-sep { font-size: 13px; color: var(--ss-w-faint); font-weight: 500; }
6724
+ .ss-w-btg-sheet-col { font-size: 12.5px; font-weight: 700; color: var(--ss-w-accent); }
6725
+ .ss-w-btg-sheet-close { background: none; border: none; cursor: pointer; font-size: 14px; color: var(--ss-w-faint); padding: 2px 6px; border-radius: 6px; line-height: 1; font: inherit; }
6726
+ .ss-w-btg-sheet-close:hover { color: var(--ss-w-ink); background: var(--ss-w-bubble); }
6727
+
6728
+ /* ---- Guess the XI game screen (D3) ---- */
6729
+ .ss-w-gxi { display: flex; flex-direction: column; gap: 12px; }
6730
+ /* Context label (pool label) */
6731
+ .ss-w-gxi-ctx { display: flex; align-items: center; }
6732
+ .ss-w-gxi-ctx-label { font-size: 12px; font-weight: 700; color: var(--ss-w-faint); text-transform: uppercase; letter-spacing: .05em; }
6733
+ /* Positions pitch: compact slot grid */
6734
+ .ss-w-gxi-pitch { display: flex; flex-wrap: wrap; gap: 5px; }
6735
+ .ss-w-gxi-pslot { display: flex; flex-direction: column; align-items: center; gap: 2px; background: var(--ss-w-bubble); border: 1px solid var(--ss-w-line); border-radius: 8px; padding: 6px 10px; min-width: 52px; }
6736
+ .ss-w-gxi-pslot-pos { font-size: 10px; font-weight: 800; text-transform: uppercase; letter-spacing: .06em; color: var(--ss-w-accent); }
6737
+ .ss-w-gxi-pslot-nat { font-size: 10px; color: var(--ss-w-faint); font-weight: 500; text-align: center; line-height: 1.2; }
6738
+ /* Earned reveals */
6739
+ .ss-w-gxi-reveals { display: flex; flex-direction: column; gap: 4px; }
6740
+ .ss-w-gxi-reveal { display: flex; align-items: center; gap: 6px; padding: 7px 10px; background: color-mix(in srgb, var(--ss-w-cta) 8%, var(--ss-w-panel)); border: 1px solid color-mix(in srgb, var(--ss-w-cta) 22%, var(--ss-w-line)); border-radius: 8px; }
6741
+ .ss-w-gxi-reveal-slot { font-size: 10.5px; font-weight: 800; text-transform: uppercase; letter-spacing: .05em; color: var(--ss-w-cta-ink, #1b1300); background: var(--ss-w-cta); border-radius: 6px; padding: 1px 6px; flex: none; }
6742
+ .ss-w-gxi-reveal-val { font-size: 12.5px; font-weight: 600; color: var(--ss-w-ink); }
6743
+ /* Team pool: responsive flex grid of buttons */
6744
+ .ss-w-gxi-pool { display: flex; flex-wrap: wrap; gap: 6px; }
6745
+ .ss-w-gxi-team-btn { font: inherit; font-size: 12.5px; font-weight: 650; border-radius: 10px; padding: 9px 14px; cursor: pointer; border: 1.5px solid var(--ss-w-line); background: var(--ss-w-panel); color: var(--ss-w-ink); transition: background .1s, border-color .1s; }
6746
+ .ss-w-gxi-team-btn:hover:not(:disabled) { background: var(--ss-w-bubble); border-color: var(--ss-w-accent); }
6747
+ .ss-w-gxi-team-btn:disabled { opacity: .5; cursor: not-allowed; }
6748
+ .ss-w-gxi-team-btn--correct { background: color-mix(in srgb, var(--ss-w-correct) 14%, var(--ss-w-panel)); border-color: color-mix(in srgb, var(--ss-w-correct) 35%, var(--ss-w-line)); color: var(--ss-w-correct); }
6749
+ .ss-w-gxi-team-btn--wrong { background: color-mix(in srgb, var(--ss-w-wrong) 8%, var(--ss-w-panel)); text-decoration: line-through; opacity: .65; }
6750
+ /* Outcome banner */
6751
+ .ss-w-gxi-banner { display: flex; align-items: center; justify-content: center; padding: 10px 12px; border-radius: 10px; }
6752
+ .ss-w-gxi-banner--solved { background: color-mix(in srgb, var(--ss-w-correct) 12%, var(--ss-w-panel)); border: 1px solid color-mix(in srgb, var(--ss-w-correct) 28%, var(--ss-w-line)); }
6753
+ .ss-w-gxi-banner--failed { background: color-mix(in srgb, var(--ss-w-wrong) 8%, var(--ss-w-panel)); border: 1px solid var(--ss-w-line); }
6754
+ .ss-w-gxi-banner-label { font-size: 13px; font-weight: 700; color: var(--ss-w-ink); }
6755
+ /* Hint line */
6756
+ .ss-w-gxi-hint { font-size: 11.5px; color: var(--ss-w-faint); text-align: center; font-style: italic; }
6757
+
6758
+ /* ---- Daily Quiz game screen (D3) ---- */
6759
+ .ss-w-dq { display: flex; flex-direction: column; gap: 14px; }
6760
+ /* Score banner (post-reveal) */
6761
+ .ss-w-dq-score { display: flex; align-items: baseline; justify-content: center; gap: 4px; padding: 10px; background: color-mix(in srgb, var(--ss-w-correct) 10%, var(--ss-w-panel)); border: 1px solid color-mix(in srgb, var(--ss-w-correct) 28%, var(--ss-w-line)); border-radius: 12px; }
6762
+ .ss-w-dq-score-val { font-size: 26px; font-weight: 800; color: var(--ss-w-correct); font-variant-numeric: tabular-nums; }
6763
+ .ss-w-dq-score-label { font-size: 13px; font-weight: 650; color: var(--ss-w-faint); }
6764
+ /* Progress bar */
6765
+ .ss-w-dq-prog { height: 4px; border-radius: 999px; background: var(--ss-w-bubble); overflow: hidden; }
6766
+ .ss-w-dq-prog-fill { height: 100%; border-radius: 999px; background: var(--ss-w-accent); transition: width .25s ease; }
6767
+ /* Questions list */
6768
+ .ss-w-dq-questions { display: flex; flex-direction: column; gap: 16px; }
6769
+ /* Single question */
6770
+ .ss-w-dq-q { display: flex; flex-direction: column; gap: 8px; }
6771
+ .ss-w-dq-qstem { font-size: 13.5px; font-weight: 650; color: var(--ss-w-ink); line-height: 1.4; }
6772
+ /* Options grid: 2 across */
6773
+ .ss-w-dq-opts { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
6774
+ .ss-w-dq-qopt { display: flex; align-items: center; gap: 8px; padding: 9px 12px; border-radius: 10px; border: 1.5px solid var(--ss-w-line); background: var(--ss-w-panel); font: inherit; font-size: 12.5px; cursor: pointer; text-align: left; color: var(--ss-w-ink); transition: background .1s, border-color .1s; }
6775
+ .ss-w-dq-qopt:hover:not(:disabled) { background: var(--ss-w-bubble); border-color: var(--ss-w-accent); }
6776
+ .ss-w-dq-qopt:disabled { cursor: not-allowed; }
6777
+ .ss-w-dq-qopt--selected { border-color: var(--ss-w-accent); background: color-mix(in srgb, var(--ss-w-accent) 8%, var(--ss-w-panel)); }
6778
+ .ss-w-dq-qopt--correct { border-color: var(--ss-w-correct); background: color-mix(in srgb, var(--ss-w-correct) 12%, var(--ss-w-panel)); color: var(--ss-w-correct); }
6779
+ .ss-w-dq-qopt--wrong { border-color: color-mix(in srgb, var(--ss-w-cta) 50%, var(--ss-w-line)); background: color-mix(in srgb, var(--ss-w-cta) 8%, var(--ss-w-panel)); opacity: .75; }
6780
+ /* Option letter badge */
6781
+ .ss-w-dq-qopt-letter { flex: none; width: 20px; height: 20px; border-radius: 50%; background: var(--ss-w-bubble); border: 1px solid var(--ss-w-line); font-size: 10px; font-weight: 800; display: flex; align-items: center; justify-content: center; color: var(--ss-w-faint); }
6782
+ .ss-w-dq-qopt-text { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
6783
+ /* Why/reveal text */
6784
+ .ss-w-dq-qwhy { font-size: 11.5px; padding: 6px 10px; border-radius: 8px; line-height: 1.4; }
6785
+ .ss-w-dq-qwhy--correct { background: color-mix(in srgb, var(--ss-w-correct) 9%, var(--ss-w-panel)); color: var(--ss-w-correct); border: 1px solid color-mix(in srgb, var(--ss-w-correct) 22%, var(--ss-w-line)); }
6786
+ .ss-w-dq-qwhy--wrong { background: var(--ss-w-bubble); color: var(--ss-w-faint); border: 1px solid var(--ss-w-line); }
6787
+ /* Submit button */
6788
+ .ss-w-dq-submit { width: 100%; padding: 13px; border-radius: 12px; border: none; background: var(--ss-w-accent); color: #fff; font: inherit; font-size: 14px; font-weight: 700; cursor: pointer; transition: opacity .15s; }
6789
+ .ss-w-dq-submit:disabled { opacity: .4; cursor: not-allowed; }
6790
+ .ss-w-dq-submit:hover:not(:disabled) { opacity: .88; }
6791
+
6792
+ /* \u2500\u2500 Matchday Predictor \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
6793
+ .ss-w-mp { display: flex; flex-direction: column; gap: 14px; }
6794
+ /* Score prediction row */
6795
+ .ss-w-mp-pred-score { display: flex; align-items: center; justify-content: center; gap: 12px; padding: 12px 0; }
6796
+ .ss-w-mp-team { display: flex; flex-direction: column; align-items: center; gap: 6px; flex: 1; min-width: 0; }
6797
+ .ss-w-mp-team-name { font-size: 12px; font-weight: 650; color: var(--ss-w-ink); text-align: center; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; }
6798
+ .ss-w-mp-stepper { display: flex; align-items: center; gap: 8px; }
6799
+ .ss-w-mp-stepper-btn { width: 32px; height: 32px; border-radius: 50%; border: 1.5px solid var(--ss-w-line); background: var(--ss-w-panel); font: inherit; font-size: 18px; font-weight: 700; color: var(--ss-w-ink); cursor: pointer; display: flex; align-items: center; justify-content: center; transition: background .1s; }
6800
+ .ss-w-mp-stepper-btn:hover:not(:disabled) { background: var(--ss-w-bubble); }
6801
+ .ss-w-mp-stepper-btn:disabled { opacity: .35; cursor: not-allowed; }
6802
+ .ss-w-mp-stepper-val { font-size: 26px; font-weight: 800; color: var(--ss-w-ink); min-width: 28px; text-align: center; font-variant-numeric: tabular-nums; }
6803
+ .ss-w-mp-sep { font-size: 22px; font-weight: 700; color: var(--ss-w-faint); padding: 0 4px; }
6804
+ /* First-scorer picker */
6805
+ .ss-w-mp-scorer { display: flex; flex-direction: column; gap: 6px; }
6806
+ .ss-w-mp-scorer-label { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--ss-w-faint); }
6807
+ .ss-w-mp-scorer-list { display: flex; flex-wrap: wrap; gap: 6px; }
6808
+ .ss-w-mp-scorer-opt { padding: 6px 12px; border-radius: 999px; border: 1.5px solid var(--ss-w-line); background: var(--ss-w-panel); font: inherit; font-size: 12px; font-weight: 600; color: var(--ss-w-ink); cursor: pointer; transition: background .1s, border-color .1s; }
6809
+ .ss-w-mp-scorer-opt:hover:not(:disabled) { background: var(--ss-w-bubble); border-color: var(--ss-w-accent); }
6810
+ .ss-w-mp-scorer-opt--selected { border-color: var(--ss-w-accent); background: color-mix(in srgb, var(--ss-w-accent) 10%, var(--ss-w-panel)); color: var(--ss-w-accent); }
6811
+ .ss-w-mp-scorer-opt:disabled { opacity: .35; cursor: not-allowed; }
6812
+ /* Save button */
6813
+ .ss-w-mp-savebtn { width: 100%; padding: 13px; border-radius: 12px; border: none; background: var(--ss-w-accent); color: #fff; font: inherit; font-size: 14px; font-weight: 700; cursor: pointer; transition: opacity .15s; }
6814
+ .ss-w-mp-savebtn:disabled { opacity: .4; cursor: not-allowed; }
6815
+ .ss-w-mp-savebtn:hover:not(:disabled) { opacity: .88; }
6816
+ /* Live / pending state */
6817
+ .ss-w-mp-live { display: flex; flex-direction: column; gap: 10px; align-items: center; text-align: center; padding: 14px 0; }
6818
+ .ss-w-mp-live-score { font-size: 30px; font-weight: 800; color: var(--ss-w-ink); font-variant-numeric: tabular-nums; }
6819
+ .ss-w-mp-live-label { font-size: 12px; color: var(--ss-w-faint); font-style: italic; }
6820
+ .ss-w-mp-live-outcome { display: flex; flex-direction: column; gap: 6px; width: 100%; }
6821
+ .ss-w-mp-live-row { display: flex; align-items: center; justify-content: space-between; padding: 7px 12px; border-radius: 10px; background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); font-size: 12.5px; }
6822
+ .ss-w-mp-live-row--correct { border-color: color-mix(in srgb, var(--ss-w-correct) 40%, var(--ss-w-line)); background: color-mix(in srgb, var(--ss-w-correct) 8%, var(--ss-w-panel)); }
6823
+ .ss-w-mp-live-row-key { color: var(--ss-w-faint); font-weight: 600; }
6824
+ .ss-w-mp-live-row-val { font-weight: 700; color: var(--ss-w-ink); }
6825
+ .ss-w-mp-live-row--correct .ss-w-mp-live-row-val { color: var(--ss-w-correct); }
6826
+ /* For-fun note */
6827
+ .ss-w-mp-fun { font-size: 11px; color: var(--ss-w-faint); text-align: center; font-style: italic; }
6828
+
6829
+ /* \u2500\u2500 Starting XI \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
6830
+ .ss-w-sxi { display: flex; flex-direction: column; gap: 14px; }
6831
+ .ss-w-sxi-formation { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--ss-w-faint); text-align: center; }
6832
+ /* Formation pitch area */
6833
+ .ss-w-sxi-pitch { display: flex; flex-direction: column; gap: 10px; padding: 12px 8px; border-radius: 12px; background: color-mix(in srgb, var(--ss-w-accent) 4%, var(--ss-w-panel)); border: 1px solid var(--ss-w-line); min-height: 260px; }
6834
+ .ss-w-sxi-pitch-row { display: flex; justify-content: center; gap: 6px; flex-wrap: wrap; }
6835
+ /* Player slot */
6836
+ .ss-w-sxi-pslot { display: flex; flex-direction: column; align-items: center; gap: 3px; width: 64px; cursor: pointer; }
6837
+ .ss-w-sxi-pslot-num { width: 36px; height: 36px; border-radius: 50%; border: 2px dashed var(--ss-w-line); background: var(--ss-w-bubble); display: flex; align-items: center; justify-content: center; font-size: 11px; font-weight: 700; color: var(--ss-w-faint); transition: border-color .1s, background .1s; }
6838
+ .ss-w-sxi-pslot--filled .ss-w-sxi-pslot-num { border-style: solid; border-color: var(--ss-w-accent); background: color-mix(in srgb, var(--ss-w-accent) 12%, var(--ss-w-panel)); color: var(--ss-w-accent); }
6839
+ .ss-w-sxi-pslot-name { font-size: 9.5px; font-weight: 600; color: var(--ss-w-ink); text-align: center; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; }
6840
+ /* Squad picker */
6841
+ .ss-w-sxi-squad { display: flex; flex-direction: column; gap: 4px; max-height: 200px; overflow-y: auto; }
6842
+ .ss-w-sxi-squad-row { display: flex; align-items: center; justify-content: space-between; padding: 8px 12px; border-radius: 8px; border: 1px solid var(--ss-w-line); background: var(--ss-w-panel); cursor: pointer; transition: background .1s; }
6843
+ .ss-w-sxi-squad-row:hover:not(.ss-w-sxi-squad-row--picked) { background: var(--ss-w-bubble); }
6844
+ .ss-w-sxi-squad-row--picked { background: color-mix(in srgb, var(--ss-w-accent) 8%, var(--ss-w-panel)); border-color: var(--ss-w-accent); }
6845
+ .ss-w-sxi-squad-name { font-size: 12.5px; font-weight: 600; color: var(--ss-w-ink); }
6846
+ .ss-w-sxi-squad-pos { font-size: 10.5px; color: var(--ss-w-faint); }
6847
+ .ss-w-sxi-savebtn { width: 100%; padding: 13px; border-radius: 12px; border: none; background: var(--ss-w-accent); color: #fff; font: inherit; font-size: 14px; font-weight: 700; cursor: pointer; transition: opacity .15s; }
6848
+ .ss-w-sxi-savebtn:disabled { opacity: .4; cursor: not-allowed; }
6849
+ .ss-w-sxi-savebtn:hover:not(:disabled) { opacity: .88; }
6850
+ /* Pending / graded states */
6851
+ .ss-w-sxi-status { display: flex; flex-direction: column; align-items: center; gap: 8px; padding: 14px 12px; border-radius: 12px; background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); text-align: center; }
6852
+ .ss-w-sxi-status--graded { background: color-mix(in srgb, var(--ss-w-correct) 8%, var(--ss-w-panel)); border-color: color-mix(in srgb, var(--ss-w-correct) 28%, var(--ss-w-line)); }
6853
+ .ss-w-sxi-status-score { font-size: 28px; font-weight: 800; color: var(--ss-w-correct); font-variant-numeric: tabular-nums; }
6854
+ .ss-w-sxi-status-label { font-size: 12.5px; color: var(--ss-w-faint); }
6855
+
6856
+ /* \u2500\u2500 Stat Ladder \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
6857
+ .ss-w-sl { display: flex; flex-direction: column; gap: 14px; }
6858
+ .ss-w-sl-title { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--ss-w-faint); text-align: center; }
6859
+ /* Ladder list */
6860
+ .ss-w-sl-ladder { display: flex; flex-direction: column; gap: 6px; }
6861
+ .ss-w-sl-lrow { display: flex; align-items: center; gap: 10px; padding: 10px 12px; border-radius: 10px; border: 1px solid var(--ss-w-line); background: var(--ss-w-panel); }
6862
+ .ss-w-sl-lrow-rank { font-size: 11px; font-weight: 800; color: var(--ss-w-faint); width: 18px; flex: none; text-align: center; }
6863
+ .ss-w-sl-lrow-name { flex: 1; font-size: 13px; font-weight: 650; color: var(--ss-w-ink); }
6864
+ .ss-w-sl-lrow-stat { font-size: 13px; font-weight: 700; color: var(--ss-w-ink); font-variant-numeric: tabular-nums; }
6865
+ /* Mystery rung */
6866
+ .ss-w-sl-mystery { border: 1.5px dashed var(--ss-w-accent); background: color-mix(in srgb, var(--ss-w-accent) 5%, var(--ss-w-panel)); }
6867
+ .ss-w-sl-mystery .ss-w-sl-lrow-name { color: var(--ss-w-faint); font-style: italic; }
6868
+ /* Reveal overlay: correct / wrong */
6869
+ .ss-w-sl-lrow--correct { border-color: color-mix(in srgb, var(--ss-w-correct) 40%, var(--ss-w-line)); background: color-mix(in srgb, var(--ss-w-correct) 8%, var(--ss-w-panel)); }
6870
+ .ss-w-sl-lrow--wrong { border-color: color-mix(in srgb, var(--ss-w-wrong, #e05050) 30%, var(--ss-w-line)); background: color-mix(in srgb, var(--ss-w-wrong, #e05050) 6%, var(--ss-w-panel)); }
6871
+ /* Player picker */
6872
+ .ss-w-sl-picker { display: flex; flex-wrap: wrap; gap: 6px; }
6873
+ .ss-w-sl-picker-opt { padding: 6px 12px; border-radius: 999px; border: 1.5px solid var(--ss-w-line); background: var(--ss-w-panel); font: inherit; font-size: 12px; font-weight: 600; color: var(--ss-w-ink); cursor: pointer; transition: background .1s, border-color .1s; }
6874
+ .ss-w-sl-picker-opt:hover:not(:disabled) { background: var(--ss-w-bubble); border-color: var(--ss-w-accent); }
6875
+ .ss-w-sl-picker-opt:disabled { opacity: .35; cursor: not-allowed; }
6876
+ .ss-w-sl-reveal { display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 10px 12px; border-radius: 12px; text-align: center; font-size: 13px; font-weight: 650; color: var(--ss-w-ink); }
6877
+ .ss-w-sl-reveal--correct { background: color-mix(in srgb, var(--ss-w-correct) 10%, var(--ss-w-panel)); border: 1px solid color-mix(in srgb, var(--ss-w-correct) 28%, var(--ss-w-line)); color: var(--ss-w-correct); }
6878
+ .ss-w-sl-reveal--wrong { background: var(--ss-w-bubble); border: 1px solid var(--ss-w-line); color: var(--ss-w-faint); }
6879
+
6880
+ /* \u2500\u2500 Fan MOTM \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
6881
+ .ss-w-motm { display: flex; flex-direction: column; gap: 14px; }
6882
+ .ss-w-motm-title { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--ss-w-faint); text-align: center; }
6883
+ /* Vote candidate list */
6884
+ .ss-w-motm-votes { display: flex; flex-direction: column; gap: 6px; }
6885
+ .ss-w-motm-vrow { display: flex; align-items: center; gap: 10px; padding: 11px 14px; border-radius: 10px; border: 1.5px solid var(--ss-w-line); background: var(--ss-w-panel); cursor: pointer; transition: background .1s, border-color .1s; position: relative; overflow: hidden; }
6886
+ .ss-w-motm-vrow:hover:not(.ss-w-motm-vrow--voted):not(.ss-w-motm-vrow--result) { background: var(--ss-w-bubble); border-color: var(--ss-w-accent); }
6887
+ .ss-w-motm-vrow--voted { border-color: var(--ss-w-accent); background: color-mix(in srgb, var(--ss-w-accent) 8%, var(--ss-w-panel)); cursor: default; }
6888
+ .ss-w-motm-vrow--result { cursor: default; }
6889
+ .ss-w-motm-vrow-name { flex: 1; font-size: 13px; font-weight: 650; color: var(--ss-w-ink); position: relative; z-index: 1; }
6890
+ .ss-w-motm-vrow-pct { font-size: 12px; font-weight: 700; color: var(--ss-w-faint); position: relative; z-index: 1; font-variant-numeric: tabular-nums; }
6891
+ /* Share fill bar (behind content) */
6892
+ .ss-w-motm-vfill { position: absolute; top: 0; left: 0; height: 100%; background: color-mix(in srgb, var(--ss-w-accent) 9%, var(--ss-w-panel)); transition: width .4s ease; pointer-events: none; }
6893
+ .ss-w-motm-vrow--voted .ss-w-motm-vfill { background: color-mix(in srgb, var(--ss-w-accent) 18%, var(--ss-w-panel)); }
6894
+ /* For-fun note */
6895
+ .ss-w-motm-fun { font-size: 11px; color: var(--ss-w-faint); text-align: center; font-style: italic; }
4747
6896
  `;
4748
6897
 
4749
6898
  // src/StatsWidget.tsx
4750
- import { jsx as jsx53 } from "react/jsx-runtime";
6899
+ import { jsx as jsx71 } from "react/jsx-runtime";
4751
6900
  function buildClient(props) {
4752
6901
  try {
4753
6902
  if ("client" in props && props.client) {
@@ -4781,14 +6930,14 @@ function StatsWidget(props) {
4781
6930
  [built?.client]
4782
6931
  );
4783
6932
  const ui = useMemo3(() => normalizeUi(props.config ?? { operatorId: "", publicKey: "" }), [props.config]);
4784
- const rootRef = useRef9(null);
4785
- const introDoneRef = useRef9(false);
4786
- const markIntroDone = useCallback6(() => {
6933
+ const rootRef = useRef13(null);
6934
+ const introDoneRef = useRef13(false);
6935
+ const markIntroDone = useCallback9(() => {
4787
6936
  introDoneRef.current = true;
4788
6937
  }, []);
4789
6938
  const convStorageKey = `ss-w-conv:${cfg?.operatorId ?? ""}:${cfg?.userContext?.operatorUserId ?? "anon"}`;
4790
6939
  const controller = useChatStream(built?.conversation ?? emptyConversation(), ui.starters, built ? ui.greetingMessage : void 0, convStorageKey);
4791
- const [hasToday, setHasToday] = useState20(false);
6940
+ const [hasToday, setHasToday] = useState33(false);
4792
6941
  const monitor = useLiveMonitor({
4793
6942
  getLiveMonitor: (pins) => built ? built.conversation.getLiveMonitor(pins) : Promise.resolve(null),
4794
6943
  getMarketOdds: (matchId, dev) => built ? built.conversation.getMarketOdds(matchId, dev) : Promise.resolve(null),
@@ -4796,11 +6945,11 @@ function StatsWidget(props) {
4796
6945
  isOpen: controller.state.isOpen,
4797
6946
  hasToday
4798
6947
  });
4799
- const getSchedule = useCallback6(
6948
+ const getSchedule = useCallback9(
4800
6949
  (localDate, utcOffsetMinutes) => built ? built.conversation.getSchedule(localDate, utcOffsetMinutes) : Promise.resolve(null),
4801
6950
  [built]
4802
6951
  );
4803
- const getStates = useCallback6(
6952
+ const getStates = useCallback9(
4804
6953
  (matchIds) => built ? built.conversation.getStates(matchIds) : Promise.resolve(null),
4805
6954
  [built]
4806
6955
  );
@@ -4816,12 +6965,14 @@ function StatsWidget(props) {
4816
6965
  pinnedMatchIds
4817
6966
  });
4818
6967
  const todayHasContent = visibleGroupsOf(discovery.groups, discovery.states).length > 0;
4819
- useEffect12(() => {
6968
+ useEffect15(() => {
4820
6969
  setHasToday(todayHasContent);
4821
6970
  }, [todayHasContent]);
6971
+ const gamesResult = useGames(built?.conversation ?? null, { activeTab: monitor.activeTab });
6972
+ const leaderboardResult = useLeaderboard(built?.conversation ?? null, { activeTab: monitor.activeTab });
4822
6973
  const markTodayActivity = monitor.markTodayActivity;
4823
- const prevLiveCountRef = useRef9(0);
4824
- useEffect12(() => {
6974
+ const prevLiveCountRef = useRef13(0);
6975
+ useEffect15(() => {
4825
6976
  const rose = prevLiveCountRef.current === 0 && discovery.liveCount > 0;
4826
6977
  prevLiveCountRef.current = discovery.liveCount;
4827
6978
  if (rose) markTodayActivity();
@@ -4856,11 +7007,11 @@ function StatsWidget(props) {
4856
7007
  const operatorUserId = cfg?.userContext?.operatorUserId;
4857
7008
  const anonymousUserId = cfg?.userContext?.anonymousUserId;
4858
7009
  const conversationId = controller.state.conversationId ?? void 0;
4859
- useEffect12(() => {
7010
+ useEffect15(() => {
4860
7011
  if (!logger) return;
4861
7012
  logger.setIdentity({ operatorUserId, anonymousUserId, conversationId });
4862
7013
  }, [logger, operatorUserId, anonymousUserId, conversationId]);
4863
- useEffect12(() => {
7014
+ useEffect15(() => {
4864
7015
  if (!logger) return;
4865
7016
  const onHide = () => {
4866
7017
  logger.flushOnHide();
@@ -4877,14 +7028,27 @@ function StatsWidget(props) {
4877
7028
  logger.dispose();
4878
7029
  };
4879
7030
  }, [logger]);
4880
- useEffect12(() => {
7031
+ useEffect15(() => {
4881
7032
  if (!built || !ui.injectStyles) return;
4882
7033
  const node = rootRef.current?.getRootNode();
4883
7034
  if (node) injectStyles(node);
4884
7035
  }, [built, ui.injectStyles]);
4885
7036
  if (!built) return null;
4886
7037
  const attrs = themeAttrs(ui);
4887
- return /* @__PURE__ */ jsx53(EventLogContext.Provider, { value: logger, children: /* @__PURE__ */ jsx53("div", { ref: rootRef, className: "ss-w-root", "data-ss-w-theme": attrs["data-ss-w-theme"], "data-ss-w-pos": attrs["data-ss-w-pos"], style: attrs.style, children: controller.state.isOpen ? /* @__PURE__ */ jsx53(ChatPanel, { controller, ui, slip, onDashboardTap, monitor: monitor.enabled ? monitor : void 0, discovery }) : /* @__PURE__ */ jsx53(
7038
+ return /* @__PURE__ */ jsx71(EventLogContext.Provider, { value: logger, children: /* @__PURE__ */ jsx71("div", { ref: rootRef, className: "ss-w-root", "data-ss-w-theme": attrs["data-ss-w-theme"], "data-ss-w-pos": attrs["data-ss-w-pos"], style: attrs.style, children: controller.state.isOpen ? /* @__PURE__ */ jsx71(
7039
+ ChatPanel,
7040
+ {
7041
+ controller,
7042
+ ui,
7043
+ slip,
7044
+ onDashboardTap,
7045
+ monitor: monitor.enabled ? monitor : void 0,
7046
+ discovery,
7047
+ gamesResult,
7048
+ leaderboardResult,
7049
+ loggedIn: !!operatorUserId
7050
+ }
7051
+ ) : /* @__PURE__ */ jsx71(
4888
7052
  ChatFab,
4889
7053
  {
4890
7054
  label: ui.launcherLabel,