@sensiblestats/widget-react 0.29.2 → 0.29.4

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_react17 = require("react");
39
+ var import_react19 = require("react");
40
40
  var import_widget_sdk5 = require("@sensiblestats/widget-sdk");
41
41
 
42
42
  // src/kickoff.ts
@@ -876,7 +876,7 @@ function ChatFab({ label, greeting, popupText, onOpen, onDismissPopup, dismissLa
876
876
  }
877
877
 
878
878
  // src/components/ChatPanel.tsx
879
- var import_react16 = require("react");
879
+ var import_react18 = require("react");
880
880
 
881
881
  // src/components/ChatHeader.tsx
882
882
  var import_jsx_runtime4 = require("react/jsx-runtime");
@@ -889,7 +889,7 @@ function ChatHeader({ onClose, closeLabel = "Close chat" }) {
889
889
  }
890
890
 
891
891
  // src/components/MessageList.tsx
892
- var import_react14 = require("react");
892
+ var import_react16 = require("react");
893
893
 
894
894
  // src/components/Markdown.tsx
895
895
  var import_react_markdown = __toESM(require("react-markdown"), 1);
@@ -1469,17 +1469,20 @@ function resultClass(result) {
1469
1469
  function FormStrip({ form }) {
1470
1470
  return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "ss-w-fandash-form", children: form.map((r, i) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: `ss-w-fandash-form-pill ${resultClass(r)}`, children: r }, `${r}-${i}`)) });
1471
1471
  }
1472
- function FormRow({ name, form }) {
1472
+ function FormRow({ name, form, crestUrl }) {
1473
1473
  return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "ss-w-fandash-formrow", children: [
1474
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "ss-w-fandash-formrow-name", children: name }),
1474
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { className: "ss-w-fandash-formrow-team", children: [
1475
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Crest2, { url: crestUrl ?? void 0, name, kind: "team" }),
1476
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "ss-w-fandash-formrow-name", children: name })
1477
+ ] }),
1475
1478
  /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(FormStrip, { form })
1476
1479
  ] });
1477
1480
  }
1478
- function FixtureCard({ card, onTap }) {
1481
+ function FixtureCard({ card }) {
1479
1482
  const { data } = card;
1480
1483
  const h2h = data.h2H;
1481
1484
  return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
1482
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("button", { type: "button", className: "ss-w-fandash-card ss-w-fandash-card--tap ss-w-fandash-fixture", onClick: () => onTap(card), children: [
1485
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "ss-w-fandash-card ss-w-fandash-fixture", children: [
1483
1486
  /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { className: "ss-w-fandash-eyebrow", children: [
1484
1487
  card.title,
1485
1488
  " \xB7 ",
@@ -1497,22 +1500,18 @@ function FixtureCard({ card, onTap }) {
1497
1500
  ] })
1498
1501
  ] }),
1499
1502
  /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "ss-w-fandash-fixture-meta", children: [
1500
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "ss-w-fandash-fixture-metarow", children: [
1501
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "ss-w-fandash-fixture-metakey", children: data.dateLabel }),
1502
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "ss-w-fandash-fixture-metaval", children: data.kickoffLabel })
1503
- ] }),
1504
- data.venue ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "ss-w-fandash-fixture-metarow", children: [
1505
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "ss-w-fandash-fixture-metakey", children: data.venueLabel }),
1506
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "ss-w-fandash-fixture-metaval", children: data.venue })
1503
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "ss-w-fandash-fixture-kickoff", children: data.kickoffLabel }),
1504
+ data.venue ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { className: "ss-w-fandash-fixture-venue", children: [
1505
+ " \xB7 ",
1506
+ data.venue
1507
1507
  ] }) : null
1508
- ] }),
1509
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "ss-w-fandash-card-cta", children: card.actionLabel })
1508
+ ] })
1510
1509
  ] }),
1511
1510
  /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "ss-w-fandash-card ss-w-fandash-lastfive", children: [
1512
1511
  /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "ss-w-fandash-eyebrow", children: data.formLabel }),
1513
1512
  /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "ss-w-fandash-fixture-form", children: [
1514
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(FormRow, { name: data.homeName, form: data.homeForm }),
1515
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(FormRow, { name: data.awayName, form: data.awayForm })
1513
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(FormRow, { name: data.homeName, form: data.homeForm, crestUrl: data.homeCrestUrl }),
1514
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(FormRow, { name: data.awayName, form: data.awayForm, crestUrl: data.awayCrestUrl })
1516
1515
  ] })
1517
1516
  ] }),
1518
1517
  h2h || data.fact ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "ss-w-fandash-card ss-w-fandash-h2h", children: [
@@ -1582,16 +1581,19 @@ function CountdownCard({ card }) {
1582
1581
  }
1583
1582
 
1584
1583
  // src/components/dashboard/InjuriesCard.tsx
1584
+ var import_react10 = require("react");
1585
1585
  var import_jsx_runtime19 = require("react/jsx-runtime");
1586
+ var SHOWN = 3;
1586
1587
  function ColHead({ name, crestUrl }) {
1587
1588
  return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { className: "ss-w-fandash-injuries-col-head", children: [
1588
1589
  /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Crest2, { url: crestUrl ?? void 0, name, kind: "team" }),
1589
1590
  /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "ss-w-fandash-injuries-col-head-name", children: name })
1590
1591
  ] });
1591
1592
  }
