@sensiblestats/widget-react 0.18.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),
@@ -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,75 +1303,75 @@ 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, void 0, 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,
@@ -1348,10 +1379,10 @@ function MatchPreviewBlock({
1348
1379
  }) {
1349
1380
  if (block.facts.length === 0) return null;
1350
1381
  const heading = ui.clubMatchPreviewHeading;
1351
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "ss-w-cdash-lines", children: [
1352
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "ss-w-cdash-lines-heading", children: heading }),
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 }),
1353
1384
  block.facts.map(
1354
- (f, i) => f.entityRef ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
1385
+ (f, i) => f.entityRef ? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
1355
1386
  "button",
1356
1387
  {
1357
1388
  type: "button",
@@ -1359,20 +1390,20 @@ function MatchPreviewBlock({
1359
1390
  onClick: () => onAction(f.question ?? f.sentence, { ...f.entityRef, subject: f.sentence, personaHint: "club" }),
1360
1391
  children: [
1361
1392
  f.sentence,
1362
- f.label ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { className: "ss-w-cdash-fact-label", children: [
1393
+ f.label ? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { className: "ss-w-cdash-fact-label", children: [
1363
1394
  " ",
1364
1395
  f.label
1365
1396
  ] }) : null
1366
1397
  ]
1367
1398
  },
1368
1399
  i
1369
- ) : /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { children: f.sentence }, i)
1400
+ ) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { children: f.sentence }, i)
1370
1401
  )
1371
1402
  ] });
1372
1403
  }
1373
1404
 
1374
1405
  // src/components/club-dashboard/TeamDnaBlock.tsx
1375
- var import_jsx_runtime20 = require("react/jsx-runtime");
1406
+ var import_jsx_runtime21 = require("react/jsx-runtime");
1376
1407
  function TeamDnaBlock({
1377
1408
  block,
1378
1409
  ui,
@@ -1380,10 +1411,10 @@ function TeamDnaBlock({
1380
1411
  }) {
1381
1412
  if (block.facts.length === 0) return null;
1382
1413
  const heading = ui.clubTeamDnaHeading;
1383
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "ss-w-cdash-lines", children: [
1384
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "ss-w-cdash-lines-heading", children: heading }),
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 }),
1385
1416
  block.facts.map(
1386
- (f, i) => f.entityRef ? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
1417
+ (f, i) => f.entityRef ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
1387
1418
  "button",
1388
1419
  {
1389
1420
  type: "button",
@@ -1391,21 +1422,21 @@ function TeamDnaBlock({
1391
1422
  onClick: () => onAction(f.question ?? f.sentence, { ...f.entityRef, subject: f.sentence, personaHint: "club" }),
1392
1423
  children: [
1393
1424
  f.sentence,
1394
- f.label ? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { className: "ss-w-cdash-fact-label", children: [
1425
+ f.label ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { className: "ss-w-cdash-fact-label", children: [
1395
1426
  " ",
1396
1427
  f.label
1397
1428
  ] }) : null
1398
1429
  ]
1399
1430
  },
1400
1431
  i
1401
- ) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { children: f.sentence }, i)
1432
+ ) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { children: f.sentence }, i)
1402
1433
  )
1403
1434
  ] });
1404
1435
  }
1405
1436
 
1406
1437
  // src/components/club-dashboard/CountdownBlock.tsx
1407
- var import_react8 = require("react");
1408
- var import_jsx_runtime21 = require("react/jsx-runtime");
1438
+ var import_react9 = require("react");
1439
+ var import_jsx_runtime22 = require("react/jsx-runtime");
1409
1440
  var DAY_MS = 24 * 3600 * 1e3;
