Problem: Users who explore alternative glosses in the interlinear popup want their choices remembered. Without persistence, selections are lost when the popup closes.
Solution: Two-layer persistence — localStorage for instant offline access, server-side for authenticated users. Selections merge with server data winning on conflict.
Not included: Cloud sync between accounts or sharing selections.
Selections are saved immediately and restored when reopening the popup for the same verse.
User flow:
Merge: Server wins over localStorage on conflict.
Invisible persistence — users just see their selections restored.
Visual indicators: Selected word cards get word-card--selected class + badge. Composed translation bar at bottom updates.
localStorage: Key bibleweb_translations — Record<"bookId-chapter-verse-wordPosition", gloss>
Server: GET/POST/DELETE /api/word-selections/{bookId}/{chapter}/{verse}
DB: word_selections — unique on (userId, bookId, chapter, verse, wordPosition), upsert on conflict.
Files:
apps/web/src/lib/components/bible/InterlinearPopup.svelte — load/save logicapps/web/src/routes/api/word-selections/[bookId]/[chapter]/[verse]/+server.tsapps/web/src/lib/server/queries/word-selections.tsCurrent: DONE Milestone: v2 Priority: Core — without persistence, gloss selection is useless
Dependencies: