From f5df384b13e4d02a54732e7893d25cd20e9cf557 Mon Sep 17 00:00:00 2001 From: Marco Date: Sun, 19 Jul 2026 20:03:12 +0000 Subject: [PATCH] fix(Navbar): stop backdrop-blur from breaking NewsletterModal's fixed positioning backdrop-filter (backdrop-blur-md, applied to the sticky header once scrolled) creates a new containing block for position:fixed descendants, same as transform does. NewsletterModal was rendered inside that header, so its `fixed inset-0` backdrop silently stopped being fixed to the viewport once scrolled and became fixed to the 100px header instead, clipping the modal to the top of the page. Moved the modal to be a sibling of
instead of a child. Co-Authored-By: Claude Sonnet 5 --- app/components/Navbar.tsx | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/app/components/Navbar.tsx b/app/components/Navbar.tsx index b65d208..6ff0acd 100644 --- a/app/components/Navbar.tsx +++ b/app/components/Navbar.tsx @@ -252,6 +252,20 @@ export function Navbar() { const closeMobile = () => setMobileOpen(false); return ( + // Fragment, not just the
— NewsletterModal must NOT be a + // descendant of it. `backdrop-blur-md` below is a `backdrop-filter`, + // which (like `transform`) makes its element a new containing block + // for `position: fixed` descendants per spec. Since the header only + // gets that class once `scrolled` is true, the modal's `fixed inset-0` + // backdrop silently stopped being fixed to the viewport and became + // fixed to the 100px-tall header instead — centering math then ran + // against that instead of the viewport, clipping the modal to the top + // of the page. Exactly reproduced whenever the modal was opened while + // scrolled (e.g. after clicking an anchor link), never at the very + // top of the page (scrollY <= 8, no backdrop-blur yet) — which is why + // it looked tied to "clicked an anchor first" rather than to scroll + // position itself. + <>
+
setNewsletterOpen(false)} /> -
+ ); }