The app can now operate backend-agnostically: a production build still
asks on first start, but /setup also offers 'Continue without a backend'
(stored as the sentinel 'none'), and the shell adapts:
- Local mode shows only the e621-facing pages: Online (search, post view,
favorites, blacklist editor, direct downloads) and Pools. Library,
uploads, duplicates, stats, users, follows and similarity are hidden
from the nav and palette and render a 'backend needed' state when
reached directly; /detail/<e621 id> still works while /detail/J-x asks
for a backend.
- e621 credentials are stored in this browser (j621.e621) and the
Account page becomes a credentials-only screen; the store reads/writes
locally instead of /api/auth/e621/.
- The header replaces the status pill and login/user area with an e621
credentials button and a 'Setup Backend' button; the footer shows
'Local mode — e621 features only' with the same entry point.
- In-library lookups (badges/browse markers) are skipped without a
backend; 'Download to client' links straight to the e621 file instead
of the backend proxy; follow buttons and palette follow toggles are
hidden; api() fails fast with a clear message if something slips
through.
Mode logic lives in lib/backend.ts (URL / '' same-origin / 'none') with
its matrix verified in Node; tsc, oxlint and the build are clean.