Skip to content

Web player and library UX pass: hover-card chapter count, sleep timer, phone sign-in, AA contrast - #8

Merged
techmore merged 11 commits into
mainfrom
claude/ux-pass-f29d6b
Nov 3, 2026
Merged

techmore merged 11 commits into
mainfrom
claude/ux-pass-f29d6b

Conversation

@techmore

@techmore techmore commented Nov 2, 2026

Copy link
Copy Markdown
Owner

UI/UX pass on the audiobook web player and library, plus one iOS fix. Nine focused fix commits and a findings doc; nothing here is deployed.

What changed

Commit Fix
Audiobooks: real chapter count on the rails hover card The known "? chapters" bug. The list API never fills chapterCount, so the card now loads the real count from the chapter timeline on hover/focus and never prints a placeholder. The classic list no longer says "0 chapters".
Audiobooks rails: no jump on load, quieter screen reader output On a 375px phone /audiobooks jumped ~4,300px past the whole library on load. Removed whole-page aria-live regions (every click re-read the library); summaries out of tile names; one h1; cover fallbacks.
Audiobooks rails: speed, 30-second skip and sleep timer The default audiobook page had a bare <audio> with no sleep timer or speed. Adds −30/+30 s, speed (remembered) and sleep (15–60 min or end of chapter); phone layout fixes.
Player: sleep timer on desktop The main player's sleep timer was hidden by CSS on desktop and its panel was only styled for phones. Now a popover above the bar.
Player: name the progress-scope button A bare "5" sat between elapsed and total time; it now reads "Book · 5 chapters" / "Chapter 2 of 5" (WCAG 2.5.3).
Sign-in: fits a phone, announces errors, keeps the username The card overflowed a 375px screen (sideways scroll, fields cut off). Error is role="alert", username kept after a wrong password, Google button only when configured.
Techmore theme: AA contrast Light theme secondary text 3.9:1 → ≥4.6:1; listened badge 3.5:1 → 5.2:1. axe: no contrast failures in any theme.
Library cards: keep text clear of the bookmark button Author/runtime text ran under the round bookmark button.
iOS: show 1.25x and 1.75x speeds correctly Speed menu showed "1.2×" and "1.8×" (%.2g). One line, in a file PR #7 does not touch.

Full findings list (20 items, 13 fixed, 7 open), method and all screenshots: docs/ux-review-2026-11/README.md.

Before / after

Hover card:

Hover card before: 6:20:00 • ? chapters; after: 6:20:00 • 27 chapters

/audiobooks on a phone, on load:

Before: page scrolled to the player; after: library shelves at the top

Desktop sleep timer (before: no button):

Sleep timer popover above the player bar

Sign-in after a wrong password, 375px:

Before: card cut off at right edge; after: card fits, username kept

Expanded phone player: scope label:

Before: bare 5; after: Book · 5 chapters on its own row

More (rails at 1440, player bar, Techmore contrast, card text) in the review doc.

How it was tested

  • The repo's AGENTS.md forbids a local Sonder runtime and production was off limits, so the pages were served from this branch's web/ files by a stub API with 11 public-domain titles (3 with real spoken audio and chapter markers). "Before" is ac0c484 on the same stub. Headless Chrome at 1440×900 and 375×812, all four themes, axe-core 4.10 (WCAG 2.2 A/AA tags), plus keyboard, focus and accessible-name checks.
  • node --test library.test.cjs: 101 pass. go test ./internal/httpapi/: pass. New tests cover the hover-card count, rails speed/sleep, the desktop sleep button and the sign-in page.
  • Not verified: a real library on ser8 (long multi-part books, real covers), Safari/iOS Safari, VoiceOver itself (names were checked through the accessibility tree), and an iOS build (the iOS change is a format-string fix; CI builds it).

Notes for review

  • Does not touch any file changed by iOS: account sign-in, and local + public server addresses #7.
  • docs/ux-review-2026-11/ adds ~0.8 MB of JPEGs; drop that commit before merging if you'd rather not keep them in the repo.
  • The rails hover card now makes one GET /api/audiobooks/{id}/chapters per tile hovered (cached for the page). Server-side that runs ffprobe once per file and then hits the existing chapter cache.

