@sensiblestats/widget-react 0.81.0 → 0.81.1

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 useCallback17, useEffect as useEffect29, useMemo as useMemo6, useRef as useRef24, useState as useState48 } from "react";
2
+ import { useCallback as useCallback18, useEffect as useEffect29, useMemo as useMemo6, useRef as useRef25, useState as useState48 } from "react";
3
3
  import { StatsWidgetClient } from "@sensiblestats/widget-sdk";
4
4
 
5
5
  // src/kickoff.ts
@@ -120,6 +120,7 @@ var STRINGS = {
120
120
  allLeagues: "All leagues",
121
121
  searchLeaguesPlaceholder: "Search leagues or teams",
122
122
  noLeagueResults: "No league or team matches that search.",
123
+ clearSearchLabel: "Clear search",
123
124
  starOnLabel: "Add to Your leagues",
124
125
  starOffLabel: "Remove from Your leagues",
125
126
  starredToast: "Added to Your leagues.",
@@ -485,6 +486,7 @@ var STRINGS = {
485
486
  allLeagues: "T\xFCm ligler",
486
487
  searchLeaguesPlaceholder: "Lig veya tak\u0131m ara",
487
488
  noLeagueResults: "Aramana uyan lig veya tak\u0131m yok.",
489
+ clearSearchLabel: "Aramay\u0131 temizle",
488
490
  starOnLabel: "Liglerine ekle",
489
491
  starOffLabel: "Liglerinden \xE7\u0131kar",
490
492
  starredToast: "Liglerin b\xF6l\xFCm\xFCne eklendi.",
@@ -847,6 +849,7 @@ function normalizeUi(cfg) {
847
849
  allLeagues: strings.allLeagues,
848
850
  searchLeaguesPlaceholder: strings.searchLeaguesPlaceholder,
849
851
  noLeagueResults: strings.noLeagueResults,
852
+ clearSearchLabel: strings.clearSearchLabel,
850
853
  starOnLabel: strings.starOnLabel,
851
854
  starOffLabel: strings.starOffLabel,
852
855
  starredToast: strings.starredToast,
@@ -3411,7 +3414,7 @@ function ChatFab({ label, greeting, popupText, logoUrl, onOpen, onDismissPopup,
3411
3414
  }
3412
3415
 
3413
3416
  // src/components/ChatPanel.tsx
3414
- import { useCallback as useCallback16, useEffect as useEffect28, useMemo as useMemo5, useRef as useRef23, useState as useState47 } from "react";
3417
+ import { useCallback as useCallback17, useEffect as useEffect28, useMemo as useMemo5, useRef as useRef24, useState as useState47 } from "react";
3415
3418
 
3416
3419
  // src/components/ChatHeader.tsx
3417
3420
  import { useEffect as useEffect12, useRef as useRef12, useState as useState10 } from "react";
@@ -3816,7 +3819,8 @@ function PinToggle({ pin, monitor, ui, market }) {
3816
3819
  const key = pinKey(pin);
3817
3820
  const pinned = monitor.isPinned(key);
3818
3821
  const labels = pin.kind === "match" ? { pin: ui.matchPinLabel, unpin: ui.matchUnpinLabel } : { pin: ui.pinLabel, unpin: ui.unpinLabel };
3819
- const onClick = () => {
3822
+ const onClick = (e) => {
3823
+ e.stopPropagation();
3820
3824
  if (pin.kind === "match" && !monitor.isPinned(key)) {
3821
3825
  if (monitor.pinMatch({ matchId: pin.matchId, marketDeveloperName: market }) === "added") {
3822
3826
  log?.log({ name: "pin_add", entityType: "match", entityId: String(pin.matchId), marketDeveloperName: pin.marketDeveloperName });
@@ -6148,6 +6152,9 @@ function LeagueDetail({ group, position, states, stale, ui, monitor, starTap, on
6148
6152
  ] });
6149
6153
  }
6150
6154
 
6155
+ // src/components/games/ui/SearchField.tsx
6156
+ import { useCallback as useCallback14, useRef as useRef18 } from "react";
6157
+
6151
6158
  // src/components/games/ui/icons.tsx
6152
6159
  import { jsx as jsx58 } from "react/jsx-runtime";
6153
6160
  var svg = (size, children, fill = false) => /* @__PURE__ */ jsx58(
@@ -6184,7 +6191,13 @@ var IconFlame = ({ size = 16 }) => svg(size, /* @__PURE__ */ jsx58("path", { d:
6184
6191
 
6185
6192
  // src/components/games/ui/SearchField.tsx
6186
6193
  import { jsx as jsx59, jsxs as jsxs53 } from "react/jsx-runtime";
6187
- function SearchField({ id, label, labelHidden = false, placeholder, value, onChange, disabled, inputRef, onKeyDown }) {
6194
+ function SearchField({ id, label, labelHidden = false, placeholder, value, onChange, disabled, inputRef, onKeyDown, clearLabel }) {
6195
+ const localRef = useRef18(null);
6196
+ const setInputRef = useCallback14((node) => {
6197
+ localRef.current = node;
6198
+ if (typeof inputRef === "function") inputRef(node);
6199
+ else if (inputRef) inputRef.current = node;
6200
+ }, [inputRef]);
6188
6201
  return /* @__PURE__ */ jsxs53("div", { className: "ss-g-search", children: [
6189
6202
  /* @__PURE__ */ jsx59("label", { htmlFor: id, className: labelHidden ? "ss-g-sr" : "ss-g-search-label", children: label }),
6190
6203
  /* @__PURE__ */ jsxs53("div", { className: "ss-g-search-box", children: [
@@ -6193,7 +6206,7 @@ function SearchField({ id, label, labelHidden = false, placeholder, value, onCha
6193
6206
  "input",
6194
6207
  {
6195
6208
  id,
6196
- ref: inputRef,
6209
+ ref: setInputRef,
6197
6210
  type: "text",
6198
6211
  autoComplete: "off",
6199
6212
  placeholder,
@@ -6202,7 +6215,20 @@ function SearchField({ id, label, labelHidden = false, placeholder, value, onCha
6202
6215
  onKeyDown,
6203
6216
  onChange: (e) => onChange(e.target.value)
6204
6217
  }
6205
- )
6218
+ ),
6219
+ clearLabel && value.length > 0 ? /* @__PURE__ */ jsx59(
6220
+ "button",
6221
+ {
6222
+ type: "button",
6223
+ className: "ss-g-search-clear",
6224
+ "aria-label": clearLabel,
6225
+ onClick: () => {
6226
+ onChange("");
6227
+ localRef.current?.focus();
6228
+ },
6229
+ children: /* @__PURE__ */ jsx59(IconClose, { size: 11 })
6230
+ }
6231
+ ) : null
6206
6232
  ] })
6207
6233
  ] });
6208
6234
  }
@@ -6286,7 +6312,7 @@ function TodayPanel({ discovery, ui, monitor }) {
6286
6312
  ] }) });
6287
6313
  }
6288
6314
  const searching = query.trim().length > 0;
6289
- const searchResults = searching ? visibleGroups.filter((g) => matchesQuery(g, query)) : [];
6315
+ const searchResults = searching ? placement.order.filter((g) => matchesQuery(g, query)) : [];
6290
6316
  return /* @__PURE__ */ jsxs54("div", { className: "ss-w-today-root", children: [
6291
6317
  /* @__PURE__ */ jsxs54("div", { className: "ss-w-mon-list", children: [
6292
6318
  stale && /* @__PURE__ */ jsx60("div", { className: "ss-w-stale", children: ui.staleStates }),
@@ -6299,21 +6325,41 @@ function TodayPanel({ discovery, ui, monitor }) {
6299
6325
  labelHidden: true,
6300
6326
  placeholder: ui.searchLeaguesPlaceholder,
6301
6327
  value: query,
6302
- onChange: setQuery
6328
+ onChange: setQuery,
6329
+ clearLabel: ui.clearSearchLabel
6303
6330
  }
6304
6331
  ),
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: [
6332
+ searching ? searchResults.length === 0 ? /* @__PURE__ */ jsx60("div", { className: "ss-w-today-empty", children: ui.noLeagueResults }) : /* @__PURE__ */ jsx60(Fragment7, { children: searchResults.map((group) => /* @__PURE__ */ jsxs54("div", { className: "ss-w-today-search-block", children: [
6333
+ /* @__PURE__ */ jsxs54("div", { className: "ss-w-today-search-group", children: [
6334
+ /* @__PURE__ */ jsx60(Crest2, { url: group.competitionImagePath ?? void 0, name: group.competitionName, kind: "comp" }),
6335
+ /* @__PURE__ */ jsxs54("span", { className: "ss-w-today-search-group-name", children: [
6336
+ group.competitionName,
6337
+ (nameCounts[group.competitionName] ?? 0) > 1 && group.competitionCountry ? /* @__PURE__ */ jsxs54("span", { className: "ss-w-today-tile-country", children: [
6338
+ " (",
6339
+ group.competitionCountry,
6340
+ ")"
6341
+ ] }) : null
6342
+ ] })
6343
+ ] }),
6344
+ group.matches.map((match) => /* @__PURE__ */ jsx60(
6345
+ "div",
6346
+ {
6347
+ role: "button",
6348
+ tabIndex: 0,
6349
+ className: "ss-w-today-search-row",
6350
+ onClick: () => setSelectedCompetitionId(group.competitionId),
6351
+ onKeyDown: (e) => {
6352
+ if (e.target !== e.currentTarget) return;
6353
+ if (e.key === "Enter" || e.key === " ") {
6354
+ e.preventDefault();
6355
+ setSelectedCompetitionId(group.competitionId);
6356
+ }
6357
+ },
6358
+ children: /* @__PURE__ */ jsx60(FixtureRow, { match, state: states[match.matchId], stale, ui, monitor })
6359
+ },
6360
+ match.matchId
6361
+ ))
6362
+ ] }, group.competitionId)) }) : /* @__PURE__ */ jsxs54(Fragment7, { children: [
6317
6363
  /* @__PURE__ */ jsxs54("div", { className: "ss-w-today-sec", children: [
6318
6364
  placement.personal ? ui.yourLeagues : ui.topLeagues,
6319
6365
  !placement.personal && /* @__PURE__ */ jsx60("span", { className: "ss-w-today-sec-sub", children: ui.topLeaguesSub })
@@ -6571,10 +6617,10 @@ function GamesHub({ games, myWeeklyRow, weeklyPrize, onOpen, ui }) {
6571
6617
  }
6572
6618
 
6573
6619
  // src/components/GameScreenHost.tsx
6574
- import { useEffect as useEffect24, useRef as useRef20, useState as useState42 } from "react";
6620
+ import { useEffect as useEffect24, useRef as useRef21, useState as useState42 } from "react";
6575
6621
 
6576
6622
  // src/useGamePlay.ts
6577
- import { useCallback as useCallback14, useRef as useRef18, useState as useState31 } from "react";
6623
+ import { useCallback as useCallback15, useRef as useRef19, useState as useState31 } from "react";
6578
6624
  function toSubmitResult(payload) {
6579
6625
  return {
6580
6626
  // 'pending' means the play is recorded but awaiting resolution (fixture games)
@@ -6589,14 +6635,14 @@ function useGamePlay(conversation, { gameId, gameDay, fixtureId, locale, refresh
6589
6635
  const [result, setResult] = useState31(null);
6590
6636
  const [submitting, setSubmitting] = useState31(false);
6591
6637
  const [rawStatus, setRawStatus] = useState31(null);
6592
- const inFlightRef = useRef18(false);
6593
- const convRef = useRef18(conversation);
6638
+ const inFlightRef = useRef19(false);
6639
+ const convRef = useRef19(conversation);
6594
6640
  convRef.current = conversation;
6595
- const optsRef = useRef18({ gameId, gameDay, fixtureId, locale, refresh });
6641
+ const optsRef = useRef19({ gameId, gameDay, fixtureId, locale, refresh });
6596
6642
  optsRef.current = { gameId, gameDay, fixtureId, locale, refresh };
6597
- const resultRef = useRef18(null);
6643
+ const resultRef = useRef19(null);
6598
6644
  resultRef.current = result;
6599
- const refetch = useCallback14(async () => {
6645
+ const refetch = useCallback15(async () => {
6600
6646
  const conv = convRef.current;
6601
6647
  if (!conv) return;
6602
6648
  const opts = optsRef.current;
@@ -6612,7 +6658,7 @@ function useGamePlay(conversation, { gameId, gameDay, fixtureId, locale, refresh
6612
6658
  } catch {
6613
6659
  }
6614
6660
  }, []);
6615
- const submit = useCallback14(async (answerJson) => {
6661
+ const submit = useCallback15(async (answerJson) => {
6616
6662
  const conv = convRef.current;
6617
6663
  if (!conv || inFlightRef.current) return;
6618
6664
  inFlightRef.current = true;
@@ -6639,7 +6685,7 @@ function useGamePlay(conversation, { gameId, gameDay, fixtureId, locale, refresh
6639
6685
  setSubmitting(false);
6640
6686
  }
6641
6687
  }, [refetch]);
6642
- const hydrate = useCallback14(() => {
6688
+ const hydrate = useCallback15(() => {
6643
6689
  void refetch();
6644
6690
  }, [refetch]);
6645
6691
  return { result, submitting, submit, hydrate, rawStatus };
@@ -7523,7 +7569,7 @@ function CareerPathGame({
7523
7569
  }
7524
7570
 
7525
7571
  // src/components/games/BeatTheGridGame.tsx
7526
- import React, { useEffect as useEffect23, useId as useId5, useRef as useRef19, useState as useState36 } from "react";
7572
+ import React, { useEffect as useEffect23, useId as useId5, useRef as useRef20, useState as useState36 } from "react";
7527
7573
 
7528
7574
  // src/components/games/ui/OptionList.tsx
7529
7575
  import { jsx as jsx79 } from "react/jsx-runtime";
@@ -7614,7 +7660,7 @@ function SearchSheet({
7614
7660
  const s = ui.games.beatTheGrid;
7615
7661
  const [query, setQuery] = useState36("");
7616
7662
  const inputId = useId5();
7617
- const inputRef = useRef19(null);
7663
+ const inputRef = useRef20(null);
7618
7664
  useEffect23(() => {
7619
7665
  inputRef.current?.focus();
7620
7666
  }, [row, col]);
@@ -8945,7 +8991,7 @@ function GameScreenHost({
8945
8991
  useEffect24(() => {
8946
8992
  if (conversation) hydrate();
8947
8993
  }, [conversation, gameId]);
8948
- const hydrateRef = useRef20(hydrate);
8994
+ const hydrateRef = useRef21(hydrate);
8949
8995
  hydrateRef.current = hydrate;
8950
8996
  useEffect24(() => {
8951
8997
  if (!FIXTURE_GAME_IDS.has(gameId)) return;
@@ -9316,11 +9362,11 @@ function PresetSpeedDial({ expanded, showDot, strings, onToggle, onOpen, rootRef
9316
9362
  }
9317
9363
 
9318
9364
  // src/components/PresetTools.tsx
9319
- import { Fragment as Fragment21, useEffect as useEffect26, useId as useId11, useRef as useRef21, useState as useState45 } from "react";
9365
+ import { Fragment as Fragment21, useEffect as useEffect26, useId as useId11, useRef as useRef22, useState as useState45 } from "react";
9320
9366
  import { Fragment as Fragment22, jsx as jsx95, jsxs as jsxs80 } from "react/jsx-runtime";
9321
9367
  var FOCUSABLE = 'button:not([disabled]), [href], input:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
9322
9368
  function PresetToolModal({ title, closeLabel, onClose, children, footer }) {
9323
- const dialogRef = useRef21(null);
9369
+ const dialogRef = useRef22(null);
9324
9370
  const titleId = useId11();
9325
9371
  useEffect26(() => {
9326
9372
  dialogRef.current?.focus();
@@ -9609,7 +9655,7 @@ function BuildComboTool({ grid, strings, streaming, formatKickoff, initialTotal,
9609
9655
  }
9610
9656
 
9611
9657
  // src/usePresetDial.ts
9612
- import { useCallback as useCallback15, useEffect as useEffect27, useRef as useRef22, useState as useState46 } from "react";
9658
+ import { useCallback as useCallback16, useEffect as useEffect27, useRef as useRef23, useState as useState46 } from "react";
9613
9659
  function sendInFlight(messages, isStreaming) {
9614
9660
  const last = messages[messages.length - 1];
9615
9661
  return isStreaming && !!last && last.role === "assistant" && !last.done && !last.isGreeting;
@@ -9624,22 +9670,22 @@ function lastUserId(messages) {
9624
9670
  var SCROLL_KEYS = /* @__PURE__ */ new Set(["ArrowUp", "ArrowDown", "PageUp", "PageDown", "Home", "End", " "]);
9625
9671
  function usePresetDial({ layerRef, dialRef, dialButtonRef, messages, isStreaming, activeTab }) {
9626
9672
  const [expanded, setExpanded] = useState46(() => !sendInFlight(messages, isStreaming));
9627
- const fold = useCallback15(() => setExpanded(false), []);
9628
- const toggle = useCallback15(() => setExpanded((e) => !e), []);
9673
+ const fold = useCallback16(() => setExpanded(false), []);
9674
+ const toggle = useCallback16(() => setExpanded((e) => !e), []);
9629
9675
  const currentUserId = lastUserId(messages);
9630
- const userIdRef = useRef22(currentUserId);
9676
+ const userIdRef = useRef23(currentUserId);
9631
9677
  useEffect27(() => {
9632
9678
  if (currentUserId === userIdRef.current) return;
9633
9679
  userIdRef.current = currentUserId;
9634
9680
  setExpanded(false);
9635
9681
  }, [currentUserId]);
9636
- const tabRef = useRef22(activeTab);
9682
+ const tabRef = useRef23(activeTab);
9637
9683
  useEffect27(() => {
9638
9684
  if (activeTab === tabRef.current) return;
9639
9685
  tabRef.current = activeTab;
9640
9686
  setExpanded(false);
9641
9687
  }, [activeTab]);
9642
- const expandedRef = useRef22(expanded);
9688
+ const expandedRef = useRef23(expanded);
9643
9689
  expandedRef.current = expanded;
9644
9690
  useEffect27(() => {
9645
9691
  const onEscape = (e) => {
@@ -9744,13 +9790,13 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
9744
9790
  if (monitor && monitor.activeTab !== "chat" && state.isStreaming) monitor.markChatActivity();
9745
9791
  }, [monitor, state.isStreaming, state.messages.length]);
9746
9792
  const onChatTab = !monitor || monitor.activeTab === "chat";
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);
9793
+ const layerRef = useRef24(null);
9794
+ const dialRef = useRef24(null);
9795
+ const dialButtonRef = useRef24(null);
9796
+ const inputRef = useRef24(null);
9797
+ const limitRef = useRef24(null);
9798
+ const typedSendRef = useRef24(false);
9799
+ const focusAfterCloseRef = useRef24(null);
9754
9800
  const [tool, setTool] = useState47(null);
9755
9801
  const [toolSeen, setToolSeen] = useState47(readToolSeen);
9756
9802
  const dial = usePresetDial({
@@ -9772,28 +9818,28 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
9772
9818
  if (typedSendRef.current) limitRef.current?.focus();
9773
9819
  typedSendRef.current = false;
9774
9820
  }, [paused]);
9775
- const openTool = useCallback16((next) => {
9821
+ const openTool = useCallback17((next) => {
9776
9822
  fold();
9777
9823
  markToolSeen();
9778
9824
  setToolSeen(true);
9779
9825
  setTool(next);
9780
9826
  }, [fold]);
9781
- const onPill = useCallback16((kind) => openTool(kind === "numbers" ? { kind: "numbers" } : { kind: "combo" }), [openTool]);
9827
+ const onPill = useCallback17((kind) => openTool(kind === "numbers" ? { kind: "numbers" } : { kind: "combo" }), [openTool]);
9782
9828
  const toolsValue = useMemo5(
9783
9829
  () => presetGrid && !paused ? { openBuilder: (total, legs) => openTool({ kind: "combo", total, legs }), changeLabel: ui.presets.changeCombo } : null,
9784
9830
  [presetGrid, paused, openTool, ui.presets.changeCombo]
9785
9831
  );
9786
- const closeTool = useCallback16(() => {
9832
+ const closeTool = useCallback17(() => {
9787
9833
  focusAfterCloseRef.current = "dial";
9788
9834
  setTool(null);
9789
9835
  }, []);
9790
- const sendAsk = useCallback16((ask) => {
9836
+ const sendAsk = useCallback17((ask) => {
9791
9837
  focusAfterCloseRef.current = "composer";
9792
9838
  setTool(null);
9793
9839
  monitor?.setActiveTab("chat");
9794
9840
  send(ask.message, { displayText: ask.displayText, preset: ask.preset });
9795
9841
  }, [monitor, send]);
9796
- const formatKickoff = useCallback16((kickoffUtc) => {
9842
+ const formatKickoff = useCallback17((kickoffUtc) => {
9797
9843
  const k = ui.bettingKickoff(kickoffUtc);
9798
9844
  return `${k.dayLabel} ${k.time}`;
9799
9845
  }, [ui]);
@@ -10023,6 +10069,8 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
10023
10069
  .ss-g-search-box { display: flex; align-items: center; gap: 10px; height: 50px; padding: 0 14px; border-radius: 14px; background: var(--ss-g-surface); border: 1.5px solid var(--ss-g-line); color: var(--ss-g-muted); }
10024
10070
  .ss-g-search-box:focus-within { border-color: var(--ss-w-accent); }
10025
10071
  .ss-g-search-box input { flex: 1; min-width: 0; border: 0; outline: none; background: transparent; color: var(--ss-g-ink); font: 500 15px var(--ss-g-font-body); }
10072
+ .ss-g-search-clear { flex: none; width: 20px; height: 20px; padding: 0; border: none; border-radius: 50%; background: var(--ss-g-line); color: var(--ss-g-muted); display: flex; align-items: center; justify-content: center; cursor: pointer; }
10073
+ .ss-g-search-clear:focus-visible { outline: 2px solid var(--ss-w-accent); outline-offset: -2px; }
10026
10074
  .ss-g-footer { flex: none; padding: 12px 16px 16px; border-top: 1px solid var(--ss-g-line); display: flex; flex-direction: column; gap: 10px; background: var(--ss-g-ground); }
10027
10075
  .ss-g-sil { position: relative; flex: none; display: inline-flex; align-items: flex-end; justify-content: center; overflow: hidden; border-radius: 50%; background: var(--ss-g-raised); color: var(--ss-g-strong-line); }
10028
10076
  .ss-g-sil--selected { background: var(--ss-g-accent-tint); color: color-mix(in srgb, var(--ss-w-accent) 40%, var(--ss-g-raised)); }
@@ -11112,6 +11160,13 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
11112
11160
  .ss-w-today-sec-sub { text-transform: none; letter-spacing: normal; font-weight: 600; }
11113
11161
  .ss-w-today-tiles { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
11114
11162
  .ss-w-today-empty { font-size: 12px; color: var(--ss-w-faint); padding: 10px 2px; }
11163
+ .ss-w-today-search-block { display: flex; flex-direction: column; }
11164
+ .ss-w-today-search-group { display: flex; align-items: center; gap: 7px; padding: 2px 2px 6px; }
11165
+ .ss-w-today-search-group::after { content: ""; flex: 1; height: 1px; background: var(--ss-w-line); }
11166
+ .ss-w-today-search-group .ss-w-bi-comp-logo { width: 16px; height: 16px; }
11167
+ .ss-w-today-search-group-name { font-size: 10px; font-weight: 800; letter-spacing: .09em; text-transform: uppercase; color: var(--ss-w-faint); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
11168
+ .ss-w-today-search-row { cursor: pointer; border-radius: 10px; }
11169
+ .ss-w-today-search-row:focus-visible { outline: 2px solid var(--ss-w-accent); outline-offset: -2px; }
11115
11170
 
11116
11171
  /* League tile (Task 5): a flat row (crest + name as the open target, star as a separate sibling
11117
11172
  button) rather than a disclosure header -- opening is Task 6's LeagueDetail, not an inline
@@ -11667,9 +11722,9 @@ function StatsWidget(props) {
11667
11722
  [built?.client]
11668
11723
  );
11669
11724
  const ui = useMemo6(() => normalizeUi(props.config ?? { operatorId: "", publicKey: "" }), [props.config]);
11670
- const rootRef = useRef24(null);
11671
- const introDoneRef = useRef24(false);
11672
- const markIntroDone = useCallback17(() => {
11725
+ const rootRef = useRef25(null);
11726
+ const introDoneRef = useRef25(false);
11727
+ const markIntroDone = useCallback18(() => {
11673
11728
  introDoneRef.current = true;
11674
11729
  }, []);
11675
11730
  const convStorageKey = `ss-w-conv:${cfg?.operatorId ?? ""}:${cfg?.userContext?.operatorUserId ?? "anon"}`;
@@ -11699,15 +11754,15 @@ function StatsWidget(props) {
11699
11754
  });
11700
11755
  const operatorUserId = cfg?.userContext?.operatorUserId;
11701
11756
  const anonymousUserId = cfg?.userContext?.anonymousUserId;
11702
- const getSchedule = useCallback17(
11757
+ const getSchedule = useCallback18(
11703
11758
  (localDate, utcOffsetMinutes) => built ? built.conversation.getSchedule(localDate, utcOffsetMinutes, operatorUserId, anonymousUserId) : Promise.resolve(null),
11704
11759
  [built, operatorUserId, anonymousUserId]
11705
11760
  );
11706
- const postLeagueStar = useCallback17(
11761
+ const postLeagueStar = useCallback18(
11707
11762
  (competitionId, starred) => built ? built.conversation.starLeague(competitionId, starred, operatorUserId, anonymousUserId) : Promise.resolve(null),
11708
11763
  [built, operatorUserId, anonymousUserId]
11709
11764
  );
11710
- const getStates = useCallback17(
11765
+ const getStates = useCallback18(
11711
11766
  (matchIds) => built ? built.conversation.getStates(matchIds) : Promise.resolve(null),
11712
11767
  [built]
11713
11768
  );
@@ -11729,7 +11784,7 @@ function StatsWidget(props) {
11729
11784
  useEffect29(() => {
11730
11785
  setHasToday(todayHasContent);
11731
11786
  }, [todayHasContent]);
11732
- const prevLiveSnapshotRef = useRef24(monitor.snapshot);
11787
+ const prevLiveSnapshotRef = useRef25(monitor.snapshot);
11733
11788
  useEffect29(() => {
11734
11789
  const snap = monitor.snapshot;
11735
11790
  if (!snap || snap === prevLiveSnapshotRef.current) return;
@@ -11766,13 +11821,13 @@ function StatsWidget(props) {
11766
11821
  }, [monitor.snapshot]);
11767
11822
  const gamesResult = useGames(built?.conversation ?? null, { activeTab: monitor.activeTab });
11768
11823
  const leaderboardResult = useLeaderboard(built?.conversation ?? null, { activeTab: monitor.activeTab });
11769
- const getPricePresets = useCallback17(
11824
+ const getPricePresets = useCallback18(
11770
11825
  (locale2) => built ? built.conversation.getPricePresets(locale2, { pool: "open" }) : Promise.resolve(null),
11771
11826
  [built]
11772
11827
  );
11773
11828
  const presetGrid = usePresetGrid({ getPricePresets, isOpen: controller.state.isOpen, locale: ui.presets.lang });
11774
11829
  const markTodayActivity = monitor.markTodayActivity;
11775
- const prevLiveCountRef = useRef24(0);
11830
+ const prevLiveCountRef = useRef25(0);
11776
11831
  useEffect29(() => {
11777
11832
  const rose = prevLiveCountRef.current === 0 && discovery.liveCount > 0;
11778
11833
  prevLiveCountRef.current = discovery.liveCount;