Adds a ringtoneId setting (classic | chime | soft | retro | none) so the
incoming-call ring is no longer hardcoded to call.ogg. The three synth
styles are generated in-browser via a new utils/ringtones.ts module
(mirroring the existing callSounds.ts WebAudio pattern), so no new binary
assets are bundled; 'classic' keeps the existing call.ogg clip and 'none'
is a silent, visual-only incoming-call UI.
- ringtones.ts: startRingtone() loops until stopped; previewRingtone()
plays a single non-looping preview and auto-cancels the prior preview.
- IncomingCall: ring driven by the setting; <audio> element removed.
- Settings > Calls: Ringtone selector with on-select preview, beside the
existing Ringtone Volume slider.
- settings.ts: persisted value whitelisted back to a known id.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>