@sensiblestats/widget-react 0.53.0 → 0.55.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/dist/index.js CHANGED
@@ -4152,6 +4152,24 @@ function useGamePlay(conversation, { gameId, gameDay, fixtureId, refresh }) {
4152
4152
  convRef.current = conversation;
4153
4153
  const optsRef = useRef11({ gameId, gameDay, fixtureId, refresh });
4154
4154
  optsRef.current = { gameId, gameDay, fixtureId, refresh };
4155
+ const resultRef = useRef11(null);
4156
+ resultRef.current = result;
4157
+ const refetch = useCallback8(async () => {
4158
+ const conv = convRef.current;
4159
+ if (!conv) return;
4160
+ const opts = optsRef.current;
4161
+ try {
4162
+ const payload = await conv.getGameResult(opts.gameId, opts.fixtureId, opts.gameDay);
4163
+ if (payload === null) return;
4164
+ if (payload.clientStateJson == null && resultRef.current?.clientStateJson != null) {
4165
+ setRawStatus(payload.status);
4166
+ return;
4167
+ }
4168
+ setResult(toSubmitResult(payload));
4169
+ setRawStatus(payload.status);
4170
+ } catch {
4171
+ }
4172
+ }, []);
4155
4173
  const submit = useCallback8(async (answerJson) => {
4156
4174
  const conv = convRef.current;
4157
4175
  if (!conv || inFlightRef.current) return;
@@ -4161,7 +4179,14 @@ function useGamePlay(conversation, { gameId, gameDay, fixtureId, refresh }) {
4161
4179
  const opts = optsRef.current;
4162
4180
  const playResult = await conv.postPlay(opts.gameId, answerJson, opts.gameDay, opts.fixtureId);
4163
4181
  if (playResult !== null) {
4164
- setResult(playResult);
4182
+ const hasFreshState = playResult.clientStateJson != null;
4183
+ const isTerminal2 = playResult.alreadyPlayed === true;
4184
+ const holdsState = resultRef.current?.clientStateJson != null;
4185
+ if (!hasFreshState && !isTerminal2 && holdsState) {
4186
+ await refetch();
4187
+ } else {
4188
+ setResult(playResult);
4189
+ }
4165
4190
  if (playResult.pointsDelta != null) {
4166
4191
  opts.refresh?.();
4167
4192
  }
@@ -4171,22 +4196,10 @@ function useGamePlay(conversation, { gameId, gameDay, fixtureId, refresh }) {
4171
4196
  inFlightRef.current = false;
4172
4197
  setSubmitting(false);
4173
4198
  }
4174
- }, []);
4199
+ }, [refetch]);
4175
4200
  const hydrate = useCallback8(() => {
4176
- const conv = convRef.current;
4177
- if (!conv) return;
4178
- const opts = optsRef.current;
4179
- void (async () => {
4180
- try {
4181
- const payload = await conv.getGameResult(opts.gameId, opts.fixtureId, opts.gameDay);
4182
- if (payload !== null) {
4183
- setResult(toSubmitResult(payload));
4184
- setRawStatus(payload.status);
4185
- }
4186
- } catch {
4187
- }
4188
- })();
4189
- }, []);
4201
+ void refetch();
4202
+ }, [refetch]);
4190
4203
  return { result, submitting, submit, hydrate, rawStatus };
4191
4204
  }
4192
4205
 
@@ -4288,7 +4301,7 @@ var ATTR_LABELS = {
4288
4301
  position: "Pos",
4289
4302
  nationality: "Nat",
4290
4303
  age: "Age",
4291
- shirtNumber: "Kit",
4304
+ shirtNumber: "Shirt",
4292
4305
  apps: "Apps"
4293
4306
  };
4294
4307
  var ATTR_KEYS = [
@@ -4349,6 +4362,7 @@ function MysteryTigerGame({
4349
4362
  " left"
4350
4363
  ] })
4351
4364
  ] }),
