feat: add dropdown navigation menus

- Add Blog dropdown with all post types (articles, notes, photos, bookmarks, likes, replies, reposts)
- Add Activity dropdown with GitHub, Listening, Funkwhale, YouTube
- Add /news and /interactions links to main nav
- Add mobile-responsive collapsible sections with Alpine.js
- Add CSS for dropdown menus and mobile nav sections

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Ricardo
2026-01-26 19:17:34 +01:00
parent 8da928a91c
commit 80ced7b148
2 changed files with 107 additions and 16 deletions
+59 -3
View File
@@ -93,14 +93,42 @@
<nav class="site-nav" id="site-nav"> <nav class="site-nav" id="site-nav">
<a href="/">Home</a> <a href="/">Home</a>
<a href="/about/">About</a> <a href="/about/">About</a>
<a href="/blog/">Blog</a> {# Blog dropdown #}
<div class="nav-dropdown" x-data="{ open: false }" @mouseenter="open = true" @mouseleave="open = false">
<a href="/blog/" class="nav-dropdown-trigger">
Blog
<svg class="w-3 h-3 ml-1 inline" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/>
</svg>
</a>
<div class="nav-dropdown-menu" x-show="open" x-transition x-cloak>
<a href="/blog/">All Posts</a>
<a href="/articles/">Articles</a> <a href="/articles/">Articles</a>
<a href="/notes/">Notes</a> <a href="/notes/">Notes</a>
<a href="/photos/">Photos</a>
<a href="/bookmarks/">Bookmarks</a>
<a href="/likes/">Likes</a>
<a href="/replies/">Replies</a>
<a href="/reposts/">Reposts</a>
</div>
</div>
<a href="/interactions/">Interactions</a> <a href="/interactions/">Interactions</a>
<a href="/news/">News</a>
{# Activity dropdown #}
<div class="nav-dropdown" x-data="{ open: false }" @mouseenter="open = true" @mouseleave="open = false">
<button type="button" class="nav-dropdown-trigger">
Activity
<svg class="w-3 h-3 ml-1 inline" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/>
</svg>
</button>
<div class="nav-dropdown-menu" x-show="open" x-transition x-cloak>
<a href="/github/">GitHub</a> <a href="/github/">GitHub</a>
<a href="/listening/">Listening</a> <a href="/listening/">Listening</a>
<a href="/funkwhale/">Funkwhale</a> <a href="/funkwhale/">Funkwhale</a>
<a href="/youtube/">YouTube</a> <a href="/youtube/">YouTube</a>
</div>
</div>
</nav> </nav>
<button id="theme-toggle" type="button" class="theme-toggle" aria-label="Toggle dark mode" title="Toggle dark mode"> <button id="theme-toggle" type="button" class="theme-toggle" aria-label="Toggle dark mode" title="Toggle dark mode">
<svg class="sun-icon" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> <svg class="sun-icon" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
@@ -115,17 +143,45 @@
</div> </div>
{# Mobile nav dropdown #} {# Mobile nav dropdown #}
<nav class="mobile-nav hidden" id="mobile-nav"> <nav class="mobile-nav hidden" id="mobile-nav" x-data="{ blogOpen: false, activityOpen: false }">
<a href="/">Home</a> <a href="/">Home</a>
<a href="/about/">About</a> <a href="/about/">About</a>
<a href="/blog/">Blog</a> {# Blog section #}
<div class="mobile-nav-section">
<button type="button" class="mobile-nav-toggle" @click="blogOpen = !blogOpen">
Blog
<svg class="w-4 h-4 transition-transform" :class="{ 'rotate-180': blogOpen }" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/>
</svg>
</button>
<div class="mobile-nav-submenu" x-show="blogOpen" x-collapse>
<a href="/blog/">All Posts</a>
<a href="/articles/">Articles</a> <a href="/articles/">Articles</a>
<a href="/notes/">Notes</a> <a href="/notes/">Notes</a>
<a href="/photos/">Photos</a>
<a href="/bookmarks/">Bookmarks</a>
<a href="/likes/">Likes</a>
<a href="/replies/">Replies</a>
<a href="/reposts/">Reposts</a>
</div>
</div>
<a href="/interactions/">Interactions</a> <a href="/interactions/">Interactions</a>
<a href="/news/">News</a>
{# Activity section #}
<div class="mobile-nav-section">
<button type="button" class="mobile-nav-toggle" @click="activityOpen = !activityOpen">
Activity
<svg class="w-4 h-4 transition-transform" :class="{ 'rotate-180': activityOpen }" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/>
</svg>
</button>
<div class="mobile-nav-submenu" x-show="activityOpen" x-collapse>
<a href="/github/">GitHub</a> <a href="/github/">GitHub</a>
<a href="/listening/">Listening</a> <a href="/listening/">Listening</a>
<a href="/funkwhale/">Funkwhale</a> <a href="/funkwhale/">Funkwhale</a>
<a href="/youtube/">YouTube</a> <a href="/youtube/">YouTube</a>
</div>
</div>
</nav> </nav>
</header> </header>
+36 -1
View File
@@ -68,10 +68,28 @@
@apply flex items-center gap-4; @apply flex items-center gap-4;
} }
.site-nav a { .site-nav > a,
.site-nav .nav-dropdown-trigger {
@apply text-surface-600 dark:text-surface-400 hover:text-primary-600 dark:hover:text-primary-400 no-underline transition-colors py-2; @apply text-surface-600 dark:text-surface-400 hover:text-primary-600 dark:hover:text-primary-400 no-underline transition-colors py-2;
} }
/* Navigation dropdown */
.nav-dropdown {
@apply relative;
}
.nav-dropdown-trigger {
@apply flex items-center gap-1 cursor-pointer bg-transparent border-none text-base;
}
.nav-dropdown-menu {
@apply absolute top-full left-0 mt-1 py-2 bg-white dark:bg-surface-800 border border-surface-200 dark:border-surface-700 rounded-lg shadow-lg min-w-[160px] z-50;
}
.nav-dropdown-menu a {
@apply block px-4 py-2 text-sm text-surface-600 dark:text-surface-400 hover:bg-surface-100 dark:hover:bg-surface-700 hover:text-primary-600 dark:hover:text-primary-400 no-underline;
}
/* Mobile menu toggle button */ /* Mobile menu toggle button */
.menu-toggle { .menu-toggle {
@apply md:hidden p-2 rounded-lg text-surface-600 dark:text-surface-400 hover:bg-surface-100 dark:hover:bg-surface-800 transition-colors; @apply md:hidden p-2 rounded-lg text-surface-600 dark:text-surface-400 hover:bg-surface-100 dark:hover:bg-surface-800 transition-colors;
@@ -86,6 +104,23 @@
@apply block px-4 py-3 text-surface-600 dark:text-surface-400 hover:bg-surface-100 dark:hover:bg-surface-800 hover:text-primary-600 dark:hover:text-primary-400 no-underline transition-colors border-b border-surface-100 dark:border-surface-800 last:border-b-0; @apply block px-4 py-3 text-surface-600 dark:text-surface-400 hover:bg-surface-100 dark:hover:bg-surface-800 hover:text-primary-600 dark:hover:text-primary-400 no-underline transition-colors border-b border-surface-100 dark:border-surface-800 last:border-b-0;
} }
/* Mobile nav collapsible sections */
.mobile-nav-section {
@apply border-b border-surface-100 dark:border-surface-800;
}
.mobile-nav-toggle {
@apply flex items-center justify-between w-full px-4 py-3 text-surface-600 dark:text-surface-400 hover:bg-surface-100 dark:hover:bg-surface-800 hover:text-primary-600 dark:hover:text-primary-400 transition-colors bg-transparent border-none text-base text-left cursor-pointer;
}
.mobile-nav-submenu {
@apply bg-surface-50 dark:bg-surface-800;
}
.mobile-nav-submenu a {
@apply pl-8 py-2 text-sm border-b-0;
}
/* Theme toggle button */ /* Theme toggle button */
.theme-toggle { .theme-toggle {
@apply p-2 rounded-lg text-surface-600 dark:text-surface-400 hover:bg-surface-100 dark:hover:bg-surface-800 transition-colors; @apply p-2 rounded-lg text-surface-600 dark:text-surface-400 hover:bg-surface-100 dark:hover:bg-surface-800 transition-colors;