1410
1441
  function pad2(n) {
1411
1442
  return String(n).padStart(2, "0");
@@ -1418,8 +1449,8 @@ function splitRemaining(remainingMs) {
1418
1449
  return { h: pad2(h), m: pad2(m), s: pad2(s) };
1419
1450
  }
1420
1451
  function CountdownBlock({ block, ui }) {
1421
- const [remainingMs, setRemainingMs] = (0, import_react8.useState)(() => block.kickoffUnix * 1e3 - Date.now());
1422
- (0, import_react8.useEffect)(() => {
1452
+ const [remainingMs, setRemainingMs] = (0, import_react9.useState)(() => block.kickoffUnix * 1e3 - Date.now());
1453
+ (0, import_react9.useEffect)(() => {
1423
1454
  setRemainingMs(block.kickoffUnix * 1e3 - Date.now());
1424
1455
  if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) return;
1425
1456
  const id = setInterval(() => {
@@ -1430,30 +1461,30 @@ function CountdownBlock({ block, ui }) {
1430
1461
  if (remainingMs <= 0) return null;
1431
1462
  if (remainingMs > DAY_MS) return null;
1432
1463
  const { h, m, s } = splitRemaining(remainingMs);
1433
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "ss-w-cdash-cd", "aria-label": ui.clubKickoffAria(block.kickoffUnix * 1e3), children: [
1434
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "ss-w-cdash-cd-clock", "aria-hidden": "true", children: [
1435
- /* @__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 }),
1436
1467
  "h",
1437
1468
  " ",
1438
- /* @__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 }),
1439
1470
  "m",
1440
1471
  " ",
1441
- /* @__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 }),
1442
1473
  "s"
1443
1474
  ] }),
1444
- /* @__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 })
1445
1476
  ] });
1446
1477
  }
1447
1478
 
1448
1479
  // src/components/club-dashboard/ClubDashboard.tsx
1449
- var import_jsx_runtime22 = require("react/jsx-runtime");
1480
+ var import_jsx_runtime23 = require("react/jsx-runtime");
1450
1481
  var CLUB_BLOCK_REGISTRY = {
1451
- greetingHeader: ({ block }) => block.type === "greetingHeader" ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(GreetingHeaderBlock, { block }) : null,
1452
- fixtureHero: ({ block, ui, onAction }) => block.type === "fixtureHero" ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(FixtureHeroBlock, { block, ui, onAction }) : null,
1453
- formGuide: ({ block, ui }) => block.type === "formGuide" ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(FormGuideBlock, { block, ui }) : null,
1454
- matchPreview: ({ block, ui, onAction }) => block.type === "matchPreview" ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(MatchPreviewBlock, { block, ui, onAction }) : null,
1455
- teamDna: ({ block, ui, onAction }) => block.type === "teamDna" ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TeamDnaBlock, { block, ui, onAction }) : null,
1456
- 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
1457
1488
  };
1458
1489
  function ClubDashboard({
1459
1490
  dashboard,
@@ -1461,39 +1492,39 @@ function ClubDashboard({
1461
1492
  onAction
1462
1493
  }) {
1463
1494
  if (!dashboard.blocks.length) return null;
1464
- 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) => {
1465
1496
  const Comp = Object.prototype.hasOwnProperty.call(CLUB_BLOCK_REGISTRY, block.type) ? CLUB_BLOCK_REGISTRY[block.type] : void 0;
1466
1497
  if (!Comp) {
1467
1498
  console.warn(`[club-dashboard] no renderer for block type "${block.type}"`);
1468
1499
  return null;
1469
1500
  }
1470
- 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);
1471
1502
  }) });
1472
1503
  }
1473
1504
 
1474
1505
  // src/components/ChatMessage.tsx
1475
- var import_jsx_runtime23 = require("react/jsx-runtime");
1506
+ var import_jsx_runtime24 = require("react/jsx-runtime");
1476
1507
  function ChatMessage({ message, disabled, onAct, onTap, onClubAction, ui, slip }) {
1477
1508
  if (message.role === "user") {
1478
- 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 }) });
1479
1510
  }
1480
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "ss-w-msg ss-w-bot", children: [
1481
- message.text && !message.greetingDashboard && !message.clubDashboard ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Markdown, { text: message.text }) : null,
1482
- message.greetingDashboard ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(GreetingDashboard, { dashboard: message.greetingDashboard, onTap }) : null,
1483
- message.clubDashboard && ui ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ClubDashboard, { dashboard: message.clubDashboard, ui, onAction: onClubAction }) : null,
1484
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(EntityCardList, { cards: message.cards, disabled, showLessLabel: ui?.showLess, showMoreLabel: ui?.showMore }),
1485
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(BettingInsightList, { insights: message.insights, ui, slip }),
1486
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(MarketOddsCardList, { cards: message.marketOdds, ui, slip }),
1487
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(OddsMovementCardList, { cards: message.oddsMovement, ui }),
1488
- /* @__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 })
1489
1520
  ] });
1490
1521
  }
1491
1522
 
1492
1523
  // src/components/IntentChips.tsx
1493
- var import_jsx_runtime24 = require("react/jsx-runtime");
1524
+ var import_jsx_runtime25 = require("react/jsx-runtime");
1494
1525
  function IntentChips({ chips, onPick }) {
1495
1526
  if (chips.length === 0) return null;
1496
- 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}`)) });
1497
1528
  }
1498
1529
 
1499
1530
  // src/scroll.ts
@@ -1503,18 +1534,18 @@ function isPinnedToBottom(el, threshold = PIN_THRESHOLD) {
1503
1534
  }
1504
1535
 
1505
1536
  // src/components/MessageList.tsx
1506
- var import_jsx_runtime25 = require("react/jsx-runtime");
1537
+ var import_jsx_runtime26 = require("react/jsx-runtime");
1507
1538
  function MessageList({ controller, ui, slip, onDashboardTap }) {
1508
1539
  const { state, send } = controller;
1509
- const listRef = (0, import_react9.useRef)(null);
1510
- const endRef = (0, import_react9.useRef)(null);
1511
- const pinnedRef = (0, import_react9.useRef)(true);
1512
- (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)(() => {
1513
1544
  if (pinnedRef.current) endRef.current?.scrollIntoView({ block: "end" });
1514
1545
  }, [state.messages, state.status]);
1515
1546
  const hasUserMessage = state.messages.some((m) => m.role === "user");
1516
1547
  const hasDashboard = state.messages.some((m) => m.role === "assistant" && m.greetingDashboard);
1517
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
1548
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
1518
1549
  "div",
1519
1550
  {
1520
1551
  className: "ss-w-list",
@@ -1524,7 +1555,7 @@ function MessageList({ controller, ui, slip, onDashboardTap }) {
1524
1555
  if (listRef.current) pinnedRef.current = isPinnedToBottom(listRef.current);
1525
1556
  },
1526
1557
  children: [
1527
- state.messages.map((m) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
1558
+ state.messages.map((m) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
1528
1559
  ChatMessage,
1529
1560
  {
1530
1561
  message: m,
@@ -1540,25 +1571,25 @@ function MessageList({ controller, ui, slip, onDashboardTap }) {
1540
1571
  },
1541
1572
  m.id
1542
1573
  )),
1543
- 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: () => {
1544
1575
  } }) : null,
1545
- state.status ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "ss-w-status", children: state.status }) : null,
1546
- state.error ? /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "ss-w-error", role: "alert", children: [
1547
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { children: "message" in state.error ? state.error.message : ui.somethingWentWrong }),
1548
- /* @__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 })
1549
1580
  ] }) : null,
1550
- !hasUserMessage && !hasDashboard ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(IntentChips, { chips: state.starters, onPick: (t) => send(t) }) : null,
1551
- /* @__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 })
1552
1583
  ]
1553
1584
  }
1554
1585
  );
1555
1586
  }
1556
1587
 
1557
1588
  // src/components/ChatInput.tsx
1558
- var import_react10 = require("react");
1559
- var import_jsx_runtime26 = require("react/jsx-runtime");
1589
+ var import_react11 = require("react");
1590
+ var import_jsx_runtime27 = require("react/jsx-runtime");
1560
1591
  function ChatInput({ placeholder, streaming, onSend, onStop, stopLabel = "Stop response", sendLabel = "Send message" }) {
1561
- const [value, setValue] = (0, import_react10.useState)("");
1592
+ const [value, setValue] = (0, import_react11.useState)("");
1562
1593
  const submit = () => {
1563
1594
  const t = value.trim();
1564
1595
  if (!t) return;
@@ -1571,18 +1602,18 @@ function ChatInput({ placeholder, streaming, onSend, onStop, stopLabel = "Stop r
1571
1602
  submit();
1572
1603
  }
1573
1604
  };
1574
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "ss-w-input", children: [
1575
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("textarea", { className: "ss-w-textarea", rows: 1, placeholder, value, disabled: streaming, onChange: (e) => setValue(e.target.value), onKeyDown }),
1576
- 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, {}) })
1577
1608
  ] });
1578
1609
  }
1579
1610
 
1580
1611
  // src/components/ChatPanel.tsx
1581
- var import_jsx_runtime27 = require("react/jsx-runtime");
1612
+ var import_jsx_runtime28 = require("react/jsx-runtime");
1582
1613
  var FULLSCREEN_QUERY = "(max-width: 639px)";
1583
1614
  function useIsModal() {
1584
- const [modal, setModal] = (0, import_react11.useState)(false);
1585
- (0, import_react11.useEffect)(() => {
1615
+ const [modal, setModal] = (0, import_react12.useState)(false);
1616
+ (0, import_react12.useEffect)(() => {
1586
1617
  if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
1587
1618
  const mql = window.matchMedia(FULLSCREEN_QUERY);
1588
1619
  const sync = () => setModal(mql.matches);
@@ -1595,17 +1626,17 @@ function useIsModal() {
1595
1626
  function ChatPanel({ controller, ui, slip, onDashboardTap }) {
1596
1627
  const { state, close, stop, send } = controller;
1597
1628
  const isModal = useIsModal();
1598
- (0, import_react11.useEffect)(() => {
1629
+ (0, import_react12.useEffect)(() => {
1599
1630
  const onKey = (e) => {
1600
1631
  if (e.key === "Escape") close();
1601
1632
  };
1602
1633
  window.addEventListener("keydown", onKey);
1603
1634
  return () => window.removeEventListener("keydown", onKey);
1604
1635
  }, [close]);
1605
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "ss-w-panel", role: "dialog", "aria-modal": isModal, "aria-label": ui.chatDialogLabel, children: [
1606
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ChatHeader, { onClose: close, closeLabel: ui.closeChat }),
1607
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(MessageList, { controller, ui, slip, onDashboardTap }),
1608
- /* @__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 })
1609
1640
  ] });
1610
1641
  }
1611
1642
 
@@ -1653,7 +1684,7 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
1653
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; }
1654
1685
 
1655
1686
  /* panel */
1656
- .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); }
1657
1688
  .ss-w-root[data-ss-w-pos="right"] .ss-w-panel { right: var(--ss-w-offset-x); }
1658
1689
  .ss-w-root[data-ss-w-pos="left"] .ss-w-panel { left: var(--ss-w-offset-x); }
1659
1690
  @media (max-width: 639px) {
@@ -1756,9 +1787,9 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
1756
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; }
1757
1788
 
1758
1789
  /* crests -- CSS background-image on a span, never <img> (matches .ss-w-ecard-crest precedent) */
1759
- .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; }
1760
- .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); }
1761
- .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)); }
1762
1793
 
1763
1794
  /* row 2: crest-flanked fixture on the left, boxed action panel on the right */
1764
1795
  .ss-w-bi-body { display: flex; align-items: center; gap: 10px; }
@@ -1766,16 +1797,16 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
1766
1797
  .ss-w-bi-team { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
1767
1798
  .ss-w-bi-vs { font-size: 10px; font-weight: 600; color: var(--ss-w-faint); flex: none; }
1768
1799
  .ss-w-bi-fixture-txt { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
1769
- .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; }
1770
- .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; }
1771
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. */
1772
1804
  .ss-w-bi-action .ss-w-toast { left: auto; right: 0; width: max-content; max-width: 210px; white-space: normal; }
1773
- .ss-w-bi-mkt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
1774
- .ss-w-bi-market { font-size: 13.5px; font-weight: 700; line-height: 1.25; color: var(--ss-w-ink); }
1775
- .ss-w-bi-sel { font-size: 11.5px; line-height: 1.3; color: var(--ss-w-faint); }
1776
- .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; }
1777
- .ss-w-bi-odds-cap { font-size: 9px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase; color: var(--ss-w-faint); }
1778
- .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; }
1779
1810
  .ss-w-bi-book { font-size: 9.5px; color: var(--ss-w-faint); }
