Card delete animation (public/css/style.css, public/js/modules/board.js):
* @keyframes card-remove: opacity 1→0 + scale(1)→0.85 + translateY(8px),
250ms ease-in forwards. .card-removing class with pointer-events:none.
* New exported animateCardRemoval(ids) in board.js: adds .card-removing
to each matching board-card element, resolves after 260ms so the
caller can await before the API DELETE + _reloadAll.
* Wired into all three delete paths:
- context-menu.js group delete: animates parent + all children
- context-menu.js single delete: same path (allCards has one entry)
- app.js Del/Backspace shortcut: animates all selected cards
Quick capture no #inbox (public/js/app.js):
* Removed the line that auto-injected #inbox into the body of every
quick-captured card. Cards now land tag-free in the active bucket
(or unsorted).
Settings: preset delete lock (public/js/modules/theme.js):
* refreshPresetSelect() now disables the delete button (disabled attr
+ opacity 0.35 + cursor not-allowed) when a builtin: preset is
selected. Re-enabled when a user: preset is selected. The click
handler already had a startsWith('user:') guard but the button
wasn't visually locked.
chore: bump version to 0.9.17
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The <select> element survives settings open/close, so its lingering value
masked the otherwise-empty restore path on the second open and the
dropdown always reverted to whatever was last picked in the *current*
session. Track the active preset in localStorage on every change /
save, restore from localStorage first (it's the source of truth), and
clear the entry on delete.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>