26/09 — From one button to a curriculum
Continuing the daily protocol of building schlau.app in public — this installment covers turning a single, fixed Rechenart into a real, extensible menu of options, and populating it with three new algebra topics.
Day 20 — Turning one button into a menu
Every Rechenart added since the migration had been a new top-level button. That doesn't scale — a dozen new algebra topics would mean a dozen new buttons crowding the same row. Today's job was making room for depth instead of width, without breaking anything already live.
What happened
- Before writing anything, had Claude Code audit how the existing dropdown-based Rechenarten (Prop, Prozent, Powers) actually work — not assumed, read directly from the code: where option state lives, how routes map to options, how each option earns its own badge icon
- The audit turned up an immediate complication: the Rechenart meant to host the first new option, addsub ("Plus Minus & Klammern"), wasn't built the option-based way at all. It picked its internal variant with a private switch statement and had no dropdown, no numbered route, nothing to hang a new option off of
- That forced a real decision before any feature work could start: convert addsub to the same architecture as Prop/Prozent/Powers first, as its own deliberate step
- The conversion surfaced a distinction worth getting exactly right: addsub already had internal randomization — different sign-presentation variants of the same calculation, invisible to the student. That's not the same thing as a Rechenart-Option, which is a deliberate, user-visible choice in a dropdown. Conflating the two would have quietly merged unrelated concepts into the same mechanism
- Landed on a clean split: the entire existing addsub logic, internal randomization included, became Option 1 — unchanged, just wrapped in a new outer dispatch. New options would be added as Option 2, 3, 4 onward, each getting its own numbered icon (
addsub1,addsub2, …) alongside the Rechenart's existing bare icon - Also picked up and fixed a latent, unrelated bug the audit surfaced along the way: the option/route/icon mapping in the existing dropdown Rechenarten relied on array position matching an item's stored ID purely by coincidence — a fragile pattern already sitting one edit away from silently serving the wrong task under the right title. Fixed to select by ID explicitly, before building anything new on top of the old pattern
Lesson for the audience
The feature everyone was waiting for wasn't the risky part today. The risky part was discovering, before writing a line of new code, that the thing meant to host it wasn't built the way it needed to be — and choosing to fix that properly rather than bolt a new option onto old, incompatible plumbing.
Day 21 — Klammern auflösen: the first option, ported and hardened
With the architecture in place, today shipped the actual first new option: practicing sign-flipping brackets — the classic "watch every sign flip when you remove a minus-bracket" skill.
What happened
- The task generator itself already existed as a working prototype built earlier, independent of the app — so the job was porting known-good logic into the new architecture, not designing it from scratch
- Defined a clean three-part content model per option, matching how the app's existing Help / Result / Explainer buttons already work: Help shows the bare step-by-step numbers with no commentary, Explainer shows the same steps with their teaching labels, Result shows just the final answer
- The first real bug: MathJax — the math-rendering engine — silently refused to render a plain HTML color tag sitting inside a math expression. Switched to MathJax's own color command instead, confirmed empirically before committing to it, rather than guessing
- The second, subtler bug: that color command didn't reliably close its own scope in the rendering engine actually used in production — once one span turned red, everything typeset afterward kept inheriting red, regardless of where the closing brace sat in the source. Traced with per-token color inspection, not eyeballing screenshots, and fixed with a different, correctly-scoped color form
- A design correction along the way: labels were sitting below their expression, which read fine in plain text but became genuinely ambiguous once color entered the picture — a colored line could visually look like it belonged to the previous step's label. Switched to label-above-expression, which resolved the ambiguity structurally instead of papering over it with spacing
- A late randomization fix: the generator could occasionally produce two numeric terms sitting directly next to each other (or the same variable twice in a row) — technically correct, but it let a student shortcut past the actual skill being practiced by mentally combining them first. Added a constraint so no two adjacent terms are ever trivially combinable, verified against 3,000 generated tasks with zero violations afterward
Lesson for the audience
"It renders" and "it teaches the right thing" are two different bars. The color bug was a rendering bug. The adjacent-terms bug wasn't a bug at all by the compiler's standard — the math was always correct — it just let students skip the point of the exercise. Both needed catching before either could be called done.
Day 22 — Distributivgesetz and Binomische Formeln: the curriculum, filling in fast
With the pattern proven once, the next two options went in far faster — and surfaced one real lesson about reusing worked examples as a specification.
What happened
- Added Distributivgesetz — distributing a factor into a bracket, and its mirror image, factoring the greatest common factor back out — as two randomly alternating sub-cases within one new option
- Added Binomische Formeln — the three binomial identities,
(a+b)²,(a-b)², and(a+b)(a-b), each with its own worked-out, color-highlighted derivation rather than just stating the formula - Building the Explainer content from hand-written worked examples caught two genuine authoring mistakes before they could ship: one where the color-highlighting rule wasn't actually consistent between two supposedly-identical examples (traced with pixel-level color sampling, not a glance), and a real algebra sign error in one reference derivation —
(1-x)²expanded using a device that accidentally flipped the sign of the squared term. Caught by tracing the algebra step by step rather than trusting that a worked example must be correct because a human wrote it - Also caught, from live browser testing rather than scripted checks alone: a generator could occasionally produce a degenerate task — the same term appearing as both halves of a "spot the common factor" exercise, which defeats the entire point of the question. Fixed with an explicit uniqueness guard, the same instinct as the adjacent-terms fix from the day before
Lesson for the audience
A worked example you write by hand isn't automatically correct just because it looks right — it's exactly as easy to get an algebra sign wrong in a spec as in code, and both get caught the same way: by actually tracing through the arithmetic, not by trusting that it must be fine.
Day 23 — Klammern multiplizieren: the fifth option, and catching errors in the spec itself
The fourth new algebra option shipped today — but the more interesting story is what happened before any code was written: a hand-authored spec that had real mistakes in it, caught before they could get baked into a generator that would repeat them on every single generated task.
What happened
- Added Klammern multiplizieren — multiplying two bracketed binomials,
(a+b)(c+d)— as a fifth option, with two randomly alternating sub-cases: all-positive terms, and terms with mixed or negative signs - Before any implementation, the worked-example spec itself went through two rounds of review. First pass found a straightforward copy-paste slip: one example's explanation still referenced letters from an earlier example that didn't actually appear in its own numbers. Fixed, but the second pass caught something more substantial — a case that multiplies two negative terms together (
-3 · -4 = +12) had no rule in its own explanation covering that sign combination, even though the final answer depended on it. A student working through that example would have hit a+with nothing in the text explaining where it came from - Fixed by extending the sign-rule sentence — but only for the one sign combination that actually needs the third clause ("minus times minus gives plus"); the other two combinations never produce two negatives multiplying together, so their explanation correctly stays at two clauses instead of three
- Implementation reused this session's now-established term model — a small independent pattern check confirmed that cross-variable products (like
(a+b)(c+d) → ac + ad + bc + bd, where nothing combines because all four letters differ) were intentional, not a bug to avoid, distinct from same-variable cases that do combine like terms - Verified both sub-cases on the preview deployment before merging to production, same as every option before it
Lesson for the audience
A worked example is a spec, and specs get proofread the same way code does — by tracing through the actual logic, not by trusting that a human wrote it carefully the first time. Catching a missing rule in a hand-written example, before it became a generator that would reproduce the gap thousands of times over, was worth the extra pass.
What's next
addsub now carries five options — sign-flipping brackets, distribution and factoring, the three binomial formulas, and multiplying two binomials together — each built the same proven way: examples worked by hand, checked twice, then generated and verified against hundreds of tasks before shipping. Together they cover most of the groundwork a student needs before the next real milestone: solving linear equations, where combining, distributing, and factoring terms stop being the exercise itself and start being the tools for isolating a variable.