- Secure Vault (AES-256-GCM + PBKDF2 passphrase)
- Zustand partialize (secrets never in plain localStorage)
- No client-side API key injection
- Widget lazy-loading (React.lazy + Suspense + WidgetSkeleton)
-
scripts/measure-bundle.mjs+npm run measure:bundle/build:analyze
-
ResponsiveGrid— breakpoints lg→xxs (12→2 cols) - Auto-compact on mobile; resize disabled under 768px
- Drag via
.drag-handleonly; inputs/buttons cancelled -
useIsMobile/useContainerWidthhooks - viewport-fit=cover + safe-area + 44px coarse-pointer targets
- Docs:
docs/mobile-pwa.md
-
services/cloudBackup.ts— encrypted.ogbak.json+ optional HTTPS PUT/GET endpoint - Unit tests:
test/cloudBackup.test.ts - Docs:
docs/cloud-backup.md - Wire full UI in Settings → Data tab (API ready; polish remaining)
-
test/useMediaQuery.test.ts -
test/cloudBackup.test.ts - E2E (Playwright) smoke for mobile viewport + vault unlock
- Settings Data tab UI for encrypted export/import + cloud endpoint
- App chrome mobile menu for header controls (safe-area already in CSS)
- E2E mobile + backup flows
- Lighthouse mobile TTI after
npm run build:analyze
npm run test:run
npm run build:analyze # vite build + bundle size report
npm run measure:bundle # report only (needs dist/)Last Updated: August 2026