# Trip Planning Enhancements Design

**Date:** 2026-01-12
**Status:** Draft
**Scope:** High-level overview for scoping/prioritization

## Goal

Transform trip creation from a dense single-form into a guided, progressive-reveal flow that walks users through planning one decision at a time—while keeping everything on a single scrolling screen.

## Current State

- Single `TripCreationView` (~2500 lines) with all options visible at once
- Planning mode selector controls which sections appear
- 4 planning modes: Date Range, Game First, Locations, Follow Team
- Sports without games in date range are not indicated

## Target State

- Progressive disclosure: sections reveal as user makes selections
- Conversational headers guide the user ("Great! When would you like to travel?")
- Each section is a small, focused view component (~100-150 lines)
- Sports with no games in selected date range are grayed out
- Current form remains accessible via Settings toggle for power users

## Approach: Progressive Single-Screen Flow

### Container Architecture

```swift
struct TripWizardView: View {
    @State var viewModel = TripWizardViewModel()

    var body: some View {
        ScrollView {
            VStack(spacing: Theme.Spacing.lg) {
                // Always visible
                PlanningModeStep(selection: $viewModel.planningMode)

                // Reveals after planning mode selected
                if viewModel.planningMode != nil {
                    SportsStep(...)
                        .transition(.move(edge: .bottom).combined(with: .opacity))
                }

                // Reveals after at least one sport selected
                if !viewModel.selectedSports.isEmpty {
                    DatesStep(...)
                        .transition(.move(edge: .bottom).combined(with: .opacity))
                }

                // Continues for each step...
            }
            .animation(.easeInOut(duration: 0.3), value: viewModel.revealState)
        }
    }
}
```

### Step Sequence

| Step | Question | Reveals When |
|------|----------|--------------|
| 1 | "How do you want to plan?" | Always visible |
| 2 | "Which sports interest you?" | After planning mode selected |
| 3 | "When would you like to travel?" | After sport(s) selected |
| 4 | "Where do you want to go?" | After dates set |
| 5 | "What's your route preference?" | After region(s) selected |
| 6 | "Visit cities more than once?" | After route preference |
| 7 | "Any must-stop locations?" | After repeat cities choice |
| 8 | Review & Plan button | After all required steps complete |

Note: Step order varies by planning mode (e.g., "Game First" skips dates, shows game picker).

### Behavior

- Steps slide in from bottom with fade animation
- Auto-scroll to newly revealed section (300ms after animation starts)
- User can scroll back up and change earlier answers
- Changing an answer resets/updates downstream sections as needed
- Conversational headers: "Nice! Now pick your travel dates"

### Sport Availability (Graying)

After date selection:
1. Fetch game counts per sport for selected date range
2. Use existing `AppDataProvider.shared.filterGames(sports:startDate:endDate:)`
3. Cache results; re-fetch if dates change
4. Display: grayed card + disabled + subtitle "No games in this period"

## File Structure

```
Features/Trip/Views/Wizard/
├── TripWizardView.swift          # Container with progressive reveal logic
├── TripWizardViewModel.swift     # Shared state across all steps
├── Steps/
│   ├── PlanningModeStep.swift    # "How do you want to plan?"
│   ├── SportsStep.swift          # Sport grid with availability graying
│   ├── DatesStep.swift           # Date range picker
│   ├── RegionsStep.swift         # Region map
│   ├── RoutePreferenceStep.swift # Efficient/Scenic/Flexible
│   ├── RepeatCitiesStep.swift    # Yes/No toggle
│   ├── MustStopsStep.swift       # Optional locations
│   └── ReviewStep.swift          # Summary + Plan button
```

## Key Decisions

| Decision | Choice | Rationale |
|----------|--------|-----------|
| Keep old `TripCreationView`? | Yes | Power users, accessible via Settings toggle |
| Reset downstream on change? | Yes | Changing sports resets dates, changing dates refetches sport availability |
| Sport graying | Grayed + disabled + subtitle | Clear feedback why sport unavailable |
| Auto-scroll | 300ms delay after reveal | Let animation start before scrolling |
| Step headers | Conversational tone | Guides user, feels less like a form |

## Not Included (YAGNI)

- Progress indicator (single screen doesn't need it)
- Save draft functionality (overkill for single-session flow)
- Undo/redo beyond scrolling back up
- Swipe gestures between steps (intentional friction for decisions)

## Dependencies

- None - uses existing data providers and models
- `AppDataProvider.shared.filterGames()` for sport availability

## Testing Considerations

- Test progressive reveal with all 4 planning modes
- Test sport availability graying with various date ranges
- Test downstream reset when changing earlier selections
- Test auto-scroll behavior on different screen sizes
