Free-text annotations on any channel or video, searchable from the
global filter box.
## Storage
New `notes` table keyed by (target_kind, target_id):
- target_kind: "channel" or "video"
- target_id: "platform/handle" for channels, video ID for videos
- empty body deletes the row, so the table only holds real notes
DB methods: get_note, set_note (upsert-or-delete), get_all_notes.
## API
- GET /api/notes → { "video:<id>": body, "channel:<plat>/<handle>": body }
fetched once on page load, held in memory for indicators + search
- POST /api/notes/:kind/:id { body } → upsert/delete
## Web UI
- 📝 button on every video card; turns accent-colored when a note
exists. Opens an edit-in-place modal.
- 📝 Add/Edit note… sub-action under each channel in the sidebar.
- Global search now also matches note bodies, so you can find a clip
by what you wrote about it.
## Desktop UI
- Note field in the video detail panel (bottom dock). Loads lazily
from the DB when the selection changes; persists on focus-loss.
## Restore
Backup import merges the notes table too (keep-later-timestamp,
same as watched/positions). Guarded with a table-exists check so
pre-notes backups still import cleanly. RestoreSummary gains
notes_added; both UIs show it.
4 new tests (2 notes DB behavior, restore merge already covered the
shape). 79 pass total.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>