@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/dist/index.js CHANGED
@@ -129,7 +129,10 @@ var STRINGS = {
129
129
  dialName: "Set the numbers and Build a combo",
130
130
  maxPriceRow: "{count} picks, max {price}",
131
131
  minPriceRow: "Picks from {price} up",
132
- comboRow: "A combo of {legs} matches priced at about {total}",
132
+ comboRow: "Combo of {legs} paying {total}",
133
+ bigComboRow: "Total {total} with {legs} matches",
134
+ readyCount: (n) => `${n} ready`,
135
+ readyAt: (total) => `ready at ${total.toFixed(2)}`,
133
136
  maxPriceDisplay: (count, price) => `${count} picks, max ${price.toFixed(2)}`,
134
137
  maxPriceMessage: (count, price) => `Show me ${count} picks priced at ${price.toFixed(2)} or less.`,
135
138
  minPriceDisplay: (count, price) => `${count} picks from ${price.toFixed(2)} up`,
@@ -461,6 +464,9 @@ var STRINGS = {
461
464
  maxPriceRow: "{count} se\xE7im, en fazla {price}",
462
465
  minPriceRow: "{price} ve \xFCzeri se\xE7imler",
463
466
  comboRow: "Yakla\u015F\u0131k {total} oranl\u0131 {legs} ma\xE7l\u0131k kombin",
467
+ bigComboRow: "{legs} ma\xE7la toplam {total}",
468
+ readyCount: (n) => `${n} haz\u0131r`,
469
+ readyAt: (total) => `${total.toFixed(2)} ile haz\u0131r`,
464
470
  maxPriceDisplay: (count, price) => `${count} se\xE7im, en fazla ${price.toFixed(2)}`,
465
471
  maxPriceMessage: (count, price) => `${price.toFixed(2)} veya alt\u0131 oranl\u0131 ${count} se\xE7im g\xF6ster.`,
466
472
  minPriceDisplay: (count, price) => `${count} se\xE7im, ${price.toFixed(2)} ve \xFCzeri`,
@@ -4156,11 +4162,13 @@ function HeroTile({ tile, onTap, oddsLabel }) {
4156
4162
  ] })
4157
4163
  ] });
4158
4164
  }
