Compare commits

..

2 commits

Author SHA1 Message Date
43cb271077 fix: show the dark mode toast only after the cookie banner is answered
All checks were successful
Deploy to OVH VPS / deploy (push) Successful in 1m9s
2026-09-29 00:36:29 +02:00
7a53279e60 fix: align navbar and footer with the page content width 2026-09-29 00:36:29 +02:00
4 changed files with 60 additions and 7 deletions

View file

@ -1,11 +1,17 @@
--- ---
import { Image } from "astro:assets"; import { Image } from "astro:assets";
import forgejoIcon from "../assets/forgejo.svg"; import forgejoIcon from "../assets/forgejo.svg";
interface Props {
width?: "4xl" | "7xl";
}
const { width = "4xl" } = Astro.props;
const maxWidth = width === "7xl" ? "max-w-7xl" : "max-w-4xl";
--- ---
<div class="w-full bg-secondary dark:bg-gray-800 py-8 px-4 transition-colors duration-200"> <div class="w-full bg-secondary dark:bg-gray-800 py-8 transition-colors duration-200">
<div <div
class="max-w-6xl mx-auto flex justify-between flex-col-reverse sm:flex-row gap-4 sm:items-end items-center" class:list={[maxWidth, "mx-auto px-4 sm:px-6 lg:px-8 flex justify-between flex-col-reverse sm:flex-row gap-4 sm:items-end items-center"]}
> >
<div <div
class="text-center sm:text-left text-gray-800 dark:text-gray-200 flex flex-col items-center sm:items-start" class="text-center sm:text-left text-gray-800 dark:text-gray-200 flex flex-col items-center sm:items-start"

View file

@ -1,11 +1,17 @@
--- ---
interface Props {
// Match the page content: 4xl for reading pages, 7xl for posts with the table of contents
width?: "4xl" | "7xl";
}
const { width = "4xl" } = Astro.props;
const maxWidth = width === "7xl" ? "max-w-7xl" : "max-w-4xl";
const currentPath = Astro.url.pathname; const currentPath = Astro.url.pathname;
--- ---
<nav <nav
class="fixed top-0 left-0 right-0 z-50 bg-secondary dark:bg-gray-800 shadow-sm transition-colors duration-200" class="fixed top-0 left-0 right-0 z-50 bg-secondary dark:bg-gray-800 shadow-sm transition-colors duration-200"
> >
<div class="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8"> <div class={`${maxWidth} mx-auto px-4 sm:px-6 lg:px-8`}>
<div class="flex justify-between items-center h-16"> <div class="flex justify-between items-center h-16">
<!-- Logo/Brand --> <!-- Logo/Brand -->
<a <a

View file

@ -69,6 +69,20 @@ const fullCanonicalUrl = canonicalUrl || `${siteUrl}${Astro.url.pathname}`;
showTitle: false, showTitle: false,
textColor: "#000000", textColor: "#000000",
}, },
// Let the dark mode toast wait until the cookie banner is gone
callback: {
onBannerShown: function () {
window.__iubBannerOpen = true;
},
onPreferenceExpressed: function () {
window.__iubBannerOpen = false;
window.dispatchEvent(new Event("iub-consent"));
},
onReady: function () {
window.__iubReady = true;
window.dispatchEvent(new Event("iub-ready"));
},
},
}; };
</script> </script>
<script <script
@ -310,12 +324,39 @@ const fullCanonicalUrl = canonicalUrl || `${siteUrl}${Astro.url.pathname}`;
const hasBeenDismissed = localStorage.getItem(TOAST_DISMISSED_KEY); const hasBeenDismissed = localStorage.getItem(TOAST_DISMISSED_KEY);
// Only show toast if user is in light mode and hasn't dismissed it // Only show toast if user is in light mode and hasn't dismissed it
setTimeout(() => { const bannerOpen = () =>
window.__iubBannerOpen || !!document.getElementById("iubenda-cs-banner");
const showToast = () => {
if (bannerOpen()) {
window.addEventListener("iub-consent", () => setTimeout(showToast, 1500), { once: true });
return;
}
const isDarkMode = document.documentElement.classList.contains("dark"); const isDarkMode = document.documentElement.classList.contains("dark");
if (!isDarkMode && !hasBeenDismissed && toast) { if (!isDarkMode && !hasBeenDismissed && toast) {
toast.classList.remove("hidden"); toast.classList.remove("hidden");
} }
}, 2000); };
// Never on top of the cookie banner: wait for iubenda, and if the banner
// is open wait for the visitor's answer. If iubenda never loads
// (blocked), show it anyway after a few seconds.
let scheduled = false;
const scheduleToast = (delay) => {
if (scheduled) return;
scheduled = true;
setTimeout(showToast, delay);
};
const afterIubenda = () => {
scheduleToast(2000);
};
if (window.__iubReady) {
afterIubenda();
} else {
window.addEventListener("iub-ready", afterIubenda, { once: true });
setTimeout(() => {
if (!window.__iubReady) scheduleToast(0);
}, 6000);
}
// Enable dark mode // Enable dark mode
if (tryButton) { if (tryButton) {

View file

@ -38,7 +38,7 @@ const heroImageSrc = entry.data.heroImage?.src || mePhoto.src;
modifiedTime={entry.data.updatedDate} modifiedTime={entry.data.updatedDate}
tags={entry.data.tags} tags={entry.data.tags}
> >
<Navbar /> <Navbar width="7xl" />
<div class="min-h-screen pt-16 bg-gray-50 dark:bg-gray-900 transition-colors duration-200"> <div class="min-h-screen pt-16 bg-gray-50 dark:bg-gray-900 transition-colors duration-200">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8 md:py-12"> <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8 md:py-12">
<div class="flex gap-8 items-start"> <div class="flex gap-8 items-start">
@ -200,5 +200,5 @@ const heroImageSrc = entry.data.heroImage?.src || mePhoto.src;
</div> </div>
</div> </div>
</div> </div>
<Footer /> <Footer width="7xl" />
</BaseLayout> </BaseLayout>