Skip to content

Live stats widget - #2579

Merged
lexicalunit merged 5 commits into
mainfrom
live-stats-widget
Sep 11, 2026
Merged

lexicalunit merged 5 commits into
mainfrom
live-stats-widget

Conversation

@lexicalunit

Copy link
Copy Markdown
Owner

No description provided.

lexicalunit and others added 5 commits September 10, 2026 18:07
Showcase the queues page on the marketing site with live server, player
and game counts.

The counts are served by a new `/stats.json` endpoint that reads only from
Redis, never the database. A task loop in the bot process recomputes them
every minute and writes them to Redis with a TTL well beyond the refresh
interval, so a transient failure shows slightly stale numbers rather than
an empty widget. Homepage traffic is the highest-volume traffic we have,
so it must not translate into database load.

Counts are derived from the same service calls that back the queues page,
so the numbers on spellbot.io always agree with what a visitor sees after
clicking through. `STARTED_GAMES_WINDOW` moves into the service layer so
the page, `/queues.json` and the cache share one definition.

CORS is added for an explicit allowlist of public, unauthenticated,
read-only JSON endpoints, matched as exact paths so an authenticated route
can never pick it up by accident. This also makes `/status.json` readable
cross-origin; CORS only ever grants access, so nothing that worked before
is affected.

The widget itself is progressive enhancement: it stays hidden unless the
fetch succeeds, leaving the page unchanged when the API is unreachable.
Its API base is a Jekyll config value so it can point at a local API
during development (`make dev` in docs/).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Reuse the amber -> purple gradient from `.screenshot` as the widget's
border so it reads as part of this page rather than a bolted-on
component. The purple stop is lifted from the brand #5a3efd to #7c5cff:
at 2px on #1a202c the brand value is only 2.75:1, under the 3:1 floor for
non-text UI, which is what made the border hard to pick out.

The whole card is now one click target, using the stretched-link pattern
rather than a click handler on the container. A single anchor's ::after
is stretched over the positioned card, which keeps middle-click,
right-click -> open in new tab, keyboard focus and screen-reader link
semantics working -- none of which survives an onclick on a <div>.

Add a live indicator and count up the numbers on load. Both are there to
earn the click, but the indicator also states something true: the counts
really are refreshed every minute.

Every colour was measured against its real backdrop rather than eyeballed;
text lands between 5.3:1 and 14.9:1 across both surface states. Keyboard
focus draws a ring on the card, and prefers-reduced-motion drops the lift,
the arrow, the pulse and the count-up. There is deliberately no
prefers-color-scheme branch: this site commits to one dark palette and
does not follow the OS setting.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Restore the typography the page was already paying for: a `*` rule forced
Verdana over everything with !important, so both Google fonts loaded and
were then discarded. Reassign the theme's own --body-font/--header-font
instead of overriding per element, so every rule in beautifuljekyll.css
follows along. Headings are Outfit, running text Open Sans.

Repeat the amber -> purple gradient from `.screenshot` as a rule under each
section heading so the site's existing motif becomes the connective tissue
between sections rather than a one-off on images.

Rebuild the server directory as an auto-fill grid. The track floor is
measured rather than guessed: the longest name renders 211px at `.small`
and these names are joined with &nbsp; by scripts/update_servers.py, so
they cannot wrap and the tile has to be wide enough to hold them. Each
tile is a two-row grid so every name starts at the same y and the labels
line up across the grid.

Turn the Help list into real numbered steps -- these are a sequence the
reader works through in order, not decoration -- and make the Discord
embed responsive.

Add sections for the Playgroup Live and Castlog integrations, with copy
taken from what the integrations actually do rather than from their
marketing pages. Use "live queues" for the queues site throughout.

Every colour was measured against the surface it actually sits on rather
than eyeballed, and prefers-reduced-motion drops every transform and
animation, including the avatar spin.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@lexicalunit
lexicalunit merged commit da4659e into main Sep 11, 2026
11 checks passed
@lexicalunit
lexicalunit deleted the live-stats-widget branch September 11, 2026 02:35
@codecov

codecov Bot commented Sep 11, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (0a1b9cd) to head (0184297).
⚠️ Report is 6 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##              main     #2579    +/-   ##
==========================================
  Coverage   100.00%   100.00%            
==========================================
  Files          291       295     +4     
  Lines        23572     23792   +220     
  Branches       957       964     +7     
==========================================
+ Hits         23572     23792   +220     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant