feat(nav): add hamburger menu for mobile navigation (Fix #27)
All checks were successful
Deploy Feature Branch to Test / deploy (push) Successful in 24s

- Hamburger button with animated X toggle (CSS-only icon)
- Slide-down mobile nav on ≤900px with 44px+ tap targets
- Semi-transparent overlay when menu is open
- Escape key + outside click + link click closes menu
- Auto-close on resize to desktop
- Desktop navigation unchanged
- Pure vanilla JS toggle, no jQuery dependency
This commit is contained in:
2026-05-14 17:40:20 +00:00
parent 51d4f96b20
commit 565c8b304d
3 changed files with 180 additions and 0 deletions

View File

@@ -115,6 +115,84 @@ nav.scrolled .nav-links a:hover {
box-shadow: 0 4px 20px rgb(139 105 20 / 50%);
}
/* HAMBURGER */
.nav-hamburger {
display: none;
width: 44px;
height: 44px;
background: none;
border: none;
cursor: pointer;
position: relative;
z-index: 110;
align-items: center;
justify-content: center;
padding: 0;
}
.nav-hamburger span,
.nav-hamburger span::before,
.nav-hamburger span::after {
display: block;
width: 22px;
height: 2px;
background: var(--white);
border-radius: 1px;
transition:
transform 0.3s ease,
opacity 0.3s ease,
background 0.4s;
position: absolute;
}
.nav-hamburger span::before,
.nav-hamburger span::after {
content: "";
}
.nav-hamburger span::before {
transform: translateY(-7px);
}
.nav-hamburger span::after {
transform: translateY(7px);
}
nav.scrolled .nav-hamburger span,
nav.scrolled .nav-hamburger span::before,
nav.scrolled .nav-hamburger span::after {
background: var(--dark);
}
.nav-hamburger.active span {
background: transparent;
}
.nav-hamburger.active span::before {
transform: rotate(45deg);
background: var(--dark);
}
.nav-hamburger.active span::after {
transform: rotate(-45deg);
background: var(--dark);
}
.nav-mobile-overlay {
display: none;
position: fixed;
inset: 0;
background: rgb(28 26 23 / 50%);
z-index: 90;
opacity: 0;
transition: opacity 0.3s ease;
}
.nav-mobile-overlay.active {
display: block;
opacity: 1;
}
/* HERO */
.hero {
position: relative;
@@ -1042,6 +1120,59 @@ footer {
display: none;
}
.nav-hamburger {
display: flex;
}
/* Mobile slide-down nav */
nav.mobile-open .nav-links {
display: flex;
flex-direction: column;
position: fixed;
top: 0;
left: 0;
right: 0;
background: rgb(253 252 250 / 98%);
backdrop-filter: blur(12px);
padding: 5rem 1.5rem 2rem;
gap: 0;
z-index: 95;
border-bottom: 1px solid var(--warm);
animation: slideDown 0.3s ease;
}
nav.mobile-open .nav-links a {
color: var(--charcoal);
font-size: 1rem;
padding: 1rem 0;
border-bottom: 1px solid var(--warm);
display: block;
min-height: 44px;
display: flex;
align-items: center;
}
nav.mobile-open .nav-hamburger span,
nav.mobile-open .nav-hamburger span::before,
nav.mobile-open .nav-hamburger span::after {
background: var(--dark);
}
nav.mobile-open .nav-hamburger.active span {
background: transparent;
}
@keyframes slideDown {
from {
opacity: 0;
transform: translateY(-10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.hero-content {
padding: 0 1.5rem 4rem;
}