diff --git a/src/workspaces/officerdev/src/apps/CommandHQ/CommandHqDetail.tsx b/src/workspaces/officerdev/src/apps/CommandHQ/CommandHqDetail.tsx
index c9bfca0b..d87488b9 100644
--- a/src/workspaces/officerdev/src/apps/CommandHQ/CommandHqDetail.tsx
+++ b/src/workspaces/officerdev/src/apps/CommandHQ/CommandHqDetail.tsx
@@ -44,7 +44,7 @@ function EmptyState() {
* which matters because this ships on every deploy whether the copy is ready or not.
*/
const NewCommanderGuide = () => (
-
+
{NEW_COMMANDER_GUIDE.map((section) => (
@@ -302,8 +302,19 @@ function NewCommander({
and not to the component left that radio hidden inside a commander — the one place it exists for. */}
{/* Before the first message, the pane explains itself. `EmbeddableChat`'s own empty state is "Send a
message to start", which is true and tells a first-time user nothing about what to send. */}
+ {/*
+ One scroll region for the whole pre-start pane, rather than three `shrink-0` siblings.
+
+ They stacked to whatever height they wanted and nothing could scroll: the guide carried its own
+ `overflow-y-auto`, which never engaged, because `shrink-0` had already given it its full natural
+ height. Fine at 100%, and the panel system is zoomable — at 120% the setup ran off the bottom of
+ the panel with no way to reach it.
+
+ So the scroller is here, where the height is actually constrained, and the composer below keeps
+ `shrink-0` so it stays reachable at the bottom whatever the zoom.
+ */}
{chat.messages.length === 0 && (
- <>
+
setPickerOpen(true)} />
- >
+
)}
{/* Disabled until both are chosen. The composer is where somebody would otherwise type first and
discover the requirement afterwards, having already written what they meant to say. */}
@@ -338,7 +349,7 @@ function NewCommander({
? { reason: !name.trim() ? 'Name it first…' : 'Choose a working directory first…' }
: false
}
- className="min-h-0 flex-1"
+ className={chat.messages.length === 0 ? 'shrink-0' : 'min-h-0 flex-1'}
/>
setPickerOpen(false)} onSelect={setCwd} />