feat: design system v2 with liquid glass aesthetic

Overhaul design constants for OLED-first dark mode:
- Colors: brand palette, phase colors, glass/shadow tokens, gradients
- Typography: Inter font scale matching iOS type system
- Spacing: 4px base unit with layout constants
- Border radius: liquid glass card radii
- Animations: spring/timing presets for UI transitions

Add v2 product docs (PRD, PDD, BDSD) and update CLAUDE.md.
Install expo-video, expo-sharing, @expo-google-fonts/inter.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Millian Lamiaux
2026-02-20 13:23:18 +01:00
parent 54ac8326fa
commit 511e207762
15 changed files with 2865 additions and 312 deletions

594
TabataFit_BDSD_v2.0.md Normal file
View File

@@ -0,0 +1,594 @@
# TabataFit — Brand Design Specification v2.0
> Apple Liquid Glass Design for Tabata
---
## Brand Positioning
**TabataFit = Apple Fitness+ avec Liquid Glass (iOS 18.4)**
| Attribute | Description |
|-----------|-------------|
| **Analogy** | "If Apple made a Tabata app in 2026" |
| **Vibe** | Premium, glassy, fluid, immersive |
| **Emotion** | Confident, empowering, sleek |
| **Differentiator** | Video-led + Liquid Glass UI |
---
## 🪟 Liquid Glass System (iOS 18.4 Style)
### Concept
Le **Liquid Glass** est le nouveau design language d'Apple qui combine :
- **Glassmorphism avancé** — Blur dynamique, transparence multicouche
- **Fluidité organique** — Formes arrondies, animations liquides
- **Lumière réactive** — Reflets, glows qui répondent au contenu
- **Profondeur atmosphérique** — Layers de verre empilés
### Glass Layers
```typescript
const GLASS = {
// Base glass (surfaces)
BASE: {
backgroundColor: 'rgba(255, 255, 255, 0.05)',
backdropFilter: 'blur(40px)',
borderWidth: 1,
borderColor: 'rgba(255, 255, 255, 0.1)',
shadowColor: '#000',
shadowOffset: { width: 0, height: 8 },
shadowOpacity: 0.3,
shadowRadius: 32,
},
// Elevated glass (cards, modals)
ELEVATED: {
backgroundColor: 'rgba(255, 255, 255, 0.08)',
backdropFilter: 'blur(60px)',
borderWidth: 1,
borderColor: 'rgba(255, 255, 255, 0.15)',
shadowColor: '#000',
shadowOffset: { width: 0, height: 12 },
shadowOpacity: 0.4,
shadowRadius: 48,
},
// Inset glass (input fields, controls)
INSET: {
backgroundColor: 'rgba(0, 0, 0, 0.2)',
backdropFilter: 'blur(20px)',
borderWidth: 1,
borderColor: 'rgba(255, 255, 255, 0.05)',
},
// Tinted glass (accent overlays)
TINTED: {
backgroundColor: 'rgba(255, 107, 53, 0.15)', // Brand tint
backdropFilter: 'blur(40px)',
borderWidth: 1,
borderColor: 'rgba(255, 107, 53, 0.3)',
},
}
```
### Liquid Animations
```typescript
const LIQUID = {
// Morphing shapes
MORPH: {
duration: 600,
easing: 'cubic-bezier(0.4, 0, 0.2, 1)',
},
// Ripple effect on tap
RIPPLE: {
scale: { from: 0.8, to: 1 },
opacity: { from: 0.5, to: 0 },
duration: 400,
},
// Breathing glow
BREATHE: {
scale: { from: 1, to: 1.02 },
shadowRadius: { from: 20, to: 30 },
duration: 2000,
loop: true,
},
// Slide with liquid easing
SLIDE: {
damping: 20,
stiffness: 300,
mass: 1,
},
}
```
---
## Visual Identity
### Logo Concept
```
┌─────────────────────────────┐
│ │
│ TABATA │ ← Bold, black
│ FIT │ ← Accent orange
│ │
│ [Flame icon] │ ← Optional mark
│ │
└─────────────────────────────┘
```
### Brand Voice
| DO | DON'T |
|----|-------|
| "Let's burn." | "Get ripped fast!" |
| "4 minutes to stronger." | "Lose weight now!" |
| "Your daily dose of HIIT." | "The #1 fitness app!" |
| Minimal, confident copy | Excessive exclamation marks!! |
---
## Color Palette
### Primary Colors
```
┌─────────────────────────────────────────────────────────┐
│ │
│ BLACK ████████████ #000000 Background │
│ CHARCOAL ████████████ #1C1C1E Surfaces │
│ SLATE ████████████ #2C2C2E Elevated │
│ │
│ FLAME ████████████ #FF6B35 Brand accent │
│ FLAME LIGHT ████████████ #FF8C5A Highlights │
│ │
│ ICE ████████████ #5AC8FA Rest phases │
│ GLOW ████████████ #FFD60A Achievement │
│ ENERGY ████████████ #30D158 Success/Complete│
│ │
└─────────────────────────────────────────────────────────┘
```
### Semantic Usage
| Color | Hex | Usage |
|-------|-----|-------|
| **Black** | #000000 | Main background, video frames |
| **Charcoal** | #1C1C1E | Cards, raised surfaces |
| **Slate** | #2C2C2E | Modals, elevated elements |
| **Flame** | #FF6B35 | Work phase, CTAs, brand |
| **Ice** | #5AC8FA | Rest phase, calm states |
| **Glow** | #FFD60A | Achievement badges, streaks |
| **Energy** | #30D158 | Complete states, success |
### Phase Colors (Critical)
```typescript
const PHASE_COLORS = {
PREP: '#FF9500', // Orange-yellow - get ready
WORK: '#FF6B35', // Flame orange - WORK!
REST: '#5AC8FA', // Ice blue - recover
COMPLETE: '#30D158', // Energy green - done!
}
```
---
## Typography
### Font Stack
**Primary**: Inter (Google Fonts)
- Clean, modern, excellent readability
- Variable weight support
- Apple SF Pro alternative
### Type Scale
| Style | Size | Weight | Use Case |
|-------|------|--------|----------|
| **HERO** | 48px | 900 | Marketing, celebration |
| **TITLE_1** | 34px | 700 | Screen titles |
| **TITLE_2** | 28px | 700 | Section headers |
| **TITLE_3** | 22px | 600 | Card titles |
| **BODY** | 17px | 400 | Default text |
| **BODY_BOLD** | 17px | 600 | Emphasis |
| **CAPTION** | 15px | 400 | Metadata |
| **MICRO** | 13px | 400 | Small labels |
| **TIMER** | 96px | 900 | Countdown display |
### Timer Typography (Special)
```typescript
const TIMER_STYLES = {
// Main countdown number
NUMBER: {
fontFamily: 'Inter_900Black',
fontSize: 96,
fontVariant: ['tabular-nums'], // Monospace digits
letterSpacing: -2,
},
// Phase label (WORK, REST)
PHASE: {
fontFamily: 'Inter_700Bold',
fontSize: 24,
letterSpacing: 2,
textTransform: 'uppercase',
},
// Round indicator
ROUND: {
fontFamily: 'Inter_500Medium',
fontSize: 17,
fontVariant: ['tabular-nums'],
},
}
```
---
## Spacing System
```typescript
const SPACING = {
// Base unit: 4px
0: 0,
1: 4,
2: 8,
3: 12,
4: 16,
5: 20,
6: 24,
8: 32,
10: 40,
12: 48,
16: 64,
// Semantic
XS: 4,
SM: 8,
MD: 16,
LG: 24,
XL: 32,
XXL: 48,
}
const LAYOUT = {
SCREEN_PADDING: 24, // Horizontal screen padding
CARD_RADIUS: 16, // Standard card radius
BUTTON_RADIUS: 12, // Button radius
TAB_BAR_HEIGHT: 80, // Bottom tab bar
STATUS_BAR: 44, // iOS status bar
}
```
---
## Component Styles
### Cards
```typescript
const CARD = {
CONTAINER: {
backgroundColor: '#1C1C1E',
borderRadius: 16,
overflow: 'hidden',
},
THUMBNAIL: {
aspectRatio: 16/9,
backgroundColor: '#2C2C2E',
},
CONTENT: {
padding: 16,
},
// Variants
FEATURED: {
borderRadius: 20,
},
COMPACT: {
flexDirection: 'row',
borderRadius: 12,
},
}
```
### Buttons
```typescript
const BUTTON = {
PRIMARY: {
backgroundColor: '#FF6B35',
paddingVertical: 16,
paddingHorizontal: 24,
borderRadius: 12,
alignItems: 'center',
justifyContent: 'center',
},
PRIMARY_TEXT: {
color: '#FFFFFF',
fontFamily: 'Inter_600SemiBold',
fontSize: 17,
letterSpacing: 0.5,
},
SECONDARY: {
backgroundColor: 'transparent',
borderWidth: 1,
borderColor: '#3A3A3C',
},
GHOST: {
backgroundColor: 'transparent',
},
}
```
### Timer Display
```typescript
const TIMER = {
CONTAINER: {
position: 'absolute',
bottom: 0,
left: 0,
right: 0,
padding: 24,
background: 'linear-gradient(transparent, rgba(0,0,0,0.8))',
},
NUMBER: {
fontFamily: 'Inter_900Black',
fontSize: 96,
color: '#FFFFFF',
textAlign: 'center',
},
PROGRESS_BAR: {
height: 4,
backgroundColor: 'rgba(255,255,255,0.2)',
borderRadius: 2,
marginTop: 16,
},
PROGRESS_FILL: {
height: '100%',
borderRadius: 2,
// Color based on phase
},
}
```
---
## Animation Specifications
### Timing Constants
```typescript
const DURATION = {
INSTANT: 100,
FAST: 200,
NORMAL: 300,
SLOW: 500,
XSLow: 800,
}
const EASING = {
// Standard iOS ease
DEFAULT: 'ease-out',
// Spring animations
BOUNCY: {
damping: 15,
stiffness: 180,
},
GENTLE: {
damping: 20,
stiffness: 100,
},
}
```
### Key Animations
**Timer Countdown:**
```typescript
// Number pulses slightly each second
Animated.sequence([
Animated.timing(scale, { toValue: 1.05, duration: 100 }),
Animated.timing(scale, { toValue: 1, duration: 100 }),
])
```
**Progress Bar:**
```typescript
// Smooth linear fill during phase
Animated.timing(width, {
toValue: 100,
duration: phaseDuration,
easing: Easing.linear,
})
```
**Phase Transition:**
```typescript
// Color crossfade
Animated.timing(colorProgress, {
toValue: 1,
duration: 300,
})
```
**Workout Complete:**
```typescript
// Celebration with scale + fade
Animated.parallel([
Animated.spring(scale, { toValue: 1, ...BOUNCY }),
Animated.timing(opacity, { toValue: 1, duration: 500 }),
])
```
---
## Icon System
Using SF Symbols / Ionicons equivalent:
| Context | Icon | Size |
|---------|------|------|
| Home Tab | house.fill | 24 |
| Workouts Tab | flame.fill | 24 |
| Activity Tab | chart.bar.fill | 24 |
| Browse Tab | square.grid.2x2.fill | 24 |
| Profile Tab | person.fill | 24 |
| Play | play.fill | 20 |
| Pause | pause.fill | 20 |
| Close | xmark | 20 |
| Back | chevron.left | 20 |
| Forward | chevron.right | 20 |
| Heart | heart.fill | 20 |
| Search | magnifyingglass | 20 |
---
## Video Player UI
### Overlay Layout
```
┌─────────────────────────────────────────────┐
│ [Close X] [♥︎] [···] │ ← Top bar
│ │
│ │
│ [VIDEO CONTENT] │
│ │
│ │
│ │
│ ┌─────────────────────────────────────────┐ │
│ │ 🔥 WORK │ │
│ │ │ │
│ │ 00:14 │ │ ← Timer overlay
│ │ │ │
│ │ Round 3 of 8 │ │
│ │ ████████████░░░░ │ │
│ └─────────────────────────────────────────┘ │
└─────────────────────────────────────────────┘
```
### Video Requirements
- **Resolution**: 1080p minimum
- **Aspect**: 16:9 (landscape) or 9:16 (portrait mode)
- **Format**: HLS (m3u8) for streaming
- **Audio**: AAC, 128kbps minimum
- **Thumbnail**: JPG, same aspect ratio
---
## Sound Design
### Sound Effects
| Event | Sound | Description |
|-------|-------|-------------|
| Phase Start | "ding" | Quick, bright chime |
| Count 3-2-1 | "tick" | Subtle tick sound |
| Workout Start | "whoosh" | Energy whoosh |
| Workout Complete | "success" | Celebratory chime |
| Button Tap | "tap" | Soft tap feedback |
| Streak Achieved | "fire" | Crackling fire |
### Haptics
| Event | Haptic |
|-------|--------|
| Phase change | Medium |
| Button tap | Light |
| Countdown tick | Selection |
| Workout complete | Success |
| Error | Error |
---
## Dark Mode Only
TabataFit is **dark mode only** — no light mode. This is a deliberate design choice matching Apple Fitness+ and creating an immersive, cinematic experience.
Reasons:
1. Better video contrast
2. Less eye strain during workouts
3. Premium feel
4. Consistent with fitness studio lighting
---
## Image Guidelines
### Trainer Photos
- Professional, high-quality headshots
- Warm, approachable expressions
- Fitness attire visible
- Consistent lighting style
- Background: Dark or studio setting
### Workout Thumbnails
- Action shot from the workout
- Clear exercise demonstration
- Trainer visible
- Dark/gradient background
- Text overlay: Title, duration, level
### Collection Banners
- 16:9 aspect ratio
- Composite of trainer + exercises
- Gradient overlay for text
- Brand accent color elements
---
## Copy Guidelines
### Tone
- **Confident** but not arrogant
- **Encouraging** but not cheesy
- **Clear** and direct
- **Minimal** — let the content speak
### Examples
| Context | Good | Bad |
|---------|------|-----|
| CTA | "Start Workout" | "Start Your Workout Now!" |
| Empty state | "No workouts yet" | "You haven't done any workouts :(" |
| Error | "Connection lost" | "Oh no! Something went wrong!" |
| Success | "Workout complete" | "AMAZING! You crushed it!!!" |
### Coach Dialogue
- Motivational but authentic
- Form cues during exercises
- Breathing reminders during rest
- Encouragement without clichés
---
*Document created: February 18, 2026*
*Version: 2.0*
*Brand: Apple Fitness+ inspired*