Drill transitions live in drillReducer.ts with no React, so they test
like the domain does. Choosing the next card needs randomness, so that
happens outside and arrives in the deal action; the reducer only ever
transforms what it is given.
Rules it encodes, each now pinned by a test:
- Show me counts as a miss. You did not know it, so the card goes back
to box 1 rather than being skipped.
- Presses are inert once a card is graded, because the panel is showing
the answer at that point.
- Tapping toggles, so a mis-hit can be taken back; holding accumulates,
because a second report from a held finger is just contact.
- Changing deck or direction drops the current card, since it may not be
in the new pool. Changing only the answering mode keeps it.
- A card cannot be graded twice.
132 tests, typecheck clean.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>