1592
- function InjuryList({ rows, emptyLabel }) {
1593
+ function InjuryList({ rows, emptyLabel, limit }) {
1593
1594
  if (rows.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "ss-w-fandash-injuries-empty", children: emptyLabel });
1594
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("ul", { className: "ss-w-fandash-injury-list", children: rows.map((r, i) => /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("li", { className: "ss-w-fandash-injury-row", children: [
1595
+ const shown = limit === void 0 ? rows : rows.slice(0, limit);
1596
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("ul", { className: "ss-w-fandash-injury-list", children: shown.map((r, i) => /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("li", { className: "ss-w-fandash-injury-row", children: [
1595
1597
  /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "ss-w-fandash-injury-name", children: r.playerName }),
1596
1598
  /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { className: "ss-w-fandash-injury-meta", children: [
1597
1599
  /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "ss-w-fandash-injury-status", children: r.status }),
@@ -1600,21 +1602,36 @@ function InjuryList({ rows, emptyLabel }) {
1600
1602
  ] })
1601
1603
  ] }, `${r.playerName}-${i}`)) });
1602
1604
  }
1603
- function InjuriesCard({ card }) {
1605
+ function InjuriesCard({ card, ui }) {
1604
1606
  const { data } = card;
1607
+ const [expanded, setExpanded] = (0, import_react10.useState)(false);
1608
+ const hidden = Math.max(0, data.ours.length - SHOWN) + Math.max(0, data.theirs.length - SHOWN);
1609
+ const limit = expanded ? void 0 : SHOWN;
1610
+ const showMore = ui?.showMore ?? ((n) => `Show ${n} more`);
1611
+ const showLess = ui?.showLess ?? "Show less";
1605
1612
  return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "ss-w-fandash-card ss-w-fandash-injuries", children: [
1606
1613
  card.title ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "ss-w-fandash-eyebrow", children: card.title }) : null,
1607
1614
  /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "ss-w-fandash-injuries-cols", children: [
1608
1615
  /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "ss-w-fandash-injuries-col", children: [
1609
1616
  /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(ColHead, { name: data.oursName, crestUrl: data.oursCrestUrl }),
1610
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(InjuryList, { rows: data.ours, emptyLabel: data.emptyLabel })
1617
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(InjuryList, { rows: data.ours, emptyLabel: data.emptyLabel, limit })
1611
1618
  ] }),
1612
1619
  /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "ss-w-fandash-injuries-divider" }),
1613
1620
  /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "ss-w-fandash-injuries-col", children: [
1614
1621
  /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(ColHead, { name: data.theirsName, crestUrl: data.theirsCrestUrl }),
1615
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(InjuryList, { rows: data.theirs, emptyLabel: data.emptyLabel })
1622
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(InjuryList, { rows: data.theirs, emptyLabel: data.emptyLabel, limit })
1616
1623
  ] })
1617
- ] })
1624
+ ] }),
1625
+ hidden > 0 ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1626
+ "button",
1627
+ {
1628
+ type: "button",
1629
+ className: "ss-w-fandash-injuries-more",
1630
+ "aria-expanded": expanded,
1631
+ onClick: () => setExpanded((v) => !v),
1632
+ children: expanded ? showLess : showMore(hidden)
1633
+ }
1634
+ ) : null
1618
1635
  ] });
1619
1636
  }
1620
1637
 
@@ -1691,21 +1708,60 @@ function LinksCard({ card }) {
1691
1708
  }
1692
1709
 
1693
1710
  // src/components/dashboard/PostMatchResultCard.tsx
1711
+ var import_react11 = require("react");
1694
1712
  var import_jsx_runtime25 = require("react/jsx-runtime");
1713
+ function initials3(name) {
1714
+ return name.trim().slice(0, 3).toUpperCase();
1715
+ }
1716
+ function PostMatchCrest({
1717
+ url,
1718
+ name,
1719
+ side
1720
+ }) {
1721
+ const [failed, setFailed] = (0, import_react11.useState)(false);
1722
+ const cls = `ss-w-fandash-postmatch-crest ss-w-fandash-postmatch-crest--${side}`;
1723
+ if (url && !failed) {
1724
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("img", { className: cls, src: url, alt: "", "aria-hidden": "true", onError: () => setFailed(true) });
1725
+ }
1726
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: `${cls} ss-w-fandash-postmatch-crest--fallback`, "aria-hidden": "true", children: initials3(name) });
1727
+ }
1695
1728
  function PostMatchResultCard({ card }) {
1696
1729
  const { data } = card;
1730
+ const homeWon = data.homeScore >= data.awayScore;
1731
+ const awayWon = data.awayScore >= data.homeScore;
1697
1732
  return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "ss-w-fandash-card ss-w-fandash-postmatch-result", children: [
1698
- card.title ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "ss-w-fandash-eyebrow", children: card.title }) : null,
1699
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "ss-w-fandash-postmatch-scoreboard", children: [
1700
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "ss-w-fandash-postmatch-team", children: data.homeName }),
1701
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "ss-w-fandash-postmatch-score", children: data.homeScore }),
1702
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "ss-w-fandash-postmatch-sep", children: "\u2013" }),
1703
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "ss-w-fandash-postmatch-score", children: data.awayScore }),
1704
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "ss-w-fandash-postmatch-team ss-w-fandash-postmatch-team--away", children: data.awayName })
1733
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "ss-w-fandash-postmatch-top", children: [
1734
+ card.title ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "ss-w-fandash-postmatch-pill", children: card.title }) : null,
1735
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: `ss-w-fandash-postmatch-tag ss-w-fandash-postmatch-tag--${data.outcome}`, children: data.resultLabel })
1736
+ ] }),
1737
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "ss-w-fandash-postmatch-main", children: [
1738
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "ss-w-fandash-postmatch-side ss-w-fandash-postmatch-side--home", children: [
1739
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(PostMatchCrest, { url: data.homeCrestUrl, name: data.homeName, side: "home" }),
1740
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "ss-w-fandash-postmatch-team-name", children: data.homeName })
1741
+ ] }),
1742
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "ss-w-fandash-postmatch-score-main", children: [
1743
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
1744
+ "span",
1745
+ {
1746
+ className: `ss-w-fandash-postmatch-score-value ss-w-fandash-postmatch-score-value--${homeWon ? "win" : "lose"}`,
1747
+ children: data.homeScore
1748
+ }
1749
+ ),
1750
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "ss-w-fandash-postmatch-score-sep", children: "\u2013" }),
1751
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
1752
+ "span",
1753
+ {
1754
+ className: `ss-w-fandash-postmatch-score-value ss-w-fandash-postmatch-score-value--${awayWon ? "win" : "lose"}`,
1755
+ children: data.awayScore
1756
+ }
1757
+ )
1758
+ ] }),
1759
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "ss-w-fandash-postmatch-side ss-w-fandash-postmatch-side--away", children: [
1760
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(PostMatchCrest, { url: data.awayCrestUrl, name: data.awayName, side: "away" }),
1761
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "ss-w-fandash-postmatch-team-name", children: data.awayName })
1762
+ ] })
1705
1763
  ] }),
