Merge nucleic/upbeat-jade-ibis-kt5e into main
Mirrored from corpo a08e349.
This commit is contained in:
+40
-7
@@ -9,11 +9,15 @@ const canonical = new URL('/', Astro.site);
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
|
<!-- Deliberately no viewport-fit=cover. It looks like the fix for the bands behind
|
||||||
|
Safari's chrome and it is not: measured on iOS 27, screen.height is 874 while
|
||||||
|
100lvh is 754 and both safe-area insets report 0, cover or not. Safari does not
|
||||||
|
hand those 120px to the page, so no element and no viewport unit reaches them —
|
||||||
|
see the note on .ambient for what actually resolves it. -->
|
||||||
<meta name="viewport" content="width=device-width" />
|
<meta name="viewport" content="width=device-width" />
|
||||||
<!-- Not --paper. Safari paints its toolbar and overscroll regions with this flat
|
<!-- Not --paper. Safari paints its overscroll regions with this flat colour, but
|
||||||
colour, but the page underneath is the ambient field, which lifts the edges to
|
the page underneath is the ambient field, which lifts the edges well off paper.
|
||||||
roughly #0e1813 — against paper that reads as a grey bar sitting behind the
|
Measured off rendered pixels at the top and bottom edges. -->
|
||||||
browser chrome. Measured off rendered pixels at the top and bottom edges. -->
|
|
||||||
<meta name="theme-color" content="#0f1813" />
|
<meta name="theme-color" content="#0f1813" />
|
||||||
<meta name="generator" content={Astro.generator} />
|
<meta name="generator" content={Astro.generator} />
|
||||||
<title>{title}</title>
|
<title>{title}</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
|
/* 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
|
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
|
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.
|
a grey bar under the chrome. Sized to the large viewport, the field paints
|
||||||
Sized to the large viewport, the field paints through the toolbar instead. */
|
through the toolbar instead. */
|
||||||
height: 100%;
|
height: 100%;
|
||||||
height: 100lvh;
|
height: 100lvh;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
pointer-events: none;
|
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
|
/* 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. */
|
frame — what should be visible is the light moving, never the thing carrying it. */
|
||||||
.ambient-haze,
|
.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
|
/* 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. */
|
margin puts the copy and the window edge in each other's way. */
|
||||||
--edge: clamp(1.35rem, 4.8vw, 5rem);
|
--edge: clamp(1.35rem, 4.8vw, 5rem);
|
||||||
|
--shell-y: clamp(1.25rem, 2.6vh, 2.5rem);
|
||||||
|
|
||||||
position: relative;
|
position: relative;
|
||||||
display: grid;
|
display: grid;
|
||||||
@@ -248,7 +281,7 @@ const canonical = new URL('/', Astro.site);
|
|||||||
width: min(100%, 1600px);
|
width: min(100%, 1600px);
|
||||||
min-height: 100svh;
|
min-height: 100svh;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
padding: clamp(1.25rem, 2.6vh, 2.5rem) var(--edge);
|
padding: var(--shell-y) var(--edge);
|
||||||
}
|
}
|
||||||
|
|
||||||
.masthead,
|
.masthead,
|
||||||
|
|||||||
Reference in New Issue
Block a user