feat(header mobile): Pills wie Desktop, Menü-Overlay optimiert
Deploy / verify (push) Successful in 1m8s
Deploy / deploy (push) Successful in 1m27s

- Suche + Menü als Desktop-Pills (rounded-full, wald-700/8), Icons text-sm,
  Menü mit Label „Menü/Schließen"
- Menü-Overlay: absolute (überlagert statt schiebt), bg-stein-900/90 +
  backdrop-blur-lg, scrollbar (max-h dvh, overscroll-contain, Safe-Area-pb)
- CTA-Block oben: Mitmachen + Termin melden (btn-sm)
- aktive Sektion auto-aufgeklappt, Submenu-Targets py-3
- Logo mobil h-8 (Desktop h-10)
- Header backdrop-blur-md entfernt (entsperrt Kind-backdrop-filter)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Peter Meier
2026-06-30 15:49:59 +02:00
parent 9115134852
commit 25c1c5f2ed
2 changed files with 25 additions and 16 deletions
+22 -16
View File
@@ -64,6 +64,11 @@
} else {
searchOpen = false;
menuOpen = true;
// Sektion der aktuellen Seite direkt aufgeklappt zeigen.
openSubmenu =
links.find(
(l) => l.children && l.children.length > 0 && isActiveTree(l, $page.url.pathname),
)?.label ?? null;
}
}
@@ -111,7 +116,7 @@
<header
id="horizontal-navigation"
class="relative sticky top-0 z-20 border-b border-white/30 shadow-2xl backdrop-blur-md bg-wald-50"
class="relative sticky top-0 z-20 border-b border-white/30 shadow-2xl bg-wald-50"
>
<span class="gradient-blob-bg-inner" aria-hidden="true"></span>
<div class="relative flex items-center justify-between container-custom py-2">
@@ -122,11 +127,11 @@
>
{#if logoSvgHtml}
<span
class="logo-svg h-10 w-auto inline-flex items-center text-inherit [&_svg]:block [&_svg]:h-full [&_svg]:w-auto [&_svg]:max-h-10"
class="logo-svg h-8 lg:h-10 w-auto inline-flex items-center text-inherit [&_svg]:block [&_svg]:h-full [&_svg]:w-auto [&_svg]:max-h-8 lg:[&_svg]:max-h-10"
aria-hidden="true">{@html logoSvgHtml}</span
>
{:else if logoUrl && logoUrl.trim() !== ""}
<img src={logoUrl} alt="" class="h-10 w-auto object-contain" />
<img src={logoUrl} alt="" class="h-8 lg:h-10 w-auto object-contain" />
{:else}
<span>{t(T.site_name_fallback)}</span>
{/if}
@@ -242,7 +247,7 @@
<div class="lg:hidden flex items-center gap-1">
<button
type="button"
class="p-2 rounded-xs transition-colors flex items-center justify-center"
class="rounded-full border border-wald-700/15 bg-wald-700/8 px-2.5 py-1 transition-opacity hover:opacity-70 inline-flex items-center justify-center"
aria-label={searchOpen
? t(T.header_search_close)
: t(T.header_search_open)}
@@ -253,20 +258,20 @@
{#if searchOpen}
<Icon
icon="lucide:x"
class="text-2xl text-error!"
class="text-sm text-error!"
aria-hidden="true"
/>
{:else}
<Icon
icon="lucide:search"
class="text-2xl"
class="text-sm"
aria-hidden="true"
/>
{/if}
</button>
<button
type="button"
class="p-2 -mr-2 hover:bg-stein-0/10 rounded-xs transition-colors flex items-center justify-center"
class="-mr-1 inline-flex items-center gap-1.5 rounded-full border border-wald-700/15 bg-wald-700/8 px-2.5 py-1 transition-opacity hover:opacity-70"
aria-label={menuOpen
? t(T.header_menu_close)
: t(T.header_menu_open)}
@@ -280,14 +285,11 @@
: t(T.header_menu_open)}</span
>
{#if menuOpen}
<Icon
icon="lucide:x"
class="text-2xl"
aria-hidden="true"
/>
<Icon icon="lucide:x" class="text-sm" aria-hidden="true" />
{:else}
<Icon icon="lucide:menu" class="text-2xl" aria-hidden="true" />
<Icon icon="lucide:menu" class="text-sm" aria-hidden="true" />
{/if}
<span class="text-[.7rem] leading-none" aria-hidden="true">{menuOpen ? "Schließen" : "Menü"}</span>
</button>
</div>
</div>
@@ -298,7 +300,7 @@
{#if menuOpen}
<div
id="mobile-nav"
class="lg:hidden border-t border-stein-0/10 bg-stein-900/98 backdrop-blur max-h-[calc(100dvh-3.5rem)] overflow-y-auto overscroll-contain"
class="lg:hidden absolute left-0 right-0 top-full z-30 shadow-2xl border-t border-stein-0/10 bg-stein-900/90 backdrop-blur-lg max-h-[calc(100dvh-3.5rem)] overflow-y-auto overscroll-contain"
role="dialog"
aria-label="Navigation"
in:slide={{ duration: 200 }}
@@ -308,6 +310,10 @@
class="container-custom pt-4 pb-[calc(2rem+env(safe-area-inset-bottom))] flex flex-col gap-1"
aria-label={t(T.header_nav_aria)}
>
<div class="grid grid-cols-2 gap-2 pb-3 mb-1 border-b border-stein-0/10">
<a href="/mitmachen/" class="btn-primary btn-sm justify-center" onclick={closeMenu}>Mitmachen</a>
<a href="/termin-melden" class="btn-warning btn-sm justify-center" onclick={closeMenu}>Termin melden</a>
</div>
{#each links as link}
{@const active = isActiveTree(link, $page.url.pathname)}
{#if link.children && link.children.length > 0}
@@ -328,7 +334,7 @@
{@const pActive = isActiveLink(link.href, $page.url.pathname)}
<a
href={link.href}
class="block py-2 px-3 text-sm {pActive ? 'font-bold text-wald-300' : 'text-stein-200 hover:text-stein-0'}"
class="block py-3 px-3 text-sm {pActive ? 'font-bold text-wald-300' : 'text-stein-200 hover:text-stein-0'}"
aria-current={pActive ? "page" : undefined}
onclick={closeMenu}
>
@@ -339,7 +345,7 @@
{@const cActive = isActiveLink(child.href, $page.url.pathname)}
<a
href={child.href}
class="block py-2 px-3 text-sm {cActive ? 'font-bold text-wald-300' : 'text-stein-200 hover:text-stein-0'}"
class="block py-3 px-3 text-sm {cActive ? 'font-bold text-wald-300' : 'text-stein-200 hover:text-stein-0'}"
aria-current={cActive ? "page" : undefined}
onclick={closeMenu}
>
@@ -129,6 +129,9 @@
"calendar-search": {
"body": "<g fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"M16 2v4m5 5.75V6a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h7.25M22 22l-1.875-1.875M3 10h18M8 2v4\"/><circle cx=\"18\" cy=\"18\" r=\"3\"/></g>"
},
"plus": {
"body": "<path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 12h14m-7-7v14\"/>"
},
"calendar-plus": {
"body": "<path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M16 19h6M16 2v4m3 10v6m2-9.402V6a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h8.5M3 10h18M8 2v4\"/>"
},