diff --git a/components/sidebar.tsx b/components/sidebar.tsx
index 2425cd3..e1b387c 100644
--- a/components/sidebar.tsx
+++ b/components/sidebar.tsx
@@ -52,22 +52,47 @@ export function SidebarProvider({ children }: { children: React.ReactNode }) {
return (
{/* transitions gated on mount: no slide-in flash on page load */}
-
{children}
+
{children}
);
}
-/** Hamburger for page headers — only visible when the sidebar is closed. */
+/** Hamburger for page headers — only visible when the sidebar is closed.
+ *
+ * Owner, round 6c: the toggle is ALWAYS MOUNTED, owning a slot whose
+ * width+margin animate in LOCKSTEP with the sidebar's own width
+ * transition (same duration-200, same easing, both gated on mount) —
+ * before, it mounted/unmounted in one frame, so its 48px footprint
+ * (button + gap) popped and dragged the title and chips sideways while
+ * the sidebar was still mid-slide. When open the slot is exactly zero
+ * (w-0 -mr-3: width 0, the negative margin cancels the header's gap-3),
+ * so resting layouts are pixel-identical to the old conditional render.
+ * The icon fades with the slot and is clipped by it as it collapses —
+ * no popping in either direction. */
export function SidebarToggle() {
const { open, toggle } = useSidebar();
- if (open) return null;
return (
-
+
+
+
);
}