Files
Montech_Landing/apps/landing/components/layout/SiteHeader.vue
T

95 lines
5.3 KiB
Vue
Raw Normal View History

<template>
<header class="sticky top-0 z-50 transition-all duration-300 bg-white/90 dark:bg-[#0b1329]/90 backdrop-blur-xl border-b border-slate-200/70 dark:border-slate-800/80 shadow-sm">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 h-20 flex items-center justify-between">
<div class="flex items-center gap-3">
<ThemeToggle />
<button
type="button"
class="hidden sm:inline-flex items-center gap-2.5 px-6 py-2.5 rounded-full bg-brand-600 hover:bg-brand-700 active:scale-95 text-white text-sm font-semibold transition-all duration-300 shadow-md shadow-brand-600/25 group"
@click="consult.open()"
>
<span class="w-6 h-6 rounded-full bg-white/20 flex items-center justify-center -mr-1 transition-transform group-hover:-translate-x-1">
<svg class="w-3.5 h-3.5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M10 19l-7-7m0 0l7-7m-7 7h18" />
</svg>
</span>
<span>{{ header.ctaLabel }}</span>
</button>
<button
type="button"
class="md:hidden p-2 rounded-xl text-slate-700 dark:text-slate-300 hover:bg-slate-100 dark:hover:bg-slate-800 transition-colors focus:outline-none"
:aria-expanded="isMobileMenuOpen"
aria-controls="mobile-nav"
:aria-label="isMobileMenuOpen ? 'بستن منو' : 'باز کردن منو'"
@click="isMobileMenuOpen = !isMobileMenuOpen"
>
<svg v-if="!isMobileMenuOpen" class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" />
</svg>
<svg v-else class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
</div>
<nav class="hidden md:flex items-center gap-8 text-sm font-semibold text-slate-600 dark:text-slate-300" aria-label="منوی اصلی">
<a
v-for="link in desktopNav"
:key="link.href + link.label"
:href="resolveHref(link.href)"
class="hover:text-brand-600 dark:hover:text-brand-400 transition-colors duration-200"
>{{ link.label }}</a>
</nav>
<a :href="resolveHref('#')" class="flex items-center gap-3 group focus:outline-none" :aria-label="header.brandTitle">
<div class="flex flex-col text-right">
<span class="text-2xl font-black tracking-tight text-slate-900 dark:text-white group-hover:text-brand-600 dark:group-hover:text-brand-400 transition-colors">{{ header.brandTitle }}</span>
<span class="text-[9px] font-black text-slate-400 dark:text-slate-500 tracking-[0.25em] uppercase -mt-1">{{ header.brandSubtitle }}</span>
</div>
<div class="relative flex items-center justify-center w-11 h-11 rounded-2xl bg-gradient-to-br from-brand-600 via-brand-500 to-sky-400 text-white shadow-md shadow-brand-600/25 transition-all duration-500 group-hover:scale-105 group-hover:shadow-brand-600/40">
<svg class="w-7 h-7" viewBox="0 0 32 32" fill="none" aria-hidden="true">
<path d="M6 22L12 8L16 15L20 8L26 22" stroke="white" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" />
<circle cx="16" cy="22" r="2.2" fill="white" />
</svg>
</div>
</a>
</div>
<transition
enter-active-class="transition duration-300 ease-out"
enter-from-class="transform -translate-y-4 opacity-0"
enter-to-class="transform translate-y-0 opacity-100"
leave-active-class="transition duration-200 ease-in"
leave-from-class="transform translate-y-0 opacity-100"
leave-to-class="transform -translate-y-4 opacity-0"
>
<div v-if="isMobileMenuOpen" id="mobile-nav" class="md:hidden bg-white/95 dark:bg-[#0b1329]/95 backdrop-blur-xl border-b border-slate-200 dark:border-slate-800 px-6 py-5 space-y-4 shadow-2xl">
<a
v-for="link in header.nav"
:key="link.href + link.label"
:href="resolveHref(link.href)"
class="block text-base font-semibold text-slate-700 dark:text-slate-200 hover:text-brand-600 dark:hover:text-brand-400"
@click="isMobileMenuOpen = false"
>{{ link.label }}</a>
<div class="pt-2 flex flex-col gap-2">
<button type="button" class="w-full flex items-center justify-center gap-2 py-3 rounded-full bg-brand-600 text-white font-bold shadow-md" @click="consult.open(); isMobileMenuOpen = false">
<span>{{ header.ctaLabel }}</span>
<svg class="w-4 h-4 rotate-180" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14 5l7 7m0 0l-7 7m7-7H3" /></svg>
</button>
</div>
</div>
</transition>
</header>
</template>
<script setup lang="ts">
const { section } = useSiteContent();
const header = section("header");
const consult = useConsultModal();
const isMobileMenuOpen = ref(false);
const desktopNav = computed(() => [...header.value.nav].reverse());
const resolveHref = useSectionHref();
</script>