---
name: tabata-kine-design-system
description: >
  Design system complet pour l'application Tabata Kiné. Utilise ce skill pour
  toute tâche liée au design, aux composants UI, aux écrans, aux couleurs, à la
  typographie ou aux décisions d'interface de l'app Tabata Kiné. Déclenche ce
  skill dès que l'utilisateur mentionne : un écran de l'app (onboarding, séance,
  dashboard, paywall, programmes), un composant (bouton, carte, timer, badge,
  input), une couleur, une typographie, une animation, un espacement, ou demande
  à coder un élément UI. Ce skill contient les règles non négociables du design
  "Dark Medical" — le style qui différencie l'app de tous les concurrents fitness.
---

# Design System — Tabata Kiné

## Principe directeur : Dark Medical

L'app Tabata Kiné n'est **pas** une app fitness classique. C'est une app médicale
qui utilise le format tabata. Le style "Dark Medical" traduit visuellement ce
positionnement : fond sombre professionnel, vert santé comme seule couleur d'action,
expertise kiné visible à chaque écran.

**Règles absolues :**
- Pas de mode clair. Dark only, sans exception.
- Le vert (#00C896) ne sert qu'aux actions et à la validation.
- L'orange (#FF8A5C) ne sert qu'aux conseils kiné et alertes positives.
- Le rouge (#FF4444) est réservé au timer en phase d'urgence (<10s).
- Touch target minimum : 44×44px pour tous les éléments interactifs.

---

## 1. Tokens de couleur

### Fonds — Navy

| Token | Valeur | Usage |
|-------|--------|-------|
| `navy-900` | `#0D1B2A` | Fond principal de l'app |
| `navy-800` | `#112240` | Surface 1 — cartes par défaut |
| `navy-700` | `#1A3050` | Surface 2 — cartes surélevées |
| `navy-600` | `#243C5E` | Bordures actives |

### Vert Kiné — action & santé

| Token | Valeur | Usage |
|-------|--------|-------|
| `green-500` | `#00C896` | CTA principal, timer effort, progress |
| `green-600` | `#00A67C` | État hover / pressed |
| `green-700` | `#00875F` | État active deep |
| `green-dim` | `rgba(0,200,150,0.12)` | Fond badge, chip, card accent |
| `green-border` | `rgba(0,200,150,0.35)` | Bordure card accent |

### Texte & bordures

| Token | Valeur | Usage |
|-------|--------|-------|
| `white-100` | `#E6F1FF` | Texte primaire |
| `slate-300` | `#A8B2D8` | Texte secondaire |
| `slate-400` | `#8892B0` | Texte tertiaire, placeholders |
| `border-dim` | `rgba(168,178,216,0.15)` | Bordure par défaut |
| `border-hover` | `rgba(168,178,216,0.25)` | Bordure hover |

### Orange — conseils kiné uniquement

| Token | Valeur | Usage |
|-------|--------|-------|
| `orange-500` | `#FF8A5C` | Tip card border, badge Kiné+ |
| `orange-600` | `#E06A3C` | Hover orange |
| `orange-dim` | `rgba(255,138,92,0.12)` | Fond tip card |

### Sémantique

| Token | Valeur | Usage |
|-------|--------|-------|
| `red-500` | `#FF4444` | Timer urgence <10s UNIQUEMENT |

---

## 2. Typographie

### Familles

| Rôle | Famille | Notes |
|------|---------|-------|
| Titres émotionnels | Serif italique (ex: DM Serif Display, Georgia) | Célébration, fin de séance, accroches |
| Interface & corps | Sans-serif géométrique (ex: Outfit, DM Sans) | Navigation, descriptions, labels |
| Données & timer | Monospace (ex: DM Mono, JetBrains Mono) | Timer, stats, codes, metadata |

### Échelle

| Style | Famille | Taille | Poids | Usage |
|-------|---------|--------|-------|-------|
| `display` | Serif italic | 28–32px | 400 | Fin de séance, titres forts |
| `heading-1` | Serif | 22–24px | 500 | Titres de section |
| `heading-2` | Sans | 18px | 500 | Titre exercice, carte programme |
| `body` | Sans | 15–16px | 400 | Corps, conseil kiné |
| `label` | Mono | 11–13px | 500 | Tags, metadata, uppercase tracking |
| `timer` | Mono | **80–100px** | 500 | Timer séance — lisible à 2 mètres |
| `caption` | Sans | 12px | 400 | Sous-labels, hints |

**Règle typographie :** La taille du timer est la décision de design la plus
importante de l'écran séance. Tout se dimensionne autour de lui.

---

## 3. Espacement

Base : **4px**

| Token | Valeur | Usage |
|-------|--------|-------|
| `space-1` | 4px | Gap minimal entre éléments liés |
| `space-2` | 8px | Gap interne composant |
| `space-3` | 12px | Gap entre composants proches |
| `space-4` | 16px | Padding carte, gap standard |
| `space-6` | 24px | Espacement sections |
| `space-8` | 32px | Padding écran horizontal |
| `space-12` | 48px | Espacement majeur |
| `space-16` | 64px | Espacement entre blocs screens |

---

## 4. Border Radius

| Token | Valeur | Usage |
|-------|--------|-------|
| `radius-sm` | 4px | Badge, chip, tag |
| `radius-md` | 8px | Bouton, input, tip card |
| `radius-lg` | 12px | Carte programme standard |
| `radius-xl` | 16px | Carte large, modal |
| `radius-pill` | 9999px | Pill, toggle, progress bar |
| `radius-circle` | 50% | Icon button, avatar, streak dot |

---

## 5. Système d'élévation (surfaces)

```
Fond (navy-900)
  └── Surface 1 (navy-800) — cartes par défaut
        └── Surface 2 (navy-700) — cartes surélevées / hover
              └── Surface active (navy-800 + border green-500 1.5px)
```

Différencier les surfaces **uniquement par la couleur de fond**, jamais par des
ombres portées (box-shadow : non). La bordure active verte est le seul signal
d'état sélectionné.

---

## 6. Composants

### Boutons

```
PrimaryButton
  background: green-500
  color: navy-900
  padding: 14px 24px
  height: 52–56px
  border-radius: radius-md
  font: sans 15px 500
  width: 100% (full-width dans les screens)
  hover: background green-600
  active: background green-700 + scale(0.98)

SecondaryButton
  background: transparent
  color: green-500
  border: 1.5px solid green-500
  padding: 13px 24px
  hover: background green-dim

GhostButton
  background: transparent
  color: slate-300
  no border
  usage: actions secondaires (Passer, Annuler)

DangerButton
  background: rgba(255,68,68,0.12)
  color: #FF6B6B
  border: 1px solid rgba(255,68,68,0.3)
  usage: Quitter la séance UNIQUEMENT

IconButton
  width: 44px
  height: 44px
  border-radius: 50%
  background: rgba(168,178,216,0.10)
  color: slate-300
  JAMAIS en dessous de 44×44px (accessibilité)
```

### Inputs

```
TextField
  background: navy-800
  border: 1px solid border-dim
  border-radius: radius-md
  padding: 12px 16px
  color: white-100
  font: sans 15px 400
  focus: border green-500
  error: border red-500
  height: 48px
```

### Badges & Pills

```
Badge (tier)
  font: mono 11px 500
  padding: 3px 10px
  border-radius: radius-sm
  UPPERCASE + letter-spacing: 0.08em

  .free:   background green-dim,  color green-500
  .premium: background orange-dim, color orange-500
  .kine:   background rgba(168,178,216,0.12), color slate-300

Pill (metadata)
  font: sans 12px 400
  padding: 4px 12px
  border-radius: radius-pill
  border: 1px solid (couleur correspondante à 0.3 opacity)
```

### Cartes

```
CardDefault
  background: navy-800
  border: 1px solid border-dim
  border-radius: radius-lg
  padding: 16px

CardAccent (CTA, prochaine séance)
  background: rgba(0,200,150,0.05)
  border: 1.5px solid green-border
  border-radius: radius-lg

CardTip (conseil kiné)
  background: orange-dim
  border-left: 3px solid orange-500
  border-radius: 0 radius-lg radius-lg 0
  NE PAS arrondir le côté gauche (border-left unique)
  Structure: icône 💡 + texte + signature "— Prénom, kiné"

CardProgram
  border-radius: radius-xl
  overflow: hidden
  Thumbnail: 120px height, gradient navy-700→navy-600
  Body: padding 14px
  Toujours afficher: progression bar + "X/12 séances"
```

### Timer

```
Timer (composant le plus critique de l'app)
  font: mono 80–100px 500
  text-align: center

  État effort normal (>10s):
    color: green-500

  État urgence (<10s):
    color: red-500
    animation: pulse subtil (scale 1→1.02→1, 1s infinite)

  Label sous le chiffre:
    font: mono 14px 400
    color: slate-400
    letter-spacing: 0.1em
    text: "SECONDES"

  Contexte repos:
    color: slate-300 (pas de vert, signal visuel de repos)
```

### Progress Bar

```
ProgressBar
  track: background rgba(168,178,216,0.12), height 4px, border-radius pill
  fill: background green-500, border-radius pill
  
  Variante séance (épaisseur réduite):
    height: 3px

  Variante programme:
    height: 4px
    Afficher le % à droite en mono 11px green-500

  Animation: transition width 300ms ease
```

### Feedback ressenti

```
FeedbackButton
  width: flex (3 boutons égaux)
  height: 72px
  border-radius: radius-lg
  background: navy-800
  border: 1px solid border-dim
  flex-direction: column
  gap: 4px

  Emoji: 28px
  Label: sans 12px slate-400

  État sélectionné:
    border: 1.5px solid green-500
    background: green-dim
```

### Streak hebdomadaire

```
StreakDot
  width: 32px
  height: 32px
  border-radius: 50%

  .done:  background rgba(0,200,150,0.15)  → afficher ✓
  .today: background green-500             → afficher ✓
  .empty: background rgba(168,178,216,0.06), border 1px border-dim

Label jour: mono 10px slate-400, centré sous chaque dot
```

---

## 7. Écran séance — règles spéciales

L'écran séance est le plus critique de l'app. Il doit être utilisable **les mains
sur les genoux, en sueur, à 2 mètres de l'écran**. Chaque décision de design doit
passer ce test.

### Architecture visuelle

```
[Vidéo plein écran en boucle — fond de tout l'écran]
  ↓ Gradient top navy→transparent (40% opacité, 100px height)
    → Contrôles pause/audio en overlay
    → Indicateur exercice X/8 centré
  ↓ Zone centrale nette (pas de gradient — l'utilisateur voit le mouvement)
  ↓ Gradient bottom transparent→navy (70% opacité, 220px height)
    → Timer géant centré
    → Progress bar
    → Tip card conseil kiné
```

### Transitions séance

```
Effort → Repos:
  Fond passe de vidéo plein écran → navy-800 uni
  Transition: fade 300ms
  Vibration haptique légère (si disponible)
  Le repos a une identité visuelle différente (pas de vidéo, couleur unie)

Repos → Effort:
  Countdown audio "3... 2... 1..."
  Vibration haptique + transition fade

Exercice suivant pendant le repos:
  Afficher un thumbnail 56×56px du prochain exercice
  Nom en sans 14px 500
  Label "PROCHAIN EXERCICE" en mono 11px slate-400
```

### Phase repos

L'écran repos doit être **visuellement différent** de l'écran effort.

- Fond : `navy-800` uni (plus de vidéo plein écran)
- Timer couleur : `slate-300` (pas de vert — c'est le repos)
- Mot "REPOS" en mono 13px slate-400, letter-spacing 0.15em
- Aperçu prochain exercice centré

---

## 8. Navigation

```
Tab Bar (5 onglets, fixé en bas)
  height: 56px + safe area inset
  background: navy-800
  border-top: 1px solid border-dim

  Onglets:
    - Accueil (home icon)
    - Programmes (grid icon)
    - Minuteur (timer icon)
    - Progression (chart icon)
    - Profil (person icon)

  Onglet actif: icône green-500 + label green-500
  Onglet inactif: icône slate-400 + label slate-400

  Font label: sans 11px 400
  Icon size: 22×22px
  Touch target: 44×44px minimum
```

---

## 9. Animations & micro-interactions

```
FadeIn:
  opacity: 0 → 1
  duration: 300ms
  easing: ease

SlideUp (bottom sheet, modal):
  translateY(100%) → 0
  duration: 400ms
  easing: cubic-bezier(0.4, 0, 0.2, 1)

Pulse (CTA bouton, timer urgence):
  scale: 1 → 1.02 → 1
  duration: 2s
  infinite, ease-in-out

Bounce (célébration fin de séance):
  scale: 0.5 → 1.05 → 0.98 → 1
  duration: 600ms
  easing: spring

StaggerList (items qui apparaissent en séquence):
  Délai: 100ms entre chaque item
  Chaque item: FadeIn + translateY(12px→0)

ScalePress (tous les boutons):
  active: scale(0.97)
  duration: 100ms
```

**Règle d'or animations :** Une animation bien exécutée au chargement d'écran
vaut mieux que des micro-interactions dispersées partout.

---

## 10. Paywall — règles de design conversion

```
Structure obligatoire du paywall:
  1. Célébration des accomplissements (TOUJOURS en premier)
     → Font serif italic, emoji, stats concrètes
  2. Valeur du contenu débloqué (liste concrète)
  3. Pricing transparent (pas de dark patterns)
     → "Essai gratuit 7 jours · puis 24,99€/an · soit 2,08€/mois"
  4. CTA principal (PrimaryButton full-width)
  5. Réassurance ("Annulation facile à tout moment")
  6. Alternative gratuite visible (GhostButton ou lien)

  Couleur encadré pricing: CardAccent (vert)
  Bouton fermeture: TOUJOURS visible en haut à gauche
  Pas de compte à rebours fictif, pas de stock limité : anti dark patterns
```

---

## 11. Accessibilité

```
Contraste texte:
  Texte primaire (#E6F1FF) sur navy-900 → ratio 15:1 ✓
  Texte secondaire (#A8B2D8) sur navy-900 → ratio 7:1 ✓
  Vert (#00C896) sur navy-900 → ratio 8:1 ✓
  Tous conformes WCAG AA (4.5:1 minimum requis)

Touch targets:
  Minimum 44×44px pour TOUS les éléments interactifs
  Espacement minimum 8px entre deux éléments interactifs adjacents

Timer:
  La couleur n'est pas le seul signal d'urgence
  Ajouter aussi: pulse animation + vibration haptique + signal audio

Audio:
  Toujours proposer une alternative visuelle à chaque signal audio
  Le toggle audio est accessible en 1 tap depuis l'écran séance
```

---

## 12. Tokens React Native / Expo

```typescript
// design-tokens.ts
export const colors = {
  // Navy
  navy900: '#0D1B2A',
  navy800: '#112240',
  navy700: '#1A3050',
  navy600: '#243C5E',

  // Green
  green500: '#00C896',
  green600: '#00A67C',
  green700: '#00875F',
  greenDim: 'rgba(0,200,150,0.12)',
  greenBorder: 'rgba(0,200,150,0.35)',

  // Text
  white100: '#E6F1FF',
  slate300: '#A8B2D8',
  slate400: '#8892B0',

  // Borders
  borderDim: 'rgba(168,178,216,0.15)',
  borderHover: 'rgba(168,178,216,0.25)',

  // Orange (tip/kine only)
  orange500: '#FF8A5C',
  orange600: '#E06A3C',
  orangeDim: 'rgba(255,138,92,0.12)',

  // Semantic
  red500: '#FF4444', // timer urgence ONLY
} as const

export const spacing = {
  1: 4,
  2: 8,
  3: 12,
  4: 16,
  6: 24,
  8: 32,
  12: 48,
  16: 64,
} as const

export const radius = {
  sm: 4,
  md: 8,
  lg: 12,
  xl: 16,
  pill: 9999,
} as const

export const fontSizes = {
  caption: 12,
  label: 13,
  body: 15,
  heading2: 18,
  heading1: 22,
  display: 28,
  timer: 88, // taille par défaut du timer
} as const

export const timerThreshold = 10 // secondes — passage vert → rouge
```

---

## Checklist avant livraison d'un écran

- [ ] Fond `navy-900` utilisé comme base
- [ ] Aucun shadow/élévation — différenciation par couleur uniquement
- [ ] Tous les touch targets ≥ 44×44px
- [ ] Le vert n'est utilisé que pour des actions ou validations
- [ ] L'orange n'est utilisé que pour des conseils kiné ou alertes positives
- [ ] Le rouge n'apparaît que sur le timer en urgence
- [ ] Timer ≥ 80px de haut sur l'écran séance
- [ ] Vidéo plein écran sur l'écran séance (pas un bloc vidéo)
- [ ] Gradients top + bottom sur l'écran séance pour la lisibilité
- [ ] Phase repos visuellement différente de la phase effort
- [ ] Paywall : célébration en premier, alternative gratuite visible
- [ ] Typographie : serif pour les moments émotionnels, mono pour les données
