# GAB-129 · ExerciseResultSummary — « Résumé de résultats »

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

## Pack (structure officielle par-GAB)
```
GAB-129/
  renderer.html            ← moteur résumé de résultats (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` · `result_summary_id` · `title` · `score_value` · `score_max` · `result_items[]{status,label}` · `primary_cta{label,action}`

Optionnels : `emoji`, `retry_cta{label,action}`, `feedback_retry`, `feedback_next`.

## Ce qui vient du JSON vs HTML
- **JSON** : emoji, titre, score (valeur + max), texte de synthèse, liste d'items (statut + libellé), libellés des boutons, textes de feedback post-clic.
- **HTML** : anneau SVG animé, grille d'items colorés (good/bad), layout carte centrée, logic de calcul stroke-dashoffset.

## Archétype
Carte de bilan post-exercice à **anneau de score** (SVG stroke-dashoffset calculé depuis `score_value/score_max`), liste de points réussis/à revoir et deux CTAs d'action :
- **retry_cta** → déclenche un feedback gold (mode correction)
- **primary_cta** → déclenche un feedback mint et désactive le bouton (passage à la suite)

La couleur de l'arc change selon le score : ≥ 80 % → mint, ≥ 50 % → gold, < 50 % → coral.

## Garde-fous (child_safety)
- **Anti-invention** : aucun texte pédagogique n'est codé en dur dans le HTML ; tout texte visible provient de l'instance JSON.
- **BLOCKED** si `title`, `score_value`, `score_max`, `result_items` (vide) ou `primary_cta` absents.
- `score_value` est clamped entre 0 et `score_max` pour éviter un anneau cassé.

## QA à vérifier
1. Modifier `summary` / `result_items` → rendu change sans toucher au HTML (critère d'or).
2. `result_items:[]` → BLOCKED propre.
3. `primary_cta` absent → BLOCKED propre.
4. `score_value = score_max` → anneau plein (mint).
5. `score_value = 0` → anneau vide (coral).
6. Clic « Refaire les erreurs » → feedback gold.
7. Clic « Suite » → feedback mint + bouton désactivé.
8. Responsive 375/768/1024.

## Source
`INDEX-300-exerciselearning-GAB-126-130-PLAYABLE.html` (stage `data-tpl="129"`, handlers `rsRetry`, `rsNext`).

## external_refs / dependencies
- **GAB-021** : fin de session moteur (ne pas utiliser à la place de ce GAB).
- **GAB-109** : fin de session Memory (idem).
- **GAB-059** : fin d'épisode Story (idem).
- **GAB-130** : ExerciseRetryPrompt — utilisé lorsque le score est bas et qu'on veut une invitation bienveillante à réessayer (complémentaire à ce GAB).
