- storage.ts: Centralize ALL_LIBRARIES = "__all__" sentinel constant.
setSelectedLibrary() now writes both localStorage and a cookie
(selectedLibrary, Path=/, SameSite=Lax, max-age=365d). The
sentinel "__all__" is used in both storage mediums — empty strings
are never stored. getSelectedLibrary() maps __all__ back to "".
Cookie enables server-side rendering to read the stored library
selection without access to localStorage.
- library-switcher.ts: Import ALL_LIBRARIES and setSelectedLibrary/
getSelectedLibrary from storage.ts instead of managing localStorage
directly. Remove local constants.
- dashboard.ts: Remove duplicate localStorage.setItem call that was
overwriting the __all__ sentinel with raw empty string. Fix
reloadPage() and scan-complete handler to work with empty libraryId.
openDashboardSettings/saveDashboardSettings show clear messages for
All Libraries mode.
- collections.ts: Remove library switcher initialization from the
collections list page — the list page no longer has a switcher.
- series.ts: Rewrite to use initLibrarySwitcher from library-switcher
module and switchWithTransition for navigation. Series card links
no longer include library_id in their URLs.
- bookshelf.ts: Autocomplete fetch calls handle empty libraryId
correctly for All Libraries mode.
- search.ts, collection-rules.ts: Use setSelectedLibrary() and
getSelectedLibrary() from storage.ts instead of direct localStorage
access.
Create a new /series/detail?name=X&library_id=Y SSR page that shows
all books in a specific series, replacing the broken approach of
linking to /bookshelf?series_filter=X (the bookshelf SSR handler
ignores all filter query params).
The series detail page features:
- Back link to /series browse page
- Library selector dropdown (full page navigation on change)
- Series name header with book count badge
- Book grid using the shared BookCard template
- Empty state for series with no books
Update all links to point to the new page:
- Series cards on /series browse page
- Series badge on book detail page
- JS-rendered cards in series.ts switchLibrary
Add seriesDetailPage Alpine component for the detail page's
library switcher (simple navigation, no AJAX needed).
Create web/src/series.ts with Alpine component implementing the same
switchLibrary pattern as the dashboard:
- Fetch /api/series on library change instead of full page reload
- Fade out/in transition with loading spinner
- Re-render series grid and pagination from JSON response
- Save selected library to localStorage
Import series.ts in main.ts.
Add stacked-cascade CSS to input.css for multi-cover series cards:
- Covers cascade from top-left to bottom-right with increasing z-index
- Front cover sits at bottom-right (highest z-index)
- Separate layout rules for 1-7 covers with rotation offsets
- Hover lift effect on series cards