# GAB-095 · VisualPrintableSheetLayout — « Fiche imprimable »

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

## Pack (structure officielle par-GAB)
```
GAB-095/
  renderer.html            ← moteur fiche imprimable (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` · `sheet_id` · `title` · `blocks[]{icon, heading, content, full_width}`
Optionnels : `toolbar_label`, `print_btn_label`.

## Ce qui vient du JSON vs HTML
- **JSON** : titre de la fiche, libellé de la barre outil, libellé du bouton Imprimer, liste des blocs (icône, titre, contenu, pleine largeur).
- **HTML** : grille de blocs, bouton structurel print, layout responsive, media query `@print`, fallback BLOCKED.

## Garde-fous (child_safety)
- **BLOCKED** si `blocks` absent/vide, `title` absent, ou `sheet_id` absent.
- **Anti-invention** : aucun contenu pédagogique en dur dans le HTML — tout vient de l'instance JSON.
- **Print-safe** : media query `@print` isole la fiche `.psheet` à l'impression (le reste masqué).

## QA à vérifier
1. Modifier un bloc `content` → rendu change sans toucher au HTML (critère d'or).
2. `blocks:[]` → BLOCKED propre.
3. `full_width:true` sur un bloc → `grid-column:1/-1` effectif.
4. Bouton Imprimer → `window.print()` déclenché.
5. Responsive 375/768/1024 — pas de débordement horizontal.
6. Instance externe injectée via `ENGINE.init(ext)` → fiche change.

## Source
`INDEX-300-visuallearning-GAB-091-095-PLAYABLE.html` (stage `data-tpl="95"`, bloc `<!-- GAB-095 -->`).
