# Feature 3.2 — Scan UI

## Overview
The parlay scanner interface. Users input legs via a manual form builder, submit for analysis, and see color-coded grades with full reasoning. Displays scan count for free tier users, upgrade prompts at the limit.

## Dependencies
- Feature 2.1 — Parlay Scan API (`POST /api/scan/parlay`)
- Feature 3.1 — Landing Page (shared layout, auth, design system)

## Page: /scan

### Layout
```
┌─────────────────────────────────────────────┐
│  Header: VYNDR logo + nav + scan counter │
├─────────────────────────────────────────────┤
│                                             │
│  ┌─── Leg Builder ────────────────────────┐ │
│  │  Player: [___________] (autocomplete)  │ │
│  │  Stat:   [points ▼]   Line: [26.5]    │ │
│  │  Direction: [Over ▼]  Book: [DK ▼]    │ │
│  │  [+ Add Leg]                           │ │
│  └────────────────────────────────────────┘ │
│                                             │
│  Legs: ┌──┐ ┌──┐ ┌──┐                      │
│        │L1│ │L2│ │L3│  (removable chips)    │
│        └──┘ └──┘ └──┘                      │
│                                             │
│  [🔍 Scan Parlay]                           │
│                                             │
├─────────────────────────────────────────────┤
│  Results (after scan):                      │
│                                             │
│  ┌─ Overall ──────────────────────────────┐ │
│  │  PARLAY GRADE: [B]  Confidence: 68%    │ │
│  │  Correlations: 1 flag                  │ │
│  └────────────────────────────────────────┘ │
│                                             │
│  ┌─ Leg 1 ────────────────────────────────┐ │
│  │  Jokic Over 26.5 pts  [A] 85%         │ │
│  │  Season: 26.3 | Last 10: 28.1         │ │
│  │  Home: 27.8 | vs LAL: 30.5            │ │
│  │  Kill conditions: none                 │ │
│  └────────────────────────────────────────┘ │
│                                             │
│  ┌─ Leg 2 ────────────────────────────────┐ │
│  │  LeBron Over 8.5 reb  [C] 52%         │ │
│  │  ...                                   │ │
│  └────────────────────────────────────────┘ │
│                                             │
│  ┌─ Correlations ─────────────────────────┐ │
│  │  ⚠ Same game, same team: LeBron + AD  │ │
│  └────────────────────────────────────────┘ │
│                                             │
│  [📋 Save to Bet Tracker] [🔄 New Scan]    │
│                                             │
└─────────────────────────────────────────────┘
```

### Components

**ScanCounter** (header)
- Shows "3 of 5 scans used" for free tier
- Shows "Unlimited" for paid tiers
- Progress bar visual

**LegBuilder**
- Player input with autocomplete (calls GET /players/search on NBA stats service)
- Stat type dropdown: points, rebounds, assists, threes, blocks, steals, pra, turnovers
- Line: numeric input
- Direction: over/under toggle
- Book: DraftKings, FanDuel, BetMGM dropdown
- "Add Leg" button → adds to legs list (2-12 legs)

**LegChip**
- Compact display: "Jokic O26.5 pts DK"
- Remove button (X)
- Reorderable (nice-to-have)

**ScanButton**
- Disabled until 2+ legs added
- Loading state during API call
- Calls `POST /api/scan/parlay` with auth token

**ResultsPanel**
- Overall parlay grade card (large, color-coded)
- Individual leg cards with grade, confidence, edge, reasoning summary
- Correlation flags section with icons
- Kill conditions listed per leg

**UpgradePitch** (modal or inline)
- Appears at scan 5 (from API response `upgrade_pitch`)
- Shows personalized hook, insight, CTA
- "Subscribe" button → Stripe checkout
- "Maybe Later" dismisses

**GradeCard** (shared component from 3.1)
- Letter grade (A/B/C/D) with background color
- Confidence percentage
- Edge percentage

### State Management
```
scanState = {
  legs: [],           // array of leg objects
  isScanning: false,  // loading state
  results: null,      // API response
  error: null,        // error message
  scanCount: 0,       // from user profile
  scansRemaining: 5,  // computed
  upgradePitch: null,  // from API when applicable
}
```

### API Integration
```
1. Player search: GET http://localhost:8000/players/search?name=...
   → Autocomplete results (debounced, 300ms)

2. Scan: POST /api/scan/parlay
   Headers: { Authorization: Bearer <jwt> }
   Body: { legs: [...] }
   → Full parlay analysis response

3. Save to tracker: POST /api/bets/quickslip
   → Creates bet from scan results
```

## Acceptance Criteria
1. Leg builder allows adding 2-12 legs with all required fields
2. Player autocomplete searches as user types (debounced)
3. Scan button calls API and displays results with grades
4. Grade cards show correct colors (A=green, B=yellow, C=orange, D=red)
5. Correlation flags displayed with appropriate severity icons
6. Kill conditions listed per leg
7. Scan counter shows remaining scans for free tier
8. Upgrade pitch modal appears at scan 5 with personalized content
9. "Save to Bet Tracker" creates a bet via quickslip API
10. Error states handled: API down, invalid input, auth expired
11. Responsive: works on mobile and desktop
12. Loading states during API calls

## Test Plan
- Component tests: LegBuilder adds/removes legs correctly
- Component tests: GradeCard renders correct color per grade
- Integration: full scan flow → results displayed
- Upgrade pitch: appears at correct scan count
- Error handling: API error → user-friendly message
- Responsive: mobile leg builder usable
