47f0cdf3a2
Keep-alive keeps every ever-active tab mounted, but each hidden tab's ChatRuntimeBoundary still subscribed to its view's $messages — so every streaming delta flush (~30x/s) re-rendered every busy tab's whole thread, and five concurrent sessions dropped the app to a crawl. Flow the pane layer's visibility down as PaneVisibleContext and gate the $messages subscription on it: a hidden tab freezes its transcript (status dots stay live through the separate status atoms) and catches up in one commit on reveal, since subscribe fires immediately with the current value.