feat(player): show progress on the phone's bar border
CI / check (push) Skipped
CI / e2e (push) Skipped
CI / check (pull_request) Successful in 2m28s
CI / e2e (pull_request) Successful in 8m55s

#59 took the seek bar off the phone's transport, so the one thing a
mini player is expected to say without being opened -- how far through
the song it is -- had nowhere left to be said.

It is the shell's element and its own 2px grid row between `bottom-bar`
and `bottom-nav`, because those two are separate components and either
one drawing the line means reaching into the other's box. The fill is
`scaleX()` off the same `PlaybackPositionChanged` the seek bar renders,
with the same `trackChangeId`/`seq` guards and an interval that only
interpolates *between* reports -- never its own clock, which is the
rule that exists because a local counter drifted 30 s away from the
backend across four keyboard seeks.

It is `aria-hidden` and takes no pointer events at any depth: Now
Playing's seek bar is what announces the position, and a 2px strip on
the top edge of the tab bar is exactly where a thumb aiming at a tab
lands. It renders nothing above 600px, from `matchMedia` rather than a
media query, because a stylesheet cannot stop a 1 Hz interval running
for the life of every desktop session about a line nobody can see.

Its phone rule is at the foot of index.css beside `job-band`'s, not in
the phone block above: a media query adds no specificity, so a
`display: block` written before the `display: none` that takes it out
of the desktop grid loses to it and the line never appears at all.

Closes #58
This commit is contained in:
2026-08-21 03:43:37 -04:00
parent 14e3ab574c
commit bd45e5d595
8 changed files with 660 additions and 3 deletions
+38
View File
@@ -0,0 +1,38 @@
# Journal
Running work log: what was done, what was verified, what was left open.
Newest entry last.
## 2026-08-21 — #58, the phone's progress line
Took #58 (Phase 3, item 4 of the roadmap in #73; #56 and #59 landed
before it and #64 after, so this was the phase's remaining item ahead of
#51's verification pass). Branch `feat/58-mini-player-progress-line`.
**What.** `<player-progress-line>` in the shell, with its own `auto`
grid row between `bottom-bar` and `bottom-nav` below 600px. 2px, the
fill is `scaleX()` off `PlaybackPositionChanged` with the seek bar's
`trackChangeId`/`seq` guards and an interval that only interpolates
between reports. `aria-hidden`, `pointer-events: none`, and it renders
nothing above 600px or with no track.
**Verified.**
- `make ui-test` — 992 passed, including 8 new in
`frontend/test/components/progress-line.test.ts` (the matchMedia
branch, the report/interpolation rules, paused, a stale report, and
that it is neither announced nor touchable).
- `make e2e --project=chromium` — 223 passed, including 3 new in
`e2e/specs/phone-progress-line.spec.ts` (the two adjacencies, that it
takes no taps, that it is absent on a desktop). WebKit is CI's half;
Arch cannot run Playwright's Linux WebKit.
- Read a screenshot at the reference device's 424x439 with a real track
playing, and watched the real transform advance 0.288889 -> 0.377778
over 8 s of a 90 s track. Also checked the line goes with the bar on
`now-playing`.
- No Go changed, so `make lint`/`make test` were not run.
**Left open.** No device tier: this is a browser at 424x439, which
`CLAUDE.md` is explicit is not a phone. The line's *appearance* on
Chrome 113 is unverified; the CSS it uses (a transform and a flat
background) is nowhere near that engine's gaps.