# GAB-158 · GameMistakeTrap — « Piège pédagogique »

**Archétype / renderer_key :** `text_cta` (cartographie) · **module :** EdTechGameLearning
**Critère validé :** changer le JSON change la question, les options et le feedback sans modifier le HTML. ✅ check.py 12/12.

## Pack (structure officielle par-GAB)
```
GAB-158/
  renderer.html            ← moteur piège pédagogique (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
```

## Champs requis (instance, à plat)
`gab_id` · `trap_id` · `title` · `instruction` · `items[]{id,label,type}` · `feedback{heading,body}`

Optionnels : `trap_pattern`.

## Ce qui vient du JSON vs HTML
- **JSON** : le titre de la question, l'instruction, les libellés des options, leur type (`trap`/`ok`/`other`), le heading et le corps du feedback.
- **HTML** : layout carte, liste d'options, animations shake/fadein, logique pick (clic → état coloré → feedback), fallback BLOCKED.

## Logique de jeu (extraite du source)
1. L'apprenant clique une option.
2. Si `type='trap'` ou `type='other'` : l'option cliquée passe en rouge, la bonne option (`type='ok'`) passe en vert.
3. Si `type='ok'` : l'option cliquée passe en vert directement.
4. Dans tous les cas : le feedback pédagogique (`feedback.body`) s'affiche après 300 ms — c'est intentionnel (pédagogie : tomber ou pas dans le piège → on explique toujours).
5. Toutes les options sont désactivées (`disabled`) après la première interaction.

## Garde-fous (child_safety)
- **Anti-piège malicieux** : `feedback.body` est obligatoire — on n'affiche jamais un piège sans explication pédagogique.
- **BLOCKED** si `items` vide / aucun item `type='ok'` / `feedback` absent.
- `feedback.body` accepte du HTML inline (`<b>`, `<em>`) mais jamais de scripts.
- Le moteur reset `data-done` à chaque `init()` — réinjection propre d'une nouvelle instance.

## QA à vérifier
1. Clic option-piège → rouge + bonne réponse verte + feedback visible. 
2. Clic bonne réponse → verte + feedback visible après 300ms.
3. `items:[]` → BLOCKED propre affiché, aucune option rendue.
4. `feedback` absent → BLOCKED affiché.
5. Instance externe `ENGINE.init({...})` → rendu change sans modifier le HTML (critère d'or).
6. Responsive 375/768/1024 px.

## external_refs / dependencies
Aucune dépendance externe hors-lot. Le GAB-158 est autonome.

Références documentaires mentionnées dans la source (use_when / do_not_use_when) :
- GAB-117 : QCM standard (à utiliser si pas de piège explicite)
- GAB-126 : erreur classique d'exercice (hors piège pédagogique)

Ces GABs sont informatifs (doc source uniquement) — ils ne sont pas consommés par ce renderer.

## Source
`INDEX-300-gamelearning-GAB-156-160-PLAYABLE.html` (stage `data-tpl="158"`, handler `mtPick()`).
