- tag_form.dspy: rewrite as multi-select checkbox list (clickable rows with toggle)
+ input field for new tag with + button (calls /api/tag/create with dedup)
+ submit button calls /api/tag/sync to sync media_tags
+ dynamically add new tag row to list after creation
- media_cards.dspy: read tags from media_tags table instead of metadata
- init.py: tag_create_handler adds dedup (check existing by kb_id+name)
- init.py: new tag_sync_handler (full sync: delete old + insert selected)
- config.json: add /api/tag/sync route