# GAB-159 · GameComboStreakLocal — « Combo local du mini-jeu »

**Archétype / renderer_key :** `text_cta` (cartographie) · **module :** EdTechGameLearning
**Tags source :** V1_X · S · P1
**Critère validé :** changer le JSON change le rendu sans modifier le HTML. ✅ check.py 12/12.

## Pack (structure officielle par-GAB)
```
GAB-159/
  renderer.html            ← moteur combo 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

**Combo streak LOCAL** : multiplicateur perdable (x1 → x2 → x3 → x5) déclenché par une série de bonnes actions consécutives au sein d'un mini-jeu. Une erreur remet le compteur à zéro. Usage strictement intra-jeu.

## Champs requis (instance, à plat)
`gab_id` · `combo_id` · `title` · `streak_label` · `multiplier_levels[]{threshold,multiplier,label}` · `msg_initial`

Optionnels : `progress_labels{level_start,level_bonus,level_max}` · `cta_ok{label,action}` · `cta_ko{label,action}` · `msg_broken` · `msg_bonus_x3` · `msg_bonus_x5` · `msg_sustain_x5` · `msg_progress_template` · `accessibility{aria_label_ok,aria_label_ko}`.

## Ce qui vient du JSON vs HTML
- **JSON** : tous les textes (label, messages d'état, libellés des boutons, jalons barre de progression, seuils multiplicateur).
- **HTML** : carte combo, barre de progression, flamme animée, afficheur multiplicateur, layout, moteur de calcul de seuil.

## Garde-fous
- **LOCAL uniquement** : ce GAB gère un streak DANS le mini-jeu, perdable à chaque erreur. Ne PAS utiliser pour le streak global gamification (→ PlayKit) ni pour le scoring d'exercice (→ GAB-129).
- **BLOCKED** si `multiplier_levels` vide / `msg_initial` absent / `gab_id` absent.
- **Moteur de seuil** : tri décroissant des `threshold` pour trouver le multiplicateur actif — l'instance peut définir autant de paliers qu'elle veut.
- **Aucun contenu pédagogique en dur** : les questions/bonnes réponses qui incrémentent le combo sont portées par le mini-jeu parent, pas par ce GAB.

## QA à vérifier
1. Modifier `streak_label`/`msg_bonus_x3` → rendu change sans toucher au HTML (critère d'or).
2. `multiplier_levels:[]` → BLOCKED propre dans `panel-err`.
3. 3 clics "Bonne action" → multiplicateur x3, message bonus x3, flamme x3.
4. 5 clics "Bonne action" → multiplicateur x5, message max x5, flamme x5.
5. Clic "Erreur" après combo → retour x1, message broken.
6. `ENGINE.init(extInstance)` → rendu piloté par l'instance externe.
7. Responsive 375/768/1024 (boutons empilés en mobile).

## Source
`INDEX-300-gamelearning-GAB-156-160-PLAYABLE.html` (stage `data-tpl="159"`, handler `csAct(ok)`, CSS `.cs-*`).

## Références externes (dependencies)
- `GAB-129` (ScoreDisplay) : scoring d'exercice — à utiliser si le multiplicateur doit impacter un score calculé.
- `GAB-155` (GameSessionEnd) : feedback de fin de jeu — reçoit le multiplicateur max atteint.
- `PlayKit / GAB-160` (GameRewardBridge) : pour la récompense globale post-jeu (streak GLOBAL hors scope de ce GAB).
