deckhearth/.convoys/scanner-mobile-checkout/brief-1-layout-immersive-chrome.md
varutasu 73424aae59
Mobile scanner checkout: scan first, commit later (#157)
* Start scanner-mobile-checkout convoy for the cart-then-commit phone flow.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Ship a cart-then-commit mobile scanner so phone sessions stay on the camera.

Scan matches enqueue locally instead of auto-writing ownership, checkout happens in a sheet, and audit fixes cover stale commit detection, returnUrl open redirects, nested Escape, and ember detection chrome.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-14 20:20:43 -05:00

2.9 KiB

convoy brief_number depends_on recommended_model model_tier files cross_brief_commitments
scanner-mobile-checkout 1
composer-2.5-fast fast
components/Layout.js
test/components/Layout.test.js
brief description
4 Brief 4 passes `chrome="immersive"` on `<Layout>` from `pages/scanner.js` for authenticated scanner sessions. This brief only adds the prop and mobile-only hiding behavior; Brief 4 owns when it is set.

Brief 1: Layout immersive chrome

Goal (1 sentence)

Add a narrow chrome="immersive" prop to Layout that hides global app chrome on viewports < md without restyling the desktop sidebar.

Files in scope (do not edit anything else)

  • components/Layout.js
  • test/components/Layout.test.js

Conventions to follow

  • Extend the existing Layout signature: export default function Layout({ children, user = null, showSearch = false }) → add chrome = 'default'.
  • Immersive is mobile-only (md:hidden / max-md: patterns). At md+, immersive behaves like default (sidebar + TopSearchBar unchanged per D3 desktop note).
  • Hide when chrome === 'immersive' on < md:
    • <MobileNavigation /> (line ~674)
    • <TopSearchBar /> (line ~986)
    • Desktop <aside> sidebar is already hidden md:flex — no change needed at md+; on mobile the drawer + bottom nav are the chrome to suppress.
  • Main column: remove pb-16 bottom padding when immersive (no bottom nav). Use max-md:pb-0 on the main wrapper (flex-1 flex flex-col pb-16 md:pb-0).
  • Outer shell: optional max-md:p-0 when immersive so camera can be true full-bleed.
  • Do not change sidebar styles, nav items, or command palette behavior.
  • Use CSS tokens only — no new hex in JSX.

Implementation shape (verified against Layout.js)

export default function Layout({
  children,
  user = null,
  showSearch = false,
  chrome = 'default',
}) {
  const isImmersive = chrome === 'immersive';
  // ...
  // MobileNavigation: {!isImmersive && <MobileNavigation ... />}
  // TopSearchBar: {user && !isImmersive && <TopSearchBar ... />}
  // Main wrapper className: include isImmersive && 'max-md:pb-0'
}

Acceptance criteria

  • chrome="immersive" hides MobileNavigation and TopSearchBar below md breakpoint
  • chrome="immersive" at md+ renders identical chrome to chrome="default" (sidebar + TopSearchBar visible)
  • chrome="default" (or omitted) is unchanged from current behavior
  • test/components/Layout.test.js adds regression tests: immersive hides mobile nav landmark; default still renders Sign-in CTA when user={null} (existing 5 assertions preserved)
  • No scope expansion (do not edit files outside files: above)

Rationale (≤3 sentences)

Immersive chrome is isolated to Layout.js so visual-diff-sensitive sidebar code stays untouched. Mobile-only gating matches design-direction desktop exception. Brief 4 wires the prop from /scanner without further Layout changes.