# GAB-039 · StreakBadgeInline — « Streak inline (lecture seule) »

**Archétype / renderer_key :** `text_cta` (cartographie) · **module :** EdTechPlayKit
**Critère validé :** changer le JSON change le badge sans modifier le HTML. ✅ check.py 12/12.

## Pack (structure officielle par-GAB)
```
GAB-039/
  renderer.html            ← moteur badge streak (ne pas modifier par instance)
  instance.example.json    ← SOURCE DE VÉRITÉ (contenu réel, à plat)
  schema.contract.json     ← contrat de validation
  README-contract.md       ← ce fichier
```

## Archétype

**StreakBadgeInline** est un gabarit de **lecture seule** : il affiche un nombre de jours consécutifs de révision et les cercles de jours de la semaine. Il ne calcule JAMAIS le streak — cette responsabilité appartient au `GamificationAdapter`. Règle d'or du module : **PlayKit affiche · GamificationAdapter calcule et écrit.**

Contextes d'usage : header de page, bloc récapitulatif, dashboard élève.

## Champs requis (instance, à plat)
`gab_id` · `streak_id` · `streak_count` · `days_labels[7]` · `days_active[7]`

Optionnels : `streak_unit_label`, `motivation_note`, `context_note`, `cta_label`, `cta_action`.

## Ce qui vient du JSON vs HTML
- **JSON** : le nombre de jours (`streak_count`), l'unité (`streak_unit_label`), les labels jours (`days_labels`), les booléens actifs (`days_active`), la note de motivation, la note de contexte, le libellé du bouton CTA.
- **HTML** : layout badge pill, animation flamme, cercles jours, bouton structurel, fallback BLOCKED.

## Garde-fous (child_safety)
- **Lecture seule** : `streak_count` est toujours fourni de l'extérieur — le renderer ne fait aucun calcul de streak.
- **Alignement days** : `days_labels.length === 7` ET `days_active.length === 7` sont vérifiés — BLOCKED sinon.
- **streak_count = 0** : cas valide, s'affiche normalement (pas de BLOCKED).
- **BLOCKED** si `streak_count` absent, `days_labels` absent/mauvaise longueur, ou `days_active` absent/mauvaise longueur.

## QA à vérifier
1. Modifier `streak_count` / `days_active` → rendu change sans toucher au HTML (critère d'or).
2. `streak_count` absent → BLOCKED propre.
3. `days_active.length != 7` → BLOCKED longueur incorrecte.
4. `streak_count = 0` → rendu valide, 0 cercle actif.
5. Instance externe injectée via `ENGINE.init(ext)` → rendu change.
6. Responsive 375/768/1024 : cercles jours restent visibles sans débordement.

## external_refs / dependencies
| Référence | Rôle |
|---|---|
| `GamificationAdapter` | Calcule et écrit le streak en base ; PlayKit consomme uniquement |
| GAB-022 (CelebrationScreen) | Célébration plein écran — à utiliser à la place de GAB-039 si besoin |
| GAB-040 (XPGainAnimation) | Animation gain XP — gabarit complémentaire du même lot |

## Source
`INDEX-300-playkit-GAB-036-040-PLAYABLE.html` (stage `data-tpl="39"`, CSS classes `streak-*`).
