diff --git a/functions/contact.js b/functions/contact.js index 6061a19..b75f82b 100644 --- a/functions/contact.js +++ b/functions/contact.js @@ -17,18 +17,32 @@ export async function onRequestPost(context) { 'Authorization': `Bearer ${context.env.RESEND_API_KEY}`, 'Content-Type': 'application/json' }, - body: JSON.stringify({ - from: 'contact@argobox.com', - to: 'daniel.laforce@gmail.com', - subject: `Contact Form: ${subject}`, + body: JSON.stringify({ + from: { + email: email, + name: name + }, + to: [ + { + email: "daniel@laforceit.com", + name: "Daniel LaForce" + } + ], + subject: `ArgoBox Contact Form: ${subject}`, html: ` -

New Contact Form Submission

+

New Contact Message on ArgoBox.com

Name: ${name}

Email: ${email}

Subject: ${subject}

Message:

${message}

- ` + `, + reply_to: [ + { + email, + name + } + ] }) }); diff --git a/index.html b/index.html index 5a91090..90a220e 100644 --- a/index.html +++ b/index.html @@ -2,7 +2,7 @@ - + ArgoBox | Enterprise-Grade Home Lab Environment @@ -894,7 +894,7 @@

diff --git a/script.js b/script.js index 61c83e2..87e5916 100644 --- a/script.js +++ b/script.js @@ -17,25 +17,69 @@ document.addEventListener('DOMContentLoaded', function() { function initNavigation() { const menuToggle = document.querySelector('.menu-toggle'); const navMenu = document.querySelector('.nav-menu'); + const navLinks = document.querySelectorAll('.nav-link'); if (menuToggle && navMenu) { + // Toggle mobile menu menuToggle.addEventListener('click', () => { - navMenu.classList.toggle('show'); - const icon = menuToggle.querySelector('i'); - if (navMenu.classList.contains('show')) { - icon.classList.remove('fa-bars'); - icon.classList.add('fa-times'); - } else { - icon.classList.remove('fa-times'); - icon.classList.add('fa-bars'); + toggleMobileMenu(); + }); + + // Close mobile menu when clicking outside + document.addEventListener('click', (e) => { + if (navMenu.classList.contains('show') && + !navMenu.contains(e.target) && + !menuToggle.contains(e.target)) { + toggleMobileMenu(); } }); + + // Close mobile menu when link is clicked + navLinks.forEach(link => { + link.addEventListener('click', () => { + if (window.innerWidth <= 768 && navMenu.classList.contains('show')) { + toggleMobileMenu(); + } + }); + }); + + // Handle resize events + window.addEventListener('resize', () => { + if (window.innerWidth > 768 && navMenu.classList.contains('show')) { + navMenu.classList.remove('show'); + updateMenuIcon(false); + } + }); + } + + // Toggle function for mobile menu + function toggleMobileMenu() { + navMenu.classList.toggle('show'); + updateMenuIcon(navMenu.classList.contains('show')); + + // Prevent body scrolling when menu is open + if (navMenu.classList.contains('show')) { + document.body.style.overflow = 'hidden'; + } else { + document.body.style.overflow = ''; + } + } + + // Update menu icon based on menu state + function updateMenuIcon(isOpen) { + const icon = menuToggle.querySelector('i'); + if (isOpen) { + icon.classList.remove('fa-bars'); + icon.classList.add('fa-times'); + } else { + icon.classList.remove('fa-times'); + icon.classList.add('fa-bars'); + } } // Scroll spy for navigation window.addEventListener('scroll', () => { const sections = document.querySelectorAll('section'); - const navLinks = document.querySelectorAll('.nav-link'); let current = ''; sections.forEach(section => { @@ -62,10 +106,22 @@ function initParticlesAndIcons() { createFloatingIcons(); } +/** + * Optimize images for better mobile performance + */ +function optimizeImagesForMobile() { + if (window.innerWidth <= 768) { + // Reduce particles count on mobile for better performance + createBackgroundParticles(15); // Fewer particles + } else { + createBackgroundParticles(50); // Normal number of particles + } +} + /** * Create animated background particles */ -function createBackgroundParticles() { +function createBackgroundParticles(count = 50) { const particlesContainer = document.getElementById('particles-container'); if (!particlesContainer) return; @@ -74,7 +130,7 @@ function createBackgroundParticles() { particlesContainer.innerHTML = ''; // Create particles - for (let i = 0; i < 50; i++) { + for (let i = 0; i < count; i++) { const particle = document.createElement('div'); particle.classList.add('particle'); @@ -120,6 +176,21 @@ function updateYear() { } } +/** + * Create and initialize floating icons in the hero section + */ +function createFloatingIcons() { + // Implemented if needed for mobile +} + +// Initialize responsive behaviors +window.addEventListener('resize', () => { + optimizeImagesForMobile(); +}); + +// Call once on page load +optimizeImagesForMobile(); + // Contact Form Handler const contactForm = document.getElementById('contact-form'); if (contactForm) { diff --git a/styles.css b/styles.css index 836be7f..50f8984 100644 --- a/styles.css +++ b/styles.css @@ -34,6 +34,10 @@ --transition-fast: 0.2s ease; --transition-normal: 0.3s ease; --transition-slow: 0.5s ease; + + /* Mobile Nav */ + --mobile-nav-height: 60px; + --mobile-menu-bg: rgba(15, 23, 42, 0.95); } /* Reset & Base Styles */ @@ -286,8 +290,91 @@ section { background: transparent; border: none; color: var(--text-primary); - cursor: pointer; font-size: 1.5rem; + cursor: pointer; + padding: 0.5rem; + margin-left: 1rem; + transition: color var(--transition-normal); + z-index: 1001; +} + +.menu-toggle:hover { + color: var(--accent); +} + +@media (max-width: 768px) { + .menu-toggle { + display: flex; + align-items: center; + justify-content: center; + width: 40px; + height: 40px; + border-radius: 8px; + background: rgba(255, 255, 255, 0.1); + } +} + +/* Touch-specific optimizations */ +@media (pointer: coarse) { + /* Increase tap target sizes for touch devices */ + .nav-link, .btn, .service-item, .footer-link { + padding: 0.75rem; + } + + .form-group input, + .form-group textarea, + .form-group button { + min-height: 48px; /* Minimum recommended touch target size */ + } + + /* Improved mobile scrolling */ + .services-grid, + .tech-grid, + .projects-grid { + -webkit-overflow-scrolling: touch; + } +} + +/* Image optimizations for better mobile performance */ +@media (max-width: 768px) { + .hero { + background-position: center; + background-size: cover; + } + + img { + max-width: 100%; + height: auto; + } + + /* Optimizing layout for mobile screens */ + .container { + width: 100%; + padding-left: 16px; + padding-right: 16px; + } + + /* Improve loading speed on mobile */ + @media (prefers-reduced-motion: reduce) { + .particle, .floating-icon, .data-line { + animation: none !important; + } + + .hero-terminal { + box-shadow: var(--card-shadow); + transform: none !important; + } + } +} + +/* Fix iOS input zooming issues */ +@media screen and (-webkit-min-device-pixel-ratio: 0) { + select:focus, + textarea:focus, + input:focus { + font-size: 16px; + background: rgba(0, 0, 0, 0.1); + } } /* Hero Section */ @@ -2153,6 +2240,11 @@ section { color: var(--success); } +.service-status.maintenance { + background-color: rgba(245, 158, 11, 0.1); + color: var(--warning); +} + .service-status.restricted { background-color: rgba(107, 114, 128, 0.1); color: var(--text-secondary); @@ -2168,8 +2260,8 @@ section { background-color: var(--success); } -.service-status.restricted .status-dot { - background-color: var(--text-secondary); +.service-status.maintenance .status-dot { + background-color: var(--warning); } /* Projects */ @@ -2562,4 +2654,242 @@ section { background-color: rgba(239, 68, 68, 0.1); border: 1px solid var(--error); color: var(--error); +} + +/* Mobile Navigation Enhancement */ +@media (max-width: 768px) { + .navbar .container { + height: var(--mobile-nav-height); + } + + .nav-menu { + position: fixed; + top: var(--mobile-nav-height); + left: 0; + width: 100%; + height: calc(100vh - var(--mobile-nav-height)); + flex-direction: column; + background-color: var(--mobile-menu-bg); + transform: translateY(-100%); + opacity: 0; + visibility: hidden; + transition: transform 0.3s ease, opacity 0.3s ease, visibility 0.3s ease; + backdrop-filter: var(--glass-effect); + -webkit-backdrop-filter: var(--glass-effect); + padding: 2rem 1rem; + z-index: 999; + overflow-y: auto; + } + + .nav-menu.show { + transform: translateY(0); + opacity: 1; + visibility: visible; + } + + .nav-link { + font-size: 1.25rem; + padding: 1rem 0.5rem; + width: 100%; + text-align: center; + } + + .nav-buttons { + margin-left: auto; + } + + .dashboard-link { + display: none; + } + + .menu-toggle { + display: flex !important; + } +} + +/* Responsive Hero Section */ +@media (max-width: 768px) { + .hero-content { + flex-direction: column; + padding: 5rem 0 3rem; + } + + .hero-text { + width: 100%; + padding-right: 0; + margin-bottom: 2rem; + text-align: center; + } + + .hero-title { + font-size: 2rem; + line-height: 1.2; + } + + .hero-description { + font-size: 1rem; + } + + .hero-terminal { + width: 100%; + max-width: 100%; + margin: 0 auto; + } + + .hero-stats { + flex-wrap: wrap; + justify-content: center; + } + + .stat-item { + flex: 1 1 40%; + margin-bottom: 1rem; + } + + .cta-buttons { + flex-direction: column; + align-items: center; + width: 100%; + } + + .btn { + width: 100%; + margin-bottom: 1rem; + } +} + +/* Enhanced Mobile Optimizations */ +@media (max-width: 480px) { + section { + padding: 3rem 0; + } + + .section-title { + font-size: 1.75rem; + } + + .section-description { + font-size: 0.95rem; + } + + .container { + padding: 0 1rem; + } + + /* Architecture section mobile optimization */ + .architecture-diagram { + flex-direction: column; + } + + .diagram-wrapper { + width: 100%; + margin-bottom: 2rem; + } + + .architecture-details { + width: 100%; + } + + /* Improved mobile tech grid */ + .tech-grid { + grid-template-columns: 1fr; + } + + .tech-card { + padding: 1.5rem; + } + + /* Services optimization */ + .services-grid { + grid-template-columns: 1fr; + } + + .service-items { + grid-template-columns: 1fr; + } + + /* Contact form mobile friendly */ + .contact-grid { + grid-template-columns: 1fr; + } + + .contact-form { + padding: 1.5rem; + } + + /* Top links mobile optimization */ + .top-links { + padding: 0.5rem 1rem; + justify-content: center; + } + + .laforceit-link, .signin-button { + font-size: 0.85rem; + } + + /* Projects section mobile */ + .projects-grid { + grid-template-columns: 1fr; + } + + /* Dashboard section mobile */ + .dashboard-grid { + grid-template-columns: 1fr; + } +} + +/* Touch-friendly adjustments */ +@media (hover: none) { + .btn:hover::before { + display: none; + } + + .btn:active { + transform: scale(0.98); + } + + .service-item, .tech-card, .project-card, .dashboard-card { + transition: transform 0.2s ease; + } + + .service-item:active, .tech-card:active, .project-card:active, .dashboard-card:active { + transform: scale(0.98); + } + + .nav-link:active::after { + width: 100%; + } +} + +/* Improved scrolling for mobile */ +@media (max-width: 768px) { + html { + scroll-padding-top: var(--mobile-nav-height); + } + + /* Handle form inputs better on mobile */ + input, textarea, select, button { + font-size: 16px !important; /* Prevents zoom on focus in iOS */ + } + + /* Optimized footer for mobile */ + .footer-content { + flex-direction: column; + } + + .footer-info { + margin-bottom: 2rem; + text-align: center; + width: 100%; + } + + .footer-links { + width: 100%; + grid-template-columns: 1fr; + gap: 2rem; + } + + .footer-links-column { + text-align: center; + } } \ No newline at end of file