1706
1764
  /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "ss-w-fandash-postmatch-meta", children: [
1707
- data.resultLabel,
1708
- " \xB7 ",
1709
1765
  data.kickoffLabel,
1710
1766
  data.competition ? ` \xB7 ${data.competition}` : ""
1711
1767
  ] })
@@ -1717,38 +1773,75 @@ var import_jsx_runtime26 = require("react/jsx-runtime");
1717
1773
  function PostMatchGoalsCard({ card, onTap }) {
1718
1774
  return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("button", { type: "button", className: "ss-w-fandash-card ss-w-fandash-card--tap ss-w-fandash-postmatch-goals", onClick: () => onTap(card), children: [
1719
1775
  card.title ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "ss-w-fandash-eyebrow", children: card.title }) : null,
1720
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("ul", { className: "ss-w-fandash-postmatch-goal-list", children: card.data.goals.map((g, i) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("li", { className: g.scoredByClub ? "ss-w-fandash-postmatch-goal ss-w-fandash-postmatch-goal--club" : "ss-w-fandash-postmatch-goal", children: g.text }, `${g.text}-${i}`)) }),
1776
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("ul", { className: "ss-w-fandash-postmatch-goal-list", children: card.data.goals.map((g, i) => /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("li", { className: g.scoredByClub ? "ss-w-fandash-postmatch-goal ss-w-fandash-postmatch-goal--club" : "ss-w-fandash-postmatch-goal", children: [
1777
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "ss-w-fandash-postmatch-goal-ball" }),
1778
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { children: g.text })
1779
+ ] }, `${g.text}-${i}`)) }),
1721
1780
  /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "ss-w-fandash-card-cta", children: card.actionLabel })
1722
1781
  ] });
1723
1782
  }
1724
1783
 
1725
1784
  // src/components/dashboard/PostMatchStatsCard.tsx
1726
1785
  var import_jsx_runtime27 = require("react/jsx-runtime");
1786
+ function splitWidths(homeNum, awayNum) {
1787
+ const total = homeNum + awayNum;
1788
+ if (total <= 0) return { home: "50%", away: "50%" };
1789
+ const homePct = Math.round(homeNum / total * 1e3) / 10;
1790
+ return { home: `${homePct}%`, away: `${Math.round((100 - homePct) * 10) / 10}%` };
1791
+ }
1727
1792
  function PostMatchStatsCard({ card, onTap }) {
1793
+ const { data } = card;
1728
1794
  return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("button", { type: "button", className: "ss-w-fandash-card ss-w-fandash-card--tap ss-w-fandash-postmatch-stats", onClick: () => onTap(card), children: [
1729
1795
  card.title ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "ss-w-fandash-eyebrow", children: card.title }) : null,
1730
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "ss-w-fandash-postmatch-stat-rows", children: card.data.rows.map((r, i) => {
1731
- const leftValue = card.data.clubIsHome ? r.clubValue : r.oppValue;
1732
- const rightValue = card.data.clubIsHome ? r.oppValue : r.clubValue;
1733
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "ss-w-fandash-postmatch-stat-row", children: [
1734
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "ss-w-fandash-postmatch-stat-value", children: leftValue }),
1735
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "ss-w-fandash-postmatch-stat-label", children: r.label }),
1736
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "ss-w-fandash-postmatch-stat-value", children: rightValue })
1796
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "ss-w-fandash-postmatch-stat-rows", children: data.rows.map((r, i) => {
1797
+ const leftValue = data.clubIsHome ? r.clubValue : r.oppValue;
1798
+ const rightValue = data.clubIsHome ? r.oppValue : r.clubValue;
1799
+ const homeNum = data.clubIsHome ? r.clubNum : r.oppNum;
1800
+ const awayNum = data.clubIsHome ? r.oppNum : r.clubNum;
1801
+ const { home, away } = splitWidths(homeNum, awayNum);
1802
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "ss-w-fandash-postmatch-stat", children: [
1803
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "ss-w-fandash-postmatch-stat-row", children: [
1804
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "ss-w-fandash-postmatch-stat-value ss-w-fandash-postmatch-stat-value--home", children: leftValue }),
1805
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "ss-w-fandash-postmatch-stat-label", children: r.label }),
1806
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "ss-w-fandash-postmatch-stat-value ss-w-fandash-postmatch-stat-value--away", children: rightValue })
1807
+ ] }),
1808
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "ss-w-fandash-postmatch-stat-bar", children: [
1809
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "ss-w-fandash-postmatch-stat-bar-home", style: { width: home } }),
1810
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "ss-w-fandash-postmatch-stat-bar-away", style: { width: away } })
1811
+ ] })
1737
1812
  ] }, `${r.label}-${i}`);
1738
1813
  }) }),
1814
+ data.rows.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "ss-w-fandash-postmatch-legend", children: [
1815
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("span", { className: "ss-w-fandash-postmatch-legend-item", children: [
1816
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("i", { className: "ss-w-fandash-postmatch-legend-swatch ss-w-fandash-postmatch-legend-swatch--home" }),
1817
+ data.homeName
1818
+ ] }),
1819
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("span", { className: "ss-w-fandash-postmatch-legend-item", children: [
1820
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("i", { className: "ss-w-fandash-postmatch-legend-swatch ss-w-fandash-postmatch-legend-swatch--away" }),
1821
+ data.awayName
1822
+ ] })
1823
+ ] }) : null,
1739
1824
  /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "ss-w-fandash-card-cta", children: card.actionLabel })
1740
1825
  ] });
1741
1826
  }
1742
1827
 
1743
1828
  // src/components/dashboard/PostMatchTopPerformerCard.tsx
1744
1829
  var import_jsx_runtime28 = require("react/jsx-runtime");
