@sensiblestats/widget-react 0.50.1 → 0.51.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.cjs CHANGED
@@ -138,6 +138,13 @@ var STRINGS = {
138
138
  leaderboardOffBoard: "Outside top 50",
139
139
  leaderboardThisWeek: "This week",
140
140
  leaderboardAllTime: "All time",
141
+ leaderboardEmptyFreshTitle: "New week, blank slate",
142
+ leaderboardEmptyFreshBody: "No scores yet. The first fan to play a game takes #1.",
143
+ leaderboardEmptyColdTitle: "Be the first up",
144
+ leaderboardEmptyColdBody: "Nobody's on the board yet. Play a game and you're #1.",
145
+ leaderboardEmptyCta: "Play today's games",
146
+ leaderboardLastWeekLabel: "Last week",
147
+ leaderboardAllTimeEmpty: "The all-time board fills as fans play \u2014 nothing here yet.",
141
148
  gamePlay: "Play",
142
149
  gameResume: "Resume",
143
150
  gameLocked: "Locked",
@@ -228,6 +235,13 @@ var STRINGS = {
228
235
  leaderboardOffBoard: "\u0130lk 50 d\u0131\u015F\u0131nda",
229
236
  leaderboardThisWeek: "Bu hafta",
230
237
  leaderboardAllTime: "T\xFCm zamanlar",
238
+ leaderboardEmptyFreshTitle: "Yeni hafta, temiz sayfa",
239
+ leaderboardEmptyFreshBody: "Hen\xFCz skor yok. Oynayan ilk taraftar 1. s\u0131raya ge\xE7er.",
240
+ leaderboardEmptyColdTitle: "\u0130lk sen ol",
241
+ leaderboardEmptyColdBody: "Panoda hen\xFCz kimse yok. Bir oyun oyna, 1. s\u0131ra senin.",
242
+ leaderboardEmptyCta: "Bug\xFCn\xFCn oyunlar\u0131n\u0131 oyna",
243
+ leaderboardLastWeekLabel: "Ge\xE7en hafta",
244
+ leaderboardAllTimeEmpty: "T\xFCm zamanlar panosu taraftarlar oynad\u0131k\xE7a dolar \u2014 hen\xFCz bir \u015Fey yok.",
231
245
  gamePlay: "Oyna",
232
246
  gameResume: "Devam et",
233
247
  gameLocked: "Kilitli",
@@ -337,6 +351,13 @@ function normalizeUi(cfg) {
337
351
  leaderboardOffBoard: strings.leaderboardOffBoard,
338
352
  leaderboardThisWeek: strings.leaderboardThisWeek,
339
353
  leaderboardAllTime: strings.leaderboardAllTime,
354
+ leaderboardEmptyFreshTitle: strings.leaderboardEmptyFreshTitle,
355
+ leaderboardEmptyFreshBody: strings.leaderboardEmptyFreshBody,
356
+ leaderboardEmptyColdTitle: strings.leaderboardEmptyColdTitle,
357
+ leaderboardEmptyColdBody: strings.leaderboardEmptyColdBody,
358
+ leaderboardEmptyCta: strings.leaderboardEmptyCta,
359
+ leaderboardLastWeekLabel: strings.leaderboardLastWeekLabel,
360
+ leaderboardAllTimeEmpty: strings.leaderboardAllTimeEmpty,
340
361
  gamePlay: strings.gamePlay,
341
362
  gameResume: strings.gameResume,
342
363
  gameLocked: strings.gameLocked,
@@ -4209,6 +4230,13 @@ var ATTR_KEYS = [
4209
4230
  "shirtNumber",
4210
4231
  "apps"
4211
4232
  ];
4233
+ function verdictGlyph(v) {
4234
+ if (v.verdict === "exact") return "\u2713";
4235
+ if (v.verdict === "miss") return "\u2717";
4236
+ if (v.direction === "up") return "\u2191";
4237
+ if (v.direction === "down") return "\u2193";
4238
+ return "\u2248";
4239
+ }
4212
4240
  function MysteryTigerGame({
4213
4241
  config,
4214
4242
  result,
@@ -4218,16 +4246,15 @@ function MysteryTigerGame({
4218
4246
  const [query, setQuery] = (0, import_react29.useState)("");
4219
4247
  const inputId = (0, import_react29.useId)();
4220
4248
  const clientState = parseClientState(result?.clientStateJson);
4221
- const alreadyGuessedIds = new Set(
4222
- clientState?.guessResults.map((g) => g.playerId) ?? []
4223
- );
4249
+ const guessResults = clientState?.guessResults ?? [];
4250
+ const alreadyGuessedIds = new Set(guessResults.map((g) => g.playerId));
4224
4251
  const isOver = result?.alreadyPlayed === true || clientState?.solved === true || clientState?.failed === true;
4225
4252
  const filtered = config && !isOver ? config.squadPlayers.filter(
4226
4253
  (p) => !alreadyGuessedIds.has(p.id) && p.name.toLowerCase().includes(query.toLowerCase())
4227
4254
  ) : [];
4228
4255
  function handleSelect(playerId) {
4229
4256
  if (!config || isOver || submitting) return;
4230
- const prevGuesses = clientState?.guessResults.map((g) => g.playerId) ?? [];
4257
+ const prevGuesses = guessResults.map((g) => g.playerId);
4231
4258
  const newGuesses = [...prevGuesses, playerId];
4232
4259
  setQuery("");
4233
4260
  onSubmit(JSON.stringify({ guesses: newGuesses }));
@@ -4235,9 +4262,46 @@ function MysteryTigerGame({
4235
4262
  return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "ss-w-gt", "data-testid": "game-screen-mystery-tiger", children: [
4236
4263
  !config && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "ss-w-gscreen-body", children: "Loading\u2026" }),
4237
4264
  config && /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(import_jsx_runtime55.Fragment, { children: [
4238
- isOver && clientState && /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: `ss-w-gt-banner ss-w-gt-banner--${clientState.solved ? "solved" : "failed"}`, children: [
4239
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "ss-w-gt-banner-label", children: clientState.solved ? "\u{1F42F} You found them!" : "\u{1F614} Better luck tomorrow" }),
4240
- clientState.revealedPlayerName && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "ss-w-gt-banner-name", children: clientState.revealedPlayerName })
4265
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "ss-w-gt-head", children: [
4266
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { children: [
4267
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "ss-w-gt-title", children: "Mystery Tiger" }),
4268
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "ss-w-gt-sub", children: "Guess today's squad player" })
4269
+ ] }),
4270
+ clientState && !isOver && /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("span", { className: "ss-w-gt-left", children: [
4271
+ clientState.guessesRemaining,
4272
+ " left"
4273
+ ] })
4274
+ ] }),
4275
+ guessResults.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "ss-w-gtrows", children: guessResults.map((gr, i) => {
4276
+ const player = config.squadPlayers.find((p) => p.id === gr.playerId);
4277
+ return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "ss-w-gtguess", children: [
4278
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "ss-w-gtguess-nm", children: [
4279
+ i + 1,
4280
+ " \xB7 ",
4281
+ player?.name ?? `#${gr.playerId}`
4282
+ ] }),
4283
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "ss-w-gtrow", children: ATTR_KEYS.map((key) => {
4284
+ const v = gr[key];
4285
+ return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(
4286
+ "div",
4287
+ {
4288
+ className: `ss-w-gtile ss-w-gtile--${v.verdict}`,
4289
+ "data-testid": `verdict-${key}-${i}`,
4290
+ "data-verdict": v.verdict,
4291
+ "aria-label": `${ATTR_LABELS[key]}: ${v.verdict}${v.direction ? ` ${v.direction}` : ""}`,
4292
+ children: [
4293
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("span", { className: "ss-w-gtile-lab", children: ATTR_LABELS[key] }),
4294
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("span", { className: "ss-w-gtile-v", "aria-hidden": "true", children: verdictGlyph(v) })
4295
+ ]
4296
+ },
4297
+ key
4298
+ );
4299
+ }) })
4300
+ ] }, gr.playerId);
4301
+ }) }),
4302
+ clientState?.hintLine && !isOver && /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "ss-w-gt-hint", children: [
4303
+ "\u{1F4A1} ",
4304
+ clientState.hintLine
4241
4305
  ] }),
4242
4306
  !isOver && /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "ss-w-gtta", children: [
4243
4307
  /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
@@ -4272,38 +4336,15 @@ function MysteryTigerGame({
4272
4336
  p.id
4273
4337
  )) })
4274
4338
  ] }),
4275
- clientState && clientState.guessResults.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { children: [
4276
- /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "ss-w-gthdr", children: [
4277
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "ss-w-gthdr-c ss-w-gthdr-c--name", children: "Player" }),
4278
- ATTR_KEYS.map((key) => /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "ss-w-gthdr-c", children: ATTR_LABELS[key] }, key))
4279
- ] }),
4280
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "ss-w-gtrows", children: clientState.guessResults.map((gr, i) => {
4281
- const player = config.squadPlayers.find((p) => p.id === gr.playerId);
4282
- return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "ss-w-gtrow", children: [
4283
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "ss-w-gtrow-nm", children: player?.name ?? `#${gr.playerId}` }),
4284
- ATTR_KEYS.map((key) => {
4285
- const v = gr[key];
4286
- return /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
4287
- "div",
4288
- {
4289
- className: `ss-w-gtile ss-w-gtile--${v.verdict}`,
4290
- "data-testid": `verdict-${key}-${i}`,
4291
- "data-verdict": v.verdict,
4292
- "aria-label": `${ATTR_LABELS[key]}: ${v.verdict}${v.direction ? ` ${v.direction}` : ""}`,
4293
- children: v.direction && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("span", { className: "ss-w-gtile-dir", "aria-hidden": "true", children: v.direction === "up" ? "\u2191" : "\u2193" })
4294
- },
4295
- key
4296
- );
4297
- })
4298
- ] }, gr.playerId);
4299
- }) })
4300
- ] }),
4301
- clientState?.hintLine && !isOver && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "ss-w-gt-hint", children: clientState.hintLine }),
4302
- !isOver && clientState && /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "ss-w-gt-hint", children: [
4303
- clientState.guessesRemaining,
4304
- " guess",
4305
- clientState.guessesRemaining !== 1 ? "es" : "",
4306
- " remaining"
4339
+ isOver && clientState && /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: `ss-w-gt-banner ss-w-gt-banner--${clientState.solved ? "solved" : "failed"}`, children: [
4340
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "ss-w-gt-banner-label", children: clientState.solved ? "\u{1F42F} You found them!" : "\u{1F614} Out of guesses" }),
4341
+ clientState.revealedPlayerName && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "ss-w-gt-banner-name", children: clientState.revealedPlayerName }),
4342
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "ss-w-gt-banner-sub", children: [
4343
+ clientState.guessesUsed,
4344
+ " guess",
4345
+ clientState.guessesUsed === 1 ? "" : "es",
4346
+ " \xB7 come back tomorrow"
4347
+ ] })
4307
4348
  ] })
