Files
neuron-web/src/nav.el
T

112 lines
4.5 KiB
EmacsLisp

// components/nav.el Top navigation bar.
//
// Responsive: desktop shows full link bar, 1060px collapses to hamburger.
// Hamburger toggles .nav-mobile panel. Closes on link click or outside click.
fn nav() -> String {
return "
<nav id=\"nav\">
<div class=\"nav-inner\">
<a href=\"/\" class=\"nav-logo\" aria-label=\"Neuron home\"><img src=\"/assets/brand/neuron-wordmark-on-light.png\" srcset=\"/assets/brand/neuron-wordmark-on-light@2x.png 2x\" alt=\"Neuron\" height=\"28\"></a>
<div class=\"nav-links\">
<a href=\"/#how-it-works\" class=\"nav-link\">How it works</a>
<div class=\"nav-dropdown\">
<button class=\"nav-link nav-dropdown-btn\" aria-haspopup=\"true\" aria-expanded=\"false\">Mission &#9662;</button>
<div class=\"nav-dropdown-menu\">
<a href=\"/#mission\" class=\"nav-dropdown-item\">Our mission</a>
<a href=\"/#safety\" class=\"nav-dropdown-item\">Safety</a>
<a href=\"/#environmental\" class=\"nav-dropdown-item\">Environment</a>
</div>
</div>
<a href=\"/#pricing\" class=\"nav-link\">Pricing</a>
<a href=\"/#marketplace\" class=\"nav-link\">Marketplace</a>
<a href=\"/#enterprise\" class=\"nav-link\">Enterprise</a>
<a href=\"/about\" class=\"nav-link\">About</a>
<a href=\"/said\" class=\"nav-link\">Gallery</a>
<a href=\"/account\" class=\"nav-link\">Account</a>
<a href=\"/#pricing\" class=\"nav-cta\">Get Access</a>
</div>
<button class=\"nav-hamburger\" id=\"nav-hamburger\" aria-label=\"Open navigation\" aria-expanded=\"false\" aria-controls=\"nav-mobile\">
<span></span>
<span></span>
<span></span>
</button>
<div class=\"nav-mobile\" id=\"nav-mobile\" role=\"navigation\" aria-label=\"Mobile navigation\">
<a href=\"/#how-it-works\" class=\"nav-mobile-link\">How it works</a>
<a href=\"/#mission\" class=\"nav-mobile-link\">Mission</a>
<a href=\"/#safety\" class=\"nav-mobile-link\" style=\"padding-left:1.75rem;font-size:0.8rem;color:var(--t3)\">- Safety</a>
<a href=\"/#environmental\" class=\"nav-mobile-link\" style=\"padding-left:1.75rem;font-size:0.8rem;color:var(--t3)\">- Environment</a>
<a href=\"/#pricing\" class=\"nav-mobile-link\">Pricing</a>
<a href=\"/#enterprise\" class=\"nav-mobile-link\">Enterprise</a>
<a href=\"/about\" class=\"nav-mobile-link\">About</a>
<a href=\"/said\" class=\"nav-mobile-link\">Gallery</a>
<a href=\"/account\" class=\"nav-mobile-link\">Account</a>
<a href=\"/#pricing\" class=\"nav-mobile-cta\">Get Access</a>
</div>
</div>
</nav>
<script>
(function() {
var btn = document.getElementById('nav-hamburger');
var menu = document.getElementById('nav-mobile');
var nav = document.getElementById('nav');
if (!btn || !menu) return;
function close() {
menu.classList.remove('open');
btn.setAttribute('aria-expanded', 'false');
}
function open() {
menu.classList.add('open');
btn.setAttribute('aria-expanded', 'true');
}
function toggle() {
if (menu.classList.contains('open')) { close(); } else { open(); }
}
btn.addEventListener('click', function(e) { e.stopPropagation(); toggle(); });
// Dropdown — Mission
var ddBtn = document.querySelector('.nav-dropdown-btn');
var dd = document.querySelector('.nav-dropdown');
if (ddBtn && dd) {
ddBtn.addEventListener('click', function(e) {
e.stopPropagation();
var isOpen = dd.classList.contains('open');
dd.classList.toggle('open');
ddBtn.setAttribute('aria-expanded', isOpen ? 'false' : 'true');
});
dd.querySelectorAll('.nav-dropdown-item').forEach(function(a) {
a.addEventListener('click', function() { dd.classList.remove('open'); });
});
document.addEventListener('click', function() { dd.classList.remove('open'); });
}
// Close on any link inside mobile menu
menu.querySelectorAll('a').forEach(function(a) {
a.addEventListener('click', close);
});
// Close when clicking outside
document.addEventListener('click', function(e) {
if (!nav.contains(e.target)) { close(); }
});
// Close on Escape
document.addEventListener('keydown', function(e) {
if (e.key === 'Escape') { close(); }
});
// Close if viewport grows past breakpoint
window.addEventListener('resize', function() {
if (window.innerWidth > 1060) { close(); }
});
})();
</script>
"
}