wrongmove/docs/plans/2026-02-21-mobile-responsive-design.md
Viktor Barzin a744b33578
feat: make frontend fully responsive with mobile-first layout
Add mobile-responsive design with full feature parity:
- Bottom sheet (vaul) with 3 snap points for map+list coexistence
- Swipeable property cards with horizontal scroll-snap
- Hamburger menu with health, tasks, user info
- Full-screen map with repositioned legend (top-left on mobile)
- Filter FAB opening Sheet drawer
- TaskProgressDrawer from bottom on mobile
- All changes gated behind useIsMobile() hook (768px breakpoint)
- Desktop layout completely untouched

New components: MobileBottomSheet, SwipeableCardRow,
PropertyCardCompact, MobileMenu

Also fixes: idempotent longitude migration, React hooks order
2026-02-21 11:34:53 +00:00

123 lines
4.4 KiB
Markdown

# Mobile Responsive Design
## Goal
Make the realestate-crawler frontend fully responsive with complete feature parity on mobile devices. All desktop functionality must be preserved, adapted to mobile-friendly interaction patterns.
## Current State
The frontend (React 19, TypeScript, Vite, Tailwind CSS, Radix UI, Mapbox GL) has partial mobile support:
- `useIsMobile()` hook with 768px breakpoint
- Filter panel converts to FAB + Sheet on mobile
- Scattered `md:hidden` / `hidden md:block` patterns
Missing: bottom sheet for map+list coexistence, swipeable property cards, compact header, touch-optimized interactions, mobile task progress.
## Design Decisions
| Decision | Choice | Rationale |
|----------|--------|-----------|
| Map + list coexistence | Bottom sheet over full-screen map | Natural pattern for geo apps (Google Maps, Zillow) |
| Property browsing | Horizontal swipeable cards | Quick scanning with map context preserved |
| Heavy features (filters, POI, tasks) | Sheet drawers | Already partly implemented; consistent UX |
| Bottom sheet library | `vaul` | Lightweight (~4KB), snap points, gesture handling, Radix-compatible |
| Card swiping | CSS scroll-snap | Native, no extra dependency, smooth performance |
| Desktop impact | None | All changes gated behind `useIsMobile()` |
## Layout Architecture
### Mobile (< 768px)
```
+----------------------------+
| HEADER (compact, h-12) |
| Logo | hamburger |
+----------------------------+
| |
| |
| FULL-SCREEN MAP |
| |
| |
| |
+----------------------------+ <- draggable handle
| Bottom Sheet |
| Stats bar (compact) |
| +----+ +----+ +----+ | <- swipeable cards
| |Card|>|Card|>|Card| |
| +----+ +----+ +----+ |
| |
| (drag up to expand to |
| full list view) |
+----------------------------+
FAB buttons (bottom-right, above sheet):
Filter icon - opens filter Sheet
POI icon - opens POI manager Sheet
```
### Bottom Sheet Snap Points
- `80px` - collapsed: drag handle + listing count
- `35%` - peek (default): stats + swipeable property cards
- `85%` - expanded: full scrollable list with sort controls
### Desktop (>= 768px)
No changes. Existing layout preserved exactly.
## Component Changes
### New Components
| Component | Purpose |
|-----------|---------|
| `MobileBottomSheet` | vaul-based drawer with 3 snap points, contains stats + cards + list |
| `SwipeableCardRow` | Horizontal scroll-snap container of compact property cards, syncs with map |
| `PropertyCardCompact` | ~280px wide card for swipe browsing (thumbnail, price, beds, sqm) |
| `MobileMenu` | Hamburger menu Sheet with health, tasks, user info |
### Modified Components
| Component | Changes |
|-----------|---------|
| `App.tsx` | Conditional layout: mobile renders full-screen map + MobileBottomSheet + FABs |
| `Header.tsx` | Hamburger menu on mobile, hide inline items |
| `StatsBar.tsx` | Render inside bottom sheet header on mobile |
| `Map.tsx` | Full-screen on mobile, legend to top-left, bidirectional sync with cards |
| `ListView.tsx` | Render inside expanded bottom sheet on mobile |
| `TaskProgressDrawer.tsx` | Bottom Sheet on mobile instead of right-side drawer |
| `FilterPanel.tsx` | Touch-friendly sizing, no structural changes |
| `POIManager.tsx` | Touch-friendly sizing when in Sheet |
### Unchanged
- Backend, API, services, auth
- Core logic, data flow, state management
- Desktop layout
## Map-Card Synchronization
- Swipe to a card -> map pans/highlights that listing's marker
- Tap a map marker -> cards scroll to that listing
- Maintains spatial context during browsing
## Navigation & Touch
- Header: logo + hamburger on mobile. Hamburger opens Sheet with health, tasks, user info
- Two FABs stacked bottom-right (filter, POI). Auto-hide when sheet is fully expanded
- All tap targets minimum 44x44px
- No hover-dependent interactions on mobile (tooltips become tap-to-show)
- Map popup close buttons enlarged
- Gesture isolation: horizontal card swipe, vertical sheet drag, and map pan don't conflict
## New Dependencies
- `vaul` (~4KB gzipped) - bottom sheet drawer with snap points and gestures
## Scope Boundaries
- No new backend work
- No new API endpoints
- No changes to authentication flow
- No changes to data models
- Purely frontend layout and interaction changes