4308
4349
  ] })
4309
4350
  ] });
@@ -4319,22 +4360,6 @@ function parseClientState2(json) {
4319
4360
  return null;
4320
4361
  }
4321
4362
  }
4322
- function AnsweredRow({
4323
- answered,
4324
- pair
4325
- }) {
4326
- const cls = `ss-w-hlrrow ss-w-hlrrow--${answered.wasCorrect ? "correct" : "wrong"}`;
4327
- const icon = answered.wasCorrect ? "\u2713" : "\u2717";
4328
- return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: cls, children: [
4329
- /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("span", { className: "ss-w-hlrrow-names", children: [
4330
- pair?.playerAName ?? "?",
4331
- " vs ",
4332
- pair?.playerBName ?? "?"
4333
- ] }),
4334
- /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { className: "ss-w-hlrrow-pick", children: answered.pick }),
4335
- /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { className: "ss-w-hlrrow-icon", children: icon })
4336
- ] });
4337
- }
4338
4363
  function HigherOrLowerGame({
4339
4364
  config,
4340
4365
  result,
@@ -4342,74 +4367,114 @@ function HigherOrLowerGame({
4342
4367
  onSubmit
4343
4368
  }) {
4344
4369
  const clientState = parseClientState2(result?.clientStateJson);
4345
- const answeredCount = clientState?.answeredPairs.length ?? 0;
4346
- const runEndedWrong = clientState?.answeredPairs.some((p) => !p.wasCorrect) ?? false;
4370
+ const answeredPairs = clientState?.answeredPairs ?? [];
4371
+ const answeredCount = answeredPairs.length;
4372
+ const runEndedWrong = answeredPairs.some((p) => !p.wasCorrect);
4347
4373
  const allPairsAnswered = config != null && answeredCount >= config.pairs.length;
4348
4374
  const isOver = result?.alreadyPlayed === true || runEndedWrong || allPairsAnswered;
4349
4375
  const currentPair = config && !isOver ? config.pairs[answeredCount] ?? null : null;
4376
+ const correctCount = answeredPairs.filter((p) => p.wasCorrect).length;
4377
+ const score = clientState?.score ?? correctCount;
4378
+ const runLength = clientState?.runLength ?? 0;
4350
4379
  function handlePick(pick) {
4351
4380
  if (!config || isOver || submitting || !currentPair) return;
4352
- const prevAnswers = clientState?.answeredPairs.map((p) => ({ pairIndex: p.pairIndex, pick: p.pick })) ?? [];
4381
+ const prevAnswers = answeredPairs.map((p) => ({ pairIndex: p.pairIndex, pick: p.pick }));
4353
4382
  const newAnswers = [...prevAnswers, { pairIndex: currentPair.pairIndex, pick }];
4354
4383
  onSubmit(JSON.stringify({ answers: newAnswers }));
4355
4384
  }
4356
4385
  return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "ss-w-hl", "data-testid": "game-screen-higher-or-lower", children: [
4357
4386
  !config && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: "ss-w-gscreen-body", children: "Loading\u2026" }),
4358
4387
  config && /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(import_jsx_runtime56.Fragment, { children: [
4359
- /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "ss-w-hlctx", children: [
4360
- /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { className: "ss-w-hlctx-fam", children: config.statLabel }),
4361
- /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { className: "ss-w-hlctx-szn", children: config.seasonLabel })
4388
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "ss-w-hl-head", children: [
4389
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { children: [
4390
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: "ss-w-hl-title", children: "Higher or Lower" }),
4391
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "ss-w-hl-sub", children: [
4392
+ config.statLabel,
4393
+ " \xB7 ",
4394
+ config.seasonLabel
4395
+ ] })
4396
+ ] }),
4397
+ runLength > 0 && !isOver && /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("span", { className: "ss-w-hl-streak", children: [
4398
+ "\u{1F525} ",
4399
+ runLength
4400
+ ] })
4362
4401
  ] }),
4363
- currentPair && /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "ss-w-hlpair", children: [
4364
- /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "ss-w-hlpc", children: [
4365
- /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: "ss-w-hlpc-name", children: currentPair.playerAName }),
4366
- /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: "ss-w-hlpc-val", children: currentPair.playerAValue })
4402
+ currentPair && /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(import_jsx_runtime56.Fragment, { children: [
4403
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "ss-w-hl-q", children: [
4404
+ "Who has more ",
4405
+ config.statLabel.toLowerCase(),
4406
+ "?"
4367
4407
  ] }),
4368
- /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "ss-w-hlpc ss-w-hlpc--b", children: [
4369
- /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: "ss-w-hlpc-name", children: currentPair.playerBName }),
4370
- /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: "ss-w-hlpc-val ss-w-hlpc-val--hidden", children: "?" })
4408
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "ss-w-hlpair", children: [
4409
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "ss-w-hlpc", children: [
4410
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: "ss-w-hlpc-av", "aria-hidden": "true", children: "\u26BD" }),
4411
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: "ss-w-hlpc-name", children: currentPair.playerAName }),
4412
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: "ss-w-hlpc-stat", children: config.statLabel }),
4413
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: "ss-w-hlpc-val", children: currentPair.playerAValue })
4414
+ ] }),
4415
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "ss-w-hlbtns", children: [
4416
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
4417
+ "button",
4418
+ {
4419
+ type: "button",
4420
+ className: "ss-w-hlbtn ss-w-hlbtn--up",
4421
+ disabled: submitting,
4422
+ onClick: () => handlePick("higher"),
4423
+ children: "Higher \u25B2"
4424
+ }
4425
+ ),
4426
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { className: "ss-w-hl-or", children: "or" }),
4427
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
4428
+ "button",
4429
+ {
4430
+ type: "button",
4431
+ className: "ss-w-hlbtn ss-w-hlbtn--dn",
4432
+ disabled: submitting,
4433
+ onClick: () => handlePick("lower"),
4434
+ children: "Lower \u25BC"
4435
+ }
4436
+ )
4437
+ ] }),
4438
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "ss-w-hlpc ss-w-hlpc--b", children: [
4439
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: "ss-w-hlpc-av", "aria-hidden": "true", children: "\u26BD" }),
4440
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: "ss-w-hlpc-name", children: currentPair.playerBName }),
4441
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: "ss-w-hlpc-stat", children: config.statLabel }),
4442
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: "ss-w-hlpc-val ss-w-hlpc-val--hidden", children: "?" })
4443
+ ] })
4371
4444
  ] })
4372
4445
  ] }),
4373
- !isOver && currentPair && /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "ss-w-hlbtns", children: [
4374
- /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
4375
- "button",
4376
- {
4377
- type: "button",
4378
- className: "ss-w-hlbtn",
4379
- disabled: submitting,
4380
- onClick: () => handlePick("higher"),
4381
- children: "Higher"
4382
- }
4383
- ),
4384
- /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
4385
- "button",
4386
- {
4387
- type: "button",
4388
- className: "ss-w-hlbtn",
4389
- disabled: submitting,
4390
- onClick: () => handlePick("lower"),
4391
- children: "Lower"
4392
- }
4393
- )
4446
+ isOver && /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "ss-w-hl-over", children: [
4447
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: "ss-w-hl-over-title", children: runEndedWrong ? "Run over" : "Nice run!" }),
4448
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: "ss-w-hl-over-score", children: score }),
4449
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "ss-w-hl-over-sub", children: [
4450
+ correctCount,
4451
+ " correct",
4452
+ correctCount === 1 ? "" : "",
4453
+ " \xB7 come back tomorrow for a new run"
4454
+ ] })
4394
4455
  ] }),
4395
- clientState && clientState.answeredPairs.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: "ss-w-hlresults", children: clientState.answeredPairs.map((answered) => {
4456
+ answeredPairs.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: "ss-w-hlresults", children: answeredPairs.map((answered) => {
4396
4457
  const pair = config.pairs.find((p) => p.pairIndex === answered.pairIndex);
4397
- const vCls = `ss-w-hlpc-val ss-w-hlpc-val--${answered.wasCorrect ? "correct" : "wrong"}`;
4398
- const badgeCls = `ss-w-hlpc-badge ss-w-hlpc-badge--${answered.wasCorrect ? "correct" : "wrong"}`;
4399
- return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "ss-w-hlrrow", children: [
4400
- /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "ss-w-hlpair", children: [
4401
- /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "ss-w-hlpc", children: [
4402
- /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: "ss-w-hlpc-name", children: pair?.playerAName ?? "?" }),
4403
- /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: "ss-w-hlpc-val", children: pair?.playerAValue })
4404
- ] }),
4405
- /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "ss-w-hlpc ss-w-hlpc--b", children: [
4406
- /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: "ss-w-hlpc-name", children: pair?.playerBName ?? "?" }),
4407
- /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: vCls, children: answered.playerBValue }),
4408
- /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: badgeCls, children: answered.wasCorrect ? "\u2713" : "\u2717" })
4409
- ] })
4410
- ] }),
4411
- /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(AnsweredRow, { answered, pair })
4412
- ] }, answered.pairIndex);
4458
+ return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(
4459
+ "div",
4460
+ {
4461
+ className: `ss-w-hlrrow ss-w-hlrrow--${answered.wasCorrect ? "correct" : "wrong"}`,
4462
+ children: [
4463
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("span", { className: "ss-w-hlrrow-names", children: [
4464
+ pair?.playerAName ?? "?",
4465
+ " ",
4466
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("b", { className: "ss-w-hlrrow-val", children: pair?.playerAValue }),
4467
+ " vs ",
4468
+ pair?.playerBName ?? "?",
4469
+ " ",
4470
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("b", { className: "ss-w-hlrrow-val", children: answered.playerBValue })
4471
+ ] }),
4472
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { className: "ss-w-hlrrow-pick", children: answered.pick }),
4473
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { className: "ss-w-hlrrow-icon", children: answered.wasCorrect ? "\u2713" : "\u2717" })
4474
+ ]
4475
+ },
4476
+ answered.pairIndex
4477
+ );
4413
4478
  }) })