1780
1811
 
1781
1812
  /* row 3: bar-chart glyph + reasoning prose + stats-expander chevron, in a subtle strip */
@@ -1789,11 +1820,11 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
1789
1820
  }
1790
1821
  .ss-w-bi-reason-body { display: flex; flex-direction: column; gap: 8px; min-width: 0; flex: 1; }
1791
1822
  .ss-w-bi-text { font-size: 12px; line-height: 1.45; color: var(--ss-w-ink); }
1792
- .ss-w-bi-stats { display: flex; flex-direction: column; gap: 8px; }
1793
- .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; }
1794
- .ss-w-bi-toggle:hover { text-decoration: underline; }
1795
- .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; }
1796
- .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); }
1797
1828
  .ss-w-bi-rows { display: flex; flex-direction: column; }
1798
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); }
1799
1830
  .ss-w-bi-row:first-child { border-top: none; }
@@ -1808,11 +1839,13 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
1808
1839
  /* market odds card */
1809
1840
  .ss-w-mocards { display: flex; flex-direction: column; gap: 7px; }
1810
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; }
1811
- .ss-w-mo-head { display: flex; align-items: center; gap: 8px; }
1812
- .ss-w-mo-market { font-size: 13px; font-weight: 700; color: var(--ss-w-ink); }
1813
- .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; }
1814
- .ss-w-mo-fixture { display: flex; align-items: center; gap: 6px; font-size: 11.5px; color: var(--ss-w-faint); min-width: 0; }
1815
- .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); }
1816
1849
  .ss-w-mo-rows { display: flex; flex-direction: column; gap: 4px; }
