// Small offline Web Audio cues: no network or audio-file dependency. export class CasualAudio { constructor(host,storage,key){this.host=host;this.storage=storage;this.key=key;this.context=null;this.lastEvent=null;this.lastAt={};try{this.enabled=storage.getItem(key)!=='off';}catch{this.enabled=true;}} unlock(){if(!this.enabled)return false;try{const Audio=this.host.AudioContext||this.host.webkitAudioContext;if(!Audio)return false;if(!this.context)this.context=new Audio();if(this.context.state==='suspended')this.context.resume()?.catch(()=>{});return true;}catch{return false;}} toggle(){this.enabled=!this.enabled;try{this.storage.setItem(this.key,this.enabled?'on':'off');}catch{}if(this.enabled)this.unlock();return this.enabled;} play(kind,delay=0,step=1){if(!this.unlock())return;const ctx=this.context,now=ctx.currentTime;const gap=kind==='error'?.18:0;if(this.lastAt[kind]!==undefined&&now-this.lastAt[kind]{osc.disconnect();gain.disconnect();};osc.start(start);osc.stop(start+duration+.015);}catch{}} } }