4414
4479
  ] })
4415
4480
  ] });
@@ -4426,29 +4491,19 @@ function parseClientState3(json) {
4426
4491
  return null;
4427
4492
  }
4428
4493
  }
4429
- function SpellYear({ spell }) {
4494
+ function spellYears(spell) {
4430
4495
  const parts = [];
4431
4496
  if (spell.startYear) parts.push(String(spell.startYear));
4432
4497
  if (spell.endYear) parts.push(String(spell.endYear));
4433
- if (parts.length === 0) return null;
4434
- return /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "ss-w-cpath-spell-yr", children: parts.join(" \u2013 ") });
4498
+ return parts.join("\u2013");
4435
4499
  }
4436
4500
  function ClubSpellCard({ spell }) {
4501
+ const years = spellYears(spell);
4437
4502
  return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: `ss-w-cpath-club${spell.isLoan ? " ss-w-cpath-club--loan" : ""}`, children: [
4438
- spell.crestUrl ? /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
4439
- "img",
4440
- {
4441
- src: spell.crestUrl,
4442
- alt: spell.clubName,
4443
- className: "ss-w-cpath-crest",
4444
- loading: "lazy"
4445
- }
4446
- ) : /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: "ss-w-cpath-crest ss-w-cpath-crest--fallback", "aria-hidden": "true" }),
4447
- /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "ss-w-cpath-club-info", children: [
4448
- /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "ss-w-cpath-club-name", children: spell.clubName }),
4449
- /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(SpellYear, { spell }),
4450
- spell.isLoan && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "ss-w-cpath-loan-badge", children: "Loan" })
4451
- ] })
4503
+ spell.crestUrl ? /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("img", { src: spell.crestUrl, alt: "", className: "ss-w-cpath-crest", loading: "lazy" }) : /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: "ss-w-cpath-crest ss-w-cpath-crest--fallback", "aria-hidden": "true", children: spell.clubName.slice(0, 3).toUpperCase() }),
4504
+ /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "ss-w-cpath-club-name", children: spell.clubName }),
4505
+ years && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "ss-w-cpath-spell-yr", children: years }),
4506
+ spell.isLoan && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "ss-w-cpath-loan-badge", children: "Loan" })
4452
4507
  ] });
4453
4508
  }
4454
4509
  function CareerPathGame({
@@ -4460,11 +4515,11 @@ function CareerPathGame({
4460
4515
  const [query, setQuery] = (0, import_react30.useState)("");
4461
4516
  const inputId = (0, import_react30.useId)();
4462
4517
  const clientState = parseClientState3(result?.clientStateJson);
4463
- const alreadyGuessedIds = new Set(
4464
- clientState?.guessResults.map((g) => g.playerId) ?? []
4465
- );
4518
+ const alreadyGuessedIds = new Set(clientState?.guessResults.map((g) => g.playerId) ?? []);
4466
4519
  const isOver = result?.alreadyPlayed === true || clientState?.solved === true || clientState?.failed === true;
4467
4520
  const visiblePath = clientState?.visiblePath ?? config?.initialPath ?? [];
4521
+ const totalClubs = clientState?.totalClubs ?? config?.totalClubs ?? visiblePath.length;
4522
+ const hiddenCount = Math.max(0, totalClubs - visiblePath.length);
4468
4523
  const filtered = config && !isOver ? config.typeaheadPool.filter(
4469
4524
  (p) => !alreadyGuessedIds.has(p.id) && p.name.toLowerCase().includes(query.toLowerCase())
4470
4525
  ) : [];
@@ -4478,24 +4533,33 @@ function CareerPathGame({
4478
4533
  return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "ss-w-cpath", "data-testid": "game-screen-career-path", children: [
4479
4534
  !config && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: "ss-w-gscreen-body", children: "Loading\u2026" }),
4480
4535
  config && /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(import_jsx_runtime57.Fragment, { children: [
4481
- /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "ss-w-cpath-ctx", children: [
4482
- /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "ss-w-cpath-ctx-label", children: "Career clubs" }),
4483
- /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("span", { className: "ss-w-cpath-ctx-count", children: [
4484
- config.totalClubs,
4485
- " clubs total"
4536
+ /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "ss-w-cpath-head", children: [
4537
+ /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { children: [
4538
+ /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: "ss-w-cpath-title", children: "Career Path" }),
4539
+ /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: "ss-w-cpath-sub", children: "Which player had this career?" })
4540
+ ] }),
4541
+ clientState && !isOver && /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("span", { className: "ss-w-cpath-left", children: [
4542
+ clientState.guessesRemaining,
4543
+ " left"
4486
4544
  ] })
4487
4545
  ] }),
4488
- /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "ss-w-cpath-path", children: [
4489
- visiblePath.map((spell, i) => /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(ClubSpellCard, { spell }, `${spell.clubName}-${i}`)),
4490
- (clientState?.totalClubs ?? config.totalClubs) > visiblePath.length && /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "ss-w-cpath-hidden", children: [
4491
- "+",
4492
- (clientState?.totalClubs ?? config.totalClubs) - visiblePath.length,
4493
- " more clubs hidden"
4546
+ /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "ss-w-cpath-seq", children: [
4547
+ visiblePath.map((spell, i) => /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(import_react30.Fragment, { children: [
4548
+ i > 0 && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "ss-w-cpath-arrow", "aria-hidden": "true", children: "\u2192" }),
4549
+ /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(ClubSpellCard, { spell })
4550
+ ] }, `${spell.clubName}-${i}`)),
4551
+ hiddenCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(import_jsx_runtime57.Fragment, { children: [
4552
+ /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "ss-w-cpath-arrow", "aria-hidden": "true", children: "\u2192" }),
4553
+ /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "ss-w-cpath-hidden", children: [
4554
+ "+",
4555
+ hiddenCount,
4556
+ " more"
4557
+ ] })
4494
4558
  ] })
4495
4559
  ] }),
4496
- isOver && clientState && /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: `ss-w-cpath-banner ss-w-cpath-banner--${clientState.solved ? "solved" : "failed"}`, children: [
4497
- /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: "ss-w-cpath-banner-label", children: clientState.solved ? "Career traced!" : "Better luck tomorrow" }),
4498
- clientState.revealedPlayerName && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: "ss-w-cpath-banner-name", children: clientState.revealedPlayerName })
4560
+ clientState?.hintLine && !isOver && /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "ss-w-cpath-hint", children: [
4561
+ "\u{1F4A1} ",
4562
+ clientState.hintLine
4499
4563
  ] }),
4500
4564
  !isOver && /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "ss-w-gtta", children: [
4501
4565
  /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
@@ -4505,7 +4569,7 @@ function CareerPathGame({
4505
4569
  type: "text",
4506
4570
  role: "textbox",
4507
4571
  className: "ss-w-gtta-i",
4508
- placeholder: "Search players\u2026",
4572
+ placeholder: "Name the player\u2026",
4509
4573
  value: query,
4510
4574
  disabled: submitting || isOver,
4511
4575
  onChange: (e) => setQuery(e.target.value),
@@ -4530,12 +4594,15 @@ function CareerPathGame({
4530
4594
  p.id
4531
4595
  )) })
4532
4596
  ] }),
4533
- clientState?.hintLine && !isOver && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: "ss-w-cpath-hint", children: clientState.hintLine }),
4534
- !isOver && clientState && /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "ss-w-cpath-hint", children: [
4535
- clientState.guessesRemaining,
4536
- " guess",
4537
- clientState.guessesRemaining !== 1 ? "es" : "",
4538
- " remaining"
4597
+ isOver && clientState && /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: `ss-w-cpath-banner ss-w-cpath-banner--${clientState.solved ? "solved" : "failed"}`, children: [
4598
+ /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: "ss-w-cpath-banner-label", children: clientState.solved ? "\u2705 Career traced!" : "\u{1F614} Out of guesses" }),
4599
+ clientState.revealedPlayerName && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: "ss-w-cpath-banner-name", children: clientState.revealedPlayerName }),
4600
+ /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "ss-w-cpath-banner-sub", children: [
4601
+ clientState.guessesUsed,
4602
+ " guess",
4603
+ clientState.guessesUsed === 1 ? "" : "es",
4604
+ " \xB7 come back tomorrow"
4605
+ ] })
4539
4606
  ] })
4540
4607
  ] })
4541
4608
  ] });
@@ -4589,7 +4656,7 @@ function SearchSheet({
4589
4656
  }
4590
4657
  )
4591
4658
  ] }),
