# GAB-110 · MemoryWeakCardsReview — « Révision des cartes faibles »

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

## Pack (structure officielle par-GAB)
```
GAB-110/
  renderer.html            ← moteur révision cartes faibles (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` · `weak_cards_review_id` · `title` · `body` · `items[]{icon,label,fail_dots,total_dots}` · `primary_cta{icon,label,label_done,action}`

Optionnels : `accessibility{keyboard_navigable,focus_visible,prefers_reduced_motion}`

## Ce qui vient du JSON vs HTML
- **JSON** : titre de la section, sous-titre motivationnel, liste des cartes faibles (icône + label + nombre de points d'échec), libellé et état final du bouton CTA.
- **HTML** : structure de la carte, barre de points (dots), bouton structurel, layout, palette DS V2, fallback BLOCKED.

## Archétype
GAB-110 est une carte de **révision ciblée** : elle présente uniquement les cartes mal rappelées lors d'une session précédente. Elle s'oppose à GAB-108 (paquet complet) et GAB-103 (rappel espacé global). Elle clôt un workflow de mémoire (après GAB-109 fin de session) ou démarre une sous-session ciblée.

## Garde-fous (child_safety)
- **Items non vides obligatoires** : la vue n'a de sens que si des cartes faibles existent ; `items[]` vide → BLOCKED.
- **CTA terminal** : après le premier clic, le bouton est désactivé (opacité 0.7, pointer-events none), état visuel irréversible pour éviter les doubles lancements.
- **fail_dots ≤ total_dots** : la barre ne peut pas dépasser le total.

## QA à vérifier
1. Modifier un `label` dans `items` → rendu change sans toucher au HTML (critère d'or).
2. `items:[]` → BLOCKED propre.
3. `title` absent → BLOCKED propre.
4. `primary_cta` absent → BLOCKED propre.
5. Clic CTA → label devient `label_done`, bouton désactivé.
6. Instance externe injectée via `ENGINE.init(ext)` → rendu change sans modifier le HTML.
7. Responsive 375 / 768 / 1024.

## Source
`INDEX-300-memorylearning-GAB-106-110-PLAYABLE.html` (stage `data-tpl="110"`, handler `wkcStart()`).
