diff --git a/packages/tui/src/ui/layout.ts b/packages/tui/src/ui/layout.ts index d9c94830c3..43c615c890 100644 --- a/packages/tui/src/ui/layout.ts +++ b/packages/tui/src/ui/layout.ts @@ -6,10 +6,13 @@ export function sessionTabsFitVertically(total: number) { return total >= SESSION_SIDEBAR_WIDTH + SESSION_CONTENT_MIN_WIDTH } +// The shared spine centers the prose measure; the technical rail shares its +// leading edge and extends rightward, clamped so it still fits the canvas. export function sessionLaneLayout(available: number, readable: number) { const technical = Math.min(available, Math.max(readable, SESSION_TECHNICAL_LANE_WIDTH)) + const centered = Math.floor((available - Math.min(readable, technical)) / 2) return { - inset: Math.max(0, Math.floor((available - technical) / 2)), + inset: Math.max(0, Math.min(centered, available - technical)), readable: Math.min(readable, technical), technical, } diff --git a/packages/tui/test/ui/layout.test.ts b/packages/tui/test/ui/layout.test.ts index 530975a6c0..a597919db2 100644 --- a/packages/tui/test/ui/layout.test.ts +++ b/packages/tui/test/ui/layout.test.ts @@ -12,9 +12,12 @@ test("vertical tabs match the session sidebar and preserve compact content width expect(sessionTabsFitVertically(85)).toBe(false) }) -test("session lanes share one leading edge", () => { +test("session lanes center the prose measure on one leading edge", () => { expect(SESSION_TECHNICAL_LANE_WIDTH).toBe(88) - expect(sessionLaneLayout(156, 66)).toEqual({ inset: 34, readable: 66, technical: 88 }) + // Wide canvas: prose is truly centered, technical extends rightward. + expect(sessionLaneLayout(156, 66)).toEqual({ inset: 45, readable: 66, technical: 88 }) + // Centering the prose would push the technical rail past the canvas; clamp. + expect(sessionLaneLayout(100, 66)).toEqual({ inset: 12, readable: 66, technical: 88 }) expect(sessionLaneLayout(80, 66)).toEqual({ inset: 0, readable: 66, technical: 80 }) expect(sessionLaneLayout(60, 66)).toEqual({ inset: 0, readable: 60, technical: 60 }) })