feat(ui): the full-screen now playing a phone needs
Plan 016 B2, phase 2. Phase 1 took the seek bar and the volume out of the phone's bottom bar -- 4px of height is not a thumb target, and a phone's volume belongs to its hardware keys -- and promised them a full-screen view. This is it, reached from a button over the mini player's cover art. **It composes the transport rather than reimplementing it.** The same `seek-bar`, `player-controls` and `volume-control` the desktop bar uses; a phone layout that copies them is a second transport to fix every bug in, and the seek bar in particular carries interpolation rules that took a plan of their own to get right. The seek bar thickens its own track below the breakpoint, in its own stylesheet, because the track size lives on a wa-slider inside its shadow root where a custom property from the host cannot reach. **It is a detail view, not a primary one.** It is somewhere you go and come back from, so index.ts pushes the current view and Back pops it -- which is also why it is not a fifth tab: a tab you cannot leave by pressing it again is not a tab. Two things came from reading a screenshot rather than from a failing test, and both were invisible to assertions that were individually correct. **The mini player was still under the full-screen view**, repeating it in 4em of an 844px phone. index.css hides the bottom bar while `#main-content[data-active-view="now-playing"]`, through `:has()` rather than a class toggled from index.ts, because the active view is already published as an attribute. That takes the queue button with it, so the view carries its own. **And phase 1's shell rules had never applied.** A media query adds no specificity, and the phone block sat above the plain rules it meant to override, so at 390px the header kept its 2em gutters (32px), its 16px gap and its 24px title, and the bottom bar kept a fixed 320px first column. Nothing failed: the shell fits because of `min-width: 0` and each component's own media query, which live in their own stylesheets and have no later rule to lose to -- so what was dead was exactly the cosmetic half no assertion looks at. The phone rules are one section at the end of the file now, and it says why it is last. Measured after: 12px, 8px, 17.6px, `154px 187px 33px`.
This commit is contained in:
@@ -2929,3 +2929,57 @@ page rather than a failed setup.
|
||||
both times.** That is the property to keep — a spec tier whose second
|
||||
run differs from its first is a tier that will one day blame the wrong
|
||||
commit.
|
||||
|
||||
## A media query adds no specificity, and dead CSS looks like working CSS (2026-08-16)
|
||||
|
||||
Plan 016 B2 phase 2 shipped the full-screen now-playing view, and
|
||||
checking it with a screenshot found that **phase 1's shell rules had
|
||||
never applied**.
|
||||
|
||||
`index.css` is base rules then component rules, and the phone block had
|
||||
been inserted in the middle — above the plain `.top-bar` and `.title`
|
||||
rules it meant to override. A media query is not a specificity boost,
|
||||
so with equal specificity the *later* declaration wins. Measured at
|
||||
390px before the fix:
|
||||
|
||||
| declared for the phone | actually computed |
|
||||
|---|---|
|
||||
| `padding-left: 0.75em` | 32px (the 2em base) |
|
||||
| `gap: 0.5em` | 16px (base) |
|
||||
| `font-size: 1.1em` | 24px (the 1.5em base) |
|
||||
| `grid-template-columns: minmax(0,1fr) auto auto` | `320px 1fr auto` (base) |
|
||||
|
||||
After moving the block to the end of the file: 12px, 8px, 17.6px, and
|
||||
`154px 187px 33px`.
|
||||
|
||||
**Nothing failed while they were dead**, which is the part worth
|
||||
keeping. The phone spec asserts that the shell does not scroll
|
||||
sideways, and it did not — because the fitting was being done by
|
||||
`min-width: 0` and by each component's *own* media query, which live in
|
||||
their own stylesheets and so had no later rule to lose to. The
|
||||
declarations that did nothing were the cosmetic ones, and no assertion
|
||||
was ever going to see them. A screenshot did, in about ten seconds.
|
||||
|
||||
The file now ends with one phone section, and says why it is last.
|
||||
|
||||
### What the same screenshot found about the view itself
|
||||
|
||||
The bottom bar was still rendering the mini player *underneath* the
|
||||
full-screen view — 4em of a 844px phone spent saying exactly what the
|
||||
view above it says, and invisible to every assertion about either one
|
||||
(both were correct on their own). `index.css` hides `.bottom-bar` while
|
||||
`#main-content[data-active-view="now-playing"]`, through `:has()`
|
||||
rather than a class toggled from `index.ts`: which view is showing is
|
||||
already published as an attribute, and a second expression of the same
|
||||
fact is a second thing to keep in step.
|
||||
|
||||
That took the queue button away with it, since that button lives in the
|
||||
bar — so the view carries its own, toggling the same `open` attribute
|
||||
on the same panel element.
|
||||
|
||||
**And a css`` literal cannot contain a backtick.** A comment reading
|
||||
"the track size is set on the `wa-slider` inside its shadow root"
|
||||
terminates the tagged template, and the failure arrives as
|
||||
`Expected "]" but found "wa"` from the CSS parser, at a line number in
|
||||
the *comment*. `make css-check` exists for this and named it
|
||||
immediately.
|
||||
|
||||
@@ -315,14 +315,22 @@ places had to agree — `abiFilters`, the Makefile's `android:package`
|
||||
anchor is what stops it also matching the fat APK's line. Adding the
|
||||
ABI back, if modernc ever fixes `Xlstat64`, is those same three edits.
|
||||
|
||||
**B2, the desktop shell.** Scope decided (below) and **phase 1 is
|
||||
done**: the shell itself. Below 600px the sidebar column is gone,
|
||||
`<bottom-nav>` is the primary navigation, and the shell fits 320px
|
||||
exactly — measured, from 652px in a 360px viewport before. What is left
|
||||
is the *views*: a full-screen now-playing (which is where seeking and
|
||||
volume went), long-press for the context menus that are right-click
|
||||
today, and the track list's resizable columns, which are a pointer
|
||||
feature with no touch equivalent.
|
||||
**B2, the desktop shell.** Scope decided (below); **phases 1 and 2 are
|
||||
done.**
|
||||
|
||||
- *Phase 1, the shell.* Below 600px the sidebar column is gone,
|
||||
`<bottom-nav>` is the primary navigation, and the shell fits 320px
|
||||
exactly — measured, from 652px in a 360px viewport before.
|
||||
- *Phase 2, the full-screen now-playing view.* Where phase 1's seek bar
|
||||
and volume went. A detail view, so Back pops the nav stack; it
|
||||
composes the real transport components rather than copying them; and
|
||||
it hides the bottom bar while it is up, so it carries its own queue
|
||||
button.
|
||||
|
||||
What is left is the rest of the *interactions*: long-press for the
|
||||
context menus that are right-click today, and the track list's
|
||||
resizable columns, which are a pointer feature with no touch
|
||||
equivalent. Neither is started.
|
||||
|
||||
**B3/B4** are unchanged, and B3 is now *possible* where it was not:
|
||||
with all-files access, `tagwriter` can write in place.
|
||||
|
||||
Reference in New Issue
Block a user