# GAB-174 · AudioSpeedControl — « Contrôle de vitesse »

**Archétype / renderer_key :** `media_viewer` (cartographie) · **module :** EdTechAudioLearning
**Critère validé :** changer le JSON change les options de vitesse sans modifier le HTML. check.py 12/12.

> **renderer_key à concevoir (pas de moteur kit)** — `media_viewer` n'a pas de moteur kit de référence dans le lot actuel. Le renderer est dérivé directement de l'écran source (stage `data-tpl="174"` du fichier PLAYABLE).

## Pack (structure officielle par-GAB)
```
GAB-174/
  renderer.html            ← moteur contrôle de vitesse (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

**Composant transversal embarquable** : le sélecteur de vitesse audio peut s'insérer dans d'autres gabarits du module EdTechAudioLearning (GAB-166, GAB-168, GAB-170, GAB-171). Cohérence d'expérience garantie entre les gabarits hôtes.

**3 vitesses pédagogiques** extraites du source :
| Vitesse | Icône | Rate | Conseil contextuel |
|---------|-------|------|--------------------|
| Lent | 🐢 | 0.7× | Découverte · concentration |
| Normal | 🚶 | 1.0× | Lecture standard recommandée *(défaut)* |
| Rapide | 🏃 | 1.4× | Révision · mémorisation |

## Champs requis (instance, à plat)
`gab_id` · `speed_control_id` · `title` · `items` · `preview_sentence` · `default_rate`

Optionnels : `recommendation`, `accessibility{preview_btn_label,grid_role,grid_aria_label}`, `child_safety{speed_min,speed_max,note}`.

## Ce qui vient du JSON vs HTML
- **JSON** : chaque option de vitesse (icône, libellé, rate, conseil), phrase d'aperçu, recommandation, bornes child_safety, labels accessibilité.
- **HTML** : grille de sélection, bouton aperçu (SpeechSynthesis), layout, animations.

## Garde-fous (child_safety)
- Vitesses extrêmes (`>2×` ou `<0.5×`) interdites : le moteur filtre les items hors bornes `child_safety.speed_min` / `child_safety.speed_max` avant le rendu.
- Un seul item `is_default:true` autorisé ; le premier item est utilisé en fallback si aucun.
- `items` vide ou absent → BLOCKED.

## external_refs / dependencies
- **GAB-166, GAB-168, GAB-170, GAB-171** (EdTechAudioLearning) : gabarits hôtes dans lesquels ce composant peut être embarqué.
- **GAB-154** (EdTechTimerLearning) : chrono de jeu — ne pas utiliser GAB-174 comme remplacement.
- **SpeechSynthesis API** : le bouton aperçu utilise `window.speechSynthesis` (browser-native). En l'absence de l'API, le bouton reste actif sans effet sonore.

## QA à vérifier
1. Modifier `items[].tip` → texte du conseil change sans toucher au HTML.
2. `items: []` → BLOCKED propre.
3. `preview_sentence` absent → BLOCKED propre.
4. Clic "Lent" → label aperçu = "0.7×", `aria-checked=true` sur l'item.
5. Bouton ▶ → SpeechSynthesis joue la `preview_sentence` au rate actif.
6. Responsive 375/768/1024 — grille sans débordement.
7. `child_safety.speed_max:1.0` → item "Rapide" (1.4×) filtré, non rendu.

## Source
`INDEX-300-audiolearning-GAB-171-175-PLAYABLE.html` (stage `data-tpl="174"`, handlers `scPick` / `scPreview`).
