@sensiblestats/widget-react 0.15.0 → 0.17.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 +22 -0
- package/dist/index.cjs +128 -34
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +133 -39
- package/dist/index.js.map +1 -1
- package/dist/styles.css +36 -10
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
import { useEffect as useEffect6, useMemo as useMemo2, useRef as useRef3 } from "react";
|
|
3
3
|
import { StatsWidgetClient } from "@sensiblestats/widget-sdk";
|
|
4
4
|
|
|
5
|
+
// src/kickoff.ts
|
|
6
|
+
function formatBettingKickoff(kickoffUtc, ui, locale, now = /* @__PURE__ */ new Date()) {
|
|
7
|
+
const at = new Date(kickoffUtc);
|
|
8
|
+
const intlLocale = locale === "tr" ? "tr-TR" : "en-GB";
|
|
9
|
+
const time = new Intl.DateTimeFormat(intlLocale, { hour: "2-digit", minute: "2-digit" }).format(at);
|
|
10
|
+
const atLocalDate = new Date(at.getFullYear(), at.getMonth(), at.getDate());
|
|
11
|
+
const nowLocalDate = new Date(now.getFullYear(), now.getMonth(), now.getDate());
|
|
12
|
+
const dayDiff = Math.round((atLocalDate.getTime() - nowLocalDate.getTime()) / 864e5);
|
|
13
|
+
const dayLabel = dayDiff === 0 ? ui.today : dayDiff === 1 ? ui.tomorrow : new Intl.DateTimeFormat(intlLocale, { weekday: "short", day: "numeric", month: "short" }).format(at);
|
|
14
|
+
return { dayLabel, time };
|
|
15
|
+
}
|
|
16
|
+
|
|
5
17
|
// src/i18n.ts
|
|
6
18
|
var STRINGS = {
|
|
7
19
|
en: {
|
|
@@ -20,6 +32,7 @@ var STRINGS = {
|
|
|
20
32
|
hideStats: "Hide stats",
|
|
21
33
|
oddsLabel: "Odds",
|
|
22
34
|
liveLabel: "Live",
|
|
35
|
+
marketFloorLabel: "Market price \xB7 not a value pick",
|
|
23
36
|
addToSlip: "Add to slip",
|
|
24
37
|
marketPrices: "Market prices",
|
|
25
38
|
moreLines: "More lines",
|
|
@@ -55,7 +68,10 @@ var STRINGS = {
|
|
|
55
68
|
slipPriceNotAccepted: (from, to) => `Price moved to ${to} (was ${from}). Tap to add.`,
|
|
56
69
|
slipLoginRequired: "Sign in to add to your slip",
|
|
57
70
|
slipSuspended: "Market suspended",
|
|
58
|
-
slipFailed: "Couldn't add to slip. Try again."
|
|
71
|
+
slipFailed: "Couldn't add to slip. Try again.",
|
|
72
|
+
today: "Today",
|
|
73
|
+
tomorrow: "Tomorrow",
|
|
74
|
+
bettingKickoff: (kickoffUtc, now) => formatBettingKickoff(kickoffUtc, STRINGS.en, "en", now)
|
|
59
75
|
},
|
|
60
76
|
tr: {
|
|
61
77
|
launcherLabel: "SensibleStats ile sohbet et",
|
|
@@ -73,6 +89,7 @@ var STRINGS = {
|
|
|
73
89
|
hideStats: "\u0130statistikleri gizle",
|
|
74
90
|
oddsLabel: "Oran",
|
|
75
91
|
liveLabel: "Canl\u0131",
|
|
92
|
+
marketFloorLabel: "Piyasa oran\u0131 \xB7 de\u011Fer bahsi de\u011Fil",
|
|
76
93
|
addToSlip: "Kupona ekle",
|
|
77
94
|
marketPrices: "Piyasa fiyatlar\u0131",
|
|
78
95
|
moreLines: "Di\u011Fer \xE7izgiler",
|
|
@@ -108,7 +125,10 @@ var STRINGS = {
|
|
|
108
125
|
slipPriceNotAccepted: (from, to) => `Oran ${to} oldu (\xF6nceki ${from}). Eklemek i\xE7in dokunun.`,
|
|
109
126
|
slipLoginRequired: "Kupona eklemek i\xE7in giri\u015F yap\u0131n",
|
|
110
127
|
slipSuspended: "Bu market ask\u0131ya al\u0131nd\u0131",
|
|
111
|
-
slipFailed: "Kupona eklenemedi. Tekrar deneyin."
|
|
128
|
+
slipFailed: "Kupona eklenemedi. Tekrar deneyin.",
|
|
129
|
+
today: "Bug\xFCn",
|
|
130
|
+
tomorrow: "Yar\u0131n",
|
|
131
|
+
bettingKickoff: (kickoffUtc, now) => formatBettingKickoff(kickoffUtc, STRINGS.tr, "tr", now)
|
|
112
132
|
}
|
|
113
133
|
};
|
|
114
134
|
function resolveLocaleStrings(locale) {
|
|
@@ -143,6 +163,7 @@ function normalizeUi(cfg) {
|
|
|
143
163
|
hideStats: strings.hideStats,
|
|
144
164
|
oddsLabel: strings.oddsLabel,
|
|
145
165
|
liveLabel: strings.liveLabel,
|
|
166
|
+
marketFloorLabel: strings.marketFloorLabel,
|
|
146
167
|
marketPrices: strings.marketPrices,
|
|
147
168
|
moreLines: strings.moreLines,
|
|
148
169
|
hideLines: strings.hideLines,
|
|
@@ -174,7 +195,10 @@ function normalizeUi(cfg) {
|
|
|
174
195
|
slipPriceNotAccepted: strings.slipPriceNotAccepted,
|
|
175
196
|
slipLoginRequired: strings.slipLoginRequired,
|
|
176
197
|
slipSuspended: strings.slipSuspended,
|
|
177
|
-
slipFailed: strings.slipFailed
|
|
198
|
+
slipFailed: strings.slipFailed,
|
|
199
|
+
today: strings.today,
|
|
200
|
+
tomorrow: strings.tomorrow,
|
|
201
|
+
bettingKickoff: strings.bettingKickoff
|
|
178
202
|
};
|
|
179
203
|
}
|
|
180
204
|
function toClientOptions(cfg) {
|
|
@@ -359,10 +383,17 @@ function toInsightVM(insight) {
|
|
|
359
383
|
matchId: typeof insight.matchId === "number" ? insight.matchId : 0,
|
|
360
384
|
matchOddsId,
|
|
361
385
|
addToSlipEnabled: insight.addToSlipEnabled === true,
|
|
386
|
+
isMarketFloor: insight.isMarketFloor === true,
|
|
362
387
|
oddsDecimal: typeof oddsValue === "number" && Number.isFinite(oddsValue) ? oddsValue : void 0,
|
|
363
388
|
quotedAtUtc: str(insight.odds?.quotedAtUtc),
|
|
364
389
|
previousOdds: previous !== void 0 && direction !== void 0 ? previous.toFixed(2) : void 0,
|
|
365
|
-
movementDirection: previous !== void 0 && direction !== void 0 ? direction : void 0
|
|
390
|
+
movementDirection: previous !== void 0 && direction !== void 0 ? direction : void 0,
|
|
391
|
+
homeTeamName: home,
|
|
392
|
+
awayTeamName: away,
|
|
393
|
+
homeCrest: str(insight.homeTeamImagePath),
|
|
394
|
+
awayCrest: str(insight.awayTeamImagePath),
|
|
395
|
+
competitionCrest: str(insight.competitionImagePath),
|
|
396
|
+
kickoffUtc: str(insight.kickoffUtc)
|
|
366
397
|
};
|
|
367
398
|
}
|
|
368
399
|
function toSlipSelection(vm, conversationId) {
|
|
@@ -937,7 +968,7 @@ function OddsMovementBadge({
|
|
|
937
968
|
}
|
|
938
969
|
|
|
939
970
|
// src/components/BettingInsightList.tsx
|
|
940
|
-
import { jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
971
|
+
import { Fragment, jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
941
972
|
function StatRows2({ stats }) {
|
|
942
973
|
return /* @__PURE__ */ jsx10("div", { className: "ss-w-bi-rows", children: stats.map((s) => /* @__PURE__ */ jsxs7("div", { className: "ss-w-bi-row", children: [
|
|
943
974
|
/* @__PURE__ */ jsx10("span", { className: "ss-w-bi-row-lbl", children: s.label }),
|
|
@@ -952,10 +983,21 @@ function ScopedStats({ scopes }) {
|
|
|
952
983
|
/* @__PURE__ */ jsx10(StatRows2, { stats: current.stats }, current.key)
|
|
953
984
|
] });
|
|
954
985
|
}
|
|
986
|
+
function hasStatsContent(it) {
|
|
987
|
+
return !!it.scopes && it.scopes.length >= 2 || it.stats.length > 0;
|
|
988
|
+
}
|
|
989
|
+
function initials2(name) {
|
|
990
|
+
return (name ?? "").trim().slice(0, 1).toUpperCase() || "?";
|
|
991
|
+
}
|
|
992
|
+
function Crest2({ url, name, kind }) {
|
|
993
|
+
const cls = kind === "comp" ? "ss-w-bi-comp-logo" : "ss-w-bi-crest";
|
|
994
|
+
if (url) return /* @__PURE__ */ jsx10("span", { className: cls, style: { backgroundImage: `url(${url})` }, "aria-hidden": "true" });
|
|
995
|
+
return /* @__PURE__ */ jsx10("span", { className: `${cls} ss-w-bi-crest-mono`, "aria-hidden": "true", children: initials2(name) });
|
|
996
|
+
}
|
|
955
997
|
function StatsDisclosure({ it, ui }) {
|
|
956
998
|
const [open, setOpen] = useState3(false);
|
|
957
999
|
const hasScopes = !!it.scopes && it.scopes.length >= 2;
|
|
958
|
-
const hasStats =
|
|
1000
|
+
const hasStats = hasStatsContent(it);
|
|
959
1001
|
if (!hasStats) return null;
|
|
960
1002
|
return /* @__PURE__ */ jsxs7("div", { className: "ss-w-bi-stats", children: [
|
|
961
1003
|
/* @__PURE__ */ jsxs7(
|
|
@@ -976,21 +1018,42 @@ function StatsDisclosure({ it, ui }) {
|
|
|
976
1018
|
}
|
|
977
1019
|
function InsightCard({ it, ui, slip }) {
|
|
978
1020
|
const live = it.isLive || it.phase === "live";
|
|
1021
|
+
const kickoff = it.kickoffUtc && ui?.bettingKickoff ? ui.bettingKickoff(it.kickoffUtc) : void 0;
|
|
1022
|
+
const hasNamedTeams = !!it.homeTeamName && !!it.awayTeamName;
|
|
1023
|
+
const showHeader = !!it.competition || live || !!kickoff;
|
|
1024
|
+
const showReason = !!it.text || hasStatsContent(it);
|
|
979
1025
|
return /* @__PURE__ */ jsxs7("div", { className: "ss-w-binsight", children: [
|
|
980
|
-
|
|
981
|
-
/* @__PURE__ */ jsx10("span", { className: "ss-w-bi-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
/* @__PURE__ */ jsxs7("span", { className: "ss-w-bi-
|
|
986
|
-
/* @__PURE__ */
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
1026
|
+
showHeader ? /* @__PURE__ */ jsxs7("div", { className: "ss-w-bi-header", children: [
|
|
1027
|
+
/* @__PURE__ */ jsx10("span", { className: "ss-w-bi-header-left", children: it.competition ? /* @__PURE__ */ jsxs7(Fragment, { children: [
|
|
1028
|
+
/* @__PURE__ */ jsx10(Crest2, { kind: "comp", url: it.competitionCrest, name: it.competition }),
|
|
1029
|
+
/* @__PURE__ */ jsx10("span", { className: "ss-w-bi-comp", children: it.competition })
|
|
1030
|
+
] }) : null }),
|
|
1031
|
+
/* @__PURE__ */ jsxs7("span", { className: "ss-w-bi-header-right", children: [
|
|
1032
|
+
live ? /* @__PURE__ */ jsxs7("span", { className: "ss-w-bi-live", children: [
|
|
1033
|
+
/* @__PURE__ */ jsx10("span", { className: "ss-w-bi-live-dot", "aria-hidden": "true" }),
|
|
1034
|
+
ui?.liveLabel ?? "Live"
|
|
1035
|
+
] }) : null,
|
|
1036
|
+
kickoff ? /* @__PURE__ */ jsxs7("span", { className: "ss-w-bi-kick", children: [
|
|
1037
|
+
kickoff.dayLabel,
|
|
1038
|
+
" ",
|
|
1039
|
+
kickoff.time
|
|
991
1040
|
] }) : null
|
|
992
|
-
] })
|
|
1041
|
+
] })
|
|
1042
|
+
] }) : null,
|
|
1043
|
+
/* @__PURE__ */ jsxs7("div", { className: "ss-w-bi-body", children: [
|
|
1044
|
+
/* @__PURE__ */ jsx10("div", { className: "ss-w-bi-fixture", children: hasNamedTeams ? /* @__PURE__ */ jsxs7(Fragment, { children: [
|
|
1045
|
+
/* @__PURE__ */ jsx10(Crest2, { kind: "team", url: it.homeCrest, name: it.homeTeamName }),
|
|
1046
|
+
/* @__PURE__ */ jsx10("span", { className: "ss-w-bi-team", children: it.homeTeamName }),
|
|
1047
|
+
/* @__PURE__ */ jsx10("span", { className: "ss-w-bi-vs", "aria-hidden": "true", children: "vs" }),
|
|
1048
|
+
/* @__PURE__ */ jsx10("span", { className: "ss-w-bi-team", children: it.awayTeamName }),
|
|
1049
|
+
/* @__PURE__ */ jsx10(Crest2, { kind: "team", url: it.awayCrest, name: it.awayTeamName })
|
|
1050
|
+
] }) : it.fixture ? /* @__PURE__ */ jsx10("span", { className: "ss-w-bi-fixture-txt", children: it.fixture }) : null }),
|
|
993
1051
|
/* @__PURE__ */ jsxs7("div", { className: "ss-w-bi-action", children: [
|
|
1052
|
+
/* @__PURE__ */ jsxs7("span", { className: "ss-w-bi-mkt", children: [
|
|
1053
|
+
/* @__PURE__ */ jsx10("span", { className: "ss-w-bi-market", children: it.market }),
|
|
1054
|
+
it.selection ? /* @__PURE__ */ jsx10("span", { className: "ss-w-bi-sel", children: it.selection }) : null
|
|
1055
|
+
] }),
|
|
1056
|
+
it.isMarketFloor ? /* @__PURE__ */ jsx10("span", { className: "ss-w-bi-floor", children: ui?.marketFloorLabel ?? "Market price \xB7 not a value pick" }) : null,
|
|
994
1057
|
it.odds ? /* @__PURE__ */ jsxs7("span", { className: "ss-w-bi-odds", children: [
|
|
995
1058
|
/* @__PURE__ */ jsx10("span", { className: "ss-w-bi-odds-cap", children: ui?.oddsLabel ?? "Odds" }),
|
|
996
1059
|
/* @__PURE__ */ jsx10("b", { children: it.odds }),
|
|
@@ -1000,8 +1063,13 @@ function InsightCard({ it, ui, slip }) {
|
|
|
1000
1063
|
/* @__PURE__ */ jsx10(AddToSlipButton, { it, slip, ui })
|
|
1001
1064
|
] })
|
|
1002
1065
|
] }),
|
|
1003
|
-
|
|
1004
|
-
|
|
1066
|
+
showReason ? /* @__PURE__ */ jsxs7("div", { className: "ss-w-bi-reason", children: [
|
|
1067
|
+
/* @__PURE__ */ jsx10("span", { className: "ss-w-bi-chart", "aria-hidden": "true" }),
|
|
1068
|
+
/* @__PURE__ */ jsxs7("div", { className: "ss-w-bi-reason-body", children: [
|
|
1069
|
+
it.text ? /* @__PURE__ */ jsx10("p", { className: "ss-w-bi-text", children: it.text }) : null,
|
|
1070
|
+
/* @__PURE__ */ jsx10(StatsDisclosure, { it, ui })
|
|
1071
|
+
] })
|
|
1072
|
+
] }) : null,
|
|
1005
1073
|
it.disclaimer ? /* @__PURE__ */ jsx10("p", { className: "ss-w-bi-disc", children: it.disclaimer }) : null
|
|
1006
1074
|
] });
|
|
1007
1075
|
}
|
|
@@ -1051,7 +1119,7 @@ function MarketOddsCardList({ cards, ui, slip }) {
|
|
|
1051
1119
|
}
|
|
1052
1120
|
|
|
1053
1121
|
// src/components/OddsMovementCard.tsx
|
|
1054
|
-
import { Fragment, jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1122
|
+
import { Fragment as Fragment2, jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1055
1123
|
function directionWord(vm, ui) {
|
|
1056
1124
|
if (vm.direction === "shortened") return ui?.oddsShortened ?? "shortened";
|
|
1057
1125
|
if (vm.direction === "drifted") return ui?.oddsDrifted ?? "drifted";
|
|
@@ -1087,7 +1155,7 @@ function OddsMovementCard({ vm, ui }) {
|
|
|
1087
1155
|
] }, g.price)),
|
|
1088
1156
|
/* @__PURE__ */ jsx12("path", { className: "ss-w-om-line", d: vm.geometry.path, fill: "none" }),
|
|
1089
1157
|
vm.geometry.markers.map((m, i) => /* @__PURE__ */ jsx12("circle", { className: "ss-w-om-dot", cx: m.x, cy: m.y, r: 2.5 }, i)),
|
|
1090
|
-
ui?.chartTimeLabel ? /* @__PURE__ */ jsxs9(
|
|
1158
|
+
ui?.chartTimeLabel ? /* @__PURE__ */ jsxs9(Fragment2, { children: [
|
|
1091
1159
|
/* @__PURE__ */ jsx12("text", { className: "ss-w-om-xlab", x: 40, y: CHART_VIEW_H - 8, textAnchor: "start", children: ui.chartTimeLabel(vm.geometry.startMs) }),
|
|
1092
1160
|
/* @__PURE__ */ jsx12("text", { className: "ss-w-om-xlab", x: CHART_VIEW_W - 8, y: CHART_VIEW_H - 8, textAnchor: "end", children: ui.chartTimeLabel(vm.geometry.endMs) })
|
|
1093
1161
|
] }) : /* @__PURE__ */ jsx12("text", { className: "ss-w-om-xlab", x: 40, y: CHART_VIEW_H - 8, children: ui?.movementWindow ? ui.movementWindow(vm.windowHours) : `Last ${vm.windowHours}h` })
|
|
@@ -1118,12 +1186,12 @@ function OddsMovementCardList({ cards, ui }) {
|
|
|
1118
1186
|
}
|
|
1119
1187
|
|
|
1120
1188
|
// src/components/ActionButtons.tsx
|
|
1121
|
-
import { Fragment as
|
|
1189
|
+
import { Fragment as Fragment3, jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1122
1190
|
function ActionButtons({ actions, loading, disabled, onAct }) {
|
|
1123
1191
|
if (actions.length === 0 && !loading) return null;
|
|
1124
1192
|
return /* @__PURE__ */ jsxs10("div", { className: "ss-w-actions", children: [
|
|
1125
1193
|
actions.map((a, i) => /* @__PURE__ */ jsx13("button", { type: "button", className: "ss-w-abtn", disabled, onClick: () => onAct(a), children: a.label }, `${a.label}-${i}`)),
|
|
1126
|
-
actions.length === 0 && loading ? /* @__PURE__ */ jsxs10(
|
|
1194
|
+
actions.length === 0 && loading ? /* @__PURE__ */ jsxs10(Fragment3, { children: [
|
|
1127
1195
|
/* @__PURE__ */ jsx13("span", { className: "ss-w-abtn-shimmer" }),
|
|
1128
1196
|
/* @__PURE__ */ jsx13("span", { className: "ss-w-abtn-shimmer" })
|
|
1129
1197
|
] }) : null
|
|
@@ -1189,13 +1257,13 @@ function GreetingHeaderBlock({ block }) {
|
|
|
1189
1257
|
// src/components/club-dashboard/FixtureHeroBlock.tsx
|
|
1190
1258
|
import { useState as useState5 } from "react";
|
|
1191
1259
|
import { jsx as jsx17, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1192
|
-
function
|
|
1260
|
+
function initials3(name) {
|
|
1193
1261
|
return name.split(/\s+/).filter(Boolean).slice(0, 2).map((w) => w[0].toUpperCase()).join("");
|
|
1194
1262
|
}
|
|
1195
|
-
function
|
|
1263
|
+
function Crest3({ url, name }) {
|
|
1196
1264
|
const [broken, setBroken] = useState5(false);
|
|
1197
1265
|
if (!url || broken) {
|
|
1198
|
-
return /* @__PURE__ */ jsx17("span", { className: "ss-w-cdash-crest ss-w-cdash-crest--fallback", "aria-hidden": "true", children:
|
|
1266
|
+
return /* @__PURE__ */ jsx17("span", { className: "ss-w-cdash-crest ss-w-cdash-crest--fallback", "aria-hidden": "true", children: initials3(name) });
|
|
1199
1267
|
}
|
|
1200
1268
|
return /* @__PURE__ */ jsx17("img", { className: "ss-w-cdash-crest", src: url, alt: "", "aria-hidden": "true", onError: () => setBroken(true) });
|
|
1201
1269
|
}
|
|
@@ -1206,11 +1274,11 @@ function FixtureHeroBlock({
|
|
|
1206
1274
|
}) {
|
|
1207
1275
|
return /* @__PURE__ */ jsxs14("div", { className: "ss-w-cdash-fixture", children: [
|
|
1208
1276
|
/* @__PURE__ */ jsxs14("div", { className: "ss-w-cdash-tie", children: [
|
|
1209
|
-
/* @__PURE__ */ jsx17(
|
|
1277
|
+
/* @__PURE__ */ jsx17(Crest3, { url: block.homeCrestUrl, name: block.homeName }),
|
|
1210
1278
|
/* @__PURE__ */ jsx17("span", { className: "ss-w-cdash-team", children: block.homeName }),
|
|
1211
1279
|
/* @__PURE__ */ jsx17("span", { className: "ss-w-cdash-vs", children: "v" }),
|
|
1212
1280
|
/* @__PURE__ */ jsx17("span", { className: "ss-w-cdash-team", children: block.awayName }),
|
|
1213
|
-
/* @__PURE__ */ jsx17(
|
|
1281
|
+
/* @__PURE__ */ jsx17(Crest3, { url: block.awayCrestUrl, name: block.awayName })
|
|
1214
1282
|
] }),
|
|
1215
1283
|
/* @__PURE__ */ jsxs14("div", { className: "ss-w-cdash-fixture-meta", children: [
|
|
1216
1284
|
/* @__PURE__ */ jsx17("span", { className: "ss-w-cdash-kickoff", children: ui.clubKickoff(block.kickoffUnix * 1e3) }),
|
|
@@ -1604,25 +1672,51 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
1604
1672
|
|
|
1605
1673
|
/* betting insights */
|
|
1606
1674
|
.ss-w-binsights { display: flex; flex-direction: column; gap: 7px; }
|
|
1607
|
-
.ss-w-binsight { background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); border-radius: 12px; border-left: 3px solid var(--ss-w-accent); padding: 9px 11px; display: flex; flex-direction: column; gap:
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
.ss-w-bi-
|
|
1675
|
+
.ss-w-binsight { background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); border-radius: 12px; border-left: 3px solid var(--ss-w-accent); padding: 9px 11px; display: flex; flex-direction: column; gap: 8px; }
|
|
1676
|
+
|
|
1677
|
+
/* row 1: competition logo + name on the left, live badge + kickoff on the right */
|
|
1678
|
+
.ss-w-bi-header { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-width: 0; padding-bottom: 7px; border-bottom: 1px solid var(--ss-w-line); }
|
|
1679
|
+
.ss-w-bi-header-left { display: inline-flex; align-items: center; gap: 6px; min-width: 0; }
|
|
1680
|
+
.ss-w-bi-header-right { display: inline-flex; align-items: center; gap: 8px; flex: none; }
|
|
1681
|
+
.ss-w-bi-comp { font-size: 10.5px; color: var(--ss-w-faint); font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
1682
|
+
.ss-w-bi-kick { font-size: 10.5px; font-weight: 600; color: var(--ss-w-faint); white-space: nowrap; flex: none; }
|
|
1611
1683
|
.ss-w-bi-live { font-size: 8.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: #fff; background: #c0392b; border-radius: 4px; padding: 1px 5px; display: inline-flex; align-items: center; gap: 4px; flex: none; }
|
|
1612
1684
|
.ss-w-bi-live-dot { width: 5px; height: 5px; border-radius: 50%; background: #fff; }
|
|
1613
|
-
.ss-w-bi-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
.ss-w-bi-
|
|
1617
|
-
.ss-w-bi-
|
|
1618
|
-
.ss-w-bi-
|
|
1685
|
+
.ss-w-bi-floor { font-size: 8.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--ss-w-faint); background: var(--ss-w-bubble); border: 1px solid var(--ss-w-line); border-radius: 4px; padding: 1px 5px; display: inline-flex; align-items: center; align-self: flex-start; flex: none; }
|
|
1686
|
+
|
|
1687
|
+
/* crests -- CSS background-image on a span, never <img> (matches .ss-w-ecard-crest precedent) */
|
|
1688
|
+
.ss-w-bi-comp-logo { width: 15px; height: 15px; flex: none; display: block; border-radius: 50%; background-size: contain; background-repeat: no-repeat; background-position: center; }
|
|
1689
|
+
.ss-w-bi-crest { width: 22px; height: 22px; flex: none; display: block; border-radius: 50%; background-size: contain; background-repeat: no-repeat; background-position: center; background-color: var(--ss-w-bubble); border: 1px solid var(--ss-w-line); }
|
|
1690
|
+
.ss-w-bi-crest-mono { display: grid; place-items: center; font-size: 9px; font-weight: 700; color: var(--ss-w-accent); background: color-mix(in srgb, var(--ss-w-accent) 16%, var(--ss-w-panel)); }
|
|
1691
|
+
|
|
1692
|
+
/* row 2: crest-flanked fixture on the left, boxed action panel on the right */
|
|
1693
|
+
.ss-w-bi-body { display: flex; align-items: center; gap: 10px; }
|
|
1694
|
+
.ss-w-bi-fixture { display: flex; align-items: center; gap: 6px; min-width: 0; flex: 1; font-size: 12px; font-weight: 650; color: var(--ss-w-ink); }
|
|
1695
|
+
.ss-w-bi-team { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
1696
|
+
.ss-w-bi-vs { font-size: 10px; font-weight: 600; color: var(--ss-w-faint); flex: none; }
|
|
1697
|
+
.ss-w-bi-fixture-txt { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
1698
|
+
.ss-w-bi-action { margin-left: auto; flex: none; display: flex; flex-direction: column; align-items: stretch; gap: 6px; background: var(--ss-w-bubble); border: 1px solid var(--ss-w-line); border-radius: 12px; padding: 8px 10px; }
|
|
1619
1699
|
.ss-w-bi-action .ss-w-slip > button { flex: 1; text-align: center; }
|
|
1620
1700
|
/* The action column is narrow; let its toast size to its own text and anchor to the card's right edge instead of being clipped to the button width. */
|
|
1621
1701
|
.ss-w-bi-action .ss-w-toast { left: auto; right: 0; width: max-content; max-width: 210px; white-space: normal; }
|
|
1702
|
+
.ss-w-bi-mkt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
|
|
1703
|
+
.ss-w-bi-market { font-size: 13.5px; font-weight: 700; line-height: 1.25; color: var(--ss-w-ink); }
|
|
1704
|
+
.ss-w-bi-sel { font-size: 11.5px; line-height: 1.3; color: var(--ss-w-faint); }
|
|
1622
1705
|
.ss-w-bi-odds { flex: none; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; gap: 1px; background: color-mix(in srgb, var(--ss-w-accent) 12%, var(--ss-w-panel)); border: 1px solid color-mix(in srgb, var(--ss-w-accent) 30%, var(--ss-w-line)); border-radius: 10px; padding: 4px 11px; min-width: 62px; }
|
|
1623
1706
|
.ss-w-bi-odds-cap { font-size: 9px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase; color: var(--ss-w-faint); }
|
|
1624
1707
|
.ss-w-bi-odds b { font-size: 19px; font-family: ui-monospace, monospace; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--ss-w-accent); line-height: 1.1; }
|
|
1625
1708
|
.ss-w-bi-book { font-size: 9.5px; color: var(--ss-w-faint); }
|
|
1709
|
+
|
|
1710
|
+
/* row 3: bar-chart glyph + reasoning prose + stats-expander chevron, in a subtle strip */
|
|
1711
|
+
.ss-w-bi-reason { display: flex; align-items: flex-start; gap: 8px; background: var(--ss-w-bubble); border-radius: 10px; padding: 8px 10px; }
|
|
1712
|
+
.ss-w-bi-chart { flex: none; width: 13px; height: 12px; margin-top: 2px; opacity: .55;
|
|
1713
|
+
background:
|
|
1714
|
+
linear-gradient(var(--ss-w-accent), var(--ss-w-accent)) left / 3px 55% no-repeat,
|
|
1715
|
+
linear-gradient(var(--ss-w-accent), var(--ss-w-accent)) center / 3px 100% no-repeat,
|
|
1716
|
+
linear-gradient(var(--ss-w-accent), var(--ss-w-accent)) right / 3px 75% no-repeat;
|
|
1717
|
+
background-position: left bottom, center bottom, right bottom;
|
|
1718
|
+
}
|
|
1719
|
+
.ss-w-bi-reason-body { display: flex; flex-direction: column; gap: 8px; min-width: 0; flex: 1; }
|
|
1626
1720
|
.ss-w-bi-text { font-size: 12px; line-height: 1.45; color: var(--ss-w-ink); }
|
|
1627
1721
|
.ss-w-bi-stats { display: flex; flex-direction: column; gap: 8px; }
|
|
1628
1722
|
.ss-w-bi-toggle { align-self: flex-start; display: inline-flex; align-items: center; gap: 5px; background: none; border: none; color: var(--ss-w-accent); font: inherit; font-size: 11.5px; font-weight: 600; padding: 2px 0; cursor: pointer; }
|