SHA256
ui.js now (a) decides setup-vs-unlock from GET /api/records emptiness, (b) runs the setup flow (double entry check, min length, TOCTOU re-check that the DB stayed empty), (c) detects a fully failed unlock (all rows undecryptable = wrong passphrase) and returns to a clean state, and (d) blocks double submits while Argon2id derives the key. Verified: node --check passes, live server serves both screens and a crypto roundtrip proves setup passphrase unlocks on second visit while a wrong passphrase is rejected. 🤖 Generated with Codebuff Co-Authored-By: Codebuff <noreply@codebuff.com>