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