android: three the audit found — bars translucent over nothing, and two insets the WebView does not report

A pass over every screen the app can reach, at rest and scrolled, shot from the
DEVICE so the Android status bar is in the frame. Three of what it found are
nothing to do with the page's top edge and predate it; they are here on their
own.

**The bars are translucent over nothing.** Glass — the backdrop blur behind the
chrome — is off by default on the phone, deliberately: perf.mjs measured three
blurred bands taking a 60 Hz scroll to 30. But the bars kept the alphas that
were chosen to sit ON that blur, so what shipped was the middle state, 92% and
94% over no backdrop at all. The audit reads "Random Access Memories", "Alive
2007", "Latest release" and "Touch (feat. Paul Williams) 8:17" straight through
the navigation bar. The base values are the no-glass case —
`html[data-glass="blur"]` overrides them — so the base is what had to be
opaque; the blurred variants keep their alphas, because there they have
something to be translucent against. The device now answers `rgb(16, 16, 19)`
for the nav and `rgb(28, 28, 32)` for the mini bar, no alpha on either.

**The bottom inset is reported as zero, and the gesture pill is drawn anyway.**
The WebView answers 51px for the top and 0 for the bottom, while the page runs
the full height under Android's gesture handle — the nav measured y 855→915 of
a 915 viewport — so its labels sat exactly where the pill lands, straight
through the word "Library".

**And in landscape the top goes to zero too.** The cutout's inset correctly
moves to the side (portrait top=51 left=0; landscape top=0 left=51), but the
status bar is still drawn across the top there, so the clock sat on "MONDAY,
SEPTEMBER 14" and the battery icons sat on the floating ⋯.

Both are floors rather than replacements: `max(env(...), 18px)` and
`max(env(...), 24px)`, 24 being Android's own status bar height. A device that
reports its insets properly is untouched — portrait's 51 wins on its own — and
only one that reports nothing gets the floor, which every Android with a
gesture pill or a status bar needs. Everything along the bottom is already
anchored to `--inset-bottom`, so the mini bar, `.endpad`, the composer, the
sheets and the player frame all move in step with it.

What the pass did NOT find, having looked: the chip rows clipped at the right
edge of the sleep-timer and sort sheets are not broken — `scrollWidth 458` in a
`clientWidth 412` with `overflow-x: auto`, so they are meant to be swiped,
though nothing on screen says so. The player's three faces, the artwork viewer,
the track sheet, the page overflow and Community's four tabs all render
correctly.

The harness is in research/ (gitignored): shots.mjs walks every reachable
screen and shoots the device frame at several offsets, contact.mjs tiles a pass
into one sheet, clip.mjs records a GIF of the app scrolling, fadetry.mjs
previews a CSS value live without a build, and selectors.mjs checks in one
minute what the full walk takes twenty to cover. Two things it learned the hard
way are written into it: every overlay sits on top of whatever page is behind
it, and a pass once came back as twenty-five photographs of the same player
sheet; and every tab keeps its own stack, so go(tab) shows that stack's top and
only resets when the tab is already active — a pass shot Discography and
labelled it You.
This commit is contained in:
KeelrLeek committed 2026-09-14 15:31:31 -05:00
1 parent 1f9b30c51f
commit c1a2608bdd
2 files changed
+16 -5

No files matched your search

+11 -2
View File
@@ -55,8 +55,17 @@
--tap: 48px;
/* Android's own insets: the status bar above, the gesture handle below. */
--inset-top: env(safe-area-inset-top, 0px);
--inset-bottom: env(safe-area-inset-bottom, 0px);
/* A floor, for the same reason as --inset-bottom. Landscape reports the
cutout on the side and the top as 0, but the status bar is still drawn
across the top there — without this the clock sits on the page's own
kicker and the battery icons sit on the floating ⋯. Portrait reports 51
(the punch-hole included) and keeps it. */
--inset-top: max(env(safe-area-inset-top, 0px), 24px);
/* A floor, because this WebView reports the bottom inset as 0 while it
reports the top as 51 — and the gesture pill is still drawn down there,
straight across the nav's "Library". A device that reports its own
inset keeps it; only one that reports nothing gets the floor. */
--inset-bottom: max(env(safe-area-inset-bottom, 0px), 18px);
/* landscape moves the cutout and the gesture pill to the SIDES, and
viewport-fit=cover puts our content under both */
--inset-left: env(safe-area-inset-left, 0px);
+5 -3
View File
@@ -628,7 +628,7 @@ html[data-material="solid"] .card, html[data-material="solid"] .group { backgrou
align-items: center;
gap: 11px;
padding: 0 10px 26px 8px; /* 4 above the lane, 16 of lane, 6 below */
background: rgba(28, 28, 33, 0.94);
background: #1c1c20; /* opaque for the same reason as .nav */
box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.09), 0 10px 28px -10px rgba(0, 0, 0, 0.9);
overflow: hidden;
transition: transform var(--m-sheet), opacity 200ms ease;
@@ -654,7 +654,9 @@ html[data-material="solid"] .mini { background: #1c1c20; backdrop-filter: none;
height: calc(var(--nav-h) + var(--inset-bottom));
padding-bottom: var(--inset-bottom);
display: flex;
background: rgba(16, 16, 19, 0.92);
/* opaque: glass is off by default, so there is no blur for an alpha to
sit on — 0.92 here let album titles read through the nav */
background: #101013;
box-shadow: 0 -1px 0 rgba(255, 255, 255, 0.06);
transition: transform var(--m-sheet);
}
@@ -892,7 +894,7 @@ html[data-material="solid"] .nav { background: #101013; backdrop-filter: none; -
display: flex;
flex-direction: column;
border-radius: var(--r-sheet) var(--r-sheet) 0 0;
background: rgba(26, 26, 30, 0.97);
background: #1a1a1e; /* opaque for the same reason as .nav */
box-shadow: 0 -14px 40px rgba(0, 0, 0, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.1);
transform: translateY(102%);
transition: transform var(--spd-spatial-default) var(--sp-spatial-default);