Enhance site configuration and layout with modern styling, improved font usage, and updated service components. Refactor navigation and footer for better accessibility and user experience, while ensuring inline definitions to resolve import issues.
This commit is contained in:
@@ -8,115 +8,252 @@ const lang = getLangFromUrl(Astro.url);
|
||||
const t = await useTranslations(lang);
|
||||
---
|
||||
|
||||
<header class="sticky top-0 z-50 w-full border-b border-border/40 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
|
||||
<nav class="container-custom">
|
||||
<div class="flex h-16 items-center justify-between">
|
||||
<!-- Logo -->
|
||||
<div class="flex items-center">
|
||||
<a href={localizePath("/", lang)} class="flex items-center space-x-2">
|
||||
<div class="h-8 w-8 flex items-center justify-center">
|
||||
<img
|
||||
src="/images/TIBER365.png"
|
||||
alt="Tiber365 Logo"
|
||||
class="h-6 w-6 object-contain"
|
||||
/>
|
||||
</div>
|
||||
<span class="font-display font-bold text-xl text-foreground">Tiber365</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Desktop Navigation -->
|
||||
<div class="hidden md:flex items-center space-x-6">
|
||||
{NAVIGATION.map((item) => (
|
||||
<a
|
||||
href={item.type === 'external' ? item.href : localizePath(item.href, lang)}
|
||||
target={item.type === 'external' ? '_blank' : undefined}
|
||||
rel={item.type === 'external' ? 'noopener noreferrer' : undefined}
|
||||
class="text-sm font-medium text-muted-foreground hover:text-foreground transition-colors relative group"
|
||||
>
|
||||
{t(item.label)}
|
||||
{item.type === 'external' && (
|
||||
<svg class="inline h-3 w-3 ml-1 opacity-70" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"/>
|
||||
</svg>
|
||||
)}
|
||||
<span class="absolute inset-x-0 -bottom-1 h-0.5 bg-primary scale-x-0 group-hover:scale-x-100 transition-transform origin-left"></span>
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<!-- Theme Toggle & Language Switcher -->
|
||||
<div class="flex items-center space-x-4">
|
||||
<LanguageSwitcher />
|
||||
<ThemeToggle />
|
||||
<header class="fixed top-0 left-0 right-0 z-50 transition-all duration-500" id="main-header">
|
||||
<!-- Glass morphism navigation -->
|
||||
<nav class="nav-glass">
|
||||
<div class="container-custom">
|
||||
<div class="flex h-20 items-center justify-between">
|
||||
|
||||
<!-- Mobile Menu Button -->
|
||||
<button
|
||||
id="mobile-menu-button"
|
||||
class="md:hidden inline-flex items-center justify-center p-2 rounded-md text-muted-foreground hover:text-foreground hover:bg-accent focus:outline-none focus:ring-2 focus:ring-primary"
|
||||
aria-expanded="false"
|
||||
aria-label="Toggle mobile menu"
|
||||
>
|
||||
<svg id="mobile-menu-icon" class="h-6 w-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"/>
|
||||
</svg>
|
||||
<svg id="mobile-close-icon" class="h-6 w-6 hidden" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
|
||||
</svg>
|
||||
</button>
|
||||
<!-- Logo with modern styling -->
|
||||
<div class="flex items-center">
|
||||
<a href={localizePath("/", lang)} class="group flex items-center space-x-3 transition-all">
|
||||
<div class="relative">
|
||||
<div class="absolute inset-0 bg-primary/20 rounded-xl blur-md opacity-0 group-hover:opacity-100 transition-opacity"></div>
|
||||
<div class="relative h-10 w-10 bg-gradient-to-br from-primary to-accent rounded-xl flex items-center justify-center">
|
||||
<img
|
||||
src="/images/TIBER365.png"
|
||||
alt="Tiber365 Logo"
|
||||
class="h-6 w-6 object-contain brightness-0 invert"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<span class="font-bold text-lg text-foreground group-hover:text-primary transition-colors">Tiber365</span>
|
||||
<span class="text-xs text-subtle -mt-1">IT Excellence</span>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Desktop Navigation with modern hover effects -->
|
||||
<div class="hidden lg:flex items-center space-x-1">
|
||||
{NAVIGATION.map((item) => (
|
||||
<a
|
||||
href={item.type === 'external' ? item.href : localizePath(item.href, lang)}
|
||||
target={item.type === 'external' ? '_blank' : undefined}
|
||||
rel={item.type === 'external' ? 'noopener noreferrer' : undefined}
|
||||
class="relative px-4 py-2 text-sm font-medium text-muted hover:text-foreground transition-all duration-300 rounded-lg group"
|
||||
>
|
||||
<span class="relative z-10 flex items-center gap-1">
|
||||
{t(item.label)}
|
||||
{item.type === 'external' && (
|
||||
<svg class="h-3 w-3 opacity-60" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"/>
|
||||
</svg>
|
||||
)}
|
||||
</span>
|
||||
<!-- Hover background -->
|
||||
<div class="absolute inset-0 bg-surface/50 rounded-lg opacity-0 group-hover:opacity-100 transition-all duration-300 scale-95 group-hover:scale-100"></div>
|
||||
<!-- Active indicator -->
|
||||
<div class="absolute bottom-0 left-1/2 transform -translate-x-1/2 w-0 h-0.5 bg-gradient-to-r from-primary to-accent group-hover:w-full transition-all duration-300"></div>
|
||||
</a>
|
||||
))}
|
||||
|
||||
<!-- CTA Button in nav -->
|
||||
<a
|
||||
href={localizePath("/contact", lang)}
|
||||
class="ml-4 btn btn-primary btn-sm"
|
||||
>
|
||||
Get Started
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Right side controls -->
|
||||
<div class="flex items-center space-x-3">
|
||||
<!-- Language switcher with modern styling -->
|
||||
<LanguageSwitcher />
|
||||
|
||||
<!-- Theme toggle with modern animation -->
|
||||
<ThemeToggle />
|
||||
|
||||
<!-- Mobile Menu Button -->
|
||||
<button
|
||||
id="mobile-menu-button"
|
||||
class="lg:hidden p-2 rounded-xl bg-surface/50 border border-border/50 text-muted hover:text-foreground hover:bg-surface transition-all"
|
||||
aria-expanded="false"
|
||||
aria-label="Toggle mobile menu"
|
||||
>
|
||||
<svg id="mobile-menu-icon" class="h-5 w-5 transition-transform" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"/>
|
||||
</svg>
|
||||
<svg id="mobile-close-icon" class="h-5 w-5 hidden transition-transform" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Mobile Navigation -->
|
||||
<div id="mobile-menu" class="md:hidden hidden border-t border-border">
|
||||
<div class="px-2 pt-2 pb-3 space-y-1">
|
||||
{NAVIGATION.map((item) => (
|
||||
<a
|
||||
href={item.type === 'external' ? item.href : localizePath(item.href, lang)}
|
||||
target={item.type === 'external' ? '_blank' : undefined}
|
||||
rel={item.type === 'external' ? 'noopener noreferrer' : undefined}
|
||||
class="block px-3 py-2 text-base font-medium text-muted-foreground hover:text-foreground hover:bg-accent rounded-md transition-colors"
|
||||
>
|
||||
{t(item.label)}
|
||||
{item.type === 'external' && (
|
||||
<svg class="inline h-4 w-4 ml-1 opacity-70" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"/>
|
||||
<!-- Mobile Navigation Menu -->
|
||||
<div id="mobile-menu" class="lg:hidden hidden border-t border-border/50">
|
||||
<div class="container-custom py-6">
|
||||
<div class="space-y-2">
|
||||
{NAVIGATION.map((item) => (
|
||||
<a
|
||||
href={item.type === 'external' ? item.href : localizePath(item.href, lang)}
|
||||
target={item.type === 'external' ? '_blank' : undefined}
|
||||
rel={item.type === 'external' ? 'noopener noreferrer' : undefined}
|
||||
class="flex items-center justify-between p-4 text-base font-medium text-muted hover:text-foreground hover:bg-surface/50 rounded-xl transition-all group"
|
||||
>
|
||||
<span class="flex items-center gap-2">
|
||||
{t(item.label)}
|
||||
{item.type === 'external' && (
|
||||
<svg class="h-4 w-4 opacity-60" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"/>
|
||||
</svg>
|
||||
)}
|
||||
</span>
|
||||
<svg class="h-4 w-4 opacity-40 group-hover:opacity-60 transition-all" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"/>
|
||||
</svg>
|
||||
)}
|
||||
</a>
|
||||
))}
|
||||
</a>
|
||||
))}
|
||||
|
||||
<!-- Mobile CTA -->
|
||||
<div class="pt-4 mt-4 border-t border-border/50">
|
||||
<a
|
||||
href={localizePath("/contact", lang)}
|
||||
class="btn btn-primary w-full justify-center"
|
||||
>
|
||||
Get Started Today
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Progress bar for scroll -->
|
||||
<div class="absolute bottom-0 left-0 h-0.5 bg-gradient-to-r from-primary to-accent transition-all duration-300" id="scroll-progress"></div>
|
||||
</header>
|
||||
|
||||
<script>
|
||||
// Mobile menu functionality
|
||||
// Enhanced mobile menu functionality with animations
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const header = document.getElementById('main-header');
|
||||
const mobileMenuButton = document.getElementById('mobile-menu-button');
|
||||
const mobileMenu = document.getElementById('mobile-menu');
|
||||
const menuIcon = document.getElementById('mobile-menu-icon');
|
||||
const closeIcon = document.getElementById('mobile-close-icon');
|
||||
const scrollProgress = document.getElementById('scroll-progress');
|
||||
|
||||
// Header scroll effect
|
||||
let lastScrollY = window.scrollY;
|
||||
|
||||
function updateHeader() {
|
||||
const currentScrollY = window.scrollY;
|
||||
|
||||
if (currentScrollY > 100) {
|
||||
header?.classList.add('backdrop-blur-xl', 'bg-background/80');
|
||||
header?.classList.remove('bg-transparent');
|
||||
} else {
|
||||
header?.classList.remove('backdrop-blur-xl', 'bg-background/80');
|
||||
header?.classList.add('bg-transparent');
|
||||
}
|
||||
|
||||
// Hide/show header on scroll
|
||||
if (currentScrollY > lastScrollY && currentScrollY > 100) {
|
||||
header?.classList.add('-translate-y-full');
|
||||
} else {
|
||||
header?.classList.remove('-translate-y-full');
|
||||
}
|
||||
|
||||
lastScrollY = currentScrollY;
|
||||
|
||||
// Update progress bar
|
||||
const scrollPercentage = (currentScrollY / (document.documentElement.scrollHeight - window.innerHeight)) * 100;
|
||||
if (scrollProgress) {
|
||||
scrollProgress.style.width = `${Math.min(scrollPercentage, 100)}%`;
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener('scroll', updateHeader, { passive: true });
|
||||
|
||||
// Mobile menu toggle with enhanced animations
|
||||
if (mobileMenuButton && mobileMenu && menuIcon && closeIcon) {
|
||||
mobileMenuButton.addEventListener('click', () => {
|
||||
const isExpanded = mobileMenuButton.getAttribute('aria-expanded') === 'true';
|
||||
const newState = !isExpanded;
|
||||
|
||||
mobileMenuButton.setAttribute('aria-expanded', (!isExpanded).toString());
|
||||
mobileMenu.classList.toggle('hidden');
|
||||
menuIcon.classList.toggle('hidden');
|
||||
closeIcon.classList.toggle('hidden');
|
||||
});
|
||||
|
||||
// Close mobile menu when clicking outside
|
||||
document.addEventListener('click', (event) => {
|
||||
if (!mobileMenuButton.contains(event.target as Node) && !mobileMenu.contains(event.target as Node)) {
|
||||
mobileMenuButton.setAttribute('aria-expanded', 'false');
|
||||
mobileMenu.classList.add('hidden');
|
||||
mobileMenuButton.setAttribute('aria-expanded', newState.toString());
|
||||
|
||||
if (newState) {
|
||||
mobileMenu.classList.remove('hidden');
|
||||
// Animate in
|
||||
requestAnimationFrame(() => {
|
||||
mobileMenu.style.opacity = '0';
|
||||
mobileMenu.style.transform = 'translateY(-10px)';
|
||||
mobileMenu.style.transition = 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)';
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
mobileMenu.style.opacity = '1';
|
||||
mobileMenu.style.transform = 'translateY(0)';
|
||||
});
|
||||
});
|
||||
|
||||
menuIcon.classList.add('hidden');
|
||||
closeIcon.classList.remove('hidden');
|
||||
document.body.style.overflow = 'hidden';
|
||||
} else {
|
||||
// Animate out
|
||||
mobileMenu.style.opacity = '0';
|
||||
mobileMenu.style.transform = 'translateY(-10px)';
|
||||
|
||||
setTimeout(() => {
|
||||
mobileMenu.classList.add('hidden');
|
||||
document.body.style.overflow = '';
|
||||
}, 300);
|
||||
|
||||
menuIcon.classList.remove('hidden');
|
||||
closeIcon.classList.add('hidden');
|
||||
}
|
||||
});
|
||||
|
||||
// Close menu when clicking outside
|
||||
document.addEventListener('click', (event) => {
|
||||
if (!mobileMenuButton.contains(event.target as Node) &&
|
||||
!mobileMenu.contains(event.target as Node) &&
|
||||
!mobileMenu.classList.contains('hidden')) {
|
||||
mobileMenuButton.click();
|
||||
}
|
||||
});
|
||||
|
||||
// Close menu on escape key
|
||||
document.addEventListener('keydown', (event) => {
|
||||
if (event.key === 'Escape' && !mobileMenu.classList.contains('hidden')) {
|
||||
mobileMenuButton.click();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</script>
|
||||
|
||||
<style>
|
||||
/* Enhanced mobile menu animations */
|
||||
#mobile-menu {
|
||||
backdrop-filter: blur(20px);
|
||||
-webkit-backdrop-filter: blur(20px);
|
||||
}
|
||||
|
||||
/* Smooth header transitions */
|
||||
#main-header {
|
||||
transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1),
|
||||
background-color 0.3s cubic-bezier(0.4, 0, 0.2, 1),
|
||||
backdrop-filter 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
/* Logo hover effect */
|
||||
.group:hover .brightness-0 {
|
||||
filter: brightness(1) invert(0);
|
||||
transition: filter 0.3s ease;
|
||||
}
|
||||
</style>
|
Reference in New Issue
Block a user