4592
- /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { className: "ss-w-gtta", children: [
4659
+ playerPool.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("div", { className: "ss-w-btg-sheet-empty", children: "No players available to search yet." }) : /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { className: "ss-w-gtta", children: [
4593
4660
  /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
4594
4661
  "input",
4595
4662
  {
@@ -4654,18 +4721,23 @@ function BeatTheGridGame({
4654
4721
  const rows = config.rows;
4655
4722
  const cols = config.cols;
4656
4723
  return /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { className: "ss-w-btg", "data-testid": "game-screen-beat-the-grid", children: [
4657
- /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { className: "ss-w-btg-ctx", children: [
4658
- /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("span", { className: "ss-w-btg-ctx-score", children: [
4659
- "Score: ",
4660
- clientState?.totalScore ?? 0
4724
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { className: "ss-w-btg-head", children: [
4725
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { children: [
4726
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("div", { className: "ss-w-btg-title", children: "Beat the Grid" }),
4727
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("div", { className: "ss-w-btg-sub", children: "Fill each cell with a player who fits" })
4661
4728
  ] }),
4662
- !isLocked2 && /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("span", { className: "ss-w-btg-ctx-left", children: [
4663
- config.maxGuesses - filledCells.length,
4664
- " cell",
4665
- config.maxGuesses - filledCells.length !== 1 ? "s" : "",
4666
- " left"
4667
- ] }),
4668
- isLocked2 && /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("span", { className: "ss-w-btg-ctx-done", children: "Complete" })
4729
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { className: "ss-w-btg-ctx", children: [
4730
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("span", { className: "ss-w-btg-ctx-score", children: [
4731
+ clientState?.totalScore ?? 0,
4732
+ " pts"
4733
+ ] }),
4734
+ !isLocked2 && /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("span", { className: "ss-w-btg-ctx-left", children: [
4735
+ config.maxGuesses - filledCells.length,
4736
+ " cell",
4737
+ config.maxGuesses - filledCells.length !== 1 ? "s" : "",
4738
+ " left"
4739
+ ] })
4740
+ ] })
4669
4741
  ] }),
4670
4742
  /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(
4671
4743
  "div",
@@ -4706,6 +4778,16 @@ function BeatTheGridGame({
4706
4778
  ]
4707
4779
  }
4708
4780
  ),
4781
+ isLocked2 && /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { className: "ss-w-btg-done", children: [
4782
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("div", { className: "ss-w-btg-done-label", children: "\u{1F532} Grid complete" }),
4783
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("div", { className: "ss-w-btg-done-score", children: clientState?.totalScore ?? 0 }),
4784
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { className: "ss-w-btg-done-sub", children: [
4785
+ filledCells.filter((c) => c.isCorrect).length,
4786
+ "/",
4787
+ filledCells.length,
4788
+ " correct \xB7 come back tomorrow"
4789
+ ] })
4790
+ ] }),
4709
4791
  activeCell !== null && /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
4710
4792
  SearchSheet,
4711
4793
  {
@@ -4746,6 +4828,7 @@ function GuessTheXiGame({
4746
4828
  }) {
4747
4829
  const clientState = parseClientState5(result?.clientStateJson);
4748
4830
  const isOver = result?.alreadyPlayed === true || clientState?.status === "solved" || clientState?.status === "failed";
4831
+ const solved = clientState?.status === "solved";
4749
4832
  function handlePick(teamId) {
4750
4833
  if (!config || isOver || submitting) return;
4751
4834
  const prevGuesses = clientState?.guessHistory.map((g) => ({ teamId: g.teamId })) ?? [];
@@ -4755,14 +4838,23 @@ function GuessTheXiGame({
4755
4838
  return /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { className: "ss-w-gxi", "data-testid": "game-screen-guess-the-xi", children: [
4756
4839
  !config && /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: "ss-w-gscreen-body", children: "Loading\u2026" }),
4757
4840
  config && /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(import_jsx_runtime59.Fragment, { children: [
4758
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: "ss-w-gxi-ctx", children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("span", { className: "ss-w-gxi-ctx-label", children: config.poolLabel }) }),
4759
- config.positions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: "ss-w-gxi-pitch", children: config.positions.map((pos) => /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { className: "ss-w-gxi-pslot", children: [
4841
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { className: "ss-w-gxi-head", children: [
4842
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { children: [
4843
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: "ss-w-gxi-title", children: "Guess the XI" }),
4844
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: "ss-w-gxi-sub", children: config.poolLabel })
4845
+ ] }),
4846
+ clientState && !isOver && /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("span", { className: "ss-w-gxi-left", children: [
4847
+ "Guess ",
4848
+ clientState.guessesUsed + 1,
4849
+ "/6"
4850
+ ] })
4851
+ ] }),
4852
+ config.positions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: "ss-w-gxi-pitch", children: config.positions.map((pos, i) => /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { className: "ss-w-gxi-pslot", children: [
4760
4853
  /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("span", { className: "ss-w-gxi-pslot-pos", children: pos.slot }),
4761
4854
  /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("span", { className: "ss-w-gxi-pslot-nat", children: pos.nationality })
4762
- ] }, pos.slot)) }),
4855
+ ] }, `${pos.slot}-${i}`)) }),
4763
4856
  clientState && clientState.earnedReveals.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: "ss-w-gxi-reveals", children: clientState.earnedReveals.map((r, i) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(RevealCard, { reveal: r }, i)) }),
4764
- isOver && clientState && /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: `ss-w-gxi-banner ss-w-gxi-banner--${clientState.status}`, children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("span", { className: "ss-w-gxi-banner-label", children: clientState.status === "solved" ? `Solved! ${clientState.score} pts` : "Better luck tomorrow" }) }),
4765
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: "ss-w-gxi-pool", children: config.teamPool.map((team) => {
4857
+ !isOver ? /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: "ss-w-gxi-pool", children: config.teamPool.map((team) => {
4766
4858
  const guessRecord = clientState?.guessHistory.find((g) => g.teamId === team.teamId);
4767
4859
  return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
4768
4860
  "button",
@@ -4772,17 +4864,21 @@ function GuessTheXiGame({
4772
4864
  "ss-w-gxi-team-btn",
4773
4865
  guessRecord ? guessRecord.wasCorrect ? "ss-w-gxi-team-btn--correct" : "ss-w-gxi-team-btn--wrong" : ""
4774
4866
  ].filter(Boolean).join(" "),
4775
- disabled: isOver || submitting,
4867
+ disabled: submitting,
4776
4868
  onClick: () => handlePick(team.teamId),
4777
4869
  children: team.teamName
4778
4870
  },
4779
4871
  team.teamId
4780
4872
  );
4781
- }) }),
4782
- !isOver && clientState && /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { className: "ss-w-gxi-hint", children: [
4783
- "Guess ",
4784
- clientState.guessesUsed + 1,
4785
- " of 6"
4873
+ }) }) : clientState && /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { className: `ss-w-gxi-banner ss-w-gxi-banner--${solved ? "solved" : "failed"}`, children: [
4874
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: "ss-w-gxi-banner-label", children: solved ? "\u2705 Solved!" : "\u{1F614} Out of guesses" }),
4875
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: "ss-w-gxi-banner-score", children: clientState.score }),
4876
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { className: "ss-w-gxi-banner-sub", children: [
4877
+ clientState.guessesUsed,
4878
+ " guess",
4879
+ clientState.guessesUsed === 1 ? "" : "es",
4880
+ " \xB7 come back tomorrow"
4881
+ ] })
4786
4882
  ] })
4787
4883
  ] })
4788
4884
  ] });
@@ -5538,18 +5634,58 @@ function LeaderboardAllTimeRow({
5538
5634
  ] });
5539
5635
  }
5540
5636
 
5541
- // src/components/Leaderboard.tsx
5637
+ // src/components/LeaderboardEmpty.tsx
5542
5638
  var import_jsx_runtime68 = require("react/jsx-runtime");
