- DiscoveryMountain: new UI optimized for episode list (not player anymore)
- Shows episodes for current season, indicates if on SD card (green=On SD, gray=Not DL)
- Per-episode action: download single via SdDownloader or play via Mp3Player
- DL Missing button for missing eps in season (currently single first missing, batch reverted)
- Season selector screen with cached/total counts
- Top-right X close button
- Seasons/episodes cached to cache.json to avoid network fetch every launch
- Fixes: overlay deletion race (deferred timer), ui_timer leak causing crash on close, season selection overwritten by fetch task
- Fixes: unicode ellipsis squares
- SdDownloader: revert to stable single-file mode (batch array caused crashes)
- Remove batch fields and array allocation, keep single url/path download
- Result bundle simple success/path/bytes
- Mp3Player: add resume position support (pos_sec from bundle, total_sec estimate, total_decoded_samples), return position on exit via bundle for DM to save
Tested on 192.168.68.133: opens, shows S10 2/6, Play/DL buttons, close works, no crash on open/close cycles, cache shows 'Loaded from cache, refreshing...'
- Mp3Player: sdk 0.7->0.8.0-dev, find audio-stream device, open_output with resampler (hz/ch), write via audio_stream_write, close on pause
- BookPlayer: close/open per format change via AudioStreamConfig, write via stream
- VoiceRecorder: input_handle open_input 16k/mono via audio_stream_read, output_handle open_output file rate via write/resampler
- ES8311 native 44100, old direct I2S at 16k caused 4.096MHz MCLK vs 11.29MHz -> fast playback
- Brick game correct because it uses audio-stream resampler path
- Mp3Player: increase task stack 4096->6144, prio 5->6, remove taskYIELD causing audio gaps
- VoiceRecorder: configure I2S as stereo for ES7210 (dual mic) like working MicroPython,
then downmix left channel to mono WAV to fix low-pitch mic-like recording