# GAB-066 · StoryNarrativeBoss — « Défi narratif (boss) »

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

## Pack (structure officielle par-GAB)
```
GAB-066/
  renderer.html            ← moteur défi narratif boss (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` · `boss_id` · `kick_label` · `title` · `question` · `choices[]{id, label, is_correct, feedback_win|feedback_lose}` · `primary_cta{label, action}`
Optionnels : `boss_emoji`, `_note_dev`.

## Ce qui vient du JSON vs HTML
- **JSON** : kick_label, titre de la boss-card, question, libellés des choix, feedbacks win/lose, emoji boss, libellé du bouton CTA.
- **HTML** : fond sombre dramatique, banner boss (avatar + titres), zone question, liste des boutons, feedback zone, bouton CTA structurel, layout, animation boss-pulse.

## Garde-fous (child_safety)
- **One-shot** : une fois qu'un choix est sélectionné, tous les boutons sont désactivés. Pas de rejeu possible sans recharger (intention pédagogique : moment fort de consolidation).
- **Révélation bonne réponse** : si un choix incorrect est sélectionné, la bonne réponse est toujours révélée (class `win`) pour que l'élève comprenne.
- **BLOCKED** si `choices` est absent ou vide, si aucun choix n'est `is_correct:true`, si `question` ou `boss_id` manquent.
- **Jamais d'invention** : tout le contenu (question, choix, feedbacks) vient de l'instance JSON.

## QA à vérifier
1. Modifier `question`/`choices` → rendu change sans toucher au HTML (critère d'or).
2. `choices:[]` → BLOCKED propre.
3. Sélection choix correct → feedback_win + class win + CTA visible.
4. Sélection choix incorrect → feedback_lose + class lose + bonne réponse révélée.
5. Deux clics → second clic ignoré (boutons disabled après premier choix).
6. Responsive 375/768/1024.

## Source
`INDEX-300-storylearning-GAB-065-069-PLAYABLE.html` (stage `data-tpl="66"`, handler `bossPick()`).

## external_refs / dependencies
Ce GAB est V1_X (optionnel enrichi). Il s'insère dans un parcours StoryLearning typiquement après :
- **GAB-065** (StoryCheckpoint) — point de contrôle avant le défi.
- Suivi de **GAB-067** (StoryChapterEnd) — fin de chapitre après validation.
