fix(nav): add responsive hamburger menu for mobile

- Hide horizontal nav links below md breakpoint
- Add hamburger/close toggle button using Datastar signals
- Show vertical dropdown menu on mobile with stacked nav links
This commit is contained in:
Jon Seager 2026-02-03 10:40:24 +00:00
parent 2ac61345ec
commit 32c0935124
No known key found for this signature in database

View file

@ -1,18 +1,46 @@
<nav class="flex items-center justify-between gap-4 rounded-lg border border-amber-300 bg-amber-100/80 p-3 text-sm text-stone-600"> <nav class="relative rounded-lg border border-amber-300 bg-amber-100/80 p-3 text-sm text-stone-600" data-signals:nav-open="false">
<div class="font-semibold uppercase tracking-[0.25em] text-amber-700"><a href="/timeline">B{rew}log</a></div> <div class="flex items-center justify-between">
<div class="flex items-center gap-3"> <div class="font-semibold uppercase tracking-[0.25em] text-amber-700"><a href="/timeline">B{rew}log</a></div>
<a class="border-b-2 pb-1 transition {% if nav_active == "roasters" %}text-amber-700 border-amber-500{% else %}text-stone-500 border-transparent hover:text-amber-600 hover:border-amber-400{% endif %}" href="/roasters">Roasters</a> <!-- Desktop links -->
<a class="border-b-2 pb-1 transition {% if nav_active == "roasts" %}text-amber-700 border-amber-500{% else %}text-stone-500 border-transparent hover:text-amber-600 hover:border-amber-400{% endif %}" href="/roasts">Roasts</a> <div class="hidden md:flex items-center gap-3">
<a class="border-b-2 pb-1 transition {% if nav_active == "bags" %}text-amber-700 border-amber-500{% else %}text-stone-500 border-transparent hover:text-amber-600 hover:border-amber-400{% endif %}" href="/bags">Bags</a> <a class="border-b-2 pb-1 transition {% if nav_active == "roasters" %}text-amber-700 border-amber-500{% else %}text-stone-500 border-transparent hover:text-amber-600 hover:border-amber-400{% endif %}" href="/roasters">Roasters</a>
<a class="border-b-2 pb-1 transition {% if nav_active == "brews" %}text-amber-700 border-amber-500{% else %}text-stone-500 border-transparent hover:text-amber-600 hover:border-amber-400{% endif %}" href="/brews">Brews</a> <a class="border-b-2 pb-1 transition {% if nav_active == "roasts" %}text-amber-700 border-amber-500{% else %}text-stone-500 border-transparent hover:text-amber-600 hover:border-amber-400{% endif %}" href="/roasts">Roasts</a>
<a class="border-b-2 pb-1 transition {% if nav_active == "gear" %}text-amber-700 border-amber-500{% else %}text-stone-500 border-transparent hover:text-amber-600 hover:border-amber-400{% endif %}" href="/gear">Gear</a> <a class="border-b-2 pb-1 transition {% if nav_active == "bags" %}text-amber-700 border-amber-500{% else %}text-stone-500 border-transparent hover:text-amber-600 hover:border-amber-400{% endif %}" href="/bags">Bags</a>
<a class="border-b-2 pb-1 transition {% if nav_active == "timeline" %}text-amber-700 border-amber-500{% else %}text-stone-500 border-transparent hover:text-amber-600 hover:border-amber-400{% endif %}" href="/timeline">Timeline</a> <a class="border-b-2 pb-1 transition {% if nav_active == "brews" %}text-amber-700 border-amber-500{% else %}text-stone-500 border-transparent hover:text-amber-600 hover:border-amber-400{% endif %}" href="/brews">Brews</a>
<a class="border-b-2 pb-1 transition {% if nav_active == "gear" %}text-amber-700 border-amber-500{% else %}text-stone-500 border-transparent hover:text-amber-600 hover:border-amber-400{% endif %}" href="/gear">Gear</a>
<a class="border-b-2 pb-1 transition {% if nav_active == "timeline" %}text-amber-700 border-amber-500{% else %}text-stone-500 border-transparent hover:text-amber-600 hover:border-amber-400{% endif %}" href="/timeline">Timeline</a>
{% if is_authenticated %}
<form method="post" action="/logout" class="inline">
<button type="submit" class="border-b-2 pb-1 transition text-stone-500 border-transparent hover:text-amber-600 hover:border-amber-400">Logout</button>
</form>
{% else %}
<a class="border-b-2 pb-1 transition text-stone-500 border-transparent hover:text-amber-600 hover:border-amber-400" href="/login">Login</a>
{% endif %}
</div>
<!-- Hamburger button (mobile only) -->
<button class="md:hidden p-1 text-amber-700" data-on:click="$navOpen = !$navOpen" aria-label="Toggle menu">
<svg data-show="!$navOpen" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M4 6h16M4 12h16M4 18h16" />
</svg>
<svg data-show="$navOpen" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" style="display:none">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
</div>
<!-- Mobile menu -->
<div class="md:hidden flex flex-col gap-2 pt-3 mt-3 border-t border-amber-300" data-show="$navOpen" style="display:none">
<a class="py-1 transition {% if nav_active == "roasters" %}text-amber-700 font-medium{% else %}text-stone-500 hover:text-amber-600{% endif %}" href="/roasters">Roasters</a>
<a class="py-1 transition {% if nav_active == "roasts" %}text-amber-700 font-medium{% else %}text-stone-500 hover:text-amber-600{% endif %}" href="/roasts">Roasts</a>
<a class="py-1 transition {% if nav_active == "bags" %}text-amber-700 font-medium{% else %}text-stone-500 hover:text-amber-600{% endif %}" href="/bags">Bags</a>
<a class="py-1 transition {% if nav_active == "brews" %}text-amber-700 font-medium{% else %}text-stone-500 hover:text-amber-600{% endif %}" href="/brews">Brews</a>
<a class="py-1 transition {% if nav_active == "gear" %}text-amber-700 font-medium{% else %}text-stone-500 hover:text-amber-600{% endif %}" href="/gear">Gear</a>
<a class="py-1 transition {% if nav_active == "timeline" %}text-amber-700 font-medium{% else %}text-stone-500 hover:text-amber-600{% endif %}" href="/timeline">Timeline</a>
{% if is_authenticated %} {% if is_authenticated %}
<form method="post" action="/logout" class="inline"> <form method="post" action="/logout" class="inline">
<button type="submit" class="border-b-2 pb-1 transition text-stone-500 border-transparent hover:text-amber-600 hover:border-amber-400">Logout</button> <button type="submit" class="py-1 transition text-stone-500 hover:text-amber-600 text-left">Logout</button>
</form> </form>
{% else %} {% else %}
<a class="border-b-2 pb-1 transition text-stone-500 border-transparent hover:text-amber-600 hover:border-amber-400" href="/login">Login</a> <a class="py-1 transition text-stone-500 hover:text-amber-600" href="/login">Login</a>
{% endif %} {% endif %}
</div> </div>
</nav> </nav>