@@ -101,53 +101,78 @@ var projectCards = [];
101101var recentSearches = JSON . parse ( localStorage . getItem ( "recentSearches" ) || "[]" ) ;
102102
103103// ============================================
104- // INFO MODAL FUNCTIONS
104+ // INFO MODAL FUNCTIONS - FIXED
105105// ============================================
106106
107107function showInfoModal ( title , steps ) {
108108 var overlay = document . getElementById ( "infoModalOverlay" ) ;
109109 var titleEl = document . getElementById ( "infoModalTitle" ) ;
110110 var listEl = document . getElementById ( "infoModalList" ) ;
111+ var closeBtn = document . getElementById ( "infoModalClose" ) ;
112+ var gotItBtn = document . getElementById ( "infoModalGotIt" ) ;
111113
112114 if ( ! overlay || ! titleEl || ! listEl ) return ;
113115
114116 titleEl . textContent = title ;
115- listEl . innerHTML = "" ; // Safely clear the existing list
117+ listEl . innerHTML = "" ;
116118 steps . forEach ( function ( step ) {
117119 const li = document . createElement ( "li" ) ;
118- li . textContent = step ; // textContent automatically escapes malicious scripts!
120+ li . textContent = step ;
119121 listEl . appendChild ( li ) ;
120122 } ) ;
121123
122- const toggleBackToTopButton = ( ) => {
123- if ( ! backToTopButton ) return ;
124- backToTopButton . classList . toggle ( 'visible' , window . scrollY > 300 ) ;
125- } ;
124+ // Show modal
125+ overlay . style . display = 'flex' ;
126+ overlay . style . visibility = 'visible' ;
127+ overlay . style . opacity = '1' ;
126128 overlay . classList . add ( "active" ) ;
129+ overlay . setAttribute ( 'aria-hidden' , 'false' ) ;
127130
128131 function closeModal ( ) {
132+ overlay . style . display = 'none' ;
133+ overlay . style . visibility = 'hidden' ;
134+ overlay . style . opacity = '0' ;
129135 overlay . classList . remove ( "active" ) ;
130- closeBtn . removeEventListener ( "click" , closeModal ) ;
131- gotItBtn . removeEventListener ( "click" , closeModal ) ;
136+ overlay . setAttribute ( 'aria-hidden' , 'true' ) ;
137+ // Clean up event listeners
138+ if ( closeBtn ) closeBtn . removeEventListener ( "click" , closeModal ) ;
139+ if ( gotItBtn ) gotItBtn . removeEventListener ( "click" , closeModal ) ;
132140 overlay . removeEventListener ( "click" , overlayClick ) ;
141+ document . removeEventListener ( "keydown" , escapeHandler ) ;
133142 }
134143
135- if ( backToTopButton ) {
136- backToTopButton . addEventListener ( 'click' , ( ) => {
137- const prefersReducedMotion = window . matchMedia ( '(prefers-reduced-motion: reduce)' ) . matches ;
138- window . scrollTo ( { top : 0 , behavior : prefersReducedMotion ? 'auto' : 'smooth' } ) ;
139- } ) ;
140- }
141144 function overlayClick ( e ) {
142145 if ( e . target === overlay ) closeModal ( ) ;
143146 }
144147
145- var closeBtn = document . getElementById ( "infoModalClose" ) ;
146- var gotItBtn = document . getElementById ( "infoModalGotIt" ) ;
148+ function escapeHandler ( e ) {
149+ if ( e . key === 'Escape' ) closeModal ( ) ;
150+ }
151+
152+ // Add event listeners
153+ if ( closeBtn ) {
154+ // Remove old listeners by cloning
155+ const newClose = closeBtn . cloneNode ( true ) ;
156+ closeBtn . parentNode . replaceChild ( newClose , closeBtn ) ;
157+ newClose . addEventListener ( "click" , function ( e ) {
158+ e . preventDefault ( ) ;
159+ e . stopPropagation ( ) ;
160+ closeModal ( ) ;
161+ } ) ;
162+ }
163+
164+ if ( gotItBtn ) {
165+ const newGotIt = gotItBtn . cloneNode ( true ) ;
166+ gotItBtn . parentNode . replaceChild ( newGotIt , gotItBtn ) ;
167+ newGotIt . addEventListener ( "click" , function ( e ) {
168+ e . preventDefault ( ) ;
169+ e . stopPropagation ( ) ;
170+ closeModal ( ) ;
171+ } ) ;
172+ }
147173
148- closeBtn . addEventListener ( "click" , closeModal ) ;
149- gotItBtn . addEventListener ( "click" , closeModal ) ;
150174 overlay . addEventListener ( "click" , overlayClick ) ;
175+ document . addEventListener ( "keydown" , escapeHandler ) ;
151176}
152177
153178// Themed confirmation modal (in-page) helper
0 commit comments