4365
+ guessResults.length === 0 && !isOver && /* @__PURE__ */ jsx55("div", { className: "ss-w-gt-lead", children: "Guess any squad player \u2014 each guess reveals how close you are on position, nationality, age, shirt and apps." }),
4352
4366
  guessResults.length > 0 && /* @__PURE__ */ jsx55("div", { className: "ss-w-gtrows", children: guessResults.map((gr, i) => {
4353
4367
  const player = config.squadPlayers.find((p) => p.id === gr.playerId);
4354
4368
  return /* @__PURE__ */ jsxs49("div", { className: "ss-w-gtguess", children: [
@@ -4433,6 +4447,7 @@ function MysteryTigerGame({
4433
4447
 
4434
4448
  // src/components/games/HigherOrLowerGame.tsx
4435
4449
  import { Fragment as Fragment10, jsx as jsx56, jsxs as jsxs50 } from "react/jsx-runtime";
4450
+ var POINTS_PER_CORRECT = 10;
4436
4451
  function parseClientState2(json) {
4437
4452
  if (!json) return null;
4438
4453
  try {
@@ -4524,39 +4539,25 @@ function HigherOrLowerGame({
4524
4539
  ] })
4525
4540
  ] })
4526
4541
  ] }),
4542
+ !isOver && /* @__PURE__ */ jsxs50("div", { className: "ss-w-hl-foot", children: [
4543
+ /* @__PURE__ */ jsxs50("span", { className: "ss-w-hl-chip", children: [
4544
+ score,
4545
+ " pts"
4546
+ ] }),
4547
+ /* @__PURE__ */ jsxs50("span", { className: "ss-w-hl-chip ss-w-hl-chip--green", children: [
4548
+ "+",
4549
+ POINTS_PER_CORRECT,
4550
+ " / correct"
4551
+ ] })
4552
+ ] }),
4527
4553
  isOver && /* @__PURE__ */ jsxs50("div", { className: "ss-w-hl-over", children: [
4528
4554
  /* @__PURE__ */ jsx56("div", { className: "ss-w-hl-over-title", children: runEndedWrong ? "Run over" : "Nice run!" }),
4529
4555
  /* @__PURE__ */ jsx56("div", { className: "ss-w-hl-over-score", children: score }),
4530
4556
  /* @__PURE__ */ jsxs50("div", { className: "ss-w-hl-over-sub", children: [
4531
4557
  correctCount,
4532
- " correct",
4533
- correctCount === 1 ? "" : "",
4534
- " \xB7 come back tomorrow for a new run"
4558
+ " correct \xB7 come back tomorrow for a new run"
4535
4559
  ] })
4536
- ] }),
4537
- answeredPairs.length > 0 && /* @__PURE__ */ jsx56("div", { className: "ss-w-hlresults", children: answeredPairs.map((answered) => {
4538
- const pair = config.pairs.find((p) => p.pairIndex === answered.pairIndex);
4539
- return /* @__PURE__ */ jsxs50(
4540
- "div",
4541
- {
4542
- className: `ss-w-hlrrow ss-w-hlrrow--${answered.wasCorrect ? "correct" : "wrong"}`,
4543
- children: [
4544
- /* @__PURE__ */ jsxs50("span", { className: "ss-w-hlrrow-names", children: [
4545
- pair?.playerAName ?? "?",
4546
- " ",
4547
- /* @__PURE__ */ jsx56("b", { className: "ss-w-hlrrow-val", children: pair?.playerAValue }),
4548
- " vs ",
4549
- pair?.playerBName ?? "?",
4550
- " ",
4551
- /* @__PURE__ */ jsx56("b", { className: "ss-w-hlrrow-val", children: answered.playerBValue })
4552
- ] }),
4553
- /* @__PURE__ */ jsx56("span", { className: "ss-w-hlrrow-pick", children: answered.pick }),
4554
- /* @__PURE__ */ jsx56("span", { className: "ss-w-hlrrow-icon", children: answered.wasCorrect ? "\u2713" : "\u2717" })
4555
- ]
4556
- },
4557
- answered.pairIndex
4558
- );
4559
- }) })
4560
+ ] })
4560
4561
  ] })
