deckhearth/.convoys/scanner-mobile-checkout/brief-1-layout-immersive-chrome.md

70 lines
2.9 KiB
Markdown
Raw Permalink Normal View History

---
convoy: scanner-mobile-checkout
brief_number: 1
depends_on: []
recommended_model: composer-2.5-fast
model_tier: fast
files:
- components/Layout.js
- test/components/Layout.test.js
cross_brief_commitments:
- brief: 4
description: |
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`)
```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.