{
  "_": "LE MANIFEST DE L'ÉLÈVE — celui que application/index.html déclare. ⚠ NE PAS LE CONFONDRE AVEC application/moteur/manifest.json, qui est celui de la page de vérification (verifier.html) et qui ouvrirait l'application sur la page de test. Le fichier est ici, à la racine de application/, pour la même raison que sw.js : la portée d'un service worker et le scope d'un manifest se lisent depuis leur emplacement, et depuis moteur/ ils ne couvriraient pas index.html.",

  "__id": "L'IDENTITÉ, ET ELLE NE BOUGE PLUS. `id` est ce à quoi le navigateur reconnaît une application DÉJÀ installée. Le changer republie une seconde icône à côté de la première sur l'écran d'accueil de l'élève, sans supprimer l'ancienne — qui continue de pointer vers la même adresse. On l'écrit en absolu et on n'y touche pas.",
  "id": "/application/",

  "name": "fhamtha.ma — 2ᵉ bac, maths et physique-chimie",
  "short_name": "fhamtha.ma",
  "description": "Préparation au baccalauréat marocain, 2ᵉ année : mathématiques et physique-chimie, pour les filières PC, SVT et Sciences Maths. Le cours, les séries et les sujets nationaux, avec les corrigés.",

  "__lang": "⚠ UN MANIFEST FIGE UNE LANGUE, ET L'APPLICATION EN A DEUX. langue.js bascule fr ⇄ ar à l'exécution (D-ARABE-1) ; le manifest, lui, est lu UNE FOIS à l'installation et ne se relit pas quand l'élève change de langue. Servir deux manifests demanderait de savoir la langue AVANT de charger la page — on ne la sait pas. On choisit donc le manifest NEUTRE : `dir: auto` laisse le système placer le texte selon son propre contenu, et `short_name` est en caractères latins, donc identique dans les deux sens de lecture. C'est ce qui coûte le moins à celui qui bascule : l'icône ne change pas de nom sous lui.",
  "lang": "fr",
  "dir": "auto",

  "__scope": "LE SCOPE ET LE SERVICE WORKER DOIVENT S'ACCORDER. sw.js a la portée /application/ (voir sa tête de fichier). Un scope plus large ici — « / » — ferait sortir l'application installée de la portée du worker dès la page d'accueil du domaine, donc sans hors-ligne, sans que rien ne le dise. Les deux valent /application/, et c'est délibéré. ⚠ Le paquet de contenu vit HORS du scope (/design/donnees/paquets/) : ce n'est pas un problème — le scope dit quelles PAGES appartiennent à l'application, pas quelles requêtes elle a le droit de faire.",
  "scope": "./",
  "start_url": "./",

  "display": "standalone",
  "display_override": ["standalone", "minimal-ui"],
  "orientation": "any",

  "__couleurs": "Reprises de design/tokens.css, comme moteur/manifest.json : `papier` pour l'écran de démarrage, `encre` pour la barre du système. Une valeur inventée ferait clignoter un fond blanc puis crème au lancement.",
  "background_color": "#FBFAF6",
  "theme_color": "#16212B",

  "categories": ["education"],
  "prefer_related_applications": false,

  "__icones": "⚠ DU PNG, ET PAS SEULEMENT LE SVG. Les icônes de marque existent en SVG (moteur/icone.svg, moteur/icone-masque.svg) et le favicon les utilise ; mais iOS n'installe pas depuis un SVG, et un Android qui ne le rend pas retombe sur une capture d'écran de la page. Les PNG de application/marque/ sont produits DEPUIS ces SVG par application/outils/faire-images-de-marque.mjs — une seule source de dessin, deux formats. Le SVG reste en tête : un navigateur qui le comprend prend le net à toutes les tailles.",
  "icons": [
    { "src": "moteur/icone.svg?v=declic", "type": "image/svg+xml", "sizes": "any", "purpose": "any" },
    { "src": "marque/icone-192.png?v=declic", "type": "image/png", "sizes": "192x192", "purpose": "any" },
    { "src": "marque/icone-512.png?v=declic", "type": "image/png", "sizes": "512x512", "purpose": "any" },
    { "src": "moteur/icone-masque.svg?v=declic", "type": "image/svg+xml", "sizes": "any", "purpose": "maskable" },
    { "src": "marque/icone-masque-512.png?v=declic", "type": "image/png", "sizes": "512x512", "purpose": "maskable" }
  ]
}
