@sensiblestats/widget-react 0.17.0 → 0.19.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.cjs CHANGED
@@ -36,7 +36,7 @@ __export(index_exports, {
36
36
  module.exports = __toCommonJS(index_exports);
37
37
 
38
38
  // src/StatsWidget.tsx
39
- var import_react12 = require("react");
39
+ var import_react13 = require("react");
40
40
  var import_widget_sdk5 = require("@sensiblestats/widget-sdk");
41
41
 
42
42
  // src/kickoff.ts
@@ -472,7 +472,13 @@ function toMarketOddsVM(card) {
472
472
  id: `${typeof card.matchId === "number" ? card.matchId : 0}:${str(card.marketDeveloperName) ?? ""}`,
473
473
  market: str(card.marketLabel) ?? str(card.marketDeveloperName) ?? "",
474
474
  fixture: home && away ? `${home} vs ${away}` : void 0,
475
+ homeTeamName: home,
476
+ awayTeamName: away,
477
+ homeCrest: str(card.homeTeamImagePath),
478
+ awayCrest: str(card.awayTeamImagePath),
479
+ competitionCrest: str(card.competitionImagePath),
475
480
  competition: str(card.competitionName),
481
+ kickoffUtc: str(card.kickoffUtc),
476
482
  bookmaker: rows.map((r) => str(r.bookmakerName)).find(Boolean),
477
483
  updatedAt: updated.length > 0 ? updated[updated.length - 1] : void 0,
478
484
  isLive: rows.some((r) => r.isLive === true),
@@ -652,7 +658,7 @@ function useChatStream(conversation, starterTexts, greetingMessage) {
652
658
  const send = (0, import_react.useCallback)((text, opts) => {
653
659
  const trimmed = text.trim();
654
660
  if (!trimmed) return;
655
- run({ message: trimmed, actionId: opts?.actionId }, opts?.displayText);
661
+ run({ message: trimmed, actionId: opts?.actionId, grounding: opts?.grounding }, opts?.displayText);
656
662
  }, [run]);
657
663
  const retry = (0, import_react.useCallback)(() => {
658
664
  const last = stateRef.current.lastUserInput;
@@ -748,7 +754,7 @@ function ChatFab({ label, greeting, popupText, onOpen, onDismissPopup, dismissLa
748
754
  }
749
755
 
750
756
  // src/components/ChatPanel.tsx
751
- var import_react11 = require("react");
757
+ var import_react12 = require("react");
752
758
 
753
759
  // src/components/ChatHeader.tsx
754
760
  var import_jsx_runtime4 = require("react/jsx-runtime");
@@ -761,7 +767,7 @@ function ChatHeader({ onClose, closeLabel = "Close chat" }) {
761
767
  }
762
768
 
763
769
  // src/components/MessageList.tsx
764
- var import_react9 = require("react");
770
+ var import_react10 = require("react");
765
771
 
766
772
  // src/components/Markdown.tsx
767
773
  var import_react_markdown = __toESM(require("react-markdown"), 1);
@@ -881,7 +887,7 @@ function EntityCardList({ cards, disabled, showLessLabel = "Show less", showMore
881
887
  }
882
888
 
883
889
  // src/components/BettingInsightList.tsx
884
- var import_react5 = require("react");
890
+ var import_react6 = require("react");
885
891
 
886
892
  // src/components/AddToSlipButton.tsx
887
893
  var import_react4 = require("react");
@@ -1004,53 +1010,64 @@ function OddsMovementBadge({
1004
1010
  ] });
1005
1011
  }
1006
1012
 
1007
- // src/components/BettingInsightList.tsx
1013
+ // src/components/Crest.tsx
1014
+ var import_react5 = require("react");
1008
1015
  var import_jsx_runtime10 = require("react/jsx-runtime");
1016
+ function initials2(name) {
1017
+ return (name ?? "").trim().slice(0, 1).toUpperCase() || "?";
1018
+ }
1019
+ function Crest2({ url, name, kind }) {
1020
+ const cls = kind === "comp" ? "ss-w-bi-comp-logo" : "ss-w-bi-crest";
1021
+ const [failed, setFailed] = (0, import_react5.useState)(false);
1022
+ if (url && !failed) {
1023
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("img", { className: cls, src: url, alt: "", "aria-hidden": "true", onError: () => setFailed(true) });
1024
+ }
1025
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: `${cls} ss-w-bi-crest-mono`, "aria-hidden": "true", children: initials2(name) });
1026
+ }
1027
+
1028
+ // src/components/BettingInsightList.tsx
1029
+ var import_jsx_runtime11 = require("react/jsx-runtime");
1009
1030
  function StatRows2({ stats }) {
1010
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "ss-w-bi-rows", children: stats.map((s) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "ss-w-bi-row", children: [
1011
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "ss-w-bi-row-lbl", children: s.label }),
1012
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "ss-w-bi-row-num", children: s.value })
1031
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "ss-w-bi-rows", children: stats.map((s) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "ss-w-bi-row", children: [
1032
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "ss-w-bi-row-lbl", children: s.label }),
1033
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "ss-w-bi-row-num", children: s.value })
1013
1034
  ] }, `${s.label}:${s.value}`)) });
1014
1035
  }
1015
1036
  function ScopedStats({ scopes }) {
1016
- const [active, setActive] = (0, import_react5.useState)(0);
1037
+ const [active, setActive] = (0, import_react6.useState)(0);
1017
1038
  const current = scopes[active] ?? scopes[0] ?? { key: "", label: "", stats: [] };
1018
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "ss-w-bi-scoped", children: [
1019
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "ss-w-bi-scopes", role: "group", children: scopes.map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", className: "ss-w-bi-chip", "aria-pressed": i === active, onClick: () => setActive(i), children: s.label }, s.key)) }),
1020
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(StatRows2, { stats: current.stats }, current.key)
1039
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "ss-w-bi-scoped", children: [
1040
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "ss-w-bi-scopes", role: "group", children: scopes.map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", className: "ss-w-bi-chip", "aria-pressed": i === active, onClick: () => setActive(i), children: s.label }, s.key)) }),
1041
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(StatRows2, { stats: current.stats }, current.key)
1021
1042
  ] });
1022
1043
  }
1023
1044
  function hasStatsContent(it) {
1024
1045
  return !!it.scopes && it.scopes.length >= 2 || it.stats.length > 0;
1025
1046
  }
1026
- function initials2(name) {
1027
- return (name ?? "").trim().slice(0, 1).toUpperCase() || "?";
1028
- }
1029
- function Crest2({ url, name, kind }) {
1030
- const cls = kind === "comp" ? "ss-w-bi-comp-logo" : "ss-w-bi-crest";
1031
- if (url) return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: cls, style: { backgroundImage: `url(${url})` }, "aria-hidden": "true" });
1032
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: `${cls} ss-w-bi-crest-mono`, "aria-hidden": "true", children: initials2(name) });
1033
- }
1034
- function StatsDisclosure({ it, ui }) {
1035
- const [open, setOpen] = (0, import_react5.useState)(false);
1047
+ function ReasonStrip({ it, ui }) {
1048
+ const [open, setOpen] = (0, import_react6.useState)(false);
1036
1049
  const hasScopes = !!it.scopes && it.scopes.length >= 2;
1037
1050
  const hasStats = hasStatsContent(it);
1038
- if (!hasStats) return null;
1039
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "ss-w-bi-stats", children: [
1040
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
1051
+ const hasText = !!it.text;
1052
+ if (!hasText && !hasStats) return null;
1053
+ const expandable = hasStats || (it.text?.length ?? 0) > 90;
1054
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "ss-w-bi-reason", children: [
1055
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "ss-w-bi-chart", "aria-hidden": "true" }),
1056
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "ss-w-bi-reason-body", children: [
1057
+ hasText ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: `ss-w-bi-text${open ? "" : " ss-w-bi-text-clamp"}`, children: it.text }) : null,
1058
+ open && hasStats ? hasScopes ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ScopedStats, { scopes: it.scopes }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(StatRows2, { stats: it.stats }) : null
1059
+ ] }),
1060
+ expandable ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1041
1061
  "button",
1042
1062
  {
1043
1063
  type: "button",
1044
- className: "ss-w-bi-toggle",
1064
+ className: "ss-w-bi-expand",
1045
1065
  "aria-expanded": open,
1066
+ "aria-label": open ? ui?.hideStats ?? "Hide stats" : ui?.showStats ?? "Show stats",
1046
1067
  onClick: () => setOpen((v) => !v),
1047
- children: [
1048
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: open ? ui?.hideStats ?? "Hide stats" : ui?.showStats ?? "Show stats" }),
1049
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: `ss-w-bi-chev${open ? " ss-w-bi-chev-up" : ""}`, "aria-hidden": "true" })
1050
- ]
1068
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: `ss-w-bi-arrow${open ? " ss-w-bi-arrow-open" : ""}`, "aria-hidden": "true" })
1051
1069
  }
1052
- ),
1053
- open ? hasScopes ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ScopedStats, { scopes: it.scopes }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(StatRows2, { stats: it.stats }) : null
1070
+ ) : null
1054
1071
  ] });
1055
1072
  }
1056
1073
  function InsightCard({ it, ui, slip }) {
@@ -1058,105 +1075,119 @@ function InsightCard({ it, ui, slip }) {
1058
1075
  const kickoff = it.kickoffUtc && ui?.bettingKickoff ? ui.bettingKickoff(it.kickoffUtc) : void 0;
1059
1076
  const hasNamedTeams = !!it.homeTeamName && !!it.awayTeamName;
1060
1077
  const showHeader = !!it.competition || live || !!kickoff;
1061
- const showReason = !!it.text || hasStatsContent(it);
1062
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "ss-w-binsight", children: [
1063
- showHeader ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "ss-w-bi-header", children: [
1064
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "ss-w-bi-header-left", children: it.competition ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
1065
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Crest2, { kind: "comp", url: it.competitionCrest, name: it.competition }),
1066
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "ss-w-bi-comp", children: it.competition })
1078
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "ss-w-binsight", children: [
1079
+ showHeader ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "ss-w-bi-header", children: [
1080
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "ss-w-bi-header-left", children: it.competition ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
1081
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Crest2, { kind: "comp", url: it.competitionCrest, name: it.competition }),
1082
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "ss-w-bi-comp", children: it.competition })
1067
1083
  ] }) : null }),