5639
+ function LeaderboardEmpty({
5640
+ segment,
5641
+ lastWeek,
5642
+ weeklyPrize,
5643
+ onPlay,
5644
+ ui
5645
+ }) {
5646
+ if (segment === "alltime") {
5647
+ return /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("div", { className: "ss-w-lb-empty ss-w-lb-empty--alltime", children: [
5648
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("div", { className: "ss-w-lb-empty-icon", "aria-hidden": "true", children: "\u{1F4CA}" }),
5649
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("p", { className: "ss-w-lb-empty-body", children: ui.leaderboardAllTimeEmpty })
5650
+ ] });
5651
+ }
5652
+ const fresh = lastWeek != null;
5653
+ const title = fresh ? ui.leaderboardEmptyFreshTitle : ui.leaderboardEmptyColdTitle;
5654
+ const body = fresh ? ui.leaderboardEmptyFreshBody : ui.leaderboardEmptyColdBody;
5655
+ return /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("div", { className: "ss-w-lb-empty", children: [
5656
+ weeklyPrize && /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("div", { className: "ss-w-prize", children: [
5657
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("span", { className: "ss-w-prize-icon", "aria-hidden": "true", children: "\u{1F3C6}" }),
5658
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("div", { className: "ss-w-prize-body", children: /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("span", { className: "ss-w-prize-text", children: weeklyPrize }) })
5659
+ ] }),
5660
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("div", { className: "ss-w-lb-empty-hero", children: [
5661
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("div", { className: "ss-w-lb-empty-icon", "aria-hidden": "true", children: fresh ? "\u{1F3C6}" : "\u{1F3AE}" }),
5662
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("h4", { className: "ss-w-lb-empty-title", children: title }),
5663
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("p", { className: "ss-w-lb-empty-body", children: body }),
5664
+ onPlay && /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("button", { type: "button", className: "ss-w-lb-empty-cta", onClick: onPlay, children: ui.leaderboardEmptyCta })
5665
+ ] }),
5666
+ fresh && lastWeek && /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("div", { className: "ss-w-lb-last", children: [
5667
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("span", { className: "ss-w-lb-last-label", children: ui.leaderboardLastWeekLabel }),
5668
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("span", { className: "ss-w-lb-last-champ", "aria-hidden": "true", children: "\u{1F947}" }),
5669
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("span", { className: "ss-w-lb-last-handle", children: lastWeek.handle }),
5670
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("span", { className: "ss-w-lb-last-points", children: formatPoints(lastWeek.points) })
5671
+ ] })
5672
+ ] });
5673
+ }
5674
+
5675
+ // src/components/Leaderboard.tsx
5676
+ var import_jsx_runtime69 = require("react/jsx-runtime");
5543
5677
  function Leaderboard({
5544
5678
  data,
5545
- ui
5679
+ ui,
5680
+ onPlay
5546
5681
  }) {
5547
5682
  const [segment, setSegment] = (0, import_react37.useState)("weekly");
5548
5683
  const myRow = segment === "weekly" ? data.myWeeklyRow : data.myAllTimeRow;
5549
5684
  const offBoard = myRow !== null && myRow !== void 0 && myRow.rank === -1;
5550
- return /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("div", { className: "ss-w-lb2", children: [
5551
- /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("div", { className: "ss-w-seg", children: [
5552
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
5685
+ const isEmpty = segment === "weekly" ? data.weeklyTop.length === 0 : data.allTimeTop.length === 0;
5686
+ return /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("div", { className: "ss-w-lb2", children: [
5687
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("div", { className: "ss-w-seg", children: [
5688
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
5553
5689
  "button",
5554
5690
  {
5555
5691
  type: "button",
@@ -5559,7 +5695,7 @@ function Leaderboard({
5559
5695
  children: ui.leaderboardThisWeek
5560
5696
  }
5561
5697
  ),
5562
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
5698
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
5563
5699
  "button",
5564
5700
  {
5565
5701
  type: "button",
@@ -5570,40 +5706,60 @@ function Leaderboard({
5570
5706
  }
5571
5707
  )
5572
5708
  ] }),
5573
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("div", { className: "ss-w-lb2-rows", children: segment === "weekly" ? data.weeklyTop.map((row) => /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
5574
- LeaderboardWeeklyRow,
5575
- {
5576
- row,
5577
- isMe: row.operatorUserId === data.myWeeklyRow?.operatorUserId
5578
- },
5579
- row.operatorUserId
5580
- )) : data.allTimeTop.map((row) => /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
5581
- LeaderboardAllTimeRow,
5709
+ isEmpty ? /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
5710
+ LeaderboardEmpty,
5582
5711
  {
5583
- row,
5584
- isMe: row.operatorUserId === data.myAllTimeRow?.operatorUserId
5585
- },
5586
- row.operatorUserId
5587
- )) }),
5588
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("div", { className: "ss-w-kitline", children: "\u{1F3BD}" }),
5589
- myRow != null && (offBoard ? /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("div", { className: "ss-w-lbgap", children: ui.leaderboardOffBoard }) : /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("div", { className: "ss-w-lb2-rows", children: [
5590
- segment === "weekly" && data.myWeeklyRow && /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(LeaderboardWeeklyRow, { row: data.myWeeklyRow, isMe: true }),
5591
- segment === "alltime" && data.myAllTimeRow && /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(LeaderboardAllTimeRow, { row: data.myAllTimeRow, isMe: true })
5592
- ] })),
5593
- segment === "alltime" && data.myAllTimeRow && !offBoard && /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("div", { className: "ss-w-lb2-rows", children: /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("div", { className: "ss-w-lb2-row", children: /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("span", { className: "ss-w-lb2-handle", children: formatPoints(data.allTimeTop.reduce((s, r) => s + r.allTimePoints, 0)) }) }) })
5712
+ segment,
5713
+ lastWeek: data.lastWeek,
5714
+ weeklyPrize: data.weeklyPrize,
5715
+ onPlay,
5716
+ ui
5717
+ }
5718
+ ) : /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(import_jsx_runtime69.Fragment, { children: [
5719
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("div", { className: "ss-w-lb2-rows", children: segment === "weekly" ? data.weeklyTop.map((row) => /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
5720
+ LeaderboardWeeklyRow,
5721
+ {
5722
+ row,
5723
+ isMe: row.operatorUserId === data.myWeeklyRow?.operatorUserId
5724
+ },
5725
+ row.operatorUserId
5726
+ )) : data.allTimeTop.map((row) => /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
5727
+ LeaderboardAllTimeRow,
5728
+ {
5729
+ row,
5730
+ isMe: row.operatorUserId === data.myAllTimeRow?.operatorUserId
5731
+ },
5732
+ row.operatorUserId
5733
+ )) }),
5734
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("div", { className: "ss-w-kitline", children: "\u{1F3BD}" }),
5735
+ myRow != null && (offBoard ? /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("div", { className: "ss-w-lbgap", children: ui.leaderboardOffBoard }) : /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("div", { className: "ss-w-lb2-rows", children: [
5736
+ segment === "weekly" && data.myWeeklyRow && /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(LeaderboardWeeklyRow, { row: data.myWeeklyRow, isMe: true }),
5737
+ segment === "alltime" && data.myAllTimeRow && /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(LeaderboardAllTimeRow, { row: data.myAllTimeRow, isMe: true })
5738
+ ] })),
5739
+ segment === "alltime" && data.myAllTimeRow && !offBoard && /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("div", { className: "ss-w-lb2-rows", children: /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("div", { className: "ss-w-lb2-row", children: /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("span", { className: "ss-w-lb2-handle", children: formatPoints(data.allTimeTop.reduce((s, r) => s + r.allTimePoints, 0)) }) }) })
5740
+ ] })
5594
5741
  ] });
5595
5742
  }
5596
5743
 
5597
5744
  // src/components/LeaderboardPanel.tsx
5598
- var import_jsx_runtime69 = require("react/jsx-runtime");
5599
- function LeaderboardPanel({ loggedIn, data, ui }) {
5600
- if (!loggedIn) return /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(GamesLoginWall, { ui });
5601
- if (data === null) return /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("div", { className: "ss-w-mon-list" });
5602
- return /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("div", { className: "ss-w-mon-list", children: /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(Leaderboard, { data, ui }) });
5745
+ var import_jsx_runtime70 = require("react/jsx-runtime");
5746
+ var EMPTY_PAYLOAD = {
5747
+ week: "",
5748
+ weeklyTop: [],
5749
+ myWeeklyRow: null,
5750
+ allTimeTop: [],
5751
+ myAllTimeRow: null,
5752
+ weeklyPrize: null,
5753
+ lastWeek: null
5754
+ };
5755
+ function LeaderboardPanel({ loggedIn, data, loading, onPlay, ui }) {
5756
+ if (!loggedIn) return /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(GamesLoginWall, { ui });
5757
+ if (data === null && loading) return /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("div", { className: "ss-w-mon-list" });
5758
+ return /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("div", { className: "ss-w-mon-list", children: /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(Leaderboard, { data: data ?? EMPTY_PAYLOAD, ui, onPlay }) });
5603
5759
  }
5604
5760
 
5605
5761
  // src/components/ChatPanel.tsx
5606
- var import_jsx_runtime70 = require("react/jsx-runtime");
5762
+ var import_jsx_runtime71 = require("react/jsx-runtime");
5607
5763
  var FULLSCREEN_QUERY = "(max-width: 639px)";
5608
5764
  function useIsModal() {
5609
5765
  const [modal, setModal] = (0, import_react38.useState)(false);
@@ -5634,8 +5790,8 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
5634
5790
  (0, import_react38.useEffect)(() => {
5635
5791
  if (monitor && monitor.activeTab !== "chat" && state.isStreaming) monitor.markChatActivity();
5636
5792
  }, [monitor, state.isStreaming, state.messages.length]);
5637
- return /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("div", { className: "ss-w-panel", role: "dialog", "aria-modal": isModal, "aria-label": ui.chatDialogLabel, children: [
5638
- /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
5793
+ return /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("div", { className: "ss-w-panel", role: "dialog", "aria-modal": isModal, "aria-label": ui.chatDialogLabel, children: [
5794
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
5639
5795
  ChatHeader,
5640
5796
  {
5641
5797
  onClose: close,
@@ -5648,7 +5804,7 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
5648
5804
  moreOptionsLabel: ui.moreOptions
5649
5805
  }
5650
5806
  ),
5651
- monitor && /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
5807
+ monitor && /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
5652
5808
  TabBar,
5653
5809
  {
5654
5810
  monitor,
@@ -5660,19 +5816,28 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
5660
5816
  gamesEnabled: gamesResult?.enabled ?? false
5661
5817
  }
5662
5818
  ),
5663
- /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
5819
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
5664
5820
  "div",
5665
5821
  {
5666
5822
  style: !monitor || monitor.activeTab === "chat" ? { display: "contents" } : { position: "absolute", inset: 0, visibility: "hidden", display: "flex", flexDirection: "column" },
5667
- children: /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(MessageList, { controller, ui, slip, onDashboardTap, monitor })
5823
+ children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(MessageList, { controller, ui, slip, onDashboardTap, monitor })
5668
5824
  }
5669
5825
  ),
5670
- monitor && discovery && monitor.activeTab === "today" && /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(TodayPanel, { discovery, ui, monitor }),
5671
- monitor && monitor.activeTab === "following" && /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(MatchesPanel, { monitor, ui, slip }),
5672
- monitor && monitor.activeTab === "odds" && /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(OddsPanel, { monitor, ui, slip }),
5673
- monitor && monitor.activeTab === "games" && gamesResult && /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(GamesPanel, { loggedIn: !!loggedIn, games: gamesResult.games, ui, conversation }),
5674
- monitor && monitor.activeTab === "leaderboard" && leaderboardResult && /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(LeaderboardPanel, { loggedIn: !!loggedIn, data: leaderboardResult.data, ui }),
5675
- /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ChatInput, { placeholder: ui.placeholder, streaming: state.isStreaming, onSend: handleSend, onStop: stop, stopLabel: ui.stopResponse, sendLabel: ui.sendMessage })
5826
+ monitor && discovery && monitor.activeTab === "today" && /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(TodayPanel, { discovery, ui, monitor }),
5827
+ monitor && monitor.activeTab === "following" && /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(MatchesPanel, { monitor, ui, slip }),
5828
+ monitor && monitor.activeTab === "odds" && /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(OddsPanel, { monitor, ui, slip }),
5829
+ monitor && monitor.activeTab === "games" && gamesResult && /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(GamesPanel, { loggedIn: !!loggedIn, games: gamesResult.games, ui, conversation }),
5830
+ monitor && monitor.activeTab === "leaderboard" && leaderboardResult && /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
5831
+ LeaderboardPanel,
5832
+ {
5833
+ loggedIn: !!loggedIn,
5834
+ data: leaderboardResult.data,
5835
+ loading: leaderboardResult.loading,
5836
+ onPlay: () => monitor.setActiveTab("games"),
5837
+ ui
5838
+ }
5839
+ ),
5840
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(ChatInput, { placeholder: ui.placeholder, streaming: state.isStreaming, onSend: handleSend, onStop: stop, stopLabel: ui.stopResponse, sendLabel: ui.sendMessage })
5676
5841
  ] });
5677
5842
  }
5678
5843
 
@@ -6626,6 +6791,20 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
6626
6791
  /* Off-board treatment: dashed pill indicating rank is outside top N */
6627
6792
  .ss-w-lbgap { display: flex; align-items: center; justify-content: center; gap: 6px; padding: 8px 12px; font-size: 11.5px; color: var(--ss-w-faint); border: 1px dashed var(--ss-w-line); border-radius: 10px; }
6628
6793
 
6794
+ /* ---- Leaderboard empty / weekly-reset default state ---- */
6795
+ .ss-w-lb-empty { display: flex; flex-direction: column; gap: 12px; flex: 1; }
6796
+ .ss-w-lb-empty-hero { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; gap: 8px; padding: 20px 16px; border: 1px dashed color-mix(in srgb, var(--ss-w-cta) 30%, var(--ss-w-line)); border-radius: 14px; background: color-mix(in srgb, var(--ss-w-cta) 6%, var(--ss-w-panel)); }
6797
+ .ss-w-lb-empty--alltime { align-items: center; justify-content: center; text-align: center; padding: 24px 16px; }
6798
+ .ss-w-lb-empty-icon { font-size: 30px; line-height: 1; }
6799
+ .ss-w-lb-empty-title { margin: 2px 0 0; font-size: 16px; font-weight: 800; color: var(--ss-w-ink); }
6800
+ .ss-w-lb-empty-body { margin: 0; max-width: 30ch; font-size: 12.5px; line-height: 1.4; color: var(--ss-w-faint); }
6801
+ .ss-w-lb-empty-cta { margin-top: 6px; border: none; border-radius: 10px; padding: 9px 18px; font: inherit; font-size: 13px; font-weight: 700; color: var(--ss-w-cta-ink); background: var(--ss-w-cta); cursor: pointer; }
6802
+ .ss-w-lb-empty-cta:hover { filter: brightness(1.04); }
6803
+ .ss-w-lb-last { display: flex; align-items: center; gap: 7px; padding-top: 10px; border-top: 1px solid var(--ss-w-line); font-size: 11px; }
6804
+ .ss-w-lb-last-label { text-transform: uppercase; letter-spacing: .05em; font-weight: 700; color: var(--ss-w-faint); }
6805
+ .ss-w-lb-last-handle { flex: 1; min-width: 0; font-weight: 600; color: var(--ss-w-ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
6806
+ .ss-w-lb-last-points { flex: none; font-weight: 750; font-variant-numeric: tabular-nums; color: var(--ss-w-ink); }
6807
+
6629
6808
  /* ---- Mystery Tiger game screen (D3) ---- */
6630
6809
  .ss-w-gt { display: flex; flex-direction: column; gap: 10px; }
6631
6810
  /* Typeahead wrapper: relative so the dropdown can position under it */
@@ -6637,101 +6816,121 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
6637
6816
  .ss-w-gtta-opt { padding: 9px 12px; font-size: 13px; cursor: pointer; color: var(--ss-w-ink); border-bottom: 1px solid var(--ss-w-line); }
6638
6817
  .ss-w-gtta-opt:last-child { border-bottom: none; }
6639
6818
  .ss-w-gtta-opt:hover { background: var(--ss-w-bubble); }
6640
- /* Column header labels: one cell per attribute */
6641
- .ss-w-gthdr { display: grid; grid-template-columns: 1fr repeat(5, 36px); gap: 4px; padding: 0 2px; }
6642
- .ss-w-gthdr-c { font-size: 9px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--ss-w-faint); text-align: center; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
6643
- .ss-w-gthdr-c--name { text-align: left; }
6644
- /* Guess rows */
6645
- .ss-w-gtrows { display: flex; flex-direction: column; gap: 4px; }
6646
- .ss-w-gtrow { display: grid; grid-template-columns: 1fr repeat(5, 36px); gap: 4px; align-items: center; }
6647
- .ss-w-gtrow-nm { font-size: 12px; font-weight: 600; color: var(--ss-w-ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding-right: 4px; }
6648
- /* Verdict tiles */
6649
- .ss-w-gtile { display: flex; flex-direction: column; align-items: center; justify-content: center; height: 36px; border-radius: 8px; font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; gap: 1px; transition: transform .1s; }
6650
- .ss-w-gtile--exact { background: var(--ss-w-correct); color: #fff; }
6651
- .ss-w-gtile--near { background: var(--ss-w-cta); color: var(--ss-w-cta-ink, #fff); }
6819
+ /* Header: title + sub + remaining chip */
6820
+ .ss-w-gt-head { display: flex; align-items: flex-start; gap: 8px; }
6821
+ .ss-w-gt-title { font-size: 18px; font-weight: 800; text-transform: uppercase; letter-spacing: .02em; color: var(--ss-w-ink); line-height: 1; }
6822
+ .ss-w-gt-sub { font-size: 11px; color: var(--ss-w-faint); margin-top: 4px; }
6823
+ .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; }
6824
+ /* Guess rows \u2014 one labelled block per guess */
6825
+ .ss-w-gtrows { display: flex; flex-direction: column; gap: 8px; }
6826
+ .ss-w-gtguess { display: flex; flex-direction: column; gap: 4px; }
6827
+ .ss-w-gtguess-nm { font-size: 11px; font-weight: 600; color: var(--ss-w-faint); }
6828
+ .ss-w-gtrow { display: grid; grid-template-columns: repeat(5, 1fr); gap: 5px; }
6829
+ /* Verdict tiles: label on top, verdict glyph below */
6830
+ .ss-w-gtile { display: flex; flex-direction: column; align-items: center; justify-content: center; aspect-ratio: 1; border-radius: 8px; gap: 2px; min-width: 0; }
6831
+ .ss-w-gtile-lab { font-size: 8px; font-weight: 700; text-transform: uppercase; letter-spacing: .03em; opacity: .75; }
6832
+ .ss-w-gtile-v { font-size: 15px; font-weight: 800; line-height: 1; }
6833
+ .ss-w-gtile--exact { background: var(--ss-w-correct); color: #062611; }
6834
+ .ss-w-gtile--near { background: var(--ss-w-accent); color: #241700; }
6652
6835
  .ss-w-gtile--miss { background: var(--ss-w-bubble); color: var(--ss-w-faint); border: 1px solid var(--ss-w-line); }
6653
- .ss-w-gtile-dir { font-size: 11px; line-height: 1; }
6654
6836
  /* Hint line */
6655
- .ss-w-gt-hint { font-size: 11.5px; color: var(--ss-w-faint); text-align: center; padding: 2px 0; font-style: italic; }
6656
- /* Outcome banner: shown when solved or failed */
6657
- .ss-w-gt-banner { display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 14px 12px; border-radius: 12px; text-align: center; }
6837
+ .ss-w-gt-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)); }
6838
+ /* Terminal outcome banner */
6839
+ .ss-w-gt-banner { display: flex; flex-direction: column; align-items: center; gap: 5px; padding: 16px 12px; border-radius: 14px; text-align: center; }
6658
6840
  .ss-w-gt-banner--solved { background: color-mix(in srgb, var(--ss-w-correct) 12%, var(--ss-w-panel)); border: 1px solid color-mix(in srgb, var(--ss-w-correct) 28%, var(--ss-w-line)); }
6659
- .ss-w-gt-banner--failed { background: color-mix(in srgb, var(--ss-w-wrong) 8%, var(--ss-w-panel)); border: 1px solid var(--ss-w-line); }
6660
- .ss-w-gt-banner-name { font-size: 16px; font-weight: 750; color: var(--ss-w-ink); }
6661
- .ss-w-gt-banner-label { font-size: 12px; color: var(--ss-w-faint); }
6841
+ .ss-w-gt-banner--failed { background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); }
6842
+ .ss-w-gt-banner-name { font-size: 20px; font-weight: 800; text-transform: uppercase; letter-spacing: .01em; color: var(--ss-w-accent); }
6843
+ .ss-w-gt-banner-label { font-size: 13px; font-weight: 700; color: var(--ss-w-ink); }
6844
+ .ss-w-gt-banner-sub { font-size: 11px; color: var(--ss-w-faint); }
6662
6845
 
6663
- /* ---- Higher or Lower game screen (D3) ---- */
6846
+ /* ---- Higher or Lower game screen (D3) \u2014 artifact hl-pair/pcard/hlb layout ---- */
6664
6847
  .ss-w-hl { display: flex; flex-direction: column; gap: 12px; }
6665
- /* Stat context header: family name + season */
6666
- .ss-w-hlctx { display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; }
6667
- .ss-w-hlctx-fam { font-size: 14px; font-weight: 750; color: var(--ss-w-ink); }
6668
- .ss-w-hlctx-szn { font-size: 11.5px; color: var(--ss-w-faint); font-weight: 500; }
6669
- /* Score chip */
6670
- .ss-w-hl-score { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; 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: 3px 10px; }
6671
- /* Pair card: two player cards + divider */
6672
- .ss-w-hlpair { display: flex; align-items: stretch; gap: 0; border-radius: 14px; border: 1.5px solid var(--ss-w-line); overflow: hidden; background: var(--ss-w-panel); }
6673
- /* Player card */
6674
- .ss-w-hlpc { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 14px 10px; text-align: center; }
6675
- .ss-w-hlpc--b { border-left: 1px solid var(--ss-w-line); }
6676
- .ss-w-hlpc-name { font-size: 12.5px; font-weight: 650; color: var(--ss-w-ink); line-height: 1.25; word-break: break-word; min-width: 0; }
6677
- .ss-w-hlpc-val { font-size: 22px; font-weight: 800; color: var(--ss-w-accent); font-variant-numeric: tabular-nums; line-height: 1; }
6678
- .ss-w-hlpc-val--hidden { color: var(--ss-w-faint); font-size: 26px; }
6679
- .ss-w-hlpc-val--correct { color: var(--ss-w-correct); }
6680
- .ss-w-hlpc-val--wrong { color: var(--ss-w-cta); }
6681
- .ss-w-hlpc-badge { font-size: 9.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; border-radius: 999px; padding: 2px 8px; }
6682
- .ss-w-hlpc-badge--correct { color: #fff; background: var(--ss-w-correct); }
6683
- .ss-w-hlpc-badge--wrong { color: var(--ss-w-cta-ink, #fff); background: var(--ss-w-cta); }
6684
- /* Higher / Lower buttons */
6685
- .ss-w-hlbtns { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
6686
- .ss-w-hlbtn { padding: 11px; border-radius: 10px; border: 1.5px solid var(--ss-w-line); background: var(--ss-w-panel); color: var(--ss-w-ink); font: inherit; font-size: 13px; font-weight: 700; cursor: pointer; transition: background .1s, border-color .1s, color .1s; }
6687
- .ss-w-hlbtn:hover:not(:disabled) { background: var(--ss-w-bubble); border-color: var(--ss-w-accent); color: var(--ss-w-accent); }
6848
+ /* Header: title + sub + streak chip */
6849
+ .ss-w-hl-head { display: flex; align-items: flex-start; gap: 8px; }
6850
+ .ss-w-hl-title { font-size: 18px; font-weight: 800; text-transform: uppercase; letter-spacing: .02em; color: var(--ss-w-ink); line-height: 1; }
6851
+ .ss-w-hl-sub { font-size: 11px; color: var(--ss-w-faint); margin-top: 4px; }
6852
+ .ss-w-hl-streak { margin-left: auto; flex: none; font-size: 12px; 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; }
6853
+ /* Question line */
6854
+ .ss-w-hl-q { text-align: center; font-size: 13px; font-weight: 700; text-transform: uppercase; letter-spacing: .02em; color: var(--ss-w-faint); }
6855
+ /* Pair: player A | Higher/Lower | player B */
6856
+ .ss-w-hlpair { display: grid; grid-template-columns: 1fr auto 1fr; gap: 8px; align-items: stretch; }
6857
+ .ss-w-hlpc { background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); border-radius: 14px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px; padding: 14px 6px; text-align: center; min-width: 0; }
6858
+ .ss-w-hlpc-av { width: 42px; height: 42px; border-radius: 50%; background: var(--ss-w-bubble); border: 1px solid var(--ss-w-line); display: grid; place-items: center; font-size: 20px; flex: none; }
6859
+ .ss-w-hlpc-name { font-size: 12.5px; font-weight: 700; color: var(--ss-w-ink); line-height: 1.15; }
6860
+ .ss-w-hlpc-stat { font-size: 8.5px; color: var(--ss-w-faint); text-transform: uppercase; letter-spacing: .04em; }
6861
+ .ss-w-hlpc-val { font-size: 30px; font-weight: 800; color: var(--ss-w-accent); font-variant-numeric: tabular-nums; line-height: 1; }
6862
+ .ss-w-hlpc-val--hidden { color: var(--ss-w-faint); }
6863
+ /* Higher / Lower \u2014 middle column */
6864
+ .ss-w-hlbtns { display: flex; flex-direction: column; gap: 6px; justify-content: center; }
6865
+ .ss-w-hl-or { text-align: center; font-size: 11px; font-weight: 700; color: var(--ss-w-faint); }
6866
+ .ss-w-hlbtn { font: inherit; font-size: 12px; font-weight: 800; text-transform: uppercase; letter-spacing: .03em; border-radius: 9px; padding: 10px 12px; cursor: pointer; border: 1px solid var(--ss-w-line); white-space: nowrap; transition: border-color .1s, background .1s; }
6867
+ .ss-w-hlbtn--up { background: color-mix(in srgb, var(--ss-w-accent) 12%, var(--ss-w-panel)); color: var(--ss-w-accent); border-color: color-mix(in srgb, var(--ss-w-accent) 40%, var(--ss-w-line)); }
6868
+ .ss-w-hlbtn--dn { background: var(--ss-w-panel); color: var(--ss-w-ink); }
6869
+ .ss-w-hlbtn:hover:not(:disabled) { border-color: var(--ss-w-accent); }
6688
6870
  .ss-w-hlbtn:disabled { opacity: .5; cursor: not-allowed; }
6689
- /* Answered pair result rows */
6690
- .ss-w-hlresults { display: flex; flex-direction: column; gap: 4px; }
6691
- .ss-w-hlrrow { display: flex; align-items: center; gap: 8px; padding: 7px 10px; border-radius: 8px; font-size: 12px; background: var(--ss-w-bubble); }
6692
- .ss-w-hlrrow--correct { background: color-mix(in srgb, var(--ss-w-correct) 8%, var(--ss-w-panel)); }
6871
+ /* Run-over terminal panel */
6872
+ .ss-w-hl-over { background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); border-radius: 14px; padding: 16px; text-align: center; display: flex; flex-direction: column; gap: 5px; }
6873
+ .ss-w-hl-over-title { font-size: 16px; font-weight: 800; text-transform: uppercase; letter-spacing: .02em; color: var(--ss-w-ink); }
6874
+ .ss-w-hl-over-score { font-size: 34px; font-weight: 800; color: var(--ss-w-accent); line-height: 1; font-variant-numeric: tabular-nums; }
6875
+ .ss-w-hl-over-sub { font-size: 11px; color: var(--ss-w-faint); }
6876
+ /* Answered history \u2014 clean single-line rows with the revealed value */
6877
+ .ss-w-hlresults { display: flex; flex-direction: column; gap: 5px; }
6878
+ .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); }
6879
+ .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)); }
6693
6880
  .ss-w-hlrrow--wrong { background: color-mix(in srgb, var(--ss-w-cta) 8%, var(--ss-w-panel)); }
6694
6881
  .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; }
