# Session 1 — Socle **Date :** 2026-07-27 · **Livrable :** l'encyclopédie `/zerbaj/`, prérendue et trilingue. ## Mesures de la porte de sortie | Critère | Cible | Mesuré | |---|---|---| | Fiches en ligne | 13, une page prérendue chacune | **56 pages HTML** (13 fiches × 3 langues + 17 pages de service) ✅ | | JS initial gzip | ≤ 170 Ko | **59 Ko** ✅ | | Poids total du build | ≤ 2 Mo | **1,4 Mo** ✅ | | Requêtes vers un domaine tiers | 0 | **0**, vérifié par grep du build ✅ | | Contenu lisible sans JavaScript | intégral | **1 694 caractères** de texte rendu sur une fiche, sans exécuter un octet de JS ✅ | | `npm run check` | 0 erreur, 0 warning | **248 fichiers, 0/0** ✅ | | `npm run build` | vert | vert ✅ | | Erreurs console au chargement | 0 | **0** ✅ | | Chaque fiche affiche ce qui lui manque | 13/13 | ✅ | | Questions kréyòl affichées | 4 | ✅ | Lighthouse n'a pas été exécuté : il demande un navigateur en conditions réelles que je ne peux pas piloter ici. **La porte « Lighthouse ≥ 90/95/95/95 » reste donc non vérifiée** et doit l'être avant la session 6. Les budgets qui la déterminent — JS, poids, absence de tiers, contenu SSR — sont eux mesurés et tenus. ## Ce qui a été construit SvelteKit 2 + Svelte 5 en runes, TypeScript strict, `adapter-static` en prérendu intégral, `trailingSlash: 'always'`, `paths.relative: false` (playbook §5b.5). Tokens de la charte OKI dans un fichier partagé, thème sombre par défaut et clair en opt-in, polices Archivo et Inter self-hébergées (**124 Ko** de woff2 latin), flag-bar et flag chip, bouton à balayage or, gate `prefers-reduced-motion` unique. i18n par dossiers sans middleware : `/` en kréyòl, `/fr/`, `/en/`. Route optionnelle `[[locale=locale]]` avec matcher, ce qui évite de tripler chaque page. PWA : `VitePWA` en direct plutôt que `@vite-pwa/sveltekit`, enregistrement par fichier statique à chemin absolu (playbook §2.9), page hors-ligne designée, manifest, icônes 192 / 512 / maskable générées depuis le SVG (**1,8 à 6,3 Ko** chacune). CSP stricte en deux formats — `.htaccess` et `_headers` —, 404 statique autonome, sitemap généré depuis le build réel avec alternates hreflang (54 URLs sur 18 contenus). ## Trois décisions prises en cours de route ### L'interface kréyòl ne peut pas être écrite par un agent Le projet pose le kréyòl comme langue principale, et l'ADR 0005 m'interdit d'en écrire. Résolu ainsi : le catalogue `gcf` ne contient que les termes venant des documents du porteur — `KI FWI SA YÉ ?`, `Zerbaj`, `Rekonèt`, `Kaché`, `Sézon`, `Ranmasé`, `Pa touché`, `Lakou` — soit **10 chaînes sur 132**. Tout le reste vaut `null` et se replie sur le français. `npm run check:i18n` produit la liste des **122 phrases à traduire**, par écran, avec le français en regard. C'est une tâche de participation, pas une dette technique. J'avais d'ailleurs commencé par écrire du kréyòl de mon cru dans le catalogue français (`Pa ni ayen la`, `Ba on koudmen`, `Jwé`, `Pa ni rézo`). Retiré : ces tournures étaient de moi, pas de la langue. ### `` annonce la langue réellement écrite Poser `lang="gcf"` sur une page dont le texte est français ferait lire ce français avec la phonétique kréyòl par un lecteur d'écran. `langDocument()` renvoie donc `fr` tant que la couverture du catalogue reste sous 60 %, et les fragments réellement kréyòl — noms de fruits, noms de modes, titre du site — portent `lang="gcf"` individuellement. La fonction basculera d'elle-même quand la traduction dépassera le seuil. Il n'y a rien à changer dans le code : il faut traduire. Un bandeau discret le dit sur chaque page en kréyòl, plutôt que de laisser croire. ### Les modes de jeu ne sont pas annoncés comme cliquables `/je/` liste les cinq modes, aucun n'est lié : les routes n'existent qu'en session 2 et 4. Le prerender en mode strict fait échouer le build sur un lien mort — c'est le comportement voulu, et il a effectivement attrapé le problème. Le mode Rekonèt affiche en plus son blocage réel : il demande des photographies validées, et il n'y en a aucune. Le message le dit sans détour — « ce n'est pas un bug : personne ne les a encore versées » — et renvoie vers la page de participation. ## Deux erreurs corrigées pendant le build `vite-plugin-pwa/sveltekit` n'existe pas sans le paquet `@vite-pwa/sveltekit` : le playbook prescrivait déjà `VitePWA` en direct, je m'y suis aligné plutôt que d'ajouter une dépendance. `@sveltejs/vite-plugin-svelte` v7 n'exporte plus `sveltekit` — l'import vient de `@sveltejs/kit/vite`. Vérifié sur les exports réels du paquet, pas supposé. Et un vrai défaut de conception : le sélecteur de langue fabriquait `/fr/offline/` pour une page qui n'existe qu'en un exemplaire. `cheminAlterne()` renvoie désormais la racine de la langue cible sur les routes non localisées. ## Reste à faire avant la session 6 - Lighthouse mobile sur l'accueil et sur une fiche. - Vérification manuelle de `prefers-reduced-motion` et de la navigation clavier. - `og-image` et icônes sont des aplats graphiques sans texte : à remplacer si le porteur veut une image sociale plus travaillée.