@@ -89,7 +89,9 @@ document.addEventListener('DOMContentLoaded', function() {
8989 this . appendChild ( ripple ) ;
9090
9191 setTimeout ( ( ) => {
92- ripple . remove ( ) ;
92+ if ( ripple . parentNode ) {
93+ ripple . remove ( ) ;
94+ }
9395 } , 600 ) ;
9496 } ) ;
9597 } ) ;
@@ -169,7 +171,9 @@ document.addEventListener('DOMContentLoaded', function() {
169171 document . body . appendChild ( trail ) ;
170172
171173 setTimeout ( ( ) => {
172- trail . remove ( ) ;
174+ if ( trail . parentNode ) {
175+ trail . remove ( ) ;
176+ }
173177 } , 800 ) ;
174178 }
175179
@@ -197,7 +201,9 @@ document.addEventListener('DOMContentLoaded', function() {
197201 }
198202
199203 setTimeout ( ( ) => {
200- particleContainer . remove ( ) ;
204+ if ( particleContainer . parentNode ) {
205+ particleContainer . remove ( ) ;
206+ }
201207 } , 1500 ) ;
202208 }
203209
@@ -237,7 +243,11 @@ document.addEventListener('DOMContentLoaded', function() {
237243 particle . style . animation = 'particleFloat 3s ease-out forwards' ;
238244 document . body . appendChild ( particle ) ;
239245
240- setTimeout ( ( ) => particle . remove ( ) , 3000 ) ;
246+ setTimeout ( ( ) => {
247+ if ( particle . parentNode ) {
248+ particle . remove ( ) ;
249+ }
250+ } , 3000 ) ;
241251 } , i * 50 ) ;
242252 }
243253
@@ -263,7 +273,7 @@ document.addEventListener('DOMContentLoaded', function() {
263273 ` ) ;
264274} ) ;
265275
266- // CSS for ripple effect
276+ // CSS for ripple effect and animations
267277const style = document . createElement ( 'style' ) ;
268278style . textContent = `
269279 .btn {
@@ -280,33 +290,54 @@ style.textContent = `
280290 pointer-events: none;
281291 }
282292
283- // Initialize typing animation for hero subtitle
284- function initTypewriter() {
285- const typewriterElement = document.getElementById('typewriter');
286- if (!typewriterElement) return;
287-
288- // Get the title from the data attribute or fallback
289- const text = typewriterElement.getAttribute('data-text') || "Senior Cloud Engineer & Cloud Native Competency Lead";
290-
291- // Set initial state
292- typewriterElement.textContent = '';
293- typewriterElement.style.width = '0';
294-
295- // Add typing class after a short delay to prevent layout shift
296- setTimeout(() => {
297- typewriterElement.textContent = text;
298- typewriterElement.classList.add('typing');
299- }, 1000);
300- }
301-
302- // Initialize typewriter effect
303- initTypewriter();
304-
305293 @keyframes ripple-animation {
306294 to {
307295 transform: scale(4);
308296 opacity: 0;
309297 }
310298 }
299+
300+ @keyframes particleFloat {
301+ to {
302+ transform: translateY(-100px);
303+ opacity: 0;
304+ }
305+ }
306+
307+ .cursor-trail {
308+ position: fixed;
309+ width: 6px;
310+ height: 6px;
311+ background: var(--gold-primary);
312+ border-radius: 50%;
313+ pointer-events: none;
314+ z-index: 9999;
315+ animation: trailFade 0.8s ease-out forwards;
316+ }
317+
318+ @keyframes trailFade {
319+ to {
320+ opacity: 0;
321+ transform: scale(0);
322+ }
323+ }
324+
325+ .particle {
326+ position: absolute;
327+ width: 3px;
328+ height: 3px;
329+ background: var(--gold-primary);
330+ border-radius: 50%;
331+ animation: particleFloat 1.5s ease-out forwards;
332+ }
333+
334+ .konami-activated {
335+ animation: rainbow 2s linear infinite;
336+ }
337+
338+ @keyframes rainbow {
339+ 0% { filter: hue-rotate(0deg); }
340+ 100% { filter: hue-rotate(360deg); }
341+ }
311342` ;
312343document . head . appendChild ( style ) ;
0 commit comments