@sensiblestats/widget-react 0.79.0 → 0.81.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 useCallback16, useEffect as useEffect27, useMemo as useMemo5, useRef as useRef23, useState as useState45 } from "react";
2
+ import { useCallback as useCallback17, useEffect as useEffect29, useMemo as useMemo6, useRef as useRef24, useState as useState48 } from "react";
3
3
  import { StatsWidgetClient } from "@sensiblestats/widget-sdk";
4
4
 
5
5
  // src/kickoff.ts
@@ -30,6 +30,9 @@ var STRINGS = {
30
30
  dismissGreeting: "Dismiss",
31
31
  somethingWentWrong: "Something went wrong.",
32
32
  retry: "Retry",
33
+ limitDailyCap: "You've asked all your questions for today. You can ask again tomorrow.",
34
+ limitQuotaExhausted: "The assistant can't take new questions right now. Please try again later.",
35
+ limitAssistantPaused: "The assistant isn't available right now. Please try again later.",
33
36
  showLess: "Show less",
34
37
  showMore: (n) => `Show ${n} more`,
35
38
  allMarkets: (n) => `All markets (${n})`,
@@ -111,6 +114,19 @@ var STRINGS = {
111
114
  accordionSuspended: "Suspended",
112
115
  tabToday: "Today",
113
116
  sectionLive: "Live",
117
+ yourLeagues: "Your leagues",
118
+ topLeagues: "Top leagues",
119
+ topLeaguesSub: "Popular today.",
120
+ allLeagues: "All leagues",
121
+ searchLeaguesPlaceholder: "Search leagues or teams",
122
+ noLeagueResults: "No league or team matches that search.",
123
+ starOnLabel: "Add to Your leagues",
124
+ starOffLabel: "Remove from Your leagues",
125
+ starredToast: "Added to Your leagues.",
126
+ unstarredToast: "Removed from Your leagues.",
127
+ leagueDetailPosition: (index, total) => `${index} of ${total}`,
128
+ prevLeagueLabel: "Previous league",
129
+ nextLeagueLabel: "Next league",
114
130
  halfTime: "HT",
115
131
  staleStates: "Live scores can't be updated \u2014 showing the last known state.",
116
132
  tabGames: "Games",
@@ -379,6 +395,9 @@ var STRINGS = {
379
395
  dismissGreeting: "Kapat",
380
396
  somethingWentWrong: "Bir \u015Feyler ters gitti.",
381
397
  retry: "Tekrar dene",
398
+ limitDailyCap: "Bug\xFCnl\xFCk sorular\u0131n\u0131 tamamlad\u0131n. Yar\u0131n yeniden sorabilirsin.",
399
+ limitQuotaExhausted: "Asistan \u015Fu an yeni soru alam\u0131yor. L\xFCtfen daha sonra tekrar dene.",
400
+ limitAssistantPaused: "Asistan \u015Fu an kullan\u0131lam\u0131yor. L\xFCtfen daha sonra tekrar dene.",
382
401
  showLess: "Daha az g\xF6ster",
383
402
  showMore: (n) => `${n} tane daha g\xF6ster`,
384
403
  allMarkets: (n) => `T\xFCm bahisler (${n})`,
@@ -460,6 +479,19 @@ var STRINGS = {
460
479
  accordionSuspended: "Ask\u0131da",
461
480
  tabToday: "Bug\xFCn",
462
481
  sectionLive: "Canl\u0131",
482
+ yourLeagues: "Liglerin",
483
+ topLeagues: "\xD6ne \xE7\u0131kan ligler",
484
+ topLeaguesSub: "Bug\xFCn pop\xFCler.",
485
+ allLeagues: "T\xFCm ligler",
486
+ searchLeaguesPlaceholder: "Lig veya tak\u0131m ara",
487
+ noLeagueResults: "Aramana uyan lig veya tak\u0131m yok.",
488
+ starOnLabel: "Liglerine ekle",
489
+ starOffLabel: "Liglerinden \xE7\u0131kar",
490
+ starredToast: "Liglerin b\xF6l\xFCm\xFCne eklendi.",
491
+ unstarredToast: "Liglerin b\xF6l\xFCm\xFCnden \xE7\u0131kar\u0131ld\u0131.",
492
+ leagueDetailPosition: (index, total) => `${index} / ${total}`,
493
+ prevLeagueLabel: "\xD6nceki lig",
494
+ nextLeagueLabel: "Sonraki lig",
463
495
  halfTime: "\u0130Y",
464
496
  staleStates: "Canl\u0131 skorlar g\xFCncellenemiyor \u2014 son bilinen durum g\xF6steriliyor.",
465
497
  tabGames: "Oyunlar",
@@ -757,6 +789,9 @@ function normalizeUi(cfg) {
757
789
  dismissGreeting: strings.dismissGreeting,
758
790
  somethingWentWrong: strings.somethingWentWrong,
759
791
  retry: strings.retry,
792
+ limitDailyCap: strings.limitDailyCap,
793
+ limitQuotaExhausted: strings.limitQuotaExhausted,
794
+ limitAssistantPaused: strings.limitAssistantPaused,
760
795
  showLess: strings.showLess,
761
796
  showMore: strings.showMore,
762
797
  allMarkets: strings.allMarkets,
@@ -806,6 +841,19 @@ function normalizeUi(cfg) {
806
841
  tabOdds: strings.tabOdds,
807
842
  tabToday: strings.tabToday,
808
843
  sectionLive: strings.sectionLive,
844
+ yourLeagues: strings.yourLeagues,
845
+ topLeagues: strings.topLeagues,
846
+ topLeaguesSub: strings.topLeaguesSub,
847
+ allLeagues: strings.allLeagues,
848
+ searchLeaguesPlaceholder: strings.searchLeaguesPlaceholder,
849
+ noLeagueResults: strings.noLeagueResults,
850
+ starOnLabel: strings.starOnLabel,
851
+ starOffLabel: strings.starOffLabel,
852
+ starredToast: strings.starredToast,
853
+ unstarredToast: strings.unstarredToast,
854
+ leagueDetailPosition: strings.leagueDetailPosition,
855
+ prevLeagueLabel: strings.prevLeagueLabel,
856
+ nextLeagueLabel: strings.nextLeagueLabel,
809
857
  halfTime: strings.halfTime,
810
858
  staleStates: strings.staleStates,
811
859
  pinLabel: strings.pinLabel,
@@ -1704,6 +1752,51 @@ import { WidgetSdkError as WidgetSdkError2 } from "@sensiblestats/widget-sdk";
1704
1752
 
1705
1753
  // src/reducer.ts
1706
1754
  import "@sensiblestats/widget-sdk";
1755
+
1756
+ // src/limit.ts
1757
+ import { LimitError, isLimitCode } from "@sensiblestats/widget-sdk";
1758
+ var LIMIT_TIMER_MAX_MS = 60 * 60 * 1e3;
1759
+ var ZONED = /(?:Z|[+-]\d{2}:?\d{2})$/i;
1760
+ function build(code, message, resetsAt, retryAfterSeconds) {
1761
+ return {
1762
+ code,
1763
+ paused: code === "assistant_paused",
1764
+ message: message?.trim() || null,
1765
+ resetsAt: resetsAt ?? null,
1766
+ retryAfterSeconds: typeof retryAfterSeconds === "number" && Number.isFinite(retryAfterSeconds) ? retryAfterSeconds : null
1767
+ };
1768
+ }
1769
+ function limitFromEvent(data) {
1770
+ return isLimitCode(data.code) ? build(data.code, data.message, data.resetsAt, data.retryAfterSeconds) : null;
1771
+ }
1772
+ function limitFromError(error) {
1773
+ return error instanceof LimitError ? build(error.limitCode, error.limitMessage, error.resetsAt, error.retryAfter) : null;
1774
+ }
1775
+ function isLimitNotice(data) {
1776
+ return data.terminal === false && isLimitCode(data.code);
1777
+ }
1778
+ function isPaused(limit) {
1779
+ return limit?.paused === true;
1780
+ }
1781
+ function limitText(limit, ui) {
1782
+ if (limit.message) return limit.message;
1783
+ switch (limit.code) {
1784
+ case "daily_cap":
1785
+ return ui.limitDailyCap;
1786
+ case "quota_exhausted":
1787
+ return ui.limitQuotaExhausted;
1788
+ case "assistant_paused":
1789
+ return ui.limitAssistantPaused;
1790
+ }
1791
+ }
1792
+ function limitDelayMs(limit, nowMs) {
1793
+ const retry = limit.retryAfterSeconds;
1794
+ if (retry != null && Number.isFinite(retry) && retry >= 0) return Math.min(retry * 1e3, LIMIT_TIMER_MAX_MS);
1795
+ const at = limit.resetsAt ? Date.parse(ZONED.test(limit.resetsAt) ? limit.resetsAt : `${limit.resetsAt}Z`) : Number.NaN;
1796
+ return Number.isNaN(at) ? null : Math.min(Math.max(at - nowMs, 0), LIMIT_TIMER_MAX_MS);
1797
+ }
1798
+
1799
+ // src/reducer.ts
1707
1800
  var POPUP_MAX = 160;
1708
1801
  function markAwaitingLiveUpdate(messages, held = []) {
1709
1802
  if (!messages.some((m) => m.role === "assistant" && m.marketOdds.some((vm) => vm.live != null))) return messages;
@@ -1721,12 +1814,18 @@ function markAwaitingLiveUpdate(messages, held = []) {
1721
1814
  });
1722
1815
  }
1723
1816
  function initialState(starters) {
1724
- return { isOpen: false, messages: [], isStreaming: false, status: null, actionsLoading: false, starters, configuredStarters: starters, error: null, lastUserInput: null, lastDisplayText: null, popupText: null, conversationId: null };
1817
+ return { isOpen: false, messages: [], isStreaming: false, status: null, actionsLoading: false, starters, configuredStarters: starters, error: null, lastUserInput: null, lastDisplayText: null, popupText: null, conversationId: null, limit: null };
1725
1818
  }
1726
1819
  function activeTurn(state) {
1727
1820
  const last = state.messages[state.messages.length - 1];
1728
1821
  return last && last.role === "assistant" && !last.done ? last : null;
1729
1822
  }
1823
+ function settleRefused(state, limit) {
1824
+ return { ...state, limit, error: null, isStreaming: false, status: null, actionsLoading: false, messages: mapActive(state, (t) => ({ ...t, done: true })) };
1825
+ }
1826
+ function isPlainInput(input) {
1827
+ return !!input && !input.actionRef && !input.actionId && !input.grounding && !input.preset;
1828
+ }
1730
1829
  function mapActive(state, fn) {
1731
1830
  const last = state.messages[state.messages.length - 1];
1732
1831
  if (!last || last.role !== "assistant" || last.done) return state.messages;
@@ -1766,6 +1865,7 @@ function applyEvent(state, event) {
1766
1865
  case "turn_complete": {
1767
1866
  const active = activeTurn(state);
1768
1867
  const greetingLine = event.data.clubFanDashboard?.greeting?.trim() || (active?.text.trim() ?? "");
1868
+ const clearsLimit = !active?.isGreeting && isPlainInput(state.lastUserInput);
1769
1869
  const popupText = active?.isGreeting && !state.isOpen && greetingLine ? greetingLine.slice(0, POPUP_MAX) : state.popupText;
1770
1870
  return {
1771
1871
  ...state,
@@ -1773,6 +1873,7 @@ function applyEvent(state, event) {
1773
1873
  status: null,
1774
1874
  actionsLoading: false,
1775
1875
  popupText,
1876
+ limit: clearsLimit ? null : state.limit,
1776
1877
  conversationId: event.data.conversationId ?? state.conversationId,
1777
1878
  messages: mapActive(state, (t) => ({
1778
1879
  ...t,
@@ -1783,6 +1884,9 @@ function applyEvent(state, event) {
1783
1884
  };
1784
1885
  }
1785
1886
  case "error": {
1887
+ const limit = limitFromEvent(event.data);
1888
+ if (limit && event.data.terminal === false) return { ...state, limit };
1889
+ if (limit) return settleRefused(state, limit);
1786
1890
  const suppress = activeTurn(state)?.isGreeting === true;
1787
1891
  return { ...state, error: suppress ? state.error : event.data, isStreaming: false, status: null, actionsLoading: false, messages: mapActive(state, (t) => ({ ...t, done: true })) };
1788
1892
  }
@@ -1807,7 +1911,7 @@ function reducer(state, action) {
1807
1911
  case "DISMISS_POPUP":
1808
1912
  return { ...state, popupText: null };
1809
1913
  case "RESET":
1810
- return { ...initialState(state.configuredStarters), isOpen: state.isOpen };
1914
+ return { ...initialState(state.configuredStarters), isOpen: state.isOpen, limit: state.limit };
1811
1915
  case "RESTORE":
1812
1916
  return {
1813
1917
  ...state,
@@ -1821,8 +1925,13 @@ function reducer(state, action) {
1821
1925
  };
1822
1926
  case "EVENT":
1823
1927
  return applyEvent(state, action.event);
1824
- case "STREAM_ERROR":
1928
+ case "STREAM_ERROR": {
1929
+ const limit = limitFromError(action.error);
1930
+ if (limit) return settleRefused(state, limit);
1825
1931
  return { ...state, error: action.error, isStreaming: false, status: null, actionsLoading: false, messages: mapActive(state, (t) => ({ ...t, done: true })) };
1932
+ }
1933
+ case "LIMIT_EXPIRED":
1934
+ return { ...state, limit: null };
1826
1935
  case "STOP":
1827
1936
  return { ...state, isStreaming: false, status: null, actionsLoading: false, messages: mapActive(state, (t) => ({ ...t, done: true })) };
1828
1937
  case "UPDATE_LIVE_CARD": {
@@ -1995,7 +2104,7 @@ function clearConversation(storageKey) {
1995
2104
  }
1996
2105
 
1997
2106
  // src/presets.ts
1998
- var CLIENT_CAPABILITIES = ["price_presets", "price_presets_open"];
2107
+ var CLIENT_CAPABILITIES = ["price_presets", "price_presets_open", "limit_notice"];
1999
2108
  var PRICE_TILE_PREFIX = "goal-preset-";
2000
2109
  function isPriceTile(tile) {
2001
2110
  const id = tile.signal?.entityId;
@@ -2093,7 +2202,7 @@ function useChatStream(conversation, starterTexts, greetingMessage, storageKey)
2093
2202
  try {
2094
2203
  for await (const event of handle) {
2095
2204
  dispatch({ kind: "EVENT", event });
2096
- if (event.type === "turn_complete" || event.type === "error") clearFallbackTimer();
2205
+ if (event.type === "turn_complete" || event.type === "error" && !isLimitNotice(event.data)) clearFallbackTimer();
2097
2206
  }
2098
2207
  } catch (err) {
2099
2208
  if (handleRef.current === handle) clearFallbackTimer();
@@ -2106,6 +2215,7 @@ function useChatStream(conversation, starterTexts, greetingMessage, storageKey)
2106
2215
  })();
2107
2216
  }, [clearFallbackTimer]);
2108
2217
  const run = useCallback2((input, displayText) => {
2218
+ if (isPaused(stateRef.current.limit)) return;
2109
2219
  handleRef.current?.cancel();
2110
2220
  clearFallbackTimer();
2111
2221
  dispatch({ kind: "USER_SENT", input, userId: nextId(), assistantId: nextId(), displayText });
@@ -2153,6 +2263,13 @@ function useChatStream(conversation, starterTexts, greetingMessage, storageKey)
2153
2263
  greetedRef.current = true;
2154
2264
  fireGreeting();
2155
2265
  }, [fireGreeting]);
2266
+ useEffect3(() => {
2267
+ if (!state.limit) return;
2268
+ const delay = limitDelayMs(state.limit, Date.now());
2269
+ if (delay === null) return;
2270
+ const timer = setTimeout(() => dispatch({ kind: "LIMIT_EXPIRED" }), delay);
2271
+ return () => clearTimeout(timer);
2272
+ }, [state.limit]);
2156
2273
  useEffect3(() => {
2157
2274
  if (boot.stale && storageKey) clearConversation(storageKey);
2158
2275
  }, []);
@@ -2638,14 +2755,14 @@ import { useCallback as useCallback4, useEffect as useEffect5, useMemo as useMem
2638
2755
 
2639
2756
  // src/scheduleCache.ts
2640
2757
  var PREFIX = "ss-w-schedule:";
2641
- var SCHEMA_VERSION = 1;
2758
+ var SCHEMA_VERSION = 2;
2642
2759
  var TTL_MS2 = 6 * 36e5;
2643
- function scheduleCacheKey(operatorId, localDate) {
2644
- return `${PREFIX}${operatorId}:${localDate}`;
2760
+ function scheduleCacheKey(operatorId, encodedUserKey2, localDate) {
2761
+ return `${PREFIX}${operatorId}:${encodedUserKey2}:${localDate}`;
2645
2762
  }
2646
- function read(operatorId, localDate) {
2763
+ function read(operatorId, encodedUserKey2, localDate) {
2647
2764
  try {
2648
- const raw = localStorage.getItem(scheduleCacheKey(operatorId, localDate));
2765
+ const raw = localStorage.getItem(scheduleCacheKey(operatorId, encodedUserKey2, localDate));
2649
2766
  if (!raw) return null;
2650
2767
  const entry = JSON.parse(raw);
2651
2768
  if (entry.v !== SCHEMA_VERSION || !entry.payload) return null;
@@ -2654,13 +2771,13 @@ function read(operatorId, localDate) {
2654
2771
  return null;
2655
2772
  }
2656
2773
  }
2657
- function readSchedule(operatorId, localDate, nowMs) {
2658
- const entry = read(operatorId, localDate);
2774
+ function readSchedule(operatorId, encodedUserKey2, localDate, nowMs) {
2775
+ const entry = read(operatorId, encodedUserKey2, localDate);
2659
2776
  if (!entry) return null;
2660
2777
  return nowMs - entry.at > TTL_MS2 ? null : entry.payload;
2661
2778
  }
2662
- function readScheduleIgnoringTtl(operatorId, localDate) {
2663
- return read(operatorId, localDate)?.payload ?? null;
2779
+ function readScheduleIgnoringTtl(operatorId, encodedUserKey2, localDate) {
2780
+ return read(operatorId, encodedUserKey2, localDate)?.payload ?? null;
2664
2781
  }
2665
2782
  function skeletonOnly(payload) {
2666
2783
  return {
@@ -2668,9 +2785,13 @@ function skeletonOnly(payload) {
2668
2785
  groups: payload.groups.map((g) => ({
2669
2786
  competitionId: g.competitionId,
2670
2787
  competitionName: g.competitionName,
2788
+ competitionCountry: g.competitionCountry ?? null,
2671
2789
  competitionImagePath: g.competitionImagePath ?? null,
2672
2790
  rank: g.rank,
2673
2791
  expandedByDefault: g.expandedByDefault,
2792
+ isStarred: g.isStarred,
2793
+ isLearned: g.isLearned,
2794
+ learnedRank: g.learnedRank,
2674
2795
  matches: g.matches.map((m) => ({
2675
2796
  matchId: m.matchId,
2676
2797
  homeTeamName: m.homeTeamName,
@@ -2682,9 +2803,9 @@ function skeletonOnly(payload) {
2682
2803
  }))
2683
2804
  };
2684
2805
  }
2685
- function writeSchedule(operatorId, localDate, payload, nowMs) {
2686
- const keep = scheduleCacheKey(operatorId, localDate);
2687
- const mine = `${PREFIX}${operatorId}:`;
2806
+ function writeSchedule(operatorId, encodedUserKey2, localDate, payload, nowMs) {
2807
+ const keep = scheduleCacheKey(operatorId, encodedUserKey2, localDate);
2808
+ const mine = `${PREFIX}${operatorId}:${encodedUserKey2}:`;
2688
2809
  try {
2689
2810
  for (let i = localStorage.length - 1; i >= 0; i--) {
2690
2811
  const key = localStorage.key(i);
@@ -2695,6 +2816,12 @@ function writeSchedule(operatorId, localDate, payload, nowMs) {
2695
2816
  } catch {
2696
2817
  }
2697
2818
  }
2819
+ function patchScheduleStar(operatorId, encodedUserKey2, localDate, competitionId, star) {
2820
+ const entry = read(operatorId, encodedUserKey2, localDate);
2821
+ if (!entry) return;
2822
+ const groups = entry.payload.groups.map((g) => g.competitionId === competitionId ? { ...g, ...star } : g);
2823
+ writeSchedule(operatorId, encodedUserKey2, localDate, { ...entry.payload, groups }, entry.at);
2824
+ }
2698
2825
 
2699
2826
  // src/dueSet.ts
2700
2827
  var TERMINAL_PHASES = /* @__PURE__ */ new Set(["fullTime", "postponed"]);
@@ -2715,6 +2842,9 @@ function dueMatchIds(groups, states, nowMs) {
2715
2842
  var POLL_MS = 6e4;
2716
2843
  var ROLLOVER_CHECK_MS = 6e4;
2717
2844
  var STALE_AFTER_FAILURES = 2;
2845
+ function encodedUserKey(operatorUserId, anonymousUserId) {
2846
+ return encodeURIComponent(operatorUserId || anonymousUserId || "none");
2847
+ }
2718
2848
  function localDateOf(now) {
2719
2849
  const y = now.getFullYear();
2720
2850
  const m = `${now.getMonth() + 1}`.padStart(2, "0");
@@ -2725,15 +2855,12 @@ function useMatchDiscovery(opts) {
2725
2855
  const [groups, setGroups] = useState4([]);
2726
2856
  const [states, setStates] = useState4({});
2727
2857
  const [failures, setFailures] = useState4(0);
2728
- const [expanded, setExpanded] = useState4({});
2729
- const [touched, setTouched] = useState4({});
2730
2858
  const groupsRef = useRef5(groups);
2731
2859
  groupsRef.current = groups;
2732
2860
  const statesRef = useRef5(states);
2733
2861
  statesRef.current = states;
2734
2862
  const getStatesRef = useRef5(opts.getStates);
2735
2863
  getStatesRef.current = opts.getStates;
2736
- const pinnedKey = opts.pinnedMatchIds.join(",");
2737
2864
  const [localDate, setLocalDate] = useState4(() => localDateOf(/* @__PURE__ */ new Date()));
2738
2865
  useEffect5(() => {
2739
2866
  const id = setInterval(() => {
@@ -2745,7 +2872,8 @@ function useMatchDiscovery(opts) {
2745
2872
  useEffect5(() => {
2746
2873
  let cancelled = false;
2747
2874
  const utcOffsetMinutes = -(/* @__PURE__ */ new Date()).getTimezoneOffset();
2748
- const cached = readSchedule(opts.operatorId, localDate, Date.now());
2875
+ const key = encodedUserKey(opts.operatorUserId, opts.anonymousUserId);
2876
+ const cached = readSchedule(opts.operatorId, key, localDate, Date.now());
2749
2877
  if (cached) {
2750
2878
  if (!cancelled) setGroups(cached.groups);
2751
2879
  return () => {
@@ -2756,28 +2884,17 @@ function useMatchDiscovery(opts) {
2756
2884
  try {
2757
2885
  const payload = await opts.getSchedule(localDate, utcOffsetMinutes);
2758
2886
  if (cancelled || !payload) return;
2759
- writeSchedule(opts.operatorId, localDate, payload, Date.now());
2887
+ writeSchedule(opts.operatorId, key, localDate, payload, Date.now());
2760
2888
  setGroups(payload.groups);
2761
2889
  } catch {
2762
- const fallback = readScheduleIgnoringTtl(opts.operatorId, localDate);
2890
+ const fallback = readScheduleIgnoringTtl(opts.operatorId, key, localDate);
2763
2891
  if (!cancelled && fallback) setGroups(fallback.groups);
2764
2892
  }
2765
2893
  })();
2766
2894
  return () => {
2767
2895
  cancelled = true;
2768
2896
  };
2769
- }, [opts.operatorId, localDate]);
2770
- useEffect5(() => {
2771
- setExpanded((prev) => {
2772
- const next = {};
2773
- for (const group of groups) {
2774
- const hasPin = group.matches.some((m) => opts.pinnedMatchIds.includes(m.matchId));
2775
- const seeded = group.expandedByDefault || hasPin;
2776
- next[group.competitionId] = touched[group.competitionId] ? prev[group.competitionId] ?? seeded : seeded;
2777
- }
2778
- return next;
2779
- });
2780
- }, [groups, pinnedKey, touched]);
2897
+ }, [opts.operatorId, opts.operatorUserId, opts.anonymousUserId, localDate]);
2781
2898
  const tick = useCallback4(async () => {
2782
2899
  const ids = dueMatchIds(groupsRef.current, statesRef.current, Date.now());
2783
2900
  if (ids.length === 0) return;
@@ -2807,11 +2924,20 @@ function useMatchDiscovery(opts) {
2807
2924
  () => stale ? 0 : Object.values(states).filter((s) => s.phase === "live").length,
2808
2925
  [states, stale]
2809
2926
  );
2810
- const toggleGroup = useCallback4((competitionId) => {
2811
- setTouched((prev) => ({ ...prev, [competitionId]: true }));
2812
- setExpanded((prev) => ({ ...prev, [competitionId]: !prev[competitionId] }));
2813
- }, []);
2814
- return { groups, states, liveCount, stale, expanded, toggleGroup, _tick: tick };
2927
+ const starLeague = useCallback4(async (competitionId, starred) => {
2928
+ let result;
2929
+ try {
2930
+ result = await opts.postLeagueStar(competitionId, starred);
2931
+ } catch {
2932
+ return false;
2933
+ }
2934
+ if (!result) return false;
2935
+ const patch = { isStarred: result.starred, isLearned: false, learnedRank: null };
2936
+ setGroups((prev) => prev.map((g) => g.competitionId === competitionId ? { ...g, ...patch } : g));
2937
+ patchScheduleStar(opts.operatorId, encodedUserKey(opts.operatorUserId, opts.anonymousUserId), localDate, competitionId, patch);
2938
+ return true;
2939
+ }, [opts.postLeagueStar, opts.operatorId, opts.operatorUserId, opts.anonymousUserId, localDate]);
2940
+ return { groups, states, liveCount, stale, starLeague, _tick: tick };
2815
2941
  }
2816
2942
 
2817
2943
  // src/useGames.ts
@@ -3285,7 +3411,7 @@ function ChatFab({ label, greeting, popupText, logoUrl, onOpen, onDismissPopup,
3285
3411
  }
3286
3412
 
3287
3413
  // src/components/ChatPanel.tsx
3288
- import { useCallback as useCallback15, useEffect as useEffect26, useMemo as useMemo4, useRef as useRef22, useState as useState44 } from "react";
3414
+ import { useCallback as useCallback16, useEffect as useEffect28, useMemo as useMemo5, useRef as useRef23, useState as useState47 } from "react";
3289
3415
 
3290
3416
  // src/components/ChatHeader.tsx
3291
3417
  import { useEffect as useEffect12, useRef as useRef12, useState as useState10 } from "react";
@@ -5343,7 +5469,7 @@ function MessageList({ controller, ui, slip, onDashboardTap, monitor }) {
5343
5469
  ChatMessage,
5344
5470
  {
5345
5471
  message: m,
5346
- disabled: state.isStreaming,
5472
+ disabled: state.isStreaming || isPaused(state.limit),
5347
5473
  onAct: (a) => send(a.message, { actionId: a.actionId, actionRef: a.actionRef, displayText: a.label }),
5348
5474
  onTap: (tile, index) => {
5349
5475
  const displayText = tileDisplayText(tile);
@@ -5363,7 +5489,7 @@ function MessageList({ controller, ui, slip, onDashboardTap, monitor }) {
5363
5489
  /* @__PURE__ */ jsx48("span", { children: "message" in state.error ? state.error.message : ui.somethingWentWrong }),
5364
5490
  /* @__PURE__ */ jsx48("button", { type: "button", className: "ss-w-retry", onClick: () => controller.retry(), children: ui.retry })
5365
5491
  ] }) : null,
5366
- !hasUserMessage && !hasDashboard ? /* @__PURE__ */ jsx48(IntentChips, { chips: state.starters, onPick: (t) => send(t) }) : null,
5492
+ !hasUserMessage && !hasDashboard && !isPaused(state.limit) ? /* @__PURE__ */ jsx48(IntentChips, { chips: state.starters, onPick: (t) => send(t) }) : null,
5367
5493
  /* @__PURE__ */ jsx48("div", { ref: endRef, className: "ss-w-turn-spacer", "aria-hidden": "true" })
5368
5494
  ]
5369
5495
  }
@@ -5793,16 +5919,135 @@ function OddsPanel({ monitor, ui, slip }) {
5793
5919
  }) });
5794
5920
  }
5795
5921
 
5796
- // src/components/FixtureRow.tsx
5922
+ // src/components/TodayPanel.tsx
5923
+ import { useEffect as useEffect21, useId as useId2, useMemo as useMemo4, useState as useState29 } from "react";
5924
+
5925
+ // src/placement.ts
5926
+ function placeLeagues(visible, pinnedMatchIds) {
5927
+ const candidates = [];
5928
+ const candidateIds = /* @__PURE__ */ new Set();
5929
+ for (const g of visible) {
5930
+ if (g.isStarred) {
5931
+ candidates.push(g);
5932
+ candidateIds.add(g.competitionId);
5933
+ }
5934
+ }
5935
+ let budget = 4;
5936
+ const pinned = visible.find(
5937
+ (g) => !candidateIds.has(g.competitionId) && g.matches.some((m) => pinnedMatchIds.includes(m.matchId))
5938
+ ) ?? null;
5939
+ if (pinned && budget > 0) {
5940
+ candidates.push(pinned);
5941
+ candidateIds.add(pinned.competitionId);
5942
+ budget -= 1;
5943
+ }
5944
+ const learned = visible.filter((g) => g.isLearned && !candidateIds.has(g.competitionId)).sort((a, b) => (a.learnedRank ?? Number.MAX_SAFE_INTEGER) - (b.learnedRank ?? Number.MAX_SAFE_INTEGER));
5945
+ for (const g of learned) {
5946
+ if (budget <= 0) break;
5947
+ candidates.push(g);
5948
+ candidateIds.add(g.competitionId);
5949
+ budget -= 1;
5950
+ }
5951
+ const personal = candidates.length > 0;
5952
+ const pool = personal ? candidates : visible.slice(0, 4);
5953
+ const poolIds = personal ? candidateIds : new Set(pool.map((g) => g.competitionId));
5954
+ const others = visible.filter((g) => !poolIds.has(g.competitionId));
5955
+ return { personal, candidates: pool, others, order: [...pool, ...others], pinnedCompetitionId: pinned?.competitionId ?? null };
5956
+ }
5957
+ function starClickable(group, pinnedCompetitionId) {
5958
+ return group.isStarred || group.competitionId !== pinnedCompetitionId;
5959
+ }
5960
+
5961
+ // src/search.ts
5962
+ function foldSearchText(s) {
5963
+ return s.replace(/İ/g, "I").replace(/ı/g, "i").normalize("NFD").replace(/[̀-ͯ]/g, "").toLowerCase();
5964
+ }
5965
+ function matchesQuery(group, query) {
5966
+ const q = foldSearchText(query.trim());
5967
+ if (!q) return true;
5968
+ if (foldSearchText(group.competitionName).includes(q)) return true;
5969
+ if (group.competitionCountry && foldSearchText(group.competitionCountry).includes(q)) return true;
5970
+ return group.matches.some(
5971
+ (m) => foldSearchText(m.homeTeamName).includes(q) || foldSearchText(m.awayTeamName).includes(q)
5972
+ );
5973
+ }
5974
+
5975
+ // src/useStarTap.ts
5976
+ import { useCallback as useCallback13, useRef as useRef17, useState as useState27 } from "react";
5977
+ function useStarTap(starLeague) {
5978
+ const [pendingId, setPendingId] = useState27(null);
5979
+ const pendingRef = useRef17(null);
5980
+ const tap = useCallback13(async (competitionId, next) => {
5981
+ if (pendingRef.current !== null) return false;
5982
+ pendingRef.current = competitionId;
5983
+ setPendingId(competitionId);
5984
+ try {
5985
+ return await starLeague(competitionId, next);
5986
+ } finally {
5987
+ pendingRef.current = null;
5988
+ setPendingId(null);
5989
+ }
5990
+ }, [starLeague]);
5991
+ return { pendingId, tap };
5992
+ }
5993
+
5994
+ // src/components/LeagueTile.tsx
5797
5995
  import { jsx as jsx55, jsxs as jsxs50 } from "react/jsx-runtime";
5996
+ var STAR_PATH = "M12 2.5l2.9 5.9 6.5.95-4.7 4.58 1.1 6.47L12 17.35 6.1 20.4l1.1-6.47L2.5 9.35l6.5-.95z";
5997
+ function LeagueTile({ group, starClickable: starClickable2, disambiguate, onOpen, starTap, ui }) {
5998
+ const onStarClick = () => {
5999
+ void starTap.tap(group.competitionId, !group.isStarred);
6000
+ };
6001
+ return /* @__PURE__ */ jsxs50("div", { className: "ss-w-today-tile", children: [
6002
+ /* @__PURE__ */ jsxs50("button", { type: "button", className: "ss-w-today-tile-body", onClick: onOpen, children: [
6003
+ /* @__PURE__ */ jsx55(Crest2, { url: group.competitionImagePath ?? void 0, name: group.competitionName, kind: "comp" }),
6004
+ /* @__PURE__ */ jsxs50("span", { className: "ss-w-today-tile-name", children: [
6005
+ group.competitionName,
6006
+ disambiguate && group.competitionCountry ? /* @__PURE__ */ jsxs50("span", { className: "ss-w-today-tile-country", children: [
6007
+ " (",
6008
+ group.competitionCountry,
6009
+ ")"
6010
+ ] }) : null
6011
+ ] })
6012
+ ] }),
6013
+ /* @__PURE__ */ jsx55(
6014
+ "button",
6015
+ {
6016
+ type: "button",
6017
+ className: "ss-w-today-tile-star",
6018
+ "aria-pressed": group.isStarred,
6019
+ "aria-label": group.isStarred ? ui.starOffLabel : ui.starOnLabel,
6020
+ disabled: !starClickable2 || starTap.pendingId !== null,
6021
+ onClick: onStarClick,
6022
+ children: /* @__PURE__ */ jsx55("svg", { viewBox: "0 0 24 24", "aria-hidden": "true", children: /* @__PURE__ */ jsx55(
6023
+ "path",
6024
+ {
6025
+ d: STAR_PATH,
6026
+ fill: group.isStarred ? "currentColor" : "none",
6027
+ stroke: group.isStarred ? "none" : "currentColor",
6028
+ strokeWidth: 2,
6029
+ strokeLinejoin: "round",
6030
+ strokeLinecap: "round"
6031
+ }
6032
+ ) })
6033
+ }
6034
+ )
6035
+ ] });
6036
+ }
6037
+
6038
+ // src/components/LeagueDetail.tsx
6039
+ import { useEffect as useEffect20, useState as useState28 } from "react";
6040
+
6041
+ // src/components/FixtureRow.tsx
6042
+ import { jsx as jsx56, jsxs as jsxs51 } from "react/jsx-runtime";
5798
6043
  function kickoffLabel(kickoffUnix) {
5799
6044
  const d = new Date(kickoffUnix * 1e3);
5800
6045
  return `${`${d.getHours()}`.padStart(2, "0")}:${`${d.getMinutes()}`.padStart(2, "0")}`;
5801
6046
  }
5802
6047
  function Side({ name, crest, away = false }) {
5803
- return /* @__PURE__ */ jsxs50("span", { className: away ? "ss-w-drow-side ss-w-drow-side--away" : "ss-w-drow-side", children: [
5804
- crest ? /* @__PURE__ */ jsx55("img", { className: "ss-w-drow-crest", src: crest, alt: "" }) : null,
5805
- /* @__PURE__ */ jsx55("span", { className: "ss-w-drow-nm", children: name })
6048
+ return /* @__PURE__ */ jsxs51("span", { className: away ? "ss-w-drow-side ss-w-drow-side--away" : "ss-w-drow-side", children: [
6049
+ crest ? /* @__PURE__ */ jsx56("img", { className: "ss-w-drow-crest", src: crest, alt: "" }) : null,
6050
+ /* @__PURE__ */ jsx56("span", { className: "ss-w-drow-nm", children: name })
5806
6051
  ] });
5807
6052
  }
5808
6053
  function FixtureRow({ match, state, stale, ui, monitor }) {
@@ -5811,100 +6056,310 @@ function FixtureRow({ match, state, stale, ui, monitor }) {
5811
6056
  const score = hasScore ? `${state.homeScore}\u2013${state.awayScore}` : void 0;
5812
6057
  const ticked = state?.phase === "live" ? state.minuteLabel ?? null : null;
5813
6058
  const when = state?.isHalfTime && !stale ? ui.halfTime : isLive ? ticked ?? "\u2014" : state?.phase === "live" ? "\u2014" : kickoffLabel(match.kickoffUnix);
5814
- return /* @__PURE__ */ jsxs50("div", { className: isLive || state?.isHalfTime ? "ss-w-drow ss-w-drow--live" : "ss-w-drow", children: [
5815
- /* @__PURE__ */ jsx55("span", { className: isLive || state?.isHalfTime ? "ss-w-drow-when ss-w-drow-when--live" : "ss-w-drow-when", children: when }),
5816
- /* @__PURE__ */ jsxs50("span", { className: "ss-w-drow-fx", children: [
5817
- /* @__PURE__ */ jsx55(Side, { name: match.homeTeamName, crest: match.homeTeamImagePath }),
5818
- /* @__PURE__ */ jsx55("span", { className: hasScore ? "ss-w-drow-sc" : "ss-w-drow-sc ss-w-drow-sc--idle", children: score ?? "\u2013" }),
5819
- /* @__PURE__ */ jsx55(Side, { name: match.awayTeamName, crest: match.awayTeamImagePath, away: true })
6059
+ return /* @__PURE__ */ jsxs51("div", { className: isLive || state?.isHalfTime ? "ss-w-drow ss-w-drow--live" : "ss-w-drow", children: [
6060
+ /* @__PURE__ */ jsx56("span", { className: isLive || state?.isHalfTime ? "ss-w-drow-when ss-w-drow-when--live" : "ss-w-drow-when", children: when }),
6061
+ /* @__PURE__ */ jsxs51("span", { className: "ss-w-drow-fx", children: [
6062
+ /* @__PURE__ */ jsx56(Side, { name: match.homeTeamName, crest: match.homeTeamImagePath }),
6063
+ /* @__PURE__ */ jsx56("span", { className: hasScore ? "ss-w-drow-sc" : "ss-w-drow-sc ss-w-drow-sc--idle", children: score ?? "\u2013" }),
6064
+ /* @__PURE__ */ jsx56(Side, { name: match.awayTeamName, crest: match.awayTeamImagePath, away: true })
5820
6065
  ] }),
5821
- /* @__PURE__ */ jsx55(PinToggle, { ui, monitor, pin: { kind: "match", matchId: match.matchId } })
6066
+ /* @__PURE__ */ jsx56(PinToggle, { ui, monitor, pin: { kind: "match", matchId: match.matchId } })
5822
6067
  ] });
5823
6068
  }
5824
6069
 
5825
- // src/components/CompetitionGroup.tsx
5826
- import { jsx as jsx56, jsxs as jsxs51 } from "react/jsx-runtime";
5827
- function CompetitionGroup({ group, open, onToggle, states, stale, ui, monitor, disambiguate = false }) {
6070
+ // src/components/LeagueDetail.tsx
6071
+ import { jsx as jsx57, jsxs as jsxs52 } from "react/jsx-runtime";
6072
+ var STAR_PATH2 = "M12 2.5l2.9 5.9 6.5.95-4.7 4.58 1.1 6.47L12 17.35 6.1 20.4l1.1-6.47L2.5 9.35l6.5-.95z";
6073
+ function LeagueDetail({ group, position, states, stale, ui, monitor, starTap, onBack, onPrev, onNext }) {
6074
+ const [toast, setToast] = useState28(null);
6075
+ useEffect20(() => {
6076
+ setToast(null);
6077
+ }, [group.competitionId]);
6078
+ useEffect20(() => {
6079
+ if (toast === null) return;
6080
+ const id = setTimeout(() => setToast(null), 4e3);
6081
+ return () => clearTimeout(id);
6082
+ }, [toast]);
5828
6083
  const own = group.matches.filter((m) => !isTreatedLive(states[m.matchId], stale));
5829
- const hasLive = own.length !== group.matches.length;
5830
- if (own.length === 0) {
5831
- return null;
5832
- }
5833
- return /* @__PURE__ */ jsxs51("div", { className: "ss-w-grp", children: [
5834
- /* @__PURE__ */ jsxs51("button", { type: "button", className: "ss-w-grp-head", "aria-expanded": open, onClick: onToggle, children: [
5835
- /* @__PURE__ */ jsx56("span", { className: "ss-w-grp-chev", children: open ? "\u25BE" : "\u25B8" }),
5836
- hasLive && /* @__PURE__ */ jsx56("span", { className: "ss-w-sec-dot", "aria-hidden": "true" }),
5837
- /* @__PURE__ */ jsxs51("span", { className: "ss-w-grp-name", children: [
5838
- group.competitionName,
5839
- disambiguate && group.competitionCountry ? /* @__PURE__ */ jsxs51("span", { className: "ss-w-grp-country", children: [
5840
- " (",
5841
- group.competitionCountry,
5842
- ")"
5843
- ] }) : null
5844
- ] }),
5845
- /* @__PURE__ */ jsx56("span", { className: "ss-w-grp-count", children: own.length })
6084
+ const onStarClick = () => {
6085
+ const next = !group.isStarred;
6086
+ void starTap.tap(group.competitionId, next).then((ok) => {
6087
+ if (ok) setToast(next ? ui.starredToast : ui.unstarredToast);
6088
+ });
6089
+ };
6090
+ return /* @__PURE__ */ jsxs52("div", { className: "ss-w-today-detail", children: [
6091
+ /* @__PURE__ */ jsxs52("div", { className: "ss-w-today-detail-head", children: [
6092
+ /* @__PURE__ */ jsx57("button", { type: "button", className: "ss-w-today-detail-back", "aria-label": ui.back, onClick: onBack, children: /* @__PURE__ */ jsx57(ChevronIcon, {}) }),
6093
+ /* @__PURE__ */ jsx57(Crest2, { url: group.competitionImagePath ?? void 0, name: group.competitionName, kind: "comp" }),
6094
+ /* @__PURE__ */ jsx57("span", { className: "ss-w-today-detail-name", children: group.competitionName }),
6095
+ /* @__PURE__ */ jsx57(
6096
+ "button",
6097
+ {
6098
+ type: "button",
6099
+ className: "ss-w-today-detail-star",
6100
+ "aria-pressed": group.isStarred,
6101
+ "aria-label": group.isStarred ? ui.starOffLabel : ui.starOnLabel,
6102
+ disabled: starTap.pendingId !== null,
6103
+ onClick: onStarClick,
6104
+ children: /* @__PURE__ */ jsx57("svg", { viewBox: "0 0 24 24", "aria-hidden": "true", children: /* @__PURE__ */ jsx57(
6105
+ "path",
6106
+ {
6107
+ d: STAR_PATH2,
6108
+ fill: group.isStarred ? "currentColor" : "none",
6109
+ stroke: group.isStarred ? "none" : "currentColor",
6110
+ strokeWidth: 2,
6111
+ strokeLinejoin: "round",
6112
+ strokeLinecap: "round"
6113
+ }
6114
+ ) })
6115
+ }
6116
+ )
5846
6117
  ] }),
5847
- open && /* @__PURE__ */ jsx56("div", { className: "ss-w-grp-body", children: own.map((m) => /* @__PURE__ */ jsx56(FixtureRow, { match: m, state: states[m.matchId], stale, ui, monitor }, m.matchId)) })
6118
+ /* @__PURE__ */ jsxs52("div", { className: "ss-w-today-detail-nav", children: [
6119
+ /* @__PURE__ */ jsx57(
6120
+ "button",
6121
+ {
6122
+ type: "button",
6123
+ className: "ss-w-today-detail-prev",
6124
+ "aria-label": ui.prevLeagueLabel,
6125
+ disabled: position.index <= 1,
6126
+ onClick: onPrev,
6127
+ children: /* @__PURE__ */ jsx57(ChevronIcon, {})
6128
+ }
6129
+ ),
6130
+ /* @__PURE__ */ jsx57("span", { className: "ss-w-today-detail-pos", children: ui.leagueDetailPosition(position.index, position.total) }),
6131
+ /* @__PURE__ */ jsx57(
6132
+ "button",
6133
+ {
6134
+ type: "button",
6135
+ className: "ss-w-today-detail-next",
6136
+ "aria-label": ui.nextLeagueLabel,
6137
+ disabled: position.index >= position.total,
6138
+ onClick: onNext,
6139
+ children: /* @__PURE__ */ jsx57(ChevronIcon, {})
6140
+ }
6141
+ )
6142
+ ] }),
6143
+ /* @__PURE__ */ jsxs52("div", { className: "ss-w-today-detail-body", children: [
6144
+ /* @__PURE__ */ jsx57("span", { className: "ss-w-today-detail-count", children: own.length }),
6145
+ own.map((m) => /* @__PURE__ */ jsx57(FixtureRow, { match: m, state: states[m.matchId], stale, ui, monitor }, m.matchId))
6146
+ ] }),
6147
+ toast !== null && /* @__PURE__ */ jsx57("p", { className: "ss-w-today-toast", role: "status", "aria-live": "polite", children: toast })
6148
+ ] });
6149
+ }
6150
+
6151
+ // src/components/games/ui/icons.tsx
6152
+ import { jsx as jsx58 } from "react/jsx-runtime";
6153
+ var svg = (size, children, fill = false) => /* @__PURE__ */ jsx58(
6154
+ "svg",
6155
+ {
6156
+ width: size,
6157
+ height: size,
6158
+ viewBox: "0 0 24 24",
6159
+ fill: fill ? "currentColor" : "none",
6160
+ stroke: fill ? "none" : "currentColor",
6161
+ strokeWidth: 2.2,
6162
+ strokeLinecap: "round",
6163
+ strokeLinejoin: "round",
6164
+ "aria-hidden": "true",
6165
+ children
6166
+ }
6167
+ );
6168
+ var IconChevronLeft = ({ size = 20 }) => svg(size, /* @__PURE__ */ jsx58("path", { d: "M15 18l-6-6 6-6" }));
6169
+ var IconLock = ({ size = 14 }) => svg(size, [/* @__PURE__ */ jsx58("rect", { x: "5", y: "11", width: "14", height: "10", rx: "2" }, "a"), /* @__PURE__ */ jsx58("path", { d: "M8 11V7a4 4 0 0 1 8 0v4" }, "b")]);
6170
+ var IconCheck = ({ size = 14 }) => svg(size, /* @__PURE__ */ jsx58("path", { d: "M5 12l5 5 9-10" }));
6171
+ var IconClose = ({ size = 16 }) => svg(size, /* @__PURE__ */ jsx58("path", { d: "M6 6l12 12M18 6L6 18" }));
6172
+ var IconSearch = ({ size = 18 }) => svg(size, [/* @__PURE__ */ jsx58("circle", { cx: "11", cy: "11", r: "7" }, "a"), /* @__PURE__ */ jsx58("path", { d: "M20 20l-3.5-3.5" }, "b")]);
6173
+ var IconPlus = ({ size = 20 }) => svg(size, /* @__PURE__ */ jsx58("path", { d: "M12 5v14M5 12h14" }));
6174
+ var IconBulb = ({ size = 16 }) => svg(size, [/* @__PURE__ */ jsx58("path", { d: "M9 18h6M10 21h4" }, "a"), /* @__PURE__ */ jsx58("path", { d: "M12 3a6 6 0 0 0-3.5 10.9V16h7v-2.1A6 6 0 0 0 12 3z" }, "b")]);
6175
+ var IconArrowUp = ({ size = 12 }) => svg(size, /* @__PURE__ */ jsx58("path", { d: "M12 19V5M5 12l7-7 7 7" }));
6176
+ var IconArrowDown = ({ size = 12 }) => svg(size, /* @__PURE__ */ jsx58("path", { d: "M12 5v14M19 12l-7 7-7-7" }));
6177
+ var IconCalendar = ({ size = 18 }) => svg(size, [/* @__PURE__ */ jsx58("rect", { x: "4", y: "5", width: "16", height: "15", rx: "2" }, "a"), /* @__PURE__ */ jsx58("path", { d: "M4 10h16M9 3v4M15 3v4" }, "b")]);
6178
+ var IconShield = ({ size = 18 }) => svg(size, /* @__PURE__ */ jsx58("path", { d: "M12 3l7 3v6c0 5-3 8-7 9-4-1-7-4-7-9V6z" }));
6179
+ var IconFlag = ({ size = 18 }) => svg(size, /* @__PURE__ */ jsx58("path", { d: "M5 21V4M5 4h12l-2 4 2 4H5" }));
6180
+ var IconBall = ({ size = 18 }) => svg(size, [/* @__PURE__ */ jsx58("circle", { cx: "12", cy: "12", r: "9" }, "a"), /* @__PURE__ */ jsx58("path", { d: "M12 7l4 3-1.5 4.5h-5L8 10z" }, "b")]);
6181
+ var IconBoot = ({ size = 18 }) => svg(size, /* @__PURE__ */ jsx58("path", { d: "M4 6h6l1 6 8 3v3H4z" }));
6182
+ var IconGloves = ({ size = 18 }) => svg(size, /* @__PURE__ */ jsx58("path", { d: "M7 21v-8l-2-3V6a1.5 1.5 0 0 1 3 0v3V4a1.5 1.5 0 0 1 3 0v5V3.5a1.5 1.5 0 0 1 3 0V9V5a1.5 1.5 0 0 1 3 0v9l-2 3v4z" }));
6183
+ var IconFlame = ({ size = 16 }) => svg(size, /* @__PURE__ */ jsx58("path", { d: "M12 3c1 4 5 5 5 10a5 5 0 0 1-10 0c0-3 2-4 2-7 1.5 1 2 2 2 3 1-2 1-4 1-6z" }), true);
6184
+
6185
+ // src/components/games/ui/SearchField.tsx
6186
+ import { jsx as jsx59, jsxs as jsxs53 } from "react/jsx-runtime";
6187
+ function SearchField({ id, label, labelHidden = false, placeholder, value, onChange, disabled, inputRef, onKeyDown }) {
6188
+ return /* @__PURE__ */ jsxs53("div", { className: "ss-g-search", children: [
6189
+ /* @__PURE__ */ jsx59("label", { htmlFor: id, className: labelHidden ? "ss-g-sr" : "ss-g-search-label", children: label }),
6190
+ /* @__PURE__ */ jsxs53("div", { className: "ss-g-search-box", children: [
6191
+ /* @__PURE__ */ jsx59(IconSearch, {}),
6192
+ /* @__PURE__ */ jsx59(
6193
+ "input",
6194
+ {
6195
+ id,
6196
+ ref: inputRef,
6197
+ type: "text",
6198
+ autoComplete: "off",
6199
+ placeholder,
6200
+ value,
6201
+ disabled,
6202
+ onKeyDown,
6203
+ onChange: (e) => onChange(e.target.value)
6204
+ }
6205
+ )
6206
+ ] })
5848
6207
  ] });
5849
6208
  }
5850
6209
 
5851
6210
  // src/components/TodayPanel.tsx
5852
- import { Fragment as Fragment7, jsx as jsx57, jsxs as jsxs52 } from "react/jsx-runtime";
6211
+ import { Fragment as Fragment7, jsx as jsx60, jsxs as jsxs54 } from "react/jsx-runtime";
5853
6212
  function TodayPanel({ discovery, ui, monitor }) {
5854
- const { groups, states, stale, expanded, toggleGroup } = discovery;
6213
+ const { groups, states, stale, starLeague } = discovery;
6214
+ const searchId = useId2();
6215
+ const [query, setQuery] = useState29("");
6216
+ const [selectedCompetitionId, setSelectedCompetitionId] = useState29(null);
6217
+ const [toast, setToast] = useState29(null);
6218
+ useEffect21(() => {
6219
+ if (toast === null) return;
6220
+ const id = setTimeout(() => setToast(null), 4e3);
6221
+ return () => clearTimeout(id);
6222
+ }, [toast]);
5855
6223
  const visibleGroups = visibleGroupsOf(groups, states);
5856
- const liveRows = stale ? [] : visibleGroups.flatMap((group) => group.matches.filter((m) => isTreatedLive(states[m.matchId], stale)).map((match) => ({ match, rank: group.rank }))).sort((a, b) => a.rank - b.rank);
6224
+ const pinnedMatchIds = useMemo4(
6225
+ () => monitor.pins.filter((p) => p.kind === "match").map((p) => p.matchId),
6226
+ [monitor.pins]
6227
+ );
6228
+ const placement = useMemo4(() => placeLeagues(visibleGroups, pinnedMatchIds), [visibleGroups, pinnedMatchIds]);
6229
+ const starTap = useStarTap(starLeague);
6230
+ const gridStarTap = useMemo4(() => ({
6231
+ pendingId: starTap.pendingId,
6232
+ tap: async (competitionId, next) => {
6233
+ const ok = await starTap.tap(competitionId, next);
6234
+ if (ok) setToast(next ? "starred" : "unstarred");
6235
+ return ok;
6236
+ }
6237
+ }), [starTap, starTap.pendingId]);
5857
6238
  const nameCounts = visibleGroups.reduce((acc, g) => {
5858
6239
  acc[g.competitionName] = (acc[g.competitionName] ?? 0) + 1;
5859
6240
  return acc;
5860
6241
  }, {});
5861
- return /* @__PURE__ */ jsxs52("div", { className: "ss-w-mon-list", children: [
5862
- stale && /* @__PURE__ */ jsx57("div", { className: "ss-w-stale", children: ui.staleStates }),
5863
- liveRows.length > 0 && /* @__PURE__ */ jsxs52(Fragment7, { children: [
5864
- /* @__PURE__ */ jsxs52("div", { className: "ss-w-sec-head", children: [
5865
- /* @__PURE__ */ jsx57("span", { className: "ss-w-sec-dot", "aria-hidden": "true" }),
5866
- ui.sectionLive
5867
- ] }),
5868
- /* @__PURE__ */ jsx57("div", { className: "ss-w-today-live", children: liveRows.map(({ match }) => /* @__PURE__ */ jsx57(
5869
- FixtureRow,
5870
- {
5871
- match,
5872
- state: states[match.matchId],
5873
- stale,
5874
- ui,
5875
- monitor
5876
- },
5877
- match.matchId
5878
- )) })
6242
+ const openIndex = selectedCompetitionId === null ? -1 : placement.order.findIndex((g) => g.competitionId === selectedCompetitionId);
6243
+ const openGroup = openIndex === -1 ? void 0 : placement.order[openIndex];
6244
+ useEffect21(() => {
6245
+ if (selectedCompetitionId !== null && openGroup === void 0) setSelectedCompetitionId(null);
6246
+ }, [selectedCompetitionId, openGroup]);
6247
+ const liveRows = stale ? [] : visibleGroups.flatMap((group) => group.matches.filter((m) => isTreatedLive(states[m.matchId], stale)).map((match) => ({ match, rank: group.rank }))).sort((a, b) => a.rank - b.rank);
6248
+ const liveBand = liveRows.length > 0 && /* @__PURE__ */ jsxs54(Fragment7, { children: [
6249
+ /* @__PURE__ */ jsxs54("div", { className: "ss-w-sec-head", children: [
6250
+ /* @__PURE__ */ jsx60("span", { className: "ss-w-sec-dot", "aria-hidden": "true" }),
6251
+ ui.sectionLive
5879
6252
  ] }),
5880
- visibleGroups.map((group) => /* @__PURE__ */ jsx57(
5881
- CompetitionGroup,
6253
+ /* @__PURE__ */ jsx60("div", { className: "ss-w-today-live", children: liveRows.map(({ match }) => /* @__PURE__ */ jsx60(
6254
+ FixtureRow,
5882
6255
  {
5883
- group,
5884
- open: expanded[group.competitionId] ?? group.expandedByDefault,
5885
- onToggle: () => toggleGroup(group.competitionId),
5886
- disambiguate: (nameCounts[group.competitionName] ?? 0) > 1,
5887
- states,
6256
+ match,
6257
+ state: states[match.matchId],
5888
6258
  stale,
5889
6259
  ui,
5890
6260
  monitor
5891
6261
  },
5892
- group.competitionId
5893
- ))
6262
+ match.matchId
6263
+ )) })
6264
+ ] });
6265
+ if (openGroup !== void 0) {
6266
+ return /* @__PURE__ */ jsx60("div", { className: "ss-w-today-root", children: /* @__PURE__ */ jsxs54("div", { className: "ss-w-mon-list", children: [
6267
+ stale && /* @__PURE__ */ jsx60("div", { className: "ss-w-stale", children: ui.staleStates }),
6268
+ liveBand,
6269
+ /* @__PURE__ */ jsx60(
6270
+ LeagueDetail,
6271
+ {
6272
+ group: openGroup,
6273
+ position: { index: openIndex + 1, total: placement.order.length },
6274
+ states,
6275
+ stale,
6276
+ ui,
6277
+ monitor,
6278
+ starTap,
6279
+ onBack: () => setSelectedCompetitionId(null),
6280
+ onPrev: () => setSelectedCompetitionId(placement.order[Math.max(0, openIndex - 1)].competitionId),
6281
+ onNext: () => setSelectedCompetitionId(
6282
+ placement.order[Math.min(placement.order.length - 1, openIndex + 1)].competitionId
6283
+ )
6284
+ }
6285
+ )
6286
+ ] }) });
6287
+ }
6288
+ const searching = query.trim().length > 0;
6289
+ const searchResults = searching ? visibleGroups.filter((g) => matchesQuery(g, query)) : [];
6290
+ return /* @__PURE__ */ jsxs54("div", { className: "ss-w-today-root", children: [
6291
+ /* @__PURE__ */ jsxs54("div", { className: "ss-w-mon-list", children: [
6292
+ stale && /* @__PURE__ */ jsx60("div", { className: "ss-w-stale", children: ui.staleStates }),
6293
+ !searching && liveBand,
6294
+ /* @__PURE__ */ jsx60(
6295
+ SearchField,
6296
+ {
6297
+ id: searchId,
6298
+ label: ui.searchLeaguesPlaceholder,
6299
+ labelHidden: true,
6300
+ placeholder: ui.searchLeaguesPlaceholder,
6301
+ value: query,
6302
+ onChange: setQuery
6303
+ }
6304
+ ),
6305
+ searching ? searchResults.length === 0 ? /* @__PURE__ */ jsx60("div", { className: "ss-w-today-empty", children: ui.noLeagueResults }) : /* @__PURE__ */ jsx60("div", { className: "ss-w-today-tiles", children: searchResults.map((group) => /* @__PURE__ */ jsx60(
6306
+ LeagueTile,
6307
+ {
6308
+ group,
6309
+ starClickable: starClickable(group, placement.pinnedCompetitionId),
6310
+ disambiguate: (nameCounts[group.competitionName] ?? 0) > 1,
6311
+ onOpen: () => setSelectedCompetitionId(group.competitionId),
6312
+ starTap: gridStarTap,
6313
+ ui
6314
+ },
6315
+ group.competitionId
6316
+ )) }) : /* @__PURE__ */ jsxs54(Fragment7, { children: [
6317
+ /* @__PURE__ */ jsxs54("div", { className: "ss-w-today-sec", children: [
6318
+ placement.personal ? ui.yourLeagues : ui.topLeagues,
6319
+ !placement.personal && /* @__PURE__ */ jsx60("span", { className: "ss-w-today-sec-sub", children: ui.topLeaguesSub })
6320
+ ] }),
6321
+ /* @__PURE__ */ jsx60("div", { className: "ss-w-today-tiles", children: placement.candidates.map((group) => /* @__PURE__ */ jsx60(
6322
+ LeagueTile,
6323
+ {
6324
+ group,
6325
+ starClickable: starClickable(group, placement.pinnedCompetitionId),
6326
+ disambiguate: (nameCounts[group.competitionName] ?? 0) > 1,
6327
+ onOpen: () => setSelectedCompetitionId(group.competitionId),
6328
+ starTap: gridStarTap,
6329
+ ui
6330
+ },
6331
+ group.competitionId
6332
+ )) }),
6333
+ /* @__PURE__ */ jsx60("div", { className: "ss-w-today-sec", children: ui.allLeagues }),
6334
+ /* @__PURE__ */ jsx60("div", { className: "ss-w-today-tiles", children: placement.others.map((group) => /* @__PURE__ */ jsx60(
6335
+ LeagueTile,
6336
+ {
6337
+ group,
6338
+ starClickable: starClickable(group, placement.pinnedCompetitionId),
6339
+ disambiguate: (nameCounts[group.competitionName] ?? 0) > 1,
6340
+ onOpen: () => setSelectedCompetitionId(group.competitionId),
6341
+ starTap: gridStarTap,
6342
+ ui
6343
+ },
6344
+ group.competitionId
6345
+ )) })
6346
+ ] })
6347
+ ] }),
6348
+ toast !== null && /* @__PURE__ */ jsx60("p", { className: "ss-w-today-toast", role: "status", "aria-live": "polite", children: toast === "starred" ? ui.starredToast : ui.unstarredToast })
5894
6349
  ] });
5895
6350
  }
5896
6351
 
5897
6352
  // src/components/GamesPanel.tsx
5898
- import { useEffect as useEffect23, useState as useState40 } from "react";
6353
+ import { useEffect as useEffect25, useState as useState43 } from "react";
5899
6354
 
5900
6355
  // src/components/GamesLoginWall.tsx
5901
- import { jsx as jsx58 } from "react/jsx-runtime";
6356
+ import { jsx as jsx61 } from "react/jsx-runtime";
5902
6357
  function GamesLoginWall({ ui }) {
5903
- return /* @__PURE__ */ jsx58("div", { className: "ss-w-mon-list", children: /* @__PURE__ */ jsx58("div", { className: "ss-w-games-wall", children: /* @__PURE__ */ jsx58("p", { children: ui.gamesLoginRequired }) }) });
6358
+ return /* @__PURE__ */ jsx61("div", { className: "ss-w-mon-list", children: /* @__PURE__ */ jsx61("div", { className: "ss-w-games-wall", children: /* @__PURE__ */ jsx61("p", { children: ui.gamesLoginRequired }) }) });
5904
6359
  }
5905
6360
 
5906
6361
  // src/components/GamesHub.tsx
5907
- import { useEffect as useEffect20, useState as useState27 } from "react";
6362
+ import { useEffect as useEffect22, useState as useState30 } from "react";
5908
6363
 
5909
6364
  // src/components/games/ui/gameMeta.ts
5910
6365
  function prettifyGameId(gameId) {
@@ -5920,108 +6375,74 @@ function splitName(full) {
5920
6375
  }
5921
6376
 
5922
6377
  // src/components/GameTileArt.tsx
5923
- import { Fragment as Fragment8, jsx as jsx59, jsxs as jsxs53 } from "react/jsx-runtime";
6378
+ import { Fragment as Fragment8, jsx as jsx62, jsxs as jsxs55 } from "react/jsx-runtime";
5924
6379
  function GameTileArt({ gameId }) {
5925
- return /* @__PURE__ */ jsx59("svg", { className: "ss-g-art", viewBox: "0 0 120 74", "aria-hidden": "true", children: ART[gameId] ?? ART.default });
6380
+ return /* @__PURE__ */ jsx62("svg", { className: "ss-g-art", viewBox: "0 0 120 74", "aria-hidden": "true", children: ART[gameId] ?? ART.default });
5926
6381
  }
5927
- var head = (cx, cy, r, cls = "ss-g-art-fg") => /* @__PURE__ */ jsxs53("g", { className: cls, children: [
5928
- /* @__PURE__ */ jsx59("circle", { cx, cy: cy - r * 0.3, r: r * 0.45 }),
5929
- /* @__PURE__ */ jsx59("path", { d: `M${cx - r} ${cy + r}c0-${r * 0.8} ${r * 0.45}-${r * 1.1} ${r}-${r * 1.1}s${r} ${r * 0.3} ${r} ${r * 1.1}z` })
6382
+ var head = (cx, cy, r, cls = "ss-g-art-fg") => /* @__PURE__ */ jsxs55("g", { className: cls, children: [
6383
+ /* @__PURE__ */ jsx62("circle", { cx, cy: cy - r * 0.3, r: r * 0.45 }),
6384
+ /* @__PURE__ */ jsx62("path", { d: `M${cx - r} ${cy + r}c0-${r * 0.8} ${r * 0.45}-${r * 1.1} ${r}-${r * 1.1}s${r} ${r * 0.3} ${r} ${r * 1.1}z` })
5930
6385
  ] });
5931
6386
  var ART = {
5932
- "mystery-tiger": /* @__PURE__ */ jsxs53(Fragment8, { children: [
6387
+ "mystery-tiger": /* @__PURE__ */ jsxs55(Fragment8, { children: [
5933
6388
  head(60, 38, 26, "ss-g-art-fg"),
5934
- /* @__PURE__ */ jsx59("text", { x: "60", y: "36", className: "ss-g-art-q", textAnchor: "middle", children: "?" })
6389
+ /* @__PURE__ */ jsx62("text", { x: "60", y: "36", className: "ss-g-art-q", textAnchor: "middle", children: "?" })
5935
6390
  ] }),
5936
- "higher-or-lower": /* @__PURE__ */ jsxs53(Fragment8, { children: [
6391
+ "higher-or-lower": /* @__PURE__ */ jsxs55(Fragment8, { children: [
5937
6392
  head(32, 38, 20),
5938
6393
  head(88, 38, 20),
5939
- /* @__PURE__ */ jsx59("circle", { cx: "60", cy: "37", r: "11", className: "ss-g-art-accent" }),
5940
- /* @__PURE__ */ jsx59("path", { d: "M57 33l3-3 3 3M57 41l3 3 3-3", className: "ss-g-art-ink" })
6394
+ /* @__PURE__ */ jsx62("circle", { cx: "60", cy: "37", r: "11", className: "ss-g-art-accent" }),
6395
+ /* @__PURE__ */ jsx62("path", { d: "M57 33l3-3 3 3M57 41l3 3 3-3", className: "ss-g-art-ink" })
5941
6396
  ] }),
5942
- "guess-the-xi": /* @__PURE__ */ jsxs53(Fragment8, { children: [
5943
- /* @__PURE__ */ jsx59("rect", { x: "8", y: "4", width: "104", height: "66", rx: "6", className: "ss-g-art-pitch" }),
5944
- [[60, 60, "a"], [24, 46], [48, 46], [72, 46], [96, 46], [36, 30], [60, 30], [84, 30], [40, 14], [60, 14], [80, 14]].map(([x, y, a], i) => /* @__PURE__ */ jsx59("circle", { cx: x, cy: y, r: "4", className: a ? "ss-g-art-accent" : "ss-g-art-dot" }, i))
6397
+ "guess-the-xi": /* @__PURE__ */ jsxs55(Fragment8, { children: [
6398
+ /* @__PURE__ */ jsx62("rect", { x: "8", y: "4", width: "104", height: "66", rx: "6", className: "ss-g-art-pitch" }),
6399
+ [[60, 60, "a"], [24, 46], [48, 46], [72, 46], [96, 46], [36, 30], [60, 30], [84, 30], [40, 14], [60, 14], [80, 14]].map(([x, y, a], i) => /* @__PURE__ */ jsx62("circle", { cx: x, cy: y, r: "4", className: a ? "ss-g-art-accent" : "ss-g-art-dot" }, i))
5945
6400
  ] }),
5946
- "daily-quiz": /* @__PURE__ */ jsx59(Fragment8, { children: [[14, 8], [62, 8], [14, 40], [62, 40]].map(([x, y], i) => /* @__PURE__ */ jsx59("rect", { x, y, width: "44", height: "26", rx: "5", className: i === 1 ? "ss-g-art-correct" : "ss-g-art-block" }, i)) }),
5947
- "career-path": /* @__PURE__ */ jsxs53(Fragment8, { children: [
5948
- /* @__PURE__ */ jsx59("path", { d: "M18 22h24v10c0 7-5 11-12 13-7-2-12-6-12-13z", className: "ss-g-art-fg" }),
5949
- /* @__PURE__ */ jsx59("path", { d: "M48 37h8M84 37h8", className: "ss-g-art-line" }),
5950
- /* @__PURE__ */ jsx59("path", { d: "M60 22h24v10c0 7-5 11-12 13-7-2-12-6-12-13z", className: "ss-g-art-fg" }),
5951
- /* @__PURE__ */ jsx59("rect", { x: "96", y: "22", width: "18", height: "26", rx: "4", className: "ss-g-art-dash" }),
5952
- /* @__PURE__ */ jsx59("text", { x: "105", y: "40", className: "ss-g-art-q", textAnchor: "middle", children: "?" })
6401
+ "daily-quiz": /* @__PURE__ */ jsx62(Fragment8, { children: [[14, 8], [62, 8], [14, 40], [62, 40]].map(([x, y], i) => /* @__PURE__ */ jsx62("rect", { x, y, width: "44", height: "26", rx: "5", className: i === 1 ? "ss-g-art-correct" : "ss-g-art-block" }, i)) }),
6402
+ "career-path": /* @__PURE__ */ jsxs55(Fragment8, { children: [
6403
+ /* @__PURE__ */ jsx62("path", { d: "M18 22h24v10c0 7-5 11-12 13-7-2-12-6-12-13z", className: "ss-g-art-fg" }),
6404
+ /* @__PURE__ */ jsx62("path", { d: "M48 37h8M84 37h8", className: "ss-g-art-line" }),
6405
+ /* @__PURE__ */ jsx62("path", { d: "M60 22h24v10c0 7-5 11-12 13-7-2-12-6-12-13z", className: "ss-g-art-fg" }),
6406
+ /* @__PURE__ */ jsx62("rect", { x: "96", y: "22", width: "18", height: "26", rx: "4", className: "ss-g-art-dash" }),
6407
+ /* @__PURE__ */ jsx62("text", { x: "105", y: "40", className: "ss-g-art-q", textAnchor: "middle", children: "?" })
5953
6408
  ] }),
5954
- "beat-the-grid": /* @__PURE__ */ jsx59(Fragment8, { children: [0, 1, 2].flatMap((r) => [0, 1, 2].map((c) => /* @__PURE__ */ jsx59("rect", { x: 33 + c * 19, y: 10 + r * 19, width: "16", height: "16", rx: "3", className: (r + c) % 3 === 0 ? "ss-g-art-accent" : "ss-g-art-block" }, `${r}${c}`))) }),
5955
- "matchday-predictor": /* @__PURE__ */ jsxs53(Fragment8, { children: [
5956
- /* @__PURE__ */ jsx59("path", { d: "M10 20h20v9c0 6-4 9-10 11-6-2-10-5-10-11z", className: "ss-g-art-fg" }),
5957
- /* @__PURE__ */ jsx59("rect", { x: "38", y: "22", width: "18", height: "24", rx: "4", className: "ss-g-art-accent-stroke" }),
5958
- /* @__PURE__ */ jsx59("rect", { x: "64", y: "22", width: "18", height: "24", rx: "4", className: "ss-g-art-dash" }),
5959
- /* @__PURE__ */ jsx59("path", { d: "M90 20h20v9c0 6-4 9-10 11-6-2-10-5-10-11z", className: "ss-g-art-fg" })
6409
+ "beat-the-grid": /* @__PURE__ */ jsx62(Fragment8, { children: [0, 1, 2].flatMap((r) => [0, 1, 2].map((c) => /* @__PURE__ */ jsx62("rect", { x: 33 + c * 19, y: 10 + r * 19, width: "16", height: "16", rx: "3", className: (r + c) % 3 === 0 ? "ss-g-art-accent" : "ss-g-art-block" }, `${r}${c}`))) }),
6410
+ "matchday-predictor": /* @__PURE__ */ jsxs55(Fragment8, { children: [
6411
+ /* @__PURE__ */ jsx62("path", { d: "M10 20h20v9c0 6-4 9-10 11-6-2-10-5-10-11z", className: "ss-g-art-fg" }),
6412
+ /* @__PURE__ */ jsx62("rect", { x: "38", y: "22", width: "18", height: "24", rx: "4", className: "ss-g-art-accent-stroke" }),
6413
+ /* @__PURE__ */ jsx62("rect", { x: "64", y: "22", width: "18", height: "24", rx: "4", className: "ss-g-art-dash" }),
6414
+ /* @__PURE__ */ jsx62("path", { d: "M90 20h20v9c0 6-4 9-10 11-6-2-10-5-10-11z", className: "ss-g-art-fg" })
5960
6415
  ] }),
5961
- "starting-xi": /* @__PURE__ */ jsxs53(Fragment8, { children: [
5962
- /* @__PURE__ */ jsx59("rect", { x: "8", y: "4", width: "104", height: "66", rx: "6", className: "ss-g-art-pitch" }),
5963
- [[60, 60], [30, 46], [50, 46], [70, 46], [90, 46], [45, 30], [75, 30], [30, 16], [60, 16], [90, 16]].map(([x, y], i) => /* @__PURE__ */ jsx59("circle", { cx: x, cy: y, r: "5", className: i < 7 ? "ss-g-art-accent" : "ss-g-art-dash" }, i))
6416
+ "starting-xi": /* @__PURE__ */ jsxs55(Fragment8, { children: [
6417
+ /* @__PURE__ */ jsx62("rect", { x: "8", y: "4", width: "104", height: "66", rx: "6", className: "ss-g-art-pitch" }),
6418
+ [[60, 60], [30, 46], [50, 46], [70, 46], [90, 46], [45, 30], [75, 30], [30, 16], [60, 16], [90, 16]].map(([x, y], i) => /* @__PURE__ */ jsx62("circle", { cx: x, cy: y, r: "5", className: i < 7 ? "ss-g-art-accent" : "ss-g-art-dash" }, i))
5964
6419
  ] }),
5965
- "stat-ladder": /* @__PURE__ */ jsx59(Fragment8, { children: [[20, 70], [34, 52], [48, 34]].map(([y, w], i) => /* @__PURE__ */ jsx59("rect", { x: "24", y, width: w, height: "12", rx: "3", className: i === 1 ? "ss-g-art-accent" : "ss-g-art-block" }, i)) }),
5966
- "fan-motm": /* @__PURE__ */ jsxs53(Fragment8, { children: [
5967
- /* @__PURE__ */ jsx59("circle", { cx: "60", cy: "37", r: "26", className: "ss-g-art-accent-stroke" }),
6420
+ "stat-ladder": /* @__PURE__ */ jsx62(Fragment8, { children: [[20, 70], [34, 52], [48, 34]].map(([y, w], i) => /* @__PURE__ */ jsx62("rect", { x: "24", y, width: w, height: "12", rx: "3", className: i === 1 ? "ss-g-art-accent" : "ss-g-art-block" }, i)) }),
6421
+ "fan-motm": /* @__PURE__ */ jsxs55(Fragment8, { children: [
6422
+ /* @__PURE__ */ jsx62("circle", { cx: "60", cy: "37", r: "26", className: "ss-g-art-accent-stroke" }),
5968
6423
  head(60, 40, 18),
5969
- /* @__PURE__ */ jsx59("path", { d: "M84 8l2.4 5 5.4.6-4 3.7 1.1 5.4-4.9-2.7-4.9 2.7 1.1-5.4-4-3.7 5.4-.6z", className: "ss-g-art-accent" })
6424
+ /* @__PURE__ */ jsx62("path", { d: "M84 8l2.4 5 5.4.6-4 3.7 1.1 5.4-4.9-2.7-4.9 2.7 1.1-5.4-4-3.7 5.4-.6z", className: "ss-g-art-accent" })
5970
6425
  ] }),
5971
- default: /* @__PURE__ */ jsx59("circle", { cx: "60", cy: "37", r: "22", className: "ss-g-art-fg" })
6426
+ default: /* @__PURE__ */ jsx62("circle", { cx: "60", cy: "37", r: "22", className: "ss-g-art-fg" })
5972
6427
  };
5973
6428
 
5974
6429
  // src/components/games/ui/Chip.tsx
5975
- import { jsx as jsx60, jsxs as jsxs54 } from "react/jsx-runtime";
6430
+ import { jsx as jsx63, jsxs as jsxs56 } from "react/jsx-runtime";
5976
6431
  function Chip({ variant = "neutral", icon, children, className }) {
5977
- return /* @__PURE__ */ jsxs54("span", { className: `ss-g-chip ss-g-chip--${variant}${className ? ` ${className}` : ""}`, children: [
6432
+ return /* @__PURE__ */ jsxs56("span", { className: `ss-g-chip ss-g-chip--${variant}${className ? ` ${className}` : ""}`, children: [
5978
6433
  icon,
5979
6434
  children
5980
6435
  ] });
5981
6436
  }
5982
6437
  function StatStack({ value, label }) {
5983
- return /* @__PURE__ */ jsxs54("span", { className: "ss-g-statstack", children: [
5984
- /* @__PURE__ */ jsx60("span", { className: "ss-g-statstack-v", children: value }),
5985
- /* @__PURE__ */ jsx60("span", { className: "ss-g-statstack-l", children: label })
6438
+ return /* @__PURE__ */ jsxs56("span", { className: "ss-g-statstack", children: [
6439
+ /* @__PURE__ */ jsx63("span", { className: "ss-g-statstack-v", children: value }),
6440
+ /* @__PURE__ */ jsx63("span", { className: "ss-g-statstack-l", children: label })
5986
6441
  ] });
5987
6442
  }
5988
6443
 
5989
- // src/components/games/ui/icons.tsx
5990
- import { jsx as jsx61 } from "react/jsx-runtime";
5991
- var svg = (size, children, fill = false) => /* @__PURE__ */ jsx61(
5992
- "svg",
5993
- {
5994
- width: size,
5995
- height: size,
5996
- viewBox: "0 0 24 24",
5997
- fill: fill ? "currentColor" : "none",
5998
- stroke: fill ? "none" : "currentColor",
5999
- strokeWidth: 2.2,
6000
- strokeLinecap: "round",
6001
- strokeLinejoin: "round",
6002
- "aria-hidden": "true",
6003
- children
6004
- }
6005
- );
6006
- var IconChevronLeft = ({ size = 20 }) => svg(size, /* @__PURE__ */ jsx61("path", { d: "M15 18l-6-6 6-6" }));
6007
- var IconLock = ({ size = 14 }) => svg(size, [/* @__PURE__ */ jsx61("rect", { x: "5", y: "11", width: "14", height: "10", rx: "2" }, "a"), /* @__PURE__ */ jsx61("path", { d: "M8 11V7a4 4 0 0 1 8 0v4" }, "b")]);
6008
- var IconCheck = ({ size = 14 }) => svg(size, /* @__PURE__ */ jsx61("path", { d: "M5 12l5 5 9-10" }));
6009
- var IconClose = ({ size = 16 }) => svg(size, /* @__PURE__ */ jsx61("path", { d: "M6 6l12 12M18 6L6 18" }));
6010
- var IconSearch = ({ size = 18 }) => svg(size, [/* @__PURE__ */ jsx61("circle", { cx: "11", cy: "11", r: "7" }, "a"), /* @__PURE__ */ jsx61("path", { d: "M20 20l-3.5-3.5" }, "b")]);
6011
- var IconPlus = ({ size = 20 }) => svg(size, /* @__PURE__ */ jsx61("path", { d: "M12 5v14M5 12h14" }));
6012
- var IconBulb = ({ size = 16 }) => svg(size, [/* @__PURE__ */ jsx61("path", { d: "M9 18h6M10 21h4" }, "a"), /* @__PURE__ */ jsx61("path", { d: "M12 3a6 6 0 0 0-3.5 10.9V16h7v-2.1A6 6 0 0 0 12 3z" }, "b")]);
6013
- var IconArrowUp = ({ size = 12 }) => svg(size, /* @__PURE__ */ jsx61("path", { d: "M12 19V5M5 12l7-7 7 7" }));
6014
- var IconArrowDown = ({ size = 12 }) => svg(size, /* @__PURE__ */ jsx61("path", { d: "M12 5v14M19 12l-7 7-7-7" }));
6015
- var IconCalendar = ({ size = 18 }) => svg(size, [/* @__PURE__ */ jsx61("rect", { x: "4", y: "5", width: "16", height: "15", rx: "2" }, "a"), /* @__PURE__ */ jsx61("path", { d: "M4 10h16M9 3v4M15 3v4" }, "b")]);
6016
- var IconShield = ({ size = 18 }) => svg(size, /* @__PURE__ */ jsx61("path", { d: "M12 3l7 3v6c0 5-3 8-7 9-4-1-7-4-7-9V6z" }));
6017
- var IconFlag = ({ size = 18 }) => svg(size, /* @__PURE__ */ jsx61("path", { d: "M5 21V4M5 4h12l-2 4 2 4H5" }));
6018
- var IconBall = ({ size = 18 }) => svg(size, [/* @__PURE__ */ jsx61("circle", { cx: "12", cy: "12", r: "9" }, "a"), /* @__PURE__ */ jsx61("path", { d: "M12 7l4 3-1.5 4.5h-5L8 10z" }, "b")]);
6019
- var IconBoot = ({ size = 18 }) => svg(size, /* @__PURE__ */ jsx61("path", { d: "M4 6h6l1 6 8 3v3H4z" }));
6020
- var IconGloves = ({ size = 18 }) => svg(size, /* @__PURE__ */ jsx61("path", { d: "M7 21v-8l-2-3V6a1.5 1.5 0 0 1 3 0v3V4a1.5 1.5 0 0 1 3 0v5V3.5a1.5 1.5 0 0 1 3 0V9V5a1.5 1.5 0 0 1 3 0v9l-2 3v4z" }));
6021
- var IconFlame = ({ size = 16 }) => svg(size, /* @__PURE__ */ jsx61("path", { d: "M12 3c1 4 5 5 5 10a5 5 0 0 1-10 0c0-3 2-4 2-7 1.5 1 2 2 2 3 1-2 1-4 1-6z" }), true);
6022
-
6023
6444
  // src/components/GameTile.tsx
6024
- import { Fragment as Fragment9, jsx as jsx62, jsxs as jsxs55 } from "react/jsx-runtime";
6445
+ import { Fragment as Fragment9, jsx as jsx64, jsxs as jsxs57 } from "react/jsx-runtime";
6025
6446
  function tileStatus(game, ui) {
6026
6447
  switch (game.status) {
6027
6448
  case "locked":
@@ -6045,38 +6466,38 @@ function GameTile({ game, onOpen, ui, variant = "tile" }) {
6045
6466
  const status = tileStatus(game, ui);
6046
6467
  const disabled = DISABLED.has(game.status);
6047
6468
  const title = gameTitle(game, ui.games.titles);
6048
- const body = variant === "hero" ? /* @__PURE__ */ jsxs55(Fragment9, { children: [
6049
- /* @__PURE__ */ jsxs55("span", { className: "ss-g-hero-text", children: [
6050
- /* @__PURE__ */ jsx62("span", { className: "ss-g-hero-eyebrow", children: ui.games.dailyChallenge }),
6051
- status.tone === "new" && /* @__PURE__ */ jsx62(Chip, { variant: "badge", children: ui.games.newToday }),
6052
- /* @__PURE__ */ jsx62("span", { className: "ss-g-hero-title", children: title }),
6053
- /* @__PURE__ */ jsx62("span", { className: "ss-g-hero-sub", children: ui.games.taglines[game.gameId] ?? "" }),
6054
- status.tone === "success" ? /* @__PURE__ */ jsx62("span", { className: "ss-g-tile-status", "data-tone": "success", children: status.text }) : /* @__PURE__ */ jsxs55("span", { className: "ss-g-hero-cta", children: [
6469
+ const body = variant === "hero" ? /* @__PURE__ */ jsxs57(Fragment9, { children: [
6470
+ /* @__PURE__ */ jsxs57("span", { className: "ss-g-hero-text", children: [
6471
+ /* @__PURE__ */ jsx64("span", { className: "ss-g-hero-eyebrow", children: ui.games.dailyChallenge }),
6472
+ status.tone === "new" && /* @__PURE__ */ jsx64(Chip, { variant: "badge", children: ui.games.newToday }),
6473
+ /* @__PURE__ */ jsx64("span", { className: "ss-g-hero-title", children: title }),
6474
+ /* @__PURE__ */ jsx64("span", { className: "ss-g-hero-sub", children: ui.games.taglines[game.gameId] ?? "" }),
6475
+ status.tone === "success" ? /* @__PURE__ */ jsx64("span", { className: "ss-g-tile-status", "data-tone": "success", children: status.text }) : /* @__PURE__ */ jsxs57("span", { className: "ss-g-hero-cta", children: [
6055
6476
  status.tone === "accent" ? ui.games.resume : ui.games.playNow,
6056
6477
  " \u2192"
6057
6478
  ] })
6058
6479
  ] }),
6059
- /* @__PURE__ */ jsx62("span", { className: "ss-g-hero-art", children: /* @__PURE__ */ jsx62(GameTileArt, { gameId: game.gameId }) })
6060
- ] }) : variant === "wide" ? /* @__PURE__ */ jsxs55(Fragment9, { children: [
6061
- /* @__PURE__ */ jsx62("span", { className: "ss-g-wide-art", children: /* @__PURE__ */ jsx62(GameTileArt, { gameId: game.gameId }) }),
6062
- /* @__PURE__ */ jsxs55("span", { className: "ss-g-wide-text", children: [
6063
- /* @__PURE__ */ jsx62("span", { className: "ss-g-tile-title", children: title }),
6064
- /* @__PURE__ */ jsx62("span", { className: "ss-g-tile-status", "data-tone": status.tone, children: status.text }),
6065
- status.tone === "new" && /* @__PURE__ */ jsx62(Chip, { variant: "badge", children: ui.games.newToday })
6480
+ /* @__PURE__ */ jsx64("span", { className: "ss-g-hero-art", children: /* @__PURE__ */ jsx64(GameTileArt, { gameId: game.gameId }) })
6481
+ ] }) : variant === "wide" ? /* @__PURE__ */ jsxs57(Fragment9, { children: [
6482
+ /* @__PURE__ */ jsx64("span", { className: "ss-g-wide-art", children: /* @__PURE__ */ jsx64(GameTileArt, { gameId: game.gameId }) }),
6483
+ /* @__PURE__ */ jsxs57("span", { className: "ss-g-wide-text", children: [
6484
+ /* @__PURE__ */ jsx64("span", { className: "ss-g-tile-title", children: title }),
6485
+ /* @__PURE__ */ jsx64("span", { className: "ss-g-tile-status", "data-tone": status.tone, children: status.text }),
6486
+ status.tone === "new" && /* @__PURE__ */ jsx64(Chip, { variant: "badge", children: ui.games.newToday })
6066
6487
  ] }),
6067
- /* @__PURE__ */ jsx62("span", { className: "ss-g-wide-chev", children: /* @__PURE__ */ jsx62(IconChevronLeft, { size: 18 }) })
6068
- ] }) : /* @__PURE__ */ jsxs55(Fragment9, { children: [
6069
- /* @__PURE__ */ jsx62("span", { className: "ss-g-tile-art", children: /* @__PURE__ */ jsx62(GameTileArt, { gameId: game.gameId }) }),
6070
- /* @__PURE__ */ jsx62("span", { className: "ss-g-tile-title", children: title }),
6071
- /* @__PURE__ */ jsx62("span", { className: "ss-g-tile-status", "data-tone": status.tone, children: status.text })
6488
+ /* @__PURE__ */ jsx64("span", { className: "ss-g-wide-chev", children: /* @__PURE__ */ jsx64(IconChevronLeft, { size: 18 }) })
6489
+ ] }) : /* @__PURE__ */ jsxs57(Fragment9, { children: [
6490
+ /* @__PURE__ */ jsx64("span", { className: "ss-g-tile-art", children: /* @__PURE__ */ jsx64(GameTileArt, { gameId: game.gameId }) }),
6491
+ /* @__PURE__ */ jsx64("span", { className: "ss-g-tile-title", children: title }),
6492
+ /* @__PURE__ */ jsx64("span", { className: "ss-g-tile-status", "data-tone": status.tone, children: status.text })
6072
6493
  ] });
6073
6494
  const cls = `ss-g-tile ss-g-tile--${variant}`;
6074
- if (disabled) return /* @__PURE__ */ jsx62("div", { className: cls, "data-disabled": true, "aria-disabled": "true", children: body });
6075
- return /* @__PURE__ */ jsx62("button", { type: "button", className: cls, "aria-label": `${title} \u2014 ${status.text}`, onClick: () => onOpen(game), children: body });
6495
+ if (disabled) return /* @__PURE__ */ jsx64("div", { className: cls, "data-disabled": true, "aria-disabled": "true", children: body });
6496
+ return /* @__PURE__ */ jsx64("button", { type: "button", className: cls, "aria-label": `${title} \u2014 ${status.text}`, onClick: () => onOpen(game), children: body });
6076
6497
  }
6077
6498
 
6078
6499
  // src/components/GamesHub.tsx
6079
- import { Fragment as Fragment10, jsx as jsx63, jsxs as jsxs56 } from "react/jsx-runtime";
6500
+ import { Fragment as Fragment10, jsx as jsx65, jsxs as jsxs58 } from "react/jsx-runtime";
6080
6501
  var PLAYABLE = /* @__PURE__ */ new Set(["available", "in_progress"]);
6081
6502
  var DONE = /* @__PURE__ */ new Set(["played", "graded"]);
6082
6503
  function pickHeroGame(games) {
@@ -6089,8 +6510,8 @@ function pickHeroGame(games) {
6089
6510
  }
6090
6511
  var tileKey = (g) => `${g.gameId}-${g.gameDay}-${g.fixtureId}`;
6091
6512
  function GamesHub({ games, myWeeklyRow, weeklyPrize, onOpen, ui }) {
6092
- const [, setTick] = useState27(0);
6093
- useEffect20(() => {
6513
+ const [, setTick] = useState30(0);
6514
+ useEffect22(() => {
6094
6515
  const id = setInterval(() => setTick((t) => t + 1), 6e4);
6095
6516
  return () => clearInterval(id);
6096
6517
  }, []);
@@ -6102,58 +6523,58 @@ function GamesHub({ games, myWeeklyRow, weeklyPrize, onOpen, ui }) {
6102
6523
  const kickoffs = fixtures.map((g) => g.kickoffUtc).filter((k) => !!k).sort();
6103
6524
  const todayPts = games.filter((g) => DONE.has(g.status)).reduce((s, g) => s + (g.score ?? 0), 0);
6104
6525
  const dash = "\u2014";
6105
- return /* @__PURE__ */ jsxs56("div", { className: "ss-g-hub", children: [
6106
- /* @__PURE__ */ jsxs56("div", { className: "ss-g-stats", children: [
6107
- /* @__PURE__ */ jsxs56("div", { className: "ss-g-stat", children: [
6108
- /* @__PURE__ */ jsx63("span", { className: "ss-g-stat-l", children: ui.games.statStreak }),
6109
- /* @__PURE__ */ jsxs56("span", { className: "ss-g-stat-v", "data-testid": "stat-streak", children: [
6110
- myWeeklyRow ? /* @__PURE__ */ jsxs56(Fragment10, { children: [
6111
- /* @__PURE__ */ jsx63(IconFlame, {}),
6526
+ return /* @__PURE__ */ jsxs58("div", { className: "ss-g-hub", children: [
6527
+ /* @__PURE__ */ jsxs58("div", { className: "ss-g-stats", children: [
6528
+ /* @__PURE__ */ jsxs58("div", { className: "ss-g-stat", children: [
6529
+ /* @__PURE__ */ jsx65("span", { className: "ss-g-stat-l", children: ui.games.statStreak }),
6530
+ /* @__PURE__ */ jsxs58("span", { className: "ss-g-stat-v", "data-testid": "stat-streak", children: [
6531
+ myWeeklyRow ? /* @__PURE__ */ jsxs58(Fragment10, { children: [
6532
+ /* @__PURE__ */ jsx65(IconFlame, {}),
6112
6533
  myWeeklyRow.currentStreak
6113
6534
  ] }) : dash,
6114
- myWeeklyRow && /* @__PURE__ */ jsx63("small", { children: ui.games.unitDays })
6535
+ myWeeklyRow && /* @__PURE__ */ jsx65("small", { children: ui.games.unitDays })
6115
6536
  ] })
6116
6537
  ] }),
6117
- /* @__PURE__ */ jsxs56("div", { className: "ss-g-stat", children: [
6118
- /* @__PURE__ */ jsx63("span", { className: "ss-g-stat-l", children: ui.games.statToday }),
6119
- /* @__PURE__ */ jsxs56("span", { className: "ss-g-stat-v ss-g-stat-v--accent", "data-testid": "stat-today", children: [
6538
+ /* @__PURE__ */ jsxs58("div", { className: "ss-g-stat", children: [
6539
+ /* @__PURE__ */ jsx65("span", { className: "ss-g-stat-l", children: ui.games.statToday }),
6540
+ /* @__PURE__ */ jsxs58("span", { className: "ss-g-stat-v ss-g-stat-v--accent", "data-testid": "stat-today", children: [
6120
6541
  ui.games.formatPts(todayPts),
6121
- /* @__PURE__ */ jsx63("small", { children: ui.games.unitPts })
6542
+ /* @__PURE__ */ jsx65("small", { children: ui.games.unitPts })
6122
6543
  ] })
6123
6544
  ] }),
6124
- /* @__PURE__ */ jsxs56("div", { className: "ss-g-stat", children: [
6125
- /* @__PURE__ */ jsx63("span", { className: "ss-g-stat-l", children: ui.games.statRank }),
6126
- /* @__PURE__ */ jsxs56("span", { className: "ss-g-stat-v", "data-testid": "stat-rank", children: [
6545
+ /* @__PURE__ */ jsxs58("div", { className: "ss-g-stat", children: [
6546
+ /* @__PURE__ */ jsx65("span", { className: "ss-g-stat-l", children: ui.games.statRank }),
6547
+ /* @__PURE__ */ jsxs58("span", { className: "ss-g-stat-v", "data-testid": "stat-rank", children: [
6127
6548
  myWeeklyRow ? `#${myWeeklyRow.rank}` : dash,
6128
- myWeeklyRow && /* @__PURE__ */ jsx63("small", { children: ui.games.thisWeek })
6549
+ myWeeklyRow && /* @__PURE__ */ jsx65("small", { children: ui.games.thisWeek })
6129
6550
  ] })
6130
6551
  ] })
6131
6552
  ] }),
6132
- weeklyPrize && /* @__PURE__ */ jsx63(Chip, { variant: "accent", className: "ss-g-prize", children: weeklyPrize }),
6133
- hero && /* @__PURE__ */ jsx63(GameTile, { game: hero, onOpen, ui, variant: "hero" }),
6134
- (grid.length > 0 || wide) && /* @__PURE__ */ jsxs56("section", { className: "ss-g-sec", children: [
6135
- /* @__PURE__ */ jsxs56("div", { className: "ss-g-sec-head", children: [
6136
- /* @__PURE__ */ jsx63("h3", { children: ui.games.dailyGames }),
6137
- /* @__PURE__ */ jsx63("span", { children: ui.games.newSetAtMidnight })
6553
+ weeklyPrize && /* @__PURE__ */ jsx65(Chip, { variant: "accent", className: "ss-g-prize", children: weeklyPrize }),
6554
+ hero && /* @__PURE__ */ jsx65(GameTile, { game: hero, onOpen, ui, variant: "hero" }),
6555
+ (grid.length > 0 || wide) && /* @__PURE__ */ jsxs58("section", { className: "ss-g-sec", children: [
6556
+ /* @__PURE__ */ jsxs58("div", { className: "ss-g-sec-head", children: [
6557
+ /* @__PURE__ */ jsx65("h3", { children: ui.games.dailyGames }),
6558
+ /* @__PURE__ */ jsx65("span", { children: ui.games.newSetAtMidnight })
6138
6559
  ] }),
6139
- grid.length > 0 && /* @__PURE__ */ jsx63("div", { className: "ss-g-grid", children: grid.map((g) => /* @__PURE__ */ jsx63(GameTile, { game: g, onOpen, ui }, tileKey(g))) }),
6140
- wide && /* @__PURE__ */ jsx63(GameTile, { game: wide, onOpen, ui, variant: "wide" })
6560
+ grid.length > 0 && /* @__PURE__ */ jsx65("div", { className: "ss-g-grid", children: grid.map((g) => /* @__PURE__ */ jsx65(GameTile, { game: g, onOpen, ui }, tileKey(g))) }),
6561
+ wide && /* @__PURE__ */ jsx65(GameTile, { game: wide, onOpen, ui, variant: "wide" })
6141
6562
  ] }),
6142
- fixtures.length > 0 && /* @__PURE__ */ jsxs56("section", { className: "ss-g-sec", children: [
6143
- /* @__PURE__ */ jsxs56("div", { className: "ss-g-sec-head", children: [
6144
- /* @__PURE__ */ jsx63("h3", { children: ui.games.matchdayGames }),
6145
- kickoffs[0] && /* @__PURE__ */ jsx63("span", { children: ui.games.kickoffAt(ui.games.formatDayTime(kickoffs[0])) })
6563
+ fixtures.length > 0 && /* @__PURE__ */ jsxs58("section", { className: "ss-g-sec", children: [
6564
+ /* @__PURE__ */ jsxs58("div", { className: "ss-g-sec-head", children: [
6565
+ /* @__PURE__ */ jsx65("h3", { children: ui.games.matchdayGames }),
6566
+ kickoffs[0] && /* @__PURE__ */ jsx65("span", { children: ui.games.kickoffAt(ui.games.formatDayTime(kickoffs[0])) })
6146
6567
  ] }),
6147
- /* @__PURE__ */ jsx63("div", { className: "ss-g-grid", children: fixtures.map((g) => /* @__PURE__ */ jsx63(GameTile, { game: g, onOpen, ui }, tileKey(g))) })
6568
+ /* @__PURE__ */ jsx65("div", { className: "ss-g-grid", children: fixtures.map((g) => /* @__PURE__ */ jsx65(GameTile, { game: g, onOpen, ui }, tileKey(g))) })
6148
6569
  ] })
6149
6570
  ] });
6150
6571
  }
6151
6572
 
6152
6573
  // src/components/GameScreenHost.tsx
6153
- import { useEffect as useEffect22, useRef as useRef19, useState as useState39 } from "react";
6574
+ import { useEffect as useEffect24, useRef as useRef20, useState as useState42 } from "react";
6154
6575
 
6155
6576
  // src/useGamePlay.ts
6156
- import { useCallback as useCallback13, useRef as useRef17, useState as useState28 } from "react";
6577
+ import { useCallback as useCallback14, useRef as useRef18, useState as useState31 } from "react";
6157
6578
  function toSubmitResult(payload) {
6158
6579
  return {
6159
6580
  // 'pending' means the play is recorded but awaiting resolution (fixture games)
@@ -6165,17 +6586,17 @@ function toSubmitResult(payload) {
6165
6586
  };
6166
6587
  }
6167
6588
  function useGamePlay(conversation, { gameId, gameDay, fixtureId, locale, refresh }) {
6168
- const [result, setResult] = useState28(null);
6169
- const [submitting, setSubmitting] = useState28(false);
6170
- const [rawStatus, setRawStatus] = useState28(null);
6171
- const inFlightRef = useRef17(false);
6172
- const convRef = useRef17(conversation);
6589
+ const [result, setResult] = useState31(null);
6590
+ const [submitting, setSubmitting] = useState31(false);
6591
+ const [rawStatus, setRawStatus] = useState31(null);
6592
+ const inFlightRef = useRef18(false);
6593
+ const convRef = useRef18(conversation);
6173
6594
  convRef.current = conversation;
6174
- const optsRef = useRef17({ gameId, gameDay, fixtureId, locale, refresh });
6595
+ const optsRef = useRef18({ gameId, gameDay, fixtureId, locale, refresh });
6175
6596
  optsRef.current = { gameId, gameDay, fixtureId, locale, refresh };
6176
- const resultRef = useRef17(null);
6597
+ const resultRef = useRef18(null);
6177
6598
  resultRef.current = result;
6178
- const refetch = useCallback13(async () => {
6599
+ const refetch = useCallback14(async () => {
6179
6600
  const conv = convRef.current;
6180
6601
  if (!conv) return;
6181
6602
  const opts = optsRef.current;
@@ -6191,7 +6612,7 @@ function useGamePlay(conversation, { gameId, gameDay, fixtureId, locale, refresh
6191
6612
  } catch {
6192
6613
  }
6193
6614
  }, []);
6194
- const submit = useCallback13(async (answerJson) => {
6615
+ const submit = useCallback14(async (answerJson) => {
6195
6616
  const conv = convRef.current;
6196
6617
  if (!conv || inFlightRef.current) return;
6197
6618
  inFlightRef.current = true;
@@ -6218,14 +6639,14 @@ function useGamePlay(conversation, { gameId, gameDay, fixtureId, locale, refresh
6218
6639
  setSubmitting(false);
6219
6640
  }
6220
6641
  }, [refetch]);
6221
- const hydrate = useCallback13(() => {
6642
+ const hydrate = useCallback14(() => {
6222
6643
  void refetch();
6223
6644
  }, [refetch]);
6224
6645
  return { result, submitting, submit, hydrate, rawStatus };
6225
6646
  }
6226
6647
 
6227
6648
  // src/components/games/MysteryTigerGame.tsx
6228
- import { useState as useState30, useId as useId2 } from "react";
6649
+ import { useState as useState33, useId as useId3 } from "react";
6229
6650
 
6230
6651
  // src/components/games/nationFlags.ts
6231
6652
  var FLAGS = {
@@ -6436,8 +6857,8 @@ function isNationCode(flag) {
6436
6857
  }
6437
6858
 
6438
6859
  // src/components/games/PlayerAvatar.tsx
6439
- import { useState as useState29 } from "react";
6440
- import { jsx as jsx64 } from "react/jsx-runtime";
6860
+ import { useState as useState32 } from "react";
6861
+ import { jsx as jsx66 } from "react/jsx-runtime";
6441
6862
  function initialsOf(name) {
6442
6863
  const parts = name.trim().split(/\s+/).filter(Boolean);
6443
6864
  const first = parts[0];
@@ -6454,41 +6875,41 @@ function PlayerAvatar({
6454
6875
  imagePath,
6455
6876
  className
6456
6877
  }) {
6457
- const [failed, setFailed] = useState29(false);
6878
+ const [failed, setFailed] = useState32(false);
6458
6879
  const showImage = Boolean(imagePath) && !isPlaceholderImage(imagePath) && !failed;
6459
- return /* @__PURE__ */ jsx64("div", { className, "aria-hidden": "true", children: showImage ? /* @__PURE__ */ jsx64("img", { src: imagePath, alt: "", loading: "lazy", onError: () => setFailed(true) }) : /* @__PURE__ */ jsx64("span", { className: "ss-w-av-initials", children: initialsOf(name) }) });
6880
+ return /* @__PURE__ */ jsx66("div", { className, "aria-hidden": "true", children: showImage ? /* @__PURE__ */ jsx66("img", { src: imagePath, alt: "", loading: "lazy", onError: () => setFailed(true) }) : /* @__PURE__ */ jsx66("span", { className: "ss-w-av-initials", children: initialsOf(name) }) });
6460
6881
  }
6461
6882
 
6462
6883
  // src/components/games/ui/GameHeader.tsx
6463
- import { jsx as jsx65, jsxs as jsxs57 } from "react/jsx-runtime";
6884
+ import { jsx as jsx67, jsxs as jsxs59 } from "react/jsx-runtime";
6464
6885
  function GameHeader({ title, eyebrow, right, onBack, backLabel }) {
6465
- return /* @__PURE__ */ jsxs57("div", { className: "ss-g-head", children: [
6466
- onBack && /* @__PURE__ */ jsx65("button", { type: "button", className: "ss-g-back", "aria-label": backLabel, onClick: onBack, children: /* @__PURE__ */ jsx65(IconChevronLeft, {}) }),
6467
- /* @__PURE__ */ jsxs57("div", { className: "ss-g-head-text", children: [
6468
- eyebrow && /* @__PURE__ */ jsx65("span", { className: "ss-g-eyebrow", children: eyebrow }),
6469
- /* @__PURE__ */ jsx65("h2", { className: "ss-g-title", children: title })
6886
+ return /* @__PURE__ */ jsxs59("div", { className: "ss-g-head", children: [
6887
+ onBack && /* @__PURE__ */ jsx67("button", { type: "button", className: "ss-g-back", "aria-label": backLabel, onClick: onBack, children: /* @__PURE__ */ jsx67(IconChevronLeft, {}) }),
6888
+ /* @__PURE__ */ jsxs59("div", { className: "ss-g-head-text", children: [
6889
+ eyebrow && /* @__PURE__ */ jsx67("span", { className: "ss-g-eyebrow", children: eyebrow }),
6890
+ /* @__PURE__ */ jsx67("h2", { className: "ss-g-title", children: title })
6470
6891
  ] }),
6471
- right && /* @__PURE__ */ jsx65("div", { className: "ss-g-head-right", children: right })
6892
+ right && /* @__PURE__ */ jsx67("div", { className: "ss-g-head-right", children: right })
6472
6893
  ] });
6473
6894
  }
6474
6895
 
6475
6896
  // src/components/games/ui/SegmentProgress.tsx
6476
- import { jsx as jsx66, jsxs as jsxs58 } from "react/jsx-runtime";
6897
+ import { jsx as jsx68, jsxs as jsxs60 } from "react/jsx-runtime";
6477
6898
  function SegmentProgress({ segments, ariaLabel, leftLabel, rightLabel, right }) {
6478
- return /* @__PURE__ */ jsxs58("div", { className: "ss-g-progress", children: [
6479
- /* @__PURE__ */ jsxs58("div", { className: "ss-g-progress-main", children: [
6480
- (leftLabel || rightLabel) && /* @__PURE__ */ jsxs58("div", { className: "ss-g-progress-labels", children: [
6481
- /* @__PURE__ */ jsx66("span", { children: leftLabel }),
6482
- /* @__PURE__ */ jsx66("span", { className: "ss-g-progress-rl", children: rightLabel })
6899
+ return /* @__PURE__ */ jsxs60("div", { className: "ss-g-progress", children: [
6900
+ /* @__PURE__ */ jsxs60("div", { className: "ss-g-progress-main", children: [
6901
+ (leftLabel || rightLabel) && /* @__PURE__ */ jsxs60("div", { className: "ss-g-progress-labels", children: [
6902
+ /* @__PURE__ */ jsx68("span", { children: leftLabel }),
6903
+ /* @__PURE__ */ jsx68("span", { className: "ss-g-progress-rl", children: rightLabel })
6483
6904
  ] }),
6484
- /* @__PURE__ */ jsx66(
6905
+ /* @__PURE__ */ jsx68(
6485
6906
  "div",
6486
6907
  {
6487
6908
  className: "ss-g-segs",
6488
6909
  role: "img",
6489
6910
  "aria-label": ariaLabel,
6490
6911
  style: { gridTemplateColumns: `repeat(${segments.length}, minmax(0, 1fr))` },
6491
- children: segments.map((s, i) => /* @__PURE__ */ jsx66("span", { className: "ss-g-seg", "data-state": s }, i))
6912
+ children: segments.map((s, i) => /* @__PURE__ */ jsx68("span", { className: "ss-g-seg", "data-state": s }, i))
6492
6913
  }
6493
6914
  )
6494
6915
  ] }),
@@ -6496,38 +6917,13 @@ function SegmentProgress({ segments, ariaLabel, leftLabel, rightLabel, right })
6496
6917
  ] });
6497
6918
  }
6498
6919
 
6499
- // src/components/games/ui/SearchField.tsx
6500
- import { jsx as jsx67, jsxs as jsxs59 } from "react/jsx-runtime";
6501
- function SearchField({ id, label, labelHidden = false, placeholder, value, onChange, disabled, inputRef, onKeyDown }) {
6502
- return /* @__PURE__ */ jsxs59("div", { className: "ss-g-search", children: [
6503
- /* @__PURE__ */ jsx67("label", { htmlFor: id, className: labelHidden ? "ss-g-sr" : "ss-g-search-label", children: label }),
6504
- /* @__PURE__ */ jsxs59("div", { className: "ss-g-search-box", children: [
6505
- /* @__PURE__ */ jsx67(IconSearch, {}),
6506
- /* @__PURE__ */ jsx67(
6507
- "input",
6508
- {
6509
- id,
6510
- ref: inputRef,
6511
- type: "text",
6512
- autoComplete: "off",
6513
- placeholder,
6514
- value,
6515
- disabled,
6516
- onKeyDown,
6517
- onChange: (e) => onChange(e.target.value)
6518
- }
6519
- )
6520
- ] })
6521
- ] });
6522
- }
6523
-
6524
6920
  // src/components/games/ui/AnswerTray.tsx
6525
- import { Fragment as Fragment11, jsx as jsx68, jsxs as jsxs60 } from "react/jsx-runtime";
6921
+ import { Fragment as Fragment11, jsx as jsx69, jsxs as jsxs61 } from "react/jsx-runtime";
6526
6922
  function AnswerTray({ id, label, placeholder, optionsLabel, options, query, onQuery, onPick, disabled, minQuery = 0 }) {
6527
6923
  const needle = query.trim().toLowerCase();
6528
6924
  const shown = needle.length < minQuery ? [] : needle ? options.filter((o) => o.name.toLowerCase().includes(needle)) : options;
6529
- return /* @__PURE__ */ jsxs60(Fragment11, { children: [
6530
- /* @__PURE__ */ jsx68(
6925
+ return /* @__PURE__ */ jsxs61(Fragment11, { children: [
6926
+ /* @__PURE__ */ jsx69(
6531
6927
  SearchField,
6532
6928
  {
6533
6929
  id,
@@ -6539,9 +6935,9 @@ function AnswerTray({ id, label, placeholder, optionsLabel, options, query, onQu
6539
6935
  disabled
6540
6936
  }
6541
6937
  ),
6542
- shown.length > 0 && /* @__PURE__ */ jsx68("div", { className: "ss-g-tray", role: "listbox", "aria-label": optionsLabel, children: shown.map((o) => {
6938
+ shown.length > 0 && /* @__PURE__ */ jsx69("div", { className: "ss-g-tray", role: "listbox", "aria-label": optionsLabel, children: shown.map((o) => {
6543
6939
  const { first, last } = splitName(o.name);
6544
- return /* @__PURE__ */ jsxs60(
6940
+ return /* @__PURE__ */ jsxs61(
6545
6941
  "button",
6546
6942
  {
6547
6943
  type: "button",
@@ -6552,10 +6948,10 @@ function AnswerTray({ id, label, placeholder, optionsLabel, options, query, onQu
6552
6948
  disabled,
6553
6949
  onClick: () => onPick(o.id),
6554
6950
  children: [
6555
- /* @__PURE__ */ jsx68(PlayerAvatar, { className: "ss-g-tray-av", name: o.name, imagePath: o.imagePath }),
6556
- /* @__PURE__ */ jsxs60("span", { className: "ss-g-tray-name", "aria-hidden": "true", children: [
6557
- first && /* @__PURE__ */ jsx68("span", { className: "ss-g-tray-first", children: first }),
6558
- /* @__PURE__ */ jsx68("span", { className: "ss-g-tray-last", children: last })
6951
+ /* @__PURE__ */ jsx69(PlayerAvatar, { className: "ss-g-tray-av", name: o.name, imagePath: o.imagePath }),
6952
+ /* @__PURE__ */ jsxs61("span", { className: "ss-g-tray-name", "aria-hidden": "true", children: [
6953
+ first && /* @__PURE__ */ jsx69("span", { className: "ss-g-tray-first", children: first }),
6954
+ /* @__PURE__ */ jsx69("span", { className: "ss-g-tray-last", children: last })
6559
6955
  ] })
6560
6956
  ]
6561
6957
  },
@@ -6566,59 +6962,59 @@ function AnswerTray({ id, label, placeholder, optionsLabel, options, query, onQu
6566
6962
  }
6567
6963
 
6568
6964
  // src/components/games/ui/FooterBar.tsx
6569
- import { jsx as jsx69 } from "react/jsx-runtime";
6965
+ import { jsx as jsx70 } from "react/jsx-runtime";
6570
6966
  function FooterBar({ children }) {
6571
- return /* @__PURE__ */ jsx69("div", { className: "ss-g-footer", children });
6967
+ return /* @__PURE__ */ jsx70("div", { className: "ss-g-footer", children });
6572
6968
  }
6573
6969
 
6574
6970
  // src/components/games/ui/Silhouette.tsx
6575
- import { jsx as jsx70, jsxs as jsxs61 } from "react/jsx-runtime";
6971
+ import { jsx as jsx71, jsxs as jsxs62 } from "react/jsx-runtime";
6576
6972
  function Silhouette({ size, variant = "default" }) {
6577
- return /* @__PURE__ */ jsxs61("span", { className: `ss-g-sil ss-g-sil--${variant}`, style: { width: size, height: size }, "aria-hidden": "true", children: [
6578
- /* @__PURE__ */ jsxs61("svg", { width: size * 0.86, height: size * 0.86, viewBox: "0 0 100 100", children: [
6579
- /* @__PURE__ */ jsx70("circle", { cx: "50", cy: "40", r: "19", fill: "currentColor" }),
6580
- /* @__PURE__ */ jsx70("path", { d: "M12 100c0-23 17-38 38-38s38 15 38 38z", fill: "currentColor" })
6973
+ return /* @__PURE__ */ jsxs62("span", { className: `ss-g-sil ss-g-sil--${variant}`, style: { width: size, height: size }, "aria-hidden": "true", children: [
6974
+ /* @__PURE__ */ jsxs62("svg", { width: size * 0.86, height: size * 0.86, viewBox: "0 0 100 100", children: [
6975
+ /* @__PURE__ */ jsx71("circle", { cx: "50", cy: "40", r: "19", fill: "currentColor" }),
6976
+ /* @__PURE__ */ jsx71("path", { d: "M12 100c0-23 17-38 38-38s38 15 38 38z", fill: "currentColor" })
6581
6977
  ] }),
6582
- variant === "mystery" && /* @__PURE__ */ jsx70("span", { className: "ss-g-sil-q", children: "?" })
6978
+ variant === "mystery" && /* @__PURE__ */ jsx71("span", { className: "ss-g-sil-q", children: "?" })
6583
6979
  ] });
6584
6980
  }
6585
6981
 
6586
6982
  // src/components/games/ui/GameButton.tsx
6587
- import { jsx as jsx71 } from "react/jsx-runtime";
6983
+ import { jsx as jsx72 } from "react/jsx-runtime";
6588
6984
  function GameButton({ variant = "primary", block = false, className, type = "button", ...rest }) {
6589
6985
  const cls = `ss-g-btn ss-g-btn--${variant}${block ? " ss-g-btn--block" : ""}${className ? ` ${className}` : ""}`;
6590
- return /* @__PURE__ */ jsx71("button", { type, className: cls, ...rest });
6986
+ return /* @__PURE__ */ jsx72("button", { type, className: cls, ...rest });
6591
6987
  }
6592
6988
 
6593
6989
  // src/components/games/ui/ResultCard.tsx
6594
- import { jsx as jsx72, jsxs as jsxs62 } from "react/jsx-runtime";
6990
+ import { jsx as jsx73, jsxs as jsxs63 } from "react/jsx-runtime";
6595
6991
  function ResultCard({ tone, title, score, detail, onBack, ui }) {
6596
- return /* @__PURE__ */ jsxs62("div", { className: "ss-g-result", "data-tone": tone, role: "status", children: [
6597
- /* @__PURE__ */ jsx72("span", { className: "ss-g-result-title", children: title }),
6598
- score !== void 0 && /* @__PURE__ */ jsxs62("span", { className: "ss-g-result-score", children: [
6599
- /* @__PURE__ */ jsx72("span", { className: "ss-g-result-num", children: score }),
6992
+ return /* @__PURE__ */ jsxs63("div", { className: "ss-g-result", "data-tone": tone, role: "status", children: [
6993
+ /* @__PURE__ */ jsx73("span", { className: "ss-g-result-title", children: title }),
6994
+ score !== void 0 && /* @__PURE__ */ jsxs63("span", { className: "ss-g-result-score", children: [
6995
+ /* @__PURE__ */ jsx73("span", { className: "ss-g-result-num", children: score }),
6600
6996
  ui.games.unitPts
6601
6997
  ] }),
6602
- detail && /* @__PURE__ */ jsx72("span", { className: "ss-g-result-detail", children: detail }),
6603
- onBack && /* @__PURE__ */ jsx72(GameButton, { variant: "outline", onClick: onBack, children: ui.games.backToGames })
6998
+ detail && /* @__PURE__ */ jsx73("span", { className: "ss-g-result-detail", children: detail }),
6999
+ onBack && /* @__PURE__ */ jsx73(GameButton, { variant: "outline", onClick: onBack, children: ui.games.backToGames })
6604
7000
  ] });
6605
7001
  }
6606
7002
 
6607
7003
  // src/components/games/ui/PointsLadderRow.tsx
6608
- import { jsx as jsx73, jsxs as jsxs63 } from "react/jsx-runtime";
7004
+ import { jsx as jsx74, jsxs as jsxs64 } from "react/jsx-runtime";
6609
7005
  function PointsLadderRow({ ladder, guessesUsed, ui }) {
6610
7006
  if (!ladder || ladder.length === 0) return null;
6611
7007
  const now = ladder[Math.min(guessesUsed, ladder.length - 1)];
6612
7008
  const next = ladder[guessesUsed + 1];
6613
7009
  if (now === void 0) return null;
6614
- return /* @__PURE__ */ jsxs63("div", { className: "ss-g-worth", "data-testid": "points-ladder", children: [
6615
- /* @__PURE__ */ jsx73("span", { className: "ss-g-worth-now", children: ui.games.worthNow(now) }),
6616
- next !== void 0 && next !== now && /* @__PURE__ */ jsx73("span", { className: "ss-g-worth-next", children: ui.games.worthAfterMiss(next) })
7010
+ return /* @__PURE__ */ jsxs64("div", { className: "ss-g-worth", "data-testid": "points-ladder", children: [
7011
+ /* @__PURE__ */ jsx74("span", { className: "ss-g-worth-now", children: ui.games.worthNow(now) }),
7012
+ next !== void 0 && next !== now && /* @__PURE__ */ jsx74("span", { className: "ss-g-worth-next", children: ui.games.worthAfterMiss(next) })
6617
7013
  ] });
6618
7014
  }
6619
7015
 
6620
7016
  // src/components/games/MysteryTigerGame.tsx
6621
- import { Fragment as Fragment12, jsx as jsx74, jsxs as jsxs64 } from "react/jsx-runtime";
7017
+ import { Fragment as Fragment12, jsx as jsx75, jsxs as jsxs65 } from "react/jsx-runtime";
6622
7018
  function parseClientState(json) {
6623
7019
  if (!json) return null;
6624
7020
  try {
@@ -6720,8 +7116,8 @@ function MysteryTigerGame({
6720
7116
  onBack
6721
7117
  }) {
6722
7118
  const t = ui.games.mysteryTiger;
6723
- const [query, setQuery] = useState30("");
6724
- const inputId = useId2();
7119
+ const [query, setQuery] = useState33("");
7120
+ const inputId = useId3();
6725
7121
  const clientState = parseClientState(result?.clientStateJson);
6726
7122
  const guessResults = clientState?.guessResults ?? [];
6727
7123
  const alreadyGuessedIds = new Set(guessResults.map((g) => g.playerId));
@@ -6740,22 +7136,22 @@ function MysteryTigerGame({
6740
7136
  setQuery("");
6741
7137
  onSubmit(JSON.stringify({ guesses: newGuesses }));
6742
7138
  }
6743
- const headerRight = !config ? void 0 : isOver ? /* @__PURE__ */ jsxs64(Chip, { variant: "accent", children: [
7139
+ const headerRight = !config ? void 0 : isOver ? /* @__PURE__ */ jsxs65(Chip, { variant: "accent", children: [
6744
7140
  score,
6745
7141
  " ",
6746
7142
  ui.games.unitPts
6747
- ] }) : /* @__PURE__ */ jsx74("span", { "data-testid": "mt-chip", children: /* @__PURE__ */ jsxs64(Chip, { children: [
7143
+ ] }) : /* @__PURE__ */ jsx75("span", { "data-testid": "mt-chip", children: /* @__PURE__ */ jsxs65(Chip, { children: [
6748
7144
  ui.games.guess,
6749
7145
  " ",
6750
- /* @__PURE__ */ jsx74("span", { className: "ss-g-num", children: guessesUsed + 1 }),
7146
+ /* @__PURE__ */ jsx75("span", { className: "ss-g-num", children: guessesUsed + 1 }),
6751
7147
  " / ",
6752
7148
  totalGuesses
6753
7149
  ] }) });
6754
7150
  const segments = Array.from({ length: totalGuesses }, (_, i) => i < guessesUsed ? "done" : i === guessesUsed ? "current" : "todo");
6755
7151
  const cols = { gridTemplateColumns: `minmax(0, 1fr) repeat(${keys.length}, 42px)` };
6756
7152
  const known = deriveKnownAttributes(guessResults, keys);
6757
- return /* @__PURE__ */ jsxs64("div", { className: "ss-g-screen ss-g-mt", "data-game": "mystery-tiger", "data-testid": "game-screen-mystery-tiger", children: [
6758
- /* @__PURE__ */ jsx74(
7153
+ return /* @__PURE__ */ jsxs65("div", { className: "ss-g-screen ss-g-mt", "data-game": "mystery-tiger", "data-testid": "game-screen-mystery-tiger", children: [
7154
+ /* @__PURE__ */ jsx75(
6759
7155
  GameHeader,
6760
7156
  {
6761
7157
  title: gameTitle({ gameId: "mystery-tiger" }, ui.games.titles),
@@ -6765,41 +7161,41 @@ function MysteryTigerGame({
6765
7161
  backLabel: ui.back
6766
7162
  }
6767
7163
  ),
6768
- !config && /* @__PURE__ */ jsx74("div", { className: "ss-g-body ss-g-loading", children: ui.games.loading }),
6769
- config && /* @__PURE__ */ jsxs64(Fragment12, { children: [
6770
- /* @__PURE__ */ jsxs64("div", { className: "ss-g-body", children: [
6771
- !isOver && /* @__PURE__ */ jsx74(PointsLadderRow, { ladder: config.pointsLadder, guessesUsed, ui }),
6772
- /* @__PURE__ */ jsxs64("div", { className: `ss-g-mt-card${isOver ? " ss-g-mt-card--reveal" : ""}`, children: [
6773
- /* @__PURE__ */ jsxs64("div", { className: "ss-g-mt-portrait", children: [
6774
- revealName ? /* @__PURE__ */ jsx74(PlayerAvatar, { className: "ss-g-mt-photo", name: revealName, imagePath: clientState?.revealedPlayerImagePath }) : /* @__PURE__ */ jsx74(Silhouette, { size: 150, variant: "mystery" }),
6775
- revealName && /* @__PURE__ */ jsx74("span", { className: "ss-g-mt-reveal-name", children: revealName })
7164
+ !config && /* @__PURE__ */ jsx75("div", { className: "ss-g-body ss-g-loading", children: ui.games.loading }),
7165
+ config && /* @__PURE__ */ jsxs65(Fragment12, { children: [
7166
+ /* @__PURE__ */ jsxs65("div", { className: "ss-g-body", children: [
7167
+ !isOver && /* @__PURE__ */ jsx75(PointsLadderRow, { ladder: config.pointsLadder, guessesUsed, ui }),
7168
+ /* @__PURE__ */ jsxs65("div", { className: `ss-g-mt-card${isOver ? " ss-g-mt-card--reveal" : ""}`, children: [
7169
+ /* @__PURE__ */ jsxs65("div", { className: "ss-g-mt-portrait", children: [
7170
+ revealName ? /* @__PURE__ */ jsx75(PlayerAvatar, { className: "ss-g-mt-photo", name: revealName, imagePath: clientState?.revealedPlayerImagePath }) : /* @__PURE__ */ jsx75(Silhouette, { size: 150, variant: "mystery" }),
7171
+ revealName && /* @__PURE__ */ jsx75("span", { className: "ss-g-mt-reveal-name", children: revealName })
6776
7172
  ] }),
6777
- /* @__PURE__ */ jsx74("div", { className: "ss-g-mt-known", style: { gridTemplateColumns: `repeat(${keys.length}, minmax(0, 1fr))` }, children: known.map((k) => /* @__PURE__ */ jsxs64("div", { className: "ss-g-mt-known-cell", children: [
6778
- /* @__PURE__ */ jsx74("span", { className: "ss-g-mt-lab", children: t.labels[k.key] }),
6779
- /* @__PURE__ */ jsx74("span", { className: "ss-g-mt-known-v", "data-state": k.state, "data-testid": `known-${k.key}`, children: k.text })
7173
+ /* @__PURE__ */ jsx75("div", { className: "ss-g-mt-known", style: { gridTemplateColumns: `repeat(${keys.length}, minmax(0, 1fr))` }, children: known.map((k) => /* @__PURE__ */ jsxs65("div", { className: "ss-g-mt-known-cell", children: [
7174
+ /* @__PURE__ */ jsx75("span", { className: "ss-g-mt-lab", children: t.labels[k.key] }),
7175
+ /* @__PURE__ */ jsx75("span", { className: "ss-g-mt-known-v", "data-state": k.state, "data-testid": `known-${k.key}`, children: k.text })
6780
7176
  ] }, k.key)) })
6781
7177
  ] }),
6782
- !isOver && /* @__PURE__ */ jsx74(SegmentProgress, { segments, ariaLabel: t.progress(guessesUsed, totalGuesses) }),
6783
- guessResults.length > 0 && /* @__PURE__ */ jsxs64("div", { className: "ss-g-mt-table", children: [
6784
- /* @__PURE__ */ jsxs64("div", { className: "ss-g-mt-thead", style: cols, children: [
6785
- /* @__PURE__ */ jsx74("span", { children: t.yourGuesses }),
6786
- keys.map((k) => /* @__PURE__ */ jsx74("span", { children: t.labels[k] }, k))
7178
+ !isOver && /* @__PURE__ */ jsx75(SegmentProgress, { segments, ariaLabel: t.progress(guessesUsed, totalGuesses) }),
7179
+ guessResults.length > 0 && /* @__PURE__ */ jsxs65("div", { className: "ss-g-mt-table", children: [
7180
+ /* @__PURE__ */ jsxs65("div", { className: "ss-g-mt-thead", style: cols, children: [
7181
+ /* @__PURE__ */ jsx75("span", { children: t.yourGuesses }),
7182
+ keys.map((k) => /* @__PURE__ */ jsx75("span", { children: t.labels[k] }, k))
6787
7183
  ] }),
6788
7184
  guessResults.map((gr, i) => {
6789
7185
  const name = config.squadPlayers.find((p) => p.id === gr.playerId)?.name ?? `#${gr.playerId}`;
6790
7186
  const { first, last } = splitName(name);
6791
- return /* @__PURE__ */ jsxs64("div", { className: "ss-g-mt-row", style: cols, children: [
6792
- /* @__PURE__ */ jsxs64("div", { className: "ss-g-mt-who", children: [
6793
- /* @__PURE__ */ jsx74(PlayerAvatar, { className: "ss-g-mt-av", name }),
6794
- /* @__PURE__ */ jsxs64("span", { className: "ss-g-mt-names", children: [
6795
- first && /* @__PURE__ */ jsx74("span", { className: "ss-g-mt-first", children: first }),
6796
- /* @__PURE__ */ jsx74("span", { className: "ss-g-mt-last", children: last })
7187
+ return /* @__PURE__ */ jsxs65("div", { className: "ss-g-mt-row", style: cols, children: [
7188
+ /* @__PURE__ */ jsxs65("div", { className: "ss-g-mt-who", children: [
7189
+ /* @__PURE__ */ jsx75(PlayerAvatar, { className: "ss-g-mt-av", name }),
7190
+ /* @__PURE__ */ jsxs65("span", { className: "ss-g-mt-names", children: [
7191
+ first && /* @__PURE__ */ jsx75("span", { className: "ss-g-mt-first", children: first }),
7192
+ /* @__PURE__ */ jsx75("span", { className: "ss-g-mt-last", children: last })
6797
7193
  ] })
6798
7194
  ] }),
6799
7195
  keys.map((key) => {
6800
7196
  const v = gr[key];
6801
7197
  const arrow = directionArrow(v);
6802
- return /* @__PURE__ */ jsxs64(
7198
+ return /* @__PURE__ */ jsxs65(
6803
7199
  "div",
6804
7200
  {
6805
7201
  className: "ss-g-mt-cell",
@@ -6807,8 +7203,8 @@ function MysteryTigerGame({
6807
7203
  "data-verdict": v.verdict,
6808
7204
  "aria-label": `${t.labels[key]}: ${v.value ?? v.verdict}${v.direction ? ` ${v.direction}` : ""}`,
6809
7205
  children: [
6810
- /* @__PURE__ */ jsx74("span", { className: "ss-g-mt-cell-v", "aria-hidden": "true", children: tileFace(key, v) }),
6811
- arrow && /* @__PURE__ */ jsx74("span", { className: "ss-g-mt-cell-dir", "aria-hidden": "true", children: arrow })
7206
+ /* @__PURE__ */ jsx75("span", { className: "ss-g-mt-cell-v", "aria-hidden": "true", children: tileFace(key, v) }),
7207
+ arrow && /* @__PURE__ */ jsx75("span", { className: "ss-g-mt-cell-dir", "aria-hidden": "true", children: arrow })
6812
7208
  ]
6813
7209
  },
6814
7210
  key
@@ -6817,25 +7213,25 @@ function MysteryTigerGame({
6817
7213
  ] }, gr.playerId);
6818
7214
  })
6819
7215
  ] }),
6820
- !isOver && /* @__PURE__ */ jsxs64("div", { className: "ss-g-mt-legend", children: [
6821
- /* @__PURE__ */ jsxs64("span", { children: [
6822
- /* @__PURE__ */ jsx74("i", { className: "ss-g-mt-sw", "data-verdict": "exact" }),
7216
+ !isOver && /* @__PURE__ */ jsxs65("div", { className: "ss-g-mt-legend", children: [
7217
+ /* @__PURE__ */ jsxs65("span", { children: [
7218
+ /* @__PURE__ */ jsx75("i", { className: "ss-g-mt-sw", "data-verdict": "exact" }),
6823
7219
  t.legendMatch
6824
7220
  ] }),
6825
- /* @__PURE__ */ jsxs64("span", { children: [
6826
- /* @__PURE__ */ jsx74("i", { className: "ss-g-mt-sw", "data-verdict": "near" }),
7221
+ /* @__PURE__ */ jsxs65("span", { children: [
7222
+ /* @__PURE__ */ jsx75("i", { className: "ss-g-mt-sw", "data-verdict": "near" }),
6827
7223
  t.legendClose
6828
7224
  ] }),
6829
- /* @__PURE__ */ jsxs64("span", { children: [
7225
+ /* @__PURE__ */ jsxs65("span", { children: [
6830
7226
  "\u25B2 ",
6831
7227
  t.legendHigher
6832
7228
  ] })
6833
7229
  ] }),
6834
- clientState?.hintLine && !isOver && /* @__PURE__ */ jsxs64("div", { className: "ss-g-mt-hint", children: [
6835
- /* @__PURE__ */ jsx74(IconBulb, {}),
6836
- /* @__PURE__ */ jsx74("span", { children: clientState.hintLine })
7230
+ clientState?.hintLine && !isOver && /* @__PURE__ */ jsxs65("div", { className: "ss-g-mt-hint", children: [
7231
+ /* @__PURE__ */ jsx75(IconBulb, {}),
7232
+ /* @__PURE__ */ jsx75("span", { children: clientState.hintLine })
6837
7233
  ] }),
6838
- isOver && /* @__PURE__ */ jsx74(
7234
+ isOver && /* @__PURE__ */ jsx75(
6839
7235
  ResultCard,
6840
7236
  {
6841
7237
  tone: clientState?.solved ? "win" : clientState?.failed ? "lose" : "neutral",
@@ -6847,7 +7243,7 @@ function MysteryTigerGame({
6847
7243
  }
6848
7244
  )
6849
7245
  ] }),
6850
- !isOver && /* @__PURE__ */ jsx74(FooterBar, { children: /* @__PURE__ */ jsx74(
7246
+ !isOver && /* @__PURE__ */ jsx75(FooterBar, { children: /* @__PURE__ */ jsx75(
6851
7247
  AnswerTray,
6852
7248
  {
6853
7249
  id: inputId,
@@ -6866,7 +7262,7 @@ function MysteryTigerGame({
6866
7262
  }
6867
7263
 
6868
7264
  // src/components/games/HigherOrLowerGame.tsx
6869
- import { Fragment as Fragment13, jsx as jsx75, jsxs as jsxs65 } from "react/jsx-runtime";
7265
+ import { Fragment as Fragment13, jsx as jsx76, jsxs as jsxs66 } from "react/jsx-runtime";
6870
7266
  var POINTS_PER_CORRECT = 10;
6871
7267
  function parseClientState2(json) {
6872
7268
  if (!json) return null;
@@ -6878,11 +7274,11 @@ function parseClientState2(json) {
6878
7274
  }
6879
7275
  function PlayerCard({ name, imagePath, highlight, children }) {
6880
7276
  const { first, last } = splitName(name);
6881
- return /* @__PURE__ */ jsxs65("div", { className: `ss-g-hl-card${highlight ? " ss-g-hl-card--b" : ""}`, children: [
6882
- /* @__PURE__ */ jsx75("div", { className: "ss-g-hl-photo-wrap", children: imagePath ? /* @__PURE__ */ jsx75(PlayerAvatar, { className: "ss-g-hl-photo", name, imagePath }) : /* @__PURE__ */ jsx75(Silhouette, { size: 150 }) }),
6883
- /* @__PURE__ */ jsxs65("div", { className: "ss-g-hl-info", children: [
6884
- first && /* @__PURE__ */ jsx75("span", { className: "ss-g-hl-first", children: first }),
6885
- /* @__PURE__ */ jsx75("span", { className: "ss-g-hl-surname", children: last }),
7277
+ return /* @__PURE__ */ jsxs66("div", { className: `ss-g-hl-card${highlight ? " ss-g-hl-card--b" : ""}`, children: [
7278
+ /* @__PURE__ */ jsx76("div", { className: "ss-g-hl-photo-wrap", children: imagePath ? /* @__PURE__ */ jsx76(PlayerAvatar, { className: "ss-g-hl-photo", name, imagePath }) : /* @__PURE__ */ jsx76(Silhouette, { size: 150 }) }),
7279
+ /* @__PURE__ */ jsxs66("div", { className: "ss-g-hl-info", children: [
7280
+ first && /* @__PURE__ */ jsx76("span", { className: "ss-g-hl-first", children: first }),
7281
+ /* @__PURE__ */ jsx76("span", { className: "ss-g-hl-surname", children: last }),
6886
7282
  children
6887
7283
  ] })
6888
7284
  ] });
@@ -6914,47 +7310,47 @@ function HigherOrLowerGame({
6914
7310
  const newAnswers = [...prevAnswers, { pairIndex: currentPair.pairIndex, pick }];
6915
7311
  onSubmit(JSON.stringify({ answers: newAnswers }));
6916
7312
  }
6917
- return /* @__PURE__ */ jsxs65("div", { className: "ss-g-screen ss-g-hl", "data-game": "higher-or-lower", "data-testid": "game-screen-higher-or-lower", children: [
6918
- /* @__PURE__ */ jsx75(
7313
+ return /* @__PURE__ */ jsxs66("div", { className: "ss-g-screen ss-g-hl", "data-game": "higher-or-lower", "data-testid": "game-screen-higher-or-lower", children: [
7314
+ /* @__PURE__ */ jsx76(
6919
7315
  GameHeader,
6920
7316
  {
6921
7317
  title: gameTitle({ gameId: "higher-or-lower" }, ui.games.titles),
6922
7318
  eyebrow: t.eyebrow(POINTS_PER_CORRECT),
6923
- right: config ? /* @__PURE__ */ jsx75(StatStack, { value: runLength, label: t.streak }) : void 0,
7319
+ right: config ? /* @__PURE__ */ jsx76(StatStack, { value: runLength, label: t.streak }) : void 0,
6924
7320
  onBack,
6925
7321
  backLabel: ui.back
6926
7322
  }
6927
7323
  ),
6928
- !config && /* @__PURE__ */ jsx75("div", { className: "ss-g-body ss-g-loading", children: ui.games.loading }),
6929
- config && /* @__PURE__ */ jsxs65(Fragment13, { children: [
6930
- /* @__PURE__ */ jsxs65("div", { className: "ss-g-body", children: [
6931
- /* @__PURE__ */ jsxs65("div", { className: "ss-g-hl-prompt", "data-testid": "hol-prompt", children: [
6932
- /* @__PURE__ */ jsx75("span", { className: "ss-g-hl-prompt-q", children: t.whoHadMore }),
6933
- /* @__PURE__ */ jsx75("span", { className: "ss-g-hl-prompt-stat", children: config.statLabel }),
6934
- /* @__PURE__ */ jsx75("span", { className: "ss-g-hl-prompt-season", children: t.season(config.seasonLabel) })
7324
+ !config && /* @__PURE__ */ jsx76("div", { className: "ss-g-body ss-g-loading", children: ui.games.loading }),
7325
+ config && /* @__PURE__ */ jsxs66(Fragment13, { children: [
7326
+ /* @__PURE__ */ jsxs66("div", { className: "ss-g-body", children: [
7327
+ /* @__PURE__ */ jsxs66("div", { className: "ss-g-hl-prompt", "data-testid": "hol-prompt", children: [
7328
+ /* @__PURE__ */ jsx76("span", { className: "ss-g-hl-prompt-q", children: t.whoHadMore }),
7329
+ /* @__PURE__ */ jsx76("span", { className: "ss-g-hl-prompt-stat", children: config.statLabel }),
7330
+ /* @__PURE__ */ jsx76("span", { className: "ss-g-hl-prompt-season", children: t.season(config.seasonLabel) })
6935
7331
  ] }),
6936
- currentPair && /* @__PURE__ */ jsxs65("div", { className: "ss-g-hl-pair", children: [
6937
- /* @__PURE__ */ jsxs65(PlayerCard, { name: currentPair.playerAName, imagePath: currentPair.playerAImagePath, children: [
6938
- /* @__PURE__ */ jsx75("span", { className: "ss-g-hl-value", children: currentPair.playerAValue }),
6939
- /* @__PURE__ */ jsx75("span", { className: "ss-g-hl-stat", children: config.statLabel })
7332
+ currentPair && /* @__PURE__ */ jsxs66("div", { className: "ss-g-hl-pair", children: [
7333
+ /* @__PURE__ */ jsxs66(PlayerCard, { name: currentPair.playerAName, imagePath: currentPair.playerAImagePath, children: [
7334
+ /* @__PURE__ */ jsx76("span", { className: "ss-g-hl-value", children: currentPair.playerAValue }),
7335
+ /* @__PURE__ */ jsx76("span", { className: "ss-g-hl-stat", children: config.statLabel })
6940
7336
  ] }),
6941
- /* @__PURE__ */ jsx75("span", { className: "ss-g-hl-vs", "aria-hidden": "true", children: t.vs }),
6942
- /* @__PURE__ */ jsx75(PlayerCard, { name: currentPair.playerBName, imagePath: currentPair.playerBImagePath, highlight: true, children: /* @__PURE__ */ jsxs65("div", { className: "ss-g-hl-btns", children: [
6943
- /* @__PURE__ */ jsxs65(GameButton, { variant: "primary", disabled: submitting, onClick: () => handlePick("higher"), children: [
6944
- /* @__PURE__ */ jsx75(IconArrowUp, { size: 16 }),
7337
+ /* @__PURE__ */ jsx76("span", { className: "ss-g-hl-vs", "aria-hidden": "true", children: t.vs }),
7338
+ /* @__PURE__ */ jsx76(PlayerCard, { name: currentPair.playerBName, imagePath: currentPair.playerBImagePath, highlight: true, children: /* @__PURE__ */ jsxs66("div", { className: "ss-g-hl-btns", children: [
7339
+ /* @__PURE__ */ jsxs66(GameButton, { variant: "primary", disabled: submitting, onClick: () => handlePick("higher"), children: [
7340
+ /* @__PURE__ */ jsx76(IconArrowUp, { size: 16 }),
6945
7341
  t.higher
6946
7342
  ] }),
6947
- /* @__PURE__ */ jsxs65(GameButton, { variant: "outline", disabled: submitting, onClick: () => handlePick("lower"), children: [
6948
- /* @__PURE__ */ jsx75(IconArrowDown, { size: 16 }),
7343
+ /* @__PURE__ */ jsxs66(GameButton, { variant: "outline", disabled: submitting, onClick: () => handlePick("lower"), children: [
7344
+ /* @__PURE__ */ jsx76(IconArrowDown, { size: 16 }),
6949
7345
  t.lower
6950
7346
  ] })
6951
7347
  ] }) })
6952
7348
  ] }),
6953
- lastAnswer && lastAnswerPair && /* @__PURE__ */ jsxs65("p", { className: "ss-g-hl-feedback", "data-testid": "hol-last", "data-correct": lastAnswer.wasCorrect ? "true" : "false", children: [
6954
- lastAnswer.wasCorrect ? /* @__PURE__ */ jsx75(IconCheck, {}) : /* @__PURE__ */ jsx75(IconClose, {}),
7349
+ lastAnswer && lastAnswerPair && /* @__PURE__ */ jsxs66("p", { className: "ss-g-hl-feedback", "data-testid": "hol-last", "data-correct": lastAnswer.wasCorrect ? "true" : "false", children: [
7350
+ lastAnswer.wasCorrect ? /* @__PURE__ */ jsx76(IconCheck, {}) : /* @__PURE__ */ jsx76(IconClose, {}),
6955
7351
  t.lastAnswer(splitName(lastAnswerPair.playerBName).last, lastAnswer.playerBValue)
6956
7352
  ] }),
6957
- isOver && /* @__PURE__ */ jsx75(
7353
+ isOver && /* @__PURE__ */ jsx76(
6958
7354
  ResultCard,
6959
7355
  {
6960
7356
  tone: runEndedWrong ? "lose" : allPairsAnswered ? "win" : "neutral",
@@ -6966,15 +7362,15 @@ function HigherOrLowerGame({
6966
7362
  }
6967
7363
  )
6968
7364
  ] }),
6969
- !isOver && /* @__PURE__ */ jsx75(FooterBar, { children: /* @__PURE__ */ jsxs65("div", { className: "ss-g-hl-foot", children: [
6970
- /* @__PURE__ */ jsx75("div", { className: "ss-g-hl-dots", role: "img", "aria-label": t.answersSoFar(answeredCount, config.pairs.length), children: config.pairs.map((p, i) => {
7365
+ !isOver && /* @__PURE__ */ jsx76(FooterBar, { children: /* @__PURE__ */ jsxs66("div", { className: "ss-g-hl-foot", children: [
7366
+ /* @__PURE__ */ jsx76("div", { className: "ss-g-hl-dots", role: "img", "aria-label": t.answersSoFar(answeredCount, config.pairs.length), children: config.pairs.map((p, i) => {
6971
7367
  const a = answeredPairs[i];
6972
- return /* @__PURE__ */ jsx75("span", { className: "ss-g-hl-dot", "data-state": a ? a.wasCorrect ? "correct" : "wrong" : "todo" }, p.pairIndex);
7368
+ return /* @__PURE__ */ jsx76("span", { className: "ss-g-hl-dot", "data-state": a ? a.wasCorrect ? "correct" : "wrong" : "todo" }, p.pairIndex);
6973
7369
  }) }),
6974
- /* @__PURE__ */ jsxs65("span", { className: "ss-g-hl-pts", children: [
6975
- /* @__PURE__ */ jsx75("span", { "data-testid": "hol-score", children: score }),
7370
+ /* @__PURE__ */ jsxs66("span", { className: "ss-g-hl-pts", children: [
7371
+ /* @__PURE__ */ jsx76("span", { "data-testid": "hol-score", children: score }),
6976
7372
  " ",
6977
- /* @__PURE__ */ jsx75("span", { className: "ss-g-hl-pts-unit", children: ui.games.unitPts })
7373
+ /* @__PURE__ */ jsx76("span", { className: "ss-g-hl-pts-unit", children: ui.games.unitPts })
6978
7374
  ] })
6979
7375
  ] }) })
6980
7376
  ] })
@@ -6982,21 +7378,21 @@ function HigherOrLowerGame({
6982
7378
  }
6983
7379
 
6984
7380
  // src/components/games/CareerPathGame.tsx
6985
- import { useState as useState32, useId as useId3 } from "react";
7381
+ import { useState as useState35, useId as useId4 } from "react";
6986
7382
 
6987
7383
  // src/components/games/ui/CrestShield.tsx
6988
- import { useState as useState31 } from "react";
6989
- import { jsx as jsx76 } from "react/jsx-runtime";
7384
+ import { useState as useState34 } from "react";
7385
+ import { jsx as jsx77 } from "react/jsx-runtime";
6990
7386
  function CrestShield({ src, name, size = 28 }) {
6991
- const [failed, setFailed] = useState31(false);
7387
+ const [failed, setFailed] = useState34(false);
6992
7388
  if (src && !isPlaceholderImage(src) && !failed) {
6993
- return /* @__PURE__ */ jsx76("img", { className: "ss-g-crest", src, alt: name, width: size, height: size, loading: "lazy", onError: () => setFailed(true) });
7389
+ return /* @__PURE__ */ jsx77("img", { className: "ss-g-crest", src, alt: name, width: size, height: size, loading: "lazy", onError: () => setFailed(true) });
6994
7390
  }
6995
- return /* @__PURE__ */ jsx76("svg", { className: "ss-g-crest ss-g-crest--ph", width: size, height: size * 32 / 28, viewBox: "0 0 28 32", role: "img", "aria-label": name, children: /* @__PURE__ */ jsx76("path", { d: "M2 3h24v12c0 9-6 14-12 17C8 29 2 24 2 15z", fill: "currentColor" }) });
7391
+ return /* @__PURE__ */ jsx77("svg", { className: "ss-g-crest ss-g-crest--ph", width: size, height: size * 32 / 28, viewBox: "0 0 28 32", role: "img", "aria-label": name, children: /* @__PURE__ */ jsx77("path", { d: "M2 3h24v12c0 9-6 14-12 17C8 29 2 24 2 15z", fill: "currentColor" }) });
6996
7392
  }
6997
7393
 
6998
7394
  // src/components/games/CareerPathGame.tsx
6999
- import { Fragment as Fragment14, jsx as jsx77, jsxs as jsxs66 } from "react/jsx-runtime";
7395
+ import { Fragment as Fragment14, jsx as jsx78, jsxs as jsxs67 } from "react/jsx-runtime";
7000
7396
  function parseClientState3(json) {
7001
7397
  if (!json) return null;
7002
7398
  try {
@@ -7020,15 +7416,15 @@ function CareerPathGame({
7020
7416
  }) {
7021
7417
  const s = ui.games.careerPath;
7022
7418
  const title = gameTitle({ gameId: "career-path" }, ui.games.titles);
7023
- const [query, setQuery] = useState32("");
7024
- const inputId = useId3();
7419
+ const [query, setQuery] = useState35("");
7420
+ const inputId = useId4();
7025
7421
  const clientState = parseClientState3(result?.clientStateJson);
7026
7422
  const alreadyGuessedIds = new Set(clientState?.guessResults.map((g) => g.playerId) ?? []);
7027
7423
  const isOver = result?.alreadyPlayed === true || clientState?.solved === true || clientState?.failed === true;
7028
7424
  if (!config) {
7029
- return /* @__PURE__ */ jsxs66("div", { className: "ss-g-screen", "data-game": "career-path", "data-testid": "game-screen-career-path", children: [
7030
- /* @__PURE__ */ jsx77(GameHeader, { title, eyebrow: s.eyebrow, onBack, backLabel: ui.back }),
7031
- /* @__PURE__ */ jsx77("div", { className: "ss-g-body ss-g-loading", children: ui.games.loading })
7425
+ return /* @__PURE__ */ jsxs67("div", { className: "ss-g-screen", "data-game": "career-path", "data-testid": "game-screen-career-path", children: [
7426
+ /* @__PURE__ */ jsx78(GameHeader, { title, eyebrow: s.eyebrow, onBack, backLabel: ui.back }),
7427
+ /* @__PURE__ */ jsx78("div", { className: "ss-g-body ss-g-loading", children: ui.games.loading })
7032
7428
  ] });
7033
7429
  }
7034
7430
  const visiblePath = clientState?.visiblePath ?? config.initialPath;
@@ -7042,61 +7438,61 @@ function CareerPathGame({
7042
7438
  setQuery("");
7043
7439
  onSubmit(JSON.stringify({ guesses: newGuesses }));
7044
7440
  }
7045
- const right = !isOver && clientState ? /* @__PURE__ */ jsx77("span", { "data-testid": "cp-guess-chip", children: /* @__PURE__ */ jsxs66(Chip, { variant: "neutral", children: [
7441
+ const right = !isOver && clientState ? /* @__PURE__ */ jsx78("span", { "data-testid": "cp-guess-chip", children: /* @__PURE__ */ jsxs67(Chip, { variant: "neutral", children: [
7046
7442
  ui.games.guess,
7047
7443
  " ",
7048
- /* @__PURE__ */ jsx77("span", { className: "ss-g-num", children: clientState.guessesUsed + 1 }),
7444
+ /* @__PURE__ */ jsx78("span", { className: "ss-g-num", children: clientState.guessesUsed + 1 }),
7049
7445
  " / ",
7050
7446
  clientState.guessesUsed + clientState.guessesRemaining
7051
7447
  ] }) }) : void 0;
7052
7448
  const outcome = clientState?.solved ? s.solved : clientState?.failed ? s.failed : ui.games.done;
7053
- return /* @__PURE__ */ jsxs66("div", { className: "ss-g-screen", "data-game": "career-path", "data-testid": "game-screen-career-path", children: [
7054
- /* @__PURE__ */ jsx77(GameHeader, { title, eyebrow: s.eyebrow, right, onBack, backLabel: ui.back }),
7055
- /* @__PURE__ */ jsxs66("div", { className: "ss-g-body", children: [
7056
- !isOver && /* @__PURE__ */ jsx77(PointsLadderRow, { ladder: config.pointsLadder, guessesUsed: clientState?.guessesUsed ?? 0, ui }),
7057
- /* @__PURE__ */ jsxs66("div", { className: "ss-g-cp-card", children: [
7058
- isOver && clientState?.revealedPlayerName ? /* @__PURE__ */ jsx77(PlayerAvatar, { className: "ss-g-cp-photo", name: clientState.revealedPlayerName, imagePath: clientState.revealedPlayerImagePath }) : /* @__PURE__ */ jsx77(Silhouette, { size: 64, variant: isOver ? "default" : "mystery" }),
7059
- /* @__PURE__ */ jsxs66("div", { className: "ss-g-cp-card-text", children: [
7060
- /* @__PURE__ */ jsx77("span", { className: "ss-g-cp-card-title", children: isOver && clientState?.revealedPlayerName ? clientState.revealedPlayerName : s.mysteryPlayer }),
7061
- clientState?.hintLine ? /* @__PURE__ */ jsx77("span", { className: "ss-g-cp-hint", children: clientState.hintLine }) : !isOver ? /* @__PURE__ */ jsxs66("span", { className: "ss-g-cp-locks", children: [
7062
- /* @__PURE__ */ jsx77(Chip, { variant: "lock", icon: /* @__PURE__ */ jsx77(IconLock, { size: 11 }), children: s.lockPosition }),
7063
- /* @__PURE__ */ jsx77(Chip, { variant: "lock", icon: /* @__PURE__ */ jsx77(IconLock, { size: 11 }), children: s.lockNationality })
7449
+ return /* @__PURE__ */ jsxs67("div", { className: "ss-g-screen", "data-game": "career-path", "data-testid": "game-screen-career-path", children: [
7450
+ /* @__PURE__ */ jsx78(GameHeader, { title, eyebrow: s.eyebrow, right, onBack, backLabel: ui.back }),
7451
+ /* @__PURE__ */ jsxs67("div", { className: "ss-g-body", children: [
7452
+ !isOver && /* @__PURE__ */ jsx78(PointsLadderRow, { ladder: config.pointsLadder, guessesUsed: clientState?.guessesUsed ?? 0, ui }),
7453
+ /* @__PURE__ */ jsxs67("div", { className: "ss-g-cp-card", children: [
7454
+ isOver && clientState?.revealedPlayerName ? /* @__PURE__ */ jsx78(PlayerAvatar, { className: "ss-g-cp-photo", name: clientState.revealedPlayerName, imagePath: clientState.revealedPlayerImagePath }) : /* @__PURE__ */ jsx78(Silhouette, { size: 64, variant: isOver ? "default" : "mystery" }),
7455
+ /* @__PURE__ */ jsxs67("div", { className: "ss-g-cp-card-text", children: [
7456
+ /* @__PURE__ */ jsx78("span", { className: "ss-g-cp-card-title", children: isOver && clientState?.revealedPlayerName ? clientState.revealedPlayerName : s.mysteryPlayer }),
7457
+ clientState?.hintLine ? /* @__PURE__ */ jsx78("span", { className: "ss-g-cp-hint", children: clientState.hintLine }) : !isOver ? /* @__PURE__ */ jsxs67("span", { className: "ss-g-cp-locks", children: [
7458
+ /* @__PURE__ */ jsx78(Chip, { variant: "lock", icon: /* @__PURE__ */ jsx78(IconLock, { size: 11 }), children: s.lockPosition }),
7459
+ /* @__PURE__ */ jsx78(Chip, { variant: "lock", icon: /* @__PURE__ */ jsx78(IconLock, { size: 11 }), children: s.lockNationality })
7064
7460
  ] }) : null
7065
7461
  ] })
7066
7462
  ] }),
7067
- /* @__PURE__ */ jsxs66("ol", { className: "ss-g-cp-line", children: [
7463
+ /* @__PURE__ */ jsxs67("ol", { className: "ss-g-cp-line", children: [
7068
7464
  visiblePath.map((spell, i) => {
7069
7465
  const years = i === 0 ? s.firstClub : spellYears(spell);
7070
- return /* @__PURE__ */ jsxs66("li", { className: "ss-g-cp-step", children: [
7071
- /* @__PURE__ */ jsxs66("span", { className: "ss-g-cp-rail", children: [
7072
- /* @__PURE__ */ jsx77("span", { className: "ss-g-cp-tile", children: /* @__PURE__ */ jsx77(CrestShield, { src: spell.crestUrl, name: spell.clubName, size: 30 }) }),
7073
- /* @__PURE__ */ jsx77("span", { className: "ss-g-cp-conn", "aria-hidden": "true" })
7466
+ return /* @__PURE__ */ jsxs67("li", { className: "ss-g-cp-step", children: [
7467
+ /* @__PURE__ */ jsxs67("span", { className: "ss-g-cp-rail", children: [
7468
+ /* @__PURE__ */ jsx78("span", { className: "ss-g-cp-tile", children: /* @__PURE__ */ jsx78(CrestShield, { src: spell.crestUrl, name: spell.clubName, size: 30 }) }),
7469
+ /* @__PURE__ */ jsx78("span", { className: "ss-g-cp-conn", "aria-hidden": "true" })
7074
7470
  ] }),
7075
- /* @__PURE__ */ jsxs66("span", { className: "ss-g-cp-step-text", children: [
7076
- /* @__PURE__ */ jsx77("span", { className: "ss-g-cp-club", children: spell.clubName }),
7077
- /* @__PURE__ */ jsxs66("span", { className: "ss-g-cp-sub", children: [
7078
- /* @__PURE__ */ jsx77("span", { className: "ss-g-cp-years", children: years }),
7079
- spell.isLoan && /* @__PURE__ */ jsxs66(Fragment14, { children: [
7471
+ /* @__PURE__ */ jsxs67("span", { className: "ss-g-cp-step-text", children: [
7472
+ /* @__PURE__ */ jsx78("span", { className: "ss-g-cp-club", children: spell.clubName }),
7473
+ /* @__PURE__ */ jsxs67("span", { className: "ss-g-cp-sub", children: [
7474
+ /* @__PURE__ */ jsx78("span", { className: "ss-g-cp-years", children: years }),
7475
+ spell.isLoan && /* @__PURE__ */ jsxs67(Fragment14, { children: [
7080
7476
  years ? " \xB7 " : "",
7081
- /* @__PURE__ */ jsx77("span", { className: "ss-g-cp-loan", children: s.loan })
7477
+ /* @__PURE__ */ jsx78("span", { className: "ss-g-cp-loan", children: s.loan })
7082
7478
  ] })
7083
7479
  ] })
7084
7480
  ] })
7085
7481
  ] }, `${spell.clubName}-${i}`);
7086
7482
  }),
7087
- hidden > 0 && /* @__PURE__ */ jsxs66("li", { className: "ss-g-cp-step ss-g-cp-step--hidden", children: [
7088
- /* @__PURE__ */ jsxs66("span", { className: "ss-g-cp-rail", children: [
7089
- /* @__PURE__ */ jsx77("span", { className: "ss-g-cp-tile ss-g-cp-tile--locked", children: /* @__PURE__ */ jsx77(IconLock, { size: 18 }) }),
7090
- hidden > 1 && /* @__PURE__ */ jsx77("span", { className: "ss-g-cp-conn ss-g-cp-conn--faint", "aria-hidden": "true" })
7483
+ hidden > 0 && /* @__PURE__ */ jsxs67("li", { className: "ss-g-cp-step ss-g-cp-step--hidden", children: [
7484
+ /* @__PURE__ */ jsxs67("span", { className: "ss-g-cp-rail", children: [
7485
+ /* @__PURE__ */ jsx78("span", { className: "ss-g-cp-tile ss-g-cp-tile--locked", children: /* @__PURE__ */ jsx78(IconLock, { size: 18 }) }),
7486
+ hidden > 1 && /* @__PURE__ */ jsx78("span", { className: "ss-g-cp-conn ss-g-cp-conn--faint", "aria-hidden": "true" })
7091
7487
  ] }),
7092
- /* @__PURE__ */ jsx77("span", { className: "ss-g-cp-step-text", children: /* @__PURE__ */ jsx77("span", { className: "ss-g-cp-sub", children: s.nextClubHidden }) })
7488
+ /* @__PURE__ */ jsx78("span", { className: "ss-g-cp-step-text", children: /* @__PURE__ */ jsx78("span", { className: "ss-g-cp-sub", children: s.nextClubHidden }) })
7093
7489
  ] }),
7094
- hidden > 1 && /* @__PURE__ */ jsxs66("li", { className: "ss-g-cp-step ss-g-cp-step--more", children: [
7095
- /* @__PURE__ */ jsx77("span", { className: "ss-g-cp-rail", children: /* @__PURE__ */ jsx77("span", { className: "ss-g-cp-tile ss-g-cp-tile--faint", children: /* @__PURE__ */ jsx77(IconLock, { size: 18 }) }) }),
7096
- /* @__PURE__ */ jsx77("span", { className: "ss-g-cp-step-text", children: /* @__PURE__ */ jsx77("span", { className: "ss-g-cp-sub", children: s.moreClubs(hidden - 1) }) })
7490
+ hidden > 1 && /* @__PURE__ */ jsxs67("li", { className: "ss-g-cp-step ss-g-cp-step--more", children: [
7491
+ /* @__PURE__ */ jsx78("span", { className: "ss-g-cp-rail", children: /* @__PURE__ */ jsx78("span", { className: "ss-g-cp-tile ss-g-cp-tile--faint", children: /* @__PURE__ */ jsx78(IconLock, { size: 18 }) }) }),
7492
+ /* @__PURE__ */ jsx78("span", { className: "ss-g-cp-step-text", children: /* @__PURE__ */ jsx78("span", { className: "ss-g-cp-sub", children: s.moreClubs(hidden - 1) }) })
7097
7493
  ] })
7098
7494
  ] }),
7099
- isOver && /* @__PURE__ */ jsx77(
7495
+ isOver && /* @__PURE__ */ jsx78(
7100
7496
  ResultCard,
7101
7497
  {
7102
7498
  tone: clientState?.solved ? "win" : clientState?.failed ? "lose" : "neutral",
@@ -7108,7 +7504,7 @@ function CareerPathGame({
7108
7504
  }
7109
7505
  )
7110
7506
  ] }),
7111
- !isOver && /* @__PURE__ */ jsx77(FooterBar, { children: /* @__PURE__ */ jsx77(
7507
+ !isOver && /* @__PURE__ */ jsx78(FooterBar, { children: /* @__PURE__ */ jsx78(
7112
7508
  AnswerTray,
7113
7509
  {
7114
7510
  id: inputId,
@@ -7127,16 +7523,16 @@ function CareerPathGame({
7127
7523
  }
7128
7524
 
7129
7525
  // src/components/games/BeatTheGridGame.tsx
7130
- import React, { useEffect as useEffect21, useId as useId4, useRef as useRef18, useState as useState33 } from "react";
7526
+ import React, { useEffect as useEffect23, useId as useId5, useRef as useRef19, useState as useState36 } from "react";
7131
7527
 
7132
7528
  // src/components/games/ui/OptionList.tsx
7133
- import { jsx as jsx78 } from "react/jsx-runtime";
7529
+ import { jsx as jsx79 } from "react/jsx-runtime";
7134
7530
  function OptionList({ label, options, onPick }) {
7135
- return /* @__PURE__ */ jsx78("div", { className: "ss-g-opts", role: "listbox", "aria-label": label, children: options.map((o) => /* @__PURE__ */ jsx78("button", { type: "button", role: "option", "aria-selected": false, className: "ss-g-opt", onClick: () => onPick(o.key), children: o.content }, o.key)) });
7531
+ return /* @__PURE__ */ jsx79("div", { className: "ss-g-opts", role: "listbox", "aria-label": label, children: options.map((o) => /* @__PURE__ */ jsx79("button", { type: "button", role: "option", "aria-selected": false, className: "ss-g-opt", onClick: () => onPick(o.key), children: o.content }, o.key)) });
7136
7532
  }
7137
7533
 
7138
7534
  // src/components/games/BeatTheGridGame.tsx
7139
- import { Fragment as Fragment15, jsx as jsx79, jsxs as jsxs67 } from "react/jsx-runtime";
7535
+ import { Fragment as Fragment15, jsx as jsx80, jsxs as jsxs68 } from "react/jsx-runtime";
7140
7536
  function criterionIconKind(label, key) {
7141
7537
  const l = (key ?? label).toLowerCase();
7142
7538
  if (l.includes("app")) return "calendar";
@@ -7154,34 +7550,34 @@ function rowAbbrev(label, map, key) {
7154
7550
  function CriterionIcon({ kind }) {
7155
7551
  switch (kind) {
7156
7552
  case "calendar":
7157
- return /* @__PURE__ */ jsx79(IconCalendar, {});
7553
+ return /* @__PURE__ */ jsx80(IconCalendar, {});
7158
7554
  case "ball":
7159
- return /* @__PURE__ */ jsx79(IconBall, {});
7555
+ return /* @__PURE__ */ jsx80(IconBall, {});
7160
7556
  case "boot":
7161
- return /* @__PURE__ */ jsx79(IconBoot, {});
7557
+ return /* @__PURE__ */ jsx80(IconBoot, {});
7162
7558
  case "gloves":
7163
- return /* @__PURE__ */ jsx79(IconGloves, {});
7559
+ return /* @__PURE__ */ jsx80(IconGloves, {});
7164
7560
  case "shield":
7165
- return /* @__PURE__ */ jsx79(IconShield, {});
7561
+ return /* @__PURE__ */ jsx80(IconShield, {});
7166
7562
  default:
7167
- return /* @__PURE__ */ jsx79(IconFlag, {});
7563
+ return /* @__PURE__ */ jsx80(IconFlag, {});
7168
7564
  }
7169
7565
  }
7170
7566
  function HeaderVisual({ label, textKey: iKey, meta }) {
7171
7567
  if (!meta) {
7172
- return /* @__PURE__ */ jsx79(CriterionIcon, { kind: criterionIconKind(label, iKey) });
7568
+ return /* @__PURE__ */ jsx80(CriterionIcon, { kind: criterionIconKind(label, iKey) });
7173
7569
  }
7174
7570
  switch (meta.kind) {
7175
7571
  case "club":
7176
- return /* @__PURE__ */ jsx79(CrestShield, { src: meta.imageUrl, name: label, size: 24 });
7572
+ return /* @__PURE__ */ jsx80(CrestShield, { src: meta.imageUrl, name: label, size: 24 });
7177
7573
  case "coach":
7178
- return /* @__PURE__ */ jsx79(PlayerAvatar, { name: label, imagePath: meta.imageUrl, className: "ss-g-btg-coach-av" });
7574
+ return /* @__PURE__ */ jsx80(PlayerAvatar, { name: label, imagePath: meta.imageUrl, className: "ss-g-btg-coach-av" });
7179
7575
  case "country":
7180
- return /* @__PURE__ */ jsx79("span", { className: "ss-g-btg-hdr-flag", "aria-hidden": "true", children: nationalityFlag(meta.country ?? label) });
7576
+ return /* @__PURE__ */ jsx80("span", { className: "ss-g-btg-hdr-flag", "aria-hidden": "true", children: nationalityFlag(meta.country ?? label) });
7181
7577
  case "position":
7182
- return /* @__PURE__ */ jsx79(Fragment15, {});
7578
+ return /* @__PURE__ */ jsx80(Fragment15, {});
7183
7579
  default:
7184
- return /* @__PURE__ */ jsx79(CriterionIcon, { kind: criterionIconKind(label, iKey) });
7580
+ return /* @__PURE__ */ jsx80(CriterionIcon, { kind: criterionIconKind(label, iKey) });
7185
7581
  }
7186
7582
  }
7187
7583
  function parseClientState4(json) {
@@ -7216,21 +7612,21 @@ function SearchSheet({
7216
7612
  ui
7217
7613
  }) {
7218
7614
  const s = ui.games.beatTheGrid;
7219
- const [query, setQuery] = useState33("");
7220
- const inputId = useId4();
7221
- const inputRef = useRef18(null);
7222
- useEffect21(() => {
7615
+ const [query, setQuery] = useState36("");
7616
+ const inputId = useId5();
7617
+ const inputRef = useRef19(null);
7618
+ useEffect23(() => {
7223
7619
  inputRef.current?.focus();
7224
7620
  }, [row, col]);
7225
7621
  const filtered = playerPool.filter(
7226
7622
  (p) => !alreadyFilledIds.has(p.id) && p.name.toLowerCase().includes(query.toLowerCase())
7227
7623
  );
7228
- return /* @__PURE__ */ jsxs67("div", { className: "ss-g-btg-sheet", "data-testid": "btg-search-sheet", children: [
7229
- /* @__PURE__ */ jsxs67("div", { className: "ss-g-btg-sheet-hdr", children: [
7230
- /* @__PURE__ */ jsx79(Chip, { variant: "neutral", children: rowLabel }),
7231
- /* @__PURE__ */ jsx79("span", { className: "ss-g-btg-sheet-x", "aria-hidden": "true", children: /* @__PURE__ */ jsx79(IconClose, { size: 12 }) }),
7232
- /* @__PURE__ */ jsx79(Chip, { variant: "accent", children: colLabel }),
7233
- /* @__PURE__ */ jsx79(
7624
+ return /* @__PURE__ */ jsxs68("div", { className: "ss-g-btg-sheet", "data-testid": "btg-search-sheet", children: [
7625
+ /* @__PURE__ */ jsxs68("div", { className: "ss-g-btg-sheet-hdr", children: [
7626
+ /* @__PURE__ */ jsx80(Chip, { variant: "neutral", children: rowLabel }),
7627
+ /* @__PURE__ */ jsx80("span", { className: "ss-g-btg-sheet-x", "aria-hidden": "true", children: /* @__PURE__ */ jsx80(IconClose, { size: 12 }) }),
7628
+ /* @__PURE__ */ jsx80(Chip, { variant: "accent", children: colLabel }),
7629
+ /* @__PURE__ */ jsx80(
7234
7630
  "button",
7235
7631
  {
7236
7632
  type: "button",
@@ -7238,12 +7634,12 @@ function SearchSheet({
7238
7634
  "data-testid": "btg-sheet-dismiss",
7239
7635
  "aria-label": s.closeSearch,
7240
7636
  onClick: onDismiss,
7241
- children: /* @__PURE__ */ jsx79(IconClose, {})
7637
+ children: /* @__PURE__ */ jsx80(IconClose, {})
7242
7638
  }
7243
7639
  )
7244
7640
  ] }),
7245
- playerPool.length === 0 ? /* @__PURE__ */ jsx79("div", { className: "ss-g-btg-sheet-empty", children: s.emptyPool }) : /* @__PURE__ */ jsxs67(Fragment15, { children: [
7246
- /* @__PURE__ */ jsx79(
7641
+ playerPool.length === 0 ? /* @__PURE__ */ jsx80("div", { className: "ss-g-btg-sheet-empty", children: s.emptyPool }) : /* @__PURE__ */ jsxs68(Fragment15, { children: [
7642
+ /* @__PURE__ */ jsx80(
7247
7643
  SearchField,
7248
7644
  {
7249
7645
  id: inputId,
@@ -7255,16 +7651,16 @@ function SearchSheet({
7255
7651
  inputRef
7256
7652
  }
7257
7653
  ),
7258
- query.length > 0 && filtered.length > 0 && /* @__PURE__ */ jsx79(
7654
+ query.length > 0 && filtered.length > 0 && /* @__PURE__ */ jsx80(
7259
7655
  OptionList,
7260
7656
  {
7261
7657
  label: s.searchLabel(rowLabel, colLabel),
7262
7658
  options: filtered.map((p) => ({
7263
7659
  key: p.id,
7264
- content: /* @__PURE__ */ jsxs67(Fragment15, { children: [
7265
- /* @__PURE__ */ jsx79(PlayerAvatar, { name: p.name, imagePath: p.imagePath, className: "ss-g-opt-av" }),
7266
- /* @__PURE__ */ jsx79("span", { className: "ss-g-btg-result-name", children: p.name }),
7267
- /* @__PURE__ */ jsx79("span", { className: "ss-g-btg-result-plus", "aria-hidden": "true", children: /* @__PURE__ */ jsx79(IconPlus, { size: 18 }) })
7660
+ content: /* @__PURE__ */ jsxs68(Fragment15, { children: [
7661
+ /* @__PURE__ */ jsx80(PlayerAvatar, { name: p.name, imagePath: p.imagePath, className: "ss-g-opt-av" }),
7662
+ /* @__PURE__ */ jsx80("span", { className: "ss-g-btg-result-name", children: p.name }),
7663
+ /* @__PURE__ */ jsx80("span", { className: "ss-g-btg-result-plus", "aria-hidden": "true", children: /* @__PURE__ */ jsx80(IconPlus, { size: 18 }) })
7268
7664
  ] })
7269
7665
  })),
7270
7666
  onPick: (k) => onPick(row, col, Number(k))
@@ -7284,7 +7680,7 @@ function BeatTheGridGame({
7284
7680
  }) {
7285
7681
  const s = ui.games.beatTheGrid;
7286
7682
  const title = gameTitle({ gameId: "beat-the-grid" }, ui.games.titles);
7287
- const [activeCell, setActiveCell] = useState33(null);
7683
+ const [activeCell, setActiveCell] = useState36(null);
7288
7684
  const clientState = parseClientState4(result?.clientStateJson);
7289
7685
  const filledCells = clientState?.cells ?? [];
7290
7686
  const isLocked2 = result?.alreadyPlayed === true || clientState?.isComplete === true;
@@ -7302,9 +7698,9 @@ function BeatTheGridGame({
7302
7698
  onSubmit(JSON.stringify({ cells: newCells }));
7303
7699
  }
7304
7700
  if (!config) {
7305
- return /* @__PURE__ */ jsxs67("div", { className: "ss-g-screen", "data-game": "beat-the-grid", "data-testid": "game-screen-beat-the-grid", children: [
7306
- /* @__PURE__ */ jsx79(GameHeader, { title, eyebrow: s.eyebrow, onBack, backLabel: ui.back }),
7307
- /* @__PURE__ */ jsx79("div", { className: "ss-g-body ss-g-loading", children: ui.games.loading })
7701
+ return /* @__PURE__ */ jsxs68("div", { className: "ss-g-screen", "data-game": "beat-the-grid", "data-testid": "game-screen-beat-the-grid", children: [
7702
+ /* @__PURE__ */ jsx80(GameHeader, { title, eyebrow: s.eyebrow, onBack, backLabel: ui.back }),
7703
+ /* @__PURE__ */ jsx80("div", { className: "ss-g-body ss-g-loading", children: ui.games.loading })
7308
7704
  ] });
7309
7705
  }
7310
7706
  const rows = config.rows;
@@ -7317,20 +7713,20 @@ function BeatTheGridGame({
7317
7713
  (_, i) => i < correctCount ? "correct" : i < correctCount + wrongCount ? "wrong" : "todo"
7318
7714
  );
7319
7715
  const totalScore = clientState?.totalScore ?? result?.score ?? 0;
7320
- return /* @__PURE__ */ jsxs67("div", { className: "ss-g-screen", "data-game": "beat-the-grid", "data-testid": "game-screen-beat-the-grid", children: [
7321
- /* @__PURE__ */ jsx79(GameHeader, { title, eyebrow: s.eyebrow, onBack, backLabel: ui.back }),
7322
- /* @__PURE__ */ jsx79(
7716
+ return /* @__PURE__ */ jsxs68("div", { className: "ss-g-screen", "data-game": "beat-the-grid", "data-testid": "game-screen-beat-the-grid", children: [
7717
+ /* @__PURE__ */ jsx80(GameHeader, { title, eyebrow: s.eyebrow, onBack, backLabel: ui.back }),
7718
+ /* @__PURE__ */ jsx80(
7323
7719
  SegmentProgress,
7324
7720
  {
7325
7721
  segments,
7326
7722
  ariaLabel: s.progressAria(filledCells.length, total),
7327
7723
  leftLabel: s.filled(filledCells.length, total),
7328
7724
  rightLabel: s.toGo(Math.max(0, total - filledCells.length)),
7329
- right: /* @__PURE__ */ jsx79(Chip, { variant: "accent", children: `${totalScore} ${ui.games.unitPts}` })
7725
+ right: /* @__PURE__ */ jsx80(Chip, { variant: "accent", children: `${totalScore} ${ui.games.unitPts}` })
7330
7726
  }
7331
7727
  ),
7332
- /* @__PURE__ */ jsxs67("div", { className: "ss-g-body", children: [
7333
- /* @__PURE__ */ jsxs67(
7728
+ /* @__PURE__ */ jsxs68("div", { className: "ss-g-body", children: [
7729
+ /* @__PURE__ */ jsxs68(
7334
7730
  "div",
7335
7731
  {
7336
7732
  className: activeCell !== null ? "ss-g-btg-grid ss-g-btg-grid--fit" : "ss-g-btg-grid",
@@ -7340,31 +7736,31 @@ function BeatTheGridGame({
7340
7736
  },
7341
7737
  role: "grid",
7342
7738
  children: [
7343
- /* @__PURE__ */ jsx79("div", { className: "ss-g-btg-corner" }),
7739
+ /* @__PURE__ */ jsx80("div", { className: "ss-g-btg-corner" }),
7344
7740
  cols.map((col, colIdx) => {
7345
7741
  const colMeta = config.colsMeta?.[colIdx];
7346
- return /* @__PURE__ */ jsxs67("div", { className: "ss-g-btg-colhdr", "data-meta": colMeta ? "true" : void 0, children: [
7347
- /* @__PURE__ */ jsx79(HeaderVisual, { label: col, textKey: config.colsI18n?.[colIdx]?.key, meta: colMeta }),
7348
- /* @__PURE__ */ jsx79("span", { children: col })
7742
+ return /* @__PURE__ */ jsxs68("div", { className: "ss-g-btg-colhdr", "data-meta": colMeta ? "true" : void 0, children: [
7743
+ /* @__PURE__ */ jsx80(HeaderVisual, { label: col, textKey: config.colsI18n?.[colIdx]?.key, meta: colMeta }),
7744
+ /* @__PURE__ */ jsx80("span", { children: col })
7349
7745
  ] }, col);
7350
7746
  }),
7351
7747
  rows.map((rowLabel, rowIdx) => {
7352
7748
  const rowMeta = config.rowsMeta?.[rowIdx];
7353
7749
  const abbr = rowAbbrev(rowLabel, s.rowAbbrev, config.rowsI18n?.[rowIdx]?.key);
7354
- const rowHeaderContent = rowMeta ? /* @__PURE__ */ jsxs67(Fragment15, { children: [
7355
- /* @__PURE__ */ jsx79(HeaderVisual, { label: rowLabel, textKey: config.rowsI18n?.[rowIdx]?.key, meta: rowMeta }),
7356
- /* @__PURE__ */ jsx79("span", { children: rowLabel })
7357
- ] }) : abbr === rowLabel ? /* @__PURE__ */ jsx79("span", { children: rowLabel }) : /* @__PURE__ */ jsxs67(Fragment15, { children: [
7358
- /* @__PURE__ */ jsx79("span", { "aria-hidden": "true", children: abbr }),
7359
- /* @__PURE__ */ jsx79("span", { className: "ss-g-sr", children: rowLabel })
7750
+ const rowHeaderContent = rowMeta ? /* @__PURE__ */ jsxs68(Fragment15, { children: [
7751
+ /* @__PURE__ */ jsx80(HeaderVisual, { label: rowLabel, textKey: config.rowsI18n?.[rowIdx]?.key, meta: rowMeta }),
7752
+ /* @__PURE__ */ jsx80("span", { children: rowLabel })
7753
+ ] }) : abbr === rowLabel ? /* @__PURE__ */ jsx80("span", { children: rowLabel }) : /* @__PURE__ */ jsxs68(Fragment15, { children: [
7754
+ /* @__PURE__ */ jsx80("span", { "aria-hidden": "true", children: abbr }),
7755
+ /* @__PURE__ */ jsx80("span", { className: "ss-g-sr", children: rowLabel })
7360
7756
  ] });
7361
- return /* @__PURE__ */ jsxs67(React.Fragment, { children: [
7362
- /* @__PURE__ */ jsx79("div", { className: "ss-g-btg-rowhdr", "data-meta": rowMeta ? "true" : void 0, children: rowHeaderContent }),
7757
+ return /* @__PURE__ */ jsxs68(React.Fragment, { children: [
7758
+ /* @__PURE__ */ jsx80("div", { className: "ss-g-btg-rowhdr", "data-meta": rowMeta ? "true" : void 0, children: rowHeaderContent }),
7363
7759
  cols.map((colLabel, colIdx) => {
7364
7760
  const filled = findCellResult(filledCells, rowIdx, colIdx);
7365
7761
  const isActive = activeCell?.row === rowIdx && activeCell?.col === colIdx;
7366
7762
  const state = filled ? filled.isCorrect ? "correct" : "wrong" : isActive ? "active" : "empty";
7367
- return /* @__PURE__ */ jsx79(
7763
+ return /* @__PURE__ */ jsx80(
7368
7764
  "button",
7369
7765
  {
7370
7766
  type: "button",
@@ -7375,20 +7771,20 @@ function BeatTheGridGame({
7375
7771
  className: "ss-g-btg-cell",
7376
7772
  disabled: isLocked2 || submitting,
7377
7773
  onClick: () => handleCellClick(rowIdx, colIdx),
7378
- children: filled ? /* @__PURE__ */ jsxs67(Fragment15, { children: [
7379
- /* @__PURE__ */ jsx79(
7774
+ children: filled ? /* @__PURE__ */ jsxs68(Fragment15, { children: [
7775
+ /* @__PURE__ */ jsx80(
7380
7776
  "span",
7381
7777
  {
7382
7778
  className: `ss-g-btg-badge ss-g-btg-badge--${filled.isCorrect ? "correct" : "wrong"}`,
7383
7779
  role: "img",
7384
7780
  "aria-label": filled.isCorrect ? s.correct : s.wrong,
7385
- children: filled.isCorrect ? /* @__PURE__ */ jsx79(IconCheck, { size: 11 }) : /* @__PURE__ */ jsx79(IconClose, { size: 11 })
7781
+ children: filled.isCorrect ? /* @__PURE__ */ jsx80(IconCheck, { size: 11 }) : /* @__PURE__ */ jsx80(IconClose, { size: 11 })
7386
7782
  }
7387
7783
  ),
7388
- /* @__PURE__ */ jsx79("span", { className: "ss-g-btg-rarity", children: filled.rarityScore }),
7784
+ /* @__PURE__ */ jsx80("span", { className: "ss-g-btg-rarity", children: filled.rarityScore }),
7389
7785
  (() => {
7390
7786
  const entry = playerPool.find((p) => p.id === filled.playerId);
7391
- return /* @__PURE__ */ jsx79(
7787
+ return /* @__PURE__ */ jsx80(
7392
7788
  PlayerAvatar,
7393
7789
  {
7394
7790
  name: entry?.name ?? "",
@@ -7397,8 +7793,8 @@ function BeatTheGridGame({
7397
7793
  }
7398
7794
  );
7399
7795
  })(),
7400
- /* @__PURE__ */ jsx79("span", { className: "ss-g-btg-name", children: shortName(playerPool.find((p) => p.id === filled.playerId)?.name) })
7401
- ] }) : /* @__PURE__ */ jsx79("span", { className: "ss-g-btg-plus", "aria-hidden": "true", children: /* @__PURE__ */ jsx79(IconPlus, { size: 22 }) })
7796
+ /* @__PURE__ */ jsx80("span", { className: "ss-g-btg-name", children: shortName(playerPool.find((p) => p.id === filled.playerId)?.name) })
7797
+ ] }) : /* @__PURE__ */ jsx80("span", { className: "ss-g-btg-plus", "aria-hidden": "true", children: /* @__PURE__ */ jsx80(IconPlus, { size: 22 }) })
7402
7798
  },
7403
7799
  `cell-${rowIdx}-${colIdx}`
7404
7800
  );
@@ -7408,7 +7804,7 @@ function BeatTheGridGame({
7408
7804
  ]
7409
7805
  }
7410
7806
  ),
7411
- isLocked2 && /* @__PURE__ */ jsx79(
7807
+ isLocked2 && /* @__PURE__ */ jsx80(
7412
7808
  ResultCard,
7413
7809
  {
7414
7810
  tone: "neutral",
@@ -7420,7 +7816,7 @@ function BeatTheGridGame({
7420
7816
  }
7421
7817
  )
7422
7818
  ] }),
7423
- activeCell !== null && /* @__PURE__ */ jsx79("div", { className: "ss-g-btg-pin", children: /* @__PURE__ */ jsx79(
7819
+ activeCell !== null && /* @__PURE__ */ jsx80("div", { className: "ss-g-btg-pin", children: /* @__PURE__ */ jsx80(
7424
7820
  SearchSheet,
7425
7821
  {
7426
7822
  row: activeCell.row,
@@ -7439,21 +7835,21 @@ function BeatTheGridGame({
7439
7835
  }
7440
7836
 
7441
7837
  // src/components/games/GuessTheXiGame.tsx
7442
- import { useState as useState34, useId as useId5 } from "react";
7838
+ import { useState as useState37, useId as useId6 } from "react";
7443
7839
 
7444
7840
  // src/components/games/ui/PitchSvg.tsx
7445
- import { Fragment as Fragment16, jsx as jsx80, jsxs as jsxs68 } from "react/jsx-runtime";
7841
+ import { Fragment as Fragment16, jsx as jsx81, jsxs as jsxs69 } from "react/jsx-runtime";
7446
7842
  function PitchSvg({ variant }) {
7447
- return /* @__PURE__ */ jsxs68("svg", { className: "ss-g-pitch-svg", viewBox: variant === "full" ? "0 0 100 150" : "0 0 100 100", preserveAspectRatio: "none", "aria-hidden": "true", children: [
7448
- /* @__PURE__ */ jsx80("rect", { x: "4", y: "4", width: "92", height: variant === "full" ? 142 : 92, fill: "none" }),
7449
- variant === "full" ? /* @__PURE__ */ jsxs68(Fragment16, { children: [
7450
- /* @__PURE__ */ jsx80("line", { x1: "4", y1: "75", x2: "96", y2: "75" }),
7451
- /* @__PURE__ */ jsx80("circle", { cx: "50", cy: "75", r: "12", fill: "none" }),
7452
- /* @__PURE__ */ jsx80("rect", { x: "26", y: "4", width: "48", height: "20", fill: "none" }),
7453
- /* @__PURE__ */ jsx80("rect", { x: "26", y: "126", width: "48", height: "20", fill: "none" })
7454
- ] }) : /* @__PURE__ */ jsxs68(Fragment16, { children: [
7455
- /* @__PURE__ */ jsx80("path", { d: "M38 4a12 12 0 0 0 24 0", fill: "none" }),
7456
- /* @__PURE__ */ jsx80("rect", { x: "26", y: "76", width: "48", height: "20", fill: "none" })
7843
+ return /* @__PURE__ */ jsxs69("svg", { className: "ss-g-pitch-svg", viewBox: variant === "full" ? "0 0 100 150" : "0 0 100 100", preserveAspectRatio: "none", "aria-hidden": "true", children: [
7844
+ /* @__PURE__ */ jsx81("rect", { x: "4", y: "4", width: "92", height: variant === "full" ? 142 : 92, fill: "none" }),
7845
+ variant === "full" ? /* @__PURE__ */ jsxs69(Fragment16, { children: [
7846
+ /* @__PURE__ */ jsx81("line", { x1: "4", y1: "75", x2: "96", y2: "75" }),
7847
+ /* @__PURE__ */ jsx81("circle", { cx: "50", cy: "75", r: "12", fill: "none" }),
7848
+ /* @__PURE__ */ jsx81("rect", { x: "26", y: "4", width: "48", height: "20", fill: "none" }),
7849
+ /* @__PURE__ */ jsx81("rect", { x: "26", y: "126", width: "48", height: "20", fill: "none" })
7850
+ ] }) : /* @__PURE__ */ jsxs69(Fragment16, { children: [
7851
+ /* @__PURE__ */ jsx81("path", { d: "M38 4a12 12 0 0 0 24 0", fill: "none" }),
7852
+ /* @__PURE__ */ jsx81("rect", { x: "26", y: "76", width: "48", height: "20", fill: "none" })
7457
7853
  ] })
7458
7854
  ] });
7459
7855
  }
@@ -7509,7 +7905,7 @@ function positionsBySlot(formation, rowsAttackFirst) {
7509
7905
  }
7510
7906
 
7511
7907
  // src/components/games/GuessTheXiGame.tsx
7512
- import { Fragment as Fragment17, jsx as jsx81, jsxs as jsxs69 } from "react/jsx-runtime";
7908
+ import { Fragment as Fragment17, jsx as jsx82, jsxs as jsxs70 } from "react/jsx-runtime";
7513
7909
  var MAX_GUESSES2 = 3;
7514
7910
  function parseClientState5(json) {
7515
7911
  if (!json) return null;
@@ -7528,8 +7924,8 @@ function GuessTheXiGame({
7528
7924
  onBack
7529
7925
  }) {
7530
7926
  const t = ui.games.guessTheXi;
7531
- const [query, setQuery] = useState34("");
7532
- const inputId = useId5();
7927
+ const [query, setQuery] = useState37("");
7928
+ const inputId = useId6();
7533
7929
  const clientState = parseClientState5(result?.clientStateJson);
7534
7930
  const isOver = result?.alreadyPlayed === true || clientState?.status === "solved" || clientState?.status === "failed";
7535
7931
  const solved = clientState?.status === "solved";
@@ -7559,31 +7955,31 @@ function GuessTheXiGame({
7559
7955
  const wrongGuesses = (clientState?.guessHistory ?? []).filter((g) => !g.wasCorrect);
7560
7956
  const guessesLeft = Math.max(0, MAX_GUESSES2 - (clientState?.guessesUsed ?? 0));
7561
7957
  const teamName = (id) => config?.teamPool.find((tm) => tm.teamId === id)?.teamName ?? `#${id}`;
7562
- return /* @__PURE__ */ jsxs69("div", { className: "ss-g-screen ss-g-gxi", "data-game": "guess-the-xi", "data-testid": "game-screen-guess-the-xi", children: [
7563
- /* @__PURE__ */ jsx81(
7958
+ return /* @__PURE__ */ jsxs70("div", { className: "ss-g-screen ss-g-gxi", "data-game": "guess-the-xi", "data-testid": "game-screen-guess-the-xi", children: [
7959
+ /* @__PURE__ */ jsx82(
7564
7960
  GameHeader,
7565
7961
  {
7566
7962
  title: gameTitle({ gameId: "guess-the-xi" }, ui.games.titles),
7567
7963
  eyebrow: config?.poolLabel,
7568
- right: formation ? /* @__PURE__ */ jsx81(Chip, { variant: "accent", children: formation }) : void 0,
7964
+ right: formation ? /* @__PURE__ */ jsx82(Chip, { variant: "accent", children: formation }) : void 0,
7569
7965
  onBack,
7570
7966
  backLabel: ui.back
7571
7967
  }
7572
7968
  ),
7573
- !config && /* @__PURE__ */ jsx81("div", { className: "ss-g-body ss-g-loading", children: ui.games.loading }),
7574
- config && /* @__PURE__ */ jsxs69(Fragment17, { children: [
7575
- /* @__PURE__ */ jsxs69("div", { className: "ss-g-body", children: [
7576
- !isOver && /* @__PURE__ */ jsx81(PointsLadderRow, { ladder: config.pointsLadder, guessesUsed: clientState?.guessHistory.length ?? 0, ui }),
7577
- rows.length > 0 && /* @__PURE__ */ jsxs69("div", { className: "ss-g-gxi-pitch", role: "group", "aria-label": t.pitchLabel, children: [
7578
- /* @__PURE__ */ jsx81(PitchSvg, { variant: "full" }),
7579
- /* @__PURE__ */ jsx81("div", { className: "ss-g-gxi-rows", children: rows.map((row, r) => /* @__PURE__ */ jsx81("div", { className: "ss-g-gxi-row", children: row.map((pos, c) => {
7969
+ !config && /* @__PURE__ */ jsx82("div", { className: "ss-g-body ss-g-loading", children: ui.games.loading }),
7970
+ config && /* @__PURE__ */ jsxs70(Fragment17, { children: [
7971
+ /* @__PURE__ */ jsxs70("div", { className: "ss-g-body", children: [
7972
+ !isOver && /* @__PURE__ */ jsx82(PointsLadderRow, { ladder: config.pointsLadder, guessesUsed: clientState?.guessHistory.length ?? 0, ui }),
7973
+ rows.length > 0 && /* @__PURE__ */ jsxs70("div", { className: "ss-g-gxi-pitch", role: "group", "aria-label": t.pitchLabel, children: [
7974
+ /* @__PURE__ */ jsx82(PitchSvg, { variant: "full" }),
7975
+ /* @__PURE__ */ jsx82("div", { className: "ss-g-gxi-rows", children: rows.map((row, r) => /* @__PURE__ */ jsx82("div", { className: "ss-g-gxi-row", children: row.map((pos, c) => {
7580
7976
  const posLabel = pos.slot ? posBySlot.get(pos.slot) ?? "" : "";
7581
7977
  const name = pos.slot ? nameBySlot.get(pos.slot) : void 0;
7582
7978
  const lineupEntry = pos.slot ? lineupBySlot.get(pos.slot) : void 0;
7583
7979
  const flag = nationalityFlag(pos.nationality);
7584
7980
  if (lineupEntry) {
7585
- return /* @__PURE__ */ jsxs69("div", { className: "ss-g-gxi-node", "data-revealed": "true", children: [
7586
- /* @__PURE__ */ jsx81(
7981
+ return /* @__PURE__ */ jsxs70("div", { className: "ss-g-gxi-node", "data-revealed": "true", children: [
7982
+ /* @__PURE__ */ jsx82(
7587
7983
  PlayerAvatar,
7588
7984
  {
7589
7985
  name: lineupEntry.name,
@@ -7591,11 +7987,11 @@ function GuessTheXiGame({
7591
7987
  className: "ss-g-gxi-disc ss-g-gxi-disc--photo"
7592
7988
  }
7593
7989
  ),
7594
- /* @__PURE__ */ jsx81("span", { className: "ss-g-gxi-pos ss-g-gxi-pos--name", children: splitName(lineupEntry.name).last })
7990
+ /* @__PURE__ */ jsx82("span", { className: "ss-g-gxi-pos ss-g-gxi-pos--name", children: splitName(lineupEntry.name).last })
7595
7991
  ] }, `${pos.slot}-${c}`);
7596
7992
  }
7597
- return /* @__PURE__ */ jsxs69("div", { className: "ss-g-gxi-node", "data-revealed": name ? "true" : void 0, children: [
7598
- /* @__PURE__ */ jsx81(
7993
+ return /* @__PURE__ */ jsxs70("div", { className: "ss-g-gxi-node", "data-revealed": name ? "true" : void 0, children: [
7994
+ /* @__PURE__ */ jsx82(
7599
7995
  "span",
7600
7996
  {
7601
7997
  className: "ss-g-gxi-disc",
@@ -7606,22 +8002,22 @@ function GuessTheXiGame({
7606
8002
  children: flag
7607
8003
  }
7608
8004
  ),
7609
- name ? /* @__PURE__ */ jsx81("span", { className: "ss-g-gxi-pos ss-g-gxi-pos--name", children: splitName(name).last }) : posLabel && /* @__PURE__ */ jsx81("span", { className: "ss-g-gxi-pos", children: posLabel })
8005
+ name ? /* @__PURE__ */ jsx82("span", { className: "ss-g-gxi-pos ss-g-gxi-pos--name", children: splitName(name).last }) : posLabel && /* @__PURE__ */ jsx82("span", { className: "ss-g-gxi-pos", children: posLabel })
7610
8006
  ] }, `${pos.slot}-${c}`);
7611
8007
  }) }, r)) })
7612
8008
  ] }),
7613
- !isOver && wrongGuesses.length > 0 && /* @__PURE__ */ jsxs69("div", { className: "ss-g-gxi-wrong", children: [
7614
- /* @__PURE__ */ jsx81("span", { className: "ss-g-gxi-wrong-l", children: t.notThem }),
8009
+ !isOver && wrongGuesses.length > 0 && /* @__PURE__ */ jsxs70("div", { className: "ss-g-gxi-wrong", children: [
8010
+ /* @__PURE__ */ jsx82("span", { className: "ss-g-gxi-wrong-l", children: t.notThem }),
7615
8011
  wrongGuesses.map((g) => {
7616
8012
  const crestUrl = config?.teamPool.find((tm) => tm.teamId === g.teamId)?.crestUrl;
7617
- return /* @__PURE__ */ jsxs69("span", { className: "ss-g-gxi-wrong-chip", children: [
7618
- /* @__PURE__ */ jsx81(CrestShield, { src: crestUrl, name: teamName(g.teamId), size: 18 }),
7619
- /* @__PURE__ */ jsx81("s", { children: teamName(g.teamId) })
8013
+ return /* @__PURE__ */ jsxs70("span", { className: "ss-g-gxi-wrong-chip", children: [
8014
+ /* @__PURE__ */ jsx82(CrestShield, { src: crestUrl, name: teamName(g.teamId), size: 18 }),
8015
+ /* @__PURE__ */ jsx82("s", { children: teamName(g.teamId) })
7620
8016
  ] }, g.teamId);
7621
8017
  })
7622
8018
  ] }),
7623
- isOver && /* @__PURE__ */ jsxs69(Fragment17, { children: [
7624
- /* @__PURE__ */ jsx81(
8019
+ isOver && /* @__PURE__ */ jsxs70(Fragment17, { children: [
8020
+ /* @__PURE__ */ jsx82(
7625
8021
  ResultCard,
7626
8022
  {
7627
8023
  tone: solved ? "win" : failed ? "lose" : "neutral",
@@ -7632,29 +8028,29 @@ function GuessTheXiGame({
7632
8028
  ui
7633
8029
  }
7634
8030
  ),
7635
- (solved || failed) && clientState?.answer && /* @__PURE__ */ jsxs69("div", { className: "ss-g-gxi-answer", "data-testid": "gxi-answer-reveal", children: [
7636
- /* @__PURE__ */ jsx81("span", { className: "ss-g-gxi-answer-label", children: t.theAnswer }),
7637
- /* @__PURE__ */ jsx81(CrestShield, { src: clientState.answer.crestUrl, name: clientState.answer.teamName, size: 32 }),
7638
- /* @__PURE__ */ jsx81("span", { className: "ss-g-gxi-answer-name", children: clientState.answer.teamName })
8031
+ (solved || failed) && clientState?.answer && /* @__PURE__ */ jsxs70("div", { className: "ss-g-gxi-answer", "data-testid": "gxi-answer-reveal", children: [
8032
+ /* @__PURE__ */ jsx82("span", { className: "ss-g-gxi-answer-label", children: t.theAnswer }),
8033
+ /* @__PURE__ */ jsx82(CrestShield, { src: clientState.answer.crestUrl, name: clientState.answer.teamName, size: 32 }),
8034
+ /* @__PURE__ */ jsx82("span", { className: "ss-g-gxi-answer-name", children: clientState.answer.teamName })
7639
8035
  ] })
7640
8036
  ] })
7641
8037
  ] }),
7642
- !isOver && /* @__PURE__ */ jsxs69(FooterBar, { children: [
7643
- query.length > 0 && filtered.length > 0 && /* @__PURE__ */ jsx81(
8038
+ !isOver && /* @__PURE__ */ jsxs70(FooterBar, { children: [
8039
+ query.length > 0 && filtered.length > 0 && /* @__PURE__ */ jsx82(
7644
8040
  OptionList,
7645
8041
  {
7646
8042
  label: t.optionsLabel,
7647
8043
  options: filtered.map((tm) => ({
7648
8044
  key: tm.teamId,
7649
- content: /* @__PURE__ */ jsxs69(Fragment17, { children: [
7650
- /* @__PURE__ */ jsx81(CrestShield, { src: tm.crestUrl, name: tm.teamName, size: 28 }),
7651
- /* @__PURE__ */ jsx81("span", { children: tm.teamName })
8045
+ content: /* @__PURE__ */ jsxs70(Fragment17, { children: [
8046
+ /* @__PURE__ */ jsx82(CrestShield, { src: tm.crestUrl, name: tm.teamName, size: 28 }),
8047
+ /* @__PURE__ */ jsx82("span", { children: tm.teamName })
7652
8048
  ] })
7653
8049
  })),
7654
8050
  onPick: (k) => handlePick(Number(k))
7655
8051
  }
7656
8052
  ),
7657
- /* @__PURE__ */ jsx81(
8053
+ /* @__PURE__ */ jsx82(
7658
8054
  SearchField,
7659
8055
  {
7660
8056
  id: inputId,
@@ -7671,8 +8067,8 @@ function GuessTheXiGame({
7671
8067
  }
7672
8068
 
7673
8069
  // src/components/games/DailyQuizGame.tsx
7674
- import { useState as useState35 } from "react";
7675
- import { Fragment as Fragment18, jsx as jsx82, jsxs as jsxs70 } from "react/jsx-runtime";
8070
+ import { useState as useState38 } from "react";
8071
+ import { Fragment as Fragment18, jsx as jsx83, jsxs as jsxs71 } from "react/jsx-runtime";
7676
8072
  function parseClientState6(json) {
7677
8073
  if (!json) return null;
7678
8074
  try {
@@ -7693,13 +8089,13 @@ function OptionName({ text }) {
7693
8089
  const tokens = base.split(/\s+/).filter(Boolean);
7694
8090
  const isPlainName = tokens.length >= 1 && tokens.length <= 4 && tokens.every((t) => NAME_TOKEN.test(t));
7695
8091
  if (!isPlainName || base === "") {
7696
- return /* @__PURE__ */ jsx82("span", { className: "ss-g-dq-opt-name", children: /* @__PURE__ */ jsx82("span", { className: "ss-g-dq-opt-full", children: text }) });
8092
+ return /* @__PURE__ */ jsx83("span", { className: "ss-g-dq-opt-name", children: /* @__PURE__ */ jsx83("span", { className: "ss-g-dq-opt-full", children: text }) });
7697
8093
  }
7698
8094
  const { first, last } = splitName(base);
7699
- return /* @__PURE__ */ jsxs70("span", { className: "ss-g-dq-opt-name", children: [
7700
- first && /* @__PURE__ */ jsx82("span", { className: "ss-g-dq-opt-first", children: first }),
7701
- /* @__PURE__ */ jsx82("span", { className: "ss-g-dq-opt-last", children: last }),
7702
- suffix && /* @__PURE__ */ jsx82("span", { className: "ss-g-dq-opt-suffix", children: suffix })
8095
+ return /* @__PURE__ */ jsxs71("span", { className: "ss-g-dq-opt-name", children: [
8096
+ first && /* @__PURE__ */ jsx83("span", { className: "ss-g-dq-opt-first", children: first }),
8097
+ /* @__PURE__ */ jsx83("span", { className: "ss-g-dq-opt-last", children: last }),
8098
+ suffix && /* @__PURE__ */ jsx83("span", { className: "ss-g-dq-opt-suffix", children: suffix })
7703
8099
  ] });
7704
8100
  }
7705
8101
  function DailyQuizGame({
@@ -7712,15 +8108,15 @@ function DailyQuizGame({
7712
8108
  }) {
7713
8109
  const s = ui.games.dailyQuiz;
7714
8110
  const title = gameTitle({ gameId: "daily-quiz" }, ui.games.titles);
7715
- const [selections, setSelections] = useState35(/* @__PURE__ */ new Map());
7716
- const [page, setPage] = useState35(0);
8111
+ const [selections, setSelections] = useState38(/* @__PURE__ */ new Map());
8112
+ const [page, setPage] = useState38(0);
7717
8113
  const clientState = parseClientState6(result?.clientStateJson);
7718
8114
  const results = clientState?.results ?? [];
7719
8115
  const isRevealed = results.length > 0 || result?.alreadyPlayed === true;
7720
8116
  if (!config) {
7721
- return /* @__PURE__ */ jsxs70("div", { className: "ss-g-screen", "data-game": "daily-quiz", "data-testid": "game-screen-daily-quiz", children: [
7722
- /* @__PURE__ */ jsx82(GameHeader, { title, onBack, backLabel: ui.back }),
7723
- /* @__PURE__ */ jsx82("div", { className: "ss-g-body ss-g-loading", children: ui.games.loading })
8117
+ return /* @__PURE__ */ jsxs71("div", { className: "ss-g-screen", "data-game": "daily-quiz", "data-testid": "game-screen-daily-quiz", children: [
8118
+ /* @__PURE__ */ jsx83(GameHeader, { title, onBack, backLabel: ui.back }),
8119
+ /* @__PURE__ */ jsx83("div", { className: "ss-g-body ss-g-loading", children: ui.games.loading })
7724
8120
  ] });
7725
8121
  }
7726
8122
  const questions = config.questions;
@@ -7755,11 +8151,11 @@ function DailyQuizGame({
7755
8151
  return r.isCorrect ? "correct" : "wrong";
7756
8152
  });
7757
8153
  const correctCount = results.filter((r) => r.isCorrect).length;
7758
- return /* @__PURE__ */ jsxs70("div", { className: "ss-g-screen", "data-game": "daily-quiz", "data-testid": "game-screen-daily-quiz", children: [
7759
- /* @__PURE__ */ jsx82(GameHeader, { title, eyebrow: s.results, onBack, backLabel: ui.back }),
7760
- /* @__PURE__ */ jsx82(SegmentProgress, { segments: segments2, ariaLabel: s.results }),
7761
- /* @__PURE__ */ jsxs70("div", { className: "ss-g-body", children: [
7762
- /* @__PURE__ */ jsx82(
8154
+ return /* @__PURE__ */ jsxs71("div", { className: "ss-g-screen", "data-game": "daily-quiz", "data-testid": "game-screen-daily-quiz", children: [
8155
+ /* @__PURE__ */ jsx83(GameHeader, { title, eyebrow: s.results, onBack, backLabel: ui.back }),
8156
+ /* @__PURE__ */ jsx83(SegmentProgress, { segments: segments2, ariaLabel: s.results }),
8157
+ /* @__PURE__ */ jsxs71("div", { className: "ss-g-body", children: [
8158
+ /* @__PURE__ */ jsx83(
7763
8159
  ResultCard,
7764
8160
  {
7765
8161
  tone: "neutral",
@@ -7772,15 +8168,15 @@ function DailyQuizGame({
7772
8168
  questions.map((q) => {
7773
8169
  const r = findResult(results, q.index);
7774
8170
  const picked = selections.get(q.index);
7775
- return /* @__PURE__ */ jsxs70("div", { className: "ss-g-dq-rq", children: [
7776
- /* @__PURE__ */ jsx82("div", { className: "ss-g-dq-rq-stem", children: q.stem }),
7777
- r && /* @__PURE__ */ jsx82("div", { className: "ss-g-dq-rq-opts", children: q.options.map((opt, optIdx) => {
8171
+ return /* @__PURE__ */ jsxs71("div", { className: "ss-g-dq-rq", children: [
8172
+ /* @__PURE__ */ jsx83("div", { className: "ss-g-dq-rq-stem", children: q.stem }),
8173
+ r && /* @__PURE__ */ jsx83("div", { className: "ss-g-dq-rq-opts", children: q.options.map((opt, optIdx) => {
7778
8174
  let cls = "ss-g-dq-rq-opt";
7779
8175
  if (optIdx === r.correctOptionIndex) cls += " ss-g-dq-rq-opt--correct";
7780
8176
  else if (optIdx === picked && !r.isCorrect) cls += " ss-g-dq-rq-opt--wrong";
7781
- return /* @__PURE__ */ jsx82("span", { className: cls, children: opt }, optIdx);
8177
+ return /* @__PURE__ */ jsx83("span", { className: cls, children: opt }, optIdx);
7782
8178
  }) }),
7783
- r?.revealText && /* @__PURE__ */ jsx82("div", { className: "ss-g-dq-why", children: r.revealText })
8179
+ r?.revealText && /* @__PURE__ */ jsx83("div", { className: "ss-g-dq-why", children: r.revealText })
7784
8180
  ] }, q.index);
7785
8181
  })
7786
8182
  ] })
@@ -7788,16 +8184,16 @@ function DailyQuizGame({
7788
8184
  }
7789
8185
  const segments = questions.map((_, i) => i < page ? "done" : i === page ? "current" : "todo");
7790
8186
  const selectedIdx = current ? selections.get(current.index) : void 0;
7791
- return /* @__PURE__ */ jsxs70("div", { className: "ss-g-screen", "data-game": "daily-quiz", "data-testid": "game-screen-daily-quiz", children: [
7792
- /* @__PURE__ */ jsx82(GameHeader, { title, eyebrow: s.questionOf(page + 1, total), onBack, backLabel: ui.back }),
7793
- /* @__PURE__ */ jsx82(SegmentProgress, { segments, ariaLabel: s.progressAria(page + 1, total) }),
7794
- /* @__PURE__ */ jsx82("div", { className: "ss-g-body", children: current && /* @__PURE__ */ jsxs70(Fragment18, { children: [
7795
- /* @__PURE__ */ jsx82("h3", { className: "ss-g-dq-stem", children: current.stem }),
7796
- /* @__PURE__ */ jsx82("div", { className: "ss-g-dq-opts", children: current.options.map((opt, optIdx) => {
8187
+ return /* @__PURE__ */ jsxs71("div", { className: "ss-g-screen", "data-game": "daily-quiz", "data-testid": "game-screen-daily-quiz", children: [
8188
+ /* @__PURE__ */ jsx83(GameHeader, { title, eyebrow: s.questionOf(page + 1, total), onBack, backLabel: ui.back }),
8189
+ /* @__PURE__ */ jsx83(SegmentProgress, { segments, ariaLabel: s.progressAria(page + 1, total) }),
8190
+ /* @__PURE__ */ jsx83("div", { className: "ss-g-body", children: current && /* @__PURE__ */ jsxs71(Fragment18, { children: [
8191
+ /* @__PURE__ */ jsx83("h3", { className: "ss-g-dq-stem", children: current.stem }),
8192
+ /* @__PURE__ */ jsx83("div", { className: "ss-g-dq-opts", children: current.options.map((opt, optIdx) => {
7797
8193
  const selected = optIdx === selectedIdx;
7798
8194
  const imagePath = current.optionImagePaths?.[optIdx] ?? void 0;
7799
8195
  const playerName = opt;
7800
- return /* @__PURE__ */ jsxs70(
8196
+ return /* @__PURE__ */ jsxs71(
7801
8197
  "button",
7802
8198
  {
7803
8199
  type: "button",
@@ -7806,25 +8202,25 @@ function DailyQuizGame({
7806
8202
  disabled: submitting,
7807
8203
  onClick: () => handleSelect(current.index, optIdx),
7808
8204
  children: [
7809
- current.optionImagePaths && /* @__PURE__ */ jsx82(PlayerAvatar, { name: playerName, imagePath, className: "ss-g-dq-opt-av" }),
7810
- /* @__PURE__ */ jsx82("span", { className: "ss-g-dq-badge", "aria-hidden": "true", children: selected ? /* @__PURE__ */ jsx82(IconCheck, {}) : String.fromCharCode(65 + optIdx) }),
7811
- /* @__PURE__ */ jsx82(OptionName, { text: opt })
8205
+ current.optionImagePaths && /* @__PURE__ */ jsx83(PlayerAvatar, { name: playerName, imagePath, className: "ss-g-dq-opt-av" }),
8206
+ /* @__PURE__ */ jsx83("span", { className: "ss-g-dq-badge", "aria-hidden": "true", children: selected ? /* @__PURE__ */ jsx83(IconCheck, {}) : String.fromCharCode(65 + optIdx) }),
8207
+ /* @__PURE__ */ jsx83(OptionName, { text: opt })
7812
8208
  ]
7813
8209
  },
7814
8210
  optIdx
7815
8211
  );
7816
8212
  }) })
7817
8213
  ] }) }),
7818
- /* @__PURE__ */ jsx82(FooterBar, { children: /* @__PURE__ */ jsxs70("div", { className: "ss-g-dq-nav", children: [
7819
- page > 0 && /* @__PURE__ */ jsx82(GameButton, { variant: "outline", onClick: goPrev, disabled: submitting, children: s.previous }),
7820
- isLast ? /* @__PURE__ */ jsx82(GameButton, { variant: "primary", block: true, onClick: handleSubmit, disabled: !currentAnswered || !allAnswered || submitting, children: submitting ? s.submitting : s.submit }) : /* @__PURE__ */ jsx82(GameButton, { variant: "primary", block: true, onClick: goNext, disabled: !currentAnswered || submitting, children: s.next })
8214
+ /* @__PURE__ */ jsx83(FooterBar, { children: /* @__PURE__ */ jsxs71("div", { className: "ss-g-dq-nav", children: [
8215
+ page > 0 && /* @__PURE__ */ jsx83(GameButton, { variant: "outline", onClick: goPrev, disabled: submitting, children: s.previous }),
8216
+ isLast ? /* @__PURE__ */ jsx83(GameButton, { variant: "primary", block: true, onClick: handleSubmit, disabled: !currentAnswered || !allAnswered || submitting, children: submitting ? s.submitting : s.submit }) : /* @__PURE__ */ jsx83(GameButton, { variant: "primary", block: true, onClick: goNext, disabled: !currentAnswered || submitting, children: s.next })
7821
8217
  ] }) })
7822
8218
  ] });
7823
8219
  }
7824
8220
 
7825
8221
  // src/components/games/MatchdayPredictorGame.tsx
7826
- import { useId as useId6, useState as useState36 } from "react";
7827
- import { jsx as jsx83, jsxs as jsxs71 } from "react/jsx-runtime";
8222
+ import { useId as useId7, useState as useState39 } from "react";
8223
+ import { jsx as jsx84, jsxs as jsxs72 } from "react/jsx-runtime";
7828
8224
  var SCORER_SEARCH_THRESHOLD = 9;
7829
8225
  function parseClientState7(json) {
7830
8226
  if (!json) return null;
@@ -7842,7 +8238,7 @@ function isLocked(kickoffUtc) {
7842
8238
  }
7843
8239
  }
7844
8240
  function IconMinus() {
7845
- return /* @__PURE__ */ jsx83(
8241
+ return /* @__PURE__ */ jsx84(
7846
8242
  "svg",
7847
8243
  {
7848
8244
  width: 18,
@@ -7853,20 +8249,20 @@ function IconMinus() {
7853
8249
  strokeWidth: 2.2,
7854
8250
  strokeLinecap: "round",
7855
8251
  "aria-hidden": "true",
7856
- children: /* @__PURE__ */ jsx83("path", { d: "M5 12h14" })
8252
+ children: /* @__PURE__ */ jsx84("path", { d: "M5 12h14" })
7857
8253
  }
7858
8254
  );
7859
8255
  }
7860
8256
  function TeamBadge({ team, label }) {
7861
- return /* @__PURE__ */ jsxs71("div", { className: "ss-g-mp-team", children: [
7862
- /* @__PURE__ */ jsx83(CrestShield, { name: team.name, size: 44 }),
7863
- /* @__PURE__ */ jsx83("span", { className: "ss-g-mp-team-name", children: team.name }),
7864
- /* @__PURE__ */ jsx83("span", { className: "ss-g-mp-team-side", children: label })
8257
+ return /* @__PURE__ */ jsxs72("div", { className: "ss-g-mp-team", children: [
8258
+ /* @__PURE__ */ jsx84(CrestShield, { name: team.name, size: 44 }),
8259
+ /* @__PURE__ */ jsx84("span", { className: "ss-g-mp-team-name", children: team.name }),
8260
+ /* @__PURE__ */ jsx84("span", { className: "ss-g-mp-team-side", children: label })
7865
8261
  ] });
7866
8262
  }
7867
8263
  function ScoreCard({ home, away, h, a, t, edit }) {
7868
- const col = (side, team, value) => /* @__PURE__ */ jsxs71("div", { className: "ss-g-mp-col", children: [
7869
- edit && /* @__PURE__ */ jsx83(
8264
+ const col = (side, team, value) => /* @__PURE__ */ jsxs72("div", { className: "ss-g-mp-col", children: [
8265
+ edit && /* @__PURE__ */ jsx84(
7870
8266
  "button",
7871
8267
  {
7872
8268
  type: "button",
@@ -7874,11 +8270,11 @@ function ScoreCard({ home, away, h, a, t, edit }) {
7874
8270
  "aria-label": t.goalsUp(team.name),
7875
8271
  disabled: edit.disabled,
7876
8272
  onClick: () => edit.onStep(side, 1),
7877
- children: /* @__PURE__ */ jsx83(IconPlus, { size: 18 })
8273
+ children: /* @__PURE__ */ jsx84(IconPlus, { size: 18 })
7878
8274
  }
7879
8275
  ),
7880
- /* @__PURE__ */ jsx83("span", { className: "ss-g-mp-digit", "data-testid": "mp-digit", "data-active": edit ? String(edit.active === side) : "false", children: value }),
7881
- edit && /* @__PURE__ */ jsx83(
8276
+ /* @__PURE__ */ jsx84("span", { className: "ss-g-mp-digit", "data-testid": "mp-digit", "data-active": edit ? String(edit.active === side) : "false", children: value }),
8277
+ edit && /* @__PURE__ */ jsx84(
7882
8278
  "button",
7883
8279
  {
7884
8280
  type: "button",
@@ -7886,27 +8282,27 @@ function ScoreCard({ home, away, h, a, t, edit }) {
7886
8282
  "aria-label": t.goalsDown(team.name),
7887
8283
  disabled: edit.disabled || value <= 0,
7888
8284
  onClick: () => edit.onStep(side, -1),
7889
- children: /* @__PURE__ */ jsx83(IconMinus, {})
8285
+ children: /* @__PURE__ */ jsx84(IconMinus, {})
7890
8286
  }
7891
8287
  )
7892
8288
  ] });
7893
- return /* @__PURE__ */ jsxs71("div", { className: "ss-g-mp-card", children: [
7894
- /* @__PURE__ */ jsx83(TeamBadge, { team: home, label: t.home }),
7895
- /* @__PURE__ */ jsxs71("div", { className: "ss-g-mp-scores", children: [
8289
+ return /* @__PURE__ */ jsxs72("div", { className: "ss-g-mp-card", children: [
8290
+ /* @__PURE__ */ jsx84(TeamBadge, { team: home, label: t.home }),
8291
+ /* @__PURE__ */ jsxs72("div", { className: "ss-g-mp-scores", children: [
7896
8292
  col("home", home, h),
7897
- /* @__PURE__ */ jsx83("span", { className: "ss-g-mp-dash", "aria-hidden": "true", children: "\u2013" }),
8293
+ /* @__PURE__ */ jsx84("span", { className: "ss-g-mp-dash", "aria-hidden": "true", children: "\u2013" }),
7898
8294
  col("away", away, a)
7899
8295
  ] }),
7900
- /* @__PURE__ */ jsx83(TeamBadge, { team: away, label: t.away })
8296
+ /* @__PURE__ */ jsx84(TeamBadge, { team: away, label: t.away })
7901
8297
  ] });
7902
8298
  }
7903
8299
  function OutcomeRow({ label, ok, detail, t }) {
7904
- return /* @__PURE__ */ jsxs71("li", { className: "ss-g-mp-row", "data-testid": "mp-row", "data-ok": String(ok), children: [
7905
- /* @__PURE__ */ jsx83("span", { className: "ss-g-mp-row-k", children: label }),
7906
- /* @__PURE__ */ jsxs71("span", { className: "ss-g-mp-row-v", children: [
7907
- ok ? /* @__PURE__ */ jsx83(IconCheck, {}) : /* @__PURE__ */ jsx83(IconClose, { size: 14 }),
7908
- /* @__PURE__ */ jsx83("span", { className: "ss-g-sr", children: ok ? t.correct : t.incorrect }),
7909
- detail ? /* @__PURE__ */ jsx83("span", { className: "ss-g-mp-row-d", children: detail }) : null
8300
+ return /* @__PURE__ */ jsxs72("li", { className: "ss-g-mp-row", "data-testid": "mp-row", "data-ok": String(ok), children: [
8301
+ /* @__PURE__ */ jsx84("span", { className: "ss-g-mp-row-k", children: label }),
8302
+ /* @__PURE__ */ jsxs72("span", { className: "ss-g-mp-row-v", children: [
8303
+ ok ? /* @__PURE__ */ jsx84(IconCheck, {}) : /* @__PURE__ */ jsx84(IconClose, { size: 14 }),
8304
+ /* @__PURE__ */ jsx84("span", { className: "ss-g-sr", children: ok ? t.correct : t.incorrect }),
8305
+ detail ? /* @__PURE__ */ jsx84("span", { className: "ss-g-mp-row-d", children: detail }) : null
7910
8306
  ] })
7911
8307
  ] });
7912
8308
  }
@@ -7919,20 +8315,20 @@ function MatchdayPredictorGame({
7919
8315
  onBack
7920
8316
  }) {
7921
8317
  const t = ui.games.predictor;
7922
- const [homeScore, setHomeScore] = useState36(0);
7923
- const [awayScore, setAwayScore] = useState36(0);
7924
- const [firstScorerPlayerId, setFirstScorerPlayerId] = useState36(null);
7925
- const [lastEdited, setLastEdited] = useState36("home");
7926
- const [query, setQuery] = useState36("");
7927
- const searchId = useId6();
8318
+ const [homeScore, setHomeScore] = useState39(0);
8319
+ const [awayScore, setAwayScore] = useState39(0);
8320
+ const [firstScorerPlayerId, setFirstScorerPlayerId] = useState39(null);
8321
+ const [lastEdited, setLastEdited] = useState39("home");
8322
+ const [query, setQuery] = useState39("");
8323
+ const searchId = useId7();
7928
8324
  const clientState = parseClientState7(result?.clientStateJson);
7929
8325
  const alreadyPlayed = result?.alreadyPlayed === true;
7930
- const header = /* @__PURE__ */ jsx83(
8326
+ const header = /* @__PURE__ */ jsx84(
7931
8327
  GameHeader,
7932
8328
  {
7933
8329
  title: gameTitle({ gameId: "matchday-predictor" }, ui.games.titles),
7934
8330
  eyebrow: config ? t.eyebrow(config.homeTeam.name, config.awayTeam.name) : void 0,
7935
- right: config ? /* @__PURE__ */ jsx83(Chip, { icon: /* @__PURE__ */ jsx83(IconLock, {}), children: ui.games.formatDayTime(config.kickoffUtc) }) : void 0,
8331
+ right: config ? /* @__PURE__ */ jsx84(Chip, { icon: /* @__PURE__ */ jsx84(IconLock, {}), children: ui.games.formatDayTime(config.kickoffUtc) }) : void 0,
7936
8332
  onBack,
7937
8333
  backLabel: ui.back
7938
8334
  }
@@ -7940,10 +8336,10 @@ function MatchdayPredictorGame({
7940
8336
  if (alreadyPlayed && clientState) {
7941
8337
  if (!clientState.graded) {
7942
8338
  const scorer = config?.scorerPool.find((p) => p.playerId === clientState.predictedFirstScorerPlayerId) ?? null;
7943
- return /* @__PURE__ */ jsxs71("div", { className: "ss-g-screen", "data-game": "matchday-predictor", "data-testid": "game-screen-matchday-predictor", children: [
8339
+ return /* @__PURE__ */ jsxs72("div", { className: "ss-g-screen", "data-game": "matchday-predictor", "data-testid": "game-screen-matchday-predictor", children: [
7944
8340
  header,
7945
- /* @__PURE__ */ jsxs71("div", { className: "ss-g-body", children: [
7946
- config && /* @__PURE__ */ jsx83(
8341
+ /* @__PURE__ */ jsxs72("div", { className: "ss-g-body", children: [
8342
+ config && /* @__PURE__ */ jsx84(
7947
8343
  ScoreCard,
7948
8344
  {
7949
8345
  home: config.homeTeam,
@@ -7953,7 +8349,7 @@ function MatchdayPredictorGame({
7953
8349
  t
7954
8350
  }
7955
8351
  ),
7956
- /* @__PURE__ */ jsx83(
8352
+ /* @__PURE__ */ jsx84(
7957
8353
  ResultCard,
7958
8354
  {
7959
8355
  tone: "neutral",
@@ -7970,28 +8366,28 @@ function MatchdayPredictorGame({
7970
8366
  }
7971
8367
  )
7972
8368
  ] }),
7973
- /* @__PURE__ */ jsx83(FooterBar, { children: /* @__PURE__ */ jsx83("p", { className: "ss-g-mp-fun", children: t.forFun }) })
8369
+ /* @__PURE__ */ jsx84(FooterBar, { children: /* @__PURE__ */ jsx84("p", { className: "ss-g-mp-fun", children: t.forFun }) })
7974
8370
  ] });
7975
8371
  }
7976
8372
  const r = clientState.result;
7977
- return /* @__PURE__ */ jsxs71("div", { className: "ss-g-screen", "data-game": "matchday-predictor", "data-testid": "game-screen-matchday-predictor", children: [
8373
+ return /* @__PURE__ */ jsxs72("div", { className: "ss-g-screen", "data-game": "matchday-predictor", "data-testid": "game-screen-matchday-predictor", children: [
7978
8374
  header,
7979
- /* @__PURE__ */ jsxs71("div", { className: "ss-g-body", children: [
7980
- config && /* @__PURE__ */ jsx83(ScoreCard, { home: config.homeTeam, away: config.awayTeam, h: r.homeScore, a: r.awayScore, t }),
7981
- /* @__PURE__ */ jsx83(ResultCard, { tone: "neutral", title: t.fullTime(r.homeScore, r.awayScore), onBack, ui }),
7982
- /* @__PURE__ */ jsxs71("ul", { className: "ss-g-mp-rows", children: [
7983
- /* @__PURE__ */ jsx83(OutcomeRow, { label: t.exactScore, ok: clientState.exactScoreCorrect, t }),
7984
- /* @__PURE__ */ jsx83(OutcomeRow, { label: t.outcome, ok: clientState.outcomeCorrect, t }),
7985
- !clientState.firstScorerVoid && /* @__PURE__ */ jsx83(OutcomeRow, { label: t.firstScorerRow, ok: clientState.firstScorerCorrect, detail: r.firstScorerName, t })
8375
+ /* @__PURE__ */ jsxs72("div", { className: "ss-g-body", children: [
8376
+ config && /* @__PURE__ */ jsx84(ScoreCard, { home: config.homeTeam, away: config.awayTeam, h: r.homeScore, a: r.awayScore, t }),
8377
+ /* @__PURE__ */ jsx84(ResultCard, { tone: "neutral", title: t.fullTime(r.homeScore, r.awayScore), onBack, ui }),
8378
+ /* @__PURE__ */ jsxs72("ul", { className: "ss-g-mp-rows", children: [
8379
+ /* @__PURE__ */ jsx84(OutcomeRow, { label: t.exactScore, ok: clientState.exactScoreCorrect, t }),
8380
+ /* @__PURE__ */ jsx84(OutcomeRow, { label: t.outcome, ok: clientState.outcomeCorrect, t }),
8381
+ !clientState.firstScorerVoid && /* @__PURE__ */ jsx84(OutcomeRow, { label: t.firstScorerRow, ok: clientState.firstScorerCorrect, detail: r.firstScorerName, t })
7986
8382
  ] })
7987
8383
  ] }),
7988
- /* @__PURE__ */ jsx83(FooterBar, { children: /* @__PURE__ */ jsx83("p", { className: "ss-g-mp-fun", children: t.forFun }) })
8384
+ /* @__PURE__ */ jsx84(FooterBar, { children: /* @__PURE__ */ jsx84("p", { className: "ss-g-mp-fun", children: t.forFun }) })
7989
8385
  ] });
7990
8386
  }
7991
8387
  if (!config) {
7992
- return /* @__PURE__ */ jsxs71("div", { className: "ss-g-screen", "data-game": "matchday-predictor", "data-testid": "game-screen-matchday-predictor", children: [
8388
+ return /* @__PURE__ */ jsxs72("div", { className: "ss-g-screen", "data-game": "matchday-predictor", "data-testid": "game-screen-matchday-predictor", children: [
7993
8389
  header,
7994
- /* @__PURE__ */ jsx83("div", { className: "ss-g-body ss-g-loading", children: ui.games.loading })
8390
+ /* @__PURE__ */ jsx84("div", { className: "ss-g-body ss-g-loading", children: ui.games.loading })
7995
8391
  ] });
7996
8392
  }
7997
8393
  const locked = isLocked(config.kickoffUtc);
@@ -8015,10 +8411,10 @@ function MatchdayPredictorGame({
8015
8411
  const showSearch = pool.length > SCORER_SEARCH_THRESHOLD;
8016
8412
  const q = query.trim().toLowerCase();
8017
8413
  const visible = showSearch && q ? pool.filter((p) => p.playerName.toLowerCase().includes(q)) : pool;
8018
- return /* @__PURE__ */ jsxs71("div", { className: "ss-g-screen", "data-game": "matchday-predictor", "data-testid": "game-screen-matchday-predictor", children: [
8414
+ return /* @__PURE__ */ jsxs72("div", { className: "ss-g-screen", "data-game": "matchday-predictor", "data-testid": "game-screen-matchday-predictor", children: [
8019
8415
  header,
8020
- /* @__PURE__ */ jsxs71("div", { className: "ss-g-body", children: [
8021
- /* @__PURE__ */ jsx83(
8416
+ /* @__PURE__ */ jsxs72("div", { className: "ss-g-body", children: [
8417
+ /* @__PURE__ */ jsx84(
8022
8418
  ScoreCard,
8023
8419
  {
8024
8420
  home: config.homeTeam,
@@ -8029,12 +8425,12 @@ function MatchdayPredictorGame({
8029
8425
  edit: { disabled, active: lastEdited, onStep: step }
8030
8426
  }
8031
8427
  ),
8032
- pool.length > 0 && /* @__PURE__ */ jsxs71("section", { className: "ss-g-mp-scorer", children: [
8033
- /* @__PURE__ */ jsxs71("div", { className: "ss-g-mp-sec-head", children: [
8034
- /* @__PURE__ */ jsx83("h3", { children: t.firstScorer }),
8035
- /* @__PURE__ */ jsx83("span", { children: t.optional })
8428
+ pool.length > 0 && /* @__PURE__ */ jsxs72("section", { className: "ss-g-mp-scorer", children: [
8429
+ /* @__PURE__ */ jsxs72("div", { className: "ss-g-mp-sec-head", children: [
8430
+ /* @__PURE__ */ jsx84("h3", { children: t.firstScorer }),
8431
+ /* @__PURE__ */ jsx84("span", { children: t.optional })
8036
8432
  ] }),
8037
- showSearch && /* @__PURE__ */ jsx83(
8433
+ showSearch && /* @__PURE__ */ jsx84(
8038
8434
  SearchField,
8039
8435
  {
8040
8436
  id: searchId,
@@ -8046,9 +8442,9 @@ function MatchdayPredictorGame({
8046
8442
  disabled
8047
8443
  }
8048
8444
  ),
8049
- /* @__PURE__ */ jsx83("div", { className: "ss-g-mp-grid", children: visible.map((p) => {
8445
+ /* @__PURE__ */ jsx84("div", { className: "ss-g-mp-grid", children: visible.map((p) => {
8050
8446
  const selected = firstScorerPlayerId === p.playerId;
8051
- return /* @__PURE__ */ jsxs71(
8447
+ return /* @__PURE__ */ jsxs72(
8052
8448
  "button",
8053
8449
  {
8054
8450
  type: "button",
@@ -8058,15 +8454,15 @@ function MatchdayPredictorGame({
8058
8454
  disabled,
8059
8455
  onClick: () => setFirstScorerPlayerId((id) => id === p.playerId ? null : p.playerId),
8060
8456
  children: [
8061
- selected && /* @__PURE__ */ jsx83("span", { className: "ss-g-mp-pcheck", children: /* @__PURE__ */ jsx83(IconCheck, { size: 12 }) }),
8062
- /* @__PURE__ */ jsx83(Silhouette, { size: 52, variant: selected ? "selected" : "default" }),
8063
- /* @__PURE__ */ jsx83("span", { className: "ss-g-mp-pname", children: splitName(p.playerName).last })
8457
+ selected && /* @__PURE__ */ jsx84("span", { className: "ss-g-mp-pcheck", children: /* @__PURE__ */ jsx84(IconCheck, { size: 12 }) }),
8458
+ /* @__PURE__ */ jsx84(Silhouette, { size: 52, variant: selected ? "selected" : "default" }),
8459
+ /* @__PURE__ */ jsx84("span", { className: "ss-g-mp-pname", children: splitName(p.playerName).last })
8064
8460
  ]
8065
8461
  },
8066
8462
  p.playerId
8067
8463
  );
8068
8464
  }) }),
8069
- /* @__PURE__ */ jsxs71(
8465
+ /* @__PURE__ */ jsxs72(
8070
8466
  "button",
8071
8467
  {
8072
8468
  type: "button",
@@ -8075,24 +8471,24 @@ function MatchdayPredictorGame({
8075
8471
  disabled,
8076
8472
  onClick: () => setFirstScorerPlayerId(null),
8077
8473
  children: [
8078
- /* @__PURE__ */ jsx83("span", { className: "ss-g-mp-radio", "aria-hidden": "true" }),
8474
+ /* @__PURE__ */ jsx84("span", { className: "ss-g-mp-radio", "aria-hidden": "true" }),
8079
8475
  t.noScorer
8080
8476
  ]
8081
8477
  }
8082
8478
  )
8083
8479
  ] }),
8084
- locked && /* @__PURE__ */ jsx83("p", { className: "ss-g-mp-closed", children: t.closed })
8480
+ locked && /* @__PURE__ */ jsx84("p", { className: "ss-g-mp-closed", children: t.closed })
8085
8481
  ] }),
8086
- /* @__PURE__ */ jsxs71(FooterBar, { children: [
8087
- /* @__PURE__ */ jsx83(GameButton, { variant: "primary", block: true, disabled, onClick: handleSubmit, children: submitting ? t.saving : t.save }),
8088
- /* @__PURE__ */ jsx83("p", { className: "ss-g-mp-fun", children: t.forFun })
8482
+ /* @__PURE__ */ jsxs72(FooterBar, { children: [
8483
+ /* @__PURE__ */ jsx84(GameButton, { variant: "primary", block: true, disabled, onClick: handleSubmit, children: submitting ? t.saving : t.save }),
8484
+ /* @__PURE__ */ jsx84("p", { className: "ss-g-mp-fun", children: t.forFun })
8089
8485
  ] })
8090
8486
  ] });
8091
8487
  }
8092
8488
 
8093
8489
  // src/components/games/StartingXiGame.tsx
8094
- import { useId as useId7, useState as useState37 } from "react";
8095
- import { Fragment as Fragment19, jsx as jsx84, jsxs as jsxs72 } from "react/jsx-runtime";
8490
+ import { useId as useId8, useState as useState40 } from "react";
8491
+ import { Fragment as Fragment19, jsx as jsx85, jsxs as jsxs73 } from "react/jsx-runtime";
8096
8492
  var POINTS_PER_STARTER = 8;
8097
8493
  var XI_SIZE = 11;
8098
8494
  var DEFAULT_FORMATION = "4-3-3";
@@ -8135,26 +8531,26 @@ function StartingXiGame({
8135
8531
  lockAtUtc
8136
8532
  }) {
8137
8533
  const t = ui.games.startingXi;
8138
- const [slotPlayers, setSlotPlayers] = useState37(() => Array(XI_SIZE).fill(null));
8139
- const [active, setActive] = useState37(0);
8140
- const [query, setQuery] = useState37("");
8141
- const searchId = useId7();
8534
+ const [slotPlayers, setSlotPlayers] = useState40(() => Array(XI_SIZE).fill(null));
8535
+ const [active, setActive] = useState40(0);
8536
+ const [query, setQuery] = useState40("");
8537
+ const searchId = useId8();
8142
8538
  const clientState = parseClientState8(result?.clientStateJson);
8143
8539
  const alreadyPlayed = result?.alreadyPlayed === true;
8144
- const header = /* @__PURE__ */ jsx84(
8540
+ const header = /* @__PURE__ */ jsx85(
8145
8541
  GameHeader,
8146
8542
  {
8147
8543
  title: gameTitle({ gameId: "starting-xi" }, ui.games.titles),
8148
8544
  eyebrow: t.eyebrow,
8149
- right: /* @__PURE__ */ jsx84(Chip, { variant: "accent", children: t.perStarter(POINTS_PER_STARTER) }),
8545
+ right: /* @__PURE__ */ jsx85(Chip, { variant: "accent", children: t.perStarter(POINTS_PER_STARTER) }),
8150
8546
  onBack,
8151
8547
  backLabel: ui.back
8152
8548
  }
8153
8549
  );
8154
8550
  function statusScreen(title, score) {
8155
- return /* @__PURE__ */ jsxs72("div", { className: "ss-g-screen", "data-game": "starting-xi", "data-testid": "game-screen-starting-xi", children: [
8551
+ return /* @__PURE__ */ jsxs73("div", { className: "ss-g-screen", "data-game": "starting-xi", "data-testid": "game-screen-starting-xi", children: [
8156
8552
  header,
8157
- /* @__PURE__ */ jsx84("div", { className: "ss-g-body", children: /* @__PURE__ */ jsx84(ResultCard, { tone: "neutral", title, score, onBack, ui }) })
8553
+ /* @__PURE__ */ jsx85("div", { className: "ss-g-body", children: /* @__PURE__ */ jsx85(ResultCard, { tone: "neutral", title, score, onBack, ui }) })
8158
8554
  ] });
8159
8555
  }
8160
8556
  if (alreadyPlayed) {
@@ -8163,9 +8559,9 @@ function StartingXiGame({
8163
8559
  if (clientState.status === "graded") return statusScreen(t.gradedLine(clientState.correctCount), clientState.score);
8164
8560
  }
8165
8561
  if (!config) {
8166
- return /* @__PURE__ */ jsxs72("div", { className: "ss-g-screen", "data-game": "starting-xi", "data-testid": "game-screen-starting-xi", children: [
8562
+ return /* @__PURE__ */ jsxs73("div", { className: "ss-g-screen", "data-game": "starting-xi", "data-testid": "game-screen-starting-xi", children: [
8167
8563
  header,
8168
- /* @__PURE__ */ jsx84("div", { className: "ss-g-body ss-g-loading", children: ui.games.loading })
8564
+ /* @__PURE__ */ jsx85("div", { className: "ss-g-body ss-g-loading", children: ui.games.loading })
8169
8565
  ] });
8170
8566
  }
8171
8567
  const { formation, slots } = formationSlots(config.formation);
@@ -8200,27 +8596,27 @@ function StartingXiGame({
8200
8596
  onSubmit(JSON.stringify({ predictedPlayerIds: slotPlayers }));
8201
8597
  }
8202
8598
  const segments = slotPlayers.map((p) => p !== null ? "current" : "todo");
8203
- return /* @__PURE__ */ jsxs72("div", { className: "ss-g-screen", "data-game": "starting-xi", "data-testid": "game-screen-starting-xi", children: [
8599
+ return /* @__PURE__ */ jsxs73("div", { className: "ss-g-screen", "data-game": "starting-xi", "data-testid": "game-screen-starting-xi", children: [
8204
8600
  header,
8205
- /* @__PURE__ */ jsx84(
8601
+ /* @__PURE__ */ jsx85(
8206
8602
  SegmentProgress,
8207
8603
  {
8208
8604
  segments,
8209
8605
  ariaLabel: t.picked(pickedCount),
8210
8606
  leftLabel: t.picked(pickedCount),
8211
8607
  rightLabel: t.toGo(XI_SIZE - pickedCount),
8212
- right: /* @__PURE__ */ jsx84(Chip, { children: formation })
8608
+ right: /* @__PURE__ */ jsx85(Chip, { children: formation })
8213
8609
  }
8214
8610
  ),
8215
- /* @__PURE__ */ jsxs72("div", { className: "ss-g-body", children: [
8216
- /* @__PURE__ */ jsxs72("div", { className: "ss-g-xi-pitch", children: [
8217
- /* @__PURE__ */ jsx84(PitchSvg, { variant: "half" }),
8611
+ /* @__PURE__ */ jsxs73("div", { className: "ss-g-body", children: [
8612
+ /* @__PURE__ */ jsxs73("div", { className: "ss-g-xi-pitch", children: [
8613
+ /* @__PURE__ */ jsx85(PitchSvg, { variant: "half" }),
8218
8614
  slots.map((s) => {
8219
8615
  const playerId = slotPlayers[s.index] ?? null;
8220
8616
  const player = playerId !== null ? byId.get(playerId) ?? null : null;
8221
8617
  const name = player?.playerName ?? "";
8222
8618
  const state = player ? "filled" : active === s.index ? "active" : "empty";
8223
- return /* @__PURE__ */ jsxs72(
8619
+ return /* @__PURE__ */ jsxs73(
8224
8620
  "button",
8225
8621
  {
8226
8622
  type: "button",
@@ -8232,21 +8628,21 @@ function StartingXiGame({
8232
8628
  disabled: submitting,
8233
8629
  onClick: () => tapSlot(s.index),
8234
8630
  children: [
8235
- /* @__PURE__ */ jsx84("span", { className: "ss-g-xi-ring", "aria-hidden": "true", children: player ? player.jerseyNumber ?? "" : /* @__PURE__ */ jsx84(IconPlus, { size: 18 }) }),
8236
- /* @__PURE__ */ jsx84("span", { className: "ss-g-xi-tag", "aria-hidden": "true", children: player ? splitName(name).last : s.label })
8631
+ /* @__PURE__ */ jsx85("span", { className: "ss-g-xi-ring", "aria-hidden": "true", children: player ? player.jerseyNumber ?? "" : /* @__PURE__ */ jsx85(IconPlus, { size: 18 }) }),
8632
+ /* @__PURE__ */ jsx85("span", { className: "ss-g-xi-tag", "aria-hidden": "true", children: player ? splitName(name).last : s.label })
8237
8633
  ]
8238
8634
  },
8239
8635
  s.index
8240
8636
  );
8241
8637
  })
8242
8638
  ] }),
8243
- /* @__PURE__ */ jsxs72("div", { className: "ss-g-xi-picker", children: [
8244
- /* @__PURE__ */ jsx84("div", { className: "ss-g-xi-picker-head", children: activeSlot ? /* @__PURE__ */ jsxs72(Fragment19, { children: [
8245
- /* @__PURE__ */ jsx84(Chip, { variant: "badge", children: activeSlot.label }),
8246
- /* @__PURE__ */ jsx84("strong", { children: t.pickFor(activeSlot.label) })
8247
- ] }) : /* @__PURE__ */ jsx84("strong", { children: t.allPicked }) }),
8248
- activeSlot && /* @__PURE__ */ jsxs72(Fragment19, { children: [
8249
- /* @__PURE__ */ jsx84(
8639
+ /* @__PURE__ */ jsxs73("div", { className: "ss-g-xi-picker", children: [
8640
+ /* @__PURE__ */ jsx85("div", { className: "ss-g-xi-picker-head", children: activeSlot ? /* @__PURE__ */ jsxs73(Fragment19, { children: [
8641
+ /* @__PURE__ */ jsx85(Chip, { variant: "badge", children: activeSlot.label }),
8642
+ /* @__PURE__ */ jsx85("strong", { children: t.pickFor(activeSlot.label) })
8643
+ ] }) : /* @__PURE__ */ jsx85("strong", { children: t.allPicked }) }),
8644
+ activeSlot && /* @__PURE__ */ jsxs73(Fragment19, { children: [
8645
+ /* @__PURE__ */ jsx85(
8250
8646
  SearchField,
8251
8647
  {
8252
8648
  id: searchId,
@@ -8258,18 +8654,18 @@ function StartingXiGame({
8258
8654
  disabled: submitting
8259
8655
  }
8260
8656
  ),
8261
- /* @__PURE__ */ jsx84("ul", { className: "ss-g-xi-list", children: available.map((p) => /* @__PURE__ */ jsx84("li", { children: /* @__PURE__ */ jsxs72("button", { type: "button", className: "ss-g-xi-opt", disabled: submitting, onClick: () => pick(p.playerId), children: [
8262
- /* @__PURE__ */ jsx84("span", { className: "ss-g-xi-opt-no", "aria-hidden": "true", children: p.jerseyNumber ?? "" }),
8263
- /* @__PURE__ */ jsx84("span", { className: "ss-g-xi-opt-name", children: p.playerName }),
8264
- /* @__PURE__ */ jsx84("span", { className: "ss-g-xi-opt-pos", children: p.positionName })
8657
+ /* @__PURE__ */ jsx85("ul", { className: "ss-g-xi-list", children: available.map((p) => /* @__PURE__ */ jsx85("li", { children: /* @__PURE__ */ jsxs73("button", { type: "button", className: "ss-g-xi-opt", disabled: submitting, onClick: () => pick(p.playerId), children: [
8658
+ /* @__PURE__ */ jsx85("span", { className: "ss-g-xi-opt-no", "aria-hidden": "true", children: p.jerseyNumber ?? "" }),
8659
+ /* @__PURE__ */ jsx85("span", { className: "ss-g-xi-opt-name", children: p.playerName }),
8660
+ /* @__PURE__ */ jsx85("span", { className: "ss-g-xi-opt-pos", children: p.positionName })
8265
8661
  ] }) }, p.playerId)) })
8266
8662
  ] })
8267
8663
  ] })
8268
8664
  ] }),
8269
- /* @__PURE__ */ jsxs72(FooterBar, { children: [
8270
- /* @__PURE__ */ jsx84(GameButton, { variant: "primary", block: true, disabled: !canSubmit, onClick: handleSubmit, children: submitting ? t.submitting : t.submit }),
8271
- /* @__PURE__ */ jsxs72("p", { className: "ss-g-xi-lock", children: [
8272
- /* @__PURE__ */ jsx84(IconLock, {}),
8665
+ /* @__PURE__ */ jsxs73(FooterBar, { children: [
8666
+ /* @__PURE__ */ jsx85(GameButton, { variant: "primary", block: true, disabled: !canSubmit, onClick: handleSubmit, children: submitting ? t.submitting : t.submit }),
8667
+ /* @__PURE__ */ jsxs73("p", { className: "ss-g-xi-lock", children: [
8668
+ /* @__PURE__ */ jsx85(IconLock, {}),
8273
8669
  lockAtUtc ? t.locksAt(ui.games.formatDayTime(lockAtUtc)) : t.locksSoon
8274
8670
  ] })
8275
8671
  ] })
@@ -8277,8 +8673,8 @@ function StartingXiGame({
8277
8673
  }
8278
8674
 
8279
8675
  // src/components/games/StatLadderGame.tsx
8280
- import { useId as useId8, useState as useState38 } from "react";
8281
- import { jsx as jsx85, jsxs as jsxs73 } from "react/jsx-runtime";
8676
+ import { useId as useId9, useState as useState41 } from "react";
8677
+ import { jsx as jsx86, jsxs as jsxs74 } from "react/jsx-runtime";
8282
8678
  function ladderClue(ladder) {
8283
8679
  const mystery = ladder.find((r) => r.rank === 2);
8284
8680
  if (!mystery) return null;
@@ -8300,9 +8696,9 @@ function parseClientState9(json) {
8300
8696
  }
8301
8697
  function NameStack({ name }) {
8302
8698
  const { first, last } = splitName(name);
8303
- return /* @__PURE__ */ jsxs73("span", { className: "ss-g-sl-name", children: [
8304
- first && /* @__PURE__ */ jsx85("small", { children: `${first[0]}.` }),
8305
- /* @__PURE__ */ jsx85("b", { children: last })
8699
+ return /* @__PURE__ */ jsxs74("span", { className: "ss-g-sl-name", children: [
8700
+ first && /* @__PURE__ */ jsx86("small", { children: `${first[0]}.` }),
8701
+ /* @__PURE__ */ jsx86("b", { children: last })
8306
8702
  ] });
8307
8703
  }
8308
8704
  function StatLadderGame({
@@ -8314,16 +8710,16 @@ function StatLadderGame({
8314
8710
  onBack
8315
8711
  }) {
8316
8712
  const t = ui.games.statLadder;
8317
- const [query, setQuery] = useState38("");
8318
- const [selectedId, setSelectedId] = useState38(null);
8319
- const searchId = useId8();
8713
+ const [query, setQuery] = useState41("");
8714
+ const [selectedId, setSelectedId] = useState41(null);
8715
+ const searchId = useId9();
8320
8716
  const clientState = parseClientState9(result?.clientStateJson);
8321
8717
  const revealed = clientState != null;
8322
- const header = /* @__PURE__ */ jsx85(GameHeader, { title: gameTitle({ gameId: "stat-ladder" }, ui.games.titles), eyebrow: t.eyebrow, onBack, backLabel: ui.back });
8718
+ const header = /* @__PURE__ */ jsx86(GameHeader, { title: gameTitle({ gameId: "stat-ladder" }, ui.games.titles), eyebrow: t.eyebrow, onBack, backLabel: ui.back });
8323
8719
  if (!config) {
8324
- return /* @__PURE__ */ jsxs73("div", { className: "ss-g-screen", "data-game": "stat-ladder", "data-testid": "game-screen-stat-ladder", children: [
8720
+ return /* @__PURE__ */ jsxs74("div", { className: "ss-g-screen", "data-game": "stat-ladder", "data-testid": "game-screen-stat-ladder", children: [
8325
8721
  header,
8326
- /* @__PURE__ */ jsx85("div", { className: "ss-g-body ss-g-loading", children: ui.games.loading })
8722
+ /* @__PURE__ */ jsx86("div", { className: "ss-g-body ss-g-loading", children: ui.games.loading })
8327
8723
  ] });
8328
8724
  }
8329
8725
  const question = t.question(config.statLabel);
@@ -8335,45 +8731,45 @@ function StatLadderGame({
8335
8731
  if (selectedId === null || submitting || revealed) return;
8336
8732
  onSubmit(JSON.stringify({ guessedPlayerId: selectedId }));
8337
8733
  }
8338
- return /* @__PURE__ */ jsxs73("div", { className: "ss-g-screen", "data-game": "stat-ladder", "data-testid": "game-screen-stat-ladder", children: [
8734
+ return /* @__PURE__ */ jsxs74("div", { className: "ss-g-screen", "data-game": "stat-ladder", "data-testid": "game-screen-stat-ladder", children: [
8339
8735
  header,
8340
- /* @__PURE__ */ jsxs73("div", { className: "ss-g-body", children: [
8341
- !revealed && /* @__PURE__ */ jsx85(PointsLadderRow, { ladder: config.pointsLadder, guessesUsed: 0, ui }),
8342
- /* @__PURE__ */ jsxs73("div", { className: "ss-g-sl-prompt", children: [
8343
- /* @__PURE__ */ jsx85(Chip, { variant: "accent", icon: /* @__PURE__ */ jsx85(IconShield, { size: 14 }), className: "ss-g-sl-stat", children: config.statLabel }),
8344
- /* @__PURE__ */ jsxs73("h3", { className: "ss-g-sl-q", children: [
8736
+ /* @__PURE__ */ jsxs74("div", { className: "ss-g-body", children: [
8737
+ !revealed && /* @__PURE__ */ jsx86(PointsLadderRow, { ladder: config.pointsLadder, guessesUsed: 0, ui }),
8738
+ /* @__PURE__ */ jsxs74("div", { className: "ss-g-sl-prompt", children: [
8739
+ /* @__PURE__ */ jsx86(Chip, { variant: "accent", icon: /* @__PURE__ */ jsx86(IconShield, { size: 14 }), className: "ss-g-sl-stat", children: config.statLabel }),
8740
+ /* @__PURE__ */ jsxs74("h3", { className: "ss-g-sl-q", children: [
8345
8741
  question.pre,
8346
- /* @__PURE__ */ jsx85("em", { children: question.emph }),
8742
+ /* @__PURE__ */ jsx86("em", { children: question.emph }),
8347
8743
  question.post
8348
8744
  ] })
8349
8745
  ] }),
8350
- /* @__PURE__ */ jsx85("ol", { className: "ss-g-sl-rungs", children: rungs.map(
8351
- (rung) => rung.rank === 2 ? /* @__PURE__ */ jsxs73(
8746
+ /* @__PURE__ */ jsx86("ol", { className: "ss-g-sl-rungs", children: rungs.map(
8747
+ (rung) => rung.rank === 2 ? /* @__PURE__ */ jsxs74(
8352
8748
  "li",
8353
8749
  {
8354
8750
  className: "ss-g-sl-rung ss-g-sl-rung--mystery",
8355
8751
  "data-testid": "sl-mystery-rung",
8356
8752
  "data-result": revealed ? clientState.isCorrect ? "correct" : "wrong" : void 0,
8357
8753
  children: [
8358
- /* @__PURE__ */ jsx85("span", { className: "ss-g-sl-rank", children: "2" }),
8359
- revealed ? /* @__PURE__ */ jsx85(PlayerAvatar, { name: clientState.revealedRank2.playerName, className: "ss-g-sl-av" }) : /* @__PURE__ */ jsx85(Silhouette, { size: 52, variant: "mystery" }),
8360
- revealed ? /* @__PURE__ */ jsx85(NameStack, { name: clientState.revealedRank2.playerName }) : /* @__PURE__ */ jsx85("span", { className: "ss-g-sl-who", children: t.whoSecond }),
8361
- /* @__PURE__ */ jsx85("span", { className: "ss-g-sl-val ss-g-sl-val--mystery", children: rung.statValue })
8754
+ /* @__PURE__ */ jsx86("span", { className: "ss-g-sl-rank", children: "2" }),
8755
+ revealed ? /* @__PURE__ */ jsx86(PlayerAvatar, { name: clientState.revealedRank2.playerName, className: "ss-g-sl-av" }) : /* @__PURE__ */ jsx86(Silhouette, { size: 52, variant: "mystery" }),
8756
+ revealed ? /* @__PURE__ */ jsx86(NameStack, { name: clientState.revealedRank2.playerName }) : /* @__PURE__ */ jsx86("span", { className: "ss-g-sl-who", children: t.whoSecond }),
8757
+ /* @__PURE__ */ jsx86("span", { className: "ss-g-sl-val ss-g-sl-val--mystery", children: rung.statValue })
8362
8758
  ]
8363
8759
  },
8364
8760
  rung.rank
8365
- ) : /* @__PURE__ */ jsxs73("li", { className: "ss-g-sl-rung", children: [
8366
- /* @__PURE__ */ jsx85("span", { className: "ss-g-sl-rank", children: rung.rank }),
8367
- /* @__PURE__ */ jsx85(PlayerAvatar, { name: rung.playerName ?? "?", className: "ss-g-sl-av" }),
8368
- /* @__PURE__ */ jsx85(NameStack, { name: rung.playerName ?? "?" }),
8369
- /* @__PURE__ */ jsx85("span", { className: "ss-g-sl-val", children: rung.statValue })
8761
+ ) : /* @__PURE__ */ jsxs74("li", { className: "ss-g-sl-rung", children: [
8762
+ /* @__PURE__ */ jsx86("span", { className: "ss-g-sl-rank", children: rung.rank }),
8763
+ /* @__PURE__ */ jsx86(PlayerAvatar, { name: rung.playerName ?? "?", className: "ss-g-sl-av" }),
8764
+ /* @__PURE__ */ jsx86(NameStack, { name: rung.playerName ?? "?" }),
8765
+ /* @__PURE__ */ jsx86("span", { className: "ss-g-sl-val", children: rung.statValue })
8370
8766
  ] }, rung.rank)
8371
8767
  ) }),
8372
- clue && /* @__PURE__ */ jsxs73("p", { className: "ss-g-sl-clue", children: [
8373
- /* @__PURE__ */ jsx85(IconBulb, {}),
8374
- /* @__PURE__ */ jsx85("span", { children: t.clue(clue, config.statLabel) })
8768
+ clue && /* @__PURE__ */ jsxs74("p", { className: "ss-g-sl-clue", children: [
8769
+ /* @__PURE__ */ jsx86(IconBulb, {}),
8770
+ /* @__PURE__ */ jsx86("span", { children: t.clue(clue, config.statLabel) })
8375
8771
  ] }),
8376
- !revealed && /* @__PURE__ */ jsx85("ul", { className: "ss-g-sl-pool", children: pool.map((p) => /* @__PURE__ */ jsx85("li", { children: /* @__PURE__ */ jsxs73(
8772
+ !revealed && /* @__PURE__ */ jsx86("ul", { className: "ss-g-sl-pool", children: pool.map((p) => /* @__PURE__ */ jsx86("li", { children: /* @__PURE__ */ jsxs74(
8377
8773
  "button",
8378
8774
  {
8379
8775
  type: "button",
@@ -8386,13 +8782,13 @@ function StatLadderGame({
8386
8782
  setQuery(p.playerName);
8387
8783
  },
8388
8784
  children: [
8389
- /* @__PURE__ */ jsx85(PlayerAvatar, { name: p.playerName, className: "ss-g-sl-opt-av" }),
8390
- /* @__PURE__ */ jsx85("span", { className: "ss-g-sl-opt-name", children: p.playerName }),
8391
- selectedId === p.playerId && /* @__PURE__ */ jsx85(IconCheck, {})
8785
+ /* @__PURE__ */ jsx86(PlayerAvatar, { name: p.playerName, className: "ss-g-sl-opt-av" }),
8786
+ /* @__PURE__ */ jsx86("span", { className: "ss-g-sl-opt-name", children: p.playerName }),
8787
+ selectedId === p.playerId && /* @__PURE__ */ jsx86(IconCheck, {})
8392
8788
  ]
8393
8789
  }
8394
8790
  ) }, p.playerId)) }),
8395
- revealed && /* @__PURE__ */ jsx85(
8791
+ revealed && /* @__PURE__ */ jsx86(
8396
8792
  ResultCard,
8397
8793
  {
8398
8794
  tone: clientState.isCorrect ? "win" : "lose",
@@ -8403,8 +8799,8 @@ function StatLadderGame({
8403
8799
  }
8404
8800
  )
8405
8801
  ] }),
8406
- !revealed && /* @__PURE__ */ jsx85(FooterBar, { children: /* @__PURE__ */ jsxs73("div", { className: "ss-g-sl-guess", children: [
8407
- /* @__PURE__ */ jsx85(
8802
+ !revealed && /* @__PURE__ */ jsx86(FooterBar, { children: /* @__PURE__ */ jsxs74("div", { className: "ss-g-sl-guess", children: [
8803
+ /* @__PURE__ */ jsx86(
8408
8804
  SearchField,
8409
8805
  {
8410
8806
  id: searchId,
@@ -8419,13 +8815,13 @@ function StatLadderGame({
8419
8815
  disabled: submitting
8420
8816
  }
8421
8817
  ),
8422
- /* @__PURE__ */ jsx85(GameButton, { variant: "primary", disabled: selectedId === null || submitting, onClick: guess, children: t.guess })
8818
+ /* @__PURE__ */ jsx86(GameButton, { variant: "primary", disabled: selectedId === null || submitting, onClick: guess, children: t.guess })
8423
8819
  ] }) })
8424
8820
  ] });
8425
8821
  }
8426
8822
 
8427
8823
  // src/components/games/FanMotmGame.tsx
8428
- import { jsx as jsx86, jsxs as jsxs74 } from "react/jsx-runtime";
8824
+ import { jsx as jsx87, jsxs as jsxs75 } from "react/jsx-runtime";
8429
8825
  function parseClientState10(json) {
8430
8826
  if (!json) return null;
8431
8827
  try {
@@ -8446,20 +8842,20 @@ function FanMotmGame({
8446
8842
  const clientState = parseClientState10(result?.clientStateJson);
8447
8843
  const alreadyVoted = result?.alreadyPlayed === true;
8448
8844
  const pickedId = clientState?.pickedPlayerId ?? null;
8449
- const header = /* @__PURE__ */ jsx86(
8845
+ const header = /* @__PURE__ */ jsx87(
8450
8846
  GameHeader,
8451
8847
  {
8452
8848
  title: t.title,
8453
8849
  eyebrow: t.eyebrow,
8454
- right: alreadyVoted ? /* @__PURE__ */ jsx86(Chip, { variant: "success", icon: /* @__PURE__ */ jsx86(IconCheck, {}), children: t.voted }) : void 0,
8850
+ right: alreadyVoted ? /* @__PURE__ */ jsx87(Chip, { variant: "success", icon: /* @__PURE__ */ jsx87(IconCheck, {}), children: t.voted }) : void 0,
8455
8851
  onBack,
8456
8852
  backLabel: ui.back
8457
8853
  }
8458
8854
  );
8459
8855
  if (!config) {
8460
- return /* @__PURE__ */ jsxs74("div", { className: "ss-g-screen", "data-game": "fan-motm", "data-testid": "game-screen-fan-motm", children: [
8856
+ return /* @__PURE__ */ jsxs75("div", { className: "ss-g-screen", "data-game": "fan-motm", "data-testid": "game-screen-fan-motm", children: [
8461
8857
  header,
8462
- /* @__PURE__ */ jsx86("div", { className: "ss-g-body ss-g-loading", children: ui.games.loading })
8858
+ /* @__PURE__ */ jsx87("div", { className: "ss-g-body ss-g-loading", children: ui.games.loading })
8463
8859
  ] });
8464
8860
  }
8465
8861
  const picked = config.candidates.find((c) => c.playerId === pickedId) ?? null;
@@ -8467,12 +8863,12 @@ function FanMotmGame({
8467
8863
  if (alreadyVoted || submitting) return;
8468
8864
  onSubmit(JSON.stringify({ pickedPlayerId: candidateId }));
8469
8865
  }
8470
- return /* @__PURE__ */ jsxs74("div", { className: "ss-g-screen", "data-game": "fan-motm", "data-testid": "game-screen-fan-motm", children: [
8866
+ return /* @__PURE__ */ jsxs75("div", { className: "ss-g-screen", "data-game": "fan-motm", "data-testid": "game-screen-fan-motm", children: [
8471
8867
  header,
8472
- /* @__PURE__ */ jsxs74("div", { className: "ss-g-body", children: [
8473
- /* @__PURE__ */ jsx86("ul", { className: "ss-g-motm-list", children: config.candidates.map((c) => {
8868
+ /* @__PURE__ */ jsxs75("div", { className: "ss-g-body", children: [
8869
+ /* @__PURE__ */ jsx87("ul", { className: "ss-g-motm-list", children: config.candidates.map((c) => {
8474
8870
  const isVoted = alreadyVoted && pickedId === c.playerId;
8475
- return /* @__PURE__ */ jsx86("li", { children: /* @__PURE__ */ jsxs74(
8871
+ return /* @__PURE__ */ jsx87("li", { children: /* @__PURE__ */ jsxs75(
8476
8872
  "button",
8477
8873
  {
8478
8874
  type: "button",
@@ -8481,24 +8877,24 @@ function FanMotmGame({
8481
8877
  disabled: alreadyVoted || submitting,
8482
8878
  onClick: () => handleVote(c.playerId),
8483
8879
  children: [
8484
- /* @__PURE__ */ jsx86(PlayerAvatar, { name: c.playerName, className: "ss-g-motm-av" }),
8485
- /* @__PURE__ */ jsx86("span", { className: "ss-g-motm-name", children: c.playerName }),
8486
- isVoted && /* @__PURE__ */ jsx86(Chip, { variant: "accent", className: "ss-g-motm-pill", children: t.yourVote })
8880
+ /* @__PURE__ */ jsx87(PlayerAvatar, { name: c.playerName, className: "ss-g-motm-av" }),
8881
+ /* @__PURE__ */ jsx87("span", { className: "ss-g-motm-name", children: c.playerName }),
8882
+ isVoted && /* @__PURE__ */ jsx87(Chip, { variant: "accent", className: "ss-g-motm-pill", children: t.yourVote })
8487
8883
  ]
8488
8884
  }
8489
8885
  ) }, c.playerId);
8490
8886
  }) }),
8491
- alreadyVoted && picked && /* @__PURE__ */ jsx86(ResultCard, { tone: "neutral", title: t.youVoted(picked.playerName), detail: t.thanks, onBack, ui })
8887
+ alreadyVoted && picked && /* @__PURE__ */ jsx87(ResultCard, { tone: "neutral", title: t.youVoted(picked.playerName), detail: t.thanks, onBack, ui })
8492
8888
  ] }),
8493
- /* @__PURE__ */ jsxs74(FooterBar, { children: [
8494
- !alreadyVoted && /* @__PURE__ */ jsx86("p", { className: "ss-g-motm-foot", children: t.tapToVote }),
8495
- /* @__PURE__ */ jsx86("p", { className: "ss-g-motm-fun", children: t.forFun })
8889
+ /* @__PURE__ */ jsxs75(FooterBar, { children: [
8890
+ !alreadyVoted && /* @__PURE__ */ jsx87("p", { className: "ss-g-motm-foot", children: t.tapToVote }),
8891
+ /* @__PURE__ */ jsx87("p", { className: "ss-g-motm-fun", children: t.forFun })
8496
8892
  ] })
8497
8893
  ] });
8498
8894
  }
8499
8895
 
8500
8896
  // src/components/GameScreenHost.tsx
8501
- import { jsx as jsx87 } from "react/jsx-runtime";
8897
+ import { jsx as jsx88 } from "react/jsx-runtime";
8502
8898
  var FIXTURE_GAME_IDS = /* @__PURE__ */ new Set([
8503
8899
  "matchday-predictor",
8504
8900
  "starting-xi",
@@ -8522,8 +8918,8 @@ function GameScreenHost({
8522
8918
  ui
8523
8919
  }) {
8524
8920
  const { gameId, fixtureId, gameDay = "", lockAtUtc = null } = selected;
8525
- const [configJson, setConfigJson] = useState39(null);
8526
- useEffect22(() => {
8921
+ const [configJson, setConfigJson] = useState42(null);
8922
+ useEffect24(() => {
8527
8923
  setConfigJson(null);
8528
8924
  if (!conversation) return;
8529
8925
  let cancelled = false;
@@ -8546,12 +8942,12 @@ function GameScreenHost({
8546
8942
  fixtureId: fixtureId || void 0,
8547
8943
  locale: ui.games.lang
8548
8944
  });
8549
- useEffect22(() => {
8945
+ useEffect24(() => {
8550
8946
  if (conversation) hydrate();
8551
8947
  }, [conversation, gameId]);
8552
- const hydrateRef = useRef19(hydrate);
8948
+ const hydrateRef = useRef20(hydrate);
8553
8949
  hydrateRef.current = hydrate;
8554
- useEffect22(() => {
8950
+ useEffect24(() => {
8555
8951
  if (!FIXTURE_GAME_IDS.has(gameId)) return;
8556
8952
  if (rawStatus !== "pending") return;
8557
8953
  const timerId = setInterval(() => {
@@ -8574,7 +8970,7 @@ function GameScreenHost({
8574
8970
  function renderScreen() {
8575
8971
  switch (gameId) {
8576
8972
  case "mystery-tiger":
8577
- return /* @__PURE__ */ jsx87(
8973
+ return /* @__PURE__ */ jsx88(
8578
8974
  MysteryTigerGame,
8579
8975
  {
8580
8976
  ...sharedProps,
@@ -8582,7 +8978,7 @@ function GameScreenHost({
8582
8978
  }
8583
8979
  );
8584
8980
  case "higher-or-lower":
8585
- return /* @__PURE__ */ jsx87(
8981
+ return /* @__PURE__ */ jsx88(
8586
8982
  HigherOrLowerGame,
8587
8983
  {
8588
8984
  ...sharedProps,
@@ -8590,7 +8986,7 @@ function GameScreenHost({
8590
8986
  }
8591
8987
  );
8592
8988
  case "career-path":
8593
- return /* @__PURE__ */ jsx87(
8989
+ return /* @__PURE__ */ jsx88(
8594
8990
  CareerPathGame,
8595
8991
  {
8596
8992
  ...sharedProps,
@@ -8599,7 +8995,7 @@ function GameScreenHost({
8599
8995
  );
8600
8996
  case "beat-the-grid": {
8601
8997
  const btgConfig = safeParseConfig(configJson);
8602
- return /* @__PURE__ */ jsx87(
8998
+ return /* @__PURE__ */ jsx88(
8603
8999
  BeatTheGridGame,
8604
9000
  {
8605
9001
  ...sharedProps,
@@ -8609,7 +9005,7 @@ function GameScreenHost({
8609
9005
  );
8610
9006
  }
8611
9007
  case "guess-the-xi":
8612
- return /* @__PURE__ */ jsx87(
9008
+ return /* @__PURE__ */ jsx88(
8613
9009
  GuessTheXiGame,
8614
9010
  {
8615
9011
  ...sharedProps,
@@ -8617,7 +9013,7 @@ function GameScreenHost({
8617
9013
  }
8618
9014
  );
8619
9015
  case "daily-quiz":
8620
- return /* @__PURE__ */ jsx87(
9016
+ return /* @__PURE__ */ jsx88(
8621
9017
  DailyQuizGame,
8622
9018
  {
8623
9019
  ...sharedProps,
@@ -8625,7 +9021,7 @@ function GameScreenHost({
8625
9021
  }
8626
9022
  );
8627
9023
  case "matchday-predictor":
8628
- return /* @__PURE__ */ jsx87(
9024
+ return /* @__PURE__ */ jsx88(
8629
9025
  MatchdayPredictorGame,
8630
9026
  {
8631
9027
  ...sharedProps,
@@ -8633,7 +9029,7 @@ function GameScreenHost({
8633
9029
  }
8634
9030
  );
8635
9031
  case "starting-xi":
8636
- return /* @__PURE__ */ jsx87(
9032
+ return /* @__PURE__ */ jsx88(
8637
9033
  StartingXiGame,
8638
9034
  {
8639
9035
  ...sharedProps,
@@ -8641,7 +9037,7 @@ function GameScreenHost({
8641
9037
  }
8642
9038
  );
8643
9039
  case "stat-ladder":
8644
- return /* @__PURE__ */ jsx87(
9040
+ return /* @__PURE__ */ jsx88(
8645
9041
  StatLadderGame,
8646
9042
  {
8647
9043
  ...sharedProps,
@@ -8649,7 +9045,7 @@ function GameScreenHost({
8649
9045
  }
8650
9046
  );
8651
9047
  case "fan-motm":
8652
- return /* @__PURE__ */ jsx87(
9048
+ return /* @__PURE__ */ jsx88(
8653
9049
  FanMotmGame,
8654
9050
  {
8655
9051
  ...sharedProps,
@@ -8657,10 +9053,10 @@ function GameScreenHost({
8657
9053
  }
8658
9054
  );
8659
9055
  default:
8660
- return /* @__PURE__ */ jsx87("div", { className: "ss-g-screen", "data-testid": `game-screen-${gameId}`, children: /* @__PURE__ */ jsx87(GameHeader, { title: gameTitle({ gameId }, ui.games.titles), onBack, backLabel: ui.back }) });
9056
+ return /* @__PURE__ */ jsx88("div", { className: "ss-g-screen", "data-testid": `game-screen-${gameId}`, children: /* @__PURE__ */ jsx88(GameHeader, { title: gameTitle({ gameId }, ui.games.titles), onBack, backLabel: ui.back }) });
8661
9057
  }
8662
9058
  }
8663
- return /* @__PURE__ */ jsx87("div", { className: "ss-w-gscreen", "data-testid": "gscreen", "data-lock-at": lockAtUtc ?? void 0, children: renderScreen() });
9059
+ return /* @__PURE__ */ jsx88("div", { className: "ss-w-gscreen", "data-testid": "gscreen", "data-lock-at": lockAtUtc ?? void 0, children: renderScreen() });
8664
9060
  }
8665
9061
 
8666
9062
  // src/components/games/ui/fonts.ts
@@ -8677,7 +9073,7 @@ function ensureGamesFonts(doc = document) {
8677
9073
  }
8678
9074
 
8679
9075
  // src/components/GamesPanel.tsx
8680
- import { jsx as jsx88 } from "react/jsx-runtime";
9076
+ import { jsx as jsx89 } from "react/jsx-runtime";
8681
9077
  function GamesPanel({
8682
9078
  loggedIn,
8683
9079
  games,
@@ -8686,13 +9082,13 @@ function GamesPanel({
8686
9082
  leaderboard,
8687
9083
  refreshHub
8688
9084
  }) {
8689
- const [selected, setSelected] = useState40(null);
8690
- useEffect23(() => {
9085
+ const [selected, setSelected] = useState43(null);
9086
+ useEffect25(() => {
8691
9087
  ensureGamesFonts();
8692
9088
  }, []);
8693
- if (!loggedIn) return /* @__PURE__ */ jsx88(GamesLoginWall, { ui });
9089
+ if (!loggedIn) return /* @__PURE__ */ jsx89(GamesLoginWall, { ui });
8694
9090
  if (selected !== null) {
8695
- return /* @__PURE__ */ jsx88("div", { className: "ss-w-gscreen-wrap", lang: ui.games.lang, children: /* @__PURE__ */ jsx88(
9091
+ return /* @__PURE__ */ jsx89("div", { className: "ss-w-gscreen-wrap", lang: ui.games.lang, children: /* @__PURE__ */ jsx89(
8696
9092
  GameScreenHost,
8697
9093
  {
8698
9094
  selected,
@@ -8706,7 +9102,7 @@ function GamesPanel({
8706
9102
  }
8707
9103
  ) });
8708
9104
  }
8709
- return /* @__PURE__ */ jsx88("div", { className: "ss-g-hub-wrap", "data-testid": "games-hub", lang: ui.games.lang, children: /* @__PURE__ */ jsx88(
9105
+ return /* @__PURE__ */ jsx89("div", { className: "ss-g-hub-wrap", "data-testid": "games-hub", lang: ui.games.lang, children: /* @__PURE__ */ jsx89(
8710
9106
  GamesHub,
8711
9107
  {
8712
9108
  games,
@@ -8718,10 +9114,10 @@ function GamesPanel({
8718
9114
  }
8719
9115
 
8720
9116
  // src/components/Leaderboard.tsx
8721
- import { useState as useState41 } from "react";
9117
+ import { useState as useState44 } from "react";
8722
9118
 
8723
9119
  // src/components/LeaderboardRow.tsx
8724
- import { jsx as jsx89, jsxs as jsxs75 } from "react/jsx-runtime";
9120
+ import { jsx as jsx90, jsxs as jsxs76 } from "react/jsx-runtime";
8725
9121
  function formatPoints(n) {
8726
9122
  return n.toLocaleString("en");
8727
9123
  }
@@ -8730,14 +9126,14 @@ function LeaderboardWeeklyRow({
8730
9126
  isMe
8731
9127
  }) {
8732
9128
  const rankClass = `ss-w-lb2-rank${row.rank <= 3 ? " ss-w-lb2-rank--top3" : ""}`;
8733
- return /* @__PURE__ */ jsxs75("div", { className: `ss-w-lb2-row${isMe ? " ss-w-lb2-row--you" : ""}`, children: [
8734
- /* @__PURE__ */ jsxs75("span", { className: rankClass, children: [
9129
+ return /* @__PURE__ */ jsxs76("div", { className: `ss-w-lb2-row${isMe ? " ss-w-lb2-row--you" : ""}`, children: [
9130
+ /* @__PURE__ */ jsxs76("span", { className: rankClass, children: [
8735
9131
  "#",
8736
9132
  row.rank
8737
9133
  ] }),
8738
- /* @__PURE__ */ jsx89("span", { className: "ss-w-lb2-handle", children: row.handle }),
8739
- /* @__PURE__ */ jsx89("span", { className: "ss-w-lb2-points", children: formatPoints(row.points) }),
8740
- row.currentStreak > 0 && /* @__PURE__ */ jsxs75("span", { className: "ss-w-lb2-streak", children: [
9134
+ /* @__PURE__ */ jsx90("span", { className: "ss-w-lb2-handle", children: row.handle }),
9135
+ /* @__PURE__ */ jsx90("span", { className: "ss-w-lb2-points", children: formatPoints(row.points) }),
9136
+ row.currentStreak > 0 && /* @__PURE__ */ jsxs76("span", { className: "ss-w-lb2-streak", children: [
8741
9137
  "\u{1F525} ",
8742
9138
  row.currentStreak
8743
9139
  ] })
@@ -8748,18 +9144,18 @@ function LeaderboardAllTimeRow({
8748
9144
  isMe
8749
9145
  }) {
8750
9146
  const rankClass = `ss-w-lb2-rank${row.rank <= 3 ? " ss-w-lb2-rank--top3" : ""}`;
8751
- return /* @__PURE__ */ jsxs75("div", { className: `ss-w-lb2-row${isMe ? " ss-w-lb2-row--you" : ""}`, children: [
8752
- /* @__PURE__ */ jsxs75("span", { className: rankClass, children: [
9147
+ return /* @__PURE__ */ jsxs76("div", { className: `ss-w-lb2-row${isMe ? " ss-w-lb2-row--you" : ""}`, children: [
9148
+ /* @__PURE__ */ jsxs76("span", { className: rankClass, children: [
8753
9149
  "#",
8754
9150
  row.rank
8755
9151
  ] }),
8756
- /* @__PURE__ */ jsx89("span", { className: "ss-w-lb2-handle", children: row.handle }),
8757
- /* @__PURE__ */ jsx89("span", { className: "ss-w-lb2-points", children: formatPoints(row.allTimePoints) })
9152
+ /* @__PURE__ */ jsx90("span", { className: "ss-w-lb2-handle", children: row.handle }),
9153
+ /* @__PURE__ */ jsx90("span", { className: "ss-w-lb2-points", children: formatPoints(row.allTimePoints) })
8758
9154
  ] });
8759
9155
  }
8760
9156
 
8761
9157
  // src/components/LeaderboardEmpty.tsx
8762
- import { jsx as jsx90, jsxs as jsxs76 } from "react/jsx-runtime";
9158
+ import { jsx as jsx91, jsxs as jsxs77 } from "react/jsx-runtime";
8763
9159
  function LeaderboardEmpty({
8764
9160
  segment,
8765
9161
  lastWeek,
@@ -8768,48 +9164,48 @@ function LeaderboardEmpty({
8768
9164
  ui
8769
9165
  }) {
8770
9166
  if (segment === "alltime") {
8771
- return /* @__PURE__ */ jsxs76("div", { className: "ss-w-lb-empty ss-w-lb-empty--alltime", children: [
8772
- /* @__PURE__ */ jsx90("div", { className: "ss-w-lb-empty-icon", "aria-hidden": "true", children: "\u{1F4CA}" }),
8773
- /* @__PURE__ */ jsx90("p", { className: "ss-w-lb-empty-body", children: ui.leaderboardAllTimeEmpty })
9167
+ return /* @__PURE__ */ jsxs77("div", { className: "ss-w-lb-empty ss-w-lb-empty--alltime", children: [
9168
+ /* @__PURE__ */ jsx91("div", { className: "ss-w-lb-empty-icon", "aria-hidden": "true", children: "\u{1F4CA}" }),
9169
+ /* @__PURE__ */ jsx91("p", { className: "ss-w-lb-empty-body", children: ui.leaderboardAllTimeEmpty })
8774
9170
  ] });
8775
9171
  }
8776
9172
  const fresh = lastWeek != null;
8777
9173
  const title = fresh ? ui.leaderboardEmptyFreshTitle : ui.leaderboardEmptyColdTitle;
8778
9174
  const body = fresh ? ui.leaderboardEmptyFreshBody : ui.leaderboardEmptyColdBody;
8779
- return /* @__PURE__ */ jsxs76("div", { className: "ss-w-lb-empty", children: [
8780
- weeklyPrize && /* @__PURE__ */ jsxs76("div", { className: "ss-w-prize", children: [
8781
- /* @__PURE__ */ jsx90("span", { className: "ss-w-prize-icon", "aria-hidden": "true", children: "\u{1F3C6}" }),
8782
- /* @__PURE__ */ jsx90("div", { className: "ss-w-prize-body", children: /* @__PURE__ */ jsx90("span", { className: "ss-w-prize-text", children: weeklyPrize }) })
9175
+ return /* @__PURE__ */ jsxs77("div", { className: "ss-w-lb-empty", children: [
9176
+ weeklyPrize && /* @__PURE__ */ jsxs77("div", { className: "ss-w-prize", children: [
9177
+ /* @__PURE__ */ jsx91("span", { className: "ss-w-prize-icon", "aria-hidden": "true", children: "\u{1F3C6}" }),
9178
+ /* @__PURE__ */ jsx91("div", { className: "ss-w-prize-body", children: /* @__PURE__ */ jsx91("span", { className: "ss-w-prize-text", children: weeklyPrize }) })
8783
9179
  ] }),
8784
- /* @__PURE__ */ jsxs76("div", { className: "ss-w-lb-empty-hero", children: [
8785
- /* @__PURE__ */ jsx90("div", { className: "ss-w-lb-empty-icon", "aria-hidden": "true", children: fresh ? "\u{1F3C6}" : "\u{1F3AE}" }),
8786
- /* @__PURE__ */ jsx90("h4", { className: "ss-w-lb-empty-title", children: title }),
8787
- /* @__PURE__ */ jsx90("p", { className: "ss-w-lb-empty-body", children: body }),
8788
- onPlay && /* @__PURE__ */ jsx90("button", { type: "button", className: "ss-w-lb-empty-cta", onClick: onPlay, children: ui.leaderboardEmptyCta })
9180
+ /* @__PURE__ */ jsxs77("div", { className: "ss-w-lb-empty-hero", children: [
9181
+ /* @__PURE__ */ jsx91("div", { className: "ss-w-lb-empty-icon", "aria-hidden": "true", children: fresh ? "\u{1F3C6}" : "\u{1F3AE}" }),
9182
+ /* @__PURE__ */ jsx91("h4", { className: "ss-w-lb-empty-title", children: title }),
9183
+ /* @__PURE__ */ jsx91("p", { className: "ss-w-lb-empty-body", children: body }),
9184
+ onPlay && /* @__PURE__ */ jsx91("button", { type: "button", className: "ss-w-lb-empty-cta", onClick: onPlay, children: ui.leaderboardEmptyCta })
8789
9185
  ] }),
8790
- fresh && lastWeek && /* @__PURE__ */ jsxs76("div", { className: "ss-w-lb-last", children: [
8791
- /* @__PURE__ */ jsx90("span", { className: "ss-w-lb-last-label", children: ui.leaderboardLastWeekLabel }),
8792
- /* @__PURE__ */ jsx90("span", { className: "ss-w-lb-last-champ", "aria-hidden": "true", children: "\u{1F947}" }),
8793
- /* @__PURE__ */ jsx90("span", { className: "ss-w-lb-last-handle", children: lastWeek.handle }),
8794
- /* @__PURE__ */ jsx90("span", { className: "ss-w-lb-last-points", children: formatPoints(lastWeek.points) })
9186
+ fresh && lastWeek && /* @__PURE__ */ jsxs77("div", { className: "ss-w-lb-last", children: [
9187
+ /* @__PURE__ */ jsx91("span", { className: "ss-w-lb-last-label", children: ui.leaderboardLastWeekLabel }),
9188
+ /* @__PURE__ */ jsx91("span", { className: "ss-w-lb-last-champ", "aria-hidden": "true", children: "\u{1F947}" }),
9189
+ /* @__PURE__ */ jsx91("span", { className: "ss-w-lb-last-handle", children: lastWeek.handle }),
9190
+ /* @__PURE__ */ jsx91("span", { className: "ss-w-lb-last-points", children: formatPoints(lastWeek.points) })
8795
9191
  ] })
8796
9192
  ] });
8797
9193
  }
8798
9194
 
8799
9195
  // src/components/Leaderboard.tsx
8800
- import { Fragment as Fragment20, jsx as jsx91, jsxs as jsxs77 } from "react/jsx-runtime";
9196
+ import { Fragment as Fragment20, jsx as jsx92, jsxs as jsxs78 } from "react/jsx-runtime";
8801
9197
  function Leaderboard({
8802
9198
  data,
8803
9199
  ui,
8804
9200
  onPlay
8805
9201
  }) {
8806
- const [segment, setSegment] = useState41("weekly");
9202
+ const [segment, setSegment] = useState44("weekly");
8807
9203
  const myRow = segment === "weekly" ? data.myWeeklyRow : data.myAllTimeRow;
8808
9204
  const offBoard = myRow !== null && myRow !== void 0 && myRow.rank === -1;
8809
9205
  const isEmpty = segment === "weekly" ? data.weeklyTop.length === 0 : data.allTimeTop.length === 0;
8810
- return /* @__PURE__ */ jsxs77("div", { className: "ss-w-lb2", children: [
8811
- /* @__PURE__ */ jsxs77("div", { className: "ss-w-seg", children: [
8812
- /* @__PURE__ */ jsx91(
9206
+ return /* @__PURE__ */ jsxs78("div", { className: "ss-w-lb2", children: [
9207
+ /* @__PURE__ */ jsxs78("div", { className: "ss-w-seg", children: [
9208
+ /* @__PURE__ */ jsx92(
8813
9209
  "button",
8814
9210
  {
8815
9211
  type: "button",
@@ -8819,7 +9215,7 @@ function Leaderboard({
8819
9215
  children: ui.leaderboardThisWeek
8820
9216
  }
8821
9217
  ),
8822
- /* @__PURE__ */ jsx91(
9218
+ /* @__PURE__ */ jsx92(
8823
9219
  "button",
8824
9220
  {
8825
9221
  type: "button",
@@ -8830,7 +9226,7 @@ function Leaderboard({
8830
9226
  }
8831
9227
  )
8832
9228
  ] }),
8833
- isEmpty ? /* @__PURE__ */ jsx91(
9229
+ isEmpty ? /* @__PURE__ */ jsx92(
8834
9230
  LeaderboardEmpty,
8835
9231
  {
8836
9232
  segment,
@@ -8839,15 +9235,15 @@ function Leaderboard({
8839
9235
  onPlay,
8840
9236
  ui
8841
9237
  }
8842
- ) : /* @__PURE__ */ jsxs77(Fragment20, { children: [
8843
- /* @__PURE__ */ jsx91("div", { className: "ss-w-lb2-rows", children: segment === "weekly" ? data.weeklyTop.map((row) => /* @__PURE__ */ jsx91(
9238
+ ) : /* @__PURE__ */ jsxs78(Fragment20, { children: [
9239
+ /* @__PURE__ */ jsx92("div", { className: "ss-w-lb2-rows", children: segment === "weekly" ? data.weeklyTop.map((row) => /* @__PURE__ */ jsx92(
8844
9240
  LeaderboardWeeklyRow,
8845
9241
  {
8846
9242
  row,
8847
9243
  isMe: row.operatorUserId === data.myWeeklyRow?.operatorUserId
8848
9244
  },
8849
9245
  row.operatorUserId
8850
- )) : data.allTimeTop.map((row) => /* @__PURE__ */ jsx91(
9246
+ )) : data.allTimeTop.map((row) => /* @__PURE__ */ jsx92(
8851
9247
  LeaderboardAllTimeRow,
8852
9248
  {
8853
9249
  row,
@@ -8855,18 +9251,18 @@ function Leaderboard({
8855
9251
  },
8856
9252
  row.operatorUserId
8857
9253
  )) }),
8858
- /* @__PURE__ */ jsx91("div", { className: "ss-w-kitline", children: "\u{1F3BD}" }),
8859
- myRow != null && (offBoard ? /* @__PURE__ */ jsx91("div", { className: "ss-w-lbgap", children: ui.leaderboardOffBoard }) : /* @__PURE__ */ jsxs77("div", { className: "ss-w-lb2-rows", children: [
8860
- segment === "weekly" && data.myWeeklyRow && /* @__PURE__ */ jsx91(LeaderboardWeeklyRow, { row: data.myWeeklyRow, isMe: true }),
8861
- segment === "alltime" && data.myAllTimeRow && /* @__PURE__ */ jsx91(LeaderboardAllTimeRow, { row: data.myAllTimeRow, isMe: true })
9254
+ /* @__PURE__ */ jsx92("div", { className: "ss-w-kitline", children: "\u{1F3BD}" }),
9255
+ myRow != null && (offBoard ? /* @__PURE__ */ jsx92("div", { className: "ss-w-lbgap", children: ui.leaderboardOffBoard }) : /* @__PURE__ */ jsxs78("div", { className: "ss-w-lb2-rows", children: [
9256
+ segment === "weekly" && data.myWeeklyRow && /* @__PURE__ */ jsx92(LeaderboardWeeklyRow, { row: data.myWeeklyRow, isMe: true }),
9257
+ segment === "alltime" && data.myAllTimeRow && /* @__PURE__ */ jsx92(LeaderboardAllTimeRow, { row: data.myAllTimeRow, isMe: true })
8862
9258
  ] })),
8863
- segment === "alltime" && data.myAllTimeRow && !offBoard && /* @__PURE__ */ jsx91("div", { className: "ss-w-lb2-rows", children: /* @__PURE__ */ jsx91("div", { className: "ss-w-lb2-row", children: /* @__PURE__ */ jsx91("span", { className: "ss-w-lb2-handle", children: formatPoints(data.allTimeTop.reduce((s, r) => s + r.allTimePoints, 0)) }) }) })
9259
+ segment === "alltime" && data.myAllTimeRow && !offBoard && /* @__PURE__ */ jsx92("div", { className: "ss-w-lb2-rows", children: /* @__PURE__ */ jsx92("div", { className: "ss-w-lb2-row", children: /* @__PURE__ */ jsx92("span", { className: "ss-w-lb2-handle", children: formatPoints(data.allTimeTop.reduce((s, r) => s + r.allTimePoints, 0)) }) }) })
8864
9260
  ] })
8865
9261
  ] });
8866
9262
  }
8867
9263
 
8868
9264
  // src/components/LeaderboardPanel.tsx
8869
- import { jsx as jsx92 } from "react/jsx-runtime";
9265
+ import { jsx as jsx93 } from "react/jsx-runtime";
8870
9266
  var EMPTY_PAYLOAD = {
8871
9267
  week: "",
8872
9268
  weeklyTop: [],
@@ -8877,19 +9273,19 @@ var EMPTY_PAYLOAD = {
8877
9273
  lastWeek: null
8878
9274
  };
8879
9275
  function LeaderboardPanel({ loggedIn, data, loading, onPlay, ui }) {
8880
- if (!loggedIn) return /* @__PURE__ */ jsx92(GamesLoginWall, { ui });
8881
- if (data === null && loading) return /* @__PURE__ */ jsx92("div", { className: "ss-w-mon-list" });
8882
- return /* @__PURE__ */ jsx92("div", { className: "ss-w-mon-list", children: /* @__PURE__ */ jsx92(Leaderboard, { data: data ?? EMPTY_PAYLOAD, ui, onPlay }) });
9276
+ if (!loggedIn) return /* @__PURE__ */ jsx93(GamesLoginWall, { ui });
9277
+ if (data === null && loading) return /* @__PURE__ */ jsx93("div", { className: "ss-w-mon-list" });
9278
+ return /* @__PURE__ */ jsx93("div", { className: "ss-w-mon-list", children: /* @__PURE__ */ jsx93(Leaderboard, { data: data ?? EMPTY_PAYLOAD, ui, onPlay }) });
8883
9279
  }
8884
9280
 
8885
9281
  // src/components/PresetSpeedDial.tsx
8886
- import { useId as useId9 } from "react";
8887
- import { jsx as jsx93, jsxs as jsxs78 } from "react/jsx-runtime";
9282
+ import { useId as useId10 } from "react";
9283
+ import { jsx as jsx94, jsxs as jsxs79 } from "react/jsx-runtime";
8888
9284
  function PresetSpeedDial({ expanded, showDot, strings, onToggle, onOpen, rootRef, buttonRef }) {
8889
- const pillsId = useId9();
9285
+ const pillsId = useId10();
8890
9286
  const tabIndex = expanded ? 0 : -1;
8891
- return /* @__PURE__ */ jsxs78("div", { ref: rootRef, className: "ss-w-dial", children: [
8892
- /* @__PURE__ */ jsxs78(
9287
+ return /* @__PURE__ */ jsxs79("div", { ref: rootRef, className: "ss-w-dial", children: [
9288
+ /* @__PURE__ */ jsxs79(
8893
9289
  "button",
8894
9290
  {
8895
9291
  ref: buttonRef,
@@ -8900,36 +9296,36 @@ function PresetSpeedDial({ expanded, showDot, strings, onToggle, onOpen, rootRef
8900
9296
  "aria-label": strings.dialName,
8901
9297
  onClick: onToggle,
8902
9298
  children: [
8903
- /* @__PURE__ */ jsx93("span", { className: "ss-w-dial-icon ss-w-dial-icon--open", children: /* @__PURE__ */ jsx93(SlidersIcon, {}) }),
8904
- /* @__PURE__ */ jsx93("span", { className: "ss-w-dial-icon ss-w-dial-icon--close", children: /* @__PURE__ */ jsx93(CloseIcon, {}) }),
8905
- showDot && !expanded ? /* @__PURE__ */ jsx93("span", { className: "ss-w-dial-dot", "aria-hidden": "true" }) : null
9299
+ /* @__PURE__ */ jsx94("span", { className: "ss-w-dial-icon ss-w-dial-icon--open", children: /* @__PURE__ */ jsx94(SlidersIcon, {}) }),
9300
+ /* @__PURE__ */ jsx94("span", { className: "ss-w-dial-icon ss-w-dial-icon--close", children: /* @__PURE__ */ jsx94(CloseIcon, {}) }),
9301
+ showDot && !expanded ? /* @__PURE__ */ jsx94("span", { className: "ss-w-dial-dot", "aria-hidden": "true" }) : null
8906
9302
  ]
8907
9303
  }
8908
9304
  ),
8909
- /* @__PURE__ */ jsxs78("div", { id: pillsId, className: "ss-w-dial-pills", "data-open": expanded ? "" : void 0, children: [
8910
- /* @__PURE__ */ jsxs78("button", { type: "button", className: "ss-w-dial-pill", tabIndex, onClick: () => onOpen("numbers"), children: [
8911
- /* @__PURE__ */ jsx93(SlidersIcon, {}),
8912
- /* @__PURE__ */ jsx93("span", { className: "ss-w-dial-pill-label", children: strings.setNumbers })
9305
+ /* @__PURE__ */ jsxs79("div", { id: pillsId, className: "ss-w-dial-pills", "data-open": expanded ? "" : void 0, children: [
9306
+ /* @__PURE__ */ jsxs79("button", { type: "button", className: "ss-w-dial-pill", tabIndex, onClick: () => onOpen("numbers"), children: [
9307
+ /* @__PURE__ */ jsx94(SlidersIcon, {}),
9308
+ /* @__PURE__ */ jsx94("span", { className: "ss-w-dial-pill-label", children: strings.setNumbers })
8913
9309
  ] }),
8914
- /* @__PURE__ */ jsxs78("button", { type: "button", className: "ss-w-dial-pill", tabIndex, onClick: () => onOpen("combo"), children: [
8915
- /* @__PURE__ */ jsx93(ComboIcon, {}),
8916
- /* @__PURE__ */ jsx93("span", { className: "ss-w-dial-pill-label", children: strings.buildCombo })
9310
+ /* @__PURE__ */ jsxs79("button", { type: "button", className: "ss-w-dial-pill", tabIndex, onClick: () => onOpen("combo"), children: [
9311
+ /* @__PURE__ */ jsx94(ComboIcon, {}),
9312
+ /* @__PURE__ */ jsx94("span", { className: "ss-w-dial-pill-label", children: strings.buildCombo })
8917
9313
  ] })
8918
9314
  ] })
8919
9315
  ] });
8920
9316
  }
8921
9317
 
8922
9318
  // src/components/PresetTools.tsx
8923
- import { Fragment as Fragment21, useEffect as useEffect24, useId as useId10, useRef as useRef20, useState as useState42 } from "react";
8924
- import { Fragment as Fragment22, jsx as jsx94, jsxs as jsxs79 } from "react/jsx-runtime";
9319
+ import { Fragment as Fragment21, useEffect as useEffect26, useId as useId11, useRef as useRef21, useState as useState45 } from "react";
9320
+ import { Fragment as Fragment22, jsx as jsx95, jsxs as jsxs80 } from "react/jsx-runtime";
8925
9321
  var FOCUSABLE = 'button:not([disabled]), [href], input:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
8926
9322
  function PresetToolModal({ title, closeLabel, onClose, children, footer }) {
8927
- const dialogRef = useRef20(null);
8928
- const titleId = useId10();
8929
- useEffect24(() => {
9323
+ const dialogRef = useRef21(null);
9324
+ const titleId = useId11();
9325
+ useEffect26(() => {
8930
9326
  dialogRef.current?.focus();
8931
9327
  }, []);
8932
- useEffect24(() => {
9328
+ useEffect26(() => {
8933
9329
  const onKey = (e) => {
8934
9330
  if (e.key !== "Escape") return;
8935
9331
  e.stopPropagation();
@@ -8959,79 +9355,79 @@ function PresetToolModal({ title, closeLabel, onClose, children, footer }) {
8959
9355
  first.focus();
8960
9356
  }
8961
9357
  };
8962
- return /* @__PURE__ */ jsx94("div", { className: "ss-w-tool-backdrop", children: /* @__PURE__ */ jsxs79("div", { ref: dialogRef, className: "ss-w-tool", role: "dialog", "aria-modal": "true", "aria-labelledby": titleId, tabIndex: -1, onKeyDown: trapTab, children: [
8963
- /* @__PURE__ */ jsxs79("div", { className: "ss-w-tool-head", children: [
8964
- /* @__PURE__ */ jsx94("h2", { id: titleId, className: "ss-w-tool-title", children: title }),
8965
- /* @__PURE__ */ jsx94("button", { type: "button", className: "ss-w-tool-close", "aria-label": closeLabel, onClick: onClose, children: /* @__PURE__ */ jsx94(CloseIcon, {}) })
9358
+ return /* @__PURE__ */ jsx95("div", { className: "ss-w-tool-backdrop", children: /* @__PURE__ */ jsxs80("div", { ref: dialogRef, className: "ss-w-tool", role: "dialog", "aria-modal": "true", "aria-labelledby": titleId, tabIndex: -1, onKeyDown: trapTab, children: [
9359
+ /* @__PURE__ */ jsxs80("div", { className: "ss-w-tool-head", children: [
9360
+ /* @__PURE__ */ jsx95("h2", { id: titleId, className: "ss-w-tool-title", children: title }),
9361
+ /* @__PURE__ */ jsx95("button", { type: "button", className: "ss-w-tool-close", "aria-label": closeLabel, onClick: onClose, children: /* @__PURE__ */ jsx95(CloseIcon, {}) })
8966
9362
  ] }),
8967
- /* @__PURE__ */ jsx94("div", { className: "ss-w-tool-body", children }),
8968
- footer ? /* @__PURE__ */ jsx94("div", { className: "ss-w-tool-foot", children: footer }) : null
9363
+ /* @__PURE__ */ jsx95("div", { className: "ss-w-tool-body", children }),
9364
+ footer ? /* @__PURE__ */ jsx95("div", { className: "ss-w-tool-foot", children: footer }) : null
8969
9365
  ] }) });
8970
9366
  }
8971
9367
  function fillTemplate(template, slots) {
8972
9368
  return template.split(/(\{[a-z]+\})/).filter((part) => part !== "").map((part, i) => {
8973
9369
  const key = /^\{([a-z]+)\}$/.exec(part)?.[1];
8974
- return /* @__PURE__ */ jsx94(Fragment21, { children: key !== void 0 && key in slots ? slots[key] : part }, i);
9370
+ return /* @__PURE__ */ jsx95(Fragment21, { children: key !== void 0 && key in slots ? slots[key] : part }, i);
8975
9371
  });
8976
9372
  }
8977
9373
  function NumberSelect({ current, choices: choices2, label, notToday, lockEmpty = true, onChoose }) {
8978
9374
  const selected = Math.max(0, choices2.findIndex((c) => c.text === current));
8979
- return /* @__PURE__ */ jsxs79("span", { className: "ss-w-tool-num", children: [
8980
- /* @__PURE__ */ jsx94("span", { className: "ss-w-tool-num-size", "aria-hidden": "true", children: current }),
8981
- /* @__PURE__ */ jsx94("select", { className: "ss-w-tool-num-select", "aria-label": label, value: String(selected), onChange: (e) => {
9375
+ return /* @__PURE__ */ jsxs80("span", { className: "ss-w-tool-num", children: [
9376
+ /* @__PURE__ */ jsx95("span", { className: "ss-w-tool-num-size", "aria-hidden": "true", children: current }),
9377
+ /* @__PURE__ */ jsx95("select", { className: "ss-w-tool-num-select", "aria-label": label, value: String(selected), onChange: (e) => {
8982
9378
  const c = choices2[Number(e.target.value)];
8983
9379
  if (c) onChoose(c.value);
8984
- }, children: choices2.map((c, i) => /* @__PURE__ */ jsx94("option", { value: String(i), disabled: lockEmpty && !c.available && i !== selected, children: c.available ? c.text : `${c.text}${notToday}` }, i)) })
9380
+ }, children: choices2.map((c, i) => /* @__PURE__ */ jsx95("option", { value: String(i), disabled: lockEmpty && !c.available && i !== selected, children: c.available ? c.text : `${c.text}${notToday}` }, i)) })
8985
9381
  ] });
8986
9382
  }
8987
9383
  function ChoiceSelect({ currentIdx, sizeLabels, optionLabels, label, onChoose }) {
8988
9384
  const sizeText = sizeLabels[currentIdx] ?? "";
8989
- return /* @__PURE__ */ jsxs79("span", { className: "ss-w-tool-num", children: [
8990
- /* @__PURE__ */ jsx94("span", { className: "ss-w-tool-num-size", "aria-hidden": "true", children: sizeText }),
8991
- /* @__PURE__ */ jsx94("select", { className: "ss-w-tool-num-select", "aria-label": label, value: String(currentIdx), onChange: (e) => onChoose(Number(e.target.value)), children: optionLabels.map((opt, i) => /* @__PURE__ */ jsx94("option", { value: String(i), children: opt }, i)) })
9385
+ return /* @__PURE__ */ jsxs80("span", { className: "ss-w-tool-num", children: [
9386
+ /* @__PURE__ */ jsx95("span", { className: "ss-w-tool-num-size", "aria-hidden": "true", children: sizeText }),
9387
+ /* @__PURE__ */ jsx95("select", { className: "ss-w-tool-num-select", "aria-label": label, value: String(currentIdx), onChange: (e) => onChoose(Number(e.target.value)), children: optionLabels.map((opt, i) => /* @__PURE__ */ jsx95("option", { value: String(i), children: opt }, i)) })
8992
9388
  ] });
8993
9389
  }
8994
9390
  function SendButton({ label, display, disabled, onClick }) {
8995
- return /* @__PURE__ */ jsx94("button", { type: "button", className: "ss-w-tool-send", "aria-label": `${label}: ${display}`, disabled, onClick, children: label });
9391
+ return /* @__PURE__ */ jsx95("button", { type: "button", className: "ss-w-tool-send", "aria-label": `${label}: ${display}`, disabled, onClick, children: label });
8996
9392
  }
8997
9393
  function PickList({ picks, formatKickoff }) {
8998
- return /* @__PURE__ */ jsx94("ul", { className: "ss-w-tool-picks", role: "list", children: picks.map((p) => /* @__PURE__ */ jsxs79("li", { className: "ss-w-tool-pick", children: [
8999
- /* @__PURE__ */ jsxs79("span", { className: "ss-w-tool-pick-match", children: [
9394
+ return /* @__PURE__ */ jsx95("ul", { className: "ss-w-tool-picks", role: "list", children: picks.map((p) => /* @__PURE__ */ jsxs80("li", { className: "ss-w-tool-pick", children: [
9395
+ /* @__PURE__ */ jsxs80("span", { className: "ss-w-tool-pick-match", children: [
9000
9396
  p.homeTeamName,
9001
9397
  " \u2013 ",
9002
9398
  p.awayTeamName
9003
9399
  ] }),
9004
- /* @__PURE__ */ jsxs79("span", { className: "ss-w-tool-pick-sel", children: [
9400
+ /* @__PURE__ */ jsxs80("span", { className: "ss-w-tool-pick-sel", children: [
9005
9401
  p.marketLabel,
9006
9402
  ": ",
9007
9403
  p.selectionLabel,
9008
9404
  p.line ? ` ${p.line}` : ""
9009
9405
  ] }),
9010
- /* @__PURE__ */ jsx94("span", { className: "ss-w-tool-pick-kick", children: formatKickoff(p.kickoffUtc) }),
9011
- /* @__PURE__ */ jsx94("span", { className: "ss-w-tool-pick-price", children: p.price.toFixed(2) })
9406
+ /* @__PURE__ */ jsx95("span", { className: "ss-w-tool-pick-kick", children: formatKickoff(p.kickoffUtc) }),
9407
+ /* @__PURE__ */ jsx95("span", { className: "ss-w-tool-pick-price", children: p.price.toFixed(2) })
9012
9408
  ] }, p.matchOddsId)) });
9013
9409
  }
9014
9410
  function ComboPreview({ cell, formatKickoff }) {
9015
- return /* @__PURE__ */ jsxs79(Fragment22, { children: [
9016
- /* @__PURE__ */ jsx94(PickList, { picks: cell.combo.legs, formatKickoff }),
9017
- /* @__PURE__ */ jsx94("div", { className: "ss-w-tool-math", children: cell.combo.multiplication })
9411
+ return /* @__PURE__ */ jsxs80(Fragment22, { children: [
9412
+ /* @__PURE__ */ jsx95(PickList, { picks: cell.combo.legs, formatKickoff }),
9413
+ /* @__PURE__ */ jsx95("div", { className: "ss-w-tool-math", children: cell.combo.multiplication })
9018
9414
  ] });
9019
9415
  }
9020
9416
  function Unavailable({ text }) {
9021
- return /* @__PURE__ */ jsx94("p", { className: "ss-w-tool-unavailable", children: text });
9417
+ return /* @__PURE__ */ jsx95("p", { className: "ss-w-tool-unavailable", children: text });
9022
9418
  }
9023
9419
  function AskRow({ icon, ask, ready, send }) {
9024
- return /* @__PURE__ */ jsxs79("section", { className: "ss-w-tool-row ss-w-tool-row--ask", children: [
9025
- /* @__PURE__ */ jsx94("span", { className: "ss-w-tool-icon", "aria-hidden": "true", children: icon }),
9026
- /* @__PURE__ */ jsxs79("div", { className: "ss-w-tool-main", children: [
9027
- /* @__PURE__ */ jsx94("p", { className: "ss-w-tool-ask", children: ask }),
9028
- ready ? /* @__PURE__ */ jsx94("span", { className: "ss-w-tool-ready", children: ready }) : null
9420
+ return /* @__PURE__ */ jsxs80("section", { className: "ss-w-tool-row ss-w-tool-row--ask", children: [
9421
+ /* @__PURE__ */ jsx95("span", { className: "ss-w-tool-icon", "aria-hidden": "true", children: icon }),
9422
+ /* @__PURE__ */ jsxs80("div", { className: "ss-w-tool-main", children: [
9423
+ /* @__PURE__ */ jsx95("p", { className: "ss-w-tool-ask", children: ask }),
9424
+ ready ? /* @__PURE__ */ jsx95("span", { className: "ss-w-tool-ready", children: ready }) : null
9029
9425
  ] }),
9030
9426
  send
9031
9427
  ] });
9032
9428
  }
9033
9429
  function RoundSend({ label, display, disabled, onClick }) {
9034
- return /* @__PURE__ */ jsx94("button", { type: "button", className: "ss-w-tool-go", "aria-label": `${label}: ${display}`, disabled, onClick, children: /* @__PURE__ */ jsx94(SendIcon, {}) });
9430
+ return /* @__PURE__ */ jsx95("button", { type: "button", className: "ss-w-tool-go", "aria-label": `${label}: ${display}`, disabled, onClick, children: /* @__PURE__ */ jsx95(SendIcon, {}) });
9035
9431
  }
9036
9432
  var BIG_COMBO = { total: 50, legs: 6 };
9037
9433
  function SetNumbersTool({ grid, strings, streaming, onSend, onClose }) {
@@ -9040,15 +9436,15 @@ function SetNumbersTool({ grid, strings, streaming, onSend, onClose }) {
9040
9436
  const totals = comboTotals(grid);
9041
9437
  const legChoices = comboLegChoices(grid);
9042
9438
  const count = FIXED_SINGLES_COUNT;
9043
- const [maxPrice, setMaxPrice] = useState42(() => startSingles(grid.singles, limits, START.maxPrice, count));
9044
- const [minPrice, setMinPrice] = useState42(() => startSingles(grid.singlesFrom, floors, START.minPrice, count));
9045
- const [start] = useState42(() => startCombo(grid, totals, legChoices, START.comboTotal, START.comboLegs));
9046
- const [total, setTotal] = useState42(start.total);
9047
- const [legs, setLegs] = useState42(start.legs);
9048
- const [bigStart] = useState42(() => startCombo(grid, totals, legChoices, BIG_COMBO.total, BIG_COMBO.legs));
9049
- const [bigTotal, setBigTotal] = useState42(bigStart.total);
9050
- const [bigLegs, setBigLegs] = useState42(bigStart.legs);
9051
- const [announcement, setAnnouncement] = useState42("");
9439
+ const [maxPrice, setMaxPrice] = useState45(() => startSingles(grid.singles, limits, START.maxPrice, count));
9440
+ const [minPrice, setMinPrice] = useState45(() => startSingles(grid.singlesFrom, floors, START.minPrice, count));
9441
+ const [start] = useState45(() => startCombo(grid, totals, legChoices, START.comboTotal, START.comboLegs));
9442
+ const [total, setTotal] = useState45(start.total);
9443
+ const [legs, setLegs] = useState45(start.legs);
9444
+ const [bigStart] = useState45(() => startCombo(grid, totals, legChoices, BIG_COMBO.total, BIG_COMBO.legs));
9445
+ const [bigTotal, setBigTotal] = useState45(bigStart.total);
9446
+ const [bigLegs, setBigLegs] = useState45(bigStart.legs);
9447
+ const [announcement, setAnnouncement] = useState45("");
9052
9448
  const maxCell = findSingles(grid.singles, maxPrice, count);
9053
9449
  const minCell = findSingles(grid.singlesFrom, minPrice, count);
9054
9450
  const comboCell = findCombo(grid, total, legs);
@@ -9092,95 +9488,95 @@ function SetNumbersTool({ grid, strings, streaming, onSend, onClose }) {
9092
9488
  const totalChoices = totals.map((v) => ({ value: v, text: v.toFixed(1), available: legChoices.some((n) => !!findCombo(grid, v, n)) }));
9093
9489
  const legChoicesFor = (t) => legChoices.map((n) => ({ value: n, text: String(n), available: !!findCombo(grid, t, n) }));
9094
9490
  const markets = grid.markets ?? [];
9095
- const [marketIdx, setMarketIdx] = useState42(0);
9491
+ const [marketIdx, setMarketIdx] = useState45(0);
9096
9492
  const marketCell = markets[marketIdx] ?? null;
9097
9493
  const marketLabels = markets.map((c) => strings.marketShort(c.marketDeveloperName, c.marketLabel, c.selectionLabel ?? null));
9098
9494
  const singlesReady = (cell) => cell ? strings.readyCount(cell.picks.length) : strings.unavailable;
9099
9495
  const comboReady = (cell) => cell ? strings.readyAt(cell.combo.total) : strings.unavailable;
9100
- return /* @__PURE__ */ jsxs79(PresetToolModal, { title: strings.setNumbers, closeLabel: strings.close, onClose, children: [
9101
- /* @__PURE__ */ jsx94(
9496
+ return /* @__PURE__ */ jsxs80(PresetToolModal, { title: strings.setNumbers, closeLabel: strings.close, onClose, children: [
9497
+ /* @__PURE__ */ jsx95(
9102
9498
  AskRow,
9103
9499
  {
9104
9500
  icon: "\u{1F3AF}",
9105
9501
  ask: fillTemplate(strings.maxPriceRow, {
9106
9502
  count: String(count),
9107
- price: /* @__PURE__ */ jsx94(NumberSelect, { current: maxPrice.toFixed(2), choices: maxChoices, label: strings.maxPriceName, notToday: strings.notToday, onChoose: chooseMax })
9503
+ price: /* @__PURE__ */ jsx95(NumberSelect, { current: maxPrice.toFixed(2), choices: maxChoices, label: strings.maxPriceName, notToday: strings.notToday, onChoose: chooseMax })
9108
9504
  }),
9109
9505
  ready: singlesReady(maxCell),
9110
- send: /* @__PURE__ */ jsx94(RoundSend, { label: strings.send, display: strings.maxPriceDisplay(count, maxPrice), disabled: !maxCell || streaming, onClick: () => {
9506
+ send: /* @__PURE__ */ jsx95(RoundSend, { label: strings.send, display: strings.maxPriceDisplay(count, maxPrice), disabled: !maxCell || streaming, onClick: () => {
9111
9507
  if (maxCell) onSend(maxPriceAsk(maxCell, strings));
9112
9508
  } })
9113
9509
  }
9114
9510
  ),
9115
- /* @__PURE__ */ jsx94(
9511
+ /* @__PURE__ */ jsx95(
9116
9512
  AskRow,
9117
9513
  {
9118
9514
  icon: "\u{1F4C8}",
9119
9515
  ask: fillTemplate(strings.minPriceRow, {
9120
9516
  count: String(count),
9121
- price: /* @__PURE__ */ jsx94(NumberSelect, { current: minPrice.toFixed(2), choices: minChoices, label: strings.minPriceName, notToday: strings.notToday, onChoose: chooseMin })
9517
+ price: /* @__PURE__ */ jsx95(NumberSelect, { current: minPrice.toFixed(2), choices: minChoices, label: strings.minPriceName, notToday: strings.notToday, onChoose: chooseMin })
9122
9518
  }),
9123
9519
  ready: singlesReady(minCell),
9124
- send: /* @__PURE__ */ jsx94(RoundSend, { label: strings.send, display: strings.minPriceDisplay(count, minPrice), disabled: !minCell || streaming, onClick: () => {
9520
+ send: /* @__PURE__ */ jsx95(RoundSend, { label: strings.send, display: strings.minPriceDisplay(count, minPrice), disabled: !minCell || streaming, onClick: () => {
9125
9521
  if (minCell) onSend(minPriceAsk(minCell, strings));
9126
9522
  } })
9127
9523
  }
9128
9524
  ),
9129
- /* @__PURE__ */ jsx94(
9525
+ /* @__PURE__ */ jsx95(
9130
9526
  AskRow,
9131
9527
  {
9132
9528
  icon: "\u2728",
9133
9529
  ask: fillTemplate(strings.comboRow, {
9134
- legs: /* @__PURE__ */ jsx94(NumberSelect, { current: String(legs), choices: legChoicesFor(total), label: strings.matchesLabel, notToday: strings.notToday, lockEmpty: false, onChoose: chooseLegs }),
9135
- total: /* @__PURE__ */ jsx94(NumberSelect, { current: total.toFixed(1), choices: totalChoices, label: strings.totalLabel, notToday: strings.notToday, onChoose: chooseTotal })
9530
+ legs: /* @__PURE__ */ jsx95(NumberSelect, { current: String(legs), choices: legChoicesFor(total), label: strings.matchesLabel, notToday: strings.notToday, lockEmpty: false, onChoose: chooseLegs }),
9531
+ total: /* @__PURE__ */ jsx95(NumberSelect, { current: total.toFixed(1), choices: totalChoices, label: strings.totalLabel, notToday: strings.notToday, onChoose: chooseTotal })
9136
9532
  }),
9137
9533
  ready: comboReady(comboCell),
9138
- send: /* @__PURE__ */ jsx94(RoundSend, { label: strings.send, display: strings.comboDisplay(legs, total), disabled: !comboCell || streaming, onClick: () => {
9534
+ send: /* @__PURE__ */ jsx95(RoundSend, { label: strings.send, display: strings.comboDisplay(legs, total), disabled: !comboCell || streaming, onClick: () => {
9139
9535
  if (comboCell) onSend(comboAsk(comboCell, strings));
9140
9536
  } })
9141
9537
  }
9142
9538
  ),
9143
- /* @__PURE__ */ jsx94(
9539
+ /* @__PURE__ */ jsx95(
9144
9540
  AskRow,
9145
9541
  {
9146
9542
  icon: "\u{1F3C6}",
9147
9543
  ask: fillTemplate(strings.bigComboRow, {
9148
- legs: /* @__PURE__ */ jsx94(NumberSelect, { current: String(bigLegs), choices: legChoicesFor(bigTotal), label: strings.matchesLabel, notToday: strings.notToday, lockEmpty: false, onChoose: chooseBigLegs }),
9149
- total: /* @__PURE__ */ jsx94(NumberSelect, { current: bigTotal.toFixed(1), choices: totalChoices, label: strings.totalLabel, notToday: strings.notToday, onChoose: chooseBigTotal })
9544
+ legs: /* @__PURE__ */ jsx95(NumberSelect, { current: String(bigLegs), choices: legChoicesFor(bigTotal), label: strings.matchesLabel, notToday: strings.notToday, lockEmpty: false, onChoose: chooseBigLegs }),
9545
+ total: /* @__PURE__ */ jsx95(NumberSelect, { current: bigTotal.toFixed(1), choices: totalChoices, label: strings.totalLabel, notToday: strings.notToday, onChoose: chooseBigTotal })
9150
9546
  }),
9151
9547
  ready: comboReady(bigCell),
9152
- send: /* @__PURE__ */ jsx94(RoundSend, { label: strings.send, display: strings.comboDisplay(bigLegs, bigTotal), disabled: !bigCell || streaming, onClick: () => {
9548
+ send: /* @__PURE__ */ jsx95(RoundSend, { label: strings.send, display: strings.comboDisplay(bigLegs, bigTotal), disabled: !bigCell || streaming, onClick: () => {
9153
9549
  if (bigCell) onSend(comboAsk(bigCell, strings));
9154
9550
  } })
9155
9551
  }
9156
9552
  ),
9157
- markets.length > 0 && /* @__PURE__ */ jsx94(
9553
+ markets.length > 0 && /* @__PURE__ */ jsx95(
9158
9554
  AskRow,
9159
9555
  {
9160
9556
  icon: "\u26BD",
9161
9557
  ask: fillTemplate(strings.marketRow, {
9162
- market: /* @__PURE__ */ jsx94(ChoiceSelect, { currentIdx: marketIdx, sizeLabels: marketLabels, optionLabels: marketLabels, label: strings.marketName, onChoose: chooseMarket })
9558
+ market: /* @__PURE__ */ jsx95(ChoiceSelect, { currentIdx: marketIdx, sizeLabels: marketLabels, optionLabels: marketLabels, label: strings.marketName, onChoose: chooseMarket })
9163
9559
  }),
9164
9560
  ready: marketCell ? strings.readyCount(marketCell.count) : null,
9165
- send: /* @__PURE__ */ jsx94(RoundSend, { label: strings.send, display: marketCell ? marketDisplay(marketCell, strings) : "", disabled: !marketCell || streaming, onClick: () => {
9561
+ send: /* @__PURE__ */ jsx95(RoundSend, { label: strings.send, display: marketCell ? marketDisplay(marketCell, strings) : "", disabled: !marketCell || streaming, onClick: () => {
9166
9562
  if (marketCell) onSend(marketAsk(marketCell, strings));
9167
9563
  } })
9168
9564
  }
9169
9565
  ),
9170
- /* @__PURE__ */ jsx94("p", { className: "ss-w-vh", "aria-live": "polite", children: announcement })
9566
+ /* @__PURE__ */ jsx95("p", { className: "ss-w-vh", "aria-live": "polite", children: announcement })
9171
9567
  ] });
9172
9568
  }
9173
9569
  function BuildComboTool({ grid, strings, streaming, formatKickoff, initialTotal, initialLegs, onSend, onClose }) {
9174
9570
  const totals = comboTotals(grid);
9175
9571
  const legChoices = comboLegChoices(grid);
9176
- const [start] = useState42(() => initialTotal === void 0 ? startCombo(grid, totals, legChoices, START.comboTotal, START.comboLegs) : null);
9177
- const [total, setTotal] = useState42(() => initialTotal !== void 0 ? nearest(totals, initialTotal) : start.total);
9178
- const [legs, setLegs] = useState42(() => {
9572
+ const [start] = useState45(() => initialTotal === void 0 ? startCombo(grid, totals, legChoices, START.comboTotal, START.comboLegs) : null);
9573
+ const [total, setTotal] = useState45(() => initialTotal !== void 0 ? nearest(totals, initialTotal) : start.total);
9574
+ const [legs, setLegs] = useState45(() => {
9179
9575
  if (initialTotal === void 0) return initialLegs !== void 0 ? clampLegs(legChoices, initialLegs) : start.legs;
9180
9576
  const from = initialLegs !== void 0 ? clampLegs(legChoices, initialLegs) : startValue(legChoices, START.comboLegs);
9181
9577
  return legsForTotal(grid, nearest(totals, initialTotal), from);
9182
9578
  });
9183
- const [announcement, setAnnouncement] = useState42("");
9579
+ const [announcement, setAnnouncement] = useState45("");
9184
9580
  const cell = findCombo(grid, total, legs);
9185
9581
  const minLegs = legChoices[0] ?? legs;
9186
9582
  const maxLegs = legChoices[legChoices.length - 1] ?? legs;
@@ -9191,29 +9587,29 @@ function BuildComboTool({ grid, strings, streaming, formatKickoff, initialTotal,
9191
9587
  const d = strings.comboDisplay(nextLegs, nextTotal);
9192
9588
  setAnnouncement(findCombo(grid, nextTotal, nextLegs) ? d : `${d}. ${strings.unavailable}`);
9193
9589
  };
9194
- const footer = /* @__PURE__ */ jsx94(SendButton, { label: strings.send, display, disabled: !cell || streaming, onClick: () => {
9590
+ const footer = /* @__PURE__ */ jsx95(SendButton, { label: strings.send, display, disabled: !cell || streaming, onClick: () => {
9195
9591
  if (cell) onSend(comboAsk(cell, strings));
9196
9592
  } });
9197
- return /* @__PURE__ */ jsxs79(PresetToolModal, { title: strings.buildCombo, closeLabel: strings.close, onClose, footer, children: [
9198
- /* @__PURE__ */ jsxs79("div", { className: "ss-w-tool-section", role: "group", "aria-label": strings.totalLabel, children: [
9199
- /* @__PURE__ */ jsx94("span", { className: "ss-w-tool-label", "aria-hidden": "true", children: strings.totalLabel }),
9200
- /* @__PURE__ */ jsx94("div", { className: "ss-w-tool-chips", children: totals.map((t) => /* @__PURE__ */ jsx94("button", { type: "button", className: "ss-w-tool-chip", "aria-pressed": samePrice(t, total), onClick: () => choose(t, samePrice(t, total) ? legs : legsForTotal(grid, t, legs)), children: t.toFixed(1) }, t)) })
9593
+ return /* @__PURE__ */ jsxs80(PresetToolModal, { title: strings.buildCombo, closeLabel: strings.close, onClose, footer, children: [
9594
+ /* @__PURE__ */ jsxs80("div", { className: "ss-w-tool-section", role: "group", "aria-label": strings.totalLabel, children: [
9595
+ /* @__PURE__ */ jsx95("span", { className: "ss-w-tool-label", "aria-hidden": "true", children: strings.totalLabel }),
9596
+ /* @__PURE__ */ jsx95("div", { className: "ss-w-tool-chips", children: totals.map((t) => /* @__PURE__ */ jsx95("button", { type: "button", className: "ss-w-tool-chip", "aria-pressed": samePrice(t, total), onClick: () => choose(t, samePrice(t, total) ? legs : legsForTotal(grid, t, legs)), children: t.toFixed(1) }, t)) })
9201
9597
  ] }),
9202
- /* @__PURE__ */ jsxs79("div", { className: "ss-w-tool-section", role: "group", "aria-label": strings.matchesLabel, children: [
9203
- /* @__PURE__ */ jsx94("span", { className: "ss-w-tool-label", "aria-hidden": "true", children: strings.matchesLabel }),
9204
- /* @__PURE__ */ jsxs79("div", { className: "ss-w-tool-stepper", children: [
9205
- /* @__PURE__ */ jsx94("button", { type: "button", className: "ss-w-tool-step", "aria-label": strings.fewerMatches, disabled: legs <= minLegs, onClick: () => choose(total, legs - 1), children: "\u2212" }),
9206
- /* @__PURE__ */ jsx94("span", { className: "ss-w-tool-count", children: legs }),
9207
- /* @__PURE__ */ jsx94("button", { type: "button", className: "ss-w-tool-step", "aria-label": strings.moreMatches, disabled: legs >= maxLegs, onClick: () => choose(total, legs + 1), children: "+" })
9598
+ /* @__PURE__ */ jsxs80("div", { className: "ss-w-tool-section", role: "group", "aria-label": strings.matchesLabel, children: [
9599
+ /* @__PURE__ */ jsx95("span", { className: "ss-w-tool-label", "aria-hidden": "true", children: strings.matchesLabel }),
9600
+ /* @__PURE__ */ jsxs80("div", { className: "ss-w-tool-stepper", children: [
9601
+ /* @__PURE__ */ jsx95("button", { type: "button", className: "ss-w-tool-step", "aria-label": strings.fewerMatches, disabled: legs <= minLegs, onClick: () => choose(total, legs - 1), children: "\u2212" }),
9602
+ /* @__PURE__ */ jsx95("span", { className: "ss-w-tool-count", children: legs }),
9603
+ /* @__PURE__ */ jsx95("button", { type: "button", className: "ss-w-tool-step", "aria-label": strings.moreMatches, disabled: legs >= maxLegs, onClick: () => choose(total, legs + 1), children: "+" })
9208
9604
  ] })
9209
9605
  ] }),
9210
- cell ? /* @__PURE__ */ jsx94(ComboPreview, { cell, formatKickoff }) : /* @__PURE__ */ jsx94(Unavailable, { text: strings.unavailable }),
9211
- /* @__PURE__ */ jsx94("p", { className: "ss-w-vh", "aria-live": "polite", children: announcement })
9606
+ cell ? /* @__PURE__ */ jsx95(ComboPreview, { cell, formatKickoff }) : /* @__PURE__ */ jsx95(Unavailable, { text: strings.unavailable }),
9607
+ /* @__PURE__ */ jsx95("p", { className: "ss-w-vh", "aria-live": "polite", children: announcement })
9212
9608
  ] });
9213
9609
  }
9214
9610
 
9215
9611
  // src/usePresetDial.ts
9216
- import { useCallback as useCallback14, useEffect as useEffect25, useRef as useRef21, useState as useState43 } from "react";
9612
+ import { useCallback as useCallback15, useEffect as useEffect27, useRef as useRef22, useState as useState46 } from "react";
9217
9613
  function sendInFlight(messages, isStreaming) {
9218
9614
  const last = messages[messages.length - 1];
9219
9615
  return isStreaming && !!last && last.role === "assistant" && !last.done && !last.isGreeting;
@@ -9227,25 +9623,25 @@ function lastUserId(messages) {
9227
9623
  }
9228
9624
  var SCROLL_KEYS = /* @__PURE__ */ new Set(["ArrowUp", "ArrowDown", "PageUp", "PageDown", "Home", "End", " "]);
9229
9625
  function usePresetDial({ layerRef, dialRef, dialButtonRef, messages, isStreaming, activeTab }) {
9230
- const [expanded, setExpanded] = useState43(() => !sendInFlight(messages, isStreaming));
9231
- const fold = useCallback14(() => setExpanded(false), []);
9232
- const toggle = useCallback14(() => setExpanded((e) => !e), []);
9626
+ const [expanded, setExpanded] = useState46(() => !sendInFlight(messages, isStreaming));
9627
+ const fold = useCallback15(() => setExpanded(false), []);
9628
+ const toggle = useCallback15(() => setExpanded((e) => !e), []);
9233
9629
  const currentUserId = lastUserId(messages);
9234
- const userIdRef = useRef21(currentUserId);
9235
- useEffect25(() => {
9630
+ const userIdRef = useRef22(currentUserId);
9631
+ useEffect27(() => {
9236
9632
  if (currentUserId === userIdRef.current) return;
9237
9633
  userIdRef.current = currentUserId;
9238
9634
  setExpanded(false);
9239
9635
  }, [currentUserId]);
9240
- const tabRef = useRef21(activeTab);
9241
- useEffect25(() => {
9636
+ const tabRef = useRef22(activeTab);
9637
+ useEffect27(() => {
9242
9638
  if (activeTab === tabRef.current) return;
9243
9639
  tabRef.current = activeTab;
9244
9640
  setExpanded(false);
9245
9641
  }, [activeTab]);
9246
- const expandedRef = useRef21(expanded);
9642
+ const expandedRef = useRef22(expanded);
9247
9643
  expandedRef.current = expanded;
9248
- useEffect25(() => {
9644
+ useEffect27(() => {
9249
9645
  const onEscape = (e) => {
9250
9646
  const dial = dialRef.current;
9251
9647
  if (e.key !== "Escape" || !dial || !e.composedPath().includes(dial)) return;
@@ -9258,7 +9654,7 @@ function usePresetDial({ layerRef, dialRef, dialButtonRef, messages, isStreaming
9258
9654
  window.addEventListener("keydown", onEscape, true);
9259
9655
  return () => window.removeEventListener("keydown", onEscape, true);
9260
9656
  }, [dialRef, dialButtonRef]);
9261
- useEffect25(() => {
9657
+ useEffect27(() => {
9262
9658
  if (!expanded) return;
9263
9659
  const layer = layerRef.current;
9264
9660
  const inDial = (e) => {
@@ -9310,11 +9706,11 @@ function markToolSeen() {
9310
9706
  }
9311
9707
 
9312
9708
  // src/components/ChatPanel.tsx
9313
- import { jsx as jsx95, jsxs as jsxs80 } from "react/jsx-runtime";
9709
+ import { Fragment as Fragment23, jsx as jsx96, jsxs as jsxs81 } from "react/jsx-runtime";
9314
9710
  var FULLSCREEN_QUERY = "(max-width: 639px)";
9315
9711
  function useIsModal() {
9316
- const [modal, setModal] = useState44(false);
9317
- useEffect26(() => {
9712
+ const [modal, setModal] = useState47(false);
9713
+ useEffect28(() => {
9318
9714
  if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
9319
9715
  const mql = window.matchMedia(FULLSCREEN_QUERY);
9320
9716
  const sync = () => setModal(mql.matches);
@@ -9328,7 +9724,7 @@ var HIDDEN_LAYER_STYLE = { position: "absolute", inset: 0, visibility: "hidden",
9328
9724
  function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, gamesResult, leaderboardResult, loggedIn, conversation, presetGrid }) {
9329
9725
  const { state, close, stop, send, reset } = controller;
9330
9726
  const isModal = useIsModal();
9331
- useEffect26(() => {
9727
+ useEffect28(() => {
9332
9728
  const onKey = (e) => {
9333
9729
  if (e.key === "Escape") close();
9334
9730
  };
@@ -9336,6 +9732,7 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
9336
9732
  return () => window.removeEventListener("keydown", onKey);
9337
9733
  }, [close]);
9338
9734
  const handleSend = (text) => {
9735
+ typedSendRef.current = true;
9339
9736
  monitor?.setActiveTab("chat");
9340
9737
  send(text);
9341
9738
  };
@@ -9343,17 +9740,19 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
9343
9740
  monitor?.setActiveTab("chat");
9344
9741
  send(text, { grounding });
9345
9742
  };
9346
- useEffect26(() => {
9743
+ useEffect28(() => {
9347
9744
  if (monitor && monitor.activeTab !== "chat" && state.isStreaming) monitor.markChatActivity();
9348
9745
  }, [monitor, state.isStreaming, state.messages.length]);
9349
9746
  const onChatTab = !monitor || monitor.activeTab === "chat";
9350
- const layerRef = useRef22(null);
9351
- const dialRef = useRef22(null);
9352
- const dialButtonRef = useRef22(null);
9353
- const inputRef = useRef22(null);
9354
- const focusAfterCloseRef = useRef22(null);
9355
- const [tool, setTool] = useState44(null);
9356
- const [toolSeen, setToolSeen] = useState44(readToolSeen);
9747
+ const layerRef = useRef23(null);
9748
+ const dialRef = useRef23(null);
9749
+ const dialButtonRef = useRef23(null);
9750
+ const inputRef = useRef23(null);
9751
+ const limitRef = useRef23(null);
9752
+ const typedSendRef = useRef23(false);
9753
+ const focusAfterCloseRef = useRef23(null);
9754
+ const [tool, setTool] = useState47(null);
9755
+ const [toolSeen, setToolSeen] = useState47(readToolSeen);
9357
9756
  const dial = usePresetDial({
9358
9757
  layerRef,
9359
9758
  dialRef,
@@ -9363,46 +9762,55 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
9363
9762
  activeTab: monitor?.activeTab ?? "chat"
9364
9763
  });
9365
9764
  const { fold } = dial;
9366
- const showDial = !!presetGrid && onChatTab && !tool;
9367
- const openTool = useCallback15((next) => {
9765
+ const paused = isPaused(state.limit);
9766
+ const showDial = !!presetGrid && onChatTab && !tool && !paused;
9767
+ useEffect28(() => {
9768
+ if (paused) setTool(null);
9769
+ }, [paused]);
9770
+ useEffect28(() => {
9771
+ if (!paused) return;
9772
+ if (typedSendRef.current) limitRef.current?.focus();
9773
+ typedSendRef.current = false;
9774
+ }, [paused]);
9775
+ const openTool = useCallback16((next) => {
9368
9776
  fold();
9369
9777
  markToolSeen();
9370
9778
  setToolSeen(true);
9371
9779
  setTool(next);
9372
9780
  }, [fold]);
9373
- const onPill = useCallback15((kind) => openTool(kind === "numbers" ? { kind: "numbers" } : { kind: "combo" }), [openTool]);
9374
- const toolsValue = useMemo4(
9375
- () => presetGrid ? { openBuilder: (total, legs) => openTool({ kind: "combo", total, legs }), changeLabel: ui.presets.changeCombo } : null,
9376
- [presetGrid, openTool, ui.presets.changeCombo]
9781
+ const onPill = useCallback16((kind) => openTool(kind === "numbers" ? { kind: "numbers" } : { kind: "combo" }), [openTool]);
9782
+ const toolsValue = useMemo5(
9783
+ () => presetGrid && !paused ? { openBuilder: (total, legs) => openTool({ kind: "combo", total, legs }), changeLabel: ui.presets.changeCombo } : null,
9784
+ [presetGrid, paused, openTool, ui.presets.changeCombo]
9377
9785
  );
9378
- const closeTool = useCallback15(() => {
9786
+ const closeTool = useCallback16(() => {
9379
9787
  focusAfterCloseRef.current = "dial";
9380
9788
  setTool(null);
9381
9789
  }, []);
9382
- const sendAsk = useCallback15((ask) => {
9790
+ const sendAsk = useCallback16((ask) => {
9383
9791
  focusAfterCloseRef.current = "composer";
9384
9792
  setTool(null);
9385
9793
  monitor?.setActiveTab("chat");
9386
9794
  send(ask.message, { displayText: ask.displayText, preset: ask.preset });
9387
9795
  }, [monitor, send]);
9388
- const formatKickoff = useCallback15((kickoffUtc) => {
9796
+ const formatKickoff = useCallback16((kickoffUtc) => {
9389
9797
  const k = ui.bettingKickoff(kickoffUtc);
9390
9798
  return `${k.dayLabel} ${k.time}`;
9391
9799
  }, [ui]);
9392
- useEffect26(() => {
9800
+ useEffect28(() => {
9393
9801
  if (tool) return;
9394
9802
  const target = focusAfterCloseRef.current;
9395
9803
  focusAfterCloseRef.current = null;
9396
9804
  if (target === "dial") dialButtonRef.current?.focus();
9397
9805
  else if (target === "composer") inputRef.current?.focus();
9398
9806
  }, [tool]);
9399
- useEffect26(() => {
9807
+ useEffect28(() => {
9400
9808
  if (!tool || onChatTab && presetGrid) return;
9401
9809
  focusAfterCloseRef.current = "composer";
9402
9810
  setTool(null);
9403
9811
  }, [tool, onChatTab, presetGrid]);
9404
- return /* @__PURE__ */ jsxs80("div", { className: "ss-w-panel", role: "dialog", "aria-modal": isModal, "aria-label": ui.chatDialogLabel, children: [
9405
- /* @__PURE__ */ jsx95(
9812
+ return /* @__PURE__ */ jsxs81("div", { className: "ss-w-panel", role: "dialog", "aria-modal": isModal, "aria-label": ui.chatDialogLabel, children: [
9813
+ /* @__PURE__ */ jsx96(
9406
9814
  ChatHeader,
9407
9815
  {
9408
9816
  onClose: close,
@@ -9415,7 +9823,7 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
9415
9823
  moreOptionsLabel: ui.moreOptions
9416
9824
  }
9417
9825
  ),
9418
- monitor && /* @__PURE__ */ jsx95(
9826
+ monitor && /* @__PURE__ */ jsx96(
9419
9827
  TabBar,
9420
9828
  {
9421
9829
  monitor,
@@ -9427,9 +9835,9 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
9427
9835
  gamesEnabled: gamesResult?.enabled ?? false
9428
9836
  }
9429
9837
  ),
9430
- /* @__PURE__ */ jsxs80("div", { ref: layerRef, className: "ss-w-chat-layer", "data-dial": presetGrid ? "" : void 0, style: onChatTab ? void 0 : HIDDEN_LAYER_STYLE, children: [
9431
- /* @__PURE__ */ jsx95(PresetToolsContext.Provider, { value: toolsValue, children: /* @__PURE__ */ jsx95(MessageList, { controller, ui, slip, onDashboardTap, monitor }) }),
9432
- showDial ? /* @__PURE__ */ jsx95(
9838
+ /* @__PURE__ */ jsxs81("div", { ref: layerRef, className: "ss-w-chat-layer", "data-dial": presetGrid ? "" : void 0, style: onChatTab ? void 0 : HIDDEN_LAYER_STYLE, children: [
9839
+ /* @__PURE__ */ jsx96(PresetToolsContext.Provider, { value: toolsValue, children: /* @__PURE__ */ jsx96(MessageList, { controller, ui, slip, onDashboardTap, monitor }) }),
9840
+ showDial ? /* @__PURE__ */ jsx96(
9433
9841
  PresetSpeedDial,
9434
9842
  {
9435
9843
  expanded: dial.expanded,
@@ -9441,12 +9849,12 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
9441
9849
  buttonRef: dialButtonRef
9442
9850
  }
9443
9851
  ) : null,
9444
- tool && presetGrid && onChatTab ? tool.kind === "numbers" ? /* @__PURE__ */ jsx95(SetNumbersTool, { grid: presetGrid, strings: ui.presets, streaming: state.isStreaming, onSend: sendAsk, onClose: closeTool }) : /* @__PURE__ */ jsx95(BuildComboTool, { grid: presetGrid, strings: ui.presets, streaming: state.isStreaming, formatKickoff, initialTotal: tool.total, initialLegs: tool.legs, onSend: sendAsk, onClose: closeTool }) : null
9852
+ tool && presetGrid && onChatTab && !paused ? tool.kind === "numbers" ? /* @__PURE__ */ jsx96(SetNumbersTool, { grid: presetGrid, strings: ui.presets, streaming: state.isStreaming, onSend: sendAsk, onClose: closeTool }) : /* @__PURE__ */ jsx96(BuildComboTool, { grid: presetGrid, strings: ui.presets, streaming: state.isStreaming, formatKickoff, initialTotal: tool.total, initialLegs: tool.legs, onSend: sendAsk, onClose: closeTool }) : null
9445
9853
  ] }),
9446
- monitor && discovery && monitor.activeTab === "today" && /* @__PURE__ */ jsx95(TodayPanel, { discovery, ui, monitor }),
9447
- monitor && monitor.activeTab === "following" && /* @__PURE__ */ jsx95(MatchesPanel, { monitor, ui, slip, onAsk: handleAsk }),
9448
- monitor && monitor.activeTab === "odds" && /* @__PURE__ */ jsx95(OddsPanel, { monitor, ui, slip }),
9449
- monitor && monitor.activeTab === "games" && gamesResult && /* @__PURE__ */ jsx95(
9854
+ monitor && discovery && monitor.activeTab === "today" && /* @__PURE__ */ jsx96(TodayPanel, { discovery, ui, monitor }),
9855
+ monitor && monitor.activeTab === "following" && /* @__PURE__ */ jsx96(MatchesPanel, { monitor, ui, slip, onAsk: paused ? void 0 : handleAsk }),
9856
+ monitor && monitor.activeTab === "odds" && /* @__PURE__ */ jsx96(OddsPanel, { monitor, ui, slip }),
9857
+ monitor && monitor.activeTab === "games" && gamesResult && /* @__PURE__ */ jsx96(
9450
9858
  GamesPanel,
9451
9859
  {
9452
9860
  loggedIn: !!loggedIn,
@@ -9460,7 +9868,7 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
9460
9868
  }
9461
9869
  }
9462
9870
  ),
9463
- monitor && monitor.activeTab === "leaderboard" && leaderboardResult && /* @__PURE__ */ jsx95(
9871
+ monitor && monitor.activeTab === "leaderboard" && leaderboardResult && /* @__PURE__ */ jsx96(
9464
9872
  LeaderboardPanel,
9465
9873
  {
9466
9874
  loggedIn: !!loggedIn,
@@ -9470,27 +9878,30 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
9470
9878
  ui
9471
9879
  }
9472
9880
  ),
9473
- (!monitor || monitor.activeTab !== "games" && monitor.activeTab !== "leaderboard") && /* @__PURE__ */ jsx95(
9474
- ChatInput,
9475
- {
9476
- ref: inputRef,
9477
- placeholder: ui.placeholder,
9478
- streaming: state.isStreaming,
9479
- onSend: handleSend,
9480
- onStop: stop,
9481
- stopLabel: ui.stopResponse,
9482
- sendLabel: ui.sendMessage,
9483
- disabled: !!tool,
9484
- onType: fold
9485
- }
9486
- )
9881
+ (!monitor || monitor.activeTab !== "games" && monitor.activeTab !== "leaderboard") && /* @__PURE__ */ jsxs81(Fragment23, { children: [
9882
+ /* @__PURE__ */ jsx96("div", { ref: limitRef, className: "ss-w-limit", role: "status", tabIndex: -1, children: state.limit ? limitText(state.limit, ui) : null }),
9883
+ paused ? null : /* @__PURE__ */ jsx96(
9884
+ ChatInput,
9885
+ {
9886
+ ref: inputRef,
9887
+ placeholder: ui.placeholder,
9888
+ streaming: state.isStreaming,
9889
+ onSend: handleSend,
9890
+ onStop: stop,
9891
+ stopLabel: ui.stopResponse,
9892
+ sendLabel: ui.sendMessage,
9893
+ disabled: !!tool,
9894
+ onType: fold
9895
+ }
9896
+ )
9897
+ ] })
9487
9898
  ] });
9488
9899
  }
9489
9900
 
9490
9901
  // src/components/HostEventsProvider.tsx
9491
- import { jsx as jsx96 } from "react/jsx-runtime";
9902
+ import { jsx as jsx97 } from "react/jsx-runtime";
9492
9903
  function HostEventsProvider({ value, children }) {
9493
- return /* @__PURE__ */ jsx96(SlipStateContext.Provider, { value: value.slipState, children });
9904
+ return /* @__PURE__ */ jsx97(SlipStateContext.Provider, { value: value.slipState, children });
9494
9905
  }
9495
9906
 
9496
9907
  // src/styles/css.generated.ts
@@ -10081,6 +10492,10 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
10081
10492
 
10082
10493
  /* input */
10083
10494
  .ss-w-input { display: flex; align-items: flex-end; gap: 8px; padding: 10px 12px; border-top: 1px solid var(--ss-w-line); }
10495
+ .ss-w-limit { padding: 10px 12px; border-top: 1px solid var(--ss-w-line); font-size: 13px; line-height: 1.4; color: var(--ss-w-ink); overflow-wrap: anywhere; }
10496
+ .ss-w-limit:empty { padding: 0; border-top: 0; }
10497
+ .ss-w-limit:focus { outline: none; }
10498
+ .ss-w-limit:not(:empty) + .ss-w-input { border-top: none; }
10084
10499
  .ss-w-textarea { flex: 1; resize: none; border: 1px solid var(--ss-w-line); border-radius: 12px; padding: 8px 10px; font: inherit; color: inherit; background: var(--ss-w-panel); max-height: 96px; }
10085
10500
  .ss-w-textarea:disabled { opacity: .55; cursor: not-allowed; }
10086
10501
  /* iOS Safari zooms the page when a focused field's font-size is < 16px. Bump it
@@ -10679,14 +11094,60 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
10679
11094
  .ss-w-sec-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--ss-w-neg); flex: none; }
10680
11095
  .ss-w-today-live { display: flex; flex-direction: column; gap: 2px; }
10681
11096
 
10682
- .ss-w-grp { border: 1px solid var(--ss-w-line); border-radius: 12px; overflow: hidden; }
10683
- .ss-w-grp-head { display: flex; align-items: center; gap: 8px; width: 100%; padding: 8px 11px; background: var(--ss-w-bubble); border: none; font: inherit; color: var(--ss-w-ink); cursor: pointer; text-align: left; }
10684
- .ss-w-grp-head:focus-visible { outline: 2px solid var(--ss-w-accent); outline-offset: -2px; }
10685
- .ss-w-grp-chev { color: var(--ss-w-faint); font-size: 10px; flex: none; }
10686
- .ss-w-grp-name { font-size: 12px; font-weight: 700; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
10687
- .ss-w-grp-country { font-weight: 600; color: var(--ss-w-faint); }
10688
- .ss-w-grp-count { margin-left: auto; flex: none; font-size: 10.5px; font-weight: 700; color: var(--ss-w-faint); background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); border-radius: 999px; padding: 1px 7px; font-variant-numeric: tabular-nums; }
10689
- .ss-w-grp-body { display: flex; flex-direction: column; padding: 2px 11px 6px; }
11097
+ /* Today tab root (Task 7): position: relative so the grid's own star/unstar toast (absolute,
11098
+ top-centre) anchors here rather than to some unrelated positioned ancestor. */
11099
+ /* Non-scrolling anchor for .ss-w-today-toast (position: absolute; top: 0): .ss-w-mon-list below is
11100
+ the overflow-y: auto scroller, so a toast parented to IT would scroll out of view with the
11101
+ content that moved it. This wrapper sits outside that scroller, inside .ss-w-panel's fixed-size
11102
+ flex column, so top: 0 always lands at the visible top of the Today tab. min-height: 0 is
11103
+ required: without it this flex item defaults to min-height: auto (its content height), .ss-w-panel's
11104
+ overflow: hidden then clips it, and .ss-w-mon-list inside never gets a bounded height to scroll within. */
11105
+ .ss-w-today-root { position: relative; flex: 1; min-height: 0; display: flex; flex-direction: column; }
11106
+
11107
+ /* Section header for "Your leagues"/"Top leagues"/"All leagues" (Task 7) -- same visual
11108
+ treatment as .ss-w-sec-head (the live-band header), kept as a separate class so a kept test
11109
+ asserting .ss-w-sec-head is absent when nothing is live cannot see this header too. */
11110
+ .ss-w-today-sec { display: flex; align-items: center; gap: 7px; padding: 2px 2px 0; font-size: 10px; font-weight: 800; letter-spacing: .09em; text-transform: uppercase; color: var(--ss-w-faint); }
11111
+ .ss-w-today-sec::after { content: ""; flex: 1; height: 1px; background: var(--ss-w-line); }
11112
+ .ss-w-today-sec-sub { text-transform: none; letter-spacing: normal; font-weight: 600; }
11113
+ .ss-w-today-tiles { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
11114
+ .ss-w-today-empty { font-size: 12px; color: var(--ss-w-faint); padding: 10px 2px; }
11115
+
11116
+ /* League tile (Task 5): a flat row (crest + name as the open target, star as a separate sibling
11117
+ button) rather than a disclosure header -- opening is Task 6's LeagueDetail, not an inline
11118
+ expansion. Same border/radius language .ss-w-grp used to carry, before Task 7 deleted it. */
11119
+ .ss-w-today-tile { display: flex; align-items: center; gap: 6px; border: 1px solid var(--ss-w-line); border-radius: 12px; overflow: hidden; background: var(--ss-w-bubble); }
11120
+ .ss-w-today-tile-body { flex: 1; min-width: 0; display: flex; align-items: center; gap: 8px; padding: 8px 9px; background: none; border: none; font: inherit; color: var(--ss-w-ink); cursor: pointer; text-align: left; }
11121
+ .ss-w-today-tile-body:focus-visible { outline: 2px solid var(--ss-w-accent); outline-offset: -2px; }
11122
+ .ss-w-today-tile-name { font-size: 12px; font-weight: 700; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
11123
+ .ss-w-today-tile-country { font-weight: 600; color: var(--ss-w-faint); }
11124
+ .ss-w-today-tile-star { flex: none; display: flex; align-items: center; justify-content: center; width: 32px; height: 32px; margin: 0 6px; background: none; border: none; border-radius: 8px; color: var(--ss-w-faint); cursor: pointer; }
11125
+ .ss-w-today-tile-star:focus-visible { outline: 2px solid var(--ss-w-accent); outline-offset: -2px; }
11126
+ .ss-w-today-tile-star[aria-pressed="true"] { color: var(--ss-w-accent); }
11127
+ .ss-w-today-tile-star:disabled { cursor: default; opacity: .4; }
11128
+ .ss-w-today-tile-star svg { width: 18px; height: 18px; }
11129
+
11130
+ /* League detail (Task 6): the drill-in view opened from a tile. Its header star is always
11131
+ enabled (spec \xA73/\xA77's one exception to the tile rule), so it carries no :disabled styling. */
11132
+ .ss-w-today-detail { position: relative; display: flex; flex-direction: column; gap: 10px; }
11133
+ .ss-w-today-detail-head { display: flex; align-items: center; gap: 8px; }
11134
+ .ss-w-today-detail-back { flex: none; display: flex; align-items: center; justify-content: center; width: 28px; height: 28px; background: none; border: none; border-radius: 8px; color: var(--ss-w-ink); cursor: pointer; transform: scaleX(-1); }
11135
+ .ss-w-today-detail-back:focus-visible { outline: 2px solid var(--ss-w-accent); outline-offset: -2px; }
11136
+ .ss-w-today-detail-name { flex: 1; min-width: 0; font-size: 13px; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
11137
+ .ss-w-today-detail-star { flex: none; display: flex; align-items: center; justify-content: center; width: 32px; height: 32px; background: none; border: none; border-radius: 8px; color: var(--ss-w-faint); cursor: pointer; }
11138
+ .ss-w-today-detail-star:focus-visible { outline: 2px solid var(--ss-w-accent); outline-offset: -2px; }
11139
+ .ss-w-today-detail-star[aria-pressed="true"] { color: var(--ss-w-accent); }
11140
+ .ss-w-today-detail-star svg { width: 18px; height: 18px; }
11141
+ .ss-w-today-detail-nav { display: flex; align-items: center; justify-content: center; gap: 10px; }
11142
+ .ss-w-today-detail-prev, .ss-w-today-detail-next { flex: none; display: flex; align-items: center; justify-content: center; width: 26px; height: 26px; background: none; border: none; border-radius: 8px; color: var(--ss-w-faint); cursor: pointer; }
11143
+ .ss-w-today-detail-prev:focus-visible, .ss-w-today-detail-next:focus-visible { outline: 2px solid var(--ss-w-accent); outline-offset: -2px; }
11144
+ .ss-w-today-detail-prev { transform: scaleX(-1); }
11145
+ .ss-w-today-detail-pos { font-size: 10.5px; font-weight: 700; color: var(--ss-w-faint); font-variant-numeric: tabular-nums; }
11146
+ .ss-w-today-detail-body { display: flex; flex-direction: column; }
11147
+ .ss-w-today-detail-count { align-self: flex-end; flex: none; font-size: 10.5px; font-weight: 700; color: var(--ss-w-faint); background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); border-radius: 999px; padding: 1px 7px; font-variant-numeric: tabular-nums; margin-bottom: 4px; }
11148
+ /* aria-live status region, not a modal -- pointer-events: none so the header/nav above stay
11149
+ clickable while it is showing. */
11150
+ .ss-w-today-toast { position: absolute; top: 0; left: 50%; transform: translateX(-50%); z-index: 1; pointer-events: none; width: max-content; max-width: 220px; font-size: 11px; font-weight: 560; color: var(--ss-w-accent); background: color-mix(in srgb, var(--ss-w-accent) 14%, var(--ss-w-panel)); border: 1px solid color-mix(in srgb, var(--ss-w-accent) 30%, var(--ss-w-line)); border-radius: 10px; padding: 5px 10px; box-shadow: 0 4px 14px rgba(0,0,0,.14); }
10690
11151
 
10691
11152
  .ss-w-drow { display: grid; grid-template-columns: 42px minmax(0,1fr) 22px; align-items: center; gap: 9px; padding: 7px 0; border-bottom: 1px solid var(--ss-w-line); }
10692
11153
  .ss-w-drow:last-child { border-bottom: none; }
@@ -11172,7 +11633,7 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
11172
11633
  `;
11173
11634
 
11174
11635
  // src/StatsWidget.tsx
11175
- import { jsx as jsx97 } from "react/jsx-runtime";
11636
+ import { jsx as jsx98 } from "react/jsx-runtime";
11176
11637
  function buildClient(props) {
11177
11638
  try {
11178
11639
  if ("client" in props && props.client) {
@@ -11197,24 +11658,24 @@ function injectStyles(root) {
11197
11658
  function StatsWidget(props) {
11198
11659
  const injectedClient = "client" in props ? props.client : void 0;
11199
11660
  const cfg = props.config;
11200
- const built = useMemo5(() => buildClient(props), [injectedClient, cfg?.operatorId, cfg?.publicKey, cfg?.baseUrl]);
11201
- const logger = useMemo5(
11661
+ const built = useMemo6(() => buildClient(props), [injectedClient, cfg?.operatorId, cfg?.publicKey, cfg?.baseUrl]);
11662
+ const logger = useMemo6(
11202
11663
  () => built ? built.client.createEventLogger({
11203
11664
  operatorUserId: cfg?.userContext?.operatorUserId,
11204
11665
  anonymousUserId: cfg?.userContext?.anonymousUserId
11205
11666
  }) : null,
11206
11667
  [built?.client]
11207
11668
  );
11208
- const ui = useMemo5(() => normalizeUi(props.config ?? { operatorId: "", publicKey: "" }), [props.config]);
11209
- const rootRef = useRef23(null);
11210
- const introDoneRef = useRef23(false);
11211
- const markIntroDone = useCallback16(() => {
11669
+ const ui = useMemo6(() => normalizeUi(props.config ?? { operatorId: "", publicKey: "" }), [props.config]);
11670
+ const rootRef = useRef24(null);
11671
+ const introDoneRef = useRef24(false);
11672
+ const markIntroDone = useCallback17(() => {
11212
11673
  introDoneRef.current = true;
11213
11674
  }, []);
11214
11675
  const convStorageKey = `ss-w-conv:${cfg?.operatorId ?? ""}:${cfg?.userContext?.operatorUserId ?? "anon"}`;
11215
11676
  const controller = useChatStream(built?.conversation ?? emptyConversation(), ui.starters, built ? ui.greetingMessage : void 0, convStorageKey);
11216
- const [hasToday, setHasToday] = useState45(false);
11217
- const liveCardWatches = useMemo5(() => {
11677
+ const [hasToday, setHasToday] = useState48(false);
11678
+ const liveCardWatches = useMemo6(() => {
11218
11679
  const seen = /* @__PURE__ */ new Set();
11219
11680
  const out = [];
11220
11681
  for (const msg of controller.state.messages) {
@@ -11236,31 +11697,40 @@ function StatsWidget(props) {
11236
11697
  hasToday,
11237
11698
  watches: liveCardWatches
11238
11699
  });
11239
- const getSchedule = useCallback16(
11240
- (localDate, utcOffsetMinutes) => built ? built.conversation.getSchedule(localDate, utcOffsetMinutes) : Promise.resolve(null),
11241
- [built]
11700
+ const operatorUserId = cfg?.userContext?.operatorUserId;
11701
+ const anonymousUserId = cfg?.userContext?.anonymousUserId;
11702
+ const getSchedule = useCallback17(
11703
+ (localDate, utcOffsetMinutes) => built ? built.conversation.getSchedule(localDate, utcOffsetMinutes, operatorUserId, anonymousUserId) : Promise.resolve(null),
11704
+ [built, operatorUserId, anonymousUserId]
11705
+ );
11706
+ const postLeagueStar = useCallback17(
11707
+ (competitionId, starred) => built ? built.conversation.starLeague(competitionId, starred, operatorUserId, anonymousUserId) : Promise.resolve(null),
11708
+ [built, operatorUserId, anonymousUserId]
11242
11709
  );
11243
- const getStates = useCallback16(
11710
+ const getStates = useCallback17(
11244
11711
  (matchIds) => built ? built.conversation.getStates(matchIds) : Promise.resolve(null),
11245
11712
  [built]
11246
11713
  );
11247
- const pinnedMatchIds = useMemo5(
11714
+ const pinnedMatchIds = useMemo6(
11248
11715
  () => monitor.pins.filter((p) => p.kind === "match").map((p) => p.matchId),
11249
11716
  [monitor.pins]
11250
11717
  );
11251
11718
  const discovery = useMatchDiscovery({
11252
11719
  getSchedule,
11253
11720
  getStates,
11721
+ postLeagueStar,
11254
11722
  operatorId: cfg?.operatorId ?? "",
11723
+ operatorUserId,
11724
+ anonymousUserId,
11255
11725
  isOpen: controller.state.isOpen,
11256
11726
  pinnedMatchIds
11257
11727
  });
11258
11728
  const todayHasContent = visibleGroupsOf(discovery.groups, discovery.states).length > 0;
11259
- useEffect27(() => {
11729
+ useEffect29(() => {
11260
11730
  setHasToday(todayHasContent);
11261
11731
  }, [todayHasContent]);
11262
- const prevLiveSnapshotRef = useRef23(monitor.snapshot);
11263
- useEffect27(() => {
11732
+ const prevLiveSnapshotRef = useRef24(monitor.snapshot);
11733
+ useEffect29(() => {
11264
11734
  const snap = monitor.snapshot;
11265
11735
  if (!snap || snap === prevLiveSnapshotRef.current) return;
11266
11736
  prevLiveSnapshotRef.current = snap;
@@ -11296,14 +11766,14 @@ function StatsWidget(props) {
11296
11766
  }, [monitor.snapshot]);
11297
11767
  const gamesResult = useGames(built?.conversation ?? null, { activeTab: monitor.activeTab });
11298
11768
  const leaderboardResult = useLeaderboard(built?.conversation ?? null, { activeTab: monitor.activeTab });
11299
- const getPricePresets = useCallback16(
11769
+ const getPricePresets = useCallback17(
11300
11770
  (locale2) => built ? built.conversation.getPricePresets(locale2, { pool: "open" }) : Promise.resolve(null),
11301
11771
  [built]
11302
11772
  );
11303
11773
  const presetGrid = usePresetGrid({ getPricePresets, isOpen: controller.state.isOpen, locale: ui.presets.lang });
11304
11774
  const markTodayActivity = monitor.markTodayActivity;
11305
- const prevLiveCountRef = useRef23(0);
11306
- useEffect27(() => {
11775
+ const prevLiveCountRef = useRef24(0);
11776
+ useEffect29(() => {
11307
11777
  const rose = prevLiveCountRef.current === 0 && discovery.liveCount > 0;
11308
11778
  prevLiveCountRef.current = discovery.liveCount;
11309
11779
  if (rose) markTodayActivity();
@@ -11317,7 +11787,7 @@ function StatsWidget(props) {
11317
11787
  closePanel: controller.close
11318
11788
  });
11319
11789
  const markAdded = hostEvents.markAdded;
11320
- const slip = useMemo5(
11790
+ const slip = useMemo6(
11321
11791
  () => {
11322
11792
  const handler = props.config?.onAddToSlip;
11323
11793
  return {
@@ -11336,7 +11806,7 @@ function StatsWidget(props) {
11336
11806
  },
11337
11807
  [props.config?.onAddToSlip, controller.state.conversationId, markAdded]
11338
11808
  );
11339
- const onDashboardTap = useMemo5(
11809
+ const onDashboardTap = useMemo6(
11340
11810
  () => built ? createDashboardTapSignal((input) => built.conversation.sendSignal(input), logger) : void 0,
11341
11811
  [built, logger]
11342
11812
  );
@@ -11352,14 +11822,12 @@ function StatsWidget(props) {
11352
11822
  log: logger
11353
11823
  })
11354
11824
  }));
11355
- const operatorUserId = cfg?.userContext?.operatorUserId;
11356
- const anonymousUserId = cfg?.userContext?.anonymousUserId;
11357
11825
  const conversationId = controller.state.conversationId ?? void 0;
11358
- useEffect27(() => {
11826
+ useEffect29(() => {
11359
11827
  if (!logger) return;
11360
11828
  logger.setIdentity({ operatorUserId, anonymousUserId, conversationId });
11361
11829
  }, [logger, operatorUserId, anonymousUserId, conversationId]);
11362
- useEffect27(() => {
11830
+ useEffect29(() => {
11363
11831
  if (!logger) return;
11364
11832
  logger.resume();
11365
11833
  const onHide = () => {
@@ -11377,14 +11845,14 @@ function StatsWidget(props) {
11377
11845
  logger.dispose();
11378
11846
  };
11379
11847
  }, [logger]);
11380
- useEffect27(() => {
11848
+ useEffect29(() => {
11381
11849
  if (!built || !ui.injectStyles) return;
11382
11850
  const node = rootRef.current?.getRootNode();
11383
11851
  if (node) injectStyles(node);
11384
11852
  }, [built, ui.injectStyles]);
11385
11853
  if (!built) return null;
11386
11854
  const attrs = themeAttrs(ui);
11387
- return /* @__PURE__ */ jsx97(EventLogContext.Provider, { value: logger, children: /* @__PURE__ */ jsx97(HostEventsProvider, { value: hostEvents, children: /* @__PURE__ */ jsx97("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__ */ jsx97(
11855
+ return /* @__PURE__ */ jsx98(EventLogContext.Provider, { value: logger, children: /* @__PURE__ */ jsx98(HostEventsProvider, { value: hostEvents, children: /* @__PURE__ */ jsx98("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__ */ jsx98(
11388
11856
  ChatPanel,
11389
11857
  {
11390
11858
  controller,
@@ -11399,7 +11867,7 @@ function StatsWidget(props) {
11399
11867
  conversation: built?.conversation ?? null,
11400
11868
  presetGrid
11401
11869
  }
11402
- ) : /* @__PURE__ */ jsx97(
11870
+ ) : /* @__PURE__ */ jsx98(
11403
11871
  ChatFab,
11404
11872
  {
11405
11873
  label: ui.launcherLabel,