2026-04-08 19:49:15 +02:00
|
|
|
<header
|
|
|
|
|
x-data="{ scrolled: false }"
|
|
|
|
|
x-init="window.addEventListener('htmx:pushedIntoHistory', () => { $store.nav.path = window.location.pathname; $store.nav.open = false })"
|
|
|
|
|
@scroll.window="scrolled = window.scrollY > 80"
|
|
|
|
|
class="fixed top-0 inset-x-0 z-50"
|
|
|
|
|
>
|
|
|
|
|
<!-- Top bar -->
|
|
|
|
|
<div
|
|
|
|
|
class="gutter-x flex items-center justify-between py-4 transition-all duration-500"
|
|
|
|
|
:class="$store.nav.open || scrolled ? 'bg-ink/95 backdrop-blur-md shadow-[0_1px_0_var(--color-zinc)]' : ''"
|
|
|
|
|
>
|
|
|
|
|
<!-- Logotype -->
|
2026-04-10 19:07:10 +02:00
|
|
|
<a href="/" class="logo-glitch flex items-center gap-3 hover:opacity-90 transition-opacity" aria-label="{{ .Site.Params.logoText }} Home">
|
2026-04-08 19:49:15 +02:00
|
|
|
{{- partial "logo.html" (dict "id" "nav" "class" "h-8 w-auto flex-shrink-0") -}}
|
|
|
|
|
<span class="text-gradient font-display text-2xl md:text-3xl leading-none tracking-wide">
|
|
|
|
|
{{- .Site.Params.logoText -}}
|
|
|
|
|
</span>
|
|
|
|
|
</a>
|
|
|
|
|
|
|
|
|
|
<!-- Desktop navigation -->
|
|
|
|
|
<nav class="hidden md:flex items-center gap-8" aria-label="Primary navigation">
|
|
|
|
|
{{- range .Site.Menus.main -}}
|
|
|
|
|
{{- $href := .URL -}}
|
|
|
|
|
<a
|
|
|
|
|
href="{{ $href }}"
|
2026-04-10 18:44:15 +02:00
|
|
|
class="label relative transition-colors"
|
2026-04-08 19:49:15 +02:00
|
|
|
:class="($store.nav.path === '{{ $href }}' || ('{{ $href }}' !== '/' && $store.nav.path.startsWith('{{ $href }}'))) ? 'text-heat' : 'text-fog hover:text-chalk'"
|
|
|
|
|
>
|
|
|
|
|
{{ .Name }}
|
|
|
|
|
<span
|
2026-04-10 18:44:15 +02:00
|
|
|
class="absolute -bottom-0.5 left-0 h-px bg-heat transition-all duration-300 ease-out"
|
|
|
|
|
:style="($store.nav.path === '{{ $href }}' || ('{{ $href }}' !== '/' && $store.nav.path.startsWith('{{ $href }}'))) ? 'width: 100%' : 'width: 0'"
|
|
|
|
|
style="width: 0"
|
2026-04-08 19:49:15 +02:00
|
|
|
></span>
|
|
|
|
|
</a>
|
|
|
|
|
{{- end -}}
|
|
|
|
|
</nav>
|
|
|
|
|
|
|
|
|
|
<!-- Mobile toggle — animated hamburger → X -->
|
|
|
|
|
<button
|
|
|
|
|
class="md:hidden w-10 h-10 flex flex-col items-center justify-center gap-[6px] text-fog hover:text-chalk transition-colors"
|
|
|
|
|
:class="$store.nav.open ? 'text-heat' : ''"
|
|
|
|
|
@click="$store.nav.open = !$store.nav.open"
|
|
|
|
|
:aria-expanded="$store.nav.open.toString()"
|
|
|
|
|
aria-controls="mobile-menu"
|
|
|
|
|
aria-label="Toggle navigation"
|
|
|
|
|
>
|
|
|
|
|
<span class="block h-px w-6 bg-current transition-all duration-300 origin-center"
|
|
|
|
|
:class="$store.nav.open ? 'rotate-45 translate-y-[7px]' : ''"></span>
|
|
|
|
|
<span class="block h-px w-4 bg-current transition-all duration-200"
|
|
|
|
|
:class="$store.nav.open ? 'opacity-0' : 'opacity-100'"></span>
|
|
|
|
|
<span class="block h-px w-6 bg-current transition-all duration-300 origin-center"
|
|
|
|
|
:class="$store.nav.open ? '-rotate-45 -translate-y-[7px]' : ''"></span>
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- Fullscreen overlay — teleported to <body> to escape header's stacking context -->
|
|
|
|
|
<template x-teleport="body">
|
|
|
|
|
<div
|
|
|
|
|
id="mobile-menu"
|
|
|
|
|
x-show="$store.nav.open"
|
|
|
|
|
x-cloak
|
|
|
|
|
x-transition:enter="transition duration-300 ease-out"
|
|
|
|
|
x-transition:enter-start="opacity-0"
|
|
|
|
|
x-transition:enter-end="opacity-100"
|
|
|
|
|
x-transition:leave="transition duration-200 ease-in"
|
|
|
|
|
x-transition:leave-start="opacity-100"
|
|
|
|
|
x-transition:leave-end="opacity-0"
|
|
|
|
|
class="fixed inset-0 z-40 flex flex-col bg-void speed-lines overflow-hidden"
|
|
|
|
|
>
|
|
|
|
|
<!-- Top spacer (nav bar height) -->
|
|
|
|
|
<div class="flex-none h-[65px]"></div>
|
|
|
|
|
<div class="gradient-line flex-none"></div>
|
|
|
|
|
|
|
|
|
|
<!-- Decorative background text -->
|
|
|
|
|
<div class="graffiti-tag absolute -bottom-4 -right-4 select-none pointer-events-none"
|
|
|
|
|
style="-webkit-text-stroke-color: rgba(155,0,255,0.07);" aria-hidden="true">MENU</div>
|
|
|
|
|
|
|
|
|
|
<!-- Main nav links -->
|
|
|
|
|
<nav class="flex-1 flex flex-col justify-center gutter-x py-10" aria-label="Mobile navigation">
|
|
|
|
|
<div class="flex flex-col gap-0">
|
|
|
|
|
{{- $i := 0 -}}
|
|
|
|
|
{{- range .Site.Menus.main -}}
|
|
|
|
|
{{- $href := .URL -}}
|
|
|
|
|
<a
|
|
|
|
|
href="{{ $href }}"
|
|
|
|
|
class="group relative leading-none py-3 overflow-hidden"
|
|
|
|
|
style="font-family: var(--font-display); font-size: clamp(2.8rem, 11vw, 6.5rem); animation: mob-link-in 0.5s var(--ease-out-expo) {{ mul $i 70 }}ms both"
|
|
|
|
|
@click="$store.nav.open = false"
|
|
|
|
|
>
|
|
|
|
|
<!-- Hover sweep -->
|
|
|
|
|
<span class="absolute inset-y-0 left-0 w-0 group-hover:w-full transition-all duration-300 ease-out"
|
|
|
|
|
style="background: linear-gradient(90deg, rgba(255,26,140,0.07), transparent);"></span>
|
|
|
|
|
<!-- Link text -->
|
2026-04-10 18:44:15 +02:00
|
|
|
<span class="relative transition-colors duration-200 text-paper group-hover:text-heat uppercase"
|
2026-04-08 19:49:15 +02:00
|
|
|
:class="($store.nav.path === '{{ $href }}' || ('{{ $href }}' !== '/' && $store.nav.path.startsWith('{{ $href }}'))) ? 'text-gradient' : ''"
|
|
|
|
|
>{{ .Name }}</span>
|
|
|
|
|
<!-- Index number -->
|
|
|
|
|
<span class="absolute right-0 top-1/2 -translate-y-1/2 label text-smoke group-hover:text-heat transition-colors duration-200"
|
|
|
|
|
style="animation: mob-link-in 0.4s var(--ease-out-expo) {{ add (mul $i 70) 100 }}ms both"
|
|
|
|
|
>0{{ add $i 1 }}</span>
|
|
|
|
|
</a>
|
|
|
|
|
{{- $i = add $i 1 -}}
|
|
|
|
|
{{- end -}}
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="gradient-line my-8"
|
|
|
|
|
style="animation: mob-link-in 0.4s ease {{ mul $i 70 }}ms both"></div>
|
|
|
|
|
|
|
|
|
|
<div class="flex flex-wrap gap-x-8 gap-y-3"
|
|
|
|
|
style="animation: mob-link-in 0.4s ease {{ add (mul $i 70) 40 }}ms both">
|
|
|
|
|
{{- range .Site.Menus.footer -}}
|
|
|
|
|
<a href="{{ .URL }}" class="label text-fog hover:text-heat transition-colors" @click="$store.nav.open = false">{{ .Name }}</a>
|
|
|
|
|
{{- end -}}
|
|
|
|
|
</div>
|
|
|
|
|
</nav>
|
|
|
|
|
|
|
|
|
|
<!-- Bottom bar -->
|
|
|
|
|
<div class="flex-none gutter-x pb-8 pt-4 border-t border-zinc"
|
|
|
|
|
style="animation: mob-link-in 0.4s ease 420ms both">
|
|
|
|
|
<p class="label text-smoke">{{ .Site.Params.tagline }}</p>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
</header>
|
|
|
|
|
|
|
|
|
|
<style>
|
|
|
|
|
@keyframes mob-link-in {
|
|
|
|
|
from { opacity: 0; transform: translateY(14px); }
|
|
|
|
|
to { opacity: 1; transform: translateY(0); }
|
|
|
|
|
}
|
|
|
|
|
</style>
|