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:
parent
9b5f4e42ec
commit
4f021f5f38
|
@ -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
|
||||
}
|
||||
]
|
||||
})
|
||||
});
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
93
script.js
93
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) {
|
||||
|
|
336
styles.css
336
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;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue