4a87588435
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>