@@ -299,23 +299,23 @@ function playSound(type) {
299299 else if ( type === 'levelUp' ) {
300300 osc . type = 'square' ;
301301 osc . frequency . setValueAtTime ( 440 , now ) ;
302- osc . frequency . exponentialRampToValueAtTime ( 880 , now + 0.2 ) ;
302+ osc . frequency . exponentialRampToValueAtTime ( 880 , now + 0.4 ) ;
303303 gain . gain . setValueAtTime ( 0.15 , now ) ;
304- gain . gain . exponentialRampToValueAtTime ( 0.01 , now + 0.4 ) ;
304+ gain . gain . exponentialRampToValueAtTime ( 0.01 , now + 1.0 ) ;
305305 osc . start ( now ) ;
306- osc . stop ( now + 0.4 ) ;
306+ osc . stop ( now + 1.5 ) ;
307307 }
308308 else if ( type === 'secret' ) {
309309 osc . type = 'triangle' ;
310310 [ 523.25 , 659.25 , 783.99 , 1046.50 ] . forEach ( ( freq , i ) => {
311311 const s = audioCtx . createOscillator ( ) ;
312312 const g = audioCtx . createGain ( ) ;
313313 s . connect ( g ) ; g . connect ( audioCtx . destination ) ;
314- s . frequency . setValueAtTime ( freq , now + i * 0.1 ) ;
315- g . gain . setValueAtTime ( 0.07 , now + i * 0.1 ) ;
316- g . gain . exponentialRampToValueAtTime ( 0.01 , now + i * 0.1 + 0.1 ) ;
317- s . start ( now + i * 0.1 ) ;
318- s . stop ( now + i * 0.1 + 0.1 ) ;
314+ s . frequency . setValueAtTime ( freq , now + i * 0.3 ) ;
315+ g . gain . setValueAtTime ( 0.07 , now + i * 0.3 ) ;
316+ g . gain . exponentialRampToValueAtTime ( 0.01 , now + i * 0.3 + 0.3 ) ;
317+ s . start ( now + i * 0.3 ) ;
318+ s . stop ( now + i * 0.3 + 0.3 ) ;
319319 } ) ;
320320 }
321321 else if ( type === 'restore' ) {
@@ -655,6 +655,7 @@ function triggerSecretUnlock(type) {
655655
656656 // 3. Only process XP and Save if it's the first time
657657 if ( isNewUnlock ) {
658+ playSound ( 'secret' ) ;
658659 // Update the array and save to localStorage
659660 unlockedEggs . push ( eggId ) ;
660661 localStorage . setItem ( 'unlockedEggs' , JSON . stringify ( unlockedEggs ) ) ;
@@ -670,6 +671,7 @@ function triggerSecretUnlock(type) {
670671
671672 console . log ( `✨ Secret Unlocked: ${ eggId } ` ) ;
672673 } else {
674+ playSound ( 'click' ) ;
673675 console . log ( `Secret ${ eggId } already discovered. No extra XP granted.` ) ;
674676 }
675677}
@@ -682,13 +684,31 @@ window.addEventListener('keydown', (e) => {
682684 if ( e . target . tagName === 'INPUT' || e . target . tagName === 'TEXTAREA' ) return ;
683685
684686 if ( key === 'd' ) {
685- const devPanel = document . getElementById ( 'dev-tools' ) ;
686- if ( devPanel ) {
687- const isHidden = devPanel . classList . toggle ( 'hidden' ) ;
688- localStorage . setItem ( 'devToolsVisible' , ! isHidden ) ;
689- playSound ( isHidden ? 'click' : 'secret' ) ;
687+ e . preventDefault ( ) ;
688+
689+ const systemDash = document . getElementById ( 'dev-tools' ) ; // Adjust ID as needed
690+ const isOpening = systemDash . classList . contains ( 'hidden' ) ;
691+
692+ localStorage . setItem ( 'devToolsVisible' , ! isOpening ) ;
693+ playSound ( isOpening ? 'secret' : 'click' ) ;
694+
695+ if ( isOpening ) {
696+
697+ document . getElementById ( 'matrix-console-container' ) . classList . add ( 'hidden' ) ;
698+ systemDash . classList . remove ( 'hidden' ) ;
699+
700+ // Wait 100-150ms for the animation/display to settle
701+ setTimeout ( ( ) => {
702+ // Find the first interactive element (button or link)
703+ const firstControl = systemDash . querySelector ( 'button, a, input' ) ;
704+ if ( firstControl ) {
705+ firstControl . focus ( ) ;
706+ }
707+ } , 150 ) ;
708+ } else {
709+ systemDash . classList . add ( 'hidden' ) ;
710+ document . body . focus ( ) ; // Return focus to the page
690711 }
691- return ;
692712 }
693713
694714 if ( key === konamiCode [ konamiPosition ] ) {
@@ -703,13 +723,12 @@ window.addEventListener('keydown', (e) => {
703723} ) ;
704724
705725function activateKonami ( ) {
706- playSound ( 'secret' ) ;
707726 document . documentElement . classList . add ( 'konami-roll' ) ;
708727 setTimeout ( ( ) => document . documentElement . classList . remove ( 'konami-roll' ) , 2000 ) ;
709728}
710729
711730function activateGravityEffect ( ) {
712- playSound ( 'secret' ) ;
731+
713732 document . body . classList . add ( 'glitch-shake' ) ;
714733
715734 setTimeout ( ( ) => {
@@ -803,6 +822,41 @@ function closeMatrix() {
803822 window . removeEventListener ( 'keydown' , handleMatrixEsc ) ;
804823}
805824
825+
826+ let hasTriggeredFirstLevel = false ; // Prevents the sound from spamming every click
827+
828+ function triggerBadgeLevelUp ( ) {
829+ const badge = document . getElementById ( 'level-badge' ) ;
830+
831+ // 1. Visual Pop Animation
832+ if ( badge ) {
833+ badge . classList . remove ( 'animate-badge-pop' ) ;
834+ void badge . offsetWidth ; // Force reflow to restart animation
835+ badge . classList . add ( 'animate-badge-pop' ) ;
836+ }
837+
838+ // 2. Secret Sound & Level Logic
839+ if ( ! hasTriggeredFirstLevel ) {
840+ // Play your secret sound
841+ playSound ( 'secret' ) ;
842+
843+ // Force a level up for the "first time" experience
844+ addExperience ( 45 ) ; // Assuming 45 XP = 1 Level
845+
846+ hasTriggeredFirstLevel = true ;
847+
848+ // Push a special "Easter Egg" message to the Matrix Console
849+ if ( typeof matrixConsoleLog === 'function' ) {
850+ matrixConsoleLog ( currentLevel ) ;
851+ }
852+ }
853+ }
854+
855+ // Attach to the badge click
856+ document . getElementById ( 'level-badge' ) . addEventListener ( 'click' , triggerBadgeLevelUp ) ;
857+
858+
859+
806860/**
807861 * 7. SELF DESTRUCT ENGINE
808862 */
0 commit comments