# GAB-118 · ExerciseMCQMultiple — « QCM à réponses multiples »

**Archétype / renderer_key :** `text_cta` (cartographie) · **module :** EdTechExerciseLearning
**Critère validé :** changer le JSON change l'exercice sans modifier le HTML.

## Pack (structure officielle par-GAB)
```
GAB-118/
  renderer.html            ← moteur QCM multiple (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` · `exercise_id` · `question` · `choices[]{id,text,correct}` · `cta_label`

Optionnels : `title`, `instruction`, `feedback_ok`, `feedback_ko`.

## Ce qui vient du JSON vs HTML
- **JSON** : énoncé, instruction, chaque option (texte + flag correct), libellé du bouton, feedbacks ok/ko.
- **HTML** : layout stem + liste d'options + bouton structurel + zones feedback, styles DS V2, logique de validation globale.

## Comportement du moteur
1. L'élève coche/décoche librement (case carrée ☐/☑, style `.ex-opt.multi`).
2. Au clic sur le bouton CTA : validation globale — `allGood = true` ssi toutes les `correct:true` sont cochées ET aucune `correct:false` n'est cochée.
3. Après soumission : options en `.correct` (bonnes) ou `.wrong` (mauvaises sélectionnées), bouton désactivé, feedback animé.

## Garde-fous
- **BLOCKED** si `question` absente, `choices` vide, aucune `correct:true`, ou `cta_label` absent.
- Pas de contenu en dur dans le HTML : question, options, bouton et feedbacks proviennent tous du JSON.
- Au moins 1 option `correct:false` recommandée (sinon pas de piège — signal QA).
- Palette DS V2 : mint pour correct/signature, coral pour incorrect, violet pour CTA.
- Aucun `box-shadow rgba(0,0,0,...)` : ombres colorées uniquement.

## QA à vérifier
1. Modifier `question` dans le JSON → rendu change sans toucher au HTML.
2. `choices:[]` → BLOCKED propre.
3. Cocher toutes les bonnes réponses uniquement → `feedback_ok` + toutes en vert.
4. Cocher une mauvaise réponse → `feedback_ko` + rouge sur la mauvaise, vert sur les bonnes.
5. `init(instanceExterne)` → rendu piloté par l'instance injectée.
6. Responsive 375/768/1024 — aucun débordement.

## Source
`INDEX-300-exerciselearning-GAB-116-120-PLAYABLE.html` (stage `data-tpl="118"`, handlers `mcqmToggle` / `mcqmSubmit`).
