84e843479d
ci/woodpecker/push/woodpecker Pipeline was successful
- nuxt-umami@3.2.1 installé, module configuré (host + website ID) - suppression injection script manuelle dans app.vue - TheHeader : logo § repassé en tracé SVG unique avec dégradé primary→accent Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
125 lines
3.6 KiB
Vue
125 lines
3.6 KiB
Vue
<template>
|
|
<header class="sticky top-0 z-40 border-b border-[hsl(var(--color-text)/0.08)] bg-[hsl(var(--color-bg)/0.85)] backdrop-blur-xl">
|
|
<div class="container-content flex h-[var(--header-height)] items-center justify-between px-4">
|
|
<!-- Logo -->
|
|
<NuxtLink to="/" class="logo-link flex items-center gap-2.5">
|
|
<svg class="logo-icon" viewBox="0 0 46 78" fill="none" aria-hidden="true">
|
|
<defs>
|
|
<linearGradient id="sect-grad" x1="0" y1="0" x2="0" y2="1">
|
|
<stop offset="0%" stop-color="hsl(var(--color-primary))"/>
|
|
<stop offset="100%" stop-color="hsl(var(--color-accent))"/>
|
|
</linearGradient>
|
|
</defs>
|
|
<path
|
|
d="M 33 10 C 26 7 18 7 14 11 C 8 15 7 24 10 31 C 13 38 21 40 27 44 C 33 48 38 55 35 62 C 32 69 24 72 17 70 C 10 68 8 72 10 75 C 12 78 20 79 28 76"
|
|
stroke="url(#sect-grad)"
|
|
stroke-width="5"
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
fill="none"
|
|
/>
|
|
</svg>
|
|
<span class="logo-text">{{ site?.identity.name }}</span>
|
|
</NuxtLink>
|
|
|
|
<!-- Desktop navigation -->
|
|
<nav class="hidden md:flex items-center gap-1" aria-label="Navigation principale">
|
|
<!-- Autonomie : prefix + axis buttons -->
|
|
<span class="nav-prefix">Autonomie :</span>
|
|
<NuxtLink
|
|
v-for="item in axes"
|
|
:key="item.to"
|
|
:to="item.to"
|
|
class="btn-ghost text-sm"
|
|
active-class="!text-[hsl(var(--color-text))] bg-[hsl(var(--color-text)/0.06)]"
|
|
>
|
|
{{ item.label }}
|
|
</NuxtLink>
|
|
|
|
<!-- Separator + extra nav -->
|
|
<span class="nav-sep" />
|
|
<NuxtLink
|
|
v-for="item in extra"
|
|
:key="item.to"
|
|
:to="item.to"
|
|
class="btn-ghost btn-ghost--muted text-sm"
|
|
active-class="!text-[hsl(var(--color-text))] bg-[hsl(var(--color-text)/0.06)]"
|
|
>
|
|
{{ item.label }}
|
|
</NuxtLink>
|
|
|
|
<UiPaletteSelector />
|
|
</nav>
|
|
|
|
<!-- Mobile menu button -->
|
|
<button
|
|
class="btn-ghost md:hidden !p-2"
|
|
aria-label="Menu"
|
|
@click="isMobileMenuOpen = true"
|
|
>
|
|
<div class="i-lucide-menu h-5 w-5" />
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Mobile menu -->
|
|
<LayoutNavMobile v-model:open="isMobileMenuOpen" :nav="allNav" />
|
|
</header>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
const { data: site } = await useSiteContent()
|
|
const isMobileMenuOpen = ref(false)
|
|
|
|
const axes = computed(() => (site.value as any)?.navigation?.axes ?? [])
|
|
const extra = computed(() => (site.value as any)?.navigation?.extra ?? [])
|
|
const allNav = computed(() => [...axes.value, ...extra.value])
|
|
</script>
|
|
|
|
<style scoped>
|
|
.logo-link {
|
|
transition: opacity 0.2s;
|
|
}
|
|
.logo-link:hover {
|
|
opacity: 0.8;
|
|
}
|
|
|
|
.logo-icon {
|
|
width: 1.6rem;
|
|
height: 2rem;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.logo-text {
|
|
font-family: var(--font-display);
|
|
font-weight: 400;
|
|
font-size: 1.25rem;
|
|
letter-spacing: 0.04em;
|
|
background-image: linear-gradient(to right, hsl(var(--color-primary)), hsl(var(--color-accent)));
|
|
-webkit-background-clip: text;
|
|
background-clip: text;
|
|
-webkit-text-fill-color: transparent;
|
|
}
|
|
|
|
.nav-prefix {
|
|
font-family: var(--font-display);
|
|
font-size: 0.92rem;
|
|
font-weight: 500;
|
|
font-style: italic;
|
|
letter-spacing: 0.03em;
|
|
color: hsl(var(--color-text) / 0.4);
|
|
margin-right: 0.125rem;
|
|
}
|
|
|
|
.nav-sep {
|
|
display: block;
|
|
width: 1px;
|
|
height: 1.25rem;
|
|
background: hsl(var(--color-text) / 0.12);
|
|
margin: 0 0.375rem;
|
|
}
|
|
|
|
.btn-ghost--muted {
|
|
color: hsl(var(--color-text) / 0.45);
|
|
}
|
|
</style>
|