The download progress indicator passed a deferred lambda
`progress = { progress!! }` reading UpdateState.downloadProgress
(MutableState<Float?>). Material3 invokes the lambda during
layout/draw, outside the composition snapshot that guarded it, so it
re-read the live state. ApkDownloader sets the value to null when the
response has no content length (total <= 0), and it can also flip while
the screen is being torn down, causing the `!!` to throw NPE.
Capture the value into an immutable local before branching so the
lambda closes over a non-null Float instead of re-reading live state.
On phones, the Connections list and Connection Details share a single
ModalBottomSheet. System back was consumed by the sheet's default dismiss
handler, closing the sheet and returning to Dashboard. The in-app back
button just cleared selectedConnectionId, returning to the list.
Add a BackHandler that runs only while a connection is selected, matching
the in-app back button behavior. Swipe-to-dismiss remains unchanged.
Move allLogs/bufferedLogs mutations in appendLogs, clearLogs,
and setDefaultLogLevel into viewModelScope.launch(Dispatchers.Main)
to avoid concurrent iteration from the search debounce flow.
Add a toggle in the service settings screen that calls
VpnService.Builder.allowBypass() when enabled, with a description
linking to Android documentation. Always show the Service item
in the settings list (remove battery-optimization-gated visibility).