1068
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "ss-w-bi-header-right", children: [
1069
- live ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "ss-w-bi-live", children: [
1070
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "ss-w-bi-live-dot", "aria-hidden": "true" }),
1084
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "ss-w-bi-header-right", children: [
1085
+ live ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "ss-w-bi-live", children: [
1086
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "ss-w-bi-live-dot", "aria-hidden": "true" }),
1071
1087
  ui?.liveLabel ?? "Live"
1072
1088
  ] }) : null,
1073
- kickoff ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "ss-w-bi-kick", children: [
1089
+ kickoff ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "ss-w-bi-kick", children: [
1074
1090
  kickoff.dayLabel,
1075
1091
  " ",
1076
1092
  kickoff.time
1077
1093
  ] }) : null
1078
1094
  ] })
1079
1095
  ] }) : null,
1080
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "ss-w-bi-body", children: [
1081
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "ss-w-bi-fixture", children: hasNamedTeams ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
1082
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Crest2, { kind: "team", url: it.homeCrest, name: it.homeTeamName }),
1083
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "ss-w-bi-team", children: it.homeTeamName }),
1084
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "ss-w-bi-vs", "aria-hidden": "true", children: "vs" }),
1085
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "ss-w-bi-team", children: it.awayTeamName }),
1086
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Crest2, { kind: "team", url: it.awayCrest, name: it.awayTeamName })
1087
- ] }) : it.fixture ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "ss-w-bi-fixture-txt", children: it.fixture }) : null }),
1088
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "ss-w-bi-action", children: [
1089
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "ss-w-bi-mkt", children: [
1090
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "ss-w-bi-market", children: it.market }),
1091
- it.selection ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "ss-w-bi-sel", children: it.selection }) : null
1096
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "ss-w-bi-body", children: [
1097
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "ss-w-bi-fixture", children: hasNamedTeams ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
1098
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Crest2, { kind: "team", url: it.homeCrest, name: it.homeTeamName }),
1099
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "ss-w-bi-team", children: it.homeTeamName }),
1100
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "ss-w-bi-vs", "aria-hidden": "true", children: "vs" }),
1101
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "ss-w-bi-team", children: it.awayTeamName }),
1102
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Crest2, { kind: "team", url: it.awayCrest, name: it.awayTeamName })
1103
+ ] }) : it.fixture ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "ss-w-bi-fixture-txt", children: it.fixture }) : null }),
1104
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "ss-w-bi-action", children: [
1105
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "ss-w-bi-mkt", children: [
1106
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "ss-w-bi-market", children: it.market }),
1107
+ it.selection ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "ss-w-bi-sel", children: it.selection }) : null
1092
1108
  ] }),
1093
- it.isMarketFloor ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "ss-w-bi-floor", children: ui?.marketFloorLabel ?? "Market price \xB7 not a value pick" }) : null,
1094
- it.odds ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "ss-w-bi-odds", children: [
1095
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "ss-w-bi-odds-cap", children: ui?.oddsLabel ?? "Odds" }),
1096
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("b", { children: it.odds }),
1097
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(OddsMovementBadge, { previous: it.previousOdds, current: it.odds, direction: it.movementDirection, ui }),
1098
- it.bookmaker ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "ss-w-bi-book", children: it.bookmaker }) : null
1109
+ it.isMarketFloor ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "ss-w-bi-floor", children: ui?.marketFloorLabel ?? "Market price \xB7 not a value pick" }) : null,
1110
+ it.odds ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "ss-w-bi-odds", children: [
1111
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("b", { children: it.odds }),
1112
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(OddsMovementBadge, { previous: it.previousOdds, current: it.odds, direction: it.movementDirection, ui }),
1113
+ it.bookmaker ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "ss-w-bi-book", children: it.bookmaker }) : null
1099
1114
  ] }) : null,
1100
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(AddToSlipButton, { it, slip, ui })
1115
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(AddToSlipButton, { it, slip, ui })
1101
1116
  ] })
1102
1117
  ] }),
1103
- showReason ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "ss-w-bi-reason", children: [
1104
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "ss-w-bi-chart", "aria-hidden": "true" }),
1105
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "ss-w-bi-reason-body", children: [
1106
- it.text ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "ss-w-bi-text", children: it.text }) : null,
1107
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(StatsDisclosure, { it, ui })
1108
- ] })
1109
- ] }) : null,
1110
- it.disclaimer ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "ss-w-bi-disc", children: it.disclaimer }) : null
1118
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ReasonStrip, { it, ui }),
1119
+ it.disclaimer ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "ss-w-bi-disc", children: it.disclaimer }) : null
1111
1120
  ] });
1112
1121
  }
1113
1122
  function BettingInsightList({ insights, ui, slip }) {
1114
1123
  if (!insights || insights.length === 0) return null;
1115
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "ss-w-binsights", children: insights.map((it) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(InsightCard, { it, ui, slip }, it.id)) });
1124
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "ss-w-binsights", children: insights.map((it) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(InsightCard, { it, ui, slip }, it.id)) });
1116
1125
  }
1117
1126
 
1118
1127
  // src/components/MarketOddsCardList.tsx
1119
- var import_react6 = require("react");
1120
- var import_jsx_runtime11 = require("react/jsx-runtime");
1128
+ var import_react7 = require("react");
1129
+ var import_jsx_runtime12 = require("react/jsx-runtime");
1121
1130
  function OddsRow({ vm, row, ui, slip }) {
1122
1131
  const selection = vm.addToSlipEnabled ? marketOddsRowToSlipSelection(vm, row, slip.conversationId) : null;
1123
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "ss-w-mo-row", children: [
1124
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "ss-w-mo-sel", children: row.selection }),
1125
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(OddsMovementBadge, { previous: row.previousOdds, current: row.odds, direction: row.movementDirection, ui }),
1126
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "ss-w-mo-price", children: row.odds }),
1127
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SlipButton, { selection, shownOdds: row.odds, marketName: vm.market, slip, ui })
1132
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "ss-w-mo-row", children: [
1133
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "ss-w-mo-sel", children: row.selection }),
1134
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(OddsMovementBadge, { previous: row.previousOdds, current: row.odds, direction: row.movementDirection, ui }),
1135
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "ss-w-mo-price", children: row.odds }),
1136
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SlipButton, { selection, shownOdds: row.odds, marketName: vm.market, slip, ui })
1128
1137
  ] });
1129
1138
  }
1130
1139
  function MarketOddsCard({ vm, ui, slip }) {
1131
- const [open, setOpen] = (0, import_react6.useState)(false);
1132
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "ss-w-mocard", children: [
1133
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "ss-w-mo-head", children: [
1134
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "ss-w-mo-market", children: vm.market }),
1135
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "ss-w-mo-tag", children: ui?.marketPrices ?? "Market prices" })
1136
- ] }),
1137
- vm.fixture || vm.competition ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "ss-w-mo-fixture", children: [
1138
- vm.fixture ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: vm.fixture }) : null,
1139
- vm.competition ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "ss-w-mo-comp", children: vm.competition }) : null
1140
+ const [open, setOpen] = (0, import_react7.useState)(false);
1141
+ const kickoff = vm.kickoffUtc && ui?.bettingKickoff ? ui.bettingKickoff(vm.kickoffUtc) : void 0;
1142
+ const hasNamedTeams = !!vm.homeTeamName && !!vm.awayTeamName;
1143
+ const showHeader = !!vm.competition || vm.isLive || !!kickoff;
1144
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "ss-w-mocard", children: [
1145
+ showHeader ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "ss-w-bi-header", children: [
1146
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "ss-w-bi-header-left", children: vm.competition ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
1147
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Crest2, { kind: "comp", url: vm.competitionCrest, name: vm.competition }),
1148
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "ss-w-bi-comp", children: vm.competition })
1149
+ ] }) : null }),
1150
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "ss-w-bi-header-right", children: [
1151
+ vm.isLive ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "ss-w-bi-live", children: [
1152
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "ss-w-bi-live-dot", "aria-hidden": "true" }),
1153
+ ui?.liveLabel ?? "Live"
1154
+ ] }) : null,
1155
+ kickoff ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "ss-w-bi-kick", children: [
1156
+ kickoff.dayLabel,
1157
+ " ",
1158
+ kickoff.time
1159
+ ] }) : null
1160
+ ] })
1140
1161
  ] }) : null,
1141
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "ss-w-mo-rows", children: [
1142
- vm.mainRows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(OddsRow, { vm, row, ui, slip }, row.key)),
1143
- open ? vm.moreRows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(OddsRow, { vm, row, ui, slip }, row.key)) : null
1162
+ hasNamedTeams || vm.fixture || vm.market ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "ss-w-mo-sub", children: [
1163
+ hasNamedTeams ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "ss-w-bi-fixture", children: [
1164
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Crest2, { kind: "team", url: vm.homeCrest, name: vm.homeTeamName }),
1165
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "ss-w-bi-team", children: vm.homeTeamName }),
1166
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "ss-w-bi-vs", "aria-hidden": "true", children: "vs" }),
1167
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "ss-w-bi-team", children: vm.awayTeamName }),
1168
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Crest2, { kind: "team", url: vm.awayCrest, name: vm.awayTeamName })
1169
+ ] }) : vm.fixture ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "ss-w-mo-teams", children: vm.fixture }) : null,
1170
+ vm.market ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "ss-w-mo-market", children: vm.market }) : null
1171
+ ] }) : null,
1172
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "ss-w-mo-rows", children: [
1173
+ vm.mainRows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(OddsRow, { vm, row, ui, slip }, row.key)),
1174
+ open ? vm.moreRows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(OddsRow, { vm, row, ui, slip }, row.key)) : null
1144
1175
  ] }),
