android: no bar arrives over the page — the tab pages lose their top banner

The glass bar was anonymous until you scrolled, then faded in carrying the
title the page already had in 27px type two centimetres below it. On Home that
meant "Good morning" over "Good morning", half-transparent, while the content
it covered kept moving underneath. Kyle's word: remove them.

So a tab page has no bar at all. `barOn`/`titled` and the scroll trigger they
read are gone; `showBar` is `!root`, and the element is not rendered on Home,
Search, Library, Community or You. Nothing fades in over what you are reading.

The bar was not only decoration, which is why this is more than a deletion: its
⋯ is the page overflow, and on a tab page that overflow is the app's own menu —
the queue, the sleep timer, Settings. That moves to where the page's title
already is, in `.phead`, beside Home's identicon and at the end of Library's
existing row of actions. Search and You grow the row they did not have.
Community already carried its own ⋯ and keeps it.

A pushed page still has a bar, because it carries the back chevron and a title
that is not repeated anywhere else on the screen. It is static now: rendered
only when there is somewhere to go back to, on from the first frame and titled
from the first frame. The opacity-0 default, the 180ms cross-fade, and the
`.gb-t` rise the title used to arrive on all come out of the stylesheet —
nothing is left that can catch the eye mid-scroll.

The walk reached that overflow through `.gbar .iconbtn` on a tab page, which is
now a selector that matches nothing there: `home-more` on both step lists and
the two sleep-timer steps go to `.phead .iconbtn.muted` instead. The other
`.gbar` steps are untouched on purpose — the playlist export sheet is a PUSHED
page and still has its bar, and `library-ambience` is the album page's back
chevron, not an overflow.

Checked on the device rather than argued: on Home `.gbar` is absent, the ⋯ is
present, and tapping it opens the half sheet on "SoulStream · Queue · Sleep
timer off · Settings"; on a pushed record the bar is there with its two
buttons, its title, and a computed opacity of exactly 1.

One thing this leaves: the bar was also what backed the OS status bar once a
page scrolled under it. The clock and the battery now sit on the content. That
is fine on the ground and on dark artwork, and it will not be over a white
sleeve — a short scrim with no title and no buttons would fix it without
bringing a banner back, and is deliberately not in this commit.
This commit is contained in:
KeelrLeek committed 2026-09-14 11:09:34 -05:00
1 parent 07dad65ca5
commit cdb861fcbd
7 files changed
+26 -28

No files matched your search

+4 -4
View File
@@ -966,7 +966,7 @@ const MOCK_STEPS = [
{ do: `__settle()`, wait: 600 },
{ do: `document.querySelectorAll('.nav button')[0].click()`, name: "home-again", wait: 700 },
/* the page overflow → the sleep timer */
{ do: `document.querySelectorAll('.gbar .iconbtn')[1].click()`, name: "home-more", wait: 700 },
{ do: `document.querySelector('.phead .iconbtn.muted').click()`, name: "home-more", wait: 700 },
{ do: `__click('.halfsheet .row', 'Sleep timer')`, name: "sleep-sheet", wait: 700 },
{ do: `__click('.halfsheet .chip', '30 min')`, name: "sleep-set", wait: 700 },
/* ── the phone turned over. A resize, so the app keeps playing and keeps
@@ -2105,12 +2105,12 @@ const PHONE_STEPS = [
died in that gap would leave a pause waiting on his playback — so
it is the SHORTEST chip in the sheet, not a comfortable one. */
{ do: `document.querySelectorAll('.nav button')[0].click()`, name: "home-feed", wait: 1200 },
{ do: `document.querySelectorAll('.gbar .iconbtn')[1].click()`, name: "home-more", wait: 900 },
{ do: `document.querySelector('.phead .iconbtn.muted').click()`, name: "home-more", wait: 900 },
{ do: `__click('.halfsheet .row', 'Sleep timer')`, name: "sleep-sheet", wait: 800 },
{ do: `__click('.halfsheet .chip', '15 min')`, name: "sleep-set", wait: 800 },
{ do: `document.querySelectorAll('.gbar .iconbtn')[1].click()`, name: "sleep-armed", wait: 900 },
{ do: `document.querySelector('.phead .iconbtn.muted').click()`, name: "sleep-armed", wait: 900 },
{ do: `(function () { function pick(sel, re) { return [].slice.call(document.querySelectorAll(sel)).find(function (x) { return re.test((x.textContent || '').trim()); }); } var r = pick('.halfsheet .row', /Sleep timer/); if (r) r.click(); return new Promise(function (res) { setTimeout(function () { var c = pick('.halfsheet .chip', /^Off$/); if (c) c.click(); res(!!c); }, 400); }); })()`, name: "sleep-off", wait: 900 },
{ do: `document.querySelectorAll('.gbar .iconbtn')[1].click()`, name: "sleep-cleared", wait: 900 },
{ do: `document.querySelector('.phead .iconbtn.muted').click()`, name: "sleep-cleared", wait: 900 },
{ do: `(function () { var s = document.querySelector('.scrim'); if (s) s.click(); return true; })()`, wait: 600 },
/* You: the stream cache's retention chip, read first and put back
last. The value is stashed IN THE PAGE as well as in the harness,