@@ -369,17 +369,82 @@ function updateThemeIcon(theme) {
369369/**
370370 * 5. EASTER EGG LOGIC & TRIGGERS
371371 */
372- function triggerForceSurge ( ) {
373- if ( isSurging ) return ; // Prevent overlapping surges
372+ function playForceSoundtrack ( duration = 8000 ) {
373+ initAudio ( ) ;
374+ if ( ! audioCtx ) return ;
375+
376+ // 1. Create a Master Compressor to prevent distortion
377+ const compressor = audioCtx . createDynamicsCompressor ( ) ;
378+ compressor . threshold . setValueAtTime ( - 24 , audioCtx . currentTime ) ;
379+ compressor . knee . setValueAtTime ( 40 , audioCtx . currentTime ) ;
380+ compressor . ratio . setValueAtTime ( 12 , audioCtx . currentTime ) ;
381+ compressor . attack . setValueAtTime ( 0 , audioCtx . currentTime ) ;
382+ compressor . release . setValueAtTime ( 0.25 , audioCtx . currentTime ) ;
383+ compressor . connect ( audioCtx . destination ) ;
384+
385+ const now = audioCtx . currentTime ;
386+ const masterGain = audioCtx . createGain ( ) ;
387+ masterGain . connect ( compressor ) ;
388+
389+ // Smooth volume swell
390+ masterGain . gain . setValueAtTime ( 0 , now ) ;
391+ masterGain . gain . linearRampToValueAtTime ( 0.6 , now + 1.5 ) ;
392+ masterGain . gain . setValueAtTime ( 0.6 , now + duration / 1000 - 2 ) ;
393+ masterGain . gain . exponentialRampToValueAtTime ( 0.001 , now + duration / 1000 ) ;
394+
395+ // Create the "Harmonic Stack" (Multiple notes for a rich sound)
396+ [ 55 , 110 , 164.81 ] . forEach ( ( freq , i ) => {
397+ const osc = audioCtx . createOscillator ( ) ;
398+ osc . type = i === 0 ? "sawtooth" : "triangle" ; // Mix textures
399+ osc . frequency . setValueAtTime ( freq , now ) ;
400+
401+ // Add a slight "wobble" (detune) for realism
402+ osc . detune . setValueAtTime ( i * 5 , now ) ;
374403
404+ osc . connect ( masterGain ) ;
405+ osc . start ( now ) ;
406+ osc . stop ( now + duration / 1000 ) ;
407+ } ) ;
408+ }
409+
410+ function triggerForceSurge ( ) {
411+ if ( isSurging ) return ;
375412 isSurging = true ;
376- initAudio ( ) ;
377- addExperience ( 1000 ) ;
378413
379- // Reset after the animation duration (e.g., 1 second)
414+ // 1. Audio
415+ playForceSoundtrack ( 8000 ) ;
416+
417+ // 2. Add Overlay
418+ const overlay = document . createElement ( "div" ) ;
419+ overlay . className = "force-field-overlay" ;
420+ document . body . appendChild ( overlay ) ;
421+
422+ // 3. Lightning Bolts (Flash every 1.5 seconds)
423+ const flash = document . createElement ( "div" ) ;
424+ flash . className = "lightning-flash" ;
425+ document . body . appendChild ( flash ) ;
426+
427+ const boltInterval = setInterval ( ( ) => {
428+ flash . style . animation = "none" ;
429+ void flash . offsetWidth ; // Reset animation
430+ flash . style . animation = "bolt 0.4s ease-out" ;
431+ } , 1800 ) ;
432+
433+ // 4. XP Logic
434+ let currentXPAdded = 0 ;
435+ const xpInt = setInterval ( ( ) => {
436+ addExperience ( 10 ) ;
437+ currentXPAdded += 10 ;
438+ if ( currentXPAdded >= 1000 ) clearInterval ( xpInt ) ;
439+ } , 50 ) ;
440+
441+ // 5. Cleanup
380442 setTimeout ( ( ) => {
443+ clearInterval ( boltInterval ) ;
444+ overlay . remove ( ) ;
445+ flash . remove ( ) ;
381446 isSurging = false ;
382- } , 10000 ) ;
447+ } , 8000 ) ;
383448}
384449
385450function triggerMagicXP ( ) {
0 commit comments