diff --git a/v2/src/lib/components/Agent/AgentPane.svelte b/v2/src/lib/components/Agent/AgentPane.svelte
index 277e1e8..05890dc 100644
--- a/v2/src/lib/components/Agent/AgentPane.svelte
+++ b/v2/src/lib/components/Agent/AgentPane.svelte
@@ -286,7 +286,10 @@
);
if (!msg) return;
autoScroll = false;
- scrollContainer.querySelector('#msg-' + CSS.escape(msg.id))?.scrollIntoView({ behavior: 'smooth', block: 'center' });
+ const el = scrollContainer.querySelector('#msg-' + CSS.escape(msg.id));
+ if (el instanceof HTMLElement) {
+ scrollContainer.scrollTop = el.offsetTop - scrollContainer.clientHeight / 2 + el.offsetHeight / 2;
+ }
}
// Scroll anchoring: two-phase pattern
@@ -300,7 +303,7 @@
});
$effect(() => {
if (session?.messages.length !== undefined && wasNearBottom && autoScroll) {
- scrollContainer?.querySelector('#message-end')?.scrollIntoView({ behavior: 'instant' as ScrollBehavior });
+ if (scrollContainer) scrollContainer.scrollTop = scrollContainer.scrollHeight;
}
});
@@ -585,7 +588,7 @@
${burnRatePerHr.toFixed(2)}/hr
{/if}
{#if !autoScroll}
-
+
{/if}
@@ -607,7 +610,7 @@
{/if}
{#if !autoScroll}
-
+
{/if}
{:else if session.status === 'error'}
diff --git a/v2/src/lib/components/Workspace/ProjectBox.svelte b/v2/src/lib/components/Workspace/ProjectBox.svelte
index c990edb..2afb602 100644
--- a/v2/src/lib/components/Workspace/ProjectBox.svelte
+++ b/v2/src/lib/components/Workspace/ProjectBox.svelte
@@ -390,7 +390,7 @@
display: grid;
grid-template-rows: auto auto 1fr auto;
min-width: 30rem;
- scroll-snap-align: start;
+ /* scroll-snap-align removed: see ProjectGrid */
background: var(--ctp-base);
border: 1px solid var(--ctp-surface0);
border-radius: 0.375rem;
diff --git a/v2/src/lib/components/Workspace/ProjectGrid.svelte b/v2/src/lib/components/Workspace/ProjectGrid.svelte
index d07aa78..1efa4ac 100644
--- a/v2/src/lib/components/Workspace/ProjectGrid.svelte
+++ b/v2/src/lib/components/Workspace/ProjectGrid.svelte
@@ -16,14 +16,21 @@
let slotEls = $state>({});
// Auto-scroll to active project only when activeProjectId changes
- // (untrack slotEls so agent re-renders don't trigger unwanted scrolls)
+ // Uses direct scrollLeft instead of scrollIntoView to avoid bubbling to parent containers
$effect(() => {
const id = activeProjectId;
- if (!id) return;
+ if (!id || !containerEl) return;
untrack(() => {
const el = slotEls[id];
if (!el) return;
- el.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'nearest' });
+ // Only scroll if the slot is not already visible
+ const cRect = containerEl!.getBoundingClientRect();
+ const eRect = el.getBoundingClientRect();
+ if (eRect.left >= cRect.left && eRect.right <= cRect.right) return;
+ containerEl!.scrollTo({
+ left: el.offsetLeft - containerEl!.offsetLeft,
+ behavior: 'smooth',
+ });
});
});
@@ -75,7 +82,7 @@
gap: 0.25rem;
height: 100%;
overflow-x: auto;
- scroll-snap-type: x mandatory;
+ /* scroll-snap disabled: was causing horizontal jumps when agents auto-scroll */
padding: 0.25rem;
}