KanbanBoard's board tabs implemented roving tabindex but never wired up
arrow-key navigation, making inactive tabs keyboard-unreachable. Adds
ArrowLeft/ArrowRight/Home/End handling that moves both selection and
focus between tabs, closing an unmet requirement from the original
design doc. Also adds aria-pressed to App's List/Board toggle buttons
so their active state is exposed to assistive technology, not just
conveyed visually via CSS class.
I1: move cog registration + tree.sync into ChorusBot.setup_hook (called once
before gateway connect) instead of on_ready (fires on every reconnect),
preventing duplicate cogs/listeners/poll loops after a gateway RESUME.
I2 (email_ingest.py, addressed alongside I1 for IMAP stability): none here,
handled separately.
I3/I4: TriageList.vue now renders a follow_up_date column so it actually
surfaces back to Donna. App.vue adds a "Show completed" checkbox bound to
includeDone, matching what docs/smoke-test.md step 7 already describes.
I5: add frontend/tests/ItemModal.spec.js covering stagesForType() options
for donation/other/unset types and the type-change stage reset regression.
I6: App.vue wraps loadItems/openItem in try/catch with a calm (no-panic)
error message, and shows calm empty-state copy when there are zero items.
Also fixes thread_ingest.py: standalone threads not started from a message
raise discord.NotFound on fetch_message; now caught and returns early.