1817
1850
  .ss-w-mo-row { display: flex; align-items: center; gap: 10px; padding: 4px 0; border-bottom: 1px dashed var(--ss-w-line); }
1818
1851
  .ss-w-mo-row:last-child { border-bottom: none; }
@@ -1998,7 +2031,7 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
1998
2031
  `;
1999
2032
 
2000
2033
  // src/StatsWidget.tsx
2001
- var import_jsx_runtime28 = require("react/jsx-runtime");
2034
+ var import_jsx_runtime29 = require("react/jsx-runtime");
2002
2035
  function buildClient(props) {
2003
2036
  try {
2004
2037
  if ("client" in props && props.client) {
@@ -2023,11 +2056,11 @@ function injectStyles(root) {
2023
2056
  function StatsWidget(props) {
2024
2057
  const injectedClient = "client" in props ? props.client : void 0;
2025
2058
  const cfg = props.config;
2026
- const built = (0, import_react12.useMemo)(() => buildClient(props), [injectedClient, cfg?.operatorId, cfg?.publicKey, cfg?.baseUrl]);
2027
- const ui = (0, import_react12.useMemo)(() => normalizeUi(props.config ?? { operatorId: "", publicKey: "" }), [props.config]);
2028
- 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);
2029
2062
  const controller = useChatStream(built?.conversation ?? emptyConversation(), ui.starters, built ? ui.greetingMessage : void 0);
2030
- const slip = (0, import_react12.useMemo)(
2063
+ const slip = (0, import_react13.useMemo)(
2031
2064
  () => ({
2032
2065
  onAddToSlip: props.config?.onAddToSlip,
2033
2066
  conversationId: controller.state.conversationId ?? void 0,
@@ -2040,18 +2073,18 @@ function StatsWidget(props) {
2040
2073
  }),
2041
2074
  [props.config?.onAddToSlip, controller.state.conversationId, built]
2042
2075
  );
2043
- const onDashboardTap = (0, import_react12.useMemo)(
2076
+ const onDashboardTap = (0, import_react13.useMemo)(
2044
2077
  () => built ? createDashboardTapSignal((input) => built.conversation.sendSignal(input)) : void 0,
2045
2078
  [built]
2046
2079
  );
2047
- (0, import_react12.useEffect)(() => {
2080
+ (0, import_react13.useEffect)(() => {
2048
2081
  if (!built || !ui.injectStyles) return;
2049
2082
  const node = rootRef.current?.getRootNode();
2050
2083
  if (node) injectStyles(node);
2051
2084
  }, [built, ui.injectStyles]);
2052
2085
  if (!built) return null;
2053
2086
  const attrs = themeAttrs(ui);
2054
- 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)(
2055
2088
  ChatFab,
2056
2089
  {
2057
2090
  label: ui.launcherLabel,