# GAB-293 · OralLearningPracticeTimer — « Timer non-stressant pour s'entraîner »

**Archétype / renderer_key :** `text_cta` (cartographie) · **module :** EdTechOralLearning
**Critère validé :** changer le JSON change le timer (durée, mode, politiques, textes) sans modifier le HTML. ✅ check.py 12/12.

## Pack (structure officielle par-GAB)
```
GAB-293/
  renderer.html            ← moteur timer oral (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` · `timer_id` · `practice_ref` · `duration_target` (secondes) · `timer_mode` · `completion_policy`

Optionnels : `title`, `subtitle`, `mode_label`, `target_label`, `pause_allowed`, `warning_marks[]{at_seconds,label,style}`, `grace_period`, `grace_items[]{label,detail}`, `completion_policy_title`, `completion_policy_text`, `reason_title`, `reason_text`, `primary_cta{label,action,duration_seconds,timer_label}`, `stress_support_ref`, `accessibility_adjustment`, `source_metadata`.

## Ce qui vient du JSON vs HTML
- **JSON** : durée cible, mode affiché, marques temporelles, textes policy anti-pénalité, items grace, raison pédagogique, libellé du bouton, stress_support_ref.
- **HTML** : barre de progression, affichage chrono, contrôles (pause/restart/done), layout, logique setInterval.

## Garde-fous (child_safety / accessibility)
- **BLOCKED** si `timer_id` absent / `duration_target` absent ou ≤ 0 / `timer_mode` absent.
- **Mode non-stressant** : pause libre sans pénalité affichée, grâce configurable, marque douce (pas d'alarme).
- **prefers_reduced_motion** : transitions réduites via media query globale.
- **Pénalité** : doctrine anti-pénalité portée par l'instance (`completion_policy`), jamais câblée en dur.

## QA à vérifier
1. Modifier `duration_target` → affichage et barre changent sans toucher au HTML (critère d'or).
2. `timer_id` absent → BLOCKED propre dans le panel.
3. Bouton Pause → chrono se fige, libellé bascule « Reprendre ».
4. Bouton ✓ J'ai fini → affiche le temps utilisé.
5. `warning_marks` injectés → repère affiché sur la barre, couleur gold au dépassement.
6. Responsive 375/768/1024 — 0 débordement horizontal.

## Source
`INDEX-300-orallearning-GAB-291-295-PLAYABLE.html` (stage `data-tpl="293"`, handlers `gabTimer` / `gabReveal`).
