# GAB-041 · BadgeUnlockCelebration — « Célébration de badge débloqué »

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

## Pack (structure officielle par-GAB)
```
GAB-041/
  renderer.html            ← moteur célébration badge (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` · `badge_celebration_id` · `kicker` · `badge_emoji` · `title` · `body`

Optionnels : `primary_cta{label,icon,action}`, `renderer_note`, `accessibility{badge_alt,keyboard_navigable,prefers_reduced_motion}`.

## Ce qui vient du JSON vs HTML
- **JSON** : kicker, emoji du badge, nom du badge (title), corps (body), libellé + icône du bouton CTA.
- **HTML** : carte sombre dégradée, animation badge-pop, système d'étincelles colorées, layout, fallback BLOCKED.

## Archétype
Écran de **célébration pure** — un moment fort de récompense identitaire après qu'un badge a été attribué par GamificationAdapter. Ce renderer **affiche uniquement** ; il n'attribue jamais le badge.

## Garde-fous (child_safety)
- **Anti-invention** : le contenu textuel est extrait strictement du HTML source GAB-041. Aucun libellé inventé.
- **BLOCKED** si `kicker` / `title` / `body` / `badge_emoji` absents.
- **PlayKit affiche, GamificationAdapter attribue** : responsabilités strictement séparées.
- **Étincelles** : ombres colorées uniquement (jamais `rgba(0,0,0,...)` en box-shadow).

## QA à vérifier
1. Modifier `title`/`body` dans l'instance → rendu change sans toucher au HTML (critère d'or).
2. `title` absent → BLOCKED propre.
3. Bouton CTA → animation badge-pop + étincelles relancées.
4. `init(ext)` avec instance externe → rendu change correctement.
5. Responsive 375/768/1024 — aucun débordement.
6. `prefers-reduced-motion` → animations réduites à 0.01ms.

## external_refs / dependencies
- **GamificationAdapter** : composant en amont qui attribue le badge. GAB-041 reçoit le résultat et célèbre — il ne déclenche pas l'attribution.
- **GAB-040** : à utiliser pour un gain XP simple sans badge.
- **GAB-022** : à utiliser pour une réussite sans badge.

## Source
`INDEX-300-playkit-GAB-041-044-PLAYABLE.html` (stage `data-tpl="41"`, handlers `badgeReplay`, styles `.badge-card`/`.badge-medal`/`.badge-kicker`).
