Pushed fixes for all three Bugbot findings (each verified against the code first) plus one design change:
- Escape gated on
onClickOutside— confirmed, and worse than reported: only logs passesonClickOutside. The primary Escape handler now lives inPreviewPanelitself, keyed offonClose(which every instance passes) — so Escape works on all shared instances with zero instance changes. The wrapper keeps a copy (gated ononClickOutside) to cover bespoke children like the logs detail panel; double-firing is idempotent. - Refocus on row change — confirmed. Focus now tracks open-state transitions (
wasOpenRef): moves in only on closed→open, restores only on open→closed; prev/next row navigation leaves focus where the user put it. - Focus outside the labeled dialog — confirmed.
role="dialog",aria-label(newariaLabelprop on the wrapper, default "Details"), andtabIndex={-1}are now colocated on the focusedmotion.div; removed from the inner component.
Also: panel surface bg-background → bg-card (dark: oklch 0.159 → 0.218) so the slide-over reads as an elevated layer above the page rather than a same-level region — proper dark-theme elevation via surface step + the existing border-l.