4561
4562
  ] });
4562
4563
  }
@@ -4573,18 +4574,22 @@ function parseClientState3(json) {
4573
4574
  }
4574
4575
  }
4575
4576
  function spellYears(spell) {
4576
- const parts = [];
4577
- if (spell.startYear) parts.push(String(spell.startYear));
4578
- if (spell.endYear) parts.push(String(spell.endYear));
4579
- return parts.join("\u2013");
4577
+ if (!spell.startYear) return "";
4578
+ const yy = (y) => `'${String(y % 100).padStart(2, "0")}`;
4579
+ if (spell.endYear && spell.endYear !== spell.startYear) {
4580
+ return `${yy(spell.startYear)}\u2013${String(spell.endYear % 100).padStart(2, "0")}`;
4581
+ }
4582
+ return yy(spell.startYear);
4580
4583
  }
4581
4584
  function ClubSpellCard({ spell }) {
4582
4585
  const years = spellYears(spell);
4583
4586
  return /* @__PURE__ */ jsxs51("div", { className: `ss-w-cpath-club${spell.isLoan ? " ss-w-cpath-club--loan" : ""}`, children: [
4584
4587
  spell.crestUrl ? /* @__PURE__ */ jsx57("img", { src: spell.crestUrl, alt: "", className: "ss-w-cpath-crest", loading: "lazy" }) : /* @__PURE__ */ jsx57("div", { className: "ss-w-cpath-crest ss-w-cpath-crest--fallback", "aria-hidden": "true", children: spell.clubName.slice(0, 3).toUpperCase() }),
4585
- /* @__PURE__ */ jsx57("span", { className: "ss-w-cpath-club-name", children: spell.clubName }),
4586
- years && /* @__PURE__ */ jsx57("span", { className: "ss-w-cpath-spell-yr", children: years }),
4587
- spell.isLoan && /* @__PURE__ */ jsx57("span", { className: "ss-w-cpath-loan-badge", children: "Loan" })
4588
+ /* @__PURE__ */ jsxs51("span", { className: "ss-w-cpath-club-name", children: [
4589
+ spell.clubName,
4590
+ spell.isLoan && /* @__PURE__ */ jsx57("span", { className: "ss-w-cpath-loan-note", children: " (loan)" })
4591
+ ] }),
4592
+ years && /* @__PURE__ */ jsx57("span", { className: "ss-w-cpath-spell-yr", children: years })
4588
4593
  ] });
4589
4594
  }
4590
4595
  function CareerPathGame({
@@ -4599,8 +4604,6 @@ function CareerPathGame({
4599
4604
  const alreadyGuessedIds = new Set(clientState?.guessResults.map((g) => g.playerId) ?? []);
4600
4605
  const isOver = result?.alreadyPlayed === true || clientState?.solved === true || clientState?.failed === true;
4601
4606
  const visiblePath = clientState?.visiblePath ?? config?.initialPath ?? [];
4602
- const totalClubs = clientState?.totalClubs ?? config?.totalClubs ?? visiblePath.length;
4603
- const hiddenCount = Math.max(0, totalClubs - visiblePath.length);
4604
4607
  const filtered = config && !isOver ? config.typeaheadPool.filter(
4605
4608
  (p) => !alreadyGuessedIds.has(p.id) && p.name.toLowerCase().includes(query.toLowerCase())
4606
4609
  ) : [];
@@ -4624,20 +4627,10 @@ function CareerPathGame({
4624
4627
  " left"
4625
4628
  ] })
4626
4629
  ] }),
