* fix: reduce autosave function invocation spam (25x anomaly)
Root cause: useProjectScene() was mounted in BOTH editor/index.tsx
AND project-dropdown.tsx, creating duplicate zustand subscriptions
that each independently triggered saveProjectModel() server actions.
Combined with a 2-second debounce and the fact that each server
action also calls getSession() (another function invocation), active
editing was generating ~120+ invocations/minute.
Changes:
- Remove duplicate useProjectScene() from project-dropdown.tsx
- Increase autosave debounce from 2s to 10s
- Skip auto-save on initial scene load from server (was saving the
scene right back after loading it)
- Add pending-save coalescing: changes during in-flight saves get
batched into one follow-up save instead of queuing concurrently
* fix: flush unsaved scene to cloud on page exit / unmount
Adds two safety nets so the 10s debounce doesn't lose data:
- beforeunload listener: fires saveProjectModel() when the user
closes the tab or navigates away externally
- cleanup flush on unmount: fires when navigating within the SPA
(e.g. switching projects, going to settings)
Both are fire-and-forget — if the browser kills the request,
localStorage still has the data and will sync on next load.
* style: fix biome import ordering in project-dropdown
---------
Co-authored-by: Anton Pascal <anton-pascal@users.noreply.github.com>
- /terms — Terms of Service for editor + pascal.app platform
- /privacy — Privacy Policy (data collection, third parties, user rights)
- Email notification toggle in Settings (new column + migration)
- Sign-in consent text linking to terms/privacy
- Effective date: February 20, 2026
Co-authored-by: Anton Pascal <anton-pascal@users.noreply.github.com>
- Move useCallback hooks before early return in ReferencesDialog
to fix conditional hook call violation (Rules of Hooks)
- Add useReducedMotion hook and apply to all motion animations
for WCAG 2.3.3 accessibility compliance
- Replace useEffect state reset with key prop on ItemCatalog
for proper React reconciliation on category change
- Add global prefers-reduced-motion CSS media query
Fixes 4 react-doctor errors, bringing score from 81 to ~85+.