Rework the startup device picker into a self-contained splash flow:
- probe_meshcore (renamed from smoke_test_meshcore) now leaves the confirmed
connection open and returns it, so AppContext.adopt_device reuses that live
radio instead of reopening (many boards reset on each serial open). Restore
the library's normal per-command timeout once the handshake succeeds.
- Extract the Braille animation into a reusable tui.Spinner; BusyScreen now
delegates to it.
- Pin the wordmark to a fixed vertical anchor so it never shifts as the box
swaps between the device list, spinner, and messages.
- Esc or a trailing Quit row leaves the splash and exits the program.
- Show the copyright only on the opening splash; retire it once a device is
chosen, even across a failed smoke test and re-pick.
- Disable prompt_toolkit's loop exception handler and route asyncio (and the
awaited spinner ticker) errors to the file log, so a stray background-task
error can't dump a traceback over the full-screen UI.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>