4627
- /* @__PURE__ */ jsxs51("div", { className: "ss-w-cpath-seq", children: [
4628
- visiblePath.map((spell, i) => /* @__PURE__ */ jsxs51(Fragment11, { children: [
4629
- i > 0 && /* @__PURE__ */ jsx57("span", { className: "ss-w-cpath-arrow", "aria-hidden": "true", children: "\u2192" }),
4630
- /* @__PURE__ */ jsx57(ClubSpellCard, { spell })
4631
- ] }, `${spell.clubName}-${i}`)),
4632
- hiddenCount > 0 && /* @__PURE__ */ jsxs51(Fragment12, { children: [
4633
- /* @__PURE__ */ jsx57("span", { className: "ss-w-cpath-arrow", "aria-hidden": "true", children: "\u2192" }),
4634
- /* @__PURE__ */ jsxs51("div", { className: "ss-w-cpath-hidden", children: [
4635
- "+",
4636
- hiddenCount,
4637
- " more"
4638
- ] })
4639
- ] })
4640
- ] }),
4630
+ /* @__PURE__ */ jsx57("div", { className: "ss-w-cpath-seq", children: visiblePath.map((spell, i) => /* @__PURE__ */ jsxs51(Fragment11, { children: [
4631
+ i > 0 && /* @__PURE__ */ jsx57("span", { className: "ss-w-cpath-arrow", "aria-hidden": "true", children: "\u203A" }),
4632
+ /* @__PURE__ */ jsx57(ClubSpellCard, { spell })
4633
+ ] }, `${spell.clubName}-${i}`)) }),
4641
4634
  clientState?.hintLine && !isOver && /* @__PURE__ */ jsxs51("div", { className: "ss-w-cpath-hint", children: [
4642
4635
  "\u{1F4A1} ",
4643
4636
  clientState.hintLine
@@ -4703,6 +4696,15 @@ function parseClientState4(json) {
4703
4696
  function findCellResult(cells, row, col) {
4704
4697
  return cells.find((c) => c.row === row && c.col === col);
4705
4698
  }
4699
+ function shortName(name) {
4700
+ if (!name) return "";
4701
+ const parts = name.trim().split(/\s+/).filter(Boolean);
4702
+ if (parts.length === 0) return "";
4703
+ const first = parts[0];
4704
+ if (parts.length === 1) return first;
4705
+ const last = parts[parts.length - 1];
4706
+ return `${first.charAt(0)}. ${last}`;
4707
+ }
4706
4708
  function SearchSheet({
4707
4709
  row,
4708
4710
  col,
@@ -4848,8 +4850,11 @@ function BeatTheGridGame({
4848
4850
  disabled: isLocked2 || submitting,
4849
4851
  onClick: () => handleCellClick(rowIdx, colIdx),
4850
4852
  children: filled ? /* @__PURE__ */ jsxs52(Fragment13, { children: [
4851
- /* @__PURE__ */ jsx58("span", { className: "ss-w-btg-cell-score", children: filled.rarityScore }),
4852
- filled.isCorrect && /* @__PURE__ */ jsx58("span", { className: "ss-w-btg-cell-check", "aria-hidden": "true", children: "\u2713" })
4853
+ /* @__PURE__ */ jsx58("span", { className: "ss-w-btg-cell-nm", children: shortName(playerPool.find((p) => p.id === filled.playerId)?.name) }),
4854
+ /* @__PURE__ */ jsxs52("span", { className: "ss-w-btg-cell-score", children: [
4855
+ filled.rarityScore,
4856
+ filled.isCorrect && /* @__PURE__ */ jsx58("span", { className: "ss-w-btg-cell-check", "aria-hidden": "true", children: " \u2713" })
4857
+ ] })
4853
4858
  ] }) : /* @__PURE__ */ jsx58("span", { className: "ss-w-btg-cell-empty", "aria-hidden": "true", children: "+" })
4854
4859
  },
4855
4860
  `cell-${rowIdx}-${colIdx}`
@@ -4888,6 +4893,7 @@ function BeatTheGridGame({
4888
4893
  // src/components/games/GuessTheXiGame.tsx
4889
4894
  import { useState as useState26, useId as useId5 } from "react";
4890
4895
  import { Fragment as Fragment14, jsx as jsx59, jsxs as jsxs53 } from "react/jsx-runtime";
4896
+ var MAX_GUESSES = 3;
4891
4897
  function parseClientState5(json) {
4892
4898
  if (!json) return null;
4893
4899
  try {
@@ -4943,12 +4949,12 @@ function GuessTheXiGame({
4943
4949
  /* @__PURE__ */ jsxs53("div", { children: [
4944
4950
  /* @__PURE__ */ jsx59("div", { className: "ss-w-gxi-title", children: "Guess the XI" }),
4945
4951
  /* @__PURE__ */ jsxs53("div", { className: "ss-w-gxi-sub", children: [
4946
- "Which team? \xB7 ",
4952
+ "Which team? \xB7 flags only \xB7 ",
4947
4953
  config.poolLabel
4948
4954
  ] })
4949
4955
  ] }),
4950
4956
  clientState && !isOver && /* @__PURE__ */ jsxs53("span", { className: "ss-w-gxi-left", children: [
4951
- Math.max(0, 6 - clientState.guessesUsed),
4957
+ Math.max(0, MAX_GUESSES - clientState.guessesUsed),
4952
4958
  " left"
4953
4959
  ] })
4954
4960
  ] }),
@@ -6956,6 +6962,8 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
6956
6962
  .ss-w-gt-left { margin-left: auto; flex: none; font-size: 11px; font-weight: 700; color: var(--ss-w-accent); background: color-mix(in srgb, var(--ss-w-accent) 11%, var(--ss-w-panel)); border: 1px solid color-mix(in srgb, var(--ss-w-accent) 22%, var(--ss-w-line)); border-radius: 999px; padding: 4px 10px; white-space: nowrap; }
6957
6963
  /* Guess rows \u2014 one labelled block per guess */
6958
6964
  .ss-w-gtrows { display: flex; flex-direction: column; gap: 8px; }
6965
+ /* First-load legend (empty state) */
6966
+ .ss-w-gt-lead { font-size: 11.5px; color: var(--ss-w-faint); line-height: 1.4; }
6959
6967
  .ss-w-gtguess { display: flex; flex-direction: column; gap: 4px; }
6960
6968
  .ss-w-gtguess-nm { font-size: 11px; font-weight: 600; color: var(--ss-w-faint); }
6961
6969
  .ss-w-gtrow { display: grid; grid-template-columns: repeat(5, 1fr); gap: 5px; }
@@ -7008,16 +7016,10 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
7008
7016
  .ss-w-hl-over-score { font-size: 34px; font-weight: 800; color: var(--ss-w-accent); line-height: 1; font-variant-numeric: tabular-nums; }
7009
7017
  .ss-w-hl-over-sub { font-size: 11px; color: var(--ss-w-faint); }
7010
7018
  /* Answered history \u2014 clean single-line rows with the revealed value */
7011
- .ss-w-hlresults { display: flex; flex-direction: column; gap: 5px; }
7012
- .ss-w-hlrrow { display: flex; align-items: center; gap: 8px; padding: 8px 11px; border-radius: 10px; font-size: 12px; background: var(--ss-w-bubble); border: 1px solid var(--ss-w-line); }
7013
- .ss-w-hlrrow--correct { background: color-mix(in srgb, var(--ss-w-correct) 10%, var(--ss-w-panel)); border-color: color-mix(in srgb, var(--ss-w-correct) 30%, var(--ss-w-line)); }
7014
- .ss-w-hlrrow--wrong { background: color-mix(in srgb, var(--ss-w-cta) 8%, var(--ss-w-panel)); }
7015
- .ss-w-hlrrow-names { flex: 1; min-width: 0; font-weight: 600; color: var(--ss-w-ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
7016
- .ss-w-hlrrow-val { font-weight: 800; color: var(--ss-w-accent); font-variant-numeric: tabular-nums; }
7017
- .ss-w-hlrrow-pick { font-size: 10px; font-weight: 700; text-transform: uppercase; color: var(--ss-w-faint); flex: none; }
7018
- .ss-w-hlrrow-icon { font-size: 14px; flex: none; }
7019
- .ss-w-hlrrow--correct .ss-w-hlrrow-icon { color: var(--ss-w-correct); }
7020
- .ss-w-hlrrow--wrong .ss-w-hlrrow-icon { color: var(--ss-w-cta); }
7019
+ /* In-progress footer chips (artifact) */
7020
+ .ss-w-hl-foot { display: flex; align-items: center; gap: 8px; }
7021
+ .ss-w-hl-chip { font-size: 11px; font-weight: 600; color: var(--ss-w-faint); background: var(--ss-w-bubble); border: 1px solid var(--ss-w-line); border-radius: 999px; padding: 4px 10px; }
7022
+ .ss-w-hl-chip--green { margin-left: auto; color: var(--ss-w-correct); background: color-mix(in srgb, var(--ss-w-correct) 10%, var(--ss-w-panel)); border-color: color-mix(in srgb, var(--ss-w-correct) 26%, var(--ss-w-line)); }
7021
7023
 
7022
7024
  /* ---- Career Path game screen (D3) \u2014 artifact cpath/club/cto layout ---- */
7023
7025
  .ss-w-cpath { display: flex; flex-direction: column; gap: 12px; }
@@ -7027,18 +7029,16 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
7027
7029
  .ss-w-cpath-sub { font-size: 11px; color: var(--ss-w-faint); margin-top: 4px; }
7028
7030
  .ss-w-cpath-left { margin-left: auto; flex: none; font-size: 11px; font-weight: 700; color: var(--ss-w-accent); background: color-mix(in srgb, var(--ss-w-accent) 11%, var(--ss-w-panel)); border: 1px solid color-mix(in srgb, var(--ss-w-accent) 22%, var(--ss-w-line)); border-radius: 999px; padding: 4px 10px; white-space: nowrap; }
7029
7031
  /* Career sequence \u2014 horizontal crests with arrows */
7030
- .ss-w-cpath-seq { display: flex; flex-wrap: nowrap; align-items: flex-start; gap: 4px; background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); border-radius: 14px; padding: 13px 11px; overflow-x: auto; overscroll-behavior-x: contain; }
7031
- .ss-w-cpath-arrow { align-self: center; flex: none; color: var(--ss-w-faint); font-size: 13px; padding-top: 10px; }
7032
+ .ss-w-cpath-seq { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 6px 4px; background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); border-radius: 14px; padding: 13px 11px; }
7033
+ .ss-w-cpath-arrow { align-self: flex-start; flex: none; color: var(--ss-w-faint); font-size: 13px; padding-top: 9px; }
7032
7034
  /* Single club \u2014 small vertical card */
7033
7035
  .ss-w-cpath-club { display: flex; flex-direction: column; align-items: center; gap: 3px; width: 56px; flex: none; }
7034
7036
  .ss-w-cpath-crest { width: 34px; height: 34px; object-fit: contain; flex: none; border-radius: 8px; }
7035
7037
  .ss-w-cpath-crest--fallback { background: var(--ss-w-bubble); border: 1px solid var(--ss-w-line); display: grid; place-items: center; font-size: 9px; font-weight: 800; letter-spacing: .02em; color: var(--ss-w-faint); }
7036
- .ss-w-cpath-club-name { font-size: 9px; font-weight: 600; color: var(--ss-w-ink); text-align: center; line-height: 1.15; max-width: 56px; display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
7038
+ .ss-w-cpath-club-name { font-size: 9px; font-weight: 600; color: var(--ss-w-ink); text-align: center; line-height: 1.15; max-width: 56px; overflow-wrap: anywhere; }
7037
7039
  .ss-w-cpath-spell-yr { font-size: 8px; color: var(--ss-w-faint); font-weight: 500; white-space: nowrap; }
7038
- .ss-w-cpath-loan-badge { font-size: 7.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; padding: 0 5px; border-radius: 999px; background: color-mix(in srgb, var(--ss-w-accent) 15%, var(--ss-w-panel)); color: var(--ss-w-accent); border: 1px solid color-mix(in srgb, var(--ss-w-accent) 30%, var(--ss-w-line)); }
7040
+ .ss-w-cpath-loan-note { display: block; color: var(--ss-w-faint); font-weight: 500; }
7039
7041
  .ss-w-cpath-club--loan .ss-w-cpath-crest { border: 1px dashed color-mix(in srgb, var(--ss-w-accent) 40%, var(--ss-w-line)); }
7040
- /* Hidden clubs chip */
7041
- .ss-w-cpath-hidden { align-self: center; flex: none; white-space: nowrap; font-size: 9px; font-weight: 700; color: var(--ss-w-faint); background: var(--ss-w-bubble); border: 1px dashed var(--ss-w-line); border-radius: 8px; padding: 6px 8px; }
7042
7042
  /* Hint line */
7043
7043
  .ss-w-cpath-hint { font-size: 11.5px; color: var(--ss-w-faint); text-align: center; padding: 6px 10px; border-radius: 10px; background: color-mix(in srgb, var(--ss-w-accent) 8%, var(--ss-w-panel)); border: 1px dashed color-mix(in srgb, var(--ss-w-accent) 30%, var(--ss-w-line)); }
7044
7044
  /* Terminal outcome */
@@ -7082,8 +7082,10 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
7082
7082
  .ss-w-btg-cell--correct { background: color-mix(in srgb, var(--ss-w-correct) 14%, var(--ss-w-panel)); border-color: color-mix(in srgb, var(--ss-w-correct) 35%, var(--ss-w-line)); }
7083
7083
  .ss-w-btg-cell--wrong { background: color-mix(in srgb, var(--ss-w-wrong) 10%, var(--ss-w-panel)); }
7084
7084
  .ss-w-btg-cell--active { border-color: var(--ss-w-accent); }
7085
- .ss-w-btg-cell-score { font-size: 14px; font-weight: 800; color: var(--ss-w-ink); font-variant-numeric: tabular-nums; }
7086
- .ss-w-btg-cell-check { font-size: 12px; color: var(--ss-w-correct); line-height: 1; }
7085
+ .ss-w-btg-cell-nm { font-size: 8.5px; font-weight: 600; line-height: 1.05; color: var(--ss-w-ink); text-align: center; max-width: 100%; padding: 0 2px; overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
7086
+ .ss-w-btg-cell-score { font-size: 12px; font-weight: 800; color: var(--ss-w-accent); font-variant-numeric: tabular-nums; }
7087
+ .ss-w-btg-cell--correct .ss-w-btg-cell-score { color: var(--ss-w-correct); }
7088
+ .ss-w-btg-cell-check { color: var(--ss-w-correct); line-height: 1; }
7087
7089
  .ss-w-btg-cell-empty { font-size: 16px; color: var(--ss-w-faint); }
7088
7090
  /* Scoped search sheet: slides up over the grid */
7089
7091
  .ss-w-btg-sheet { display: flex; flex-direction: column; gap: 10px; padding: 12px; background: var(--ss-w-panel); border: 1.5px solid var(--ss-w-line); border-radius: 14px; box-shadow: 0 4px 20px rgba(0,0,0,.1); }
@@ -7102,10 +7104,19 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
7102
7104
  .ss-w-gxi-title { font-size: 18px; font-weight: 800; text-transform: uppercase; letter-spacing: .02em; color: var(--ss-w-ink); line-height: 1; }
7103
7105
  .ss-w-gxi-sub { font-size: 11px; color: var(--ss-w-faint); margin-top: 4px; }
7104
7106
  .ss-w-gxi-left { margin-left: auto; flex: none; font-size: 11px; font-weight: 700; color: var(--ss-w-accent); background: color-mix(in srgb, var(--ss-w-accent) 11%, var(--ss-w-panel)); border: 1px solid color-mix(in srgb, var(--ss-w-accent) 22%, var(--ss-w-line)); border-radius: 999px; padding: 4px 10px; white-space: nowrap; }
7105
- /* Pitch: a flag per slot laid out in formation rows on a green field */
7106
- .ss-w-gxi-pitch { display: flex; flex-direction: column; justify-content: space-between; gap: 10px; padding: 16px 10px; border-radius: 14px; border: 1px solid color-mix(in srgb, var(--ss-w-correct) 22%, var(--ss-w-line)); background: linear-gradient(180deg, color-mix(in srgb, var(--ss-w-correct) 10%, var(--ss-w-panel)), color-mix(in srgb, var(--ss-w-correct) 4%, var(--ss-w-panel))); }
7107
- .ss-w-gxi-prow { display: flex; justify-content: space-around; align-items: center; gap: 8px; }
7108
- .ss-w-gxi-flag { width: 34px; height: 34px; flex: none; border-radius: 50%; display: grid; place-items: center; font-size: 19px; line-height: 1; background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); box-shadow: 0 1px 3px rgba(0,0,0,.14); overflow: hidden; }
7107
+ /* Pitch: a flag per slot laid out in formation rows on a green field. A real min-height plus
7108
+ space-between distributes the formation lines top\u2192bottom like a pitch (GK at the back, forwards
7109
+ forward); yard-line stripes reinforce the read. Without a height the lines collapse together. */
7110
+ /* A football pitch is grass-green regardless of the operator accent, so the field uses fixed
7111
+ green values (not --ss-w-correct, which is a muted per-operator token that vanished on dark
7112
+ themes) plus visible horizontal yard-lines and a brighter halfway line. */
7113
+ .ss-w-gxi-pitch { position: relative; display: flex; flex-direction: column; justify-content: space-between; gap: 8px; min-height: 300px; padding: 18px 10px; border-radius: 14px; border: 1px solid rgba(46, 160, 86, .38);
7114
+ background:
7115
+ linear-gradient(180deg, rgba(46, 160, 86, .015) 0, rgba(46, 160, 86, .015) 49.5%, rgba(255,255,255,.14) 49.5%, rgba(255,255,255,.14) 50.5%, rgba(46, 160, 86, .015) 50.5%),
7116
+ repeating-linear-gradient(180deg, transparent 0 31px, rgba(255,255,255,.045) 31px 32px),
7117
+ linear-gradient(180deg, rgba(46, 160, 86, .28), rgba(38, 132, 71, .16)); }
7118
+ .ss-w-gxi-prow { display: flex; justify-content: center; align-items: center; gap: 12px; }
7119
+ .ss-w-gxi-flag { width: 32px; height: 32px; flex: none; border-radius: 50%; display: grid; place-items: center; font-size: 17px; line-height: 1; background: rgba(9, 12, 10, .55); border: 1px solid rgba(255,255,255,.16); box-shadow: 0 1px 3px rgba(0,0,0,.3); overflow: hidden; }
7109
7120
  /* Wrong-guess trail */
7110
7121
  .ss-w-gxi-wrong { display: flex; flex-wrap: wrap; gap: 6px; }
7111
7122
  .ss-w-gxi-wrong-pill { font-size: 11px; font-weight: 600; padding: 3px 9px; border-radius: 999px; background: color-mix(in srgb, var(--ss-w-wrong) 10%, var(--ss-w-panel)); border: 1px solid var(--ss-w-line); color: var(--ss-w-faint); text-decoration: line-through; }