# 15 — Next.js Web App

## Context
Fogbreak replaces FUB, ShowingTime, Sisu, Paperless Pipeline, DocuSign, RealScout with a single platform. The existing `fogbreak.html` (2,622-line vanilla JS PWA) served as the MVP. This instruction rebuilds the frontend in Next.js 16 for SSR, SEO, performance, and white-label theming.

## What to Build

### 1. Project Setup
```bash
npx create-next-app@latest web --typescript --tailwind --app --src-dir
cd web
npm install @tanstack/react-query socket.io-client recharts lucide-react
```

### 2. Directory Structure
```
web/
├── src/
│   ├── app/
│   │   ├── layout.tsx                 # Root layout with theme provider
│   │   ├── page.tsx                   # Dashboard (home)
│   │   ├── (auth)/
│   │   │   ├── login/page.tsx
│   │   │   └── magic-link/page.tsx
│   │   ├── clients/
│   │   │   ├── page.tsx               # Client list (FUB replacement)
│   │   │   └── [id]/page.tsx          # Client detail + timeline
│   │   ├── deals/
│   │   │   ├── page.tsx               # Pipeline view
│   │   │   └── [id]/page.tsx          # Deal detail + TC tasks
│   │   ├── showings/
│   │   │   ├── page.tsx               # Showing calendar (ShowingTime)
│   │   │   ├── cart/page.tsx          # Multi-showing cart
│   │   │   └── [id]/page.tsx          # Showing detail + feedback
│   │   ├── email/
│   │   │   ├── page.tsx               # Inbox
│   │   │   └── compose/page.tsx       # Compose with AI
│   │   ├── properties/
│   │   │   ├── page.tsx               # Listings
│   │   │   └── [id]/page.tsx          # Property detail (SSR for SEO)
│   │   ├── transactions/
│   │   │   ├── page.tsx               # TC dashboard (Paperless Pipeline)
│   │   │   └── [id]/page.tsx          # Transaction detail + compliance
│   │   ├── analytics/
│   │   │   ├── page.tsx               # KPI dashboard (Sisu)
│   │   │   ├── leaderboard/page.tsx   # Leaderboards
│   │   │   ├── coaching/page.tsx      # AI coaching
│   │   │   └── tv/page.tsx            # TV display mode
│   │   ├── marketing/
│   │   │   ├── page.tsx               # Marketing hub
│   │   │   ├── social/page.tsx        # Content calendar
│   │   │   ├── staging/page.tsx       # Virtual staging
│   │   │   └── video/page.tsx         # Video generation
│   │   ├── documents/
│   │   │   ├── page.tsx               # Document management
│   │   │   └── sign/[token]/page.tsx  # eSign interface (DocuSign)
│   │   ├── calendar/page.tsx          # Calendar
│   │   ├── settings/
│   │   │   ├── page.tsx               # Settings hub
│   │   │   ├── market/page.tsx        # Market config
│   │   │   ├── brand/page.tsx         # Brand config
│   │   │   ├── integrations/page.tsx  # Connected accounts
│   │   │   └── team/page.tsx          # Team management
│   │   └── api/                       # API routes (proxy to PHP backend)
│   ├── components/
│   │   ├── ui/                        # Base components (buttons, inputs, cards)
│   │   ├── layout/                    # Shell, sidebar, header, tab bar
│   │   ├── charts/                    # Recharts wrappers
│   │   ├── ai/                        # AI chat panel, suggestions
│   │   └── shared/                    # Common patterns
│   ├── lib/
│   │   ├── api.ts                     # API client (calls PHP backend)
│   │   ├── auth.ts                    # Auth context + session management
│   │   ├── socket.ts                  # Real-time connection
│   │   └── utils.ts                   # Helpers
│   └── themes/
│       ├── theme-provider.tsx         # CSS variable injection from tenant config
│       ├── default.ts                 # Default theme
│       └── types.ts                   # Theme type definitions
├── public/
└── next.config.ts
```

### 3. White-Label Theme System
Load tenant branding from API on app init:
```typescript
// themes/theme-provider.tsx
// Fetch tenant config → inject CSS variables
// --primary, --accent, --bg, --text, --font-heading, --font-body
// Support custom domain (subdomain.fogbreak.com or brokerage.com)
// Logo URL from tenant config
```

### 4. SSR for Property Pages
Property detail pages server-rendered for SEO:
```typescript
// app/properties/[id]/page.tsx
export async function generateMetadata({ params }) {
    const property = await fetchProperty(params.id);
    return {
        title: `${property.address} | ${property.city}`,
        description: property.ai_description,
        openGraph: { images: [property.hero_image] }
    };
}
```

### 5. Real-Time Updates
Socket.io for live data:
- New showing request → dashboard updates instantly
- Deal status change → pipeline view refreshes
- New lead → notification badge
- AI response streaming
- Leaderboard updates

### 6. Mobile-First Responsive
- All pages mobile-optimized (continue the 5-breakpoint pattern)
- Bottom tab navigation on mobile
- Swipe gestures where appropriate (showing cards, property matches)
- Touch-friendly inputs

### 7. TV Display Mode
Full-screen dashboard for office displays:
- `/analytics/tv` route
- Auto-rotate between leaderboard, pipeline, KPIs
- Large fonts, high contrast
- No interaction needed (auto-refresh)
- Configurable rotation interval

### 8. AI Chat Panel
Persistent AI assistant (docked to right side or floating):
- Context-aware: knows what page you're on
- "Generate listing description for this property"
- "What should I focus on today?"
- "Draft email to this client"
- Streaming responses from self-hosted model

### 9. Migration from fogbreak.html
- Keep fogbreak.html working during transition
- Feature parity before switching
- Same API endpoints (PHP backend unchanged)
- Redirect to Next.js app once ready

## Acceptance Criteria
- [ ] Next.js 16 project with TypeScript and Tailwind
- [ ] All pages matching current 8-tab PWA functionality
- [ ] New pages for showings, analytics, marketing, TC workflows
- [ ] White-label theme system loading from tenant config
- [ ] SSR property pages for SEO
- [ ] Real-time updates via Socket.io
- [ ] Mobile-first responsive with bottom tab nav
- [ ] TV display mode for office screens
- [ ] AI chat panel integrated throughout
- [ ] Feature parity with fogbreak.html before cutover
