# CLAUDE.md — WCTV tooling

Context for working on this repo. Read `plan.md` for the full roadmap.

## What this is
Flutter + Firebase tooling for **Windy City Throwdown Five**, a 2-day dance
battle with **3 battles** (categories). Handles CSV registrant ingestion,
event configuration, prelims (randomized order + private judge scoring),
bracket seeding/management, and public live-display views.

## Architecture rules
- **`lib/src/models/` and `lib/src/services/` must stay pure Dart** — no
  `flutter`, no `firebase` imports. This keeps domain logic unit-testable and
  portable into the other Flutter project later. Firebase/Flutter live in
  `state/`, `features/`, and entrypoints only.
- State management is **Riverpod**. Data access goes through repository
  interfaces in `src/state/` so we can swap the in-memory implementation for
  Firestore without touching features.
- Feature-first folders under `lib/src/features/`.

## Domain model (see `lib/src/models/`)
- `Event` — the whole WCTV event; holds its `Battle`s.
- `Battle` — one competition category. Has `BattleFormat` (solo / crew),
  `crewSize`, `PrelimGrouping` (none / byStyle for Footwork Frenzy),
  `PrelimConfig`, `BracketConfig`.
- `Dancer` — a person (firstName, lastName, battleName, email, crewName,
  imageUrl). `battleName` is the alias they compete under; `displayName` falls
  back to `firstName` when it's blank.
- `Registration` — a dancer entered in a battle, optionally with a `style`
  (used by Footwork Frenzy).
- `Crew` — a team in a crew-format battle, derived from dancers' `crewName`
  via `CrewGrouping` (in `services/`). For crew battles the *crew* — not the
  individual dancer — is the unit that runs prelims and seeds the bracket.
  Don't store crews as duplicate source-of-truth; derive them from the roster.
- Configs: `PrelimConfig` (round length), `BracketConfig` (topN, default
  round length/rounds-per-battle, and a `rounds` list of `BracketRoundConfig`
  — per-stage length + rounds-per-battle for Top 32, Top 16, … down to Top 2).
  `BracketConfig.stageSizesFor`/`defaultRounds` derive the stages from topN.

Models expose `toMap()` / `fromMap()` for Firestore readiness.

## Commands
```bash
flutter pub get
flutter test        # pure-Dart unit tests (services + models)
flutter run
flutter analyze
```

## Firebase
Optional during early dev — the app boots on in-memory data if Firebase isn't
configured. Full walkthrough in **`FIREBASE_SETUP.md`**. Short version:
```bash
dart pub global activate flutterfire_cli
flutterfire configure     # regenerates lib/firebase_options.dart
```
`lib/firebase_options.dart` is a committed placeholder whose `currentPlatform`
throws until the CLI overwrites it. `main.dart` *tries* `Firebase.initializeApp`
and catches that throw, so the app runs on in-memory data until real options
exist, then persists automatically. Persistence goes through the repository seam
in `src/state/repository.dart` (`MemoryRepository` vs `FirestoreRepository`),
selected by `firebaseReadyProvider`. Notifiers write-through on every mutation
and hydrate on start. Secret files (`google-services.json`,
`GoogleService-Info.plist`) are gitignored; `firestore.rules` holds the dev
ruleset.

## Design system
Charcoal + vibrant orange, defined once in `lib/src/theme/` (`app_colors.dart`,
`app_dimensions.dart`, `app_theme.dart`). Content surfaces use the frosted
`GlassCard` over `AppBackground` (in `lib/src/widgets/`) rather than raw
`Card`s. Pull colors/spacing/radii from the theme files — don't hard-code hex
or magic numbers in features.

## Conventions
- Update `plan.md` checkboxes as phases land.
- Keep new business logic covered by tests under `test/`.
- Prefer immutable models with `copyWith`.
