Server-side pagination for all browse pages, glossary cleanup
Server-side pagination everywhere - the /authors, /series, /groups, /universes, and /genres pages have been migrated from loading the full list and filtering in the browser to paginating directly in the database. Each page now sends only the visible rows over the wire and updates the URL when you search, sort, filter, or page through results, so links stay shareable and the back button works as expected. Matches the pattern already in place on /characters and /books.
Faster groups page - the groups list previously loaded every group's full member roster just to display the member count. Now it asks the database for the count directly, reducing the data sent for that page to a small fraction of what it was before. Pages also run their count and data queries in parallel so each browse page makes roughly half as many sequential database round-trips.
Glossary cleanup - removed three glossary entries that didn't belong:
- "The Duat (detail)" - a duplicate of "The Duat" with a less detailed description
- "Riviera" - actually the character Peter Riviera (Neuromancer), not a glossary concept
- "Chains" - actually the character Father Chains (Gentleman Bastards), not a glossary concept
A full audit of the remaining 1,265 glossary entries turned up no other duplicates or mis-categorised characters.
Search bug fix - searching for just % or _ (which are SQL wildcards) was returning every row instead of nothing. Now correctly returns no results.
Social content generator - admin "This Day in Literary History" social post generator was sometimes showing the previous version of life event notes after a curator edit. Removed the cache layer that was causing this; curator changes now appear immediately.