Skip to content

Elemental Showdown: the unlock moment (#168) - #179

Merged
jacobcheatley merged 4 commits into
feat/167-storiesfrom
feat/168-unlock-moment
Sep 22, 2026
Merged

jacobcheatley merged 4 commits into
feat/167-storiesfrom
feat/168-unlock-moment

Conversation

@jacobcheatley

@jacobcheatley jacobcheatley commented Sep 22, 2026 •

Copy link
Copy Markdown
Owner

Closes #168. Part of #158.

The reveal carries the unlock only on the Vote that takes the gate from unmet to met. castVote counts both numbers fresh on the cast path and knows from insert ... returning whether this Vote was stored, so a repeat Vote and every Vote after the unlock report nothing. The unlocking cast also drops the cached aggregate, so the Voter who has just seen "stats unlocked" is not met by a locked screen while the cached count catches up.

On the client the moment replaces the Tug: the mosaic's tiles flip to their Element in a diagonal wave, a tilted "stats unlocked" stamp lands, the phone vibrates where it can, and after 2.6s the Stats replace the screen. Under prefers-reduced-motion the moment is skipped and the Voter goes straight to the Stats. The stamp sits under the mosaic and scales with the viewport so it fits a phone.

Verification

Real-Postgres tests (the crossing Vote reports the unlock, the Votes before and after do not, a repeat Vote does not, the Stats open at the same clock reading), component tests on fake timers (the unlock leads to the Stats, reduced motion skips the wave, no Vibration API does not throw), and a browser pass seeded one Vote short of both numbers, once with reduced motion emulated.

🤖 Generated with Claude Code

https://claude.ai/code/session_01AVEtgjCoEbaNHrYfzyCRNH

@jacobcheatley
jacobcheatley added this pull request to stack #182 September 22, 2026 00:37
@jacobcheatley jacobcheatley changed the title feat/168 unlock moment Elemental Showdown: the unlock moment (#168) Sep 22, 2026
@jacobcheatley
jacobcheatley marked this pull request as ready for review September 22, 2026 00:38
jacobcheatley and others added 4 commits September 22, 2026 13:08
The Matchup helpers the Stats gate's tests build their crowd with are about
to be what the unlock's tests need too, so they move out of that one
describe and up to the file.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AVEtgjCoEbaNHrYfzyCRNH
The reveal of the one Vote that crosses both unlock numbers carries the
Active Elements, which is what the unlock's wave flips a tile for; every
other reveal carries none of them.

Both numbers are counted fresh on the cast path rather than read from the
cached aggregate, whose crowd count is up to a minute behind and so cannot
say which Vote crossed. The insert reports whether it stored anything, so a
repeat Vote — which moves neither count — never fires the unlock.

The Stats' own gate still reads the cached count, so the unlocking cast
drops that copy: the Voter who just watched the Stats open finds them open.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AVEtgjCoEbaNHrYfzyCRNH
The reveal of an unlocking Vote is followed by the mosaic: a tile per Active
Element flips to its own colour and emoji in a diagonal wave, the tilted
stamp lands on it and the platform buzzes if it can, and then the Stats take
the screen. A Voter who asks for less motion is taken straight there.

The whole moment is one named constant long, so the component tests drive it
on fake timers.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AVEtgjCoEbaNHrYfzyCRNH
At the 44px the prototype draws it the stamp is wider than a phone, and the
prototype's locked screen keeps its mosaic near the top where a stamp across
the middle misses it. On its own screen the mosaic is centred, so the stamp
lands under it and takes its size from the screen up to that 44px.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AVEtgjCoEbaNHrYfzyCRNH
@jacobcheatley
jacobcheatley merged commit aab0b52 into main Sep 22, 2026
7 checks passed
@jacobcheatley
jacobcheatley deleted the feat/168-unlock-moment branch September 22, 2026 06:13
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.

Elemental Showdown: the unlock moment

1 participant