1145
- vm.moreRows.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("button", { type: "button", className: "ss-w-bi-toggle", "aria-expanded": open, onClick: () => setOpen((v) => !v), children: [
1146
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: open ? ui?.hideLines ?? "Hide lines" : `${ui?.moreLines ?? "More lines"} (${vm.moreRows.length})` }),
1147
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: `ss-w-bi-chev${open ? " ss-w-bi-chev-up" : ""}`, "aria-hidden": "true" })
1176
+ vm.moreRows.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("button", { type: "button", className: "ss-w-mo-more", "aria-expanded": open, onClick: () => setOpen((v) => !v), children: [
1177
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: open ? ui?.hideLines ?? "Hide lines" : `${ui?.moreLines ?? "More lines"} (${vm.moreRows.length})` }),
1178
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: `ss-w-mo-more-chev${open ? " ss-w-mo-more-chev-up" : ""}`, "aria-hidden": "true" })
1148
1179
  ] }) : null,
1149
- vm.bookmaker ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "ss-w-mo-foot", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: vm.bookmaker }) }) : null,
1150
- vm.disclaimer ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "ss-w-bi-disc", children: vm.disclaimer }) : null
1180
+ vm.bookmaker ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "ss-w-mo-foot", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: vm.bookmaker }) }) : null,
1181
+ vm.disclaimer ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "ss-w-bi-disc", children: vm.disclaimer }) : null
1151
1182
  ] });
1152
1183
  }
1153
1184
  function MarketOddsCardList({ cards, ui, slip }) {
1154
1185
  if (!cards || cards.length === 0) return null;
1155
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "ss-w-mocards", children: cards.map((vm) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(MarketOddsCard, { vm, ui, slip }, vm.id)) });
1186
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "ss-w-mocards", children: cards.map((vm) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(MarketOddsCard, { vm, ui, slip }, vm.id)) });
1156
1187
  }
1157
1188
 
1158
1189
  // src/components/OddsMovementCard.tsx
1159
- var import_jsx_runtime12 = require("react/jsx-runtime");
1190
+ var import_jsx_runtime13 = require("react/jsx-runtime");
1160
1191
  function directionWord(vm, ui) {
1161
1192
  if (vm.direction === "shortened") return ui?.oddsShortened ?? "shortened";
1162
1193
  if (vm.direction === "drifted") return ui?.oddsDrifted ?? "drifted";
@@ -1166,18 +1197,18 @@ function OddsMovementCard({ vm, ui }) {
1166
1197
  const word = directionWord(vm, ui);
1167
1198
  const drift = word ? `, ${word}` : "";
1168
1199
  const aria = ui?.chartAria ? ui.chartAria(vm.opening, vm.current, word, vm.windowHours) : `Price movement over the last ${vm.windowHours} hours: opened at ${vm.opening}, currently ${vm.current}${drift}.`;
1169
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "ss-w-omcard", children: [
1170
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "ss-w-om-head", children: [
1171
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "ss-w-om-market", children: vm.market }),
1172
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "ss-w-om-tag", children: ui?.priceMovement ?? "Price movement" })
1200
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "ss-w-omcard", children: [
1201
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "ss-w-om-head", children: [
1202
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "ss-w-om-market", children: vm.market }),
1203
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "ss-w-om-tag", children: ui?.priceMovement ?? "Price movement" })
1173
1204
  ] }),
1174
- vm.fixture ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "ss-w-om-fixture", children: [
1175
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: vm.fixture }),
1176
- vm.competition ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "ss-w-om-comp", children: vm.competition }) : null
1205
+ vm.fixture ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "ss-w-om-fixture", children: [
1206
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: vm.fixture }),
1207
+ vm.competition ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "ss-w-om-comp", children: vm.competition }) : null
1177
1208
  ] }) : null,
1178
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "ss-w-om-sel", children: vm.selection }),
1179
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(OddsMovementBadge, { previous: vm.opening, current: vm.current, direction: vm.direction, ui }),
1180
- vm.geometry === null ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "ss-w-om-empty", children: vm.observationCount === 1 ? ui?.singlePricePoint ?? "Only one price recorded so far for this selection." : ui?.notEnoughHistory ?? "No price history recorded yet for this selection." }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
1209
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "ss-w-om-sel", children: vm.selection }),
1210
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(OddsMovementBadge, { previous: vm.opening, current: vm.current, direction: vm.direction, ui }),
1211
+ vm.geometry === null ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "ss-w-om-empty", children: vm.observationCount === 1 ? ui?.singlePricePoint ?? "Only one price recorded so far for this selection." : ui?.notEnoughHistory ?? "No price history recorded yet for this selection." }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
1181
1212
  "svg",
1182
1213
  {
1183
1214
  className: "ss-w-om-chart",
@@ -1186,83 +1217,83 @@ function OddsMovementCard({ vm, ui }) {
1186
1217
  role: "img",
1187
1218
  "aria-label": aria,
1188
1219
  children: [
1189
- vm.geometry.gridlines.map((g) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("g", { children: [
1190
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("line", { className: "ss-w-om-grid", x1: 40, y1: g.y, x2: CHART_VIEW_W - 8, y2: g.y }),
1191
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("text", { className: "ss-w-om-ylab", x: 34, y: g.y + 3, textAnchor: "end", children: g.price.toFixed(2) })
1220
+ vm.geometry.gridlines.map((g) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("g", { children: [
1221
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("line", { className: "ss-w-om-grid", x1: 40, y1: g.y, x2: CHART_VIEW_W - 8, y2: g.y }),
1222
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("text", { className: "ss-w-om-ylab", x: 34, y: g.y + 3, textAnchor: "end", children: g.price.toFixed(2) })
1192
1223
  ] }, g.price)),
1193
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { className: "ss-w-om-line", d: vm.geometry.path, fill: "none" }),
1194
- vm.geometry.markers.map((m, i) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("circle", { className: "ss-w-om-dot", cx: m.x, cy: m.y, r: 2.5 }, i)),
1195
- ui?.chartTimeLabel ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
1196
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("text", { className: "ss-w-om-xlab", x: 40, y: CHART_VIEW_H - 8, textAnchor: "start", children: ui.chartTimeLabel(vm.geometry.startMs) }),
1197
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("text", { className: "ss-w-om-xlab", x: CHART_VIEW_W - 8, y: CHART_VIEW_H - 8, textAnchor: "end", children: ui.chartTimeLabel(vm.geometry.endMs) })
1198
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("text", { className: "ss-w-om-xlab", x: 40, y: CHART_VIEW_H - 8, children: ui?.movementWindow ? ui.movementWindow(vm.windowHours) : `Last ${vm.windowHours}h` })
1224
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { className: "ss-w-om-line", d: vm.geometry.path, fill: "none" }),
1225
+ vm.geometry.markers.map((m, i) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("circle", { className: "ss-w-om-dot", cx: m.x, cy: m.y, r: 2.5 }, i)),
1226
+ ui?.chartTimeLabel ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
1227
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("text", { className: "ss-w-om-xlab", x: 40, y: CHART_VIEW_H - 8, textAnchor: "start", children: ui.chartTimeLabel(vm.geometry.startMs) }),
1228
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("text", { className: "ss-w-om-xlab", x: CHART_VIEW_W - 8, y: CHART_VIEW_H - 8, textAnchor: "end", children: ui.chartTimeLabel(vm.geometry.endMs) })
1229
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("text", { className: "ss-w-om-xlab", x: 40, y: CHART_VIEW_H - 8, children: ui?.movementWindow ? ui.movementWindow(vm.windowHours) : `Last ${vm.windowHours}h` })
1199
1230
  ]
1200
1231
  }
1201
1232
  ),
1202
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "ss-w-om-foot", children: [
1203
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { children: [
1233
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "ss-w-om-foot", children: [
1234
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { children: [
1204
1235
  ui?.openingLabel ?? "Opening",
1205
1236
  " ",
1206
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("b", { children: vm.opening })
1237
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("b", { children: vm.opening })
1207
1238
  ] }),
1208
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { children: [
1239
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { children: [
1209
1240
  ui?.currentLabel ?? "Current",
1210
1241
  " ",
1211
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("b", { children: vm.current })
1242
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("b", { children: vm.current })
1212
1243
  ] })
1213
1244
  ] }),
1214
- vm.bookmaker ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "ss-w-om-foot", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: vm.bookmaker }) }) : null,
1215
- vm.excludedCount > 0 ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "ss-w-om-excl", children: ui?.excludedSuspended ? ui.excludedSuspended(vm.excludedCount) : `${vm.excludedCount} suspended price(s) excluded from this chart.` }) : null,
1216
- vm.isSuspended ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "ss-w-om-susp", children: ui?.selectionSuspended ?? "This selection is not currently available to bet." }) : null,
1217
- vm.disclaimer ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "ss-w-om-disc", children: vm.disclaimer }) : null
1245
+ vm.bookmaker ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "ss-w-om-foot", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: vm.bookmaker }) }) : null,
1246
+ vm.excludedCount > 0 ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "ss-w-om-excl", children: ui?.excludedSuspended ? ui.excludedSuspended(vm.excludedCount) : `${vm.excludedCount} suspended price(s) excluded from this chart.` }) : null,
1247
+ vm.isSuspended ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "ss-w-om-susp", children: ui?.selectionSuspended ?? "This selection is not currently available to bet." }) : null,
1248
+ vm.disclaimer ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "ss-w-om-disc", children: vm.disclaimer }) : null
1218
1249
  ] });
1219
1250
  }
