BPM lower bound dropped 30 -> 5 (engine + ramp + slave-clock-in interval filter; pure clamp choice, no engine reason for the higher floor). Very slow practice is now possible. Sub-musical (<5) sits below the slave-decay timeout so wasn't worth pursuing. Hamburger menu (☰ at the far right of the header, 3 thin recolorable rects; tap zone covers the corner). Reuses the existing overlay / _ovbtns pattern - no new framework. - Main menu (_show_menu): Save edits / Revert edits (dimmed when not _dirty) / Continue on-off (live) / Settings > / Help > / About / Done. - Settings sub-modal: LED brightness 5..50% in 5% steps, Speaker mode (Auto / Always / Off, combining MUTE_SPEAKER + SPEAKER_AUTO_MUTE), MIDI Out on/off, MIDI Channel 1..16, Clock Out on/off, Clock In on/off. < value > adjusters reusing the lane-editor row pattern. Each tap calls _save_settings(); the modal redraws live. - Help sub-modal: 3 paginated pages (Transport & Nav / Editing / Status & Hardware) with < Done > nav. - About sub-modal: version, free RAM, uptime, CircuitPython version, site URL. Defensive about gc.mem_free and sys.implementation (CircuitPython-specific). - Persistence to /settings.json: read in __init__ (_load_settings overrides defaults), written on every change (settings are small + infrequent). NAKs silently if read-only. Verified in the harness: all 4 modals render, settings.json round-trips (channel 10->11, clock_out off->on persisted), tap zones populate as expected. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
114 KiB
114 KiB