# GAB-164 · GameMistakeRematch — « Revanche ciblée erreurs »

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

## Pack (structure officielle par-GAB)
```
GAB-164/
  renderer.html            ← moteur revanche ciblée (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

**GameMistakeRematch** = écran de revanche ciblée après un mini-jeu. L'élève ne rejoue **pas** tout le jeu — uniquement les cartes qu'il a mal classées lors d'une session précédente. Le CTA reste verrouillé jusqu'à ce que toutes les cartes soient validées une par une.

Différences avec GAB voisins :
- GAB-154 (reset) → recommencer tout le mini-jeu
- GAB-131 (remédiation adaptative) → séquence adaptative complète
- GAB-115 (cram mémoire) → répétition espacée globale
- **GAB-164 → revanche ciblée, recyclage actif, après débrief (163), avant boss (165)**

## Champs requis (instance, à plat)
`gab_id` · `rematch_id` · `title` · `items[]{id, icon, label, user_answer, correct_answer, feedback_done}` · `primary_cta{label_locked, label_unlocked, action}`

Optionnels : `subtitle`, `body`, `error_count`, `blocked_message`.

## Ce qui vient du JSON vs HTML
- **JSON** : titre, sous-titre, message contextuel, chaque carte (icône, libellé, réponse élève, bonne réponse, feedback post-clic), libellés du CTA (locked/unlocked), message de blocage.
- **HTML** : structure carte, icône ↻, barre de progression, logique de déverrouillage CTA, layout, états visuels done/pending.

## Garde-fous (child_safety)
- **Anti-invention** : aucun contenu pédagogique n'est hardcodé dans le renderer — tout vient de l'instance.
- **CTA bloqué** : le bouton reste `disabled` tant que `done < total`. Impossible de passer à l'étape suivante sans avoir refait toutes les cartes.
- **feedback_done** invisible avant interaction — affiché seulement après clic sur la carte.
- **BLOCKED** si `title` absent / `items` vides / `primary_cta` absent.

## QA à vérifier
1. Modifier un `label`/`correct_answer` dans l'instance → rendu change sans toucher au HTML (critère d'or).
2. `items:[]` vide → BLOCKED propre dans panel rouge.
3. Cliquer 1 carte → icône ↻ → ✓, fond vert, compteur incrémenté, barre progresse.
4. Toutes cartes cliquées → CTA enabled, texte `label_unlocked`, panel vert succès.
5. Clic CTA avant fin → `blocked_message` s'affiche, CTA reste disabled.
6. Responsive 375/768/1024 → aucun débordement.
7. Navigation clavier (Tab + Enter/Space) sur chaque carte.

## Source
`INDEX-300-gamelearning-GAB-161-165-PLAYABLE.html` (stage `data-tpl="164"`, CSS `.mr-*`, handler `mrPick()`).

## external_refs / dependencies
Aucune dépendance externe. Ce GAB est autonome dans le lot `LOT-gamelearning-GAB-161-165`.

Gabarits de la même séquence narrative :
- GAB-163 (débrief avant revanche) — lot identique
- GAB-165 (mini-boss après revanche) — lot identique
