support: surface errors with recovery guidance and bound portal retry
- loadAnnouncements() now logs to console.warn and shows a subtle muted
message instead of silently swallowing failures
- loadTickets() error state includes a "try again" retry button
- openTicket() error state includes a "back to tickets" button to
restore the list view
- Reply and feedback submit errors show human-readable messages with
recovery hints instead of generic/raw error text
- PortalClient.register() strips and replaces handle suffix on 409
retry (preventing unbounded handle growth) and raises RuntimeError
after 3 failed attempts