From 32d4dc2c82178c915d0c2bc3399d90e3a676fb7c Mon Sep 17 00:00:00 2001 From: Logan Date: Thu, 20 Aug 2026 23:42:34 -0400 Subject: [PATCH] feat(player): slim the phone's mini player to three controls Shuffle, repeat and the queue button leave the phone's bottom bar. They are not gone: all three are on the full-screen Now Playing view, one tap away through the mini player's art, which is the "reachable only from Now Playing" this issue asks for. #55 is what makes the queue half safe -- it is a screen with an entry in the back stack now, rather than a panel with no way out but the button being removed here. Removing a control is only allowed because it is still reachable, which is plan 018's matrix promise, so that is what the spec walks rather than counting buttons. It found that the route did not exist in the state that matters: `now-playing` renders two branches and the no-track one had no `.expand` button on its placeholder, so with nothing loaded there was no way to the full-screen view at all -- and once the queue button left the bar, no way to the queue. The queue is persisted across restarts, so "tracks queued, nothing playing" is a state the app launches into, not a corner. The favourite stays on the bar and was 18x14px, the smallest control in the app, against the 48x48 art beside it. One CSS trap, because it failed silently. The phone block is last in index.css on purpose -- a media query adds no specificity -- but the rule it overrides here is written *nested* inside `.bottom-bar`, so it builds to a descendant selector one class more specific and a bare `#queue-button` lost to it. Being last is not enough when the thing above is more specific. Closes #59 --- frontend/index.css | 24 ++++++++++++ .../src/components/now-playing/now-playing.ts | 37 ++++++++++++++++++- 2 files changed, 59 insertions(+), 2 deletions(-) diff --git a/frontend/index.css b/frontend/index.css index 2875913..a42aa45 100644 --- a/frontend/index.css +++ b/frontend/index.css @@ -535,6 +535,30 @@ body div.sidebar { .bottom-bar volume-control { display: none; } + + /* The queue leaves the phone's bar (#59), because #55 made it a + screen with an entry in the back stack and Now Playing already + carries its own button for it. The route is the mini player's + art -> Now Playing -> the queue, which is the "reachable only + from Now Playing" this issue asks for. + + This is allowed to remove a control only because the control is + still reachable: plan 018's matrix promises that no action is + ever unreachable at any supported size, and that promise is what + `phone-transport.spec.ts` asserts rather than the button count. + + **`.bottom-bar #queue-button`, not `#queue-button`**, and that is + not decoration. The rule this overrides is written *nested* + inside `.bottom-bar`, so it builds to a descendant selector one + class more specific than it looks in the source -- and a bare + `#queue-button` here loses to it, media query or not. Being last + in the file is not enough when the thing above is more specific, + which is the same lesson as this section's own header one level + down: nesting adds specificity the source does not show, and the + failure is silent (the button simply stayed). */ + .bottom-bar #queue-button { + display: none; + } } /* Out of the desktop grid entirely. `job-band` renders nothing above diff --git a/frontend/src/components/now-playing/now-playing.ts b/frontend/src/components/now-playing/now-playing.ts index 860a7a2..8e335a5 100644 --- a/frontend/src/components/now-playing/now-playing.ts +++ b/frontend/src/components/now-playing/now-playing.ts @@ -215,6 +215,17 @@ export class NowPlaying extends LitElement { outline: 2px solid var(--yj-accent, #ffd43b); outline-offset: 2px; } + + /* The favourite is one of the three controls #59 keeps on the + phone's bar, and it was the **smallest control in the app**: + measured at 424x439, 18x14px, against the 48x48 art beside it. + Zero padding around an icon-sized glyph is a reasonable mouse + target and is not a thumb target at all. */ + .fav-btn { + min-width: 44px; + min-height: 44px; + font-size: var(--yj-icon-md); + } } .cover-preview-panel { @@ -446,8 +457,30 @@ export class NowPlaying extends LitElement { return html`
${announcement}
-
-
+ +
+ +
+
+