1220
1251
  function OddsMovementCardList({ cards, ui }) {
1221
1252
  if (!cards || cards.length === 0) return null;
1222
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "ss-w-omcards", children: cards.map((vm) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(OddsMovementCard, { vm, ui }, vm.id)) });
1253
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "ss-w-omcards", children: cards.map((vm) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(OddsMovementCard, { vm, ui }, vm.id)) });
1223
1254
  }
1224
1255
 
1225
1256
  // src/components/ActionButtons.tsx
1226
- var import_jsx_runtime13 = require("react/jsx-runtime");
1257
+ var import_jsx_runtime14 = require("react/jsx-runtime");
1227
1258
  function ActionButtons({ actions, loading, disabled, onAct }) {
1228
1259
  if (actions.length === 0 && !loading) return null;
1229
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "ss-w-actions", children: [
1230
- actions.map((a, i) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", className: "ss-w-abtn", disabled, onClick: () => onAct(a), children: a.label }, `${a.label}-${i}`)),
1231
- actions.length === 0 && loading ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
1232
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "ss-w-abtn-shimmer" }),
1233
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "ss-w-abtn-shimmer" })
1260
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "ss-w-actions", children: [
1261
+ actions.map((a, i) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", className: "ss-w-abtn", disabled, onClick: () => onAct(a), children: a.label }, `${a.label}-${i}`)),
1262
+ actions.length === 0 && loading ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
1263
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "ss-w-abtn-shimmer" }),
1264
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "ss-w-abtn-shimmer" })
1234
1265
  ] }) : null
1235
1266
  ] });
1236
1267
  }
1237
1268
 
1238
1269
  // src/components/dashboard/DashboardTile.tsx
1239
- var import_jsx_runtime14 = require("react/jsx-runtime");
1270
+ var import_jsx_runtime15 = require("react/jsx-runtime");
1240
1271
  var MAX_CRESTS = 3;
1241
1272
  function DashboardTile({ tile, onTap }) {
1242
1273
  const spanClass = tile.span === "full" ? "ss-w-dash-tile--full" : "ss-w-dash-tile--half";
1243
1274
  const crests = (tile.imageUrls ?? []).slice(0, MAX_CRESTS);
1244
1275
  const hasMeta = Boolean(tile.badgeText) || crests.length > 0;
1245
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("button", { type: "button", className: `ss-w-dash-tile ${spanClass}`, onClick: onTap, children: [
1246
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "ss-w-dash-tile-icon", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(DashboardIcon, { name: tile.icon }) }),
1247
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "ss-w-dash-tile-body", children: [
1248
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "ss-w-dash-tile-title", children: tile.title }),
1249
- tile.subtitle ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "ss-w-dash-tile-subtitle", children: tile.subtitle }) : null,
1276
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("button", { type: "button", className: `ss-w-dash-tile ${spanClass}`, onClick: onTap, children: [
1277
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "ss-w-dash-tile-icon", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(DashboardIcon, { name: tile.icon }) }),
1278
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { className: "ss-w-dash-tile-body", children: [
1279
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "ss-w-dash-tile-title", children: tile.title }),
1280
+ tile.subtitle ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "ss-w-dash-tile-subtitle", children: tile.subtitle }) : null,
1250
1281
  hasMeta ? (
1251
1282
  // Badge + crests sit on their own row, below the title, instead of sharing the
1252
1283
  // icon/chevron row -- at the half-span tile's ~180px width a nowrap badge alone
1253
1284
  // (~70px) left the title column at ~22px and forced character-by-character wrapping.
1254
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "ss-w-dash-tile-meta", children: [
1255
- tile.badgeText ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "ss-w-dash-tile-badge", children: tile.badgeText }) : null,
1256
- crests.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "ss-w-dash-tile-crests", children: crests.map((url, i) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "ss-w-dash-tile-crest", style: { backgroundImage: `url(${url})` }, "aria-hidden": "true" }, `${url}-${i}`)) }) : null
1285
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { className: "ss-w-dash-tile-meta", children: [
1286
+ tile.badgeText ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "ss-w-dash-tile-badge", children: tile.badgeText }) : null,
1287
+ crests.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "ss-w-dash-tile-crests", children: crests.map((url, i) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "ss-w-dash-tile-crest", style: { backgroundImage: `url(${url})` }, "aria-hidden": "true" }, `${url}-${i}`)) }) : null
1257
1288
  ] })
1258
1289
  ) : null
1259
1290
  ] }),
1260
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "ss-w-dash-tile-chevron", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ChevronIcon, {}) })
1291
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "ss-w-dash-tile-chevron", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ChevronIcon, {}) })
1261
1292
  ] });
1262
1293
  }
1263
1294
 
1264
1295
  // src/components/dashboard/GreetingDashboard.tsx
1265
- var import_jsx_runtime15 = require("react/jsx-runtime");
1296
+ var import_jsx_runtime16 = require("react/jsx-runtime");
1266
1297
  var LAYOUT_CLASSES = {
1267
1298
  market: "ss-w-dash--market",
1268
1299
  goal: "ss-w-dash--goal",
@@ -1272,106 +1303,140 @@ function layoutClass(layout) {
1272
1303
  return Object.prototype.hasOwnProperty.call(LAYOUT_CLASSES, layout) ? LAYOUT_CLASSES[layout] : LAYOUT_CLASSES.goal;
1273
1304
  }
1274
1305
  function GreetingDashboard({ dashboard, onTap }) {
1275
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: `ss-w-dash ${layoutClass(dashboard.layout)}`, children: [
1276
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "ss-w-dash-head", children: [
1277
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "ss-w-dash-title", children: dashboard.title }),
1278
- dashboard.subtitle ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "ss-w-dash-subtitle", children: dashboard.subtitle }) : null
1306
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: `ss-w-dash ${layoutClass(dashboard.layout)}`, children: [
1307
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "ss-w-dash-head", children: [
1308
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "ss-w-dash-title", children: dashboard.title }),
1309
+ dashboard.subtitle ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "ss-w-dash-subtitle", children: dashboard.subtitle }) : null
1279
1310
  ] }),
1280
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "ss-w-dash-grid", children: dashboard.tiles.map((t, i) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(DashboardTile, { tile: t, onTap: () => onTap(t, i) }, `${t.title}-${i}`)) }),
1281
- dashboard.footerTip ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "ss-w-dash-foot", children: dashboard.footerTip }) : null
1311
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "ss-w-dash-grid", children: dashboard.tiles.map((t, i) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(DashboardTile, { tile: t, onTap: () => onTap(t, i) }, `${t.title}-${i}`)) }),
1312
+ dashboard.footerTip ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "ss-w-dash-foot", children: dashboard.footerTip }) : null
1282
1313
  ] });
1283
1314
  }
1284
1315
 
1285
1316
  // src/components/club-dashboard/GreetingHeaderBlock.tsx
1286
- var import_jsx_runtime16 = require("react/jsx-runtime");
1317
+ var import_jsx_runtime17 = require("react/jsx-runtime");
1287
1318
  function GreetingHeaderBlock({ block }) {
1288
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "ss-w-cdash-greeting", children: [
1289
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "ss-w-cdash-greeting-title", children: block.title }),
1290
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "ss-w-cdash-greeting-subtitle", children: block.subtitle })
1319
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "ss-w-cdash-greeting", children: [
1320
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "ss-w-cdash-greeting-title", children: block.title }),
1321
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "ss-w-cdash-greeting-subtitle", children: block.subtitle })
1291
1322
  ] });
1292
1323
  }
1293
1324
 
1294
1325
  // src/components/club-dashboard/FixtureHeroBlock.tsx
1295
- var import_react7 = require("react");
1296
- var import_jsx_runtime17 = require("react/jsx-runtime");
1326
+ var import_react8 = require("react");
1327
+ var import_jsx_runtime18 = require("react/jsx-runtime");
1297
1328
  function initials3(name) {
1298
1329
  return name.split(/\s+/).filter(Boolean).slice(0, 2).map((w) => w[0].toUpperCase()).join("");
1299
1330
  }
1300
1331
  function Crest3({ url, name }) {
1301
- const [broken, setBroken] = (0, import_react7.useState)(false);
1332
+ const [broken, setBroken] = (0, import_react8.useState)(false);
1302
1333
  if (!url || broken) {
1303
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "ss-w-cdash-crest ss-w-cdash-crest--fallback", "aria-hidden": "true", children: initials3(name) });
1334
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "ss-w-cdash-crest ss-w-cdash-crest--fallback", "aria-hidden": "true", children: initials3(name) });
1304
1335
  }
1305
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("img", { className: "ss-w-cdash-crest", src: url, alt: "", "aria-hidden": "true", onError: () => setBroken(true) });
1336
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("img", { className: "ss-w-cdash-crest", src: url, alt: "", "aria-hidden": "true", onError: () => setBroken(true) });
1306
1337
  }
1307
1338
  function FixtureHeroBlock({
1308
1339
  block,
1309
1340
  ui,
1310
1341
  onAction
1311
1342
  }) {
1312
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "ss-w-cdash-fixture", children: [
1313
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "ss-w-cdash-tie", children: [
1314
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Crest3, { url: block.homeCrestUrl, name: block.homeName }),
1315
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "ss-w-cdash-team", children: block.homeName }),
1316
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "ss-w-cdash-vs", children: "v" }),
1317
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "ss-w-cdash-team", children: block.awayName }),
1318
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Crest3, { url: block.awayCrestUrl, name: block.awayName })
1343
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "ss-w-cdash-fixture", children: [
1344
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "ss-w-cdash-tie", children: [
1345
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Crest3, { url: block.homeCrestUrl, name: block.homeName }),
1346
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "ss-w-cdash-team", children: block.homeName }),
1347
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "ss-w-cdash-vs", children: "v" }),
1348
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "ss-w-cdash-team", children: block.awayName }),
1349
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Crest3, { url: block.awayCrestUrl, name: block.awayName })
1319
1350
  ] }),
