diff --git a/DESIGN.md b/DESIGN.md index a4804cb0e27..bda54f4da2b 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -60,8 +60,12 @@ title sizes remain larger. The bottom navigation responds to accumulated scrolling, ignoring small reversals and Safari's edge bounce. It glides out and eases back in with shared -motion tokens; the task composer follows the same motion. Keep page padding -stable while the navigation moves, and honor reduced-motion preferences. +motion tokens. Keep page padding stable while the navigation moves, and honor +reduced-motion preferences. + +Mobile task conversations size their shell to the visible viewport, with one +message scroller and a normal flex footer for the composer. Navigation stays at +the layout viewport bottom, behind the keyboard. Cold task opens reveal the instruction and recent conversation independently of plans, related metadata, and historical run activity. Show the latest human diff --git a/ui/src/components/Layout.production.tsx b/ui/src/components/Layout.production.tsx index 56afb99fc06..cdb984d85d7 100644 --- a/ui/src/components/Layout.production.tsx +++ b/ui/src/components/Layout.production.tsx @@ -45,6 +45,7 @@ import { useSidebar } from "../context/SidebarContext"; import { useKeyboardShortcuts } from "../hooks/useKeyboardShortcuts"; import { useCompanyPageMemory } from "../hooks/useCompanyPageMemory"; import { useMobileNavVisibility } from "../hooks/useMobileNavVisibility"; +import { useMobileVisualViewport } from "../hooks/useMobileVisualViewport"; import { healthApi } from "../api/health"; import { resolveArchivedCompanyBounce, @@ -178,6 +179,7 @@ export function Layout() { const scrollMemory = useRef(new NavigationScrollMemory()); const activeScrollKey = useRef(location.key); const mobileNavVisible = useMobileNavVisibility(isMobile, location.pathname); + const mobileViewportRef = useMobileVisualViewport(isMobile); const [shortcutsOpen, setShortcutsOpen] = useState(false); const matchedCompany = useMemo(() => { if (!companyPrefix) return null; @@ -588,8 +590,10 @@ export function Layout() { return (
@@ -663,12 +667,13 @@ export function Layout() {
) : null}
-
+
(location.key); const mobileNavVisible = useMobileNavVisibility(isMobile, location.pathname); + const mobileViewportRef = useMobileVisualViewport(isMobile); const [shortcutsOpen, setShortcutsOpen] = useState(false); const matchedCompany = useMemo(() => { if (!companyPrefix) return null; @@ -574,8 +576,10 @@ export function Layout({ sidebarSections }: { sidebarSections?: ReactNode }) { return (
-
+
{isMobile && sidebarOpen && (