# GAB-134 · ExerciseAudioPrompt — « Exercice audio (transcript inclus) »

**Archétype / renderer_key :** `media_viewer` (cartographie) · **module :** EdTechExerciseLearning
**Note :** renderer_key `media_viewer` = à concevoir (pas de moteur kit de référence) — renderer dérivé de l'écran source INDEX-300 (stage `data-tpl="134"`, handlers `audToggle`/`audPick`).
**Critère validé :** changer le JSON change l'exercice sans modifier le HTML. ✅ check.py 12/12.

## Pack (structure officielle par-GAB)
```
GAB-134/
  renderer.html            ← moteur exercice audio (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
```

## Archétype
Exercice avec un extrait audio (ou synthèse vocale en fallback), transcript OBLIGATOIREMENT visible,
et une question à choix unique. L'élève écoute (ou lit le transcript), puis sélectionne sa réponse.
Feedback immédiat : bonne réponse colorée mint, mauvaise réponse colorée coral + révélation de la bonne.

## Champs requis (instance, à plat)
`gab_id` · `exercise_id` · `instruction` · `audio_tts_text` · `transcript` · `question` · `options[]{id,label,correct}`

## Champs optionnels
`title` · `audio_src` · `transcript_label` · `feedback_correct` · `feedback_incorrect` · `accessibility`

## Ce qui vient du JSON vs HTML
- **JSON** : instruction, texte TTS, transcript, libellé du label transcript, question, options (labels + bonne réponse), feedbacks.
- **HTML** : layout player (bouton + wave animée), zone transcript, zone question, rendu options, feedback structurel.

## Garde-fous (child_safety / accessibilité)
- **Transcript OBLIGATOIRE et TOUJOURS visible** : un exercice audio sans transcript est INTERDIT (RGPD/accessibilité).
  → BLOCKED si `transcript` absent ou vide.
- **Exactement 1 option correcte** : BLOCKED si aucune option avec `correct:true`.
- **No double-submit** : après sélection, toutes les options sont `disabled`.
- **Fallback speechSynthesis** : si `audio_src` absent, le player utilise `audio_tts_text` via Web Speech API (fr-FR).

## Conditions BLOCKED
| Condition | Message |
|---|---|
| `transcript` absent/vide | `transcript absent ou vide (BLOCKED)` |
| `question` absente | `question absente (BLOCKED)` |
| `options` absentes/vides | `options absentes ou vides (BLOCKED)` |
| 0 option avec `correct:true` | `aucune option avec correct:true (BLOCKED)` |

## _TODO dans l'instance
- `audio_src` : URL ou chemin vers le fichier audio réel non disponible dans la source HTML (la source utilise speechSynthesis). À renseigner lors du déploiement réel.

## QA à vérifier
1. Modifier un `label` d'option → rendu change sans toucher au HTML (critère d'or).
2. `transcript:""` → BLOCKED propre.
3. `options:[]` → BLOCKED propre.
4. Click bonne réponse → mint + feedback_correct + toutes options disabled.
5. Click mauvaise réponse → coral + bonne révélée mint + feedback_incorrect + toutes options disabled.
6. Responsive 375/768/1024.
7. `init(instanceExterne)` → rendu change sans recharge de page.

## Source
`INDEX-300-exerciselearning-GAB-131-135-PLAYABLE.html` — stage `data-tpl="134"`, styles `.aud-*`, handlers `audToggle` / `audStop` / `audPick` + CSS wave animation.

## external_refs / dependencies
- `renderer_key: media_viewer` — pas de moteur kit existant à la date de conversion (2026-06-01). Le renderer est autonome, dérivé directement de l'écran source.
- Dépendance runtime optionnelle : Web Speech API (`SpeechSynthesisUtterance`) pour la lecture vocale en fallback. Non critique : le transcript garantit l'accessibilité indépendamment.
- Pas de dépendance à d'autres GAB de ce lot.