🤖 Generated with Claude Code

techmore and others added 11 commits November 2, 2026 16:15
The catalog list never fills chapterCount (only the per-book detail and
chapter timeline do, and those probe the file), so every rails hover card
read "? chapters" and every classic list row read "0 chapters".

The rails card now shows the runtime alone until the count is known,
fetches the book's chapter timeline when a tile is hovered or focused,
and reuses the count from an opened book's detail. The classic list
omits the count when it is unknown.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The automatic pick on page load no longer scrolls. On a 375px phone it
  jumped ~4,300px past the whole library to the player; on desktop it
  pushed the first shelf heading under the sticky header. A book the
  listener taps still scrolls into view on the stacked layout and moves
  focus to its title.
- The shelves and detail panel were aria-live, so every selection re-read
  the entire library. A single status line now announces search results.
- The hover summary is aria-hidden, so a tile's name is its title, author
  and narrator rather than a 220-character excerpt. Card content uses
  spans (block elements are not valid inside a button).
- One h1 per page; the selected title is an h2 and the parts list an h3.
- Progress bars have names; a missing or failed cover shows the title's
  initial instead of a fixed "A" or a broken-image icon.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The rails page (the default /audiobooks layout) played through a bare
<audio> element: no sleep timer, no skip, and no speed control outside
Chrome's overflow menu. It now has -30s/+30s, a speed menu (0.75x-2x,
remembered as sonder.player.rate) and a sleep timer (15/30/45/60 minutes
or end of chapter). The countdown updates quietly; starting, ending and
cancelling the timer are announced.

Also on phones: the three-row header no longer stays pinned, the detail
hero stacks in one column, and chapter rows are tighter.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The base stylesheet hid the sleep timer button, and the sleep panel was
only styled inside the phone media query, so a desktop listener could not
set a sleep timer at all. The button now sits beside Speed in the bar and
opens a popover above it (closing on Escape, the close button or a click
elsewhere). The phone bottom sheet is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Between the elapsed and total readouts the player showed a lone number
("5"): the chapter count, on a button that switches between whole-book
and chapter progress. Nothing on screen said what it was, and its spoken
label shared no words with it (WCAG 2.5.3 Label in Name).

It now reads "Book · 5 chapters", "Chapter 2 of 5" or "Part 1 of 3",
and the spoken label starts with that text. On the expanded phone player
it takes its own centred row so it no longer collides with the
percentage.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The card used content-box sizing with 34px padding, so on a 375px phone
  it was 415px wide: the page scrolled sideways and the right edge of
  every field was cut off. Border-box sizing and fluid padding fix it.
- The error message (wrong password, throttling) has role="alert", and a
  failed sign-in keeps the username filled in with focus on the password.
- "Continue with Google" only appears when Google sign-in is configured;
  otherwise it led to a bare "not configured" error page.
- The 12-character minimum only applies to new passwords; on sign-in it
  made the browser reject a short password before the server answered.
- 44px controls and a visible focus ring on fields and buttons.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
In the light Techmore Olive theme, secondary text (#707565) measured
3.9:1 on panels and about 3:1 on the page background, and the "% LISTENED"
badge 3.5:1; WCAG 2.2 AA needs 4.5:1 for this size. Secondary text is now
#54564a (at least 4.6:1 on every Techmore surface) and the badge #9c5733
(5.2:1). axe reports no contrast failures in any of the four themes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The round bookmark button overlaps the bottom-right corner of every book
card, and the author/runtime and narrator lines ran underneath it (for
example "Charles Dickens · 18:40:0" cut off mid-number behind the icon).
Both lines now stop short of the button and end in an ellipsis, and the
narrator line aligns with the line above it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The audiobook speed menu formatted rates with %.2g (two significant
digits), so 1.25x read "1.2x" and 1.75x read "1.8x". %g prints them
exactly (0.75x, 1x, 1.25x, 1.5x, 1.75x, 2x).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Findings list (fixed and open) with before/after screenshots at 1440 and
375 px, and how the review was run without a local Sonder runtime.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@techmore
techmore marked this pull request as ready for review November 2, 2026 23:59
@techmore
techmore merged commit 50f0a00 into main Nov 3, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant