From 57ce0fd85d6d67c76c1ac125c784171f7972fa33 Mon Sep 17 00:00:00 2001 From: Jake Jarvis Date: Fri, 6 Mar 2026 09:41:47 -0500 Subject: [PATCH] Fix mobile pinch zoom and content overlapping header/footer on iOS Safari (#3) * Fix mobile pinch zoom and content overlapping header/footer on iOS Safari Add viewport export with maximumScale=1 and userScalable=false to prevent pinch-to-zoom. Add viewportFit=cover for proper safe area support. Fix content rendering above the sticky header and below the fixed mobile tab bar on iOS Safari by adding relative z-0 to the content wrapper, creating a stacking context that keeps page content below both navigation elements. https://claude.ai/code/session_01Re8ndXPAMVMtiHZFVNDK7S * Add safe area inset support for iOS 26 and fix film grain z-index - Add safe-area-inset-top padding to NavBar for notch/Dynamic Island - Add safe-area-inset-left/right to NavBar, main content, and MobileTabBar for landscape mode - Account for safe-area-inset-bottom in content wrapper padding so content isn't hidden behind MobileTabBar + home indicator - Lower film grain overlay z-index from 9999 to 1 to avoid triggering iOS 26 Safari's fixed-element tab tinting behavior https://claude.ai/code/session_01Re8ndXPAMVMtiHZFVNDK7S * Hide ambient glow on mobile where it overwhelms the viewport The 800x600px blurred glow blob dominates narrow mobile screens and clashes with title backdrop images. Hidden below sm breakpoint. https://claude.ai/code/session_01Re8ndXPAMVMtiHZFVNDK7S * Fix asymmetric safe-area insets using separate pl/pr padding The previous px-[max(...,env(safe-area-inset-left))] shorthand applied only the left inset to both sides. Split into separate pl/pr with the correct env() variable for each side. https://claude.ai/code/session_01Re8ndXPAMVMtiHZFVNDK7S --------- Co-authored-by: Claude --- app/(pages)/layout.tsx | 8 ++++---- app/globals.css | 2 +- app/layout.tsx | 10 +++++++++- components/mobile-tab-bar.tsx | 2 +- components/nav-bar.tsx | 4 ++-- 5 files changed, 17 insertions(+), 9 deletions(-) diff --git a/app/(pages)/layout.tsx b/app/(pages)/layout.tsx index c014929..ed97bbf 100644 --- a/app/(pages)/layout.tsx +++ b/app/(pages)/layout.tsx @@ -18,13 +18,13 @@ export default async function PagesLayout({ return ( -
+
- {/* Ambient glow */} -
+ {/* Ambient glow — hidden on mobile where it overwhelms the viewport */} +
{children}
diff --git a/app/globals.css b/app/globals.css index f2399b0..5f92670 100644 --- a/app/globals.css +++ b/app/globals.css @@ -102,7 +102,7 @@ content: ""; position: fixed; inset: 0; - z-index: 9999; + z-index: 1; pointer-events: none; opacity: 0.015; background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)'/%3E%3C/svg%3E"); diff --git a/app/layout.tsx b/app/layout.tsx index ee4af8c..41c9f79 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -1,5 +1,5 @@ import { MotionConfig } from "motion/react"; -import type { Metadata } from "next"; +import type { Metadata, Viewport } from "next"; import { DM_Sans, DM_Serif_Display, Geist_Mono } from "next/font/google"; import { TooltipProvider } from "@/components/ui/tooltip"; @@ -28,6 +28,14 @@ export const metadata: Metadata = { themeColor: "#090706", }; +export const viewport: Viewport = { + width: "device-width", + initialScale: 1, + maximumScale: 1, + userScalable: false, + viewportFit: "cover", +}; + export default function RootLayout({ children, }: Readonly<{ diff --git a/components/mobile-tab-bar.tsx b/components/mobile-tab-bar.tsx index 09013a1..4dffeac 100644 --- a/components/mobile-tab-bar.tsx +++ b/components/mobile-tab-bar.tsx @@ -19,7 +19,7 @@ export function MobileTabBar() { if (!session?.user) return null; return ( -