diff --git a/src/App.svelte b/src/App.svelte index e2b91ee..4fd9c5b 100644 --- a/src/App.svelte +++ b/src/App.svelte @@ -64,6 +64,12 @@ img.src = BG_URL } + // Sync body[data-template] with the active template so CSS selectors (e.g. footer hide) + // stay correct on SPA navigation — PHP only sets it on the initial page load. + $effect(() => { + if (activeTemplate) document.body.dataset.template = activeTemplate + }) + // Active la transition seulement après le premier paint à la bonne position. // Double rAF : le premier laisse passer un paint avec le bon translateX, // le second active is-animated — évite l'animation parasite au chargement. diff --git a/src/components/layout/Footer.svelte b/src/components/layout/Footer.svelte index de0ef80..7080d01 100644 --- a/src/components/layout/Footer.svelte +++ b/src/components/layout/Footer.svelte @@ -23,8 +23,14 @@ function onScroll() { if (rafId) return rafId = requestAnimationFrame(() => { - const threshold = window.innerWidth > 800 ? 100 : 200 - const atBottom = scrollableContainer.scrollTop >= scrollableContainer.scrollHeight - scrollableContainer.clientHeight - threshold + const scrollHeight = scrollableContainer.scrollHeight + const clientHeight = scrollableContainer.clientHeight + const threshold = window.innerWidth > 800 ? 100 : 200 + // Only show footer when content actually overflows AND user is near the bottom. + // Without the overflow guard, atBottom is true even when scrollHeight === clientHeight + // (0 >= 0 - threshold), causing the footer to appear on pages with no scroll. + const overflows = scrollHeight > clientHeight + const atBottom = overflows && scrollableContainer.scrollTop >= scrollHeight - clientHeight - threshold isHidden = !atBottom rafId = null })