Summary
Phase 1 of the SMS management improvements discussed in plain-app#362 (backend: plain-app#363). Two small, independent additions to the conversation view.
### 1. Trash a single message
Hovering a chat bubble reveals a trash button (same hover affordance as the
existing tag button). Clicking it calls the new `trashSms` mutation with
`ids:<message-id>`, removes the message from the list immediately, and the
thread refetches via the existing `media_items_actioned` event. The button is
hidden for drafts and pending messages — only settled messages can be trashed.
No row is removed from the system SMS database: the backend flips an app-side
flag in a Room shadow table, so the message is recoverable for 30 days and the
system Messaging app still shows it untouched.
### 2. Keyboard review mode
A new header button (next to Export / Archive) opens a focused review modal,
one message at a time:
| Key | Action |
| --- | --- |
| `D` / `X` | trash the current message and advance |
| `K` / `→` | keep the current message and advance |
| `Z` | undo the last trash and bring it back |
This is deliberately the same interaction model as the image lightbox in #24:
actions are silent and the safety net comes at the end, rather than a toast per
action. When the queue is exhausted (or the modal is closed), the shared
`OrganizeConfirmModal` appears once — **Undo all / Keep changes**. Nothing is
final until that single decision, so reviewing 50 messages costs one
confirmation instead of 50.
## Files
- `src/lib/api/mutation.ts` — `trashSmsGQL` / `restoreSmsGQL`
- `src/hooks/sms-trash.ts` — `useSmsTrash` / `useSmsRestore` wrappers, emit `media_items_actioned`
- `src/views/messages/SmsReviewModal.vue` — the review modal
- `src/views/messages/MessageChatBubble|List|Header.vue`, `MessagesView.vue` — button, event plumbing, mutation wiring
- `src/locales/*/messages.ts` — `trash_message`, `review_mode`, `review_remaining`, `review_hints`, `review_all_done` for all 17 locales
- `components.d.ts` — regenerated
## Notes
- Requires plain-app#363 for the two new mutations.
- Restore is currently only reachable through the session undo (per-message and
the summary dialog); a browsable trash view is planned for a later phase.
- Verified with `vue-tsc --noEmit` and `vite build`.