Add favicon images, site manifest, and update logo references in HTML and CSS
This commit is contained in:
		
							parent
							
								
									bc36232b45
								
							
						
					
					
						commit
						236e64a2cc
					
				
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 24 KiB | 
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 228 KiB | 
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 22 KiB | 
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 371 B | 
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 927 B | 
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 15 KiB | 
|  | @ -0,0 +1 @@ | ||||||
|  | {"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} | ||||||
							
								
								
									
										29
									
								
								index.html
								
								
								
								
							
							
						
						
									
										29
									
								
								index.html
								
								
								
								
							|  | @ -12,13 +12,20 @@ | ||||||
|     <meta property="og:title" content="Daniel LaForce | Infrastructure & Systems Architect"> |     <meta property="og:title" content="Daniel LaForce | Infrastructure & Systems Architect"> | ||||||
|     <meta property="og:description" content="Expert in infrastructure architecture, DevOps automation, and secure cloud migrations. View my live lab dashboard and projects."> |     <meta property="og:description" content="Expert in infrastructure architecture, DevOps automation, and secure cloud migrations. View my live lab dashboard and projects."> | ||||||
|     <meta property="og:type" content="website"> |     <meta property="og:type" content="website"> | ||||||
|     <meta property="og:url" content="https://argobox.com"> |     <meta property="og:url" content="https://laforceit.com"> | ||||||
|      |      | ||||||
|     <!-- Favicon --> |     <!-- Favicon --> | ||||||
|     <link rel="icon" href="images/favicon.ico" type="image/x-icon"> |     <link rel="icon" type="image/x-icon" href="images/favicon.ico"> | ||||||
|  |     <link rel="icon" type="image/png" sizes="32x32" href="images/favicon-32x32.png"> | ||||||
|  |     <link rel="icon" type="image/png" sizes="16x16" href="images/favicon-16x16.png"> | ||||||
|  |     <link rel="apple-touch-icon" href="images/apple-touch-icon.png"> | ||||||
|  |     <link rel="manifest" href="images/site.webmanifest"> | ||||||
|  |     <link rel="icon" type="image/png" sizes="192x192" href="images/android-chrome-192x192.png"> | ||||||
|  |     <link rel="icon" type="image/png" sizes="512x512" href="images/android-chrome-512x512.png"> | ||||||
|      |      | ||||||
|     <!-- CSS --> |     <!-- CSS --> | ||||||
|     <link rel="stylesheet" href="styles.css"> |     <link rel="stylesheet" href="styles.css"> | ||||||
|  |     <link rel="stylesheet" href="test-styles.css"> | ||||||
|      |      | ||||||
|     <!-- Font Awesome --> |     <!-- Font Awesome --> | ||||||
|     <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css"> |     <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css"> | ||||||
|  | @ -34,7 +41,7 @@ | ||||||
|         <div class="container"> |         <div class="container"> | ||||||
|             <div class="logo"> |             <div class="logo"> | ||||||
|                 <a href="#home"> |                 <a href="#home"> | ||||||
|                     <span class="logo-text">Argobox</span> |                     <span class="logo-text">LaForceIT</span> | ||||||
|                     <span class="logo-dot">.com</span> |                     <span class="logo-dot">.com</span> | ||||||
|                 </a> |                 </a> | ||||||
|             </div> |             </div> | ||||||
|  | @ -47,7 +54,7 @@ | ||||||
|                 <a href="#contact" class="nav-link">Contact</a> |                 <a href="#contact" class="nav-link">Contact</a> | ||||||
|             </div> |             </div> | ||||||
|             <div class="nav-buttons"> |             <div class="nav-buttons"> | ||||||
|                 <a href="dashboard.html" class="dashboard-link" target="_blank"> |                 <a href="https://argobox.com/dashboard" class="dashboard-link" target="_blank"> | ||||||
|                     <span class="live-indicator"></span> |                     <span class="live-indicator"></span> | ||||||
|                     <span>Live Dashboard</span> |                     <span>Live Dashboard</span> | ||||||
|                 </a> |                 </a> | ||||||
|  | @ -127,7 +134,7 @@ | ||||||
|                     <span class="btn-icon"><i class="fas fa-arrow-right"></i></span> |                     <span class="btn-icon"><i class="fas fa-arrow-right"></i></span> | ||||||
|                 </a> |                 </a> | ||||||
|                  |                  | ||||||
|                 <a href="ansible-sandbox.html" class="btn btn-outline btn-featured" target="_blank"> |                 <a href="https://argobox.com/ansible-sandbox" class="btn btn-outline btn-featured" target="_blank"> | ||||||
|                     <span class="pulse-ring"></span> |                     <span class="pulse-ring"></span> | ||||||
|                     <span class="btn-text">Explore My Lab</span> |                     <span class="btn-text">Explore My Lab</span> | ||||||
|                     <span class="btn-icon"><i class="fas fa-server"></i></span> |                     <span class="btn-icon"><i class="fas fa-server"></i></span> | ||||||
|  | @ -356,13 +363,13 @@ | ||||||
|                     </ul> |                     </ul> | ||||||
|                      |                      | ||||||
|                     <div class="lab-buttons"> |                     <div class="lab-buttons"> | ||||||
|                         <a href="dashboard.html" class="btn btn-primary" target="_blank"> |                         <a href="https://argobox.com/dashboard" class="btn btn-primary" target="_blank"> | ||||||
|                             <span class="flex-center"> |                             <span class="flex-center"> | ||||||
|                                 <span class="live-indicator"></span> |                                 <span class="live-indicator"></span> | ||||||
|                                 <span>View Live Dashboard</span> |                                 <span>View Live Dashboard</span> | ||||||
|                             </span> |                             </span> | ||||||
|                         </a> |                         </a> | ||||||
|                         <a href="ansible-sandbox.html" class="btn btn-outline" target="_blank">Try Ansible Sandbox</a> |                         <a href="https://argobox.com/ansible-sandbox" class="btn btn-outline" target="_blank">Try Ansible Sandbox</a> | ||||||
|                     </div> |                     </div> | ||||||
|                 </div> |                 </div> | ||||||
|                  |                  | ||||||
|  | @ -579,7 +586,7 @@ | ||||||
|                             <i class="fas fa-envelope"></i> |                             <i class="fas fa-envelope"></i> | ||||||
|                         </div> |                         </div> | ||||||
|                         <h3 class="contact-title">Email</h3> |                         <h3 class="contact-title">Email</h3> | ||||||
|                         <p><a href="mailto:daniel.laforce@argobox.com">daniel.laforce@argobox.com</a></p> |                         <p><a href="mailto:daniel@laforceit.com">daniel@laforceit.com</a></p> | ||||||
|                     </div> |                     </div> | ||||||
|                      |                      | ||||||
|                     <div class="contact-item"> |                     <div class="contact-item"> | ||||||
|  | @ -636,7 +643,7 @@ | ||||||
|         <div class="container"> |         <div class="container"> | ||||||
|             <div class="footer-content"> |             <div class="footer-content"> | ||||||
|                 <div class="footer-logo"> |                 <div class="footer-logo"> | ||||||
|                     <span class="logo-text">Argobox</span> |                     <span class="logo-text">LaForceIT</span> | ||||||
|                     <span class="logo-dot">.com</span> |                     <span class="logo-dot">.com</span> | ||||||
|                 </div> |                 </div> | ||||||
|                  |                  | ||||||
|  | @ -651,12 +658,12 @@ | ||||||
|                 <div class="footer-social"> |                 <div class="footer-social"> | ||||||
|                     <a href="https://github.com/keyargo" target="_blank" aria-label="GitHub"><i class="fab fa-github"></i></a> |                     <a href="https://github.com/keyargo" target="_blank" aria-label="GitHub"><i class="fab fa-github"></i></a> | ||||||
|                     <a href="https://www.linkedin.com/in/danlaforce" target="_blank" aria-label="LinkedIn"><i class="fab fa-linkedin"></i></a> |                     <a href="https://www.linkedin.com/in/danlaforce" target="_blank" aria-label="LinkedIn"><i class="fab fa-linkedin"></i></a> | ||||||
|                     <a href="mailto:daniel.laforce@argobox.com" aria-label="Email"><i class="fas fa-envelope"></i></a> |                     <a href="mailto:daniel@laforceit.com" aria-label="Email"><i class="fas fa-envelope"></i></a> | ||||||
|                 </div> |                 </div> | ||||||
|             </div> |             </div> | ||||||
|              |              | ||||||
|             <div class="footer-bottom"> |             <div class="footer-bottom"> | ||||||
|                 <p>© <span id="current-year"></span> All rights reserved. Inovin LLC</p> |                 <p>© <span id="current-year"></span> All rights reserved. LaForce IT Consulting</p> | ||||||
|             </div> |             </div> | ||||||
|         </div> |         </div> | ||||||
|     </footer> |     </footer> | ||||||
|  |  | ||||||
|  | @ -0,0 +1,459 @@ | ||||||
|  | /** | ||||||
|  |  * Main JavaScript file for argobox.com | ||||||
|  |  * Handles animations, interactions, and dynamic content | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | document.addEventListener('DOMContentLoaded', function() { | ||||||
|  |     // Initialize all website functionality
 | ||||||
|  |     initNavigation(); | ||||||
|  |     initParticlesAndIcons(); | ||||||
|  |     initRoleRotation(); | ||||||
|  |     initTerminalTyping(); | ||||||
|  |     initSolutionsCarousel(); | ||||||
|  |     initScrollReveal(); | ||||||
|  |     updateMetrics(); | ||||||
|  |     updateYear(); | ||||||
|  |      | ||||||
|  |     // Initialize form handling
 | ||||||
|  |     const contactForm = document.getElementById('contact-form'); | ||||||
|  |     if (contactForm) { | ||||||
|  |         initFormHandling(contactForm); | ||||||
|  |     } | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Set up navigation functionality - mobile menu and scroll spy | ||||||
|  |  */ | ||||||
|  | function initNavigation() { | ||||||
|  |     // Mobile menu toggle
 | ||||||
|  |     const menuToggle = document.querySelector('.menu-toggle'); | ||||||
|  |     const navMenu = document.querySelector('.nav-menu'); | ||||||
|  |      | ||||||
|  |     if (menuToggle && navMenu) { | ||||||
|  |         menuToggle.addEventListener('click', function() { | ||||||
|  |             navMenu.classList.toggle('active'); | ||||||
|  |             menuToggle.setAttribute('aria-expanded',  | ||||||
|  |                 menuToggle.getAttribute('aria-expanded') === 'true' ? 'false' : 'true'); | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     // Navigation scroll spy
 | ||||||
|  |     const sections = document.querySelectorAll('section[id]'); | ||||||
|  |     const navLinks = document.querySelectorAll('.nav-link'); | ||||||
|  |      | ||||||
|  |     function updateActiveNavLink() { | ||||||
|  |         let scrollPosition = window.scrollY + 100; | ||||||
|  |          | ||||||
|  |         sections.forEach(section => { | ||||||
|  |             const sectionTop = section.offsetTop; | ||||||
|  |             const sectionHeight = section.offsetHeight; | ||||||
|  |             const sectionId = section.getAttribute('id'); | ||||||
|  |              | ||||||
|  |             if (scrollPosition >= sectionTop && scrollPosition < sectionTop + sectionHeight) { | ||||||
|  |                 navLinks.forEach(link => { | ||||||
|  |                     link.classList.remove('active'); | ||||||
|  |                     if (link.getAttribute('href') === `#${sectionId}`) { | ||||||
|  |                         link.classList.add('active'); | ||||||
|  |                     } | ||||||
|  |                 }); | ||||||
|  |             } | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     // Navbar style change on scroll
 | ||||||
|  |     const navbar = document.querySelector('.navbar'); | ||||||
|  |      | ||||||
|  |     function updateNavbarStyle() { | ||||||
|  |         if (window.scrollY > 50) { | ||||||
|  |             navbar?.classList.add('scrolled'); | ||||||
|  |         } else { | ||||||
|  |             navbar?.classList.remove('scrolled'); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     window.addEventListener('scroll', () => { | ||||||
|  |         updateActiveNavLink(); | ||||||
|  |         updateNavbarStyle(); | ||||||
|  |     }); | ||||||
|  |      | ||||||
|  |     // Initial call to set correct states
 | ||||||
|  |     updateActiveNavLink(); | ||||||
|  |     updateNavbarStyle(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Create background particles and floating tech icons | ||||||
|  |  */ | ||||||
|  | function initParticlesAndIcons() { | ||||||
|  |     createBackgroundParticles(); | ||||||
|  |     createFloatingIcons(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Create animated background particles | ||||||
|  |  */ | ||||||
|  | function createBackgroundParticles() { | ||||||
|  |     const particlesContainer = document.getElementById('particles-container'); | ||||||
|  |      | ||||||
|  |     if (!particlesContainer) return; | ||||||
|  |      | ||||||
|  |     particlesContainer.innerHTML = ''; | ||||||
|  |      | ||||||
|  |     for (let i = 0; i < 40; i++) { | ||||||
|  |         const particle = document.createElement('div'); | ||||||
|  |         particle.classList.add('particle'); | ||||||
|  |          | ||||||
|  |         // Random size, opacity, and position
 | ||||||
|  |         const size = Math.random() * 4 + 1; | ||||||
|  |         const opacity = Math.random() * 0.3 + 0.1; | ||||||
|  |          | ||||||
|  |         particle.style.width = `${size}px`; | ||||||
|  |         particle.style.height = `${size}px`; | ||||||
|  |         particle.style.opacity = opacity; | ||||||
|  |          | ||||||
|  |         // Position randomly with some clustering toward top areas
 | ||||||
|  |         const xPos = Math.random() * 100; | ||||||
|  |         const yPos = Math.random() * 100; | ||||||
|  |          | ||||||
|  |         particle.style.left = `${xPos}%`; | ||||||
|  |         particle.style.top = `${yPos}%`; | ||||||
|  |          | ||||||
|  |         // Animation properties
 | ||||||
|  |         particle.style.animationDuration = `${Math.random() * 20 + 10}s`; | ||||||
|  |         particle.style.animationDelay = `${Math.random() * 5}s`; | ||||||
|  |          | ||||||
|  |         // Add particle animation
 | ||||||
|  |         particle.style.animation = `particle-float ${Math.random() * 20 + 10}s linear infinite`; | ||||||
|  |          | ||||||
|  |         particlesContainer.appendChild(particle); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Create floating tech icons in the background | ||||||
|  |  */ | ||||||
|  | function createFloatingIcons() { | ||||||
|  |     const iconContainer = document.getElementById('floating-icons'); | ||||||
|  |      | ||||||
|  |     if (!iconContainer) return; | ||||||
|  |      | ||||||
|  |     iconContainer.innerHTML = ''; | ||||||
|  |      | ||||||
|  |     // Tech-related unicode symbols and fontawesome classes
 | ||||||
|  |     const icons = [ | ||||||
|  |         '⚙️', '💻', '🔒', '🔌', '🌐', '☁️', '📊',  | ||||||
|  |         'fa-server', 'fa-network-wired', 'fa-database',  | ||||||
|  |         'fa-code-branch', 'fa-cloud', 'fa-shield-alt' | ||||||
|  |     ]; | ||||||
|  |      | ||||||
|  |     for (let i = 0; i < 12; i++) { | ||||||
|  |         const icon = document.createElement('div'); | ||||||
|  |         icon.classList.add('floating-icon'); | ||||||
|  |          | ||||||
|  |         const iconType = icons[Math.floor(Math.random() * icons.length)]; | ||||||
|  |          | ||||||
|  |         // Handle both unicode and font awesome
 | ||||||
|  |         if (iconType.startsWith('fa-')) { | ||||||
|  |             const faIcon = document.createElement('i'); | ||||||
|  |             faIcon.className = `fas ${iconType}`; | ||||||
|  |             icon.appendChild(faIcon); | ||||||
|  |         } else { | ||||||
|  |             icon.textContent = iconType; | ||||||
|  |         } | ||||||
|  |          | ||||||
|  |         // Random size and position
 | ||||||
|  |         const size = Math.random() * 24 + 16; | ||||||
|  |         icon.style.fontSize = `${size}px`; | ||||||
|  |          | ||||||
|  |         // Position
 | ||||||
|  |         icon.style.left = `${Math.random() * 100}%`; | ||||||
|  |         icon.style.bottom = `-50px`; | ||||||
|  |          | ||||||
|  |         // Animation
 | ||||||
|  |         icon.style.animationDuration = `${Math.random() * 30 + 20}s`; | ||||||
|  |         icon.style.animationDelay = `${Math.random() * 10}s`; | ||||||
|  |          | ||||||
|  |         iconContainer.appendChild(icon); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Initialize role rotation in the hero section | ||||||
|  |  */ | ||||||
|  | function initRoleRotation() { | ||||||
|  |     const roles = document.querySelectorAll('.role'); | ||||||
|  |     const descriptionElement = document.getElementById('role-description'); | ||||||
|  |      | ||||||
|  |     if (roles.length === 0 || !descriptionElement) return; | ||||||
|  |      | ||||||
|  |     let currentRole = 0; | ||||||
|  |      | ||||||
|  |     function rotateRoles() { | ||||||
|  |         // Hide current role
 | ||||||
|  |         roles[currentRole].classList.remove('active'); | ||||||
|  |          | ||||||
|  |         // Move to next role
 | ||||||
|  |         currentRole = (currentRole + 1) % roles.length; | ||||||
|  |          | ||||||
|  |         // Show new role
 | ||||||
|  |         roles[currentRole].classList.add('active'); | ||||||
|  |          | ||||||
|  |         // Update description text
 | ||||||
|  |         const newDescription = roles[currentRole].getAttribute('data-description'); | ||||||
|  |         if (newDescription) { | ||||||
|  |             descriptionElement.textContent = newDescription; | ||||||
|  |              | ||||||
|  |             // Animate the description change
 | ||||||
|  |             descriptionElement.style.opacity = '0'; | ||||||
|  |             descriptionElement.style.transform = 'translateY(10px)'; | ||||||
|  |              | ||||||
|  |             setTimeout(() => { | ||||||
|  |                 descriptionElement.style.opacity = '1'; | ||||||
|  |                 descriptionElement.style.transform = 'translateY(0)'; | ||||||
|  |             }, 50); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     // Set initial role to active
 | ||||||
|  |     roles[0].classList.add('active'); | ||||||
|  |      | ||||||
|  |     // Initialize with the first description
 | ||||||
|  |     const initialDescription = roles[0].getAttribute('data-description'); | ||||||
|  |     if (initialDescription && descriptionElement) { | ||||||
|  |         descriptionElement.textContent = initialDescription; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     // Start rotation with delay
 | ||||||
|  |     setInterval(rotateRoles, 5000); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Initialize terminal typing animation in the hero section | ||||||
|  |  */ | ||||||
|  | function initTerminalTyping() { | ||||||
|  |     const terminalText = document.getElementById('terminal-text'); | ||||||
|  |     if (!terminalText) return; | ||||||
|  |      | ||||||
|  |     const terminalMessages = [ | ||||||
|  |         "> Ready for deployment...", | ||||||
|  |         "> Reducing operational costs by 30%", | ||||||
|  |         "> Improving system reliability to 99.9%", | ||||||
|  |         "> Accelerating digital transformation", | ||||||
|  |         "> Enhancing security compliance", | ||||||
|  |         "> Streamlining IT workflows", | ||||||
|  |         "> Optimizing infrastructure performance", | ||||||
|  |         "> Implementing best practices", | ||||||
|  |         "> Supporting business objectives" | ||||||
|  |     ]; | ||||||
|  |      | ||||||
|  |     let currentMessage = 0; | ||||||
|  |      | ||||||
|  |     function typeMessage(message, index = 0) { | ||||||
|  |         if (index < message.length) { | ||||||
|  |             terminalText.textContent = message.substring(0, index + 1); | ||||||
|  |             setTimeout(() => typeMessage(message, index + 1), 50 + Math.random() * 50); | ||||||
|  |         } else { | ||||||
|  |             // Wait before clearing and typing next message
 | ||||||
|  |             setTimeout(clearAndTypeNext, 3000); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     function clearAndTypeNext() { | ||||||
|  |         // Clear the current text with a backspace effect
 | ||||||
|  |         const currentText = terminalText.textContent; | ||||||
|  |          | ||||||
|  |         function backspace(length = currentText.length) { | ||||||
|  |             if (length > 0) { | ||||||
|  |                 terminalText.textContent = currentText.substring(0, length - 1); | ||||||
|  |                 setTimeout(() => backspace(length - 1), 20); | ||||||
|  |             } else { | ||||||
|  |                 // Move to next message
 | ||||||
|  |                 currentMessage = (currentMessage + 1) % terminalMessages.length; | ||||||
|  |                 setTimeout(() => typeMessage(terminalMessages[currentMessage]), 500); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |          | ||||||
|  |         backspace(); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     // Start the typing animation with the first message
 | ||||||
|  |     typeMessage(terminalMessages[0]); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Initialize the solutions carousel | ||||||
|  |  */ | ||||||
|  | function initSolutionsCarousel() { | ||||||
|  |     const slides = document.querySelectorAll('.solution-slide'); | ||||||
|  |     const dots = document.querySelectorAll('.slider-dot'); | ||||||
|  |      | ||||||
|  |     if (slides.length === 0 || dots.length === 0) return; | ||||||
|  |      | ||||||
|  |     let currentSlide = 0; | ||||||
|  |     let slideInterval; | ||||||
|  |      | ||||||
|  |     function showSlide(index) { | ||||||
|  |         // Hide all slides
 | ||||||
|  |         slides.forEach(slide => slide.classList.remove('active')); | ||||||
|  |         dots.forEach(dot => dot.classList.remove('active')); | ||||||
|  |          | ||||||
|  |         // Show selected slide
 | ||||||
|  |         slides[index].classList.add('active'); | ||||||
|  |         dots[index].classList.add('active'); | ||||||
|  |          | ||||||
|  |         currentSlide = index; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     function nextSlide() { | ||||||
|  |         const next = (currentSlide + 1) % slides.length; | ||||||
|  |         showSlide(next); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     // Add click events to dots
 | ||||||
|  |     dots.forEach((dot, index) => { | ||||||
|  |         dot.addEventListener('click', () => { | ||||||
|  |             clearInterval(slideInterval); | ||||||
|  |             showSlide(index); | ||||||
|  |              | ||||||
|  |             // Restart automatic rotation
 | ||||||
|  |             slideInterval = setInterval(nextSlide, 5000); | ||||||
|  |         }); | ||||||
|  |     }); | ||||||
|  |      | ||||||
|  |     // Start automatic rotation
 | ||||||
|  |     slideInterval = setInterval(nextSlide, 5000); | ||||||
|  |      | ||||||
|  |     // Show first slide initially
 | ||||||
|  |     showSlide(0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Add scroll reveal animations to elements | ||||||
|  |  */ | ||||||
|  | function initScrollReveal() { | ||||||
|  |     const revealElements = document.querySelectorAll('.section-header, .service-card, .project-card, .lab-card, .timeline-item, .contact-item'); | ||||||
|  |      | ||||||
|  |     revealElements.forEach(element => { | ||||||
|  |         element.classList.add('reveal'); | ||||||
|  |     }); | ||||||
|  |      | ||||||
|  |     function checkReveal() { | ||||||
|  |         revealElements.forEach(element => { | ||||||
|  |             const elementTop = element.getBoundingClientRect().top; | ||||||
|  |             const elementVisible = 150; | ||||||
|  |              | ||||||
|  |             if (elementTop < window.innerHeight - elementVisible) { | ||||||
|  |                 element.classList.add('active'); | ||||||
|  |             } | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     // Initial check
 | ||||||
|  |     checkReveal(); | ||||||
|  |      | ||||||
|  |     // Check on scroll
 | ||||||
|  |     window.addEventListener('scroll', checkReveal); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Update metrics values periodically to simulate live data | ||||||
|  |  */ | ||||||
|  | function updateMetrics() { | ||||||
|  |     const metrics = { | ||||||
|  |         'CPU Usage': { min: 30, max: 60, element: null }, | ||||||
|  |         'Memory': { min: 45, max: 70, element: null }, | ||||||
|  |         'Storage': { min: 60, max: 75, element: null }, | ||||||
|  |         'Network': { min: 15, max: 40, element: null } | ||||||
|  |     }; | ||||||
|  |      | ||||||
|  |     // Get all metric elements
 | ||||||
|  |     document.querySelectorAll('.metric').forEach(metric => { | ||||||
|  |         const nameElement = metric.querySelector('.metric-name'); | ||||||
|  |         if (nameElement && metrics[nameElement.textContent]) { | ||||||
|  |             metrics[nameElement.textContent].element = metric; | ||||||
|  |         } | ||||||
|  |     }); | ||||||
|  |      | ||||||
|  |     function updateMetricValues() { | ||||||
|  |         Object.keys(metrics).forEach(key => { | ||||||
|  |             const metric = metrics[key]; | ||||||
|  |             if (!metric.element) return; | ||||||
|  |              | ||||||
|  |             const valueEl = metric.element.querySelector('.metric-value'); | ||||||
|  |             const progressEl = metric.element.querySelector('.metric-progress'); | ||||||
|  |              | ||||||
|  |             if (valueEl && progressEl) { | ||||||
|  |                 const newValue = Math.floor(Math.random() * (metric.max - metric.min)) + metric.min; | ||||||
|  |                 valueEl.textContent = `${newValue}%`; | ||||||
|  |                 progressEl.style.width = `${newValue}%`; | ||||||
|  |             } | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     // Update metrics every 5 seconds
 | ||||||
|  |     setInterval(updateMetricValues, 5000); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Initialize contact form handling | ||||||
|  |  */ | ||||||
|  | function initFormHandling(form) { | ||||||
|  |     form.addEventListener('submit', async function(e) { | ||||||
|  |         e.preventDefault(); | ||||||
|  |          | ||||||
|  |         const submitButton = form.querySelector('button[type="submit"]'); | ||||||
|  |         const originalButtonText = submitButton.innerHTML; | ||||||
|  |         submitButton.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Sending...'; | ||||||
|  |         submitButton.disabled = true; | ||||||
|  |          | ||||||
|  |         try { | ||||||
|  |             // Simulated form submission - in production replace with actual API call
 | ||||||
|  |             // const formData = new FormData(form);
 | ||||||
|  |             // const formValues = Object.fromEntries(formData.entries());
 | ||||||
|  |              | ||||||
|  |             // Simulated API response delay
 | ||||||
|  |             await new Promise(resolve => setTimeout(resolve, 1500)); | ||||||
|  |              | ||||||
|  |             // Success message
 | ||||||
|  |             alert('Thank you for your message! I will get back to you soon.'); | ||||||
|  |             form.reset(); | ||||||
|  |         } catch (error) { | ||||||
|  |             console.error('Error:', error); | ||||||
|  |             alert('Failed to send message. Please try again or contact me directly via email.'); | ||||||
|  |         } finally { | ||||||
|  |             submitButton.innerHTML = originalButtonText; | ||||||
|  |             submitButton.disabled = false; | ||||||
|  |         } | ||||||
|  |     }); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Update copyright year in the footer | ||||||
|  |  */ | ||||||
|  | function updateYear() { | ||||||
|  |     const yearElement = document.getElementById('current-year'); | ||||||
|  |     if (yearElement) { | ||||||
|  |         yearElement.textContent = new Date().getFullYear(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Utility function to add particle float animation | ||||||
|  |  */ | ||||||
|  | document.addEventListener('DOMContentLoaded', function() { | ||||||
|  |     // Initialize all website functionality
 | ||||||
|  |     initNavigation(); | ||||||
|  |     initParticlesAndIcons(); | ||||||
|  |     initRoleRotation(); // Updated function
 | ||||||
|  |     initTerminalTyping(); // Updated function
 | ||||||
|  |     initSolutionsCarousel(); // Updated function
 | ||||||
|  |     initScrollReveal(); | ||||||
|  |     updateMetrics(); | ||||||
|  |     updateYear(); | ||||||
|  |      | ||||||
|  |     // Initialize form handling
 | ||||||
|  |     const contactForm = document.getElementById('contact-form'); | ||||||
|  |     if (contactForm) { | ||||||
|  |         initFormHandling(contactForm); | ||||||
|  |     } | ||||||
|  | }); | ||||||
							
								
								
									
										13
									
								
								styles.css
								
								
								
								
							
							
						
						
									
										13
									
								
								styles.css
								
								
								
								
							|  | @ -213,16 +213,27 @@ section { | ||||||
|   align-items: center; |   align-items: center; | ||||||
|   font-weight: 700; |   font-weight: 700; | ||||||
|   font-size: 1.5rem; |   font-size: 1.5rem; | ||||||
|  |   color: transparent; | ||||||
|  |   background: linear-gradient(135deg, #3b82f6, #2563eb); | ||||||
|  |   -webkit-background-clip: text; | ||||||
|  |   background-clip: text; | ||||||
|  |   text-shadow: 0 0 8px rgba(59, 130, 246, 0.5); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .logo a { | ||||||
|  |   text-decoration: none; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .logo-text { | .logo-text { | ||||||
|     color: var(--accent); |   margin-right: 4px; | ||||||
|  |   color: inherit; /* inherit gradient */ | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .logo-dot { | .logo-dot { | ||||||
|   color: var(--text-primary); |   color: var(--text-primary); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| .nav-menu { | .nav-menu { | ||||||
|     display: flex; |     display: flex; | ||||||
|     align-items: center; |     align-items: center; | ||||||
|  |  | ||||||
|  | @ -0,0 +1,57 @@ | ||||||
|  | /* Test CSS file to confirm changes are working */ | ||||||
|  | 
 | ||||||
|  | /* Save this as test-styles.css in your repository root */ | ||||||
|  | 
 | ||||||
|  | /* Logo Styles - Enhanced Version */ | ||||||
|  | .logo { | ||||||
|  |     position: relative; | ||||||
|  |     display: flex; | ||||||
|  |     align-items: center; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .logo a { | ||||||
|  |     display: flex; | ||||||
|  |     align-items: center; | ||||||
|  |     text-decoration: none; | ||||||
|  |     position: relative; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .logo-text { | ||||||
|  |     font-family: 'Inter', sans-serif; | ||||||
|  |     font-weight: 700; | ||||||
|  |     font-size: 1.5rem; | ||||||
|  |     background: linear-gradient(90deg, #ff0000 0%, #ff6e00 50%, #ffa500 100%); | ||||||
|  |     -webkit-background-clip: text; | ||||||
|  |     background-clip: text; | ||||||
|  |     color: transparent; | ||||||
|  |     position: relative; | ||||||
|  |     text-shadow: 0 0 15px rgba(255, 150, 100, 0.2); | ||||||
|  |     letter-spacing: 0.5px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .logo-dot { | ||||||
|  |     font-family: 'Inter', sans-serif; | ||||||
|  |     font-weight: 700; | ||||||
|  |     font-size: 1.5rem; | ||||||
|  |     color: #ff6e00; | ||||||
|  |     position: relative; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* Logo with tech icon detail - using different brackets to be obviously visible */ | ||||||
|  | .logo a::before { | ||||||
|  |     content: "[ "; | ||||||
|  |     font-family: 'JetBrains Mono', monospace; | ||||||
|  |     color: #ff6e00; | ||||||
|  |     font-weight: bold; | ||||||
|  |     opacity: 0.8; | ||||||
|  |     margin-right: 2px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .logo a::after { | ||||||
|  |     content: " ]"; | ||||||
|  |     font-family: 'JetBrains Mono', monospace; | ||||||
|  |     color: #ff6e00; | ||||||
|  |     font-weight: bold; | ||||||
|  |     opacity: 0.8; | ||||||
|  |     margin-left: 2px; | ||||||
|  | } | ||||||
		Loading…
	
		Reference in New Issue