feat(session-1): socle SvelteKit et encyclopédie /zerbaj/ prérendue

SvelteKit 2 + Svelte 5 runes + TS strict, adapter-static en prérendu
intégral, trailingSlash always, paths.relative false.

Mesures de la porte de sortie
- 56 pages HTML prérendues (13 fiches × 3 langues + pages de service)
- 59 Ko de JS gzip (budget : 170) · build total 1,4 Mo (budget : 2 Mo)
- 0 chargement tiers, vérifié par grep du build
- fiche lisible sans JS : 1694 caractères de texte rendu
- npm run check : 248 fichiers, 0 erreur, 0 warning
- 0 erreur console au chargement
Lighthouse non exécuté : porte encore ouverte, à vérifier avant la S6.

Charte OKI
Tokens partagés, thème sombre par défaut, Archivo et Inter self-hébergées
(124 Ko de woff2), flag-bar à segments francs, bouton à balayage or,
gate prefers-reduced-motion unique. CSP stricte en .htaccess et _headers,
404 statique autonome, PWA avec registerSW à chemin absolu (playbook 2.9).

L'interface kréyòl n'est pas écrite par l'agent
Le catalogue gcf ne contient que les termes venant des documents du
porteur — 10 chaînes sur 132. Le reste vaut null et se replie sur le
français ; check:i18n produit la liste des 122 phrases à traduire, par
écran. <html lang> annonce la langue réellement écrite : fr tant que la
couverture reste sous 60 %, avec les fragments kréyòl marqués un par un.
Des tournures kréyòl que j'avais inventées ont été retirées.

Corrections en cours de build
- vite-plugin-pwa/sveltekit n'existe pas sans @vite-pwa/sveltekit :
  VitePWA en direct, comme le prescrivait déjà le playbook.
- @sveltejs/vite-plugin-svelte v7 n'exporte plus sveltekit : import
  depuis @sveltejs/kit/vite, vérifié sur les exports réels.
- Le sélecteur de langue fabriquait /fr/offline/, page inexistante.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
OKI
2026-07-27 11:44:21 -04:00
co-authored by Claude Opus 5
parent 8cba5adfa5
commit ccad7177b3
58 changed files with 9946 additions and 3 deletions
+99
View File
@@ -0,0 +1,99 @@
# 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.
### `<html lang>` 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.