Contacts: the empty-state box no longer sits flush against the search bar separator.
Themes: toggle switches now have a border outline in the off state so they stay visible on near-black themes.
Windows: shared-instance RPC replies are read through the connection dispatch path instead of os.read, fixing bad file descriptor errors that broke LXMF delivery, interface stats, and interface management on Windows builds when connected to an external rnsd.
Messaging: outbound sends that fail the path wait are now persisted as failed messages instead of being dropped, so they resend automatically when the peer announces and can be resent manually. The propagation-node fallback now defaults on for new configurations and is a safe no-op when no propagation node is set.
Maps: user-configured tile servers, Nominatim endpoints, and extra CSP sources are no longer stripped from the Content Security Policy in privacy mode. Only the shipped public defaults stay gated. Scheme-less and subdomain-template ({s}, {r}) tile URLs are normalized so OpenLayers and the CSP match real hosts.
NomadNet: page translation now works with the sandboxed page renderer. The shell asks the renderer frame for the page text over the frame channel instead of reading an empty shell container, so the translate button opens the translator with real page content.
NomadNet: the page shell no longer can show its own scrollbar next to the rendered frame's scrollbar. The container only scrolls for state banners now, which removes the second slider on platforms with always-on scrollbars.
NomadNet: serving nodes no longer re-hash the whole source image on every /media request. The hash is memoized by file stat. Failed conversions are marked and skipped for an hour instead of respawning the encoder on every request, which removes the sustained CPU spikes on image-heavy pages.
Desktop: every popout window (call, nomad tab, translator, paper message, and the rest) now runs in its own renderer process where the API allows it, so a crash there cannot take the whole app down. A crashed child window is destroyed instead of lingering as a dead frame. The main window's crash recovery dialog is unchanged.
NomadNet: rendered pages that use the full-bleed shell (.html, .md, .txt) no longer overflow the viewer by the header and toolbar height. The content container carried a stray min-h-full that beat its min-h-0, so the rendered frame ran ~54px past the bottom of the pane and its scrollbar hung below the page boundary, reading as the extra-slider artifact.
Network visualiser: leaving the page during engine setup no longer orphans a live graph instance per visit. The init chain now checks for unmount after every await and destroys anything created in flight.
Network visualiser: the loading overlay now has a cancel button. Stopping aborts in-flight fetches, halts physics and batch work, and leaves a fresh load one click away on the refresh button.
Telemetry: tracked peers that never answer are no longer polled every interval forever. Each unanswered request doubles the wait up to a daily cap, and after a bounded number of misses the peer is skipped until a telemetry response re-arms it or tracking is re-toggled.
Messaging: automatic resends no longer retry feature-only deliveries (commands, reactions, telemetry) to peers that never sent one back, so Sideband and other LXMF clients are not spammed with payload types they cannot parse.
Contacts: shared address output now uses the bare 32-hex hash when no public key is known, since not every LXMF client parses an lxmf:// URI. lxma:// output is unchanged when a public key is available.
Android: Bluetooth RNode interfaces (BLE and classic) added or imported through the UI now write the Android-native Reticulum keys at save time, so the live attach takes the Bluetooth path instead of treating a bt:// or ble:// port as a dead USB serial device. Leftover Bluetooth keys are also stripped when an interface is switched back to serial or TCP, since the Android implementation lets stale ble_* settings override the port.
Android: the RNode form now asks for Bluetooth permission when the BLE or Bluetooth transport is enabled, instead of relying on the bundled startup prompt that can be dismissed and never re-shown.
Android (build): the bundled Reticulum wheel now guards paired-device enumeration against devices with no name and denied Bluetooth permissions, so one bad bonding record or a missing grant no longer kills RNode Bluetooth bring-up.
Relay chat: the hide join/part preference now applies. A setup-time read shadowed the setting's lookup, so presence lines kept rendering and the toggle wrote the old value back to storage.
Tools: the traffic page refresh button no longer flashes on every background poll. The spinner now only runs for manual refreshes.
Tools: the traffic page RRC hint now counts connected hubs by the real status constant instead of a string comparison that always read zero.