Compare commits
2 commits
0d9ac31099
...
d97c92a20b
| Author | SHA1 | Date | |
|---|---|---|---|
| d97c92a20b | |||
| cb4ae6af52 |
5 changed files with 76 additions and 80 deletions
|
|
@ -2,6 +2,7 @@
|
||||||
@tailwind components;
|
@tailwind components;
|
||||||
@tailwind utilities;
|
@tailwind utilities;
|
||||||
|
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Raleway';
|
font-family: 'Raleway';
|
||||||
src: url('../fonts/Raleway-SemiBold.woff2') format('woff2');
|
src: url('../fonts/Raleway-SemiBold.woff2') format('woff2');
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,6 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||||
stickyHeaderFuncionality();
|
stickyHeaderFuncionality();
|
||||||
applyMenuItemClasses();
|
applyMenuItemClasses();
|
||||||
evaluateHeaderPosition();
|
evaluateHeaderPosition();
|
||||||
mobileMenuFunctionality();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
window.stickyHeaderFuncionality = () => {
|
window.stickyHeaderFuncionality = () => {
|
||||||
|
|
@ -33,54 +32,19 @@ window.evaluateHeaderPosition = () => {
|
||||||
);
|
);
|
||||||
headerElement.classList.add(...stickyClasses);
|
headerElement.classList.add(...stickyClasses);
|
||||||
headerElement.classList.remove(...unstickyClasses);
|
headerElement.classList.remove(...unstickyClasses);
|
||||||
document.getElementById("menu").classList.add("top-[56px]");
|
|
||||||
document.getElementById("menu").classList.remove("top-[75px]");
|
|
||||||
} else {
|
} else {
|
||||||
headerElement.firstElementChild.classList.remove(...stickyClassesContainer);
|
headerElement.firstElementChild.classList.remove(...stickyClassesContainer);
|
||||||
headerElement.firstElementChild.classList.add(...unstickyClassesContainer);
|
headerElement.firstElementChild.classList.add(...unstickyClassesContainer);
|
||||||
headerElement.classList.add(...unstickyClasses);
|
headerElement.classList.add(...unstickyClasses);
|
||||||
headerElement.classList.remove(...stickyClasses);
|
headerElement.classList.remove(...stickyClasses);
|
||||||
document.getElementById("menu").classList.remove("top-[56px]");
|
|
||||||
document.getElementById("menu").classList.add("top-[75px]");
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
window.applyMenuItemClasses = () => {
|
window.applyMenuItemClasses = () => {
|
||||||
const menuItems = document.querySelectorAll("#menu a");
|
const menuItems = document.querySelectorAll("#menu a, #mobileMenu a");
|
||||||
for (let i = 0; i < menuItems.length; i++) {
|
for (let i = 0; i < menuItems.length; i++) {
|
||||||
if (menuItems[i].pathname === window.location.pathname) {
|
if (menuItems[i].pathname === window.location.pathname) {
|
||||||
menuItems[i].classList.add("text-neutral-900", "dark:text-white");
|
menuItems[i].classList.add("text-neutral-900", "dark:text-white");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function mobileMenuFunctionality() {
|
|
||||||
document.getElementById("openMenu").addEventListener("click", () => {
|
|
||||||
openMobileMenu();
|
|
||||||
});
|
|
||||||
|
|
||||||
document.getElementById("closeMenu").addEventListener("click", () => {
|
|
||||||
closeMobileMenu();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
window.openMobileMenu = () => {
|
|
||||||
document.getElementById("openMenu").classList.add("hidden");
|
|
||||||
document.getElementById("closeMenu").classList.remove("hidden");
|
|
||||||
document.getElementById("menu").classList.remove("hidden");
|
|
||||||
document.getElementById("mobileMenuBackground").classList.add("opacity-0");
|
|
||||||
document.getElementById("mobileMenuBackground").classList.remove("hidden");
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
document
|
|
||||||
.getElementById("mobileMenuBackground")
|
|
||||||
.classList.remove("opacity-0");
|
|
||||||
}, 1);
|
|
||||||
};
|
|
||||||
|
|
||||||
window.closeMobileMenu = () => {
|
|
||||||
document.getElementById("closeMenu").classList.add("hidden");
|
|
||||||
document.getElementById("openMenu").classList.remove("hidden");
|
|
||||||
document.getElementById("menu").classList.add("hidden");
|
|
||||||
document.getElementById("mobileMenuBackground").classList.add("hidden");
|
|
||||||
};
|
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,9 @@ const menus = {
|
||||||
const currentMenus = menus[currentLang] || menus.fr;
|
const currentMenus = menus[currentLang] || menus.fr;
|
||||||
---
|
---
|
||||||
|
|
||||||
|
<!-- Hidden checkbox to control mobile menu state (CSS-only) -->
|
||||||
|
<input type="checkbox" id="menuToggle" class="hidden peer" aria-hidden="true" />
|
||||||
|
|
||||||
<!-- This is an invisible div with relative position so that it takes up the height of the menu (because menu is absolute/fixed) -->
|
<!-- This is an invisible div with relative position so that it takes up the height of the menu (because menu is absolute/fixed) -->
|
||||||
<div class="relative w-full h-20 opacity-0 pointer-events-none"></div>
|
<div class="relative w-full h-20 opacity-0 pointer-events-none"></div>
|
||||||
<header id="header" class="absolute top-0 z-50 w-full h-20">
|
<header id="header" class="absolute top-0 z-50 w-full h-20">
|
||||||
|
|
@ -36,18 +39,13 @@ const currentMenus = menus[currentLang] || menus.fr;
|
||||||
class="flex items-center justify-between h-full max-w-5xl pl-6 pr-4 mx-auto border-b border-l-0 border-r-0 border-transparent select-none lg:border-r lg:border-l lg:rounded-b-xl"
|
class="flex items-center justify-between h-full max-w-5xl pl-6 pr-4 mx-auto border-b border-l-0 border-r-0 border-transparent select-none lg:border-r lg:border-l lg:rounded-b-xl"
|
||||||
>
|
>
|
||||||
<Logo />
|
<Logo />
|
||||||
<button
|
|
||||||
id="mobileMenuBackground"
|
|
||||||
type="button"
|
|
||||||
aria-label={t('ui', 'closeMenu', currentLang)}
|
|
||||||
class="fixed inset-0 z-20 hidden w-screen h-screen duration-300 ease-out bg-white/90 dark:bg-neutral-950/90 appearance-none border-0 p-0 cursor-default"
|
|
||||||
>
|
|
||||||
</button>
|
|
||||||
<nav
|
<nav
|
||||||
class="relative z-30 flex flex-row-reverse justify-start w-full text-sm sm:justify-end text-neutral-500 dark:text-neutral-400 sm:flex-row"
|
class="relative z-30 flex flex-row-reverse justify-start w-full text-sm sm:justify-end text-neutral-500 dark:text-neutral-400 sm:flex-row"
|
||||||
>
|
>
|
||||||
<div
|
<!-- Hamburger button (open) -->
|
||||||
id="openMenu"
|
<label
|
||||||
|
for="menuToggle"
|
||||||
|
aria-label={t('ui', 'openMenu', currentLang)}
|
||||||
class="flex flex-col items-end justify-center w-6 h-6 ml-4 cursor-pointer sm:hidden"
|
class="flex flex-col items-end justify-center w-6 h-6 ml-4 cursor-pointer sm:hidden"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
|
|
@ -59,38 +57,14 @@ const currentMenus = menus[currentLang] || menus.fr;
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
stroke="currentColor"><path d="M4 8h16M4 16h16"></path></svg
|
stroke="currentColor"><path d="M4 8h16M4 16h16"></path></svg
|
||||||
>
|
>
|
||||||
</div>
|
</label>
|
||||||
<div
|
<!-- Desktop menu -->
|
||||||
id="closeMenu"
|
<div id="menu" class="hidden sm:flex sm:flex-row sm:h-auto sm:w-auto sm:text-sm">
|
||||||
class="flex flex-col items-end justify-center hidden w-6 h-6 ml-4 -translate-x-1 cursor-pointer sm:hidden"
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
class="w-6 h-6 text-neutral-600 dark:text-neutral-200"
|
|
||||||
fill="none"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
stroke-width="2"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
stroke="currentColor"><path d="M6 18L18 6M6 6l12 12"></path></svg
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
id="menu"
|
|
||||||
class="fixed top-[75px] ease-out duration-300 sm:top-0 w-full left-0 sm:py-0 pt-7 pb-4 dm:mx-0 left-0 z-40 flex-col items-end justify-start hidden w-full h-auto text-sm sm:text-base sm:h-auto sm:relative sm:flex-row sm:flex sm:text-sm sm:w-auto sm:pr-0 sm:pt-0"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="absolute inset-0 top-0 right-0 block w-full h-full px-3 sm:hidden"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="relative w-full h-full bg-white border border-dashed border-neutral-300 dark:border-neutral-700 backdrop-blur-sm rounded-xl dark:bg-neutral-950"
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{
|
{
|
||||||
currentMenus.map((menu) => (
|
currentMenus.map((menu) => (
|
||||||
<a
|
<a
|
||||||
href={menu.url}
|
href={menu.url}
|
||||||
class="relative flex items-center justify-center w-full px-3 py-2 font-medium tracking-wide text-center duration-200 ease-out sm:py-0 sm:mb-0 md:w-auto hover:text-neutral-900 dark:hover:text-white"
|
class="relative flex items-center justify-center px-3 font-medium tracking-wide text-center duration-200 ease-out hover:text-neutral-900 dark:hover:text-white"
|
||||||
>
|
>
|
||||||
{menu.name}
|
{menu.name}
|
||||||
</a>
|
</a>
|
||||||
|
|
@ -101,8 +75,64 @@ const currentMenus = menus[currentLang] || menus.fr;
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<script is:inline>
|
<!-- Mobile fullscreen menu (sibling of checkbox, outside header) -->
|
||||||
document.getElementById('mobileMenuBackground').addEventListener('click', function () {
|
<div
|
||||||
window.closeMobileMenu();
|
id="mobileMenu"
|
||||||
});
|
class="mobile-menu fixed top-0 left-0 z-[100] flex-col items-center justify-center bg-white dark:bg-neutral-950"
|
||||||
</script>
|
>
|
||||||
|
<!-- Close button -->
|
||||||
|
<label
|
||||||
|
for="menuToggle"
|
||||||
|
aria-label={t('ui', 'closeMenu', currentLang)}
|
||||||
|
class="absolute top-6 right-6 w-8 h-8 cursor-pointer"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
class="w-8 h-8 text-neutral-600 dark:text-neutral-200"
|
||||||
|
fill="none"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
stroke-width="2"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke="currentColor"><path d="M6 18L18 6M6 6l12 12"></path></svg
|
||||||
|
>
|
||||||
|
</label>
|
||||||
|
{
|
||||||
|
currentMenus.map((menu) => (
|
||||||
|
<a
|
||||||
|
href={menu.url}
|
||||||
|
class="flex items-center justify-center px-3 py-4 text-2xl font-medium tracking-wide text-neutral-700 dark:text-neutral-300 hover:text-neutral-900 dark:hover:text-white duration-200 ease-out"
|
||||||
|
>
|
||||||
|
{menu.name}
|
||||||
|
</a>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* Mobile menu: hidden by default, shown when checkbox is checked */
|
||||||
|
.mobile-menu {
|
||||||
|
display: none;
|
||||||
|
overflow: hidden;
|
||||||
|
width: 100dvw;
|
||||||
|
height: 100dvh;
|
||||||
|
}
|
||||||
|
|
||||||
|
#menuToggle:checked ~ .mobile-menu {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hide menu on desktop regardless of checkbox state */
|
||||||
|
@media (min-width: 640px) {
|
||||||
|
.mobile-menu {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<style is:global>
|
||||||
|
/* Block page scroll when mobile menu is open */
|
||||||
|
html:has(#menuToggle:checked) body {
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
import SquareLine from "./square-line.astro";
|
import SquareLine from "./square-line.astro";
|
||||||
---
|
---
|
||||||
|
|
||||||
<div class="absolute w-full h-auto" style="z-index:-1">
|
<div class="absolute w-full h-auto overflow-hidden" style="z-index:-1">
|
||||||
<div
|
<div
|
||||||
class="absolute top-0 left-0 w-1/2 h-auto bg-neutral-100 dark:bg-neutral-800"
|
class="absolute top-0 left-0 w-1/2 h-auto bg-neutral-100 dark:bg-neutral-800"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,7 @@ export const translations = {
|
||||||
lightMode: { fr: 'Mode clair', en: 'Light mode', ar: 'الوضع الفاتح' },
|
lightMode: { fr: 'Mode clair', en: 'Light mode', ar: 'الوضع الفاتح' },
|
||||||
},
|
},
|
||||||
ui: {
|
ui: {
|
||||||
|
openMenu: { fr: 'Ouvrir le menu', en: 'Open menu', ar: 'فتح القائمة' },
|
||||||
closeMenu: { fr: 'Fermer le menu', en: 'Close menu', ar: 'إغلاق القائمة' },
|
closeMenu: { fr: 'Fermer le menu', en: 'Close menu', ar: 'إغلاق القائمة' },
|
||||||
changeTheme: { fr: 'Changer le thème', en: 'Change theme', ar: 'تغيير المظهر' },
|
changeTheme: { fr: 'Changer le thème', en: 'Change theme', ar: 'تغيير المظهر' },
|
||||||
themeAuto: { fr: 'Thème : automatique', en: 'Theme: auto', ar: 'المظهر: تلقائي' },
|
themeAuto: { fr: 'Thème : automatique', en: 'Theme: auto', ar: 'المظهر: تلقائي' },
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue