@sensiblestats/widget-react 0.72.2 → 0.73.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @sensiblestats/widget-react
2
2
 
3
+ ## 0.73.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Goal dashboard rows are compact cards: 60px tall with 8px corners, and a tile's badge shows as a price column on the right instead of a pill under the subtitle.
8
+
9
+ ## 0.73.0
10
+
11
+ ### Minor Changes
12
+
13
+ - Set the numbers: each row is now one sentence with its numbers, a "3 ready" or "ready at 4.97" line, and a round send button. The picks and combo legs no longer show inside the tool; they appear in the chat after the send. A fourth row offers a second combo that starts high ("Total 50.0 with 6 matches"). The English combo row reads "Combo of 3 paying 5.0".
14
+
3
15
  ## 0.72.2
4
16
 
5
17
  ### Patch Changes
package/dist/index.cjs CHANGED
@@ -167,7 +167,10 @@ var STRINGS = {
167
167
  dialName: "Set the numbers and Build a combo",
168
168
  maxPriceRow: "{count} picks, max {price}",
169
169
  minPriceRow: "Picks from {price} up",
170
- comboRow: "A combo of {legs} matches priced at about {total}",
170
+ comboRow: "Combo of {legs} paying {total}",
171
+ bigComboRow: "Total {total} with {legs} matches",
172
+ readyCount: (n) => `${n} ready`,
173
+ readyAt: (total) => `ready at ${total.toFixed(2)}`,
171
174
  maxPriceDisplay: (count, price) => `${count} picks, max ${price.toFixed(2)}`,
172
175
  maxPriceMessage: (count, price) => `Show me ${count} picks priced at ${price.toFixed(2)} or less.`,
173
176
  minPriceDisplay: (count, price) => `${count} picks from ${price.toFixed(2)} up`,
@@ -499,6 +502,9 @@ var STRINGS = {
499
502
  maxPriceRow: "{count} se\xE7im, en fazla {price}",
500
503
  minPriceRow: "{price} ve \xFCzeri se\xE7imler",
501
504
  comboRow: "Yakla\u015F\u0131k {total} oranl\u0131 {legs} ma\xE7l\u0131k kombin",
505
+ bigComboRow: "{legs} ma\xE7la toplam {total}",
506
+ readyCount: (n) => `${n} haz\u0131r`,
507
+ readyAt: (total) => `${total.toFixed(2)} ile haz\u0131r`,
502
508
  maxPriceDisplay: (count, price) => `${count} se\xE7im, en fazla ${price.toFixed(2)}`,
503
509
  maxPriceMessage: (count, price) => `${price.toFixed(2)} veya alt\u0131 oranl\u0131 ${count} se\xE7im g\xF6ster.`,
504
510
  minPriceDisplay: (count, price) => `${count} se\xE7im, ${price.toFixed(2)} ve \xFCzeri`,
@@ -4194,11 +4200,13 @@ function HeroTile({ tile, onTap, oddsLabel }) {
4194
4200
  ] })
4195
4201
  ] });
4196
4202
  }
4197
- function DashboardTile({ tile, onTap, oddsLabel = "Odds" }) {
4203
+ function DashboardTile({ tile, onTap, oddsLabel = "Odds", badgePlacement = "meta" }) {
4198
4204
  if (tile.emphasis === "hero") return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(HeroTile, { tile, onTap, oddsLabel });
4199
4205
  const spanClass = tile.span === "full" ? "ss-w-dash-tile--full" : "ss-w-dash-tile--half";
4200
4206
  const crests = (tile.imageUrls ?? []).slice(0, MAX_CRESTS);
4201
- const hasMeta = Boolean(tile.badgeText) || crests.length > 0;
4207
+ const endBadge = badgePlacement === "end" && tile.badgeText ? tile.badgeText : null;
4208
+ const metaBadge = endBadge ? null : tile.badgeText;
4209
+ const hasMeta = Boolean(metaBadge) || crests.length > 0;
4202
4210
  return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("button", { type: "button", className: `ss-w-dash-tile ${spanClass}`, onClick: onTap, children: [
4203
4211
  /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "ss-w-dash-tile-icon", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(DashboardIcon, { name: tile.icon }) }),
4204
4212
  /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { className: "ss-w-dash-tile-body", children: [
@@ -4209,12 +4217,12 @@ function DashboardTile({ tile, onTap, oddsLabel = "Odds" }) {
4209
4217
  // icon/chevron row -- at the half-span tile's ~180px width a nowrap badge alone
4210
4218
  // (~70px) left the title column at ~22px and forced character-by-character wrapping.
4211
4219
  /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { className: "ss-w-dash-tile-meta", children: [
4212
- tile.badgeText ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "ss-w-dash-tile-badge", children: tile.badgeText }) : null,
4220
+ metaBadge ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "ss-w-dash-tile-badge", children: metaBadge }) : null,
4213
4221
  crests.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "ss-w-dash-tile-crests", children: crests.map((url, i) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "ss-w-dash-tile-crest", style: { backgroundImage: `url(${url})` }, "aria-hidden": "true" }, `${url}-${i}`)) }) : null
