diff --git a/src/features/workbench/layout/workbench-layout.test.ts b/src/features/workbench/layout/workbench-layout.test.ts index b1094c3..4f072eb 100644 --- a/src/features/workbench/layout/workbench-layout.test.ts +++ b/src/features/workbench/layout/workbench-layout.test.ts @@ -5,7 +5,8 @@ import { getAgentPanelMaxWidth, getWorkbenchBasemapTone, getWorkbenchCameraPadding, - getWorkbenchViewportLayout + getWorkbenchViewportLayout, + resolveMobileWorkbenchOverlayLayout } from "./workbench-layout"; describe("workbench basemap surface tone", () => { @@ -20,6 +21,19 @@ describe("workbench basemap surface tone", () => { }); describe("workbench floating panels", () => { + it("derives mobile dock and map control offsets from one overlay stack", () => { + expect(resolveMobileWorkbenchOverlayLayout(true)).toEqual({ + timelineBottom: 12, + dockBottom: 68, + mapControlBottom: 120 + }); + expect(resolveMobileWorkbenchOverlayLayout(false)).toEqual({ + timelineBottom: 12, + dockBottom: 12, + mapControlBottom: 64 + }); + }); + it("uses bounded desktop and wide panel widths", () => { expect(getWorkbenchViewportLayout(1440)).toMatchObject({ agentWidth: 500, diff --git a/src/features/workbench/layout/workbench-layout.ts b/src/features/workbench/layout/workbench-layout.ts index d3af352..4778e2d 100644 --- a/src/features/workbench/layout/workbench-layout.ts +++ b/src/features/workbench/layout/workbench-layout.ts @@ -26,9 +26,29 @@ export const WORKBENCH_LAYOUT = { mobileSheet: { halfViewportRatio: 0.52, fullTopGap: 68 + }, + mobileOverlay: { + edgeInset: 12, + gap: 8, + dockHeight: 44, + timelineSummaryHeight: 48 } } as const; +export function resolveMobileWorkbenchOverlayLayout(timelineVisible: boolean) { + const { edgeInset, gap, dockHeight, timelineSummaryHeight } = + WORKBENCH_LAYOUT.mobileOverlay; + const dockBottom = timelineVisible + ? edgeInset + timelineSummaryHeight + gap + : edgeInset; + + return { + timelineBottom: edgeInset, + dockBottom, + mapControlBottom: dockBottom + dockHeight + gap + }; +} + export function clampAgentPanelWidth( width: number, viewportWidth: number, diff --git a/src/features/workbench/map-workbench-page.tsx b/src/features/workbench/map-workbench-page.tsx index 5e61e5d..81357fe 100644 --- a/src/features/workbench/map-workbench-page.tsx +++ b/src/features/workbench/map-workbench-page.tsx @@ -78,7 +78,8 @@ import { import { WORKBENCH_LAYOUT, getWorkbenchBasemapTone, - getWorkbenchLayoutCssVariables + getWorkbenchLayoutCssVariables, + resolveMobileWorkbenchOverlayLayout } from "./layout/workbench-layout"; import { getResponsiveWorkbenchPadding } from "./map/camera"; import { exportMapViewImage } from "./map/export-view"; @@ -220,9 +221,10 @@ export function MapWorkbenchPage({ timelineMode, timelineVisible ); + const mobileOverlayLayout = resolveMobileWorkbenchOverlayLayout(timelineVisible); const timelineBottom = isLargeScreen ? timelineScaleLayout.timelineBottom - : 12; + : mobileOverlayLayout.timelineBottom; useEffect(() => { setTimelineMode((current) => { @@ -987,19 +989,30 @@ export function MapWorkbenchPage({ onReturnNow={handleReturnOperationalNow} /> - + + : null )} mapContent={( @@ -1019,10 +1032,13 @@ export function MapWorkbenchPage({
-
+
+
-
+
{mobileSheet === null ? (