6695
- .ss-w-hlrrow-pick { font-size: 11px; font-weight: 700; text-transform: uppercase; color: var(--ss-w-faint); }
6882
+ .ss-w-hlrrow-val { font-weight: 800; color: var(--ss-w-accent); font-variant-numeric: tabular-nums; }
6883
+ .ss-w-hlrrow-pick { font-size: 10px; font-weight: 700; text-transform: uppercase; color: var(--ss-w-faint); flex: none; }
6696
6884
  .ss-w-hlrrow-icon { font-size: 14px; flex: none; }
6885
+ .ss-w-hlrrow--correct .ss-w-hlrrow-icon { color: var(--ss-w-correct); }
6886
+ .ss-w-hlrrow--wrong .ss-w-hlrrow-icon { color: var(--ss-w-cta); }
6697
6887
 
6698
- /* ---- Career Path game screen (D3) ---- */
6888
+ /* ---- Career Path game screen (D3) \u2014 artifact cpath/club/cto layout ---- */
6699
6889
  .ss-w-cpath { display: flex; flex-direction: column; gap: 12px; }
6700
- /* Context header */
6701
- .ss-w-cpath-ctx { display: flex; align-items: baseline; justify-content: space-between; flex-wrap: wrap; gap: 4px; }
6702
- .ss-w-cpath-ctx-label { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--ss-w-faint); }
6703
- .ss-w-cpath-ctx-count { font-size: 12px; font-weight: 600; color: var(--ss-w-accent); }
6704
- /* Career path: vertical timeline of club spells */
6705
- .ss-w-cpath-path { display: flex; flex-direction: column; gap: 4px; }
6706
- /* Single club card */
6707
- .ss-w-cpath-club { display: flex; align-items: center; gap: 10px; padding: 9px 12px; border-radius: 10px; background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); }
6708
- .ss-w-cpath-club--loan { border-style: dashed; }
6709
- /* Crest image / fallback */
6710
- .ss-w-cpath-crest { width: 30px; height: 30px; object-fit: contain; flex: none; border-radius: 4px; }
6711
- .ss-w-cpath-crest--fallback { background: var(--ss-w-bubble); border: 1px solid var(--ss-w-line); border-radius: 4px; }
6712
- /* Club info: name + years */
6713
- .ss-w-cpath-club-info { display: flex; flex: 1; min-width: 0; align-items: center; gap: 6px; flex-wrap: wrap; }
6714
- .ss-w-cpath-club-name { font-size: 13px; font-weight: 650; color: var(--ss-w-ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
6715
- .ss-w-cpath-spell-yr { font-size: 11px; color: var(--ss-w-faint); font-weight: 500; white-space: nowrap; }
6716
- .ss-w-cpath-loan-badge { font-size: 9.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; padding: 1px 7px; border-radius: 999px; background: color-mix(in srgb, var(--ss-w-cta) 15%, var(--ss-w-panel)); color: var(--ss-w-cta-ink, #1b1300); border: 1px solid color-mix(in srgb, var(--ss-w-cta) 30%, var(--ss-w-line)); flex: none; }
6717
- /* Hidden clubs indicator */
6718
- .ss-w-cpath-hidden { font-size: 11.5px; color: var(--ss-w-faint); font-style: italic; text-align: center; padding: 6px 0 2px; }
6890
+ /* Header */
6891
+ .ss-w-cpath-head { display: flex; align-items: flex-start; gap: 8px; }
6892
+ .ss-w-cpath-title { font-size: 18px; font-weight: 800; text-transform: uppercase; letter-spacing: .02em; color: var(--ss-w-ink); line-height: 1; }
6893
+ .ss-w-cpath-sub { font-size: 11px; color: var(--ss-w-faint); margin-top: 4px; }
6894
+ .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; }
6895
+ /* Career sequence \u2014 horizontal crests with arrows */
6896
+ .ss-w-cpath-seq { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 6px; background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); border-radius: 14px; padding: 13px 11px; }
6897
+ .ss-w-cpath-arrow { align-self: center; color: var(--ss-w-faint); font-size: 13px; padding-top: 10px; }
6898
+ /* Single club \u2014 small vertical card */
6899
+ .ss-w-cpath-club { display: flex; flex-direction: column; align-items: center; gap: 3px; width: 58px; }
6900
+ .ss-w-cpath-crest { width: 34px; height: 34px; object-fit: contain; flex: none; border-radius: 8px; }
6901
+ .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); }
6902
+ .ss-w-cpath-club-name { font-size: 9px; font-weight: 600; color: var(--ss-w-ink); text-align: center; line-height: 1.1; overflow-wrap: anywhere; }
6903
+ .ss-w-cpath-spell-yr { font-size: 8px; color: var(--ss-w-faint); font-weight: 500; white-space: nowrap; }
6904
+ .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)); }
6905
+ .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)); }
6906
+ /* Hidden clubs chip */
6907
+ .ss-w-cpath-hidden { align-self: center; 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; }
6719
6908
  /* Hint line */