1830
+ function initials4(playerName) {
1831
+ const words = playerName.trim().split(/\s+/).filter(Boolean);
1832
+ if (words.length === 0) return "?";
1833
+ const first = words[0].charAt(0);
1834
+ const last = words[words.length - 1].charAt(0);
1835
+ return (words.length > 1 ? `${first}${last}` : first).toUpperCase();
1836
+ }
1745
1837
  function PostMatchTopPerformerCard({ card, onTap }) {
1746
1838
  const { data } = card;
1747
1839
  return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("button", { type: "button", className: "ss-w-fandash-card ss-w-fandash-card--tap ss-w-fandash-postmatch-performer", onClick: () => onTap(card), children: [
1748
1840
  card.title ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "ss-w-fandash-eyebrow", children: card.title }) : null,
1749
- /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "ss-w-fandash-postmatch-performer-row", children: [
1750
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "ss-w-fandash-postmatch-performer-name", children: data.playerName }),
1751
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "ss-w-fandash-postmatch-performer-rating", children: data.ratingLabel })
1841
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "ss-w-fandash-postmatch-perf-row", children: [
1842
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "ss-w-fandash-postmatch-perf-avatar", "aria-hidden": "true", children: initials4(data.playerName) }),
1843
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "ss-w-fandash-postmatch-perf-name", children: data.playerName }),
1844
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "ss-w-fandash-postmatch-perf-rating", children: data.ratingLabel })
1752
1845
  ] }),
1753
1846
  /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "ss-w-fandash-card-cta", children: card.actionLabel })
1754
1847
  ] });
@@ -1824,10 +1917,10 @@ function RestingFormCard({ card }) {
1824
1917
  }
1825
1918
 
1826
1919
  // src/components/dashboard/LiveScoreCard.tsx
1827
- var import_react11 = require("react");
1920
+ var import_react13 = require("react");
1828
1921
 
1829
1922
  // src/useLiveClock.ts
1830
- var import_react10 = require("react");
1923
+ var import_react12 = require("react");
1831
1924
  var TICK_MS = 6e4;
1832
1925
  var MAX_LIVE_TICK_MINUTES = 15;
