mirror of
https://github.com/jakejarvis/sofa.git
synced 2026-08-29 01:35:39 -04:00
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 <noreply@anthropic.com>
This commit is contained in:
@@ -18,13 +18,13 @@ export default async function PagesLayout({
|
|||||||
return (
|
return (
|
||||||
<StoreProvider>
|
<StoreProvider>
|
||||||
<ProgressProvider>
|
<ProgressProvider>
|
||||||
<div className="min-h-screen pb-14 sm:pb-0">
|
<div className="relative z-0 min-h-screen pb-[calc(3.5rem+env(safe-area-inset-bottom))] sm:pb-0">
|
||||||
<NavBar />
|
<NavBar />
|
||||||
{/* Ambient glow */}
|
{/* Ambient glow — hidden on mobile where it overwhelms the viewport */}
|
||||||
<div className="pointer-events-none fixed left-1/2 top-1/4 -translate-x-1/2 -translate-y-1/2 h-[600px] w-[800px] rounded-full bg-primary/3 blur-[200px]" />
|
<div className="pointer-events-none fixed left-1/2 top-1/4 -translate-x-1/2 -translate-y-1/2 hidden h-[600px] w-[800px] rounded-full bg-primary/3 blur-[200px] sm:block" />
|
||||||
<main
|
<main
|
||||||
id="main-content"
|
id="main-content"
|
||||||
className="relative mx-auto max-w-6xl px-4 py-6 sm:px-6"
|
className="relative mx-auto max-w-6xl pl-[max(1rem,env(safe-area-inset-left))] pr-[max(1rem,env(safe-area-inset-right))] py-6 sm:pl-[max(1.5rem,env(safe-area-inset-left))] sm:pr-[max(1.5rem,env(safe-area-inset-right))]"
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</main>
|
</main>
|
||||||
|
|||||||
+1
-1
@@ -102,7 +102,7 @@
|
|||||||
content: "";
|
content: "";
|
||||||
position: fixed;
|
position: fixed;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
z-index: 9999;
|
z-index: 1;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
opacity: 0.015;
|
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");
|
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");
|
||||||
|
|||||||
+9
-1
@@ -1,5 +1,5 @@
|
|||||||
import { MotionConfig } from "motion/react";
|
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 { DM_Sans, DM_Serif_Display, Geist_Mono } from "next/font/google";
|
||||||
import { TooltipProvider } from "@/components/ui/tooltip";
|
import { TooltipProvider } from "@/components/ui/tooltip";
|
||||||
|
|
||||||
@@ -28,6 +28,14 @@ export const metadata: Metadata = {
|
|||||||
themeColor: "#090706",
|
themeColor: "#090706",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const viewport: Viewport = {
|
||||||
|
width: "device-width",
|
||||||
|
initialScale: 1,
|
||||||
|
maximumScale: 1,
|
||||||
|
userScalable: false,
|
||||||
|
viewportFit: "cover",
|
||||||
|
};
|
||||||
|
|
||||||
export default function RootLayout({
|
export default function RootLayout({
|
||||||
children,
|
children,
|
||||||
}: Readonly<{
|
}: Readonly<{
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ export function MobileTabBar() {
|
|||||||
if (!session?.user) return null;
|
if (!session?.user) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<nav className="fixed bottom-0 left-0 right-0 z-50 border-t border-border/50 bg-background/90 backdrop-blur-xl sm:hidden">
|
<nav className="fixed bottom-0 left-0 right-0 z-50 border-t border-border/50 bg-background/90 pl-[env(safe-area-inset-left)] pr-[env(safe-area-inset-right)] backdrop-blur-xl sm:hidden">
|
||||||
<div className="flex h-14 items-stretch">
|
<div className="flex h-14 items-stretch">
|
||||||
{tabs.map((tab) => {
|
{tabs.map((tab) => {
|
||||||
const Icon = tab.icon;
|
const Icon = tab.icon;
|
||||||
|
|||||||
@@ -28,8 +28,8 @@ export function NavBar() {
|
|||||||
const setCommandPaletteOpen = useSetAtom(commandPaletteOpenAtom);
|
const setCommandPaletteOpen = useSetAtom(commandPaletteOpenAtom);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<header className="sticky top-0 z-50 border-b border-border/50 bg-background/80 backdrop-blur-xl">
|
<header className="sticky top-0 z-50 border-b border-border/50 bg-background/80 pt-[env(safe-area-inset-top)] backdrop-blur-xl">
|
||||||
<nav className="mx-auto flex h-14 max-w-6xl items-center justify-between gap-5 px-4 sm:gap-0 sm:px-6">
|
<nav className="mx-auto flex h-14 max-w-6xl items-center justify-between gap-5 pl-[max(1rem,env(safe-area-inset-left))] pr-[max(1rem,env(safe-area-inset-right))] sm:gap-0 sm:pl-[max(1.5rem,env(safe-area-inset-left))] sm:pr-[max(1.5rem,env(safe-area-inset-right))]">
|
||||||
<div className="flex items-center gap-3 sm:gap-6">
|
<div className="flex items-center gap-3 sm:gap-6">
|
||||||
<Link
|
<Link
|
||||||
href="/dashboard"
|
href="/dashboard"
|
||||||
|
|||||||
Reference in New Issue
Block a user