4214
4222
  ] })
4215
4223
  ) : null
4216
4224
  ] }),
4217
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "ss-w-dash-tile-chevron", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ChevronIcon, {}) })
4225
+ endBadge ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "ss-w-dash-tile-value", children: endBadge }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "ss-w-dash-tile-chevron", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ChevronIcon, {}) })
4218
4226
  ] });
4219
4227
  }
4220
4228
 
@@ -4229,12 +4237,14 @@ function layoutClass(layout) {
4229
4237
  return Object.prototype.hasOwnProperty.call(LAYOUT_CLASSES, layout) ? LAYOUT_CLASSES[layout] : LAYOUT_CLASSES.goal;
4230
4238
  }
4231
4239
  function GreetingDashboard({ dashboard, onTap, oddsLabel }) {
4232
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: `ss-w-dash ${layoutClass(dashboard.layout)}`, children: [
4240
+ const layout = layoutClass(dashboard.layout);
4241
+ const badgePlacement = layout === LAYOUT_CLASSES.goal ? "end" : "meta";
4242
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: `ss-w-dash ${layout}`, children: [
4233
4243
  /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "ss-w-dash-head", children: [
4234
4244
  /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "ss-w-dash-title", children: dashboard.title }),
4235
4245
  dashboard.subtitle ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "ss-w-dash-subtitle", children: dashboard.subtitle }) : null
4236
4246
  ] }),
4237
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "ss-w-dash-grid", children: dashboard.tiles.map((t, i) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(DashboardTile, { tile: t, onTap: () => onTap(t, i), oddsLabel }, `${t.title}-${i}`)) }),
4247
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "ss-w-dash-grid", children: dashboard.tiles.map((t, i) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(DashboardTile, { tile: t, onTap: () => onTap(t, i), oddsLabel, badgePlacement }, `${t.title}-${i}`)) }),
4238
4248
  dashboard.footerTip ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "ss-w-dash-foot", children: dashboard.footerTip }) : null
4239
4249
  ] });
4240
4250
  }
