/* ========================================================================== ELEGANT AUDIO SYNTHESIZER (WEB AUDIO API) ========================================================================== */ class SoundEffects { constructor() { this.ctx = null; this.enabled = true; } init() { if (!this.ctx) { const AudioCtx = window.AudioContext || window.webkitAudioContext; if (AudioCtx) { this.ctx = new AudioCtx(); } } if (this.ctx && this.ctx.state === 'suspended') { this.ctx.resume(); } } playTick() { if (!this.enabled) return; this.init(); if (!this.ctx) return; try { const osc = this.ctx.createOscillator(); const gain = this.ctx.createGain(); osc.type = 'sine'; // Low subtle tick osc.frequency.setValueAtTime(600, this.ctx.currentTime); osc.frequency.exponentialRampToValueAtTime(1200, this.ctx.currentTime + 0.03); gain.gain.setValueAtTime(0.04, this.ctx.currentTime); gain.gain.exponentialRampToValueAtTime(0.001, this.ctx.currentTime + 0.03); osc.connect(gain); gain.connect(this.ctx.destination); osc.start(); osc.stop(this.ctx.currentTime + 0.035); } catch (e) { // Audio context edge cases } } playReveal() { if (!this.enabled) return; this.init(); if (!this.ctx) return; try { const now = this.ctx.currentTime; const osc = this.ctx.createOscillator(); const gain = this.ctx.createGain(); osc.type = 'triangle'; osc.frequency.setValueAtTime(440, now); osc.frequency.exponentialRampToValueAtTime(880, now + 0.12); gain.gain.setValueAtTime(0.08, now); gain.gain.exponentialRampToValueAtTime(0.001, now + 0.12); osc.connect(gain); gain.connect(this.ctx.destination); osc.start(now); osc.stop(now + 0.13); } catch (e) {} } playFanfare() { if (!this.enabled) return; this.init(); if (!this.ctx) return; try { const now = this.ctx.currentTime; // Elegant Glass Chimes chord: C5, E5, G5, C6 const freqs = [523.25, 659.25, 783.99, 1046.50]; freqs.forEach((f, idx) => { const osc = this.ctx.createOscillator(); const gain = this.ctx.createGain(); osc.type = 'sine'; osc.frequency.setValueAtTime(f, now + idx * 0.04); gain.gain.setValueAtTime(0.06, now + idx * 0.04); gain.gain.exponentialRampToValueAtTime(0.001, now + idx * 0.04 + 0.5); osc.connect(gain); gain.connect(this.ctx.destination); osc.start(now + idx * 0.04); osc.stop(now + idx * 0.04 + 0.55); }); } catch (e) {} } } window.soundEffects = new SoundEffects();