1320
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "ss-w-cdash-fixture-meta", children: [
1321
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "ss-w-cdash-kickoff", children: ui.clubKickoff(block.kickoffUnix * 1e3) }),
1322
- block.venue ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "ss-w-cdash-venue", children: block.venue }) : null,
1323
- block.competition ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "ss-w-cdash-comp", children: block.competition }) : null
1351
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "ss-w-cdash-fixture-meta", children: [
1352
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "ss-w-cdash-kickoff", children: ui.clubKickoff(block.kickoffUnix * 1e3) }),
1353
+ block.venue ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "ss-w-cdash-venue", children: block.venue }) : null,
1354
+ block.competition ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "ss-w-cdash-comp", children: block.competition }) : null
1324
1355
  ] }),
1325
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("button", { type: "button", className: "ss-w-cdash-cta", onClick: () => onAction(block.ctaActionValue, block.ctaLabel), children: block.ctaLabel })
1356
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("button", { type: "button", className: "ss-w-cdash-cta", onClick: () => onAction(block.ctaActionValue, void 0, block.ctaLabel), children: block.ctaLabel })
1326
1357
  ] });
1327
1358
  }
1328
1359
 
1329
1360
  // src/components/club-dashboard/FormGuideBlock.tsx
1330
- var import_jsx_runtime18 = require("react/jsx-runtime");
1361
+ var import_jsx_runtime19 = require("react/jsx-runtime");
1331
1362
  function FormGuideBlock({ block }) {
1332
1363
  if (block.rows.length === 0) return null;
1333
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "ss-w-cdash-form", children: block.rows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "ss-w-cdash-form-row", children: [
1334
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { className: "ss-w-cdash-form-name", children: [
1364
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "ss-w-cdash-form", children: block.rows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "ss-w-cdash-form-row", children: [
1365
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { className: "ss-w-cdash-form-name", children: [
1335
1366
  row.name,
1336
1367
  row.position != null ? ` #${row.position}` : ""
1337
1368
  ] }),
1338
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "ss-w-cdash-form-pills", children: row.last5.map((r, i) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: `ss-w-cdash-pill ss-w-cdash-pill--${r.toLowerCase()}`, children: r }, i)) })
1369
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "ss-w-cdash-form-pills", children: row.last5.map((r, i) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: `ss-w-cdash-pill ss-w-cdash-pill--${r.toLowerCase()}`, children: r }, i)) })
1339
1370
  ] }, row.name)) });
1340
1371
  }
1341
1372
 
1342
1373
  // src/components/club-dashboard/MatchPreviewBlock.tsx
1343
- var import_jsx_runtime19 = require("react/jsx-runtime");
1374
+ var import_jsx_runtime20 = require("react/jsx-runtime");
1344
1375
  function MatchPreviewBlock({
1345
1376
  block,
1346
1377
  ui,
1347
1378
  onAction
1348
1379
  }) {
1349
- if (block.lines.length === 0) return null;
1380
+ if (block.facts.length === 0) return null;
1350
1381
  const heading = ui.clubMatchPreviewHeading;
1351
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("button", { type: "button", className: "ss-w-cdash-lines", onClick: () => onAction(block.actionValue, heading), children: [
1352
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "ss-w-cdash-lines-heading", children: heading }),
1353
- block.lines.map((line, i) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { children: line }, i))
1382
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "ss-w-cdash-lines", children: [
1383
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "ss-w-cdash-lines-heading", children: heading }),
1384
+ block.facts.map(
1385
+ (f, i) => f.entityRef ? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
1386
+ "button",
1387
+ {
1388
+ type: "button",
1389
+ className: "ss-w-cdash-fact",
1390
+ onClick: () => onAction(f.question ?? f.sentence, { ...f.entityRef, subject: f.sentence, personaHint: "club" }),
1391
+ children: [
1392
+ f.sentence,
1393
+ f.label ? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { className: "ss-w-cdash-fact-label", children: [
1394
+ " ",
1395
+ f.label
1396
+ ] }) : null
1397
+ ]
1398
+ },
1399
+ i
1400
+ ) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { children: f.sentence }, i)
1401
+ )
1354
1402
  ] });
1355
1403
  }
1356
1404
 
1357
1405
  // src/components/club-dashboard/TeamDnaBlock.tsx
1358
- var import_jsx_runtime20 = require("react/jsx-runtime");
1406
+ var import_jsx_runtime21 = require("react/jsx-runtime");
1359
1407
  function TeamDnaBlock({
1360
1408
  block,
1361
1409
  ui,
1362
1410
  onAction
1363
1411
  }) {
1364
- if (block.lines.length === 0) return null;
1412
+ if (block.facts.length === 0) return null;
1365
1413
  const heading = ui.clubTeamDnaHeading;
1366
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("button", { type: "button", className: "ss-w-cdash-lines", onClick: () => onAction(block.actionValue, heading), children: [
1367
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "ss-w-cdash-lines-heading", children: heading }),
1368
- block.lines.map((line, i) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { children: line }, i))
1414
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "ss-w-cdash-lines", children: [
1415
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "ss-w-cdash-lines-heading", children: heading }),
1416
+ block.facts.map(
1417
+ (f, i) => f.entityRef ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
1418
+ "button",
1419
+ {
1420
+ type: "button",
1421
+ className: "ss-w-cdash-fact",
1422
+ onClick: () => onAction(f.question ?? f.sentence, { ...f.entityRef, subject: f.sentence, personaHint: "club" }),
1423
+ children: [
1424
+ f.sentence,
1425
+ f.label ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { className: "ss-w-cdash-fact-label", children: [
1426
+ " ",
1427
+ f.label
1428
+ ] }) : null
1429
+ ]
1430
+ },
1431
+ i
1432
+ ) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { children: f.sentence }, i)
1433
+ )
1369
1434
  ] });
1370
1435
  }
1371
1436
 
1372
1437
  // src/components/club-dashboard/CountdownBlock.tsx
1373
- var import_react8 = require("react");
1374
- var import_jsx_runtime21 = require("react/jsx-runtime");
1438
+ var import_react9 = require("react");
1439
+ var import_jsx_runtime22 = require("react/jsx-runtime");
1375
1440
  var DAY_MS = 24 * 3600 * 1e3;
1376
1441
  function pad2(n) {
1377
1442
  return String(n).padStart(2, "0");
@@ -1384,8 +1449,8 @@ function splitRemaining(remainingMs) {
1384
1449
  return { h: pad2(h), m: pad2(m), s: pad2(s) };
1385
1450
  }
1386
1451
  function CountdownBlock({ block, ui }) {
1387
- const [remainingMs, setRemainingMs] = (0, import_react8.useState)(() => block.kickoffUnix * 1e3 - Date.now());
1388
- (0, import_react8.useEffect)(() => {
1452
+ const [remainingMs, setRemainingMs] = (0, import_react9.useState)(() => block.kickoffUnix * 1e3 - Date.now());
1453
+ (0, import_react9.useEffect)(() => {
1389
1454
  setRemainingMs(block.kickoffUnix * 1e3 - Date.now());
1390
1455
  if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) return;
1391
1456
  const id = setInterval(() => {
@@ -1396,30 +1461,30 @@ function CountdownBlock({ block, ui }) {
1396
1461
  if (remainingMs <= 0) return null;
1397
1462
  if (remainingMs > DAY_MS) return null;
1398
1463
  const { h, m, s } = splitRemaining(remainingMs);
1399
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "ss-w-cdash-cd", "aria-label": ui.clubKickoffAria(block.kickoffUnix * 1e3), children: [
1400
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "ss-w-cdash-cd-clock", "aria-hidden": "true", children: [
1401
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "ss-w-cdash-cd-h", children: h }),
1464
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "ss-w-cdash-cd", "aria-label": ui.clubKickoffAria(block.kickoffUnix * 1e3), children: [
1465
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "ss-w-cdash-cd-clock", "aria-hidden": "true", children: [
1466
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "ss-w-cdash-cd-h", children: h }),
1402
1467
  "h",
1403
1468
  " ",
1404
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "ss-w-cdash-cd-m", children: m }),
1469
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "ss-w-cdash-cd-m", children: m }),
1405
1470
  "m",
1406
1471
  " ",
1407
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "ss-w-cdash-cd-s", children: s }),
1472
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "ss-w-cdash-cd-s", children: s }),
1408
1473
  "s"
1409
1474
  ] }),
1410
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "ss-w-cdash-cd-label", children: ui.clubCountdownLabel })
1475
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "ss-w-cdash-cd-label", children: ui.clubCountdownLabel })
1411
1476
  ] });
1412
1477
  }
1413
1478
 
1414
1479
  // src/components/club-dashboard/ClubDashboard.tsx
1415
- var import_jsx_runtime22 = require("react/jsx-runtime");
1480
+ var import_jsx_runtime23 = require("react/jsx-runtime");
1416
1481
  var CLUB_BLOCK_REGISTRY = {
1417
- greetingHeader: ({ block }) => block.type === "greetingHeader" ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(GreetingHeaderBlock, { block }) : null,
1418
- fixtureHero: ({ block, ui, onAction }) => block.type === "fixtureHero" ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(FixtureHeroBlock, { block, ui, onAction }) : null,
1419
- formGuide: ({ block, ui }) => block.type === "formGuide" ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(FormGuideBlock, { block, ui }) : null,
1420
- matchPreview: ({ block, ui, onAction }) => block.type === "matchPreview" ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(MatchPreviewBlock, { block, ui, onAction }) : null,
1421
- teamDna: ({ block, ui, onAction }) => block.type === "teamDna" ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TeamDnaBlock, { block, ui, onAction }) : null,
1422
- countdown: ({ block, ui }) => block.type === "countdown" ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(CountdownBlock, { block, ui }) : null
1482
+ greetingHeader: ({ block }) => block.type === "greetingHeader" ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(GreetingHeaderBlock, { block }) : null,
1483
+ fixtureHero: ({ block, ui, onAction }) => block.type === "fixtureHero" ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(FixtureHeroBlock, { block, ui, onAction }) : null,
1484
+ formGuide: ({ block, ui }) => block.type === "formGuide" ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(FormGuideBlock, { block, ui }) : null,
1485
+ matchPreview: ({ block, ui, onAction }) => block.type === "matchPreview" ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(MatchPreviewBlock, { block, ui, onAction }) : null,
1486
+ teamDna: ({ block, ui, onAction }) => block.type === "teamDna" ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TeamDnaBlock, { block, ui, onAction }) : null,
1487
+ countdown: ({ block, ui }) => block.type === "countdown" ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CountdownBlock, { block, ui }) : null
1423
1488
  };
