# GAB-064 · StoryObjectiveCard — « Carte objectif »

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

## Pack (structure officielle par-GAB)
```
GAB-064/
  renderer.html            ← moteur carte objectif (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` · `objective_card_id` · `title` · `objective`

Optionnels : `icon` (emoji, défaut 🎯) · `episode_label` (surtitre) · `criteria[]` (liste cochable) · `primary_cta{label,action}`.

## Ce qui vient du JSON vs HTML
- **JSON** : icône, surtitre, titre, texte objectif, critères, libellé du bouton CTA.
- **HTML** : layout de la carte, icône structurelle, zone critères cochables, bouton CTA, feedback panel.

## Archétype
Carte non-interactive de mise en contexte : l'élève voit ce qu'il doit réussir avant ou pendant l'épisode. Les critères sont cochables librement (auto-évaluation). Le CTA déclenche la suite de l'épisode.

## Garde-fous (child_safety)
- **BLOCKED** si `objective_card_id`, `title` ou `objective` absent.
- `criteria` peut être vide — jamais bloquant.
- Le texte `objective` doit être pédagogiquement mesurable (critère de conception, pas vérifié par le moteur).

## QA à vérifier
1. Modifier `objective` / `criteria` → rendu change sans toucher au HTML.
2. `objective absent` → BLOCKED propre.
3. Clic sur case à cocher → toggle visuel + aria-checked.
4. Clic CTA → feedback affiché.
5. Tous critères cochés + CTA → message de validation dédié.
6. Responsive 375 / 768 / 1024.

## Source
`INDEX-300-storylearning-GAB-060-064-PLAYABLE.html` (stage `data-tpl="64"`, section `<!-- GAB-064 -->`).
Slots déclarés dans la source : `title` (req), `objective` (req), `criteria` (opt), `icon` (opt).
