{
  "contract_version": "gab_015_contract_v1",
  "gab_id": "GAB-015",
  "canonical_name": "SessionPreviewMode",
  "module_owner": "EdTechPlayEngine",
  "renderer_key": "text_cta",
  "required_fields": [
    "gab_id",
    "preview_instance_id",
    "preview_label",
    "steps_overview",
    "note_tracking_off",
    "note_tracking_on"
  ],
  "optional_fields": [
    "tracking_enabled",
    "accessibility",
    "child_safety"
  ],
  "field_types": {
    "preview_label": "string — titre affiché dans la bannière PREVIEW",
    "tracking_enabled": "boolean — état initial du toggle (défaut false recommandé)",
    "note_tracking_off": "string — message affiché quand tracking=false",
    "note_tracking_on": "string — message affiché quand tracking=true (alerte visuelle)",
    "steps_overview": "array<{n:number, title:string, module_ref:string}> — liste ordonnée des étapes de la session"
  },
  "constraints": [
    "steps_overview doit contenir au moins 1 étape.",
    "tracking_enabled doit être false par défaut (mode preview = pas de pollution stats).",
    "note_tracking_on doit porter une mise en garde visible (⚠️ ou équivalent).",
    "Le rendu bannière PREVIEW est structurel (HTML) ; le libellé vient de preview_label."
  ],
  "blocked_conditions": [
    "preview_instance_id absent (BLOCKED)",
    "preview_label absent (BLOCKED)",
    "steps_overview vide ou absent (BLOCKED)"
  ],
  "accessibility": [
    "keyboard_navigable",
    "focus_visible",
    "prefers_reduced_motion"
  ],
  "qa_cases": [
    { "case": "instance conforme", "expected": "rendu complet, bannière PREVIEW, liste étapes, toggle OFF, note tracking off" },
    { "case": "preview_label absent", "expected": "BLOCKED avec message explicite" },
    { "case": "steps_overview vide []", "expected": "BLOCKED avec message explicite" },
    { "case": "toggle activé", "expected": "note change vers note_tracking_on, couleur alerte gold" },
    { "case": "toggle désactivé", "expected": "note revient à note_tracking_off, couleur muted" },
    { "case": "instance externe injectée via init(ext)", "expected": "le rendu change sans modifier le HTML" },
    { "case": "responsive 375/768/1024", "expected": "aucun débordement horizontal" }
  ],
  "traceability": {
    "derived_from_core_gab": "GAB-015",
    "note": "Ce schema VALIDE l'instance. Le contrat pédagogique complet (input_contract/validation_logic/feedback_scoring_logic) vit dans le CORE-GAB officiel, pas ici (évite la duplication)."
  }
}