1424
1489
  function ClubDashboard({
1425
1490
  dashboard,
@@ -1427,39 +1492,39 @@ function ClubDashboard({
1427
1492
  onAction
1428
1493
  }) {
1429
1494
  if (!dashboard.blocks.length) return null;
1430
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "ss-w-cdash", children: dashboard.blocks.map((block, i) => {
1495
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "ss-w-cdash", children: dashboard.blocks.map((block, i) => {
1431
1496
  const Comp = Object.prototype.hasOwnProperty.call(CLUB_BLOCK_REGISTRY, block.type) ? CLUB_BLOCK_REGISTRY[block.type] : void 0;
1432
1497
  if (!Comp) {
1433
1498
  console.warn(`[club-dashboard] no renderer for block type "${block.type}"`);
1434
1499
  return null;
1435
1500
  }
1436
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "ss-w-cdash-block", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Comp, { block, ui, onAction }) }, i);
1501
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "ss-w-cdash-block", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Comp, { block, ui, onAction }) }, i);
1437
1502
  }) });
1438
1503
  }
1439
1504
 
1440
1505
  // src/components/ChatMessage.tsx
1441
- var import_jsx_runtime23 = require("react/jsx-runtime");
1506
+ var import_jsx_runtime24 = require("react/jsx-runtime");
1442
1507
  function ChatMessage({ message, disabled, onAct, onTap, onClubAction, ui, slip }) {
1443
1508
  if (message.role === "user") {
1444
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "ss-w-msg ss-w-user", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "ss-w-bubble", children: message.text }) });
1509
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "ss-w-msg ss-w-user", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "ss-w-bubble", children: message.text }) });
1445
1510
  }
1446
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "ss-w-msg ss-w-bot", children: [
1447
- message.text && !message.greetingDashboard && !message.clubDashboard ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Markdown, { text: message.text }) : null,
1448
- message.greetingDashboard ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(GreetingDashboard, { dashboard: message.greetingDashboard, onTap }) : null,
1449
- message.clubDashboard && ui ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ClubDashboard, { dashboard: message.clubDashboard, ui, onAction: onClubAction }) : null,
1450
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(EntityCardList, { cards: message.cards, disabled, showLessLabel: ui?.showLess, showMoreLabel: ui?.showMore }),
1451
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(BettingInsightList, { insights: message.insights, ui, slip }),
1452
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(MarketOddsCardList, { cards: message.marketOdds, ui, slip }),
1453
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(OddsMovementCardList, { cards: message.oddsMovement, ui }),
1454
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ActionButtons, { actions: message.actions, loading: false, disabled, onAct })
1511
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "ss-w-msg ss-w-bot", children: [
1512
+ message.text && !message.greetingDashboard && !message.clubDashboard ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Markdown, { text: message.text }) : null,
1513
+ message.greetingDashboard ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(GreetingDashboard, { dashboard: message.greetingDashboard, onTap }) : null,
1514
+ message.clubDashboard && ui ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ClubDashboard, { dashboard: message.clubDashboard, ui, onAction: onClubAction }) : null,
1515
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(EntityCardList, { cards: message.cards, disabled, showLessLabel: ui?.showLess, showMoreLabel: ui?.showMore }),
1516
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(BettingInsightList, { insights: message.insights, ui, slip }),
1517
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(MarketOddsCardList, { cards: message.marketOdds, ui, slip }),
1518
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(OddsMovementCardList, { cards: message.oddsMovement, ui }),
1519
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ActionButtons, { actions: message.actions, loading: false, disabled, onAct })
1455
1520
  ] });
1456
1521
  }
1457
1522
 
1458
1523
  // src/components/IntentChips.tsx
1459
- var import_jsx_runtime24 = require("react/jsx-runtime");
1524
+ var import_jsx_runtime25 = require("react/jsx-runtime");
1460
1525
  function IntentChips({ chips, onPick }) {
1461
1526
  if (chips.length === 0) return null;
1462
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "ss-w-chips", children: chips.map((c, i) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("button", { type: "button", className: "ss-w-chip", onClick: () => onPick(c.text), children: c.text }, `${c.text}-${i}`)) });
1527
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "ss-w-chips", children: chips.map((c, i) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { type: "button", className: "ss-w-chip", onClick: () => onPick(c.text), children: c.text }, `${c.text}-${i}`)) });
1463
1528
  }
1464
1529
 
1465
1530
  // src/scroll.ts
@@ -1469,18 +1534,18 @@ function isPinnedToBottom(el, threshold = PIN_THRESHOLD) {
1469
1534
  }
1470
1535
 
1471
1536
  // src/components/MessageList.tsx
1472
- var import_jsx_runtime25 = require("react/jsx-runtime");
1537
+ var import_jsx_runtime26 = require("react/jsx-runtime");
1473
1538
  function MessageList({ controller, ui, slip, onDashboardTap }) {
1474
1539
  const { state, send } = controller;
1475
- const listRef = (0, import_react9.useRef)(null);
1476
- const endRef = (0, import_react9.useRef)(null);
1477
- const pinnedRef = (0, import_react9.useRef)(true);
1478
- (0, import_react9.useEffect)(() => {
1540
+ const listRef = (0, import_react10.useRef)(null);
1541
+ const endRef = (0, import_react10.useRef)(null);
1542
+ const pinnedRef = (0, import_react10.useRef)(true);
1543
+ (0, import_react10.useEffect)(() => {
1479
1544
  if (pinnedRef.current) endRef.current?.scrollIntoView({ block: "end" });
1480
1545
  }, [state.messages, state.status]);
1481
1546
  const hasUserMessage = state.messages.some((m) => m.role === "user");
1482
1547
  const hasDashboard = state.messages.some((m) => m.role === "assistant" && m.greetingDashboard);
1483
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
1548
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
1484
1549
  "div",
1485
1550
  {
1486
1551
  className: "ss-w-list",
@@ -1490,7 +1555,7 @@ function MessageList({ controller, ui, slip, onDashboardTap }) {
1490
1555
  if (listRef.current) pinnedRef.current = isPinnedToBottom(listRef.current);
1491
1556
  },
1492
1557
  children: [
1493
- state.messages.map((m) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
1558
+ state.messages.map((m) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
1494
1559
  ChatMessage,
1495
1560
  {
1496
1561
  message: m,
@@ -1500,31 +1565,31 @@ function MessageList({ controller, ui, slip, onDashboardTap }) {
1500
1565
  send(tile.actionValue, { displayText: tile.title });
1501
1566
  if (m.role === "assistant" && m.greetingDashboard) onDashboardTap?.(tile, index, m.greetingDashboard.layout);
1502
1567
  },
1503
- onClubAction: (actionValue, displayText) => send(actionValue, { displayText }),
1568
+ onClubAction: (message, grounding, displayText) => send(message, { grounding, displayText: displayText ?? message }),
1504
1569
  ui,
1505
1570
  slip
1506
1571
  },
1507
1572
  m.id
1508
1573
  )),
1509
- state.isStreaming && state.actionsLoading ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ActionButtons, { actions: [], loading: true, onAct: () => {
1574
+ state.isStreaming && state.actionsLoading ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ActionButtons, { actions: [], loading: true, onAct: () => {
1510
1575
  } }) : null,
1511
- state.status ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "ss-w-status", children: state.status }) : null,
1512
- state.error ? /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "ss-w-error", role: "alert", children: [
1513
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { children: "message" in state.error ? state.error.message : ui.somethingWentWrong }),
1514
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { type: "button", className: "ss-w-retry", onClick: () => controller.retry(), children: ui.retry })
1576
+ state.status ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "ss-w-status", children: state.status }) : null,
1577
+ state.error ? /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "ss-w-error", role: "alert", children: [
1578
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { children: "message" in state.error ? state.error.message : ui.somethingWentWrong }),
1579
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("button", { type: "button", className: "ss-w-retry", onClick: () => controller.retry(), children: ui.retry })
1515
1580
  ] }) : null,
1516
- !hasUserMessage && !hasDashboard ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(IntentChips, { chips: state.starters, onPick: (t) => send(t) }) : null,
1517
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { ref: endRef })
1581
+ !hasUserMessage && !hasDashboard ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(IntentChips, { chips: state.starters, onPick: (t) => send(t) }) : null,
1582
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { ref: endRef })
1518
1583
  ]
1519
1584
  }
1520
1585
  );
1521
1586
  }
1522
1587
 
1523
1588
  // src/components/ChatInput.tsx
