# `lib/` conventions Short rules. The patterns we already follow as of v0.16 — write new code that fits. **One store per cross-cutting concern.** A single `*-store.ts` file owns each one: - `auth.ts` — JWT / PIN in `localStorage`, `isAuthenticated` writable - `ui-store.ts` — bottom-nav visibility, upload-sheet open state, FAB badge count - `data-mode-store.ts` — Saver vs Original media-loading preference - `privacy-note-store.ts` — admin-configured Datenschutzhinweis text - `quota-store.ts` — live per-user storage snapshot - `upload-queue.ts` — IndexedDB-persisted upload queue + processing state Don't import these into other stores unless strictly necessary; let pages compose them. **DTOs mirror Rust types.** All TS interfaces live in `types.ts`. Each one carries a `// mirrors backend/src/path::TypeName` comment so the two stay searchable. If you add a Rust DTO, add the TS twin in the same PR. **Gestures via Svelte actions in `actions/`.** Long-press, double-tap, future swipe — each is a `use:` action that fires a CustomEvent. Components stay free of gesture plumbing. **Reusable bottom sheets via `ContextSheet.svelte`.** Pass an `actions: ContextAction[]` array. Any page that needs a long-press / kebab context menu uses the same primitive. **SSE relays are listed in `sse.ts::KNOWN_EVENTS`.** New server event → add one entry to that array, that's it. **Diashow transitions live in `diashow/transitions/`.** Each is a Svelte component plus one entry in `transitions/index.ts`. Adding a new animation is two-line work; no diashow code needs to change. **No new global stores** beyond the list above unless the new concept is genuinely app-wide. Page state belongs in the page.