@sensiblestats/widget-react 0.23.0 → 0.24.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/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # @sensiblestats/widget-react
2
2
 
3
+ ## 0.24.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 04c6e5b: Add post-match club dashboard cards (result, goals, stats, top performer, what's next); the three interactive cards tap through via actionRef.
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies [04c6e5b]
12
+ - @sensiblestats/widget-sdk@0.22.0
13
+
14
+ ## 0.23.1
15
+
16
+ ### Patch Changes
17
+
18
+ - a1d4987: Fan-dashboard fixture and congested-week card taps now send the card's opaque `actionRef` alongside its `actionLabel`, so the server resolves the pre-issued action binding for that card instead of re-planning a prose command.
19
+ - Updated dependencies [a1d4987]
20
+ - @sensiblestats/widget-sdk@0.21.0
21
+
3
22
  ## 0.23.0
4
23
 
5
24
  ### Minor Changes
package/dist/index.cjs CHANGED
@@ -359,8 +359,9 @@ function toCardVM(card) {
359
359
  function toActionVM(action) {
360
360
  const label = str(action.actionLabel) ?? str(action.label) ?? str(action.text) ?? str(action.title) ?? "Continue";
361
361
  const actionId = str(action.actionId) ?? str(action.id);
362
+ const actionRef = str(action.actionRef);
362
363
  const message = str(action.actionValue) ?? str(action.message) ?? str(action.query) ?? label;
363
- return { label, actionId, message };
364
+ return { label, actionId, actionRef, message };
364
365
  }
365
366
  function toChipVM(intent) {
366
367
  const text = str(intent.text) ?? str(intent.label) ?? str(intent.title);
@@ -1557,67 +1558,147 @@ function LinksCard({ card }) {
1557
1558
  ] });
1558
1559
  }
1559
1560
 
1560
- // src/components/dashboard/ClubFanDashboard.tsx
1561
+ // src/components/dashboard/PostMatchResultCard.tsx
1561
1562
  var import_jsx_runtime25 = require("react/jsx-runtime");
