From 17b8ffd69b253ad60df16912355776883568e7b4 Mon Sep 17 00:00:00 2001 From: Andrew Moore Date: Sun, 9 Aug 2026 17:09:41 -0700 Subject: [PATCH] Merge nucleic/upbeat-jade-ibis-kt5e into main Mirrored from corpo a08e349. --- src/pages/index.astro | 47 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 40 insertions(+), 7 deletions(-) diff --git a/src/pages/index.astro b/src/pages/index.astro index cf778ba..b61d472 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -9,11 +9,15 @@ const canonical = new URL('/', Astro.site); + - + {title} @@ -173,14 +177,42 @@ const canonical = new URL('/', Astro.site); /* Deliberately not inset: 0. A fixed box pinned to the bottom stops at the small viewport, but iOS Safari keeps rendering the page behind its translucent toolbar — so the strip between svh and lvh fell back to flat paper and read as - a grey bar under the chrome, several shades off the ambient-lit page above it. - Sized to the large viewport, the field paints through the toolbar instead. */ + a grey bar under the chrome. Sized to the large viewport, the field paints + through the toolbar instead. */ height: 100%; height: 100lvh; overflow: hidden; pointer-events: none; } + /* The grey bar, properly. + + iOS reserves a strip above and below the layout viewport for its own chrome, and + fills it from the document canvas — which takes its paint from the root element + and nowhere else. Measured on iOS 27: screen.height 874, 100lvh 754, both safe-area + insets 0. Those 120px are not addressable by the page. No height, no viewport unit + and no viewport-fit=cover reaches them; earlier attempts only moved the seam. + + So the canvas is the single point, and there is exactly one thing to get right: + the canvas colour and the page's own edge colour have to be equal. The canvas can + only be flat --paper, and the field is a moving light whose edge tone drifts, so + matching by picking a constant is a value that is wrong again as soon as the bands + move. Instead the field is brought to zero at the bottom of the viewport — then + page edge, canvas and theme-color are all --paper by construction, whatever the + animation is doing, and the seam cannot come back. + + Costs nothing to look at: this falls inside the strip Safari's toolbar already + covers. Static, so the layer still composites without repainting per frame. */ + .ambient::after { + content: ''; + position: absolute; + right: 0; + bottom: 0; + left: 0; + height: 5rem; + background: linear-gradient(to top, var(--paper), rgb(10 16 12 / 0%)); + } + /* Oversized so the bands can travel a long way without an edge ever entering the frame — what should be visible is the light moving, never the thing carrying it. */ .ambient-haze, @@ -241,6 +273,7 @@ const canonical = new URL('/', Astro.site); /* One inset for everything. It is deliberately generous: at mid widths a tighter margin puts the copy and the window edge in each other's way. */ --edge: clamp(1.35rem, 4.8vw, 5rem); + --shell-y: clamp(1.25rem, 2.6vh, 2.5rem); position: relative; display: grid; @@ -248,7 +281,7 @@ const canonical = new URL('/', Astro.site); width: min(100%, 1600px); min-height: 100svh; margin: 0 auto; - padding: clamp(1.25rem, 2.6vh, 2.5rem) var(--edge); + padding: var(--shell-y) var(--edge); } .masthead,