# GAB-103 · MemorySpacedReviewPrompt — « Invitation au rappel espacé »

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

## Pack (structure officielle par-GAB)
```
GAB-103/
  renderer.html            ← moteur rappel espacé (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` · `review_prompt_id` · `heading` · `card_count` · `primary_cta{label,action}`

Optionnels : `title`, `spr_label`, `card_count_label`, `topic`, `schedule[]{day_label,status}`, `_note_dev`.

## Ce qui vient du JSON vs HTML
- **JSON** : titre de l'invitation (`heading`), libellé badge (`spr_label`), nombre de cartes (`card_count`), sujet (`topic`), libellé et icône du bouton (`primary_cta`), timeline des étapes (`schedule`).
- **HTML** : structure de la card, cloche animée, timeline des points, bouton structurel, layout, fallback, gestion du clic (disabled + feedback).

## Archétype — MemorySpacedReviewPrompt
Écran de **déclenchement de session** dans un cycle de répétition espacée. S'affiche au moment où l'apprenant doit revoir ses cartes (J1 → J3 → J7 → J14 → J30). Pas un quiz, pas une flashcard : c'est un **appel à l'action** ancré dans la science de la mémorisation active.

## Garde-fous
- **card_count >= 1** : si aucune carte n'est due, ne pas afficher ce GAB (cas `do_not_use_when` confirmé dans la source).
- **BLOCKED** si `heading` absent, `primary_cta.label` absent, ou `card_count` non numérique.
- `schedule.status='now'` : exactement 1 item doit marquer l'étape courante pour que la timeline soit lisible.
- Le bouton CTA est désactivé après le premier clic (feedback immédiat, pas de double déclenchement).

## QA à vérifier
1. Modifier `heading`/`topic`/`card_count` → rendu change sans toucher au HTML (critère d'or).
2. `heading` absent → BLOCKED propre, card masquée.
3. `card_count` = chaîne → BLOCKED propre.
4. Clic bouton → disabled + icône ✓ + "Révision en cours — N cartes".
5. `schedule` absent/vide → timeline non rendue, reste fonctionnel.
6. Responsive 375/768/1024 — aucun débordement.

## Source
`INDEX-300-memorylearning-GAB-101-105-PLAYABLE.html` — stage `data-tpl="103"`, handler `sprStart()`, styles `.spr-*`.