1524
- var import_react10 = require("react");
1525
- var import_jsx_runtime26 = require("react/jsx-runtime");
1589
+ var import_react11 = require("react");
1590
+ var import_jsx_runtime27 = require("react/jsx-runtime");
1526
1591
  function ChatInput({ placeholder, streaming, onSend, onStop, stopLabel = "Stop response", sendLabel = "Send message" }) {
1527
- const [value, setValue] = (0, import_react10.useState)("");
1592
+ const [value, setValue] = (0, import_react11.useState)("");
1528
1593
  const submit = () => {
1529
1594
  const t = value.trim();
1530
1595
  if (!t) return;
@@ -1537,18 +1602,18 @@ function ChatInput({ placeholder, streaming, onSend, onStop, stopLabel = "Stop r
1537
1602
  submit();
1538
1603
  }
1539
1604
  };
1540
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "ss-w-input", children: [
1541
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("textarea", { className: "ss-w-textarea", rows: 1, placeholder, value, disabled: streaming, onChange: (e) => setValue(e.target.value), onKeyDown }),
1542
- streaming ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("button", { type: "button", className: "ss-w-send ss-w-stop", "aria-label": stopLabel, onClick: onStop, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "ss-w-stop-glyph" }) }) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("button", { type: "button", className: "ss-w-send", "aria-label": sendLabel, onClick: submit, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(SendIcon, {}) })
1605
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "ss-w-input", children: [
1606
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("textarea", { className: "ss-w-textarea", rows: 1, placeholder, value, disabled: streaming, onChange: (e) => setValue(e.target.value), onKeyDown }),
1607
+ streaming ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("button", { type: "button", className: "ss-w-send ss-w-stop", "aria-label": stopLabel, onClick: onStop, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "ss-w-stop-glyph" }) }) : /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("button", { type: "button", className: "ss-w-send", "aria-label": sendLabel, onClick: submit, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(SendIcon, {}) })
1543
1608
  ] });
1544
1609
  }
1545
1610
 
1546
1611
  // src/components/ChatPanel.tsx
1547
- var import_jsx_runtime27 = require("react/jsx-runtime");
1612
+ var import_jsx_runtime28 = require("react/jsx-runtime");
1548
1613
  var FULLSCREEN_QUERY = "(max-width: 639px)";