1833
1926
  function computeDisplayMinute(minute, clockRunning, receivedAtMs) {
@@ -1836,10 +1929,10 @@ function computeDisplayMinute(minute, clockRunning, receivedAtMs) {
1836
1929
  return minute + Math.min(Math.max(0, elapsedMinutes), MAX_LIVE_TICK_MINUTES);
1837
1930
  }
1838
1931
  function useLiveClock(minute, clockRunning, receivedAtMs) {
1839
- const [displayMinute, setDisplayMinute] = (0, import_react10.useState)(
1932
+ const [displayMinute, setDisplayMinute] = (0, import_react12.useState)(
1840
1933
  () => computeDisplayMinute(minute, clockRunning, receivedAtMs)
1841
1934
  );
1842
- (0, import_react10.useEffect)(() => {
1935
+ (0, import_react12.useEffect)(() => {
1843
1936
  setDisplayMinute(computeDisplayMinute(minute, clockRunning, receivedAtMs));
1844
1937
  if (!clockRunning) return;
1845
1938
  const id = window.setInterval(() => {
@@ -1852,16 +1945,16 @@ function useLiveClock(minute, clockRunning, receivedAtMs) {
1852
1945
 
1853
1946
  // src/components/dashboard/LiveScoreCard.tsx
1854
1947
  var import_jsx_runtime34 = require("react/jsx-runtime");
1855
- function initials3(name) {
1948
+ function initials5(name) {
1856
1949
  return name.trim().slice(0, 3).toUpperCase();
1857
1950
  }
1858
1951
  function LiveCrest({ url, name, side }) {
1859
- const [failed, setFailed] = (0, import_react11.useState)(false);
1952
+ const [failed, setFailed] = (0, import_react13.useState)(false);
1860
1953
  const cls = `ss-w-fandash-live-crest ss-w-fandash-live-crest--${side}`;
1861
1954
  if (url && !failed) {
1862
1955
  return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("img", { className: cls, src: url, alt: "", "aria-hidden": "true", onError: () => setFailed(true) });
1863
1956
  }
1864
- return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: `${cls} ss-w-fandash-live-crest--fallback`, "aria-hidden": "true", children: initials3(name) });
1957
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: `${cls} ss-w-fandash-live-crest--fallback`, "aria-hidden": "true", children: initials5(name) });
1865
1958
  }
1866
1959
  function scorersLine(goalEvents) {
1867
1960
  if (!goalEvents || goalEvents.length === 0) return null;
@@ -1875,7 +1968,7 @@ function LiveScoreCard({
1875
1968
  }) {
1876
1969
  const { data } = card;
1877
1970
  const seedKey = `${data.minute}:${data.homeScore}:${data.awayScore}`;
1878
- const seedRef = (0, import_react11.useRef)(null);
1971
+ const seedRef = (0, import_react13.useRef)(null);
1879
1972
  if (!seedRef.current || seedRef.current.key !== seedKey) {
1880
1973
  seedRef.current = { key: seedKey, receivedAtMs: Date.now() };
1881
1974
  }
@@ -1915,9 +2008,9 @@ function LiveScoreCard({
1915
2008
  }
1916
2009
 
1917
2010
  // src/components/dashboard/LiveTimelineCard.tsx
1918
- var import_react12 = require("react");
2011
+ var import_react14 = require("react");
1919
2012
  var import_jsx_runtime35 = require("react/jsx-runtime");
1920
- var SHOWN = 3;
2013
+ var SHOWN2 = 3;
1921
2014
  function EventIcon({ type }) {
1922
2015
  if (type === "goal") {
1923
2016
  return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "ss-w-fandash-live-tl-ico ss-w-fandash-live-tl-ico--goal", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "ss-w-fandash-live-tl-ball" }) });
@@ -1957,12 +2050,12 @@ function EventRow({ e }) {
1957
2050
  ] });
1958
2051
  }
1959
2052
  function LiveTimelineCard({ card, ui }) {
1960
- const [expanded, setExpanded] = (0, import_react12.useState)(false);
2053
+ const [expanded, setExpanded] = (0, import_react14.useState)(false);
1961
2054
  const events = card.data.events;
1962
2055
  if (!events || events.length === 0) return null;
1963
2056
  const sorted = [...events].sort((a, b) => b.minute - a.minute);
1964
- const rest = sorted.length - SHOWN;
1965
- const shown = expanded ? sorted : sorted.slice(0, SHOWN);
2057
+ const rest = sorted.length - SHOWN2;
2058
+ const shown = expanded ? sorted : sorted.slice(0, SHOWN2);
1966
2059
  const showMore = ui?.showMore ?? ((n) => `Show ${n} more`);
1967
2060
  const showLess = ui?.showLess ?? "Show less";
1968
2061
  return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "ss-w-fandash-card ss-w-fandash-live-timeline", children: [
@@ -1982,7 +2075,7 @@ function LiveTimelineCard({ card, ui }) {
1982
2075
  }
1983
2076
 
1984
2077
  // src/components/dashboard/MomentumWave.tsx
1985
- var import_react13 = require("react");
2078
+ var import_react15 = require("react");
1986
2079
  var import_jsx_runtime36 = require("react/jsx-runtime");
1987
2080
  var WIDTH = 270;
1988
2081
  var HEIGHT = 56;
@@ -2005,7 +2098,7 @@ function MomentumWave({
2005
2098
  }) {
2006
2099
  if (points.length === 0) return null;
2007
2100
  const { area, line, lastX, lastY } = buildPaths(points);
2008
- const clipId = (0, import_react13.useId)();
2101
+ const clipId = (0, import_react15.useId)();
2009
2102
  const topClipId = `${clipId}-top`;
2010
2103
  const bottomClipId = `${clipId}-bottom`;
2011
2104
  const topClass = clubIsHome ? "ss-w-fandash-live-mom-home" : "ss-w-fandash-live-mom-away";
@@ -2038,7 +2131,7 @@ function MomentumWave({
2038
2131
 
2039
2132
  // src/components/dashboard/LiveStatsCard.tsx
2040
2133
  var import_jsx_runtime37 = require("react/jsx-runtime");
2041
- function splitWidths(homeNum, awayNum) {
2134
+ function splitWidths2(homeNum, awayNum) {
2042
2135
  const total = homeNum + awayNum;
2043
2136
  if (total <= 0) return { home: "50%", away: "50%" };
2044
2137
  const homePct = Math.round(homeNum / total * 1e3) / 10;
@@ -2053,7 +2146,7 @@ function LiveStatsCard({ card }) {
2053
2146
  const awayValue = data.clubIsHome ? r.oppValue : r.clubValue;
2054
2147
  const homeNum = data.clubIsHome ? r.clubNum : r.oppNum;
2055
2148
  const awayNum = data.clubIsHome ? r.oppNum : r.clubNum;
2056
- const { home, away } = splitWidths(homeNum, awayNum);
2149
+ const { home, away } = splitWidths2(homeNum, awayNum);
2057
2150
  return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "ss-w-fandash-live-stat", children: [
2058
2151
  /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "ss-w-fandash-live-stat-row", children: [
2059
2152
  /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "ss-w-fandash-live-stat-value ss-w-fandash-live-stat-value--home", children: homeValue }),
@@ -2099,11 +2192,11 @@ function ClubFanDashboard({ dashboard, onTap, ui }) {
2099
2192
  function FanDashboardCard({ card, onTap, ui, goalEvents }) {
2100
2193
  switch (card.cardType) {
2101
2194
  case "fixture":
2102
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(FixtureCard, { card, onTap });
2195
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(FixtureCard, { card });
2103
2196
  case "countdown":
2104
2197
  return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(CountdownCard, { card });
2105
2198
  case "injuries":
2106
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(InjuriesCard, { card });
2199
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(InjuriesCard, { card, ui });
2107
2200
  case "reasonToBet":
2108
2201
  return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(ReasonToBetCard, { card });
2109
2202
  case "whereToWatch":
@@ -2187,11 +2280,11 @@ function turnAnchor(messages) {
2187
2280
  }
2188
2281
  function MessageList({ controller, ui, slip, onDashboardTap }) {
2189
2282
  const { state, send } = controller;
2190
- const listRef = (0, import_react14.useRef)(null);
2191
- const endRef = (0, import_react14.useRef)(null);
2192
- const pinnedRef = (0, import_react14.useRef)(true);
2193
- const anchoredTurnRef = (0, import_react14.useRef)(null);
2194
- (0, import_react14.useEffect)(() => {
2283
+ const listRef = (0, import_react16.useRef)(null);
2284
+ const endRef = (0, import_react16.useRef)(null);
2285
+ const pinnedRef = (0, import_react16.useRef)(true);
2286
+ const anchoredTurnRef = (0, import_react16.useRef)(null);
2287
+ (0, import_react16.useEffect)(() => {
2195
2288
  const anchor = turnAnchor(state.messages);
2196
2289
  const list = listRef.current;
2197
2290
  if (anchor && anchor.turnId !== anchoredTurnRef.current) {
@@ -2246,10 +2339,10 @@ function MessageList({ controller, ui, slip, onDashboardTap }) {
2246
2339
  }
2247
2340
 
2248
2341
  // src/components/ChatInput.tsx
2249
- var import_react15 = require("react");
2342
+ var import_react17 = require("react");
2250
2343
  var import_jsx_runtime42 = require("react/jsx-runtime");
2251
2344
  function ChatInput({ placeholder, streaming, onSend, onStop, stopLabel = "Stop response", sendLabel = "Send message" }) {
2252
- const [value, setValue] = (0, import_react15.useState)("");
2345
+ const [value, setValue] = (0, import_react17.useState)("");
2253
2346
  const submit = () => {
2254
2347
  const t = value.trim();
2255
2348
  if (!t) return;
@@ -2272,8 +2365,8 @@ function ChatInput({ placeholder, streaming, onSend, onStop, stopLabel = "Stop r
2272
2365
  var import_jsx_runtime43 = require("react/jsx-runtime");
2273
2366
  var FULLSCREEN_QUERY = "(max-width: 639px)";
2274
2367
  function useIsModal() {
2275
- const [modal, setModal] = (0, import_react16.useState)(false);
2276
- (0, import_react16.useEffect)(() => {
2368
+ const [modal, setModal] = (0, import_react18.useState)(false);
2369
+ (0, import_react18.useEffect)(() => {
2277
2370
  if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
2278
2371
  const mql = window.matchMedia(FULLSCREEN_QUERY);
2279
2372
  const sync = () => setModal(mql.matches);
@@ -2286,7 +2379,7 @@ function useIsModal() {
2286
2379
  function ChatPanel({ controller, ui, slip, onDashboardTap }) {
2287
2380
  const { state, close, stop, send } = controller;
2288
2381
  const isModal = useIsModal();
2289
- (0, import_react16.useEffect)(() => {
2382
+ (0, import_react18.useEffect)(() => {
2290
2383
  const onKey = (e) => {
2291
2384
  if (e.key === "Escape") close();
2292
2385
  };
@@ -2699,10 +2792,9 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
2699
2792
  .ss-w-fandash-fixture-team--away .ss-w-fandash-fixture-name { text-align: right; }
2700
2793
  .ss-w-fandash-fixture-vs { flex: none; font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--ss-w-faint); }
2701
2794
  /* date + venue as labelled rows, so a long stadium name gets its own line to ellipsis in */
2702
- .ss-w-fandash-fixture-meta { display: flex; flex-direction: column; gap: 1px; border-top: 1px solid var(--ss-w-line); padding-top: 8px; }
2703
- .ss-w-fandash-fixture-metarow { display: flex; align-items: baseline; gap: 9px; }
2704
- .ss-w-fandash-fixture-metakey { flex: none; width: 44px; font-size: 8.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--ss-w-faint); }
2705
- .ss-w-fandash-fixture-metaval { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12.5px; font-weight: 600; color: var(--ss-w-ink); }
2795
+ .ss-w-fandash-fixture-meta { border-top: 1px solid var(--ss-w-line); padding-top: 10px; text-align: center; font-size: 12.5px; color: var(--ss-w-faint); }
2796
+ .ss-w-fandash-fixture-kickoff { font-weight: 700; color: var(--ss-w-ink); }
2797
+ .ss-w-fandash-fixture-venue { font-weight: 600; }
2706
2798
  .ss-w-fandash-fact { font-size: 12px; color: var(--ss-w-ink); background: var(--ss-w-bubble); border-radius: 8px; padding: 6px 8px; }
2707
2799
  /* each head-to-head figure sits on its own shaded tile, so the grid gap separates wins/draws/losses */
2708
2800
  .ss-w-fandash-h2h .ss-w-fandash-split-cell { background: var(--ss-w-bubble); border-radius: 10px; padding: 12px 6px; }
@@ -2712,7 +2804,12 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
2712
2804
  /* last-five: one row per side, team name left, form pills right */
2713
2805
  .ss-w-fandash-fixture-form { display: flex; flex-direction: column; gap: 5px; }
2714
2806
  .ss-w-fandash-formrow { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
2807
+ .ss-w-fandash-formrow-team { display: flex; align-items: center; gap: 8px; min-width: 0; }
2808
+ .ss-w-fandash-formrow-team .ss-w-bi-crest { width: 20px; height: 20px; }
2809
+ .ss-w-fandash-formrow-team .ss-w-bi-crest-mono { font-size: 9px; }
2715
2810
  .ss-w-fandash-formrow-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12px; font-weight: 600; }
2811
+ .ss-w-fandash-injuries-more { margin-top: 10px; width: 100%; background: var(--ss-w-bubble); border: 1px solid var(--ss-w-line); border-radius: 9px; padding: 7px; font: inherit; font-size: 11.5px; font-weight: 700; color: var(--ss-w-accent); cursor: pointer; }
2812
+ .ss-w-fandash-injuries-more:focus-visible { outline: 2px solid var(--ss-w-accent); outline-offset: 2px; }
2716
2813
  .ss-w-fandash-form { display: inline-flex; gap: 3px; flex: none; }
2717
2814
  .ss-w-fandash-form-pill {
2718
2815
  display: inline-grid; place-items: center; width: 16px; height: 16px;
@@ -2776,35 +2873,76 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
2776
2873
  .ss-w-fandash-link-label { font-size: 12.5px; font-weight: 650; overflow-wrap: anywhere; }
2777
2874
  .ss-w-fandash-link-chevron { flex: none; width: 12px; height: 12px; color: var(--ss-w-accent); }
2778
2875
 
2779
- /* post-match result: full-time scoreboard -- team names flank the score, meta line underneath */
2780
- .ss-w-fandash-postmatch-scoreboard { display: flex; align-items: center; gap: 8px; }
2781
- .ss-w-fandash-postmatch-team { min-width: 0; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13px; font-weight: 650; }
2782
- .ss-w-fandash-postmatch-team--away { text-align: right; }
2783
- .ss-w-fandash-postmatch-score { flex: none; font-size: 20px; font-weight: 750; font-variant-numeric: tabular-nums; color: var(--ss-w-ink); }
2784
- .ss-w-fandash-postmatch-sep { flex: none; font-size: 14px; font-weight: 700; color: var(--ss-w-faint); }
2785
- .ss-w-fandash-postmatch-meta { font-size: 11.5px; color: var(--ss-w-faint); }
2786
-
2787
- /* post-match goals: a plain list, the club's own goals picked out in the accent color */
2788
- .ss-w-fandash-postmatch-goal-list { list-style: none; display: flex; flex-direction: column; gap: 4px; }
2789
- .ss-w-fandash-postmatch-goal { font-size: 12.5px; color: var(--ss-w-faint); }
2876
+ /* post-match result: full-time scoreboard, mirroring the live card's crest + big-score treatment.
2877
+ A neutral "Full time" pill sits left of a coloured Win/Draw/Loss tag; the 3-column main row
2878
+ (home crest+name | score | away crest+name, away reversed) puts the winner's score in full ink
2879
+ and the loser's dimmed; a centered meta line sits under a divider. */
2880
+ .ss-w-fandash-postmatch-top { display: flex; align-items: center; gap: 8px; margin-bottom: 15px; }
2881
+ .ss-w-fandash-postmatch-pill { display: inline-flex; align-items: center; gap: 5px; font-size: 10.5px; font-weight: 800; letter-spacing: .05em; text-transform: uppercase; color: var(--ss-w-faint); background: var(--ss-w-bubble); border: 1px solid var(--ss-w-line); border-radius: 6px; padding: 3px 8px; }
2882
+ .ss-w-fandash-postmatch-tag { margin-left: auto; flex: none; font-size: 11.5px; font-weight: 800; text-transform: uppercase; letter-spacing: .04em; }
2883
+ .ss-w-fandash-postmatch-tag--win { color: var(--ss-w-pos); }
2884
+ .ss-w-fandash-postmatch-tag--loss { color: var(--ss-w-neg); }
2885
+ .ss-w-fandash-postmatch-tag--draw { color: var(--ss-w-faint); }
2886
+ .ss-w-fandash-postmatch-main { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 10px; }
2887
+ .ss-w-fandash-postmatch-side { display: flex; align-items: center; gap: 10px; min-width: 0; }
2888
+ .ss-w-fandash-postmatch-side--away { flex-direction: row-reverse; text-align: right; }
2889
+ .ss-w-fandash-postmatch-crest { width: 38px; height: 38px; border-radius: 10px; flex: none; display: grid; place-items: center; color: #fff; font-weight: 800; font-size: 12.5px; object-fit: cover; box-shadow: 0 2px 6px rgba(0, 0, 0, .18); }
2890
+ .ss-w-fandash-postmatch-crest--fallback.ss-w-fandash-postmatch-crest--home { background: var(--ss-w-home); }
2891
+ .ss-w-fandash-postmatch-crest--fallback.ss-w-fandash-postmatch-crest--away { background: var(--ss-w-away); }
2892
+ .ss-w-fandash-postmatch-team-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 15px; font-weight: 700; line-height: 1.15; color: var(--ss-w-ink); }
2893
+ .ss-w-fandash-postmatch-score-main { display: flex; align-items: baseline; justify-content: center; font-size: 36px; font-weight: 850; font-variant-numeric: tabular-nums; line-height: 1; white-space: nowrap; }
2894
+ .ss-w-fandash-postmatch-score-value--win { color: var(--ss-w-ink); }
2895
+ .ss-w-fandash-postmatch-score-value--lose { color: var(--ss-w-faint); }
2896
+ .ss-w-fandash-postmatch-score-sep { color: var(--ss-w-faint); font-weight: 500; margin: 0 5px; }
2897
+ .ss-w-fandash-postmatch-meta { margin-top: 13px; padding-top: 12px; border-top: 1px solid var(--ss-w-line); font-size: 12px; color: var(--ss-w-faint); text-align: center; }
2898
+
2899
+ /* post-match goals: a football-ball icon per goal (mirrors the live timeline ball, duplicated here
2900
+ under the postmatch prefix), text dimmed for opponent goals and picked out in full ink + bold
2901
+ for the club's own goals */
2902
+ .ss-w-fandash-postmatch-goal-list { list-style: none; display: flex; flex-direction: column; gap: 6px; }
2903
+ .ss-w-fandash-postmatch-goal { display: flex; align-items: center; gap: 8px; font-size: 12.5px; color: var(--ss-w-faint); }
2904
+ .ss-w-fandash-postmatch-goal-ball { width: 11px; height: 11px; flex: none; border-radius: 50%; background: radial-gradient(circle at 50% 42%, #fff 0 34%, transparent 36%), var(--ss-w-ink); border: 1px solid var(--ss-w-ink); }
2790
2905
  .ss-w-fandash-postmatch-goal--club { color: var(--ss-w-ink); font-weight: 650; }
2791
2906
 
2792
- /* post-match stats: club value / stat label / opponent value, three columns per row */
2793
- .ss-w-fandash-postmatch-stat-rows { display: flex; flex-direction: column; gap: 5px; }
2794
- .ss-w-fandash-postmatch-stat-row { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 8px; }
2907
+ /* post-match stats: home value / stat label / away value, oriented by venue (u316), each row now
2908
+ backed by a home/away split bar -- the big upgrade from plain text -- plus a legend. Mirrors
2909
+ LiveStatsCard's split-bar treatment under the postmatch-prefixed classes; the shared
2910
+ --ss-w-home/--ss-w-away/--ss-w-track tokens are defined above. */
2911
+ .ss-w-fandash-postmatch-stat-rows { display: flex; flex-direction: column; gap: 15px; }
2912
+ .ss-w-fandash-postmatch-stat { display: flex; flex-direction: column; gap: 7px; }
2913
+ .ss-w-fandash-postmatch-stat-row { display: grid; grid-template-columns: 1fr auto 1fr; align-items: baseline; gap: 8px; }
2795
2914
  .ss-w-fandash-postmatch-stat-value { font-size: 13px; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--ss-w-ink); }
2796
- .ss-w-fandash-postmatch-stat-row .ss-w-fandash-postmatch-stat-value:last-child { text-align: right; }
2915
+ .ss-w-fandash-postmatch-stat-value--home { color: var(--ss-w-home); }
2916
+ .ss-w-fandash-postmatch-stat-value--away { color: var(--ss-w-away); text-align: right; }
2797
2917
  .ss-w-fandash-postmatch-stat-label { font-size: 10.5px; text-align: center; color: var(--ss-w-faint); text-transform: uppercase; letter-spacing: .03em; }
2798
-
2799
- /* post-match top performer: player name left, rating pill right */
2800
- .ss-w-fandash-postmatch-performer-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
2801
- .ss-w-fandash-postmatch-performer-name { font-size: 13px; font-weight: 650; overflow-wrap: anywhere; }
2802
- .ss-w-fandash-postmatch-performer-rating { flex: none; font-size: 12px; font-weight: 700; color: var(--ss-w-accent); background: color-mix(in srgb, var(--ss-w-accent) 13%, var(--ss-w-panel)); border-radius: 999px; padding: 2px 9px; }
2803
-
2804
- /* post-match next: the upcoming fixture teaser -- opponent left, when-label right */
2805
- .ss-w-fandash-postmatch-next-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
2806
- .ss-w-fandash-postmatch-next-opponent { font-size: 13px; font-weight: 650; overflow-wrap: anywhere; }
2807
- .ss-w-fandash-postmatch-next-when { flex: none; font-size: 11.5px; color: var(--ss-w-faint); }
2918
+ .ss-w-fandash-postmatch-stat-bar { position: relative; height: 8px; border-radius: 999px; background: var(--ss-w-track); overflow: hidden; display: flex; }
2919
+ .ss-w-fandash-postmatch-stat-bar-home { height: 100%; background: var(--ss-w-home); }
2920
+ .ss-w-fandash-postmatch-stat-bar-away { height: 100%; background: var(--ss-w-away); margin-left: auto; }
2921
+ .ss-w-fandash-postmatch-legend { display: flex; gap: 14px; margin-top: 13px; padding-top: 13px; border-top: 1px solid var(--ss-w-line); font-size: 11px; color: var(--ss-w-faint); }
2922
+ .ss-w-fandash-postmatch-legend-item { display: inline-flex; align-items: center; gap: 6px; }
2923
+ .ss-w-fandash-postmatch-legend-swatch { width: 10px; height: 10px; border-radius: 3px; flex: none; }
2924
+ .ss-w-fandash-postmatch-legend-swatch--home { background: var(--ss-w-home); }
2925
+ .ss-w-fandash-postmatch-legend-swatch--away { background: var(--ss-w-away); }
2926
+
2927
+ /* post-match top performer (full mockup treatment): gradient initials avatar + name + a
2928
+ prominent rating chip. Avatar gradient reuses the --ss-w-away token, same pairing as the live
2929
+ crest fallback; "?" renders through the same avatar span when the name is blank. */
2930
+ .ss-w-fandash-postmatch-perf-row { display: flex; align-items: center; gap: 12px; }
2931
+ .ss-w-fandash-postmatch-perf-avatar {
2932
+ flex: none; width: 42px; height: 42px; border-radius: 50%;
2933
+ display: grid; place-items: center;
2934
+ font-size: 14px; font-weight: 800; color: #fff;
2935
+ background: linear-gradient(135deg, var(--ss-w-away), color-mix(in srgb, var(--ss-w-away) 55%, #000));
2936
+ }
2937
+ .ss-w-fandash-postmatch-perf-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 15px; font-weight: 700; }
2938
+ .ss-w-fandash-postmatch-perf-rating { margin-left: auto; flex: none; font-size: 13px; font-weight: 800; font-variant-numeric: tabular-nums; color: var(--ss-w-accent); background: color-mix(in srgb, var(--ss-w-accent) 14%, var(--ss-w-panel)); border-radius: 999px; padding: 3px 11px; }
2939
+
2940
+ /* post-match next (v1, modest): whenLabel is already a complete localized phrase (opponent +
2941
+ venue + kickoff) composed server-side, so this card renders just that one line -- dressed up
2942
+ with an accent rule rather than a duplicated opponent line. The richer opponent-headline/venue-
2943
+ chip/crest layout from the mockup needs a server field split and is deferred. */
2944
+ .ss-w-fandash-postmatch-next-row { display: flex; align-items: center; gap: 10px; border-left: 3px solid var(--ss-w-accent); padding-left: 10px; }
2945
+ .ss-w-fandash-postmatch-next-when { font-size: 13.5px; font-weight: 650; color: var(--ss-w-ink); line-height: 1.3; }
2808
2946
 
2809
2947
  /* resting next: the between-matches fixture teaser -- when-label left, competition badge right */
2810
2948
  .ss-w-fandash-resting-next-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
@@ -2931,11 +3069,11 @@ function injectStyles(root) {
2931
3069
  function StatsWidget(props) {
2932
3070
  const injectedClient = "client" in props ? props.client : void 0;
2933
3071
  const cfg = props.config;
2934
- const built = (0, import_react17.useMemo)(() => buildClient(props), [injectedClient, cfg?.operatorId, cfg?.publicKey, cfg?.baseUrl]);
2935
- const ui = (0, import_react17.useMemo)(() => normalizeUi(props.config ?? { operatorId: "", publicKey: "" }), [props.config]);
2936
- const rootRef = (0, import_react17.useRef)(null);
3072
+ const built = (0, import_react19.useMemo)(() => buildClient(props), [injectedClient, cfg?.operatorId, cfg?.publicKey, cfg?.baseUrl]);
3073
+ const ui = (0, import_react19.useMemo)(() => normalizeUi(props.config ?? { operatorId: "", publicKey: "" }), [props.config]);
3074
+ const rootRef = (0, import_react19.useRef)(null);
2937
3075
  const controller = useChatStream(built?.conversation ?? emptyConversation(), ui.starters, built ? ui.greetingMessage : void 0);
2938
- const slip = (0, import_react17.useMemo)(
3076
+ const slip = (0, import_react19.useMemo)(
2939
3077
  () => ({
2940
3078
  onAddToSlip: props.config?.onAddToSlip,
2941
3079
  conversationId: controller.state.conversationId ?? void 0,
@@ -2948,11 +3086,11 @@ function StatsWidget(props) {
2948
3086
  }),
2949
3087
  [props.config?.onAddToSlip, controller.state.conversationId, built]
2950
3088
  );
2951
- const onDashboardTap = (0, import_react17.useMemo)(
3089
+ const onDashboardTap = (0, import_react19.useMemo)(
2952
3090
  () => built ? createDashboardTapSignal((input) => built.conversation.sendSignal(input)) : void 0,
2953
3091
  [built]
2954
3092
  );
2955
- (0, import_react17.useEffect)(() => {
3093
+ (0, import_react19.useEffect)(() => {
2956
3094
  if (!built || !ui.injectStyles) return;
2957
3095
  const node = rootRef.current?.getRootNode();
2958
3096
  if (node) injectStyles(node);