4159
- function DashboardTile({ tile, onTap, oddsLabel = "Odds" }) {
4165
+ function DashboardTile({ tile, onTap, oddsLabel = "Odds", badgePlacement = "meta" }) {
4160
4166
  if (tile.emphasis === "hero") return /* @__PURE__ */ jsx20(HeroTile, { tile, onTap, oddsLabel });
4161
4167
  const spanClass = tile.span === "full" ? "ss-w-dash-tile--full" : "ss-w-dash-tile--half";
4162
4168
  const crests = (tile.imageUrls ?? []).slice(0, MAX_CRESTS);
4163
- const hasMeta = Boolean(tile.badgeText) || crests.length > 0;
4169
+ const endBadge = badgePlacement === "end" && tile.badgeText ? tile.badgeText : null;
4170
+ const metaBadge = endBadge ? null : tile.badgeText;
4171
+ const hasMeta = Boolean(metaBadge) || crests.length > 0;
4164
4172
  return /* @__PURE__ */ jsxs16("button", { type: "button", className: `ss-w-dash-tile ${spanClass}`, onClick: onTap, children: [
4165
4173
  /* @__PURE__ */ jsx20("span", { className: "ss-w-dash-tile-icon", children: /* @__PURE__ */ jsx20(DashboardIcon, { name: tile.icon }) }),
4166
4174
  /* @__PURE__ */ jsxs16("span", { className: "ss-w-dash-tile-body", children: [
@@ -4171,12 +4179,12 @@ function DashboardTile({ tile, onTap, oddsLabel = "Odds" }) {
4171
4179
  // icon/chevron row -- at the half-span tile's ~180px width a nowrap badge alone
4172
4180
  // (~70px) left the title column at ~22px and forced character-by-character wrapping.
4173
4181
  /* @__PURE__ */ jsxs16("span", { className: "ss-w-dash-tile-meta", children: [
4174
- tile.badgeText ? /* @__PURE__ */ jsx20("span", { className: "ss-w-dash-tile-badge", children: tile.badgeText }) : null,
4182
+ metaBadge ? /* @__PURE__ */ jsx20("span", { className: "ss-w-dash-tile-badge", children: metaBadge }) : null,
4175
4183
  crests.length > 0 ? /* @__PURE__ */ jsx20("span", { className: "ss-w-dash-tile-crests", children: crests.map((url, i) => /* @__PURE__ */ jsx20("span", { className: "ss-w-dash-tile-crest", style: { backgroundImage: `url(${url})` }, "aria-hidden": "true" }, `${url}-${i}`)) }) : null
4176
4184
  ] })
4177
4185
  ) : null
4178
4186
  ] }),
4179
- /* @__PURE__ */ jsx20("span", { className: "ss-w-dash-tile-chevron", children: /* @__PURE__ */ jsx20(ChevronIcon, {}) })
4187
+ endBadge ? /* @__PURE__ */ jsx20("span", { className: "ss-w-dash-tile-value", children: endBadge }) : /* @__PURE__ */ jsx20("span", { className: "ss-w-dash-tile-chevron", children: /* @__PURE__ */ jsx20(ChevronIcon, {}) })
4180
4188
  ] });
4181
4189
  }
4182
4190
 
@@ -4191,12 +4199,14 @@ function layoutClass(layout) {
4191
4199
  return Object.prototype.hasOwnProperty.call(LAYOUT_CLASSES, layout) ? LAYOUT_CLASSES[layout] : LAYOUT_CLASSES.goal;
4192
4200
  }
4193
4201
  function GreetingDashboard({ dashboard, onTap, oddsLabel }) {
4194
- return /* @__PURE__ */ jsxs17("div", { className: `ss-w-dash ${layoutClass(dashboard.layout)}`, children: [
4202
+ const layout = layoutClass(dashboard.layout);
4203
+ const badgePlacement = layout === LAYOUT_CLASSES.goal ? "end" : "meta";
4204
+ return /* @__PURE__ */ jsxs17("div", { className: `ss-w-dash ${layout}`, children: [
4195
4205
  /* @__PURE__ */ jsxs17("div", { className: "ss-w-dash-head", children: [
4196
4206
  /* @__PURE__ */ jsx21("span", { className: "ss-w-dash-title", children: dashboard.title }),
4197
4207
  dashboard.subtitle ? /* @__PURE__ */ jsx21("span", { className: "ss-w-dash-subtitle", children: dashboard.subtitle }) : null
4198
4208
  ] }),
4199
- /* @__PURE__ */ jsx21("div", { className: "ss-w-dash-grid", children: dashboard.tiles.map((t, i) => /* @__PURE__ */ jsx21(DashboardTile, { tile: t, onTap: () => onTap(t, i), oddsLabel }, `${t.title}-${i}`)) }),
4209
+ /* @__PURE__ */ jsx21("div", { className: "ss-w-dash-grid", children: dashboard.tiles.map((t, i) => /* @__PURE__ */ jsx21(DashboardTile, { tile: t, onTap: () => onTap(t, i), oddsLabel, badgePlacement }, `${t.title}-${i}`)) }),
4200
4210
  dashboard.footerTip ? /* @__PURE__ */ jsx21("span", { className: "ss-w-dash-foot", children: dashboard.footerTip }) : null
4201
4211
  ] });
4202
4212
  }
@@ -8715,7 +8725,21 @@ function ComboPreview({ cell, formatKickoff }) {
8715
8725
  function Unavailable({ text }) {
8716
8726
  return /* @__PURE__ */ jsx90("p", { className: "ss-w-tool-unavailable", children: text });
8717
8727
  }
8718
- function SetNumbersTool({ grid, strings, streaming, formatKickoff, onSend, onClose }) {
8728
+ function AskRow({ icon, ask, ready, send }) {
8729
+ return /* @__PURE__ */ jsxs75("section", { className: "ss-w-tool-row ss-w-tool-row--ask", children: [
8730
+ /* @__PURE__ */ jsx90("span", { className: "ss-w-tool-icon", "aria-hidden": "true", children: icon }),
8731
+ /* @__PURE__ */ jsxs75("div", { className: "ss-w-tool-main", children: [
8732
+ /* @__PURE__ */ jsx90("p", { className: "ss-w-tool-ask", children: ask }),
8733
+ ready ? /* @__PURE__ */ jsx90("span", { className: "ss-w-tool-ready", children: ready }) : null
8734
+ ] }),
8735
+ send
8736
+ ] });
8737
+ }
8738
+ function RoundSend({ label, display, disabled, onClick }) {
8739
+ return /* @__PURE__ */ jsx90("button", { type: "button", className: "ss-w-tool-go", "aria-label": `${label}: ${display}`, disabled, onClick, children: /* @__PURE__ */ jsx90(SendIcon, {}) });
8740
+ }
8741
+ var BIG_COMBO = { total: 50, legs: 6 };
8742
+ function SetNumbersTool({ grid, strings, streaming, onSend, onClose }) {
8719
8743
  const limits = singlesLimits(grid);
8720
8744
  const floors = singlesFloors(grid);
8721
8745
  const totals = comboTotals(grid);
@@ -8726,10 +8750,14 @@ function SetNumbersTool({ grid, strings, streaming, formatKickoff, onSend, onClo
8726
8750
  const [start] = useState41(() => startCombo(grid, totals, legChoices, START.comboTotal, START.comboLegs));
8727
8751
  const [total, setTotal] = useState41(start.total);
8728
8752
  const [legs, setLegs] = useState41(start.legs);
8753
+ const [bigStart] = useState41(() => startCombo(grid, totals, legChoices, BIG_COMBO.total, BIG_COMBO.legs));
8754
+ const [bigTotal, setBigTotal] = useState41(bigStart.total);
8755
+ const [bigLegs, setBigLegs] = useState41(bigStart.legs);
8729
8756
  const [announcement, setAnnouncement] = useState41("");
8730
8757
  const maxCell = findSingles(grid.singles, maxPrice, count);
8731
8758
  const minCell = findSingles(grid.singlesFrom, minPrice, count);
8732
8759
  const comboCell = findCombo(grid, total, legs);
8760
+ const bigCell = findCombo(grid, bigTotal, bigLegs);
8733
8761
  const announce = (display, available) => setAnnouncement(available ? display : `${display}. ${strings.unavailable}`);
8734
8762
  const chooseMax = (v) => {
8735
8763
  setMaxPrice(v);
@@ -8749,41 +8777,79 @@ function SetNumbersTool({ grid, strings, streaming, formatKickoff, onSend, onClo
8749
8777
  setLegs(l);
8750
8778
  announce(strings.comboDisplay(l, v), !!findCombo(grid, v, l));
8751
8779
  };
8780
+ const chooseBigLegs = (v) => {
8781
+ setBigLegs(v);
8782
+ announce(strings.comboDisplay(v, bigTotal), !!findCombo(grid, bigTotal, v));
8783
+ };
8784
+ const chooseBigTotal = (v) => {
8785
+ const l = legsForTotal(grid, v, bigLegs);
8786
+ setBigTotal(v);
8787
+ setBigLegs(l);
8788
+ announce(strings.comboDisplay(l, v), !!findCombo(grid, v, l));
8789
+ };
8752
8790
  const maxChoices = limits.map((v) => ({ value: v, text: v.toFixed(2), available: !!findSingles(grid.singles, v, count) }));
8753
8791
  const minChoices = floors.map((v) => ({ value: v, text: v.toFixed(2), available: !!findSingles(grid.singlesFrom, v, count) }));
8754
8792
  const totalChoices = totals.map((v) => ({ value: v, text: v.toFixed(1), available: legChoices.some((n) => !!findCombo(grid, v, n)) }));
8755
- const legChoicesList = legChoices.map((n) => ({ value: n, text: String(n), available: !!findCombo(grid, total, n) }));
8793
+ const legChoicesFor = (t) => legChoices.map((n) => ({ value: n, text: String(n), available: !!findCombo(grid, t, n) }));
8794
+ const singlesReady = (cell) => cell ? strings.readyCount(cell.picks.length) : strings.unavailable;
8795
+ const comboReady = (cell) => cell ? strings.readyAt(cell.combo.total) : strings.unavailable;
8756
8796
  return /* @__PURE__ */ jsxs75(PresetToolModal, { title: strings.setNumbers, closeLabel: strings.close, onClose, children: [
8757
- /* @__PURE__ */ jsxs75("section", { className: "ss-w-tool-row", children: [
8758
- /* @__PURE__ */ jsx90("p", { className: "ss-w-tool-ask", children: fillTemplate(strings.maxPriceRow, {
8759
- count: String(count),
8760
- price: /* @__PURE__ */ jsx90(NumberSelect, { current: maxPrice.toFixed(2), choices: maxChoices, label: strings.maxPriceName, notToday: strings.notToday, onChoose: chooseMax })
8761
- }) }),
8762
- maxCell ? /* @__PURE__ */ jsx90(PickList, { picks: maxCell.picks, formatKickoff }) : /* @__PURE__ */ jsx90(Unavailable, { text: strings.unavailable }),
8763
- /* @__PURE__ */ jsx90(SendButton, { label: strings.send, display: strings.maxPriceDisplay(count, maxPrice), disabled: !maxCell || streaming, onClick: () => {
8764
- if (maxCell) onSend(maxPriceAsk(maxCell, strings));
8765
- } })
8766
- ] }),
8767
- /* @__PURE__ */ jsxs75("section", { className: "ss-w-tool-row", children: [
8768
- /* @__PURE__ */ jsx90("p", { className: "ss-w-tool-ask", children: fillTemplate(strings.minPriceRow, {
8769
- count: String(count),
8770
- price: /* @__PURE__ */ jsx90(NumberSelect, { current: minPrice.toFixed(2), choices: minChoices, label: strings.minPriceName, notToday: strings.notToday, onChoose: chooseMin })
8771
- }) }),
8772
- minCell ? /* @__PURE__ */ jsx90(PickList, { picks: minCell.picks, formatKickoff }) : /* @__PURE__ */ jsx90(Unavailable, { text: strings.unavailable }),
8773
- /* @__PURE__ */ jsx90(SendButton, { label: strings.send, display: strings.minPriceDisplay(count, minPrice), disabled: !minCell || streaming, onClick: () => {
8774
- if (minCell) onSend(minPriceAsk(minCell, strings));
8775
- } })
8776
- ] }),
8777
- /* @__PURE__ */ jsxs75("section", { className: "ss-w-tool-row", children: [
8778
- /* @__PURE__ */ jsx90("p", { className: "ss-w-tool-ask", children: fillTemplate(strings.comboRow, {
8779
- legs: /* @__PURE__ */ jsx90(NumberSelect, { current: String(legs), choices: legChoicesList, label: strings.matchesLabel, notToday: strings.notToday, lockEmpty: false, onChoose: chooseLegs }),
8780
- total: /* @__PURE__ */ jsx90(NumberSelect, { current: total.toFixed(1), choices: totalChoices, label: strings.totalLabel, notToday: strings.notToday, onChoose: chooseTotal })
8781
- }) }),
8782
- comboCell ? /* @__PURE__ */ jsx90(ComboPreview, { cell: comboCell, formatKickoff }) : /* @__PURE__ */ jsx90(Unavailable, { text: strings.unavailable }),
8783
- /* @__PURE__ */ jsx90(SendButton, { label: strings.send, display: strings.comboDisplay(legs, total), disabled: !comboCell || streaming, onClick: () => {
8784
- if (comboCell) onSend(comboAsk(comboCell, strings));
8785
- } })
8786
- ] }),
8797
+ /* @__PURE__ */ jsx90(
8798
+ AskRow,
8799
+ {
8800
+ icon: "\u{1F3AF}",
8801
+ ask: fillTemplate(strings.maxPriceRow, {
8802
+ count: String(count),
8803
+ price: /* @__PURE__ */ jsx90(NumberSelect, { current: maxPrice.toFixed(2), choices: maxChoices, label: strings.maxPriceName, notToday: strings.notToday, onChoose: chooseMax })
8804
+ }),
8805
+ ready: singlesReady(maxCell),
8806
+ send: /* @__PURE__ */ jsx90(RoundSend, { label: strings.send, display: strings.maxPriceDisplay(count, maxPrice), disabled: !maxCell || streaming, onClick: () => {
8807
+ if (maxCell) onSend(maxPriceAsk(maxCell, strings));
8808
+ } })
8809
+ }
8810
+ ),
8811
+ /* @__PURE__ */ jsx90(
8812
+ AskRow,
8813
+ {
8814
+ icon: "\u{1F4C8}",
8815
+ ask: fillTemplate(strings.minPriceRow, {
8816
+ count: String(count),
8817
+ price: /* @__PURE__ */ jsx90(NumberSelect, { current: minPrice.toFixed(2), choices: minChoices, label: strings.minPriceName, notToday: strings.notToday, onChoose: chooseMin })
8818
+ }),
8819
+ ready: singlesReady(minCell),
8820
+ send: /* @__PURE__ */ jsx90(RoundSend, { label: strings.send, display: strings.minPriceDisplay(count, minPrice), disabled: !minCell || streaming, onClick: () => {
8821
+ if (minCell) onSend(minPriceAsk(minCell, strings));
8822
+ } })
8823
+ }
8824
+ ),
8825
+ /* @__PURE__ */ jsx90(
8826
+ AskRow,
8827
+ {
8828
+ icon: "\u2728",
8829
+ ask: fillTemplate(strings.comboRow, {
8830
+ legs: /* @__PURE__ */ jsx90(NumberSelect, { current: String(legs), choices: legChoicesFor(total), label: strings.matchesLabel, notToday: strings.notToday, lockEmpty: false, onChoose: chooseLegs }),
8831
+ total: /* @__PURE__ */ jsx90(NumberSelect, { current: total.toFixed(1), choices: totalChoices, label: strings.totalLabel, notToday: strings.notToday, onChoose: chooseTotal })
8832
+ }),
8833
+ ready: comboReady(comboCell),
8834
+ send: /* @__PURE__ */ jsx90(RoundSend, { label: strings.send, display: strings.comboDisplay(legs, total), disabled: !comboCell || streaming, onClick: () => {
8835
+ if (comboCell) onSend(comboAsk(comboCell, strings));
8836
+ } })
8837
+ }
8838
+ ),
8839
+ /* @__PURE__ */ jsx90(
8840
+ AskRow,
8841
+ {
8842
+ icon: "\u{1F3C6}",
8843
+ ask: fillTemplate(strings.bigComboRow, {
8844
+ legs: /* @__PURE__ */ jsx90(NumberSelect, { current: String(bigLegs), choices: legChoicesFor(bigTotal), label: strings.matchesLabel, notToday: strings.notToday, lockEmpty: false, onChoose: chooseBigLegs }),
8845
+ total: /* @__PURE__ */ jsx90(NumberSelect, { current: bigTotal.toFixed(1), choices: totalChoices, label: strings.totalLabel, notToday: strings.notToday, onChoose: chooseBigTotal })
8846
+ }),
8847
+ ready: comboReady(bigCell),
8848
+ send: /* @__PURE__ */ jsx90(RoundSend, { label: strings.send, display: strings.comboDisplay(bigLegs, bigTotal), disabled: !bigCell || streaming, onClick: () => {
8849
+ if (bigCell) onSend(comboAsk(bigCell, strings));
8850
+ } })
8851
+ }
8852
+ ),
8787
8853
  /* @__PURE__ */ jsx90("p", { className: "ss-w-vh", "aria-live": "polite", children: announcement })
8788
8854
  ] });
8789
8855
  }
@@ -9058,7 +9124,7 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
9058
9124
  buttonRef: dialButtonRef
9059
9125
  }
9060
9126
  ) : null,
9061
- tool && presetGrid && onChatTab ? tool.kind === "numbers" ? /* @__PURE__ */ jsx91(SetNumbersTool, { grid: presetGrid, strings: ui.presets, streaming: state.isStreaming, formatKickoff, onSend: sendAsk, onClose: closeTool }) : /* @__PURE__ */ jsx91(BuildComboTool, { grid: presetGrid, strings: ui.presets, streaming: state.isStreaming, formatKickoff, initialTotal: tool.total, initialLegs: tool.legs, onSend: sendAsk, onClose: closeTool }) : null
9127
+ tool && presetGrid && onChatTab ? tool.kind === "numbers" ? /* @__PURE__ */ jsx91(SetNumbersTool, { grid: presetGrid, strings: ui.presets, streaming: state.isStreaming, onSend: sendAsk, onClose: closeTool }) : /* @__PURE__ */ jsx91(BuildComboTool, { grid: presetGrid, strings: ui.presets, streaming: state.isStreaming, formatKickoff, initialTotal: tool.total, initialLegs: tool.legs, onSend: sendAsk, onClose: closeTool }) : null
9062
9128
  ] }),
9063
9129
  monitor && discovery && monitor.activeTab === "today" && /* @__PURE__ */ jsx91(TodayPanel, { discovery, ui, monitor }),
9064
9130
  monitor && monitor.activeTab === "following" && /* @__PURE__ */ jsx91(MatchesPanel, { monitor, ui, slip, onAsk: handleAsk }),
@@ -9564,6 +9630,13 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
9564
9630
  .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); }
9565
9631
  .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; }
9566
9632
  .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; }
9633
+ .ss-w-tool-row--ask { flex-direction: row; align-items: center; gap: 10px; border-left-width: 1px; }
9634
+ .ss-w-tool-icon { flex: none; font-size: 20px; line-height: 1; }
9635
+ .ss-w-tool-main { flex: 1; min-width: 0; display: flex; flex-direction: column; align-items: flex-start; gap: 4px; }
9636
+ .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; }
9637
+ .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; }
9638
+ .ss-w-tool-go:disabled { color: var(--ss-w-faint); background: var(--ss-w-bubble); cursor: not-allowed; }
9639
+ .ss-w-tool-go:focus-visible { outline: 2px solid var(--ss-w-accent); outline-offset: 2px; }
9567
9640
  .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; }