@@ -8753,7 +8763,21 @@ function ComboPreview({ cell, formatKickoff }) {
8753
8763
  function Unavailable({ text }) {
8754
8764
  return /* @__PURE__ */ (0, import_jsx_runtime90.jsx)("p", { className: "ss-w-tool-unavailable", children: text });
8755
8765
  }
8756
- function SetNumbersTool({ grid, strings, streaming, formatKickoff, onSend, onClose }) {
8766
+ function AskRow({ icon, ask, ready, send }) {
8767
+ return /* @__PURE__ */ (0, import_jsx_runtime90.jsxs)("section", { className: "ss-w-tool-row ss-w-tool-row--ask", children: [
8768
+ /* @__PURE__ */ (0, import_jsx_runtime90.jsx)("span", { className: "ss-w-tool-icon", "aria-hidden": "true", children: icon }),
8769
+ /* @__PURE__ */ (0, import_jsx_runtime90.jsxs)("div", { className: "ss-w-tool-main", children: [
8770
+ /* @__PURE__ */ (0, import_jsx_runtime90.jsx)("p", { className: "ss-w-tool-ask", children: ask }),
8771
+ ready ? /* @__PURE__ */ (0, import_jsx_runtime90.jsx)("span", { className: "ss-w-tool-ready", children: ready }) : null
8772
+ ] }),
8773
+ send
8774
+ ] });
8775
+ }
8776
+ function RoundSend({ label, display, disabled, onClick }) {
8777
+ return /* @__PURE__ */ (0, import_jsx_runtime90.jsx)("button", { type: "button", className: "ss-w-tool-go", "aria-label": `${label}: ${display}`, disabled, onClick, children: /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(SendIcon, {}) });
8778
+ }
8779
+ var BIG_COMBO = { total: 50, legs: 6 };
8780
+ function SetNumbersTool({ grid, strings, streaming, onSend, onClose }) {
8757
8781
  const limits = singlesLimits(grid);
8758
8782
  const floors = singlesFloors(grid);
8759
8783
  const totals = comboTotals(grid);
@@ -8764,10 +8788,14 @@ function SetNumbersTool({ grid, strings, streaming, formatKickoff, onSend, onClo
8764
8788
  const [start] = (0, import_react51.useState)(() => startCombo(grid, totals, legChoices, START.comboTotal, START.comboLegs));
8765
8789
  const [total, setTotal] = (0, import_react51.useState)(start.total);
8766
8790
  const [legs, setLegs] = (0, import_react51.useState)(start.legs);
8791
+ const [bigStart] = (0, import_react51.useState)(() => startCombo(grid, totals, legChoices, BIG_COMBO.total, BIG_COMBO.legs));
8792
+ const [bigTotal, setBigTotal] = (0, import_react51.useState)(bigStart.total);
8793
+ const [bigLegs, setBigLegs] = (0, import_react51.useState)(bigStart.legs);
8767
8794
  const [announcement, setAnnouncement] = (0, import_react51.useState)("");
8768
8795
  const maxCell = findSingles(grid.singles, maxPrice, count);
8769
8796
  const minCell = findSingles(grid.singlesFrom, minPrice, count);
8770
8797
  const comboCell = findCombo(grid, total, legs);
8798
+ const bigCell = findCombo(grid, bigTotal, bigLegs);
8771
8799
  const announce = (display, available) => setAnnouncement(available ? display : `${display}. ${strings.unavailable}`);
8772
8800
  const chooseMax = (v) => {
8773
8801
  setMaxPrice(v);
@@ -8787,41 +8815,79 @@ function SetNumbersTool({ grid, strings, streaming, formatKickoff, onSend, onClo
8787
8815
  setLegs(l);
8788
8816
  announce(strings.comboDisplay(l, v), !!findCombo(grid, v, l));
8789
8817
  };
8818
+ const chooseBigLegs = (v) => {
8819
+ setBigLegs(v);
8820
+ announce(strings.comboDisplay(v, bigTotal), !!findCombo(grid, bigTotal, v));
8821
+ };
8822
+ const chooseBigTotal = (v) => {
8823
+ const l = legsForTotal(grid, v, bigLegs);
8824
+ setBigTotal(v);
8825
+ setBigLegs(l);
8826
+ announce(strings.comboDisplay(l, v), !!findCombo(grid, v, l));
8827
+ };
8790
8828
  const maxChoices = limits.map((v) => ({ value: v, text: v.toFixed(2), available: !!findSingles(grid.singles, v, count) }));
8791
8829
  const minChoices = floors.map((v) => ({ value: v, text: v.toFixed(2), available: !!findSingles(grid.singlesFrom, v, count) }));
8792
8830
  const totalChoices = totals.map((v) => ({ value: v, text: v.toFixed(1), available: legChoices.some((n) => !!findCombo(grid, v, n)) }));
8793
- const legChoicesList = legChoices.map((n) => ({ value: n, text: String(n), available: !!findCombo(grid, total, n) }));
8831
+ const legChoicesFor = (t) => legChoices.map((n) => ({ value: n, text: String(n), available: !!findCombo(grid, t, n) }));
8832
+ const singlesReady = (cell) => cell ? strings.readyCount(cell.picks.length) : strings.unavailable;
8833
+ const comboReady = (cell) => cell ? strings.readyAt(cell.combo.total) : strings.unavailable;
8794
8834
  return /* @__PURE__ */ (0, import_jsx_runtime90.jsxs)(PresetToolModal, { title: strings.setNumbers, closeLabel: strings.close, onClose, children: [
8795
- /* @__PURE__ */ (0, import_jsx_runtime90.jsxs)("section", { className: "ss-w-tool-row", children: [
8796
- /* @__PURE__ */ (0, import_jsx_runtime90.jsx)("p", { className: "ss-w-tool-ask", children: fillTemplate(strings.maxPriceRow, {
8797
- count: String(count),
8798
- price: /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(NumberSelect, { current: maxPrice.toFixed(2), choices: maxChoices, label: strings.maxPriceName, notToday: strings.notToday, onChoose: chooseMax })
8799
- }) }),
8800
- maxCell ? /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(PickList, { picks: maxCell.picks, formatKickoff }) : /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(Unavailable, { text: strings.unavailable }),
8801
- /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(SendButton, { label: strings.send, display: strings.maxPriceDisplay(count, maxPrice), disabled: !maxCell || streaming, onClick: () => {
8802
- if (maxCell) onSend(maxPriceAsk(maxCell, strings));
8803
- } })
8804
- ] }),
8805
- /* @__PURE__ */ (0, import_jsx_runtime90.jsxs)("section", { className: "ss-w-tool-row", children: [
8806
- /* @__PURE__ */ (0, import_jsx_runtime90.jsx)("p", { className: "ss-w-tool-ask", children: fillTemplate(strings.minPriceRow, {
8807
- count: String(count),
8808
- price: /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(NumberSelect, { current: minPrice.toFixed(2), choices: minChoices, label: strings.minPriceName, notToday: strings.notToday, onChoose: chooseMin })
8809
- }) }),
8810
- minCell ? /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(PickList, { picks: minCell.picks, formatKickoff }) : /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(Unavailable, { text: strings.unavailable }),
8811
- /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(SendButton, { label: strings.send, display: strings.minPriceDisplay(count, minPrice), disabled: !minCell || streaming, onClick: () => {
8812
- if (minCell) onSend(minPriceAsk(minCell, strings));
8813
- } })
8814
- ] }),
8815
- /* @__PURE__ */ (0, import_jsx_runtime90.jsxs)("section", { className: "ss-w-tool-row", children: [
8816
- /* @__PURE__ */ (0, import_jsx_runtime90.jsx)("p", { className: "ss-w-tool-ask", children: fillTemplate(strings.comboRow, {
8817
- legs: /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(NumberSelect, { current: String(legs), choices: legChoicesList, label: strings.matchesLabel, notToday: strings.notToday, lockEmpty: false, onChoose: chooseLegs }),
8818
- total: /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(NumberSelect, { current: total.toFixed(1), choices: totalChoices, label: strings.totalLabel, notToday: strings.notToday, onChoose: chooseTotal })
8819
- }) }),
8820
- comboCell ? /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(ComboPreview, { cell: comboCell, formatKickoff }) : /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(Unavailable, { text: strings.unavailable }),
8821
- /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(SendButton, { label: strings.send, display: strings.comboDisplay(legs, total), disabled: !comboCell || streaming, onClick: () => {
8822
- if (comboCell) onSend(comboAsk(comboCell, strings));
8823
- } })
8824
- ] }),
8835
+ /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(
8836
+ AskRow,
8837
+ {
8838
+ icon: "\u{1F3AF}",
8839
+ ask: fillTemplate(strings.maxPriceRow, {
8840
+ count: String(count),
8841
+ price: /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(NumberSelect, { current: maxPrice.toFixed(2), choices: maxChoices, label: strings.maxPriceName, notToday: strings.notToday, onChoose: chooseMax })
8842
+ }),
8843
+ ready: singlesReady(maxCell),
8844
+ send: /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(RoundSend, { label: strings.send, display: strings.maxPriceDisplay(count, maxPrice), disabled: !maxCell || streaming, onClick: () => {
8845
+ if (maxCell) onSend(maxPriceAsk(maxCell, strings));
8846
+ } })
8847
+ }
8848
+ ),
8849
+ /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(
8850
+ AskRow,
8851
+ {
8852
+ icon: "\u{1F4C8}",
8853
+ ask: fillTemplate(strings.minPriceRow, {
8854
+ count: String(count),
8855
+ price: /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(NumberSelect, { current: minPrice.toFixed(2), choices: minChoices, label: strings.minPriceName, notToday: strings.notToday, onChoose: chooseMin })
8856
+ }),
8857
+ ready: singlesReady(minCell),
8858
+ send: /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(RoundSend, { label: strings.send, display: strings.minPriceDisplay(count, minPrice), disabled: !minCell || streaming, onClick: () => {
8859
+ if (minCell) onSend(minPriceAsk(minCell, strings));
8860
+ } })
8861
+ }
8862
+ ),
8863
+ /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(
8864
+ AskRow,
8865
+ {
8866
+ icon: "\u2728",
8867
+ ask: fillTemplate(strings.comboRow, {
8868
+ legs: /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(NumberSelect, { current: String(legs), choices: legChoicesFor(total), label: strings.matchesLabel, notToday: strings.notToday, lockEmpty: false, onChoose: chooseLegs }),
8869
+ total: /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(NumberSelect, { current: total.toFixed(1), choices: totalChoices, label: strings.totalLabel, notToday: strings.notToday, onChoose: chooseTotal })
8870
+ }),
8871
+ ready: comboReady(comboCell),
8872
+ send: /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(RoundSend, { label: strings.send, display: strings.comboDisplay(legs, total), disabled: !comboCell || streaming, onClick: () => {
8873
+ if (comboCell) onSend(comboAsk(comboCell, strings));
8874
+ } })
8875
+ }
8876
+ ),
8877
+ /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(
8878
+ AskRow,
8879
+ {
8880
+ icon: "\u{1F3C6}",
8881
+ ask: fillTemplate(strings.bigComboRow, {
8882
+ legs: /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(NumberSelect, { current: String(bigLegs), choices: legChoicesFor(bigTotal), label: strings.matchesLabel, notToday: strings.notToday, lockEmpty: false, onChoose: chooseBigLegs }),
8883
+ total: /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(NumberSelect, { current: bigTotal.toFixed(1), choices: totalChoices, label: strings.totalLabel, notToday: strings.notToday, onChoose: chooseBigTotal })
8884
+ }),
8885
+ ready: comboReady(bigCell),
8886
+ send: /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(RoundSend, { label: strings.send, display: strings.comboDisplay(bigLegs, bigTotal), disabled: !bigCell || streaming, onClick: () => {
8887
+ if (bigCell) onSend(comboAsk(bigCell, strings));
8888
+ } })
8889
+ }
8890
+ ),
8825
8891
  /* @__PURE__ */ (0, import_jsx_runtime90.jsx)("p", { className: "ss-w-vh", "aria-live": "polite", children: announcement })
8826
8892
  ] });
8827
8893
  }
@@ -9096,7 +9162,7 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
9096
9162
  buttonRef: dialButtonRef
9097
9163
  }
9098
9164
  ) : null,
9099
- tool && presetGrid && onChatTab ? tool.kind === "numbers" ? /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(SetNumbersTool, { grid: presetGrid, strings: ui.presets, streaming: state.isStreaming, formatKickoff, onSend: sendAsk, onClose: closeTool }) : /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(BuildComboTool, { grid: presetGrid, strings: ui.presets, streaming: state.isStreaming, formatKickoff, initialTotal: tool.total, initialLegs: tool.legs, onSend: sendAsk, onClose: closeTool }) : null
9165
+ tool && presetGrid && onChatTab ? tool.kind === "numbers" ? /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(SetNumbersTool, { grid: presetGrid, strings: ui.presets, streaming: state.isStreaming, onSend: sendAsk, onClose: closeTool }) : /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(BuildComboTool, { grid: presetGrid, strings: ui.presets, streaming: state.isStreaming, formatKickoff, initialTotal: tool.total, initialLegs: tool.legs, onSend: sendAsk, onClose: closeTool }) : null
9100
9166
  ] }),
9101
9167
  monitor && discovery && monitor.activeTab === "today" && /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(TodayPanel, { discovery, ui, monitor }),
9102
9168
  monitor && monitor.activeTab === "following" && /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(MatchesPanel, { monitor, ui, slip, onAsk: handleAsk }),
@@ -9602,6 +9668,13 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
9602
9668
  .ss-w-tool-pick-price { grid-column: 2; grid-row: 1 / span 3; align-self: center; font-family: ui-monospace, monospace; font-variant-numeric: tabular-nums; font-size: 14px; font-weight: 800; color: var(--ss-w-accent); }
9603
9669
  .ss-w-tool-math { padding: 6px 8px; font-family: ui-monospace, monospace; font-variant-numeric: tabular-nums; font-size: 13px; font-weight: 700; text-align: right; color: var(--ss-w-ink); background: color-mix(in srgb, var(--ss-w-accent) 9%, var(--ss-w-panel)); border-radius: 8px; overflow-wrap: anywhere; }
9604
9670
  .ss-w-tool-unavailable { padding: 6px 8px; font-size: 12px; color: var(--ss-w-faint); border: 1px dashed var(--ss-w-line); border-radius: 8px; }
9671
+ .ss-w-tool-row--ask { flex-direction: row; align-items: center; gap: 10px; border-left-width: 1px; }
9672
+ .ss-w-tool-icon { flex: none; font-size: 20px; line-height: 1; }
9673
+ .ss-w-tool-main { flex: 1; min-width: 0; display: flex; flex-direction: column; align-items: flex-start; gap: 4px; }
9674
+ .ss-w-tool-ready { padding: 2px 8px; font-size: 11.5px; font-weight: 650; color: var(--ss-w-accent); background: color-mix(in srgb, var(--ss-w-accent) 12%, transparent); border-radius: 10px; }
9675
+ .ss-w-tool-go { flex: none; width: 44px; height: 44px; display: grid; place-items: center; font-size: 17px; color: #fff; background: var(--ss-w-accent); border: none; border-radius: 50%; cursor: pointer; }
9676
+ .ss-w-tool-go:disabled { color: var(--ss-w-faint); background: var(--ss-w-bubble); cursor: not-allowed; }
9677
+ .ss-w-tool-go:focus-visible { outline: 2px solid var(--ss-w-accent); outline-offset: 2px; }
9605
9678
  .ss-w-tool-send { align-self: flex-end; min-height: 40px; padding: 8px 18px; font: inherit; font-size: 13px; font-weight: 700; color: #fff; background: var(--ss-w-accent); border: none; border-radius: 20px; cursor: pointer; }
9606
9679
  .ss-w-tool-send:disabled { color: var(--ss-w-faint); background: var(--ss-w-bubble); cursor: not-allowed; }
9607
9680
  .ss-w-tool-foot .ss-w-tool-send { width: 100%; }
@@ -9804,9 +9877,21 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
9804
9877
  part of that visual language rather than a plain unstyled button. */
9805
9878
  .ss-w-dash--market .ss-w-dash-tile { border-left: 3px solid var(--ss-w-accent); }
9806
9879
 
9807
- /* Goal: one column of pill rows. */
9880
+ /* Goal: one column of compact cards, 60px tall with the badge as a price column on the right.
9881
+ The value ink is accent mixed toward ink (as on the hero price): plain light accent on the
9882
+ panel is 3.9:1, under the 4.5:1 small text needs. */
9808
9883
  .ss-w-dash--goal .ss-w-dash-grid { grid-template-columns: 1fr; }
9809
- .ss-w-dash--goal .ss-w-dash-tile { border-radius: 999px; padding: 10px 14px; }
9884
+ .ss-w-dash--goal .ss-w-dash-tile { gap: 12px; min-height: 60px; padding: 8px 12px 8px 14px; border-radius: 8px; }
9885
+ .ss-w-dash--goal .ss-w-dash-tile:hover { background: var(--ss-w-bubble); }
9886
+ .ss-w-dash--goal .ss-w-dash-tile-icon { width: 24px; height: 24px; font-size: 20px; }
9887
+ .ss-w-dash--goal .ss-w-dash-tile-body { gap: 1px; }
9888
+ .ss-w-dash--goal .ss-w-dash-tile-title { font-size: 15px; line-height: 1.25; }
9889
+ .ss-w-dash--goal .ss-w-dash-tile-subtitle { font-size: 13px; line-height: 1.3; overflow-wrap: break-word; }
9890
+ .ss-w-dash-tile-value {
9891
+ flex: none; margin-left: auto; max-width: 40%; text-align: right;
9892
+ font-size: 16px; font-weight: 700; line-height: 1.2; font-variant-numeric: tabular-nums;
9893
+ color: color-mix(in srgb, var(--ss-w-accent) 70%, var(--ss-w-ink));
9894
+ }
9810
9895
 
9811
9896
  /* Discovery: tinted bento cards. Stacked (icon over text) so a two- or three-word title gets
9812
9897
  the tile's full width instead of the ~100px left of a horizontal icon+chevron -- that narrow