docs: revamp AGENTS.md — canonical AI agent reference, purge obsolete TabataFit docs
All checks were successful
PR → Build → WiFi/USB Deploy → LGTM / Build & Deploy to iPhone (WiFi/USB) (pull_request) Successful in 6m52s
PR → Build → WiFi/USB Deploy → LGTM / Wait for LGTM comment (pull_request) Successful in 1m3s

This commit is contained in:
2026-07-03 12:16:53 +00:00
parent 7d9a89e637
commit 741376229d
10 changed files with 403 additions and 1572 deletions

View File

@@ -1,643 +0,0 @@
# Maestro E2E Testing Strategy for TabataFit
## Executive Summary
**Maestro** is a mobile UI testing framework that uses YAML-based test flows. It's ideal for TabataFit because:
- ✅ Declarative YAML syntax (no code required)
- ✅ Built-in support for React Native
- ✅ Handles animations and async operations gracefully
- ✅ Excellent for regression testing critical user flows
- ✅ Can run on physical devices and simulators
---
## Prerequisites
Before implementing these tests, ensure the following features are complete:
### Required Features (Implement First)
- [ ] Onboarding flow (5 screens + paywall)
- [ ] Workout player with timer controls
- [ ] Browse/Workouts tab with workout cards
- [ ] Category filtering (Full Body, Core, Cardio, etc.)
- [ ] Collections feature
- [ ] Trainer profiles
- [ ] Subscription/paywall integration
- [ ] Workout completion screen
- [ ] Profile/settings screen
### Nice to Have (Can Add Later)
- [ ] Activity history tracking
- [ ] Offline mode support
- [ ] Deep linking
- [ ] Push notifications
---
## Priority Test Flows
### **P0 - Critical Flows (Must Test Every Release)**
1. **Onboarding → First Workout**
2. **Browse → Select Workout → Play → Complete**
3. **Subscription Purchase Flow**
4. **Background/Foreground During Workout**
### **P1 - High Priority**
5. **Category Filtering**
6. **Collection Navigation**
7. **Trainer Workout Discovery**
8. **Profile Settings & Data Persistence**
### **P2 - Medium Priority**
9. **Activity History Tracking**
10. **Offline Mode Behavior**
11. **Deep Linking**
12. **Push Notifications**
---
## Test Suite Structure
```
.maestro/
├── config.yaml # Global test configuration
├── flows/
│ ├── critical/ # P0 flows - Run on every PR
│ │ ├── onboarding.yaml
│ │ ├── workoutComplete.yaml
│ │ └── subscription.yaml
│ ├── core/ # P1 flows - Run before release
│ │ ├── browseAndPlay.yaml
│ │ ├── categoryFilter.yaml
│ │ ├── collections.yaml
│ │ └── trainers.yaml
│ └── regression/ # P2 flows - Run nightly
│ ├── activityHistory.yaml
│ ├── offlineMode.yaml
│ └── settings.yaml
├── helpers/
│ ├── common.yaml # Shared test steps
│ ├── assertions.yaml # Custom assertions
│ └── mock-data.yaml # Test data
└── environments/
├── staging.yaml
└── production.yaml
```
---
## Installation & Setup
### 1. Install Maestro CLI
```bash
# macOS/Linux
curl -Ls "https://get.maestro.mobile.dev" | bash
# Verify installation
maestro --version
```
### 2. Setup Test Directory Structure
```bash
mkdir -p .maestro/flows/{critical,core,regression}
mkdir -p .maestro/helpers
mkdir -p .maestro/environments
```
### 3. Maestro Configuration (`config.yaml`)
```yaml
# .maestro/config.yaml
appId: com.tabatafit.app
name: TabataFit E2E Tests
# Timeouts
timeout: 30000 # 30 seconds default
retries: 2
# Environment variables
env:
TEST_USER_NAME: "Test User"
TEST_USER_EMAIL: "test@example.com"
# Include flows
include:
- flows/critical/*.yaml
- flows/core/*.yaml
# Exclude on CI
exclude:
- flows/regression/offlineMode.yaml # Requires airplane mode
```
---
## P0 Critical Test Flows
### Test 1: Complete Onboarding Flow
**File:** `.maestro/flows/critical/onboarding.yaml`
```yaml
appId: com.tabatafit.app
name: Complete Onboarding & First Workout
onFlowStart:
- clearState
steps:
# Splash/Loading
- waitForAnimationToEnd:
timeout: 5000
# Screen 1: Problem - "Not Enough Time"
- assertVisible: "Not enough time"
- tapOn: "Continue"
# Screen 2: Empathy
- assertVisible: "We get it"
- tapOn: "Continue"
# Screen 3: Solution
- assertVisible: "4-minute workouts"
- tapOn: "Continue"
# Screen 4: Wow Moment
- assertVisible: "Transform your body"
- tapOn: "Get Started"
# Screen 5: Personalization
- tapOn: "Name input"
- inputText: "Test User"
- tapOn: "Beginner"
- tapOn: "Lose Weight"
- tapOn: "3 times per week"
- tapOn: "Start My Journey"
# Screen 6: Paywall (or skip in test env)
- runScript: |
if (maestro.env.SKIP_PAYWALL === 'true') {
maestro.tapOn('Maybe Later');
}
# Should land on Home
- assertVisible: "Good morning|Good afternoon|Good evening"
- assertVisible: "Test User"
onFlowComplete:
- takeScreenshot: "onboarding-complete"
```
### Test 2: Browse, Select, and Complete Workout
**File:** `.maestro/flows/critical/workoutComplete.yaml`
```yaml
appId: com.tabatafit.app
name: Browse, Play & Complete Workout
steps:
# Navigate to Workouts tab
- tapOn: "Workouts"
- waitForAnimationToEnd
# Wait for data to load
- assertVisible: "All|Full Body|Core|Upper Body"
# Select first workout
- tapOn:
id: "workout-card-0"
optional: false
# Workout Detail Screen
- assertVisible: "Start Workout"
- tapOn: "Start Workout"
# Player Screen
- waitForAnimationToEnd:
timeout: 3000
# Verify timer is running
- assertVisible: "Get Ready|WORK|REST"
# Fast-forward through workout (simulation)
- repeat:
times: 3
commands:
- waitForAnimationToEnd:
timeout: 5000
- assertVisible: "WORK|REST"
# Complete workout
- tapOn:
id: "done-button"
optional: true
# Complete Screen
- assertVisible: "Workout Complete|Great Job"
- assertVisible: "Calories"
- assertVisible: "Duration"
# Return to home
- tapOn: "Done|Continue"
- assertVisible: "Home|Workouts"
onFlowComplete:
- takeScreenshot: "workout-completed"
```
### Test 3: Subscription Purchase Flow
**File:** `.maestro/flows/critical/subscription.yaml`
```yaml
appId: com.tabatafit.app
name: Subscription Purchase Flow
steps:
# Trigger paywall (via profile or workout limit)
- tapOn: "Profile"
- tapOn: "Upgrade to Premium"
# Paywall Screen
- assertVisible: "Unlock Everything|Premium"
- assertVisible: "yearly|monthly"
# Select plan
- tapOn:
id: "yearly-plan"
# Verify Apple Pay/Google Pay sheet appears
- assertVisible: "Subscribe|Confirm"
# Note: Actual purchase is mocked in test env
- runScript: |
if (maestro.env.USE_MOCK_PURCHASE === 'true') {
maestro.tapOn('Mock Purchase Success');
}
# Verify premium activated
- assertVisible: "Premium Active|You're all set"
tags:
- purchase
- revenue-critical
```
---
## P1 Core Test Flows
### Test 4: Category Filtering
**File:** `.maestro/flows/core/categoryFilter.yaml`
```yaml
appId: com.tabatafit.app
name: Category Filtering
steps:
- tapOn: "Workouts"
- waitForAnimationToEnd
# Test each category
- tapOn: "Full Body"
- assertVisible: "Full Body"
- tapOn: "Core"
- assertVisible: "Core"
- tapOn: "Cardio"
- assertVisible: "Cardio"
- tapOn: "All"
- assertVisible: "All Workouts"
# Verify filter changes content
- runScript: |
const before = maestro.getElementText('workout-count');
maestro.tapOn('Core');
const after = maestro.getElementText('workout-count');
assert(before !== after, 'Filter should change workout count');
```
### Test 5: Collection Navigation
**File:** `.maestro/flows/core/collections.yaml`
```yaml
appId: com.tabatafit.app
name: Collection Navigation
steps:
- tapOn: "Browse"
- waitForAnimationToEnd
# Scroll to collections
- swipe:
direction: UP
duration: 1000
# Tap first collection
- tapOn:
id: "collection-card-0"
# Collection Detail Screen
- assertVisible: "Collection"
- assertVisible: "workouts"
# Start collection workout
- tapOn: "Start"
- assertVisible: "Player|Timer"
onFlowComplete:
- takeScreenshot: "collection-navigation"
```
### Test 6: Trainer Discovery
**File:** `.maestro/flows/core/trainers.yaml`
```yaml
appId: com.tabatafit.app
name: Trainer Discovery
steps:
- tapOn: "Browse"
# Navigate to trainers section
- swipe:
direction: UP
# Select trainer
- tapOn:
id: "trainer-card-0"
# Verify trainer profile
- assertVisible: "workouts"
# Select trainer's workout
- tapOn:
id: "workout-card-0"
# Should show workout detail
- assertVisible: "Start Workout"
```
---
## Reusable Test Helpers
### Common Actions (`helpers/common.yaml`)
```yaml
# .maestro/helpers/common.yaml
appId: com.tabatafit.app
# Launch app fresh
- launchApp:
clearState: true
# Wait for data loading
- waitForDataLoad:
commands:
- waitForAnimationToEnd:
timeout: 3000
- assertVisible: ".*" # Any content loaded
# Handle permission dialogs
- handlePermissions:
commands:
- tapOn:
text: "Allow"
optional: true
- tapOn:
text: "OK"
optional: true
# Navigate to tab
- navigateToTab:
params:
tabName: ${tab}
commands:
- tapOn: ${tab}
# Start workout from detail
- startWorkout:
commands:
- tapOn: "Start Workout"
- waitForAnimationToEnd:
timeout: 5000
- assertVisible: "Get Ready|WORK"
```
---
## Running Tests
### Local Development
```bash
# Install Maestro
curl -Ls "https://get.maestro.mobile.dev" | bash
# Run single test
maestro test .maestro/flows/critical/onboarding.yaml
# Run all critical tests
maestro test .maestro/flows/critical/
# Run with specific environment
maestro test --env SKIP_PAYWALL=true .maestro/flows/
# Record video of test
maestro record .maestro/flows/critical/workoutComplete.yaml
# Run with tags
maestro test --include-tags=critical .maestro/flows/
```
### CI/CD Integration (GitHub Actions)
```yaml
# .github/workflows/maestro.yml
name: Maestro E2E Tests
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
e2e-tests:
runs-on: macos-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node
uses: actions/setup-node@v3
- name: Install Maestro
run: curl -Ls "https://get.maestro.mobile.dev" | bash
- name: Start iOS Simulator
run: |
xcrun simctl boot "iPhone 15"
sleep 10
- name: Install App
run: |
npm install
npx expo prebuild
npx pod install
npx react-native run-ios --simulator="iPhone 15"
- name: Run Critical Tests
run: |
export MAESTRO_DRIVER_STARTUP_TIMEOUT=120000
maestro test .maestro/flows/critical/
- name: Upload Test Results
if: always()
uses: actions/upload-artifact@v3
with:
name: maestro-results
path: |
~/.maestro/tests/
*.png
```
---
## Test Coverage Matrix
| Feature | Test File | Priority | Frequency | Status |
|---------|-----------|----------|-----------|--------|
| Onboarding | `onboarding.yaml` | P0 | Every PR | ⏳ Pending |
| Workout Play | `workoutComplete.yaml` | P0 | Every PR | ⏳ Pending |
| Purchase | `subscription.yaml` | P0 | Every PR | ⏳ Pending |
| Category Filter | `categoryFilter.yaml` | P1 | Pre-release | ⏳ Pending |
| Collections | `collections.yaml` | P1 | Pre-release | ⏳ Pending |
| Trainers | `trainers.yaml` | P1 | Pre-release | ⏳ Pending |
| Activity | `activityHistory.yaml` | P2 | Nightly | ⏳ Pending |
| Offline | `offlineMode.yaml` | P2 | Weekly | ⏳ Pending |
---
## React Native Prerequisites
Before running tests, add `testID` props to components for reliable selectors:
```tsx
// WorkoutCard.tsx
<Pressable testID={`workout-card-${index}`}>
{/* ... */}
</Pressable>
// WorkoutPlayer.tsx
<Button testID="done-button" title="Done" />
// Paywall.tsx
<Pressable testID="yearly-plan">
{/* ... */}
</Pressable>
```
### Required testIDs Checklist
- [ ] `workout-card-{index}` - Workout list items
- [ ] `collection-card-{index}` - Collection items
- [ ] `trainer-card-{index}` - Trainer items
- [ ] `done-button` - Complete workout button
- [ ] `yearly-plan` / `monthly-plan` - Subscription plans
- [ ] `start-workout-button` - Start workout CTA
- [ ] `category-{name}` - Category filter buttons
- [ ] `tab-{name}` - Bottom navigation tabs
---
## Environment Variables
Create `.env.maestro` file:
```bash
# Test Configuration
SKIP_PAYWALL=true
USE_MOCK_PURCHASE=true
TEST_USER_NAME=Test User
TEST_USER_EMAIL=test@example.com
# API Configuration (if needed)
API_BASE_URL=https://api-staging.tabatafit.com
```
---
## Troubleshooting
### Common Issues
1. **Tests fail on first run**
- Clear app state: `maestro test --clear-state`
- Increase timeout in config.yaml
2. **Element not found**
- Verify testID is set correctly
- Add wait times before assertions
- Check for animations completing
3. **Purchase tests fail**
- Ensure `USE_MOCK_PURCHASE=true` in test env
- Use sandbox/test products
4. **Slow tests**
- Use `waitForAnimationToEnd` with shorter timeouts
- Disable animations in test builds
### Debug Commands
```bash
# Interactive mode
maestro studio
# View hierarchy
maestro hierarchy
# Record test execution
maestro record <test-file>
# Verbose logging
maestro test --verbose <test-file>
```
---
## Next Steps (After Features Are Complete)
1. ✅ Create `.maestro/` directory structure
2. ✅ Write `config.yaml`
3. ✅ Implement P0 critical test flows
4. ✅ Add testIDs to React Native components
5. ✅ Run tests locally
6. ✅ Setup CI/CD pipeline
7. ⏳ Implement P1 core test flows
8. ⏳ Add visual regression tests
9. ⏳ Setup nightly regression suite
---
## Resources
- [Maestro Documentation](https://maestro.mobile.dev/)
- [Maestro YAML Reference](https://maestro.mobile.dev/api-reference/commands)
- [React Native Testing with Maestro](https://maestro.mobile.dev/platform-support/react-native)
- [Maestro Best Practices](https://maestro.mobile.dev/advanced/best-practices)
---
**Created:** March 17, 2026
**Status:** Implementation Pending (Waiting for feature completion)

View File

@@ -1,486 +0,0 @@
# TabataFit — UI Feature Brief
> Generated for Google Stitch design handoff.
> Covers all end-user screens, interactions, states, and navigation flows.
---
## App Overview
**TabataFit** is a mobile fitness app ("Apple Fitness+ for Tabata") built with React Native / Expo. It delivers guided Tabata HIIT workouts with video, voice coaching, music, and Apple Watch heart-rate sync.
### Design System
| Token | Value | Usage |
|-------|-------|-------|
| Background | `#000000` | Pure black base |
| Surface | `#1C1C1E` | Cards, sheets |
| Brand | `#FF6B35` | Flame orange — primary accent |
| Rest | `#5AC8FA` | Ice blue — rest phases |
| Success | `#30D158` | Energy green — completion |
| Prep phase | `#FF9500` | Orange-yellow |
| Work phase | `#FF6B35` | Flame orange |
| Rest phase | `#5AC8FA` | Ice blue |
| Complete phase | `#30D158` | Green |
- Supports **dark and light mode**
- Multi-language (i18n)
- Haptic feedback throughout
---
## Navigation Structure
```
Root Stack
├── Onboarding (6-step flow)
├── (tabs)
│ ├── Home — index
│ ├── Explore — browse workouts
│ ├── Activity — stats & history
│ └── Profile — settings & account
├── workout/[id] — Workout detail (push)
├── program/[id] — Program detail (push)
├── collection/[id] — Collection detail (push)
├── player/[id] — Workout player (push, full-screen)
├── complete/[id] — Post-workout celebration (push)
├── paywall — Premium upsell (modal)
├── explore-filters — Filter sheet (form sheet modal)
└── privacy — Privacy policy (push)
```
**Tab bar**: 4 tabs — Home, Explore, Activity, Profile. SF Symbol icons. Badge support.
---
## 1. Onboarding Flow
A 6-screen linear funnel shown on first launch. Progress dots at top. Skip available on some steps.
### 1.1 Problem Screen
- **Purpose**: Motivational hook about time constraints
- **Elements**: Headline text, subtitle, illustration
- **CTA**: Continue
### 1.2 Empathy Screen
- **Purpose**: User selects fitness barriers to build rapport
- **Elements**: Grid of 4 selectable cards — "No time", "Low motivation", "No knowledge", "No gym"
- **Interaction**: Tap to select, max 2 selections, visual highlight on selected
- **CTA**: Continue (enabled after 1+ selection)
### 1.3 Solution Screen
- **Purpose**: Show Tabata's effectiveness
- **Elements**: Animated comparison bar chart (Tabata vs traditional cardio calorie burn)
- **CTA**: Continue
### 1.4 Wow Screen
- **Purpose**: Reveal key app features
- **Elements**: 4 feature cards with staggered entrance animations — Timer, Exercises, Voice Coaching, Progress Tracking
- **CTA**: Continue
### 1.5 Personalization Screen
- **Purpose**: Collect user preferences to personalize experience
- **Inputs**:
- Name (text input)
- Fitness level: Beginner / Intermediate / Advanced (single select chips)
- Goal: Weight Loss / Cardio / Strength / Wellness (single select chips)
- Weekly frequency: 2x / 3x / 5x per week (single select chips)
- **CTA**: Continue (enabled when all fields filled)
### 1.6 Paywall Screen (Onboarding variant)
- **Purpose**: Premium conversion at end of onboarding
- **Elements**: Premium features list, yearly/monthly plan toggle with real prices from RevenueCat
- **CTAs**: Subscribe, Restore Purchases, Skip (close button)
- **States**: Loading prices, purchase in progress, error
---
## 2. Home Tab
Personalized dashboard and primary entry point.
### Elements
- **Greeting header**: Time-based ("Good morning/afternoon/evening") + user's name + animated mascot
- **Streak badge**: Current streak count with flame icon
- **Quick stats row**: 3 stat pills — Current streak, This week (workouts), Total minutes
- **Assessment card**: Feature-flagged (currently OFF) — fitness assessment prompt
- **Program cards**: 3 horizontal cards (Upper Body, Lower Body, Full Body)
- Each shows: icon, title, progress bar (% complete), status badge (Not Started / In Progress / Completed)
- CTA per card: Start / Continue / Restart (depends on state)
- **Switch program button**: Opens program selection
### Navigation
- Tap program card → `program/[id]`
- Tap "Start" on program → `player/[id]` (first workout)
- Tap "Continue" → `player/[id]` (next incomplete workout)
### States
- **New user**: 0 stats, no streak, programs at 0%
- **Returning user**: Populated stats, active streak, program progress
---
## 3. Explore Tab
Browse, search, and filter the full workout catalog.
### Elements
- **Search bar**: Search by workout title, trainer name, exercise name, category. Real-time filtering.
- **Featured collection**: Hero card at top with image, title, workout count. Tap → `collection/[id]`
- **Trainer avatars**: Horizontal scroll of circular trainer photos. Tap to filter workouts by trainer.
- **Collections carousel**: Horizontal scroll of collection cards. Tap → `collection/[id]`
- **Recommended For You**: Horizontal workout card list, personalized based on workout history
- **Featured workouts**: Grid of highlighted workouts
- **All Workouts section**:
- Category filter pills: All, Full Body, Upper Body, Lower Body, Core, Cardio
- Filter button → opens `explore-filters` sheet
- Active filter indicator + clear filters button
- 2-column workout card grid
### Workout Card
- Thumbnail image
- Duration badge overlay
- Title, trainer name, level indicator
- Lock icon if premium-only and user is free tier
### Navigation
- Tap workout card → `workout/[id]`
- Tap collection → `collection/[id]`
- Tap trainer avatar → filters workout list by that trainer
- Tap filter button → `explore-filters` (form sheet modal)
### States
- **Loading**: Skeleton placeholders for cards
- **Error**: Error message with Retry button
- **Empty search**: "No workouts found" message
- **Filtered**: Active filter chips shown, clear all button
---
## 4. Activity Tab
Workout history, statistics, and achievements.
### Elements
- **Streak banner**: Current streak + longest streak (flame icons)
- **Stats grid** (2x2): Each stat in a card with circular progress ring
- Total workouts (ring fills toward goal)
- Total minutes
- Total calories
- Best streak
- **Weekly bar chart**: SunSat, each bar filled if a workout was completed that day, current day highlighted
- **Recent workouts list**: Last 5 workouts
- Each row: workout title, relative time ("2h ago"), duration, calories
- Tap → `workout/[id]`
- **Achievements grid**: 4 achievement badges displayed
- Types: workouts milestone, streak milestone, minutes milestone, calories milestone
- States: locked (greyed out) / unlocked (colored with checkmark)
### States
- **Empty**: No workouts yet — motivational message + "Start Your First Workout" CTA → `explore`
- **Populated**: All sections visible with data
---
## 5. Profile Tab
User settings, account management, and app info.
### Elements
- **User header**: Avatar circle with initial, display name, plan label ("Free" or "TabataFit+")
- **Stats row**: 3 inline stats — workouts count, streak, calories
- **Upgrade CTA** (free users only): Gradient button → `paywall`
#### Workout Settings Section
- Haptic feedback toggle
- Sound effects toggle
- Voice coaching toggle
#### Notifications Section
- Daily reminders toggle
- Reminder time display (when enabled)
#### Personalization Section (premium only)
- Sync status indicator
#### About Section
- Version number
- Rate App → opens App Store rating prompt
- Contact Us → opens email compose
- FAQ → opens external web link
- Privacy Policy → `privacy` screen
#### Account Section (premium only)
- Restore Purchases → triggers RevenueCat restore
#### Danger Zone
- Sign Out button
- Data deletion: triggers confirmation modal
### Data Deletion Modal
- Warning text explaining data loss
- Cancel / Delete buttons
- Delete is destructive (red)
---
## 6. Workout Detail Screen
Pre-workout information screen. Reached by tapping any workout card.
**Route**: `workout/[id]`
### Elements
- **Header**: Thumbnail or video preview, back button, heart/save button (toggle)
- **Title**: Workout name
- **Trainer**: Trainer name (colored text)
- **Metadata row**: Duration (minutes), Calories estimate, Level badge (Beginner/Intermediate/Advanced)
- **Equipment list**: Icons + labels for required equipment (or "No equipment")
- **Timing card**: Prep time, Work time, Rest time, Rounds — displayed in a structured card
- **Exercise list**: Ordered list of exercises with individual durations
- **Repeat rounds indicator**: Shows if rounds repeat the exercise sequence
- **Music vibe label**: Genre/mood of the workout soundtrack
### CTAs
- **Start Workout** → `player/[id]` (if unlocked or user is premium)
- **Unlock with TabataFit+** → `paywall` (if locked and user is free tier)
### Header Actions
- **Back**: Navigate back
- **Save/Unsave**: Heart icon toggle — saves workout to favorites
### States
- **Loading**: Skeleton layout
- **Unlocked**: Full detail visible, "Start Workout" CTA
- **Locked**: Full detail visible but "Unlock with TabataFit+" CTA replaces start button
---
## 7. Program Detail Screen
Multi-week training program overview with per-week workout breakdown.
**Route**: `program/[id]`
### Elements
- **Header**: Program icon, title, subtitle (e.g., "4 weeks · 12 workouts")
- **Description**: Program summary text
- **Stats card**: 3 stats — Weeks, Workouts, Total Minutes
- **Tags**: Equipment required (e.g., Dumbbells, Mat) + Equipment optional + Focus areas (e.g., Arms, Core)
- **Progress bar** (if started): Percentage complete with label
- **Training plan**: Expandable week sections
- Each week shows its workouts in order
- Workout rows show: title, duration, completion checkmark (if done)
- Current week has a "Current" badge
- Future weeks may show lock icons (progressive unlock)
### CTAs
- **Start Program** (not started) → `player/[id]` (first workout)
- **Continue Training** (in progress) → `player/[id]` (next incomplete workout)
- **Restart** (completed) → resets progress, starts from week 1
### States
- **Not Started**: 0% progress, all weeks shown, "Start Program" CTA
- **In Progress**: Progress bar filled, completed workouts checked, "Continue Training" CTA
- **Completed**: 100% progress, all checked, "Restart" CTA
---
## 8. Collection Detail Screen
A curated group of workouts.
**Route**: `collection/[id]`
### Elements
- **Header**: Collection title, description, workout count
- **Workout list**: Vertical list of workout cards in the collection
- Each card: thumbnail, title, trainer, duration, level
- Lock icon for premium-gated workouts
### Navigation
- Tap workout → `workout/[id]`
- Back button → previous screen
---
## 9. Player Screen
Full-screen workout execution with timer, video, audio, and Watch sync.
**Route**: `player/[id]`
### Layout
- **Full-screen dark mode** — no tab bar, no status bar chrome
- **Background**: Workout video (HLS streaming) or gradient fallback
- **Phase-colored tint**: Background overlay changes color per phase (prep=orange, work=flame, rest=blue, complete=green)
### Timer Section
- **Timer ring**: Large circular progress indicator, fills as phase progresses
- **Phase label**: PREP / WORK / REST / COMPLETE (color-coded)
- **Countdown**: Large MM:SS timer (uses tabular-nums for alignment)
- **Round indicator**: "Round 3 of 8" text
### Exercise Info
- **Current exercise name**: Large text
- **Next exercise preview**: Smaller text ("Up next: Burpees")
- **Coach encouragement**: Motivational text overlays (e.g., "Keep going!", "Almost there!")
### Controls
- **Start**: Begins the workout (shown before first start)
- **Pause / Resume**: Toggle button during workout
- **Stop**: Ends workout early (confirmation prompt)
- **Skip**: Skip to next phase
### Stats Overlay
- **Calories**: Running calorie count
- **Heart rate**: BPM from Apple Watch (if connected)
- **Rounds**: Current / total
### Burn Bar
- Horizontal bar comparing user's current calorie burn vs. average for this workout
- Updates in real-time
### Now Playing Pill
- Shows current music track name
- Skip track button
### Audio & Haptics
- **Sound effects**: Phase start chime, 3-2-1 countdown beeps, workout complete fanfare
- **Haptic feedback**: Phase transitions, countdown ticks, button presses
- **Voice coaching**: Audio cues for exercises and encouragement
- **Screen stays awake** (useKeepAwake)
### Apple Watch Integration
- Sends: workout state (phase, timer, exercise)
- Receives: play/pause, skip, stop commands, heart rate data
### Completion State
- Timer ring shows 100%
- Phase label: COMPLETE
- Summary: Rounds completed, calories burned, total minutes
- **Done** CTA → `complete/[id]`
### States
- **Ready**: Before starting — shows workout info, Start CTA
- **Active**: Timer running, video playing, stats updating
- **Paused**: Timer frozen, controls show Resume
- **Complete**: Summary shown, Done CTA
---
## 10. Workout Complete Screen
Post-workout celebration and next steps.
**Route**: `complete/[id]`
### Elements
- **Celebration animation**: Concentric emoji rings spinning (fire, muscle, lightning emojis)
- **Stats grid**: 3 stats — Calories, Minutes, 100% completion
- **Burn bar result**: Percentile comparison ("You burned more than 73% of users")
- **Streak display**: Current streak count + subtitle ("Keep it going!")
- **Share button**: Opens native share sheet with workout summary
- **Recommended next workouts**: 3 horizontal workout cards
- Tap → `workout/[id]`
- **Back to Home** CTA → navigates to Home tab
### Sync Consent Modal
- Appears after first workout for premium users
- Prompts to enable cross-device data sync
- Accept / Decline buttons
---
## 11. Paywall Screen
Premium subscription purchase flow.
**Route**: `paywall` (presented as modal)
### Elements
- **Header**: "TabataFit+" branding
- **Features grid**: 6 premium feature cards with icons
- Music during workouts
- Unlimited workouts
- Detailed stats
- Calorie tracking
- Smart reminders
- No ads
- **Plan selection**: Two radio-style options
- Yearly: Price/year + "Save 50%" badge (highlighted as best value)
- Monthly: Price/month
- Prices fetched live from RevenueCat
- **Subscribe CTA**: Gradient button, shows selected plan price
- **Restore purchases**: Text link below CTA
- **Terms**: Privacy policy + terms of service links
- **Close button**: X in top corner to dismiss
### States
- **Loading**: Skeleton while fetching prices from RevenueCat
- **Ready**: Plans displayed with real prices
- **Purchasing**: Loading spinner on CTA, inputs disabled
- **Error**: Error message with retry
- **Success**: Dismisses modal, unlocks premium features
---
## 12. Explore Filters Sheet
Filter modal for the Explore tab workout grid.
**Route**: `explore-filters` (form sheet modal with grabber)
### Elements
- **Level filter chips**: All / Beginner / Intermediate / Advanced (single select)
- **Equipment filter chips**: All / None / Dumbbells / Band / Mat (dynamic from data, single select)
- **Apply**: Dismiss sheet, filters persist in shared store
- **Clear**: Reset all filters to "All"
---
## 13. Privacy Policy Screen
Static content screen.
**Route**: `privacy`
### Elements
- Privacy policy text content
- Back navigation
---
## Cross-Cutting Features
### Premium Gating
- Free users see all workouts but some are locked (lock icon overlay)
- Tapping a locked workout's "Start" CTA redirects to `paywall`
- Premium users have full access to all workouts, stats sync, and personalization
### Internationalization (i18n)
- All user-facing strings are translated via i18n system
- Multi-language support throughout
### Haptic Feedback
- Configurable via Profile settings toggle
- Triggered on: button presses, phase changes, countdown ticks, achievements
### Analytics (PostHog)
- Events tracked across all screens: screen views, button taps, workout starts/completions, purchases, onboarding steps
### Dark / Light Mode
- Full theme support — colors adapt to system appearance
- Player screen is always dark mode regardless of system setting
### Loading & Error States
- Skeleton placeholders during data fetches
- Error states with descriptive message + Retry button
- Empty states with motivational messaging + CTAs
### Animations
- Onboarding: staggered card reveals, animated charts
- Home: mascot animation
- Player: timer ring fill, phase color transitions
- Complete: spinning emoji celebration rings
- Navigation: standard iOS push/pop + modal presentations