6720
- .ss-w-cpath-hint { font-size: 11.5px; color: var(--ss-w-faint); text-align: center; padding: 2px 0; font-style: italic; }
6721
- /* Outcome banner */
6722
- .ss-w-cpath-banner { display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 14px 12px; border-radius: 12px; text-align: center; }
6909
+ .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)); }
6910
+ /* Terminal outcome */
6911
+ .ss-w-cpath-banner { display: flex; flex-direction: column; align-items: center; gap: 5px; padding: 16px 12px; border-radius: 14px; text-align: center; }
6723
6912
  .ss-w-cpath-banner--solved { background: color-mix(in srgb, var(--ss-w-correct) 12%, var(--ss-w-panel)); border: 1px solid color-mix(in srgb, var(--ss-w-correct) 28%, var(--ss-w-line)); }
6724
- .ss-w-cpath-banner--failed { background: color-mix(in srgb, var(--ss-w-wrong) 8%, var(--ss-w-panel)); border: 1px solid var(--ss-w-line); }
6725
- .ss-w-cpath-banner-name { font-size: 16px; font-weight: 750; color: var(--ss-w-ink); }
6726
- .ss-w-cpath-banner-label { font-size: 12px; color: var(--ss-w-faint); }
6913
+ .ss-w-cpath-banner--failed { background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); }
6914
+ .ss-w-cpath-banner-name { font-size: 20px; font-weight: 800; text-transform: uppercase; letter-spacing: .01em; color: var(--ss-w-accent); }
6915
+ .ss-w-cpath-banner-label { font-size: 13px; font-weight: 700; color: var(--ss-w-ink); }
6916
+ .ss-w-cpath-banner-sub { font-size: 11px; color: var(--ss-w-faint); }
6727
6917
 