1563
+ function PostMatchResultCard({ card }) {
1564
+ const { data } = card;
1565
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "ss-w-fandash-card ss-w-fandash-postmatch-result", children: [
1566
+ card.title ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "ss-w-fandash-eyebrow", children: card.title }) : null,
1567
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "ss-w-fandash-postmatch-scoreboard", children: [
1568
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "ss-w-fandash-postmatch-team", children: data.homeName }),
1569
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "ss-w-fandash-postmatch-score", children: data.homeScore }),
1570
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "ss-w-fandash-postmatch-sep", children: "\u2013" }),
1571
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "ss-w-fandash-postmatch-score", children: data.awayScore }),
1572
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "ss-w-fandash-postmatch-team ss-w-fandash-postmatch-team--away", children: data.awayName })
1573
+ ] }),
1574
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "ss-w-fandash-postmatch-meta", children: [
1575
+ data.resultLabel,
1576
+ " \xB7 ",
1577
+ data.kickoffLabel,
1578
+ data.competition ? ` \xB7 ${data.competition}` : ""
1579
+ ] })
1580
+ ] });
1581
+ }
1582
+
1583
+ // src/components/dashboard/PostMatchGoalsCard.tsx
1584
+ var import_jsx_runtime26 = require("react/jsx-runtime");
1585
+ function PostMatchGoalsCard({ card, onTap }) {
1586
+ 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: [
1587
+ card.title ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "ss-w-fandash-eyebrow", children: card.title }) : null,
1588
+ /* @__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}`)) }),
1589
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "ss-w-fandash-card-cta", children: card.actionLabel })
1590
+ ] });
1591
+ }
1592
+
1593
+ // src/components/dashboard/PostMatchStatsCard.tsx
1594
+ var import_jsx_runtime27 = require("react/jsx-runtime");
1595
+ function PostMatchStatsCard({ card, onTap }) {
1596
+ 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: [
1597
+ card.title ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "ss-w-fandash-eyebrow", children: card.title }) : null,
1598
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "ss-w-fandash-postmatch-stat-rows", children: card.data.rows.map((r, i) => /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "ss-w-fandash-postmatch-stat-row", children: [
1599
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "ss-w-fandash-postmatch-stat-value", children: r.clubValue }),
1600
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "ss-w-fandash-postmatch-stat-label", children: r.label }),
1601
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "ss-w-fandash-postmatch-stat-value", children: r.oppValue })
1602
+ ] }, `${r.label}-${i}`)) }),
1603
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "ss-w-fandash-card-cta", children: card.actionLabel })
1604
+ ] });
1605
+ }
1606
+
1607
+ // src/components/dashboard/PostMatchTopPerformerCard.tsx
1608
+ var import_jsx_runtime28 = require("react/jsx-runtime");
1609
+ function PostMatchTopPerformerCard({ card, onTap }) {
1610
+ const { data } = card;
1611
+ 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: [
1612
+ card.title ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "ss-w-fandash-eyebrow", children: card.title }) : null,
1613
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "ss-w-fandash-postmatch-performer-row", children: [
1614
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "ss-w-fandash-postmatch-performer-name", children: data.playerName }),
1615
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "ss-w-fandash-postmatch-performer-rating", children: data.ratingLabel })
1616
+ ] }),
1617
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "ss-w-fandash-card-cta", children: card.actionLabel })
1618
+ ] });
1619
+ }
1620
+
1621
+ // src/components/dashboard/PostMatchNextCard.tsx
1622
+ var import_jsx_runtime29 = require("react/jsx-runtime");
1623
+ function PostMatchNextCard({ card }) {
1624
+ const { data } = card;
1625
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "ss-w-fandash-card ss-w-fandash-postmatch-next", children: [
1626
+ card.title ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "ss-w-fandash-eyebrow", children: card.title }) : null,
1627
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "ss-w-fandash-postmatch-next-row", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "ss-w-fandash-postmatch-next-when", children: data.whenLabel }) })
1628
+ ] });
1629
+ }
1630
+
1631
+ // src/components/dashboard/ClubFanDashboard.tsx
1632
+ var import_jsx_runtime30 = require("react/jsx-runtime");
1562
1633
  function ClubFanDashboard({ dashboard, onTap, ui }) {
1563
1634
  const orderedCards = [
1564
1635
  ...dashboard.cards.filter((c) => c.cardType === "countdown"),
1565
1636
  ...dashboard.cards.filter((c) => c.cardType !== "countdown")
1566
1637
  ];
1567
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "ss-w-fandash", children: [
1568
- dashboard.greeting ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "ss-w-fandash-greeting", children: dashboard.greeting }) : null,
1569
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "ss-w-fandash-cards", children: orderedCards.map((card, i) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(FanDashboardCard, { card, onTap, ui }, `${card.cardType}-${i}`)) })
1638
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "ss-w-fandash", children: [
1639
+ dashboard.greeting ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "ss-w-fandash-greeting", children: dashboard.greeting }) : null,
1640
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "ss-w-fandash-cards", children: orderedCards.map((card, i) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(FanDashboardCard, { card, onTap, ui }, `${card.cardType}-${i}`)) })
1570
1641
  ] });
1571
1642
  }
1572
1643
  function FanDashboardCard({ card, onTap, ui }) {
1573
1644
  switch (card.cardType) {
1574
1645
  case "fixture":
1575
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(FixtureCard, { card, onTap });
1646
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(FixtureCard, { card, onTap });
1576
1647
  case "countdown":
1577
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(CountdownCard, { card });
1648
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(CountdownCard, { card });
1578
1649
  case "injuries":
1579
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(InjuriesCard, { card });
1650
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(InjuriesCard, { card });
1580
1651
  case "reasonToBet":
1581
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ReasonToBetCard, { card });
1652
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(ReasonToBetCard, { card });
1582
1653
  case "whereToWatch":
1583
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(WhereToWatchCard, { card });
1654
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(WhereToWatchCard, { card });
1584
1655
  case "congestedWeek":
1585
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(CongestedWeekCard, { card, onTap });
1656
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(CongestedWeekCard, { card, onTap });
1586
1657
  case "transfers":
1587
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(TransfersCard, { card });
1658
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(TransfersCard, { card });
1588
1659
  case "links":
1589
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(LinksCard, { card });
1660
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(LinksCard, { card });
1661
+ case "postMatchResult":
1662
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(PostMatchResultCard, { card });
1663
+ case "postMatchGoals":
1664
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(PostMatchGoalsCard, { card, onTap });
1665
+ case "postMatchStats":
1666
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(PostMatchStatsCard, { card, onTap });
1667
+ case "postMatchTopPerformer":
1668
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(PostMatchTopPerformerCard, { card, onTap });
1669
+ case "postMatchNext":
1670
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(PostMatchNextCard, { card });
1590
1671
  default:
1591
1672
  return null;
1592
1673
  }
1593
1674
  }
1594
1675
 
1595
1676
  // src/components/ChatMessage.tsx
1596
- var import_jsx_runtime26 = require("react/jsx-runtime");
1677
+ var import_jsx_runtime31 = require("react/jsx-runtime");
1597
1678
  function ChatMessage({ message, disabled, onAct, onTap, ui, slip }) {
1598
1679
  if (message.role === "user") {
1599
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "ss-w-msg ss-w-user", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "ss-w-bubble", children: message.text }) });
1680
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "ss-w-msg ss-w-user", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "ss-w-bubble", children: message.text }) });
1600
1681
  }
1601
1682
  const onFanDashboardTap = (card) => {
1602
- onAct({ message: card.actionValue, label: card.actionLabel || card.title || "" });
1683
+ onAct({ message: card.actionLabel, actionRef: card.actionRef, label: card.actionLabel || card.title || "" });
1603
1684
  };
1604
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "ss-w-msg ss-w-bot", children: [
1605
- message.text && !message.greetingDashboard && !message.clubFanDashboard ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Markdown, { text: message.text }) : null,
1606
- message.greetingDashboard && !message.clubFanDashboard ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(GreetingDashboard, { dashboard: message.greetingDashboard, onTap }) : null,
1607
- message.clubFanDashboard ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ClubFanDashboard, { dashboard: message.clubFanDashboard, onTap: onFanDashboardTap, ui }) : null,
1608
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(EntityCardList, { cards: message.cards, disabled, showLessLabel: ui?.showLess, showMoreLabel: ui?.showMore }),
1609
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(BettingInsightList, { insights: message.insights, ui, slip }),
1610
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(MarketOddsCardList, { cards: message.marketOdds, ui, slip }),
1611
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(OddsMovementCardList, { cards: message.oddsMovement, ui }),
1612
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ActionButtons, { actions: message.actions, loading: false, disabled, onAct })
1685
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "ss-w-msg ss-w-bot", children: [
1686
+ message.text && !message.greetingDashboard && !message.clubFanDashboard ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Markdown, { text: message.text }) : null,
1687
+ message.greetingDashboard && !message.clubFanDashboard ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(GreetingDashboard, { dashboard: message.greetingDashboard, onTap }) : null,
1688
+ message.clubFanDashboard ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(ClubFanDashboard, { dashboard: message.clubFanDashboard, onTap: onFanDashboardTap, ui }) : null,
1689
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(EntityCardList, { cards: message.cards, disabled, showLessLabel: ui?.showLess, showMoreLabel: ui?.showMore }),
1690
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(BettingInsightList, { insights: message.insights, ui, slip }),
1691
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(MarketOddsCardList, { cards: message.marketOdds, ui, slip }),
1692
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(OddsMovementCardList, { cards: message.oddsMovement, ui }),
1693
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(ActionButtons, { actions: message.actions, loading: false, disabled, onAct })
1613
1694
  ] });
1614
1695
  }
1615
1696
 
1616
1697
  // src/components/IntentChips.tsx
1617
- var import_jsx_runtime27 = require("react/jsx-runtime");
1698
+ var import_jsx_runtime32 = require("react/jsx-runtime");
1618
1699
  function IntentChips({ chips, onPick }) {
1619
1700
  if (chips.length === 0) return null;
1620
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "ss-w-chips", children: chips.map((c, i) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("button", { type: "button", className: "ss-w-chip", onClick: () => onPick(c.text), children: c.text }, `${c.text}-${i}`)) });
1701
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "ss-w-chips", children: chips.map((c, i) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("button", { type: "button", className: "ss-w-chip", onClick: () => onPick(c.text), children: c.text }, `${c.text}-${i}`)) });
1621
1702
  }
1622
1703
 
1623
1704
  // src/scroll.ts
@@ -1627,7 +1708,7 @@ function isPinnedToBottom(el, threshold = PIN_THRESHOLD) {
1627
1708
  }
1628
1709
 
1629
1710
  // src/components/MessageList.tsx
1630
- var import_jsx_runtime28 = require("react/jsx-runtime");
1711
+ var import_jsx_runtime33 = require("react/jsx-runtime");
1631
1712
  function MessageList({ controller, ui, slip, onDashboardTap }) {
1632
1713
  const { state, send } = controller;
1633
1714
  const listRef = (0, import_react9.useRef)(null);
@@ -1638,7 +1719,7 @@ function MessageList({ controller, ui, slip, onDashboardTap }) {
1638
1719
  }, [state.messages, state.status]);
1639
1720
  const hasUserMessage = state.messages.some((m) => m.role === "user");
1640
1721
  const hasDashboard = state.messages.some((m) => m.role === "assistant" && (m.greetingDashboard || m.clubFanDashboard));
1641
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
1722
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
1642
1723
  "div",
1643
1724
  {
1644
1725
  className: "ss-w-list",
@@ -1648,12 +1729,12 @@ function MessageList({ controller, ui, slip, onDashboardTap }) {
1648
1729
  if (listRef.current) pinnedRef.current = isPinnedToBottom(listRef.current);
1649
1730
  },
1650
1731
  children: [
1651
- state.messages.map((m) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
1732
+ state.messages.map((m) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
1652
1733
  ChatMessage,
1653
1734
  {
1654
1735
  message: m,
1655
1736
  disabled: state.isStreaming,
1656
- onAct: (a) => send(a.message, { actionId: a.actionId, displayText: a.label }),
1737
+ onAct: (a) => send(a.message, { actionId: a.actionId, actionRef: a.actionRef, displayText: a.label }),
1657
1738
  onTap: (tile, index) => {
1658
1739
  send(tile.actionValue, { displayText: tile.title });
1659
1740
  if (m.role === "assistant" && m.greetingDashboard) onDashboardTap?.(tile, index, m.greetingDashboard.layout);
@@ -1663,15 +1744,15 @@ function MessageList({ controller, ui, slip, onDashboardTap }) {
1663
1744
  },
1664
1745
  m.id
1665
1746
  )),
1666
- state.isStreaming && state.actionsLoading ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(ActionButtons, { actions: [], loading: true, onAct: () => {
1747
+ state.isStreaming && state.actionsLoading ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ActionButtons, { actions: [], loading: true, onAct: () => {
1667
1748
  } }) : null,
1668
- state.status ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "ss-w-status", children: state.status }) : null,
1669
- state.error ? /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "ss-w-error", role: "alert", children: [
1670
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { children: "message" in state.error ? state.error.message : ui.somethingWentWrong }),
1671
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("button", { type: "button", className: "ss-w-retry", onClick: () => controller.retry(), children: ui.retry })
1749
+ state.status ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "ss-w-status", children: state.status }) : null,
1750
+ state.error ? /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "ss-w-error", role: "alert", children: [
1751
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { children: "message" in state.error ? state.error.message : ui.somethingWentWrong }),
1752
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("button", { type: "button", className: "ss-w-retry", onClick: () => controller.retry(), children: ui.retry })
1672
1753
  ] }) : null,
1673
- !hasUserMessage && !hasDashboard ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(IntentChips, { chips: state.starters, onPick: (t) => send(t) }) : null,
1674
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { ref: endRef })
1754
+ !hasUserMessage && !hasDashboard ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(IntentChips, { chips: state.starters, onPick: (t) => send(t) }) : null,
1755
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { ref: endRef })
1675
1756
  ]
1676
1757
  }
1677
1758
  );
@@ -1679,7 +1760,7 @@ function MessageList({ controller, ui, slip, onDashboardTap }) {
1679
1760
 
1680
1761
  // src/components/ChatInput.tsx
1681
1762
  var import_react10 = require("react");
1682
- var import_jsx_runtime29 = require("react/jsx-runtime");
1763
+ var import_jsx_runtime34 = require("react/jsx-runtime");
1683
1764
  function ChatInput({ placeholder, streaming, onSend, onStop, stopLabel = "Stop response", sendLabel = "Send message" }) {
1684
1765
  const [value, setValue] = (0, import_react10.useState)("");
1685
1766
  const submit = () => {
@@ -1694,14 +1775,14 @@ function ChatInput({ placeholder, streaming, onSend, onStop, stopLabel = "Stop r
1694
1775
  submit();
1695
1776
  }
1696
1777
  };
1697
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "ss-w-input", children: [
1698
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("textarea", { className: "ss-w-textarea", rows: 1, placeholder, value, disabled: streaming, onChange: (e) => setValue(e.target.value), onKeyDown }),
1699
- streaming ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("button", { type: "button", className: "ss-w-send ss-w-stop", "aria-label": stopLabel, onClick: onStop, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "ss-w-stop-glyph" }) }) : /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("button", { type: "button", className: "ss-w-send", "aria-label": sendLabel, onClick: submit, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(SendIcon, {}) })
1778
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "ss-w-input", children: [
1779
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("textarea", { className: "ss-w-textarea", rows: 1, placeholder, value, disabled: streaming, onChange: (e) => setValue(e.target.value), onKeyDown }),
1780
+ streaming ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("button", { type: "button", className: "ss-w-send ss-w-stop", "aria-label": stopLabel, onClick: onStop, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "ss-w-stop-glyph" }) }) : /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("button", { type: "button", className: "ss-w-send", "aria-label": sendLabel, onClick: submit, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(SendIcon, {}) })
1700
1781
  ] });
1701
1782
  }
1702
1783
 
1703
1784
  // src/components/ChatPanel.tsx
1704
- var import_jsx_runtime30 = require("react/jsx-runtime");
1785
+ var import_jsx_runtime35 = require("react/jsx-runtime");
1705
1786
  var FULLSCREEN_QUERY = "(max-width: 639px)";
1706
1787
  function useIsModal() {
1707
1788
  const [modal, setModal] = (0, import_react11.useState)(false);
@@ -1725,10 +1806,10 @@ function ChatPanel({ controller, ui, slip, onDashboardTap }) {
1725
1806
  window.addEventListener("keydown", onKey);
1726
1807
  return () => window.removeEventListener("keydown", onKey);
1727
1808
  }, [close]);
1728
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "ss-w-panel", role: "dialog", "aria-modal": isModal, "aria-label": ui.chatDialogLabel, children: [
1729
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(ChatHeader, { onClose: close, closeLabel: ui.closeChat }),
1730
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(MessageList, { controller, ui, slip, onDashboardTap }),
1731
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(ChatInput, { placeholder: ui.placeholder, streaming: state.isStreaming, onSend: (t) => send(t), onStop: stop, stopLabel: ui.stopResponse, sendLabel: ui.sendMessage })
1809
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "ss-w-panel", role: "dialog", "aria-modal": isModal, "aria-label": ui.chatDialogLabel, children: [
1810
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(ChatHeader, { onClose: close, closeLabel: ui.closeChat }),
1811
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(MessageList, { controller, ui, slip, onDashboardTap }),
1812
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(ChatInput, { placeholder: ui.placeholder, streaming: state.isStreaming, onSend: (t) => send(t), onStop: stop, stopLabel: ui.stopResponse, sendLabel: ui.sendMessage })
1732
1813
  ] });
1733
1814
  }
1734
1815
 
@@ -2193,10 +2274,40 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
2193
2274
  .ss-w-fandash-link-tile:hover { background: color-mix(in srgb, var(--ss-w-accent) 16%, var(--ss-w-panel)); }
2194
2275
  .ss-w-fandash-link-label { font-size: 12.5px; font-weight: 650; overflow-wrap: anywhere; }
2195
2276
  .ss-w-fandash-link-chevron { flex: none; width: 12px; height: 12px; color: var(--ss-w-accent); }
2277
+
2278
+ /* post-match result: full-time scoreboard -- team names flank the score, meta line underneath */
2279
+ .ss-w-fandash-postmatch-scoreboard { display: flex; align-items: center; gap: 8px; }
2280
+ .ss-w-fandash-postmatch-team { min-width: 0; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13px; font-weight: 650; }
2281
+ .ss-w-fandash-postmatch-team--away { text-align: right; }
2282
+ .ss-w-fandash-postmatch-score { flex: none; font-size: 20px; font-weight: 750; font-variant-numeric: tabular-nums; color: var(--ss-w-ink); }
2283
+ .ss-w-fandash-postmatch-sep { flex: none; font-size: 14px; font-weight: 700; color: var(--ss-w-faint); }
2284
+ .ss-w-fandash-postmatch-meta { font-size: 11.5px; color: var(--ss-w-faint); }
2285
+
2286
+ /* post-match goals: a plain list, the club's own goals picked out in the accent color */
2287
+ .ss-w-fandash-postmatch-goal-list { list-style: none; display: flex; flex-direction: column; gap: 4px; }
2288
+ .ss-w-fandash-postmatch-goal { font-size: 12.5px; color: var(--ss-w-faint); }
2289
+ .ss-w-fandash-postmatch-goal--club { color: var(--ss-w-ink); font-weight: 650; }
2290
+
2291
+ /* post-match stats: club value / stat label / opponent value, three columns per row */
2292
+ .ss-w-fandash-postmatch-stat-rows { display: flex; flex-direction: column; gap: 5px; }
2293
+ .ss-w-fandash-postmatch-stat-row { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 8px; }
2294
+ .ss-w-fandash-postmatch-stat-value { font-size: 13px; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--ss-w-ink); }
2295
+ .ss-w-fandash-postmatch-stat-row .ss-w-fandash-postmatch-stat-value:last-child { text-align: right; }
2296
+ .ss-w-fandash-postmatch-stat-label { font-size: 10.5px; text-align: center; color: var(--ss-w-faint); text-transform: uppercase; letter-spacing: .03em; }
2297
+
2298
+ /* post-match top performer: player name left, rating pill right */
2299
+ .ss-w-fandash-postmatch-performer-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
2300
+ .ss-w-fandash-postmatch-performer-name { font-size: 13px; font-weight: 650; overflow-wrap: anywhere; }
2301
+ .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; }
2302
+
2303
+ /* post-match next: the upcoming fixture teaser -- opponent left, when-label right */
2304
+ .ss-w-fandash-postmatch-next-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
2305
+ .ss-w-fandash-postmatch-next-opponent { font-size: 13px; font-weight: 650; overflow-wrap: anywhere; }
2306
+ .ss-w-fandash-postmatch-next-when { flex: none; font-size: 11.5px; color: var(--ss-w-faint); }
2196
2307
  `;
2197
2308
 
2198
2309
  // src/StatsWidget.tsx
2199
- var import_jsx_runtime31 = require("react/jsx-runtime");
2310
+ var import_jsx_runtime36 = require("react/jsx-runtime");
2200
2311
  function buildClient(props) {
2201
2312
  try {
2202
2313
  if ("client" in props && props.client) {
@@ -2249,7 +2360,7 @@ function StatsWidget(props) {
2249
2360
  }, [built, ui.injectStyles]);
2250
2361
  if (!built) return null;
2251
2362
  const attrs = themeAttrs(ui);
2252
- return /* @__PURE__ */ (0, import_jsx_runtime31.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_runtime31.jsx)(ChatPanel, { controller, ui, slip, onDashboardTap }) : /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
2363
+ return /* @__PURE__ */ (0, import_jsx_runtime36.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_runtime36.jsx)(ChatPanel, { controller, ui, slip, onDashboardTap }) : /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
2253
2364
  ChatFab,
2254
2365
  {
2255
2366
  label: ui.launcherLabel,