# GAB-142 · InteractiveBuildDiagram — « Construction de schéma (B armé) »

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

## Pack (structure officielle par-GAB)
```
GAB-142/
  renderer.html            ← moteur schéma interactif (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 : Pattern B armé (sélection → arming → drop)
Interaction en 2 temps :
1. L'élève clique un token dans le pool → token « armé » (highlight gold, badge « sélectionné »).
2. L'élève clique une case du schéma → token déposé, feedback mis à jour.
Cliquer un token déjà placé le retire de la case et le repose dans le pool.

## Champs requis (instance, à plat)
`gab_id` · `diagram_id` · `tokens[]{id, label, best_slot}` · `slots[]{id, label}` · `instruction`

Optionnels : `title`, `status_idle`, `status_armed_tpl` (avec `{token}`), `arrow`, `feedback_partial` (avec `{placed}/{total}`), `feedback_success`, `feedback_partial_error` (avec `{good}/{total}`).

## Ce qui vient du JSON vs HTML
- **JSON** : tous les tokens (label + best_slot), tous les slots (id + label), instruction, messages d'état, feedbacks, flèche séparatrice.
- **HTML** : moteur pattern B armé (pick/drop/arming), layout flow, styles DS V2, aucun token ni slot en dur.

## Garde-fous (child_safety)
- **Aucun contenu pédagogique en dur** dans le HTML : l'instance exemple utilise « chaîne alimentaire » mais tout autre schéma en chaîne (cycle eau, étapes photosynthèse, etc.) s'instancie sans toucher au HTML.
- **BLOCKED** si `diagram_id` absent / `tokens` vides / `slots` vides / `instruction` absente.
- **token.best_slot** doit référencer un `id` existant dans `slots` (garde applicatif : case non trouvée = drop ignoré).

## QA à vérifier
1. Modifier `tokens[].label` ou `slots[].label` → rendu change sans toucher au HTML (critère d'or).
2. `tokens:[]` → BLOCKED propre.
3. Token placé sur mauvaise case → `feedback_partial_error` avec bon/total.
4. Tous tokens corrects → `feedback_success`.
5. Clic token placé → retiré de la case, reposé dans pool.
6. Responsive 375 : flèches tournées à 90°, colonnes empilées.

## Source
`INDEX-300-interactivelearning-GAB-141-145-PLAYABLE.html` (stage `data-tpl="142"`, handlers `bdPick/bdDrop/bdFeedback/bdArmingOn/bdArmingOff`).
