Completes FC-6.1: the series management UI now works in chapters.
- SeriesManageView: chapters as cards (inline-rename, stated-page range inputs,
move up/down, merge-into-previous, delete, pick-as-add-target), pages
drag-reorder WITHIN a chapter, a "gap: N-M missing" badge between chapters
with a stated-page hole, and Add chapter / Add placeholder. The picker adds
the selection into the targeted chapter.
- seriesManage store: chapter CRUD + reorderChapters/moveChapter/mergeChapter/
reorderPages actions; consumes chapters[]/gaps[]; addSelected targets a chapter.
- Reader: page_number is now within-chapter, so anchors switched to a global
`seq` (reading-order position) — fixes scroll/jump/active collisions across
chapters — plus chapter-title dividers at each chapter boundary.
- Updated seriesManage.spec to the chaptered store shape.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The IntersectionObserver-on-a-sentinel infinite-scroll pattern was copy-
pasted in 7 places. New composables/useInfiniteScroll(sentinelRef, cb)
owns the observer lifecycle (attach on mount, re-attach when the ref
changes, disconnect on unmount). Migrated GalleryGrid, MasonryGrid
(gallery+showcase), ArtistPostsTab, ArtistsView, TagsView, SeriesManageView.
PostsView left manual on purpose — its anchored mode does bidirectional
scroll-position preservation that doesn't fit the simple composable.
I4(a) (timestamps) is effectively already done: the UTC displays were
converted earlier; the remaining toLocaleString uses already render local
time, so they're left as-is rather than churned for format-only consistency.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>