CadenceFlashcards Lite
What it does for you
Paste a CSV and study it with a real SM-2 scheduler: learning steps, lapses, interval previews on every grade button, a due forecast, and a review heatmap.

Screenshots

In more detail
Cadence is a flashcard app. You paste in a CSV, and it schedules every card with the SM-2 spaced-repetition algorithm, so you review each card right before you would forget it. Each grade button shows exactly when you will see the card again, and a stats page shows what is coming due.
Honest limits
One browser, one user, localStorage only. Day boundaries use local midnight. It is SM-2, not a newer scheduler, because the tier asked for the basics. Notes and cards are stored together, so editing a cloze sentence does not keep its cards' history cleanly. It works and it is tested, not hammered.
How I built it
Most flashcard demos just shuffle a list, which teaches nothing about why spaced repetition works. I wanted the scheduling math to be real, visible, and tested. This was one of the parallel Claude Code builders from the September 19 one-shot night. I directed the scope: real SM-2 with Anki-style learning steps, CSV in and out, intervals printed on the buttons, and charts that make the schedule readable. Claude Code wrote srs.js first, then 164 assertions, then the UI.
The part I like most is the demo deck. It is not hand-written. It is 76 days of history made by running the real queue and scheduler day by day, with a seeded random generator picking grades. So every chart in the screenshots is genuine scheduler output. Claude Code took screenshots in both themes and fixed what looked wrong: a clipped axis label and a demo streak that read 0. Logged time was about half an hour.
What I learned
- Classic SM-2 is three numbers per card (ease, interval, reps) and one formula floored at 1.3. Everything that makes it feel like a real app (learning steps in minutes, relearning, keeping part of the interval after a lapse) is a layer around that core.
- That layering bit me once. Keeping half the interval on a lapse while resetting reps to 0 sends the card back through the 1 day, then 6 day ladder and throws the kept interval away. Reps has to stay at 2 when an interval survives.
- Make the scheduler a pure function of card, grade, settings, and now. Passing the time in gave three things at once: deterministic tests, undo as a one-line restore, and the simulated demo deck.
- Review cards and learning cards need different clocks: calendar day for reviews, exact timestamp for learning steps.
- A global regex reused with
.test()remembers where it stopped, sohasCloze()alternated true and false on the same string. A test now calls it three times in a row.
What carried forward
The pure schedule() function is the tested-core pattern from #9 through #11 at its best: the page imports the exact module the tests import. It also used the brief's standard pieces, serve.mjs, ?demo=1, and ?theme=. The screenshot step ran into the Windows path trouble first found on #7: a loop that built the path with escaped backslashes silently wrote nothing. Retaking with a single-quoted absolute Windows path fixed it. The seeded-random idea shows up again in #30 the same night.
If I took it further
I would store notes and cards separately so editing a sentence keeps its history, and put the scheduler behind an interface so a second algorithm could be compared against SM-2 on the same review log.
#028 Built with Claude Code September 20, 2026 164 automated checks