Enhance mobile navigation and performance: Updated viewport settings for better mobile experience, improved mobile menu functionality with click outside to close feature, and optimized image loading for mobile devices. Adjusted footer text for accuracy and added responsive styles for various screen sizes.

This commit is contained in:
Daniel LaForce 2025-04-10 18:13:55 -06:00
parent 9b5f4e42ec
commit 4f021f5f38
4 changed files with 437 additions and 22 deletions

View File

@ -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: `
<h3>New Contact Form Submission</h3>
<h3>New Contact Message on ArgoBox.com</h3>
<p><strong>Name:</strong> ${name}</p>
<p><strong>Email:</strong> ${email}</p>
<p><strong>Subject:</strong> ${subject}</p>
<h4>Message:</h4>
<p>${message}</p>
`
`,
reply_to: [
{
email,
name
}
]
})
});

View File

@ -2,7 +2,7 @@
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>ArgoBox | Enterprise-Grade Home Lab Environment</title>
<meta name="description" content="ArgoBox - A production-grade Kubernetes homelab for DevOps experimentation, infrastructure automation, and containerized application deployment.">
<meta name="keywords" content="kubernetes, k3s, homelab, devops, ansible, proxmox, automation, infrastructure, containerization, zero trust">
@ -894,7 +894,7 @@
</p>
<div class="footer-evolution">
<i class="fas fa-code-branch evolution-icon"></i>
<span>Continuously evolving since 2023</span>
<span>Continuously evolving since 2013</span>
</div>
</div>

View File

@ -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) {

View File

@ -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;
}
}