Spaces:
Running
Running
File size: 5,046 Bytes
afa9e42 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
---
import { getLangFromUrl, useTranslations } from '../i18n/ui';
import LanguageSelector from './LanguageSelector.astro';
import ThemeToggle from './ThemeToggle.astro';
import { Menu, X } from 'lucide-astro';
const lang = getLangFromUrl(Astro.url);
const t = useTranslations(lang);
---
<header class="fixed top-0 left-0 right-0 z-50 transition-all duration-300" data-header>
<nav class="container-custom">
<div class="flex items-center justify-between h-20 px-4 transition-all duration-300" data-nav-container>
<!-- Logo -->
<a href={lang === 'ar' ? '/' : `/${lang}`} class="flex items-center">
<img
src="/logo.jpg"
alt="Blueprint Engineering Consultancy Logo"
class="h-14 w-auto transition-all duration-300"
data-logo
/>
</a>
<!-- Desktop Navigation -->
<div class="hidden lg:flex items-center space-x-8 rtl:space-x-reverse">
<a href="#about" class="nav-link">{t('nav.about')}</a>
<a href="#services" class="nav-link">{t('nav.services')}</a>
<a href="#workflow" class="nav-link">{t('nav.workflow')}</a>
<a href="#contact" class="nav-link">{t('nav.contact')}</a>
</div>
<!-- Language Selector & Theme Toggle -->
<div class="flex items-center space-x-4 rtl:space-x-reverse">
<ThemeToggle />
<LanguageSelector />
<!-- Mobile Menu Button -->
<button class="lg:hidden text-white p-2" data-mobile-menu-toggle>
<Menu class="w-6 h-6" data-menu-icon />
<X class="w-6 h-6 hidden" data-close-icon />
</button>
</div>
</div>
<!-- Mobile Navigation -->
<div class="lg:hidden hidden bg-blueprint-primary/95 backdrop-blur-md border-t border-blueprint-accent/20" data-mobile-menu>
<div class="px-4 py-4 space-y-4">
<a href="#about" class="block nav-link">{t('nav.about')}</a>
<a href="#services" class="block nav-link">{t('nav.services')}</a>
<a href="#workflow" class="block nav-link">{t('nav.workflow')}</a>
<a href="#contact" class="block nav-link">{t('nav.contact')}</a>
</div>
</div>
</nav>
</header>
<script>
// Mobile menu toggle
const mobileMenuToggle = document.querySelector('[data-mobile-menu-toggle]');
const mobileMenu = document.querySelector('[data-mobile-menu]');
const menuIcon = document.querySelector('[data-menu-icon]');
const closeIcon = document.querySelector('[data-close-icon]');
mobileMenuToggle?.addEventListener('click', () => {
mobileMenu?.classList.toggle('hidden');
menuIcon?.classList.toggle('hidden');
closeIcon?.classList.toggle('hidden');
});
// Header scroll effects
let lastScrollTop = 0;
const header = document.querySelector('[data-header]') as HTMLElement;
const navContainer = document.querySelector('[data-nav-container]') as HTMLElement;
const logo = document.querySelector('[data-logo]') as HTMLElement;
function updateHeader() {
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
if (scrollTop > 50) {
// Scrolled state
header.classList.add('bg-blueprint-primary/95', 'backdrop-blur-md', 'border-b', 'border-blueprint-accent/20', 'shadow-lg');
navContainer.classList.add('h-16');
navContainer.classList.remove('h-20');
logo.classList.add('h-10');
logo.classList.remove('h-14');
} else {
// Top state
header.classList.remove('bg-blueprint-primary/95', 'backdrop-blur-md', 'border-b', 'border-blueprint-accent/20', 'shadow-lg');
navContainer.classList.remove('h-16');
navContainer.classList.add('h-20');
logo.classList.remove('h-10');
logo.classList.add('h-14');
}
// Hide/show header on scroll
if (scrollTop > lastScrollTop && scrollTop > 100) {
// Scrolling down
header.style.transform = 'translateY(-100%)';
} else {
// Scrolling up
header.style.transform = 'translateY(0)';
}
lastScrollTop = scrollTop <= 0 ? 0 : scrollTop;
}
window.addEventListener('scroll', updateHeader);
// Initial call
updateHeader();
// Smooth scroll for anchor links
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function (e) {
e.preventDefault();
const target = document.querySelector(this.getAttribute('href'));
if (target) {
const headerHeight = header?.offsetHeight || 0;
const targetPosition = target.offsetTop - headerHeight - 20;
window.scrollTo({
top: targetPosition,
behavior: 'smooth'
});
// Close mobile menu if open
mobileMenu?.classList.add('hidden');
menuIcon?.classList.remove('hidden');
closeIcon?.classList.add('hidden');
}
});
});
</script>
<style>
.nav-link {
@apply text-white hover:text-blueprint-accent transition-colors duration-300 font-medium;
}
.nav-link:hover {
@apply text-blueprint-accent;
}
</style> |