diff --git a/frontend/src/features/analysis/ui/StructureViewer.vue b/frontend/src/features/analysis/ui/StructureViewer.vue
index 018841c..43efb3d 100644
--- a/frontend/src/features/analysis/ui/StructureViewer.vue
+++ b/frontend/src/features/analysis/ui/StructureViewer.vue
@@ -284,29 +284,33 @@ watch(
// When the caller sets a focused self_ref (e.g. the user clicked a node in
// the graph), find which page that element lives on and jump to it. The
// overlay redraw will then show the dashed focus ring around its bbox.
-watch(
- () => props.focusedSelfRef,
- (ref) => {
- if (!ref) {
- nextTick(drawOverlay)
+function scrollToFocused(ref: string | null): void {
+ if (!ref) {
+ nextTick(drawOverlay)
+ return
+ }
+ for (const page of props.pages) {
+ if (page.elements.some((e) => e.self_ref === ref)) {
+ if (selectedPage.value !== page.page_number) {
+ selectedPage.value = page.page_number
+ // Let
reload before drawing — drawOverlay runs on @load.
+ } else {
+ nextTick(drawOverlay)
+ }
return
}
- for (const page of props.pages) {
- if (page.elements.some((e) => e.self_ref === ref)) {
- if (selectedPage.value !== page.page_number) {
- selectedPage.value = page.page_number
- // Let
reload before drawing — drawOverlay runs on @load.
- } else {
- nextTick(drawOverlay)
- }
- return
- }
- }
- // Ref not on any page (e.g. a #/body node) — just redraw to clear the
- // previous focus ring.
- nextTick(drawOverlay)
- },
-)
+ }
+ // Ref not on any page (e.g. a #/body node) — just redraw to clear the
+ // previous focus ring.
+ nextTick(drawOverlay)
+}
+
+watch(() => props.focusedSelfRef, scrollToFocused)
+
+// Imperative entry point so callers can re-trigger a scroll on the same
+// self_ref (the watch above only fires on value change). Used by the
+// reasoning workspace when the user re-clicks the active iteration card.
+defineExpose({ scrollToFocused })