- Remove play button and gear icon from chapter nav bar
- Show bottom mini-player bar always (not slide-up on play)
- Remove duplicate collapsed-bar seek track; keep only expanded panel scrub bar
- Move gear/settings button into the bottom mini-player bar
- Move settings panel into mini-player aside, opening upward
- Clean up JS: remove navBtn/navIcon refs, showPlayer/hidePlayer, playerSeekTrack refs
html/template's context-aware parser was treating the backslash-escaped
quote in the inline onclick regex literal as an HTML attribute terminator,
causing template execution to produce an empty/broken output.
Move the summary paragraph-splitting logic into a named window.openSummary
function in the script block, and call it via a clean onclick=openSummary(this)
attribute with no inline regex literals.
- Make overlay scroll within the viewport instead of being clipped (overflow-y-auto on backdrop, items-start alignment)
- Split summary text into paragraphs in the zoom overlay (newline-split with sentence-boundary fallback)
- Add Summary heading in overlay for context
- Remove old merge-poller JS; simplify generateAudio to use data.url directly (Kokoro backend rewrite cleanup)
Embed the complete ranking JSON into the page and replace the DOM-only
filter with a client-side search over ALL_ITEMS. When a filter is active
the grid is re-rendered from the full dataset; clearing filters restores
the server-paginated view. Also adds summary zoom overlay on the book page.
- Home page book cards show downloaded chapter count (amber badge) via new CountChapters method
- Book page cover image is clickable to zoom into a fullscreen overlay; click anywhere to dismiss
- Book page shows a 'Latest Chapter' button for unstarted books linking to the last downloaded chapter
- Continue-reading cards on home page have a dismiss (×) button that removes progress from localStorage and slides the card out to the left
- Remove Scrape form/button and Source text link from non-local ranking cards
- First click on a card highlights it amber and shows 'Click again to scrape' hint
- Second click POSTs to /ui/scrape/book and replaces card with polling status badge
- Pending state auto-cancels after 3 s or when clicking outside
- Source icon (external link SVG) retained but dimmed; stops click propagation
- Extract scrape form and autocomplete JS from homeTmpl into new scrapeTmpl
- Add handleScrape GET handler serving /scrape with ranking autocomplete
- Register GET /scrape route in server.go
- Replace inline scrape form on home page with '+ Add' flat button in header
- handleHome no longer loads ranking items (only needed on /scrape)
rankingPageNums now takes a current page parameter and always renders
first 2, last 2, and current±2 — so navigating to page 3 shows
1 2 3 4 5 … 80 81 instead of only the fixed quarter-mark anchors.
- Server collects distinct genres and statuses from all cached items and
passes them as AllGenres/AllStatuses slices to the template
- Facet chips rendered as pill toggles below the text search bar
- Cards gain data-status, data-genres (pipe-delimited), data-local attributes
- JS filter engine: AND between facets, OR within status facet (a book has
one status), AND within genre facet (all selected genres must be present)
- Pagination row hidden while any filter is active; restored on clear
- 'Clear filters' button appears when any filter is active
- sortedKeys helper added to produce stable sorted facet chip order
All filled/pill buttons across home, ranking, book detail, and chapter
pages now use transparent backgrounds with colored text only, consistent
with the chapter reader nav bar style:
- Home: Browse Rankings (amber text), Scrape (amber text)
- Ranking: View Markdown, page numbers, fetch buttons, Scrape/Source on cards
- Book detail: Source, Refresh, Resume, chapter pagination
- Chapter: bottom Prev/Next nav, article-end nav links
An <a> element nested inside the card's outer <a> is invalid HTML — browsers
auto-close the outer anchor before the inner one, causing the card to be split
across two grid cells visually. Replace with a <button> that calls window.open()
with event.preventDefault/stopPropagation to avoid interfering with card navigation.