1549
1614
  function useIsModal() {
1550
- const [modal, setModal] = (0, import_react11.useState)(false);
1551
- (0, import_react11.useEffect)(() => {
1615
+ const [modal, setModal] = (0, import_react12.useState)(false);
1616
+ (0, import_react12.useEffect)(() => {
1552
1617
  if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
1553
1618
  const mql = window.matchMedia(FULLSCREEN_QUERY);
1554
1619
  const sync = () => setModal(mql.matches);
@@ -1561,17 +1626,17 @@ function useIsModal() {
1561
1626
  function ChatPanel({ controller, ui, slip, onDashboardTap }) {
1562
1627
  const { state, close, stop, send } = controller;
1563
1628
  const isModal = useIsModal();
1564
- (0, import_react11.useEffect)(() => {
1629
+ (0, import_react12.useEffect)(() => {
1565
1630
  const onKey = (e) => {
1566
1631
  if (e.key === "Escape") close();
1567
1632
  };
1568
1633
  window.addEventListener("keydown", onKey);
1569
1634
  return () => window.removeEventListener("keydown", onKey);
1570
1635
  }, [close]);
1571
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "ss-w-panel", role: "dialog", "aria-modal": isModal, "aria-label": ui.chatDialogLabel, children: [
1572
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ChatHeader, { onClose: close, closeLabel: ui.closeChat }),
1573
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(MessageList, { controller, ui, slip, onDashboardTap }),
1574
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ChatInput, { placeholder: ui.placeholder, streaming: state.isStreaming, onSend: (t) => send(t), onStop: stop, stopLabel: ui.stopResponse, sendLabel: ui.sendMessage })
1636
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "ss-w-panel", role: "dialog", "aria-modal": isModal, "aria-label": ui.chatDialogLabel, children: [
1637
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(ChatHeader, { onClose: close, closeLabel: ui.closeChat }),
1638
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(MessageList, { controller, ui, slip, onDashboardTap }),
1639
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(ChatInput, { placeholder: ui.placeholder, streaming: state.isStreaming, onSend: (t) => send(t), onStop: stop, stopLabel: ui.stopResponse, sendLabel: ui.sendMessage })
1575
1640
  ] });
1576
1641
  }
1577
1642
 
@@ -1619,7 +1684,7 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
1619
1684
  .ss-w-greeting-x { flex: none; background: none; border: none; color: var(--ss-w-faint); cursor: pointer; font-size: 17px; line-height: 1; padding: 7px 9px 0 2px; }
1620
1685
 
1621
1686
  /* panel */
1622
- .ss-w-panel { position: fixed; bottom: calc(var(--ss-w-offset-y) + 72px); z-index: 2147483000; display: flex; flex-direction: column; width: min(400px, calc(100vw - 40px)); height: min(620px, calc(100vh - 120px)); background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); border-radius: var(--ss-w-radius); overflow: hidden; box-shadow: 0 12px 40px rgba(0,0,0,.24); }
1687
+ .ss-w-panel { position: fixed; bottom: calc(var(--ss-w-offset-y) + 72px); z-index: 2147483000; display: flex; flex-direction: column; width: min(460px, calc(100vw - 40px)); height: min(640px, calc(100vh - 120px)); background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); border-radius: var(--ss-w-radius); overflow: hidden; box-shadow: 0 12px 40px rgba(0,0,0,.24); }
1623
1688
  .ss-w-root[data-ss-w-pos="right"] .ss-w-panel { right: var(--ss-w-offset-x); }
1624
1689
  .ss-w-root[data-ss-w-pos="left"] .ss-w-panel { left: var(--ss-w-offset-x); }
1625
1690
  @media (max-width: 639px) {
@@ -1722,9 +1787,9 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
1722
1787
  .ss-w-bi-floor { font-size: 8.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--ss-w-faint); background: var(--ss-w-bubble); border: 1px solid var(--ss-w-line); border-radius: 4px; padding: 1px 5px; display: inline-flex; align-items: center; align-self: flex-start; flex: none; }
1723
1788
 
1724
1789
  /* crests -- CSS background-image on a span, never <img> (matches .ss-w-ecard-crest precedent) */
1725
- .ss-w-bi-comp-logo { width: 15px; height: 15px; flex: none; display: block; border-radius: 50%; background-size: contain; background-repeat: no-repeat; background-position: center; }
1726
- .ss-w-bi-crest { width: 22px; height: 22px; flex: none; display: block; border-radius: 50%; background-size: contain; background-repeat: no-repeat; background-position: center; background-color: var(--ss-w-bubble); border: 1px solid var(--ss-w-line); }
1727
- .ss-w-bi-crest-mono { display: grid; place-items: center; font-size: 9px; font-weight: 700; color: var(--ss-w-accent); background: color-mix(in srgb, var(--ss-w-accent) 16%, var(--ss-w-panel)); }
1790
+ .ss-w-bi-comp-logo { width: 16px; height: 16px; flex: none; display: block; border-radius: 50%; object-fit: contain; }
1791
+ .ss-w-bi-crest { width: 24px; height: 24px; flex: none; display: block; border-radius: 50%; object-fit: contain; }
1792
+ .ss-w-bi-crest-mono { display: grid; place-items: center; font-size: 10px; font-weight: 700; color: var(--ss-w-accent); background: color-mix(in srgb, var(--ss-w-accent) 16%, var(--ss-w-panel)); }
1728
1793
 
1729
1794
  /* row 2: crest-flanked fixture on the left, boxed action panel on the right */
1730
1795
  .ss-w-bi-body { display: flex; align-items: center; gap: 10px; }
@@ -1732,16 +1797,16 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
1732
1797
  .ss-w-bi-team { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
1733
1798
  .ss-w-bi-vs { font-size: 10px; font-weight: 600; color: var(--ss-w-faint); flex: none; }
1734
1799
  .ss-w-bi-fixture-txt { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
1735
- .ss-w-bi-action { margin-left: auto; flex: none; display: flex; flex-direction: column; align-items: stretch; gap: 6px; background: var(--ss-w-bubble); border: 1px solid var(--ss-w-line); border-radius: 12px; padding: 8px 10px; }
1736
- .ss-w-bi-action .ss-w-slip > button { flex: 1; text-align: center; }
1800
+ .ss-w-bi-action { margin-left: auto; flex: none; display: flex; flex-direction: column; align-items: flex-end; gap: 4px; min-width: 0; }
1801
+ .ss-w-bi-action .ss-w-slip { width: 100%; }
1802
+ .ss-w-bi-action .ss-w-slip > button { flex: 1; width: 100%; text-align: center; border-radius: 8px; }
1737
1803
  /* The action column is narrow; let its toast size to its own text and anchor to the card's right edge instead of being clipped to the button width. */
1738
1804
  .ss-w-bi-action .ss-w-toast { left: auto; right: 0; width: max-content; max-width: 210px; white-space: normal; }
1739
- .ss-w-bi-mkt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
1740
- .ss-w-bi-market { font-size: 13.5px; font-weight: 700; line-height: 1.25; color: var(--ss-w-ink); }
1741
- .ss-w-bi-sel { font-size: 11.5px; line-height: 1.3; color: var(--ss-w-faint); }
1742
- .ss-w-bi-odds { flex: none; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; gap: 1px; background: color-mix(in srgb, var(--ss-w-accent) 12%, var(--ss-w-panel)); border: 1px solid color-mix(in srgb, var(--ss-w-accent) 30%, var(--ss-w-line)); border-radius: 10px; padding: 4px 11px; min-width: 62px; }
1743
- .ss-w-bi-odds-cap { font-size: 9px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase; color: var(--ss-w-faint); }
1744
- .ss-w-bi-odds b { font-size: 19px; font-family: ui-monospace, monospace; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--ss-w-accent); line-height: 1.1; }
1805
+ .ss-w-bi-mkt { display: flex; flex-direction: column; gap: 1px; min-width: 0; align-items: flex-end; text-align: right; }
1806
+ .ss-w-bi-market { font-size: 12px; font-weight: 600; line-height: 1.2; color: var(--ss-w-faint); white-space: nowrap; }
1807
+ .ss-w-bi-sel { font-size: 11px; line-height: 1.25; color: var(--ss-w-faint); }
1808
+ .ss-w-bi-odds { flex: none; display: flex; align-items: baseline; justify-content: flex-end; gap: 5px; }
1809
+ .ss-w-bi-odds b { font-size: 23px; font-family: ui-monospace, monospace; font-weight: 800; font-variant-numeric: tabular-nums; color: var(--ss-w-accent); line-height: 1.05; }
1745
1810
  .ss-w-bi-book { font-size: 9.5px; color: var(--ss-w-faint); }
1746
1811
 
1747
1812
  /* row 3: bar-chart glyph + reasoning prose + stats-expander chevron, in a subtle strip */
@@ -1755,11 +1820,11 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
1755
1820
  }
1756
1821
  .ss-w-bi-reason-body { display: flex; flex-direction: column; gap: 8px; min-width: 0; flex: 1; }
1757
1822
  .ss-w-bi-text { font-size: 12px; line-height: 1.45; color: var(--ss-w-ink); }
1758
- .ss-w-bi-stats { display: flex; flex-direction: column; gap: 8px; }
1759
- .ss-w-bi-toggle { align-self: flex-start; display: inline-flex; align-items: center; gap: 5px; background: none; border: none; color: var(--ss-w-accent); font: inherit; font-size: 11.5px; font-weight: 600; padding: 2px 0; cursor: pointer; }
1760
- .ss-w-bi-toggle:hover { text-decoration: underline; }
1761
- .ss-w-bi-chev { width: 7px; height: 7px; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: translateY(-2px) rotate(45deg); transition: transform .15s ease; }
1762
- .ss-w-bi-chev-up { transform: translateY(1px) rotate(-135deg); }
1823
+ .ss-w-bi-text-clamp { display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
1824
+ .ss-w-bi-expand { flex: none; align-self: center; display: grid; place-items: center; width: 22px; height: 22px; margin: -2px -4px -2px 0; background: none; border: none; color: var(--ss-w-faint); cursor: pointer; }
1825
+ .ss-w-bi-expand:hover { color: var(--ss-w-ink); }
1826
+ .ss-w-bi-arrow { width: 7px; height: 7px; border-right: 1.6px solid currentColor; border-top: 1.6px solid currentColor; transform: rotate(45deg); transition: transform .15s ease; }
1827
+ .ss-w-bi-arrow-open { transform: rotate(135deg); }
1763
1828
  .ss-w-bi-rows { display: flex; flex-direction: column; }
1764
1829
  .ss-w-bi-row { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; padding: 5px 0; border-top: 1px solid var(--ss-w-line); }
1765
1830
  .ss-w-bi-row:first-child { border-top: none; }
@@ -1774,11 +1839,13 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
1774
1839
  /* market odds card */
1775
1840
  .ss-w-mocards { display: flex; flex-direction: column; gap: 7px; }
1776
1841
  .ss-w-mocard { background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); border-radius: 12px; border-left: 3px solid var(--ss-w-accent); padding: 9px 11px; display: flex; flex-direction: column; gap: 6px; }
1777
- .ss-w-mo-head { display: flex; align-items: center; gap: 8px; }
1778
- .ss-w-mo-market { font-size: 13px; font-weight: 700; color: var(--ss-w-ink); }
1779
- .ss-w-mo-tag { margin-left: auto; flex: none; font-size: 9px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase; color: var(--ss-w-faint); border: 1px solid var(--ss-w-line); border-radius: 8px; padding: 2px 7px; }
1780
- .ss-w-mo-fixture { display: flex; align-items: center; gap: 6px; font-size: 11.5px; color: var(--ss-w-faint); min-width: 0; }
1781
- .ss-w-mo-comp { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
1842
+ .ss-w-mo-sub { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
1843
+ .ss-w-mo-teams { font-size: 13px; font-weight: 650; color: var(--ss-w-ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
1844
+ .ss-w-mo-market { font-size: 11.5px; font-weight: 600; color: var(--ss-w-faint); }
1845
+ .ss-w-mo-more { align-self: flex-start; display: inline-flex; align-items: center; gap: 5px; background: none; border: none; color: var(--ss-w-accent); font: inherit; font-size: 11.5px; font-weight: 600; padding: 2px 0; cursor: pointer; }
1846
+ .ss-w-mo-more:hover { text-decoration: underline; }
1847
+ .ss-w-mo-more-chev { width: 7px; height: 7px; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: translateY(-2px) rotate(45deg); transition: transform .15s ease; }
1848
+ .ss-w-mo-more-chev-up { transform: translateY(1px) rotate(-135deg); }
1782
1849
  .ss-w-mo-rows { display: flex; flex-direction: column; gap: 4px; }
1783
1850
  .ss-w-mo-row { display: flex; align-items: center; gap: 10px; padding: 4px 0; border-bottom: 1px dashed var(--ss-w-line); }
1784
1851
  .ss-w-mo-row:last-child { border-bottom: none; }
@@ -1950,9 +2017,12 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
1950
2017
  .ss-w-cdash-pill--d { background: var(--ss-w-faint); }
1951
2018
  .ss-w-cdash-pill--l { background: color-mix(in srgb, var(--ss-w-neg) 88%, black); }
1952
2019
 
1953
- .ss-w-cdash-lines { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; width: 100%; text-align: left; background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); border-left: 3px solid var(--ss-w-accent); border-radius: 12px; padding: 10px 12px; font: inherit; cursor: pointer; }
2020
+ .ss-w-cdash-lines { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; width: 100%; text-align: left; background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); border-left: 3px solid var(--ss-w-accent); border-radius: 12px; padding: 10px 12px; }
1954
2021
  .ss-w-cdash-lines-heading { font-size: 12px; font-weight: 700; color: var(--ss-w-accent); }
1955
- .ss-w-cdash-lines p { font-size: 12px; line-height: 1.4; color: var(--ss-w-ink); }
2022
+ .ss-w-cdash-lines p { font-size: 12px; line-height: 1.4; color: var(--ss-w-ink); margin: 0; }
2023
+ .ss-w-cdash-fact { display: block; width: 100%; text-align: left; font: inherit; font-size: 12px; line-height: 1.4; color: var(--ss-w-ink); background: none; border: none; padding: 0; cursor: pointer; }
2024
+ .ss-w-cdash-fact:hover, .ss-w-cdash-fact:focus-visible { color: var(--ss-w-accent); text-decoration: underline; }
2025
+ .ss-w-cdash-fact-label { font-size: 11px; font-weight: 700; color: var(--ss-w-accent); }
1956
2026
 
1957
2027
  .ss-w-cdash-cd { display: flex; flex-direction: column; align-items: center; gap: 4px; background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); border-radius: 12px; padding: 10px 12px; text-align: center; }
1958
2028
  .ss-w-cdash-cd-clock { display: flex; align-items: baseline; justify-content: center; gap: 2px; font-variant-numeric: tabular-nums; font-family: ui-monospace, "SFMono-Regular", Menlo, monospace; font-weight: 700; font-size: 18px; color: var(--ss-w-ink); }
@@ -1961,7 +2031,7 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
1961
2031
  `;
1962
2032
 
1963
2033
  // src/StatsWidget.tsx
1964
- var import_jsx_runtime28 = require("react/jsx-runtime");
2034
+ var import_jsx_runtime29 = require("react/jsx-runtime");
1965
2035
  function buildClient(props) {
1966
2036
  try {
1967
2037
  if ("client" in props && props.client) {
@@ -1986,11 +2056,11 @@ function injectStyles(root) {
1986
2056
  function StatsWidget(props) {
1987
2057
  const injectedClient = "client" in props ? props.client : void 0;
1988
2058
  const cfg = props.config;
1989
- const built = (0, import_react12.useMemo)(() => buildClient(props), [injectedClient, cfg?.operatorId, cfg?.publicKey, cfg?.baseUrl]);
1990
- const ui = (0, import_react12.useMemo)(() => normalizeUi(props.config ?? { operatorId: "", publicKey: "" }), [props.config]);
1991
- const rootRef = (0, import_react12.useRef)(null);
2059
+ const built = (0, import_react13.useMemo)(() => buildClient(props), [injectedClient, cfg?.operatorId, cfg?.publicKey, cfg?.baseUrl]);
2060
+ const ui = (0, import_react13.useMemo)(() => normalizeUi(props.config ?? { operatorId: "", publicKey: "" }), [props.config]);
2061
+ const rootRef = (0, import_react13.useRef)(null);
1992
2062
  const controller = useChatStream(built?.conversation ?? emptyConversation(), ui.starters, built ? ui.greetingMessage : void 0);
1993
- const slip = (0, import_react12.useMemo)(
2063
+ const slip = (0, import_react13.useMemo)(
1994
2064
  () => ({
1995
2065
  onAddToSlip: props.config?.onAddToSlip,
1996
2066
  conversationId: controller.state.conversationId ?? void 0,
@@ -2003,18 +2073,18 @@ function StatsWidget(props) {
2003
2073
  }),
2004
2074
  [props.config?.onAddToSlip, controller.state.conversationId, built]
2005
2075
  );
2006
- const onDashboardTap = (0, import_react12.useMemo)(
2076
+ const onDashboardTap = (0, import_react13.useMemo)(
2007
2077
  () => built ? createDashboardTapSignal((input) => built.conversation.sendSignal(input)) : void 0,
2008
2078
  [built]
2009
2079
  );
2010
- (0, import_react12.useEffect)(() => {
2080
+ (0, import_react13.useEffect)(() => {
2011
2081
  if (!built || !ui.injectStyles) return;
2012
2082
  const node = rootRef.current?.getRootNode();
2013
2083
  if (node) injectStyles(node);
2014
2084
  }, [built, ui.injectStyles]);
2015
2085
  if (!built) return null;
2016
2086
  const attrs = themeAttrs(ui);
2017
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("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__ */ (0, import_jsx_runtime28.jsx)(ChatPanel, { controller, ui, slip, onDashboardTap }) : /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
2087
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("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__ */ (0, import_jsx_runtime29.jsx)(ChatPanel, { controller, ui, slip, onDashboardTap }) : /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
2018
2088
  ChatFab,
2019
2089
  {
2020
2090
  label: ui.launcherLabel,