9568
9641
  .ss-w-tool-send:disabled { color: var(--ss-w-faint); background: var(--ss-w-bubble); cursor: not-allowed; }
9569
9642
  .ss-w-tool-foot .ss-w-tool-send { width: 100%; }
@@ -9766,9 +9839,21 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
9766
9839
  part of that visual language rather than a plain unstyled button. */
9767
9840
  .ss-w-dash--market .ss-w-dash-tile { border-left: 3px solid var(--ss-w-accent); }
9768
9841
 
9769
- /* Goal: one column of pill rows. */
9842
+ /* Goal: one column of compact cards, 60px tall with the badge as a price column on the right.
9843
+ The value ink is accent mixed toward ink (as on the hero price): plain light accent on the
9844
+ panel is 3.9:1, under the 4.5:1 small text needs. */
9770
9845
  .ss-w-dash--goal .ss-w-dash-grid { grid-template-columns: 1fr; }
9771
- .ss-w-dash--goal .ss-w-dash-tile { border-radius: 999px; padding: 10px 14px; }
9846
+ .ss-w-dash--goal .ss-w-dash-tile { gap: 12px; min-height: 60px; padding: 8px 12px 8px 14px; border-radius: 8px; }
9847
+ .ss-w-dash--goal .ss-w-dash-tile:hover { background: var(--ss-w-bubble); }
9848
+ .ss-w-dash--goal .ss-w-dash-tile-icon { width: 24px; height: 24px; font-size: 20px; }
9849
+ .ss-w-dash--goal .ss-w-dash-tile-body { gap: 1px; }
9850
+ .ss-w-dash--goal .ss-w-dash-tile-title { font-size: 15px; line-height: 1.25; }
9851
+ .ss-w-dash--goal .ss-w-dash-tile-subtitle { font-size: 13px; line-height: 1.3; overflow-wrap: break-word; }
9852
+ .ss-w-dash-tile-value {
9853
+ flex: none; margin-left: auto; max-width: 40%; text-align: right;
9854
+ font-size: 16px; font-weight: 700; line-height: 1.2; font-variant-numeric: tabular-nums;
9855
+ color: color-mix(in srgb, var(--ss-w-accent) 70%, var(--ss-w-ink));
9856
+ }
9772
9857
 
9773
9858
  /* Discovery: tinted bento cards. Stacked (icon over text) so a two- or three-word title gets
9774
9859
  the tile's full width instead of the ~100px left of a horizontal icon+chevron -- that narrow