useGameLogic's own scheduler and the footer widget's scheduler both
played audible clicks while rhythm.active — assist->learn-notes switch
made the second one mount. Now the widget is the single click source in
non-zen modes; useGameLogic's scheduler is a silent tick source for
auto-advance (full sound only in zen mode, where the widget isn't
rendered). Also: widget honors Timer mode (60/seconds) like the trainer,
and useMetronome skips audio nodes at volume 0.
Layout: tuner + metronome now stack vertically everywhere (was phrase-only).
Phrase metronome bug: clicks were gated on rhythm.active, but phrase mode
has no on/off switch (the sync checkbox replaces it) and the default is
active:false — so a synced run stayed silent with no in-mode remedy.
Now: phrase mode is always armed (sync checkbox = free vs synced,
sound checkbox = clicks), and phrase clickSound reads rhythm.sound only.
Single-note modes keep the rhythm.active on/off semantics.
- Pace dropdown REMOVED from Phrase setup — replaced by a 'Sync to
exercise' checkbox in the Metronome widget (analog to 'Auto' in
single-note modes). pace is derived from the checkbox (checked = tempo,
unchecked = step).
- Preview clicks now registered in PREVIEW_GROUP: stopping/abandoning a
preview cancels its scheduled clicks — no more parallel ghost
metronomes after preview->stop->next exercise.
- Chord pool replaces the chord dropdown entirely (single chord AND
sequences): togglable degree list, empty = all 7.
- Giuliani figures corrected to NOTE sequences (p always takes the bass/
root): p-i-m, p-i-m-a, p-a-m-i, a-i-m, p-i-m-a-m-i, p-m-a-m-i-m,
p-e-a-m-a-m (replaced the fingering-driven patterns that made no
musical sense).
- 'Limit notes' is now one bordered section like Tuner/Metronome, with a
header, Clear-all link, and Strings behind a toggle (row hidden until
restricted).
- MetronomeWidget: the Phrase Mode switch now lives IN the widget as a
Free/Sync toggle. Free = independent metronome (own clock, starts when
toggled, with or without clicks). Sync = silent while idle, starts with
the exercise (count-in included), pendulum mirrors the run's beats.
- Fixed double phraseBeatBus.emit (leftover from an earlier edit) that
flipped the pendulum twice per beat — animation appeared frozen.
- Click decision unified: one sound checkbox governs both the widget and
(in sync mode) the run's click scheduler. 'Click 1 after count-in' is
musically the last count-in click (suppressed duplicate) — now with a
working pendulum the offset is visible rather than confusing.
- Giuliani figures extended: p-i-m-a-m-i, p-a-p-i-m-a, a-m-i-p-i-m,
m-i-a-m-i-m (six-note rolling/bass-skip/tremolo-adjacent figures).
- Arpeggio chord pool: togglable degree list (empty = all 7); functional
and random progressions honor the pool; first bar draws a random chord
from the pool.
- Tests 174/174.
- MetronomeWidget rebuilt cleanly: ONE 'Click sound' checkbox (the earlier
restructure left duplicated option rows behind — neither worked). Widget
body always visible (dimmed when disarmed); toggle arms sound+pendulum.
- Click decision unified: 'sync to metronome' derives phrase clickSound
from the widget's sound checkbox (no separate phrase click option);
'at your pace' clicks when the metronome is armed.
- Chord selection: abwählbare Liste (arpeggioChordSelection) restricts
progression chords; first bar draws a random chord FROM THE SELECTION
(fixed first chord repeated the exercise identically).
- Scales: rhythm setting (quarters/eighths) shared with arpeggios;
drill id includes rhythm to invalidate cached scores.
- Beam fix: register Beam via note.setBeam so VexFlow suppresses flags
(eighths/16ths previously drew BOTH beam and flag).
- Metronome widget: BPM/slider row and pendulum always visible (dimmed
when off); the toggle gates sound + animation only. BPM/Timer mode
switch restored for single-note auto-advance.
- Giuliani right-hand figures as arpeggio patterns: p-i-m, p-i-m-a,
p-a-m-i, m-a-m-i, a-m-i — cycle [root, third, fifth, octave] per figure
with octave register shift per repetition (120-studies feel).
- Pool fix: fretted instruments without active filters now get the full
0-12 fretboard in ALL modes (legacy difficulty ranges no longer clamp
the pool since the Note Set dropdown was removed).
- Tests 174/174.
- Phrase Mode (sync to metronome): the run's scheduler is the single click
source (with count-in); the metronome widget is muted and its pendulum
mirrors the run's beats via the new phraseBeatBus (audio-timestamp
scheduled). No more double clicks; clicks only while the run is active
(phraseRunBus gates the widget's own ticking).
- Schedule entries now carry continuous beat index + accent flag (downbeats
accented, count-in beat 1 accented).
- 'At your pace': optional click via the metronome toggle (kept explicit).
- Metronome widget: gate prop; in gated mode it listens to the beat bus
instead of running its own scheduler.
- Note Set dropdown and custom-fret Fret Range inputs removed from Controls:
the unified target-note filter (strings + fret window + key) fully
supersedes them; difficulty stays as internal default (clef/transpose
resolution) but is no longer user-facing.
- Pendulum: drop the beat-parity key that remounted the dot each beat
(killed the CSS transition); the same element now glides left<->right.
- Strings filter: per-string toggle buttons (replaces fret-window-only
semantics as a third 'limits notes' control); combines with fret window
and key filter in targetPool (fretted instruments).
- Key sync checkbox: display key signature can follow the target key
(major/minor mapping), default off — both remain independently settable.
- LiveNoteStaff: optional fixed clef — guitar/bass now keep their usual
clef instead of flipping at middle C; octave markers handle range.
- Unified metronome widget (MetronomeWidget) with animated linear pendulum
synced to the audible click; shown in ALL modes next to the tuner.
Phrase BPM now reads from settings.rhythm.bpm (single source); the
phrase-local BPM control was removed from the setup panel.
- Tests: 160/160; tsc + eslint clean; build ok.