Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 7 additions & 11 deletions src/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -329,16 +329,12 @@ html {
text-size-adjust: 100%;
}

/* Safety net: clip any rogue horizontal overflow on BOTH html and body.
iOS Safari + Telegram WKWebView sometimes ignore `overflow-x: clip`
on <html> alone and still let a wide child push the page past 100vw.
Applying it to body too — plus capping body width at 100vw — covers
the WebView edge cases. `clip` (not `hidden`) avoids creating a
scroll container, so position: sticky on the header keeps working. */
html,
body {
/* Safety net: clip horizontal overflow at the html (viewport) level only.
Do NOT apply overflow-x: clip to <body> — WebKit treats clip on <body>
as creating a containing block for position: fixed descendants, which
detaches the sticky/fixed header from the viewport and lets a 1-2 px
gap appear at the top during momentum scroll in Telegram WKWebView.
Per-component clipping (main, article) catches anything html misses. */
html {
overflow-x: clip;
}
body {
max-width: 100vw;
}
8 changes: 4 additions & 4 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -127,10 +127,10 @@ export default function RootLayout({
</head>
{/* grid (not flex) so position: sticky on <SiteHeader> works reliably
on iOS Safari — sticky inside a flex column has known quirks.
w-full + overflow-x-clip on the body guarantees no descendant can
push the page past the viewport, even when WKWebView (Telegram in-app
browser) ignores the html-level safety net in globals.css. */}
<body className="min-h-full w-full max-w-full overflow-x-clip grid grid-rows-[auto_1fr_auto]">
Do NOT add overflow-x clip here — WebKit treats it as creating a
containing block for position: fixed descendants and the header
ends up scrolling with the body. Clip is on html + main + article. */}
<body className="min-h-full grid grid-rows-[auto_1fr_auto]">
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: safeJsonLd(ORG_JSONLD) }}
Expand Down
14 changes: 6 additions & 8 deletions src/components/site-header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,12 @@ export function SiteHeader() {
<>
<div
ref={headerRef}
// position: fixed (not sticky) — sticky is flaky on iOS Safari
// when the URL bar animates; fixed keeps the navbar glued.
// bg-surface fills the safe-area-inset padding so body content
// does not show through the notch strip and read as a "hole".
// translate3d forces GPU compositing — known iOS Safari hint
// that stops fixed elements from detaching during momentum scroll.
className="fixed top-0 left-0 right-0 z-50 flex flex-col font-sans pt-[env(safe-area-inset-top)] bg-surface"
style={{ transform: "translate3d(0, 0, 0)" }}
// position: fixed (not sticky) — sticky is flaky on iOS Safari when
// the URL bar animates; fixed keeps the navbar glued. No ancestor
// may carry overflow: clip / transform / will-change or fixed
// positions relative to that ancestor instead of the viewport
// (Telegram WKWebView gap symptom). Verified clean as of dev.
className="fixed top-0 left-0 right-0 z-50 flex flex-col font-sans bg-surface"
>
<header className="border-b border-rule py-4 md:py-5 px-4 sm:px-6 shrink-0 text-sm bg-surface relative">
<div className="max-w-[1400px] mx-auto flex items-center justify-between gap-3">
Expand Down
Loading