interval configurator backports
Created by: jedmund
Extends the configurator + layout polish from Interval Comparison (#29) to Interval Trainer and Interval Classifier so all three scored-interval playgrounds share the same shape.
Interval Trainer
- New config fields: `progressiveIntervals`, `progressionThreshold`, `choiceCount` (all optional). Lesson-authored `progressiveAdditions` continues to work; playground uses `progressiveIntervals`.
- Side panel: vertical interval checklist (full names, None header button), Progressive difficulty toggle, Choices segmented picker (2/3/4/6), Total questions stepper (6-20, step 2).
- Per-prompt foil selection: the (N-1) semitonally-nearest intervals to the target, skipping enharmonic duplicates. Progressive unlocks more intervals, which naturally tightens foil distance.
- `lastTargetKey` dedup: targets never repeat back-to-back.
- Feedback now two centered lines:
- correct: "You're right! That was a Interval" / "N semitones ranging from Note A to Note B"
- incorrect: "That was a Interval" / "N semitones ranging from Note A to Note B"
Interval Classifier
- Optional `totalQuestions` cap in the config; exercise shuffles and truncates.
- Side panel: Octaves segmented picker (1/2/3), Total questions stepper (4-20), Shuffle toggle.
- Builder transposes the 10 base C4-octave prompts up by N octaves for 2 and 3, spanning C4-C7 max. Explanations carry over (they reference pitch classes, not octaves) and now bold the note names with Unicode ♯/♭.
Shared polish (all three exercises)
- Fixed 320pt card height with title pinned to top and Next button anchored to bottom.
- Next button shrunk to footnote font + 6pt vertical padding.
- Standalone JSONs for Trainer and Classifier deleted — params drive both. Lesson JSON paths untouched.
- Side panel renders for all three interval exercises, not just Comparison. `configVersion` bumps on any param change keep the card reactive without Reset/Restart.
Test plan
-
Interval Trainer standalone: side panel shows all 15 intervals selected, Progressive off, Choices 4, Total 8. Picker renders as 2×2. Pick 6 → 2×3. Pick 2/3 → single row. -
Trainer Progressive on: first prompt uses only easiest 3 intervals. After 3 correct total, 4th interval unlocks. No consecutive-duplicate targets. -
Trainer feedback text matches spec (two lines, accent + secondary, no trailing period). -
Interval Classifier standalone: side panel shows Octaves 1, Total 8, Shuffle on. Bump Octaves to 2 → prompts now include C5-based patterns. Bump to 3 → C6 patterns. -
Classifier feedback bolds note names (e.g. "C to D♭ is one key apart"). -
Lesson paths for all three exercises unchanged (interval-classifier.json lessons, interval_trainer with progressiveAdditions, interval_comparison pairs). -
All three cards are 320pt tall with consistent title-top / button-bottom layout.