6728
- /* ---- Beat the Grid game screen (D3) ---- */
6918
+ /* ---- Beat the Grid game screen (D3) \u2014 artifact grid/gc layout ---- */
6729
6919
  .ss-w-btg { display: flex; flex-direction: column; gap: 10px; }
6730
- /* Score/context row */
6731
- .ss-w-btg-ctx { display: flex; align-items: center; justify-content: space-between; gap: 6px; }
6732
- .ss-w-btg-ctx-score { font-size: 13px; font-weight: 700; color: var(--ss-w-ink); }
6733
- .ss-w-btg-ctx-left { font-size: 12px; color: var(--ss-w-faint); font-weight: 500; }
6734
- .ss-w-btg-ctx-done { font-size: 12px; font-weight: 700; color: var(--ss-w-correct); }
6920
+ /* Header */
6921
+ .ss-w-btg-head { display: flex; align-items: flex-start; gap: 8px; }
6922
+ .ss-w-btg-title { font-size: 18px; font-weight: 800; text-transform: uppercase; letter-spacing: .02em; color: var(--ss-w-ink); line-height: 1; }
6923
+ .ss-w-btg-sub { font-size: 11px; color: var(--ss-w-faint); margin-top: 4px; }
6924
+ .ss-w-btg-ctx { margin-left: auto; display: flex; flex-direction: column; align-items: flex-end; gap: 2px; }
6925
+ .ss-w-btg-ctx-score { font-size: 13px; font-weight: 800; color: var(--ss-w-accent); font-variant-numeric: tabular-nums; }
6926
+ .ss-w-btg-ctx-left { font-size: 11px; color: var(--ss-w-faint); font-weight: 500; white-space: nowrap; }
6927
+ /* Terminal summary */
6928
+ .ss-w-btg-done { display: flex; flex-direction: column; align-items: center; gap: 5px; padding: 16px 12px; border-radius: 14px; text-align: center; background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); }
6929
+ .ss-w-btg-done-label { font-size: 13px; font-weight: 700; color: var(--ss-w-ink); }
6930
+ .ss-w-btg-done-score { font-size: 34px; font-weight: 800; color: var(--ss-w-accent); line-height: 1; font-variant-numeric: tabular-nums; }
6931
+ .ss-w-btg-done-sub { font-size: 11px; color: var(--ss-w-faint); }
6932
+ /* Empty search pool note */
6933
+ .ss-w-btg-sheet-empty { font-size: 12px; color: var(--ss-w-faint); text-align: center; padding: 14px 8px; }
6735
6934
  /* Grid layout \u2014 col count driven inline via style */
6736
6935
  .ss-w-btg-grid { display: grid; gap: 4px; width: 100%; }
6737
6936
  /* Generic grid cell */
@@ -6764,9 +6963,11 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
6764
6963
 
6765
6964
  /* ---- Guess the XI game screen (D3) ---- */
6766
6965
  .ss-w-gxi { display: flex; flex-direction: column; gap: 12px; }
6767
- /* Context label (pool label) */
6768
- .ss-w-gxi-ctx { display: flex; align-items: center; }
6769
- .ss-w-gxi-ctx-label { font-size: 12px; font-weight: 700; color: var(--ss-w-faint); text-transform: uppercase; letter-spacing: .05em; }
6966
+ /* Header */
6967
+ .ss-w-gxi-head { display: flex; align-items: flex-start; gap: 8px; }
6968
+ .ss-w-gxi-title { font-size: 18px; font-weight: 800; text-transform: uppercase; letter-spacing: .02em; color: var(--ss-w-ink); line-height: 1; }
6969
+ .ss-w-gxi-sub { font-size: 11px; color: var(--ss-w-faint); margin-top: 4px; }
6970
+ .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; }
6770
6971
  /* Positions pitch: compact slot grid */
6771
6972
  .ss-w-gxi-pitch { display: flex; flex-wrap: wrap; gap: 5px; }
6772
6973
  .ss-w-gxi-pslot { display: flex; flex-direction: column; align-items: center; gap: 2px; background: var(--ss-w-bubble); border: 1px solid var(--ss-w-line); border-radius: 8px; padding: 6px 10px; min-width: 52px; }
@@ -6784,11 +6985,13 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
6784
6985
  .ss-w-gxi-team-btn:disabled { opacity: .5; cursor: not-allowed; }
6785
6986
  .ss-w-gxi-team-btn--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)); color: var(--ss-w-correct); }
6786
6987
  .ss-w-gxi-team-btn--wrong { background: color-mix(in srgb, var(--ss-w-wrong) 8%, var(--ss-w-panel)); text-decoration: line-through; opacity: .65; }
6787
- /* Outcome banner */
6788
- .ss-w-gxi-banner { display: flex; align-items: center; justify-content: center; padding: 10px 12px; border-radius: 10px; }
6988
+ /* Terminal outcome banner */
6989
+ .ss-w-gxi-banner { display: flex; flex-direction: column; align-items: center; gap: 5px; padding: 16px 12px; border-radius: 14px; text-align: center; }
6789
6990
  .ss-w-gxi-banner--solved { background: color-mix(in srgb, var(--ss-w-correct) 12%, var(--ss-w-panel)); border: 1px solid color-mix(in srgb, var(--ss-w-correct) 28%, var(--ss-w-line)); }
6790
- .ss-w-gxi-banner--failed { background: color-mix(in srgb, var(--ss-w-wrong) 8%, var(--ss-w-panel)); border: 1px solid var(--ss-w-line); }
6991
+ .ss-w-gxi-banner--failed { background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); }
6791
6992
  .ss-w-gxi-banner-label { font-size: 13px; font-weight: 700; color: var(--ss-w-ink); }
6993
+ .ss-w-gxi-banner-score { font-size: 34px; font-weight: 800; color: var(--ss-w-accent); line-height: 1; font-variant-numeric: tabular-nums; }
6994
+ .ss-w-gxi-banner-sub { font-size: 11px; color: var(--ss-w-faint); }
6792
6995
  /* Hint line */
6793
6996
  .ss-w-gxi-hint { font-size: 11.5px; color: var(--ss-w-faint); text-align: center; font-style: italic; }
6794
6997
 
@@ -6933,7 +7136,7 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
6933
7136
  `;
6934
7137
 
6935
7138
  // src/StatsWidget.tsx
6936
- var import_jsx_runtime71 = require("react/jsx-runtime");
7139
+ var import_jsx_runtime72 = require("react/jsx-runtime");
6937
7140
  function buildClient(props) {
6938
7141
  try {
6939
7142
  if ("client" in props && props.client) {
@@ -7072,7 +7275,7 @@ function StatsWidget(props) {
7072
7275
  }, [built, ui.injectStyles]);
7073
7276
  if (!built) return null;
7074
7277
  const attrs = themeAttrs(ui);
7075
- return /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(EventLogContext.Provider, { value: logger, children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("div", { ref: rootRef, className: "ss-w-root", "data-ss-w-theme": attrs["data-ss-w-theme"], "data-ss-w-pos": attrs["data-ss-w-pos"], style: attrs.style, children: controller.state.isOpen ? /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
7278
+ return /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(EventLogContext.Provider, { value: logger, children: /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("div", { ref: rootRef, className: "ss-w-root", "data-ss-w-theme": attrs["data-ss-w-theme"], "data-ss-w-pos": attrs["data-ss-w-pos"], style: attrs.style, children: controller.state.isOpen ? /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
7076
7279
  ChatPanel,
7077
7280
  {
7078
7281
  controller,
@@ -7086,7 +7289,7 @@ function StatsWidget(props) {
7086
7289
  loggedIn: !!operatorUserId,
7087
7290
  conversation: built?.conversation ?? null
7088
7291
  }
7089
- ) : /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
7292
+ ) : /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
7090
7293
  ChatFab,
7091
7294
  {
7092
7295
  label: ui.launcherLabel,