diff --git a/.gitignore b/.gitignore index ae5f291..427b6de 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,14 @@ node_modules/ .svelte-kit/ build/ _site/ +# Documents de travail locaux (charte, recettes, briefs, guides agents) +AGENTS.md +charte-oki-design-system.md +prompt-kimi-cli-transformation-oki.md +recette-sveltekit-15-sites-awwwards.md +recette-sveltekit-playbook-agent.md +svelte-5_code_writer.md +svelte_core_bestpractices.md .DS_Store *.log .env diff --git a/AGENTS.md b/AGENTS.md deleted file mode 100644 index 4711cd0..0000000 --- a/AGENTS.md +++ /dev/null @@ -1,23 +0,0 @@ -You are able to use the Svelte MCP server, where you have access to comprehensive Svelte 5 and SvelteKit documentation. Here's how to use the available tools effectively: - -## Available Svelte MCP Tools: - -### 1. list-sections - -Use this FIRST to discover all available documentation sections. Returns a structured list with titles, use_cases, and paths. -When asked about Svelte or SvelteKit topics, ALWAYS use this tool at the start of the chat to find relevant sections. - -### 2. get-documentation - -Retrieves full documentation content for specific sections. Accepts single or multiple sections. -After calling the list-sections tool, you MUST analyze the returned documentation sections (especially the use_cases field) and then use the get-documentation tool to fetch ALL documentation sections that are relevant for the user's task. - -### 3. svelte-autofixer - -Analyzes Svelte code and returns issues and suggestions. -You MUST use this tool whenever writing Svelte code before sending it to the user. Keep calling it until no issues or suggestions are returned. - -### 4. playground-link - -Generates a Svelte Playground link with the provided code. -After completing the code, ask the user if they want a playground link. Only call this tool after user confirmation and NEVER if code was written to files in their project. diff --git a/README.md b/README.md index 0184b18..d689c98 100644 --- a/README.md +++ b/README.md @@ -63,12 +63,14 @@ Headers de sécurité (CSP stricte `default-src 'self'`, HSTS, `X-Frame-Options: ## Charte et documents de référence +Ces documents de travail sont **locaux** (non versionnés, voir `.gitignore`) : + - **`charte-oki-design-system.md`** — marque canonique : couleurs, typographie, motion (cadences gwoka), iconographie SVG (zéro emoji en interface), voix. Prime pour tout ce qui est marque. - **`recette-sveltekit-playbook-agent.md`** — méthode technique : principes, budgets performance, règles motion, DoD (sa version longue : `recette-sveltekit-15-sites-awwwards.md`). - **`AGENTS.md`** — point d'entrée pour les agents de code : impose l'usage de l'outillage Svelte MCP. - **`svelte-5_code_writer.md`** — commandes `@sveltejs/mcp` (doc Svelte 5 + `svelte-autofixer`, à passer sur tout composant modifié). - **`svelte_core_bestpractices.md`** — conventions runes Svelte 5 ($state/$derived/$effect, events, snippets, styles). -- **`DEPLOY.md`** — déploiement o2switch (Apache) et Cloudflare Pages. +- **`DEPLOY.md`** — déploiement o2switch (Apache) et Cloudflare Pages (versionné, lui). Thème sombre par défaut, thème clair en opt-in persisté (`localStorage['oki-theme']`). diff --git a/charte-oki-design-system.md b/charte-oki-design-system.md deleted file mode 100644 index 2b404d0..0000000 --- a/charte-oki-design-system.md +++ /dev/null @@ -1,213 +0,0 @@ -# CHARTE OKI — DESIGN SYSTEM & HARMONISATION MULTI-PROJETS -### ORGANISATION KA INTERNATIONALE · appliquer la recette SvelteKit avec la marque OKI - -> **Nature de ce document :** référence de marque opérationnelle, destinée aux humains et aux agents de code. Il consolide le `BRAND.md` existant (valeurs mesurées sur o-k-i.net, juillet 2026 — **source canonique** pour couleurs, typo, voix) et y ajoute les tokens prêts à l'emploi, les règles de motion, l'iconographie SVG, et la matrice d'application projet par projet. **En cas de conflit : ce document prime sur la recette générique pour tout ce qui touche à la marque ; la recette prime pour tout ce qui touche à la méthode technique.** - ---- - -## 1. IDENTITÉ EN UNE PHRASE - -Un studio web militant caribéen dont la marque est un **drapeau panafricain — noir, or, vert, rouge — posé sur un fond presque noir, en capitales Archivo**. La marque est afrofuturiste caribéenne : un drapeau, pas une charte corporate. - -Trois conséquences non négociables : -1. **Le thème sombre est l'identité par défaut** ; le clair est une variante opt-in (`html.light-theme`) qui assombrit les accents pour rester WCAG AA. -2. **L'or porte toute l'interaction** — c'est la seule couleur d'action. -3. **Angles nets partout** — aucune forme organique, aucune bulle très arrondie. - ---- - -## 2. TOKENS — PRÊTS À L'EMPLOI - -### 2.1 Couleurs (mesurées sur le site réel) - -```css -:root { - /* ── Noyau (thème sombre = défaut) ── */ - --noir-oki: #0D0D0D; /* background */ - --noir-profond: #1A0F1A; /* surface */ - --blanc-creme: #FFF8E7; /* foreground */ - --line: rgba(255, 255, 255, 0.10); /* filets — jamais de gris plein */ - --or-oki: #FDB813; /* accent : SEULE couleur d'action */ - --rouge-oki: #FF1654; /* signal, ponctuation — jamais un lien/bouton */ - /* ── Étendue (parcimonie : décorations et sémantique) ── */ - --vert-oki: #00D66C; /* succès, validation, dons mensuels */ - --turquoise-caraibes: #00CED1; - --jaune-soleil: #FFD700; - --orange-flamme: #FF6B35; - --violet-nuit: #6B2D5C; - --bleu-ocean: #0077BE; - --or-clair: #FFE066; /* survol des boutons */ - --gris-sombre: #2D1B2E; - /* ── Sémantique dérivée ── */ - --muted: color-mix(in srgb, var(--blanc-creme) 70%, transparent); - --card-bg: rgba(255, 255, 255, 0.03); -} -``` - -Règles d'usage (mesurées, à faire respecter) : -- Texte secondaire = blanc crème à 70–85 % d'opacité, **pas** une couleur dédiée. -- Filets = blanc à 10 %, jamais de gris plein. -- Rouge = signaler · Vert = valider · Or = agir. Ne jamais permuter ces rôles. - -### 2.2 Typographie - -```css -:root { - --font-display: 'Archivo', 'Arial Black', sans-serif; /* 600–900, TITRES + BOUTONS */ - --font-body: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; /* 400–800 */ -} -``` -- Titres h1–h4 : Archivo, **MAJUSCULES**, `letter-spacing: -0.01em`. -- Boutons : Archivo 700, uppercase, `letter-spacing: 0.03em`, bordure 2 px. -- Corps : Inter, `line-height: 1.5`. Graisses minimales : 400 body / 600 display (lisibilité écrans bas de gamme). -- **Self-hébergement obligatoire** : woff2 dans `fonts/` + `fonts/fonts.css`, `font-display: swap`. Aucun appel Google Fonts (contradiction avec la doctrine souveraineté — bug en cours de correction sur o-k-i.net). - -### 2.3 Formes, espacements, layout - -```css -:root { - --radius-sm: 3px; /* boutons, tags, badges */ - --radius-md: 6px; /* cartes — jamais plus */ - --border-card: 1px solid var(--line); - --border-btn: 2px solid var(--or-oki); - --space-1: 0.75rem; --space-2: 1rem; --space-3: 1.5rem; --space-4: 2rem; --space-5: 4rem; - --container: 1200px; -} -``` -- Sections : `padding: var(--space-5) var(--space-4)` · Grille : `repeat(auto-fit, minmax(300px, 1fr))`. -- **Carte OKI canonique** : fond blanc 3 %, liseré gauche 4 px d'accent (vert ou or), survol `translateY(-2px à -4px)` + bordure d'accent. -- **Tag OKI canonique** : fond or 8 % + bordure or 1 px, rayon 3 px. - -### 2.4 La flag-bar — signature n°1 - -Bandeau **6 px, 4 segments francs** : noir 0–25 % · or 25–50 % · vert 50–75 % · rouge 75–100 %. Arrêts nets, **jamais de dégradé**. - -```css -.flag-bar { - height: 6px; - background: linear-gradient(to right, - var(--noir-oki) 0 25%, var(--or-oki) 25% 50%, - var(--vert-oki) 50% 75%, var(--rouge-oki) 75% 100%); -} -``` -Placement : bord inférieur de la navigation fixe ; peut ponctuer un héros ou un pied de page. **Une occurrence visible par écran maximum.** C'est l'élément le plus reconnaissable de la marque — le diluer, c'est le tuer. - -### 2.5 Logotype - -Monogramme « OKI » : arche or, point vert, accent rouge sur noir. Fichier canonique `logos/favicon-1.png` (512×512, transparent — aussi og:image et apple-touch-icon) ; déclinaisons `logos/favicon-0.ico`, `assets/maskable_oki.png`. Les `logos/header-img-*` sont des marques de **partenaires** (Joukawouvè, Aktivist Vybz, cyber-mawonaj, KA UBUNTU) : provenance conservée, **ne jamais les utiliser comme logo OKI**. - ---- - -## 3. MOTION OKI — LES CADENCES GWOKA - -La marque ne bouge pas comme une startup : elle pulse comme un ka. Tokens obligatoires dans tout projet OKI animé : - -```css -:root { - --ease-ka: cubic-bezier(0.22, 1, 0.36, 1); /* temps fort : attaque franche, longue tenue */ - --ease-syncope: cubic-bezier(0.65, 0, 0.35, 1); /* contretemps : symétrique, urgent */ - --dur-tanbou: 120ms; /* double-croche — micro-interactions, hovers */ - --dur-mesure: 480ms; /* une mesure — entrées de section */ - --dur-phrase: 960ms; /* deux mesures — transitions de page */ -} -``` - -Règles de motion : -1. **Le stagger de marque OKI est syncopé (3+3+2)**, pas linéaire : délais `[0, 120, 300, 360, 600, 660, 900, 960]` ms pour 8 éléments. C'est subtil — c'est le but : le rythme est une identité, pas un effet. -2. Uniquement `transform` + `opacity` (recette P3/budgets). -3. `prefers-reduced-motion` : gate unique au provider, contenu statique complet (le site actuel n'a **aucune** garde — à corriger partout). -4. Durées toujours lues depuis les tokens, jamais hardcodées. - ---- - -## 4. ICONOGRAPHIE — LA RÈGLE « ZÉRO EMOJI EN PRODUCTION » - -Le site actuel utilise des emojis (✊🏿🔓🤝🏿🛡️) : rendu dépendant de l'OS, incohérent avec la précision du drapeau. **Tout projet harmonisé remplace les emojis par le set SVG OKI.** - -Spécifications du set : -- ViewBox 24×24, **stroke 2 px**, angles nets (pas de courbes organiques), une seule couleur : `currentColor` (or par défaut sur noir). -- Remplissage réservé aux pictogrammes ≤ 16 px. -- Grille de nommage en KA : les fichiers portent des noms kréyòl. - -Set initial à produire (correspondances avec l'existant) : - -| Fichier | Sujet | Remplace / usage | -|---|---|---| -| `ka.svg` | tambour ka | icône maîtresse, 404, loader | -| `lambi.svg` | conque lambi | communication, annonces, « bòkaz » | -| `zetwal.svg` | étoile 4 branches | navigation, favoris, instances fédivers | -| `mawon.svg` | silhouette/brisure de chaîne stylisée | souveraineté, valeurs | -| `lakanmou.svg` | flamme | engagement, dons ponctuels | -| `jaden.svg` | pousse/jardin | solidarité, lakou, projets | -| `kannen.svg` | canne à sucre stylisée | patrimoine, histoire | -| `lanme.svg` | vague | océan, liens internationaux, Réunion↔Gwada | -| `glo.svg` | poing levé géométrique | ✊🏿 — luttes, tarifs solidaires | -| `kle.svg` | clé/cadenas ouvert | 🔓 — liberté, open-source | -| `pawol.svg` | bulle de parole angulaire | langues, traduction, PAWÒL-NU | -| `mizik-note.svg` | note de musique | MIZIK, DJANGOKAM | - -Chaque picto livré en `` dans un sprite `icons.svg` + usage `` (une seule requête, stylable en CSS). - ---- - -## 5. VOIX & TON (canonique, reprise du BRAND.md) - -Vouvoiement direct et empathique, phrases courtes. On parle d'abord de la cause du visiteur — « Vous luttez, vous organisez, vous mobilisez » — puis de l'outil. La technique sert la lutte, jamais l'inverse. - -- **À dire :** sur mesure · tarifs adaptés à vos moyens · organisations engagées · transition numérique · écosystème numérique libre · à la hauteur. -- **À éviter :** « template générique », jargon corporate/marketing, « clé en main », startup-speak. -- Piliers : ORGANISATION KA · INTERNATIONALE · Des solutions pour chaque besoin · Le budget ne doit jamais être un frein. -- **Langues :** FR par défaut ; le KA (kréyòl) en signature, titres de sections symboliques et microcopy (404, loader, remerciements) ; EN en version dédiée. Attribut `lang` correct à chaque bascule. - -## 6. IMAGERIE (canonique) - -Illustration numérique afrofuturiste caribéenne : scènes au coucher de soleil, personnages caribéens, pochettes musicales typographiées. Couleurs chaudes saturées sur fonds sombres. **Jamais** de photo de banque d'images corporate, jamais d'illustration générique de startup, jamais d'icône ou de logo en guise d'image. Formats : AVIF/WebP, self-hébergés, `loading="lazy"` hors LCP. - ---- - -## 7. MATRICE D'APPLICATION PAR PROJET - -Harmoniser ≠ tout refaire : chaque plateforme a un canal de personnalisation officiel. N'UTILISER QUE ces canaux (jamais de fork pour du style). - -| Projet | Logiciel | Canal de theming | Application OKI | -|---|---|---|---| -| **o-k-i.net** | SvelteKit (migration en cours) | Natif | Référence absolue : tokens §2, flag-bar, village SVG, KineticText gwoka | -| **BOKANTE** | Mastodon | CSS personnalisé admin + `custom.css` | Variables Mastodon remappées sur tokens OKI : fond `--noir-oki`, accent `--or-oki`, boutons Archivo uppercase ; logo colonne = monogramme OKI ; flag-bar en haut de la colonne de composition | -| **GADE** | PeerTube | Thème CSS admin (champ « CSS personnalisé ») | Mêmes remappages ; player : contrôles or sur noir ; page À-propos = texte marque (« vidéos sans algorithme, dédiées aux cultures afro-diasporiques ») | -| **NIYAJ** | Nextcloud | App **Theming** officielle | Couleur primaire `#FDB813`, fond sombre, logo + slogan « Votre cloud, vos données » ; favicon OKI | -| **MIZIK** | Funkwhale | `custom.css` admin | Fond `--noir-oki`, accents or, player accentué or ; typographie : Inter si surchargeable, sinon système | -| **KUTE** | App PHP maison | Natif | Appliquer les tokens §2 en entier — c'est un projet first-party, aucune excuse de ne pas être au niveau d'o-k-i.net | -| **LABOLA** | Forgejo/Gitea | `custom/templates` + `custom/public/css` | Thème sombre OKI, accent or ; logo forge = monogramme ; **ne pas toucher aux templates Go au-delà du header/footer** (fragile aux upgrades) | -| **PAWÒL-NU / djangokam.pawol.nu / nyyoka.pawol.nu** | Selon stack | Natif | Charte complète + liberté artistique accrue (pochettes, kinetic type poussé) : c'est la vitrine culturelle, le motion peut y être plus riche qu'ailleurs | -| **fediverse.o-k-i.net** | Statique | Natif | **Constellation zétwal** : chaque instance = étoile SVG reliée, hover/focus = éclat or + label ; DOM/SVG léger uniquement | - -### Le footer fédéré commun (tous les sous-domaines) - -``` -[monogramme OKI] Un service libre opéré par ORGANISATION KA INTERNATIONALE · o-k-i.net -``` -+ flag-bar 6 px au-dessus du footer. Une seule ligne, `--muted`, lien or. C'est le fil rouge qui fait l'écosystème. - -### Règles cross-projets - -1. **Un domaine, une famille** : `*.o-k-i.net` = écosystème fédivers et outils ; `pawol.nu` = projets culturels/musicaux. Ne pas mélanger. -2. Chaque service porte un **nom KA + le nom du logiciel en sous-titre** (pattern existant : « BOKANTE — Mastodon », « NIYAJ — Nextcloud »). Ne jamais masquer le logiciel sous-jacent : la transparence est un pilier. -3. Favicon = monogramme OKI partout (déclinaisons ico/png/maskable). -4. og:image par service : monogramme sur `--noir-oki` + nom du service en Archivo or. -5. Toute nouvelle page statique du réseau démarre du template o-k-i.net (tokens inclus), jamais de zéro. - ---- - -## 8. CHECKLIST D'HARMONISATION D'UN PROJET (DoD marque) - -- [ ] Thème sombre par défaut, clair opt-in contrasté AA. -- [ ] Tokens §2 importés (pas de valeur recopiée à la main — un fichier `oki-tokens.css` partagé). -- [ ] Or = seule couleur d'action ; rouge/vert dans leurs rôles sémantiques. -- [ ] Archivo/Inter self-hébergées, zéro fonte externe. -- [ ] Flag-bar présente, segments francs, ≤ 1 par écran. -- [ ] Zéro emoji en interface (set SVG §4). -- [ ] Tokens motion §3 + gate `prefers-reduced-motion`. -- [ ] Footer fédéré + monogramme + favicon OKI. -- [ ] Voix conforme §5 (test : aucune occurrence de « clé en main », « solution innovante », « disruptive »). -- [ ] Zéro requête tierce au chargement (fonts, CDN, analytics) — vérifié onglet réseau. -- [ ] Nom KA + logiciel en sous-titre visible en page d'accueil du service. diff --git a/prompt-kimi-cli-transformation-oki.md b/prompt-kimi-cli-transformation-oki.md deleted file mode 100644 index 0eb699c..0000000 --- a/prompt-kimi-cli-transformation-oki.md +++ /dev/null @@ -1,79 +0,0 @@ -# PROMPT KIMI CLI — Transformation de o-k-i.net en SvelteKit - -> **Mode d'emploi :** copie l'intégralité du bloc ci-dessous (entre les lignes `---`) dans Kimi CLI, en joignant les deux documents de référence : `recette-sveltekit-playbook-agent.md` (la méthode) et `charte-oki-design-system.md` (la marque). Ajuste la section « Périmètre de cette session » selon ce que tu veux faire en une passe. - ---- - -# MISSION : Migrer o-k-i.net vers SvelteKit selon la recette et la charte OKI - -Tu es un agent de code senior. Ta mission : reconstruire le site **o-k-i.net** (ORGANISATION KA INTERNATIONALE) en SvelteKit, en suivant **à la lettre** le playbook `recette-sveltekit-playbook-agent.md` (méthode, budgets, DoD) et la charte `charte-oki-design-system.md` (couleurs, typo, voix, iconographie — elle prime pour tout ce qui est marque). - -## 1. Contexte du site existant (audit réel, juillet 2026) - -**Identité :** association tech militante guadeloupéenne — « Le numérique au service de vos luttes ». Applis web sur mesure à tarifs solidaires pour associations, collectifs et organisations militantes. Positionnement souveraineté numérique : indépendance des GAFAM, logiciels libres, hébergement éthique. L'identité visuelle est afrofuturiste caribéenne : drapeau panafricain (noir/or/vert/rouge), **thème sombre par défaut**. - -**Écosystème lié (liens externes à préserver, ne pas migrer) :** -- bokante.o-k-i.net → instance Mastodon -- gade.o-k-i.net → instance PeerTube -- mizik.o-k-i.net → instance Funkwhale -- niyaj.o-k-i.net → Nextcloud -- kute.o-k-i.net → application PHP maison -- labola.o-k-i.net → forge (code source public, dont celui du site) -- fediverse.o-k-i.net → portail fédivers -- pawol.nu + djangokam.pawol.nu + nyyoka.pawol.nu → paroles/traductions/karaokés (projet DJANGOKAM, artiste IA caribéen) - -**Stack actuelle mesurée :** HTML statique + CSS vanilla (~44 KB) + 3 petits JS vanilla (main.js, theme.js, lang-redirect.js). Hébergement o2switch (mutualisé FR). Images via BunnyCDN (`organisationka.b-cdn.net`). Headers de sécurité exemplaires à **conserver à l'identique ou renforcer** : CSP `default-src 'self'` (+ style 'unsafe-inline' + fonts.googleapis.com), HSTS, `X-Frame-Options: DENY`, `X-Content-Type-Options: nosniff`, `Referrer-Policy: strict-origin-when-cross-origin`, `Permissions-Policy` restrictive. - -**Bugs et défauts de production confirmés (à corriger dans la migration) :** -1. **CRITIQUE — Toutes les images renvoient 403** (pull zone BunnyCDN cassée) : logo header, logos partenaires, portrait DJANGOKAM, pochettes, logos clients, og:image. Décision cible : **self-héberger toutes les images** dans `static/images/` (AVIF/WebP générés au build via vite-imagetools), supprimer toute dépendance à BunnyCDN, retirer `https://organisationka.b-cdn.net` de la CSP. -2. **Google Fonts** chargé (fonts.googleapis.com + gstatic.com) alors que le site revendique l'indépendance des GAFAM → self-héberger Archivo (600-900) et Inter (400-800) en woff2, retirer les deux domaines de la CSP. -3. Aucun `prefers-reduced-motion` nulle part. -4. Iconographie 100 % emoji (✊🏿🔓🤝🏿🛡️💼🏛️) → set SVG conforme à la charte (angles nets, stroke 2 px, or sur noir). -5. Les 3 cards « publics » (Militants / Associations & Collectifs / Entreprises) apparaissent en double dans la page → une seule occurrence. -6. Lazy-loading d'images partiel (4/~14) → systématique hors LCP. - -**Contenu éditorial (conserver tel quel, sauf mention contraire) :** one-page FR à ancres — Hero (« ORGANISATION KA INTERNATIONALE », 3 badges, 2 CTA) · Solutions ×3 publics · Projets web · Partenaires (Joukawouvè, Aktivist Vybz #AKV, cyber-mawonaj) · DJANGOKAM (artiste IA caribéen, lore Wanakaera/Karukera, liens pawol.nu, plateformes musicales, presse) · Mission + 4 valeurs (Engagement, Liberté, Solidarité, Souveraineté) · Développement web sur mesure · Clients (KA UBUNTU kaubuntu.com, KA UBUNTU Hub kaubuntu.re PWA, KBM kbm.gp) · Services hébergés (BOKANTE, GADE, NIYAJ, etc.) · FAQ « Qu'est-ce que le Ka ? » · CTA final + contact (kontak@o-k-i.net, WhatsApp, Telegram, Discord, forge) · footer avec mentions légales. Pages satellites : `/dons/` (Stripe + Liberapay), `/en/` (version anglaise complète), `/mentions-legales/`. - -## 2. Exigences techniques - -- **SvelteKit + Svelte 5 runes + TypeScript**, adapter-static (prerender intégral) — le site doit pouvoir être servi depuis o2switch en statique ou Cloudflare Pages, sans serveur Node. -- **i18n FR/EN** : FR par défaut, EN sur `/en/` comme actuellement ; attributs `lang` corrects ; pas de lib lourde si un routage par dossier suffit. -- **Thème sombre par défaut** (identité de marque), thème clair en opt-in persisté en localStorage, appliqué sans FOUC via snippet dans `app.html`. -- **Conserver toutes les URLs** existantes (/, /dons/, /en/, /mentions-legales/, ancres #solutions #projets #partenaires #djangokam #hebergement #contact). -- **Headers de sécurité** : reproduire la CSP et les headers actuels (via `_headers` Cloudflare ou doc d'htaccess o2switch), en retirant les domaines devenus inutiles (Google Fonts, BunnyCDN). -- **PWA légère** : manifest + service worker de cache du shell (vite-plugin-pwa) — le site doit rester lisible hors-ligne. -- OpenGraph complet (10 balises actuelles) reconduit, og:image self-hébergée. -- Budgets du playbook §4 : JS initial ≤ 170 KB, page d'accueil ≤ 2 MB, Lighthouse mobile ≥ 90/95/95/95. - -## 3. Motion & composants (sélection depuis la bibliothèque du playbook §5) - -Applique la sélection suivante — pas plus, le site doit rester sobre : -1. **KineticText** sur les titres de sections (Archivo uppercase), split par mots, stagger piloté par les tokens gwoka de la charte (`--dur-tanbou` 120 ms de base, pattern syncopé), scrub natif `animation-timeline: view()` avec fallback ScrollTrigger. -2. **ScrollProgressBar** en haut de page, gradient or→vert de la charte. -3. **PageTransition** légère (View Transitions + fallback), durée `--dur-mesure` 480 ms. -4. **Village écosystème** : remplacer la grille de cards « Services hébergés » par une scène SVG isométrique « village créole » (case à ka = BOKANTE, karbay = GADE, silo nuage = NIYAJ, scène de musique = MIZIK…), chaque bâtiment = lien vers l'instance, hover/focus = liseré or + label. **DOM/SVG uniquement, aucun WebGL** (P3 du playbook). Fallback : grille de cards accessible pour reduced-motion/mobile étroit. -5. **Flag-bar** (signature marque, 4 segments francs 6 px) : sous la nav fixe + en haut du footer, jamais plus d'une occurrence visible par écran. -6. **404 designé** en KA (texte créole + ka/tambour SVG), page hors-ligne PWA assortie. -7. CursorTracker : **ne pas installer** (audience mobile-dominante, ROI faible). -8. WebGL : **aucun** sur cette migration. - -## 4. Périmètre de cette session - -- [ ] Scaffold SvelteKit + tokens charte + thème sombre/clair + fonts self-hébergées -- [ ] Migration de la home complète (toutes sections, contenu FR repris à l'identique) -- [ ] Pages /dons, /mentions-legales, /en (structure, contenu EN repris) -- [ ] Composants motion §3 (KineticText, ScrollProgressBar, PageTransition, village SVG) -- [ ] 404 + page hors-ligne + manifest PWA -- [ ] Headers sécurité + _headers + doc déploiement (o2switch statique ET Cloudflare Pages) -- [ ] Rapport final : Lighthouse, poids par page, écarts éventuels avec ce brief - -## 5. Critères d'acceptation - -- La DoD du playbook §8 est intégralement vérifiée. -- Zéro requête vers un domaine tiers au chargement (vérifier l'onglet réseau) : ni Google, ni BunnyCDN, ni aucun CDN. -- Toutes les images présentes et optimisées (plus aucun 403, plus aucune image > 200 KB hors hero). -- Le contenu éditorial FR est repris à l'identique (aucune réécriture non demandée), hormis la déduplication des cards « publics ». -- La nav au clavier fonctionne sur tout le village SVG (chaque bâtiment focusable, label lisible). -- `npm run build && npm run preview` : zéro erreur, zéro warning a11y. - -Commence par la Phase 1 du playbook (audit de confirmation du dépôt actuel) et présente-moi le plan avant d'écrire le moindre composant. diff --git a/recette-sveltekit-15-sites-awwwards.md b/recette-sveltekit-15-sites-awwwards.md deleted file mode 100644 index e371cc8..0000000 --- a/recette-sveltekit-15-sites-awwwards.md +++ /dev/null @@ -1,908 +0,0 @@ -# 15 Award Sites → The SvelteKit Recipe -### An autopsy of Awwwards-grade websites + an actionable implementation guide for Cyber-mawonaj - -> **Method note.** Stack claims are grounded in official case studies, Awwwards entries and technical write-ups wherever they exist (footnotes at the end of the document). Where no public source exists (marked *inference*), the analysis is based on observable rendering behavior and the studio's known toolchain. Every "stealable pattern" is something you can extract without the original codebase. - ---- - -# PART 1 — SITE-BY-SITE ANALYSIS - ---- - -## 1. unseen.co — Unseen Studio (Bristol, UK) - -Unseen Studio is the rebrand of Green Chameleon, a studio with 35 SOTDs; their own site won SOTD at launch [^38^][^39^]. - -**[A] Visual language.** Dark, atmospheric base with volumetric lighting as the signature — their designers publish "volumetric lighting studies" as R&D, and that light-fog sensibility pervades the site [^39^]. Palette: near-black grounds, soft chromatic blooms (rainbow-adjacent volumetric glows), restrained UI chrome. Typography is large, confident grotesque with generous tracking; type never competes with the 3D — it floats above it. Composition is free-form asymmetry around a central 3D stage. - -**[B] Motion.** Physics-feeling, inertia-heavy. Real-time WebGL particle simulations are an in-house specialty (they teased a "real-time WebGL particle sim" before project launches) [^39^]. Scroll acts as a camera dolly through project worlds; hover states distort or illuminate the medium rather than underline links. Cursor is part of the lighting rig. - -**[C] Tech stack.** WebGL/Three.js confirmed by their own hiring and project tags (#webgl #threejs) [^39^]. Custom shader work for volumetrics and particles; DOM reserved for text/UI. Performance strategy: the studio iterates "directly in the browser" with live shader reloading. - -**[D] UX.** Scroll-driven portfolio-as-journey. Navigation is minimal; the work *is* the menu. Accessibility trade-off: heavy reliance on pointer + WebGL, text contrast sometimes sacrificed to atmosphere. Mobile gets a simplified but genuine version, not a broken one. - -**[E] Critical assessment.** -- ✅ **Strengths:** (1) volumetric light identity — instantly recognizable; (2) particle/cursor integration makes the UI feel alive; (3) brand confidence: the site demonstrates the product instead of describing it. -- ⚠️ **Weaknesses:** (1) WebGL-first means a hard floor for low-end devices; (2) atmosphere-over-contrast hurts readability on cheap screens. -- 🔓 **Stealable pattern:** **the cursor-as-light-source** — pass pointer position as a uniform to your scene shader so the user literally illuminates content. One uniform, huge perceived interactivity. - ---- - -## 2. animejs.com — Anime.js v4 (Julian Garnier) - -The v4 relaunch site (2025) went viral in r/webdev as "just incredible" — the 3D hero scene is Three.js, everything else is animated with the library itself as a living demo [^14^]. - -**[A] Visual language.** Deep-space dark UI, electric accent colors, dot-grid/blueprint textures referencing engineering drawing. Typography: technical sans with tabular numerals, kinetic type everywhere — the docs headlines themselves animate. Atmosphere: glassy panels + grain, "lab instrument" aesthetic. - -**[B] Motion.** The philosophy *is* the product: timeline-orchestrated, stagger-driven, spring-eased. The v4 API is modular — `animate`, `createTimeline`, `createScope`, `createSpring`, `stagger`, `splitText`, `createDraggable` are separate named imports [^5^]. Scroll Observer API syncs animations to scroll with multiple sync modes and thresholds [^12^]. Micro-interactions: every parameter knob in the docs is draggable and live-updates the demo. - -**[C] Tech stack.** Three.js for the hero scene; Anime.js v4 for all DOM/SVG animation [^14^]. Tree-shakeable ESM modules — you import only `animejs/animation`, `animejs/timeline`, etc. [^5^]. This modularity is itself a lesson: ship ≤ what you use. - -**[D] UX.** Documentation as experience: interactive playground embedded in the narrative. Accessibility: motion-heavy but each demo is self-contained; reduced-motion handling is left to the implementer (a gap). - -**[E] Critical assessment.** -- ✅ **Strengths:** (1) product demonstrates itself — zero stock imagery; (2) interactive docs collapse learning time; (3) spring physics defaults feel modern vs. GSAP's classic easings. -- ⚠️ **Weaknesses:** (1) animation overload can fatigue on long doc sessions; (2) no first-party reduced-motion story. -- 🔓 **Stealable pattern:** **`createScope` per component** — scope animation queries to a component root and `revert()` on cleanup. Maps 1:1 to Svelte's component lifecycle (see §6). - ---- - -## 3. immersive-g.com — Immersive Garden (Paris) - -3× Awwwards Studio of the Year, 90+ awards; the 2025 rebuild won SOTM and is fully documented in an official case study [^24^][^27^]. - -**[A] Visual language.** Minimalist-yet-atmospheric: bas-relief 3D compositions of natural elements, Roman numerals rendered in 3D as menu anchors, muted stone/bone palettes with deep shadows [^27^]. It's "digital craftsmanship" as brand — tactile, sculptural, almost geological. - -**[B] Motion.** Restrained and ceremonial. GSAP for transitions, **Lenis for scroll** [^27^]. Nothing bounces; everything glides. The wow is in scene transitions and reveal choreography, not jitter. - -**[C] Tech stack (confirmed):** Three.js + Blender/Houdini/ZBrush asset pipeline; **Vue/Nuxt frontend; GSAP + Lenis; Strapi + Node backend; Vercel deployment** [^27^]. Performance strategy is the headline: **server-side KTX GPU texture compression, channel-packed textures, gltf-transform automated exports** with custom Blender/JS scripts [^27^]. - -**[D] UX.** One-click access navigation doctrine: any case study reachable in a single interaction. The **"Backstage" section** — behind-the-scenes technical breakdowns per project — is a hidden-gem IA pattern that turns process into content [^27^]. - -**[E] Critical assessment.** -- ✅ **Strengths:** (1) compression pipeline is industry best practice (KTX + channel packing); (2) Backstage = transparency as marketing; (3) minimalism with one strong sculptural motif instead of ten effects. -- ⚠️ **Weaknesses:** (1) Strapi + Node backend adds hosting weight you'd feel on a 50 €/mo budget; (2) realism-first 3D = large asset payloads even compressed. -- 🔓 **Stealable pattern:** **the Backstage section** — document your process publicly per project. For Cyber-mawonaj this doubles as pedagogical content (open knowledge = sovereignty). - ---- - -## 4. davidwhyte.com/experience — David Whyte Experience (by Immersive Garden) - -SOTM Dec 2024; official case study available [^17^][^20^]. - -**[A] Visual language.** Watercolor paintings by Matthew Phinn as the entire visual substrate — organic pigment bleeds, paper texture, muted landscape hues. Typography is literary serif, quiet. This is the anti-neon site: proof that "immersive" doesn't mean cyber. - -**[B] Motion.** Two hero techniques: a **cursor-driven watercolor fluid simulation** — one fluid sim per visible painting, optimized via a **simulation atlas + stencil buffer** so only active paper regions compute [^20^]; and a **generative watercolor reveal** — noise-layered droplets dissolving the painting into view, with **noise baked in advance** to avoid real-time cost [^20^]. Long-press reveals video of the real location. - -**[C] Tech stack (confirmed):** Nuxt/Vue, Sass + BEM, Three.js (Blender-driven camera recreated in WebGL, custom shaders), GSAP, Lenis, WordPress CMS, Vercel [^20^]. - -**[D] UX.** Scroll through landscapes; each poem gets full-screen focus. Long-press is a deliberate slow-interaction — forces contemplation, matches the content's tempo. Accessibility: text remains real DOM text (good); the fluid sim is decorative-only (also good). - -**[E] Critical assessment.** -- ✅ **Strengths:** (1) baked-noise reveal = generative feel at zero runtime cost; (2) stencil-buffer atlas is a genuinely clever perf pattern; (3) motion tempo matched to content (slow poetry, slow interaction). -- ⚠️ **Weaknesses:** (1) fluid sim still taxes low-end GPUs; (2) long-press is undiscoverable without onboarding hints. -- 🔓 **Stealable pattern:** **bake your noise** — precompute generative textures offline (Blender/Python/ComfyUI for you), ship them as KTX2, blend in shader. Generative look, static-asset perf. Perfect fit for your ComfyUI pipeline. - ---- - -## 5. kriss.ai/home/aftercare — Kriss.ai (by Studio 28K) - -Awwwards case study available [^28^]. - -**[A] Visual language.** Deliberate rejection of "cold AI tech" aesthetics: **70s-inspired palette, organic shapes, soft warm tones** — a dental AI presented as a human service [^28^]. The whole site is a "Dollhouse": an open 3D cutaway of a dental clinic where each room (front desk, surgery, aftercare) is a content section. - -**[B] Motion.** Spatial navigation through the dollhouse: camera moves between rooms on scroll/click. Motion serves wayfinding — you always know where you are in the building, hence in the offer. - -**[C] Tech stack (confirmed):** WebGL 3D built in Blender; **deployed on Cloudflare Pages + R2 for media** — a notable choice: heavy visual assets on an edge CDN, zero traditional backend [^28^]. Figma → Blender → VSCode pipeline. - -**[D] UX.** Metaphor-driven IA: product features mapped to physical rooms. This collapses the learning curve for non-technical buyers (dentists) — the spatial metaphor carries the explanation. - -**[E] Critical assessment.** -- ✅ **Strengths:** (1) narrative pivot "from tech to human" executed in the medium itself; (2) dollhouse = site map you can see; (3) **Cloudflare Pages/R2 architecture proves you can host heavy WebGL at near-zero backend cost** — directly relevant to your budget. -- ⚠️ **Weaknesses:** (1) the 3D metaphor forces all content into rooms — awkward for dense text; (2) 70s warmth risks reading as dated outside the US market. -- 🔓 **Stealable pattern:** **the dollhouse IA** — map AKILPA's or Cyber-mawonaj's sections to physical Caribbean spaces (case à ka, marché, karbay, plage). Navigation becomes cultural storytelling. Free pattern, no shaders required. - ---- - -## 6. zentry.com — Zentry (by Resn) - -Full Awwwards case study available — and the tech decision is the most instructive of all 15 sites [^6^]. - -**[A] Visual language.** Bold, vibrant, "evil-corporation-playful": saturated color fields, chunky display type, 3D portal masks as signature motif. Sound-designed: dynamic soundtrack evolving from upbeat to ambient as you explore [^6^]. - -**[B] Motion.** Motion system designed **before** the website: every reaction, curve and principle specced upfront [^6^]. Flashy, fast, reactive — but (see below) done entirely in DOM. - -**[C] Tech stack (confirmed):** **Nuxt/Vue + Vite, proprietary utility framework — and deliberately NO WebGL.** The team needed massive DOM throughput (text, dynamic media) and chose to build the 3D portal-mask effects as **custom DOM/CSS solutions instead of Three.js**, explicitly to minimize complexity and maximize DOM performance [^6^]. - -**[D] UX.** Portal motifs as content reveals; sound as orientation layer. The lesson: "immersive" is a design outcome, not a rendering technology. - -**[E] Critical assessment.** -- ✅ **Strengths:** (1) **proof that award-grade "3D" can be pure DOM** — transform3d, clip-path, masks, perspective; (2) motion-first design process (curves before comps); (3) sound design treated as first-class UX. -- ⚠️ **Weaknesses:** (1) proprietary framework = not reproducible as-is; (2) audio autoplay remains an accessibility/UX minefield. -- 🔓 **Stealable pattern:** **DOM-only portal masks** — `clip-path` + `transform-style: preserve-3d` + a GSAP scrub timeline gives you 80% of the Zentry wow at 5% of the GPU cost. **This is your #1 pattern for 4G/low-end Gwada devices.** - ---- - -## 7. igloo.inc — Igloo Inc (by Abeto + Bureaux) - -SOTD Jul 2024 (7.92/10); unusually detailed case study + WebGPU showcase write-up [^3^][^7^][^1^]. **And it's built in Svelte — your stack.** - -**[A] Visual language.** A frozen landscape: each portfolio project encased in a **procedurally generated ice block** (custom crystal-growth algorithm inside container shapes — unique every time, scales without manual modeling) [^1^]. Chromatic aberration + frost-dissolve scene transitions; intro sequence "between sci-fi title crawl and luxury brand ad" [^1^]. - -**[B] Motion.** Camera drifts between scenes; footer is an interactive particle simulation that coalesces into different 3D shapes per hovered link, **color shifting with particle velocity** [^1^]. Text glitches via shaders; **letter-scramble swaps SDF texture offsets instead of forcing DOM relayout** — a performance decision doubling as a creative one [^1^]. - -**[C] Tech stack (confirmed):** **Three.js + Svelte + GSAP**, Houdini + Blender, plus proprietary tooling including a **custom VDB-to-browser exporter** compressing volume data smaller than a typical website image [^1^]. Entire UI rendered in WebGL. Workflow: grey-box previs animations, then iterate directly in browser with real-time shader/model reloading, continuously measuring on low-end devices [^7^]. - -**[D] UX.** Three sections only — the constraint forced a scroll experience dense with interaction [^7^]. Navigation = the journey itself. - -**[E] Critical assessment.** -- ✅ **Strengths:** (1) **Svelte at the absolute top tier of the craft** — kills any "can Svelte do this?" doubt; (2) procedural assets scale content without artists; (3) SDF-text-in-shader eliminates DOM relayout cost. -- ⚠️ **Weaknesses:** (1) full-WebGL UI = screen-reader hostile, needs a parallel DOM layer; (2) proprietary VDB pipeline is not reproducible on a budget. -- 🔓 **Stealable pattern:** **velocity-reactive particles** — map particle/element color or size to pointer *velocity*, not just position. Trivially implementable in a Svelte action (`$derived` from delta of pointer positions), huge tactile payoff. Also: **SDF text rendering** if you go WebGL-UI (troika-three-text does this for free). - ---- - -## 8. kprverse.com — KPR (by Resn) - -SOTD Dec 2022 (7.98) + SOTM; official making-of available [^35^][^45^]. - -**[A] Visual language.** "New Eden" concept-art tableaux: hand-painted assets, bold concept-art style, terminal/console easter-egg aesthetics (fake file-system loading messages, "HTTPS://KPRVERSE.COM/KPCO/..." loader strings) [^41^]. Mixes 3D characters with 2D design elements, "interactive motion revealing a hidden dimension" [^45^]. - -**[B] Motion.** **Click-and-hold** as the signature: holding reveals a second interactive layer (geography, factions, lifestyle of the world) [^45^]. Scroll moves through parallax tableaux (the Keep, the Factions, the World). Loading is theatrical: console-style progress theater. - -**[C] Tech stack.** Resn proprietary (Nuxt-era Resn = Vue-based, per their Zentry write-up [^6^]); layered 2D/3D compositing rather than full 3D scenes. - -**[D] UX.** Narrative gating: lore revealed in layers, community invited to "shape the story". Notably **hard device gating**: "Your Browser resolution is currently not supported" and portrait-only enforcement on mobile [^41^] — a controversial but deliberate trade. - -**[E] Critical assessment.** -- ✅ **Strengths:** (1) click-and-hold "second layer" is a brilliant lore-delivery mechanic; (2) loader-as-fiction (terminal theater) turns wait time into worldbuilding; (3) tableaux = content with room for community contribution. -- ⚠️ **Weaknesses:** (1) **resolution gating is hostile** — for Gwada's mobile-dominant reality this pattern is toxic; ship a degraded mode instead; (2) hand-painted asset volume = production cost. -- 🔓 **Stealable pattern:** **click-and-hold reveal layer** — pointer-down starts a GSAP timeline that cross-fades a hidden info stratum; release reverses it. One timeline, two states, infinite narrative uses (patrimoine layers: colonial map ↔ créole map). - ---- - -## 9. hape.io — HAPE (by Dogstudio/DEPT for Digimental) - -SOTD Apr 2022 (7.84, dev award animations 9.4/10); official case study available [^36^][^37^][^40^]. - -**[A] Visual language.** High-fashion-magazine web design: black/gold footer palette, editorial grids, the 3D ape treated like a couture model [^36^][^37^]. - -**[B] Motion.** **The HAPE walk is the scroll**: page opens zoomed on the ape's head; scrolling rotates the camera and dollies out to reveal the full strutting character — a walk cycle art-directed for "attitude" and **synchronized to a handpicked soundtrack** [^40^]. A "hapewalk mode" hands rotation/zoom control to the user [^40^]. - -**[C] Tech stack (confirmed):** **custom OGL micro-framework** — OGL (minimal-abstraction WebGL library) extended in-house with PBR rendering, skinning, post-processing and an animation player [^37^]. Built in 4 weeks [^37^]. - -**[D] UX.** One character, one gesture (scroll), one attitude — radical focus. Results: 57K visitors launch month, 4.58 min average session [^37^]. - -**[E] Critical assessment.** -- ✅ **Strengths:** (1) scroll-synced skeletal animation with music sync is a masterclass in single-idea execution; (2) OGL proves you don't need Three.js if your needs are narrow; (3) fashion-editorial framing elevates NFT kitsch to design. -- ⚠️ **Weaknesses:** (1) skinned 3D + PBR is heavy for low-end mobile; (2) audio-synced motion degrades silently when sound is off/blocked. -- 🔓 **Stealable pattern:** **scroll-scrubbed skeletal camera** — bind `scrollProgress` to a baked animation clip's time (`mixer.setTime(progress * duration)`). Works with any GLTF walk/dance cycle. Imagine it with a **gwoka dancer** or a lambi procession: cultural motion as scroll engine. - ---- - -## 10. labs.noomoagency.com — Noomo Labs - -Developer Award + SOTD 2024; official behind-the-scenes available [^16^][^13^]. - -**[A] Visual language.** A dreamlike underwater journey with a glass jellyfish: 3D glass materials, refractive transparency, calm ambient sound design ("sound of the glass sphere appearing", music complementing the jellyfish) [^13^]. It's a hub for experiments — R&D made public. - -**[B] Motion.** The technical doctrine: **all 3D assembled in ONE Blender scene; all non-interactive animation (camera, jellyfish, words) baked in Blender; materials baked to textures** [^13^]. Camera rigged to two Empties — one at the focal point, one animating the camera object [^13^]. Runtime = playback + interactive garnish. - -**[C] Tech stack (confirmed):** Three.js + GSAP, **explicitly avoiding React Three Fiber "to maintain flexibility"**, Nuxt framework, Blender-baked assets [^13^]. The storytelling sister site scrolls a Three.js camera through five differently-lit "rooms" of case studies [^8^]. - -**[D] UX.** Labs = experiments before they "grow up" [^8^] — an institutional pattern: public R&D as marketing. - -**[E] Critical assessment.** -- ✅ **Strengths:** (1) **bake-everything philosophy = cinematic quality at playback cost**; (2) one-scene assembly avoids runtime scene-graph juggling; (3) labs-as-content is a sustainable publishing model. -- ⚠️ **Weaknesses:** (1) baked = rigid; content changes require re-bakes; (2) glass/refraction shaders are expensive on Mali-class GPUs. -- 🔓 **Stealable pattern:** **the two-Empty camera rig** — in Blender, parent your camera to a target-Empty + path-Empty, bake, export GLTF, and in SvelteKit just scrub `cameraAnimation.time` from Lenis scroll progress. Zero camera math at runtime. Your ComfyUI/Blender pipeline already supports this. - ---- - -## 11. noomoagency.com — Noomo Agency - -Awwwards **Website of the Year** winner [^9^][^16^]. - -**[A] Visual language.** Glassmorphism at its most disciplined: glass cards on-scroll animations, 3D hover effects, a **dynamic logo incorporating handwritten elements from each team member** — personalization as brand system [^9^][^11^]. Boutique-agency warmth inside high-tech execution. - -**[B] Motion.** "Every interaction and hover has its unique purpose" [^9^] — hover states are individually art-directed (button hovers, 3D case previews, showreel controls) [^11^]. Scroll animations drive case reveals; 3D transitions between pages. - -**[C] Tech stack (confirmed):** **Nuxt 3 front AND back (Node), Three.js + GSAP** [^9^]. - -**[D] UX.** Classic agency IA (work/story/contact) elevated by transition choreography — proof you don't need experimental IA if execution is flawless. - -**[E] Critical assessment.** -- ✅ **Strengths:** (1) hover-as-portfolio: micro-interactions individually designed, not defaulted; (2) humanizing details (handwritten logo) offset tech flex; (3) full-stack Nuxt keeps ops simple. -- ⚠️ **Weaknesses:** (1) glass everywhere = blur = GPU cost on weak devices; (2) 3D page transitions can delay content access. -- 🔓 **Stealable pattern:** **budgeted hover craft** — pick your 5 most-tapped elements and give each a unique, purposeful micro-interaction; leave the rest at system defaults. Award juries notice the ratio of intentional to generic interactions. - ---- - -## 12. nudot.com.tw — Nudot (Taiwan) - -*No public case study found — this section is inference from the live site and studio profile; treat stack claims as low-confidence.* - -**[A] Visual language.** Taiwanese studio aesthetic in the lineage of Ultra Combos/Studio Pros: precise CJK+Latin bilingual typography, generous whitespace punctuated by abrupt kinetic moments, muted palette with one aggressive accent. Bilingual typesetting (Chinese vertical/horizontal + English) is itself the design flex. - -**[B] Motion.** Text-led motion: character-level reveals, marquee systems, cursor-following media previews on project lists. Motion is typographic rather than 3D. - -**[C] Tech stack (inference).** DOM/CSS + GSAP-class animation, canvas accents; likely Nuxt or similar Vue meta-framework (dominant in Taiwanese award studios). - -**[D] UX.** Project-list-as-gallery with hover media previews; bilingual toggle as first-class nav item — relevant precedent for FR/KRÉ bilingual switching. - -**[E] Critical assessment.** -- ✅ **Strengths:** (1) bilingual typography treated as design material, not i18n afterthought; (2) restraint — effects deployed sparingly; (3) fast: typography-led sites are inherently light. -- ⚠️ **Weaknesses:** (1) hover-previews have no touch equivalent (mobile gets a lesser list); (2) minimal feedback cues can confuse first-time visitors. -- 🔓 **Stealable pattern:** **bilingual kinetic type** — design your FR/KRÉ switch as an *animation event* (lines rotate/mask-swap in place) rather than a page reload. Language toggle becomes brand moment. Implement with `splitText` + a shared-layout transition. - ---- - -## 13. 375.studio/en/studio — Studio375 (Vicenza, Italy) - -SOTD Apr 30, 2026 (7.33, plus Developer Award) [^2^][^15^]. - -**[A] Visual language.** Two-color discipline (their earlier HM site was strict #000/#FFF) [^10^], clean-flat-minimal portfolio aesthetic with colorful punctuations [^10^]. Communications-agency clarity rather than tech-lab showing-off. - -**[B] Motion.** Hero image animation, mouse interaction, scroll-linked text decoration, animated 404 — a **complete system of small moments** rather than one big WebGL bet [^10^]. Dev-award scores show the craft is in transitions (animations 7.8, their strongest dev metric) [^2^]. - -**[C] Tech stack (inference).** DOM-first, GSAP-class orchestration; no heavy WebGL signature. Accessibility dev-score 7.2 is above the award-site average [^2^] — suggests semantic care. - -**[D] UX.** Conventional studio IA executed with transition polish; even the 404 is a designed moment [^10^]. - -**[E] Critical assessment.** -- ✅ **Strengths:** (1) proves SOTD is achievable without WebGL; (2) systematic micro-motion (every page state designed, incl. errors); (3) strong accessibility score for the category. -- ⚠️ **Weaknesses:** (1) less memorably distinctive than the WebGL cohort; (2) creativity scores (7.57) lag the experimental sites. -- 🔓 **Stealable pattern:** **design your error/empty/404 states with the same rigor as the hero.** For an association site (AKILPA), the 404, the "no events yet", the offline page are touchpoints where grassroots personality can outshine budget. - ---- - -## 14. ten.375.studio/en — "Ten Years Away" (Studio375) - -SOTD Jun 26, 2026 (7.32; users rated creativity 9.3) [^4^]. - -**[A] Visual language.** **An interactive comic** chronicling ten years of the studio — "real characters, real stories" [^4^]. Illustrated panels, comic-page composition translated to scroll, hand-drawn texture over digital precision. - -**[B] Motion.** Mouse trail as a signature element, page transitions between comic chapters, intro sequence [^4^]. Motion serves panel-to-panel reading rhythm — scroll as page-turn. - -**[C] Tech stack (inference).** DOM/SVG illustration + GSAP-class scrubbing; the comic format suggests asset sequencing rather than runtime 3D. - -**[D] UX.** Narrative chronology as IA: ten years = ten chapters. Personal/historical storytelling instead of service listing — an anniversary site that earns attention through vulnerability (real people, real stories). - -**[E] Critical assessment.** -- ✅ **Strengths:** (1) format courage — a comic, not a portfolio grid; (2) chaptered narrative maps perfectly to scroll; (3) authenticity as differentiator (users scored creativity 9.3, far above jury [^4^]). -- ⚠️ **Weaknesses:** (1) niche payoff — low utility for prospective clients; (2) illustrated asset production is time-expensive. -- 🔓 **Stealable pattern:** **the chaptered scroll-comic** — for AKILPA, a "10 dates du patrimoine gwada" or "l'histoire du lambi" as an interactive scroll-comic. Chapters = routes (`/histoire/[slug]`), panels = SVG/AI-generated assets (your Qwen/Seedream pipeline), transitions = shared-element morphs. High storytelling ROI per byte. - ---- - -## 15. apple.com/airpods-pro — Apple - -The canonical scroll-scrubbed product page; technique fully documented by CSS-Tricks and the GSAP community [^19^][^18^]. - -**[A] Visual language.** Product-photographic maximalism on pure black; type appears only when the product pauses. No texture tricks — the hardware render *is* the visual language. - -**[B] Motion.** **Scroll-scrubbed image sequences**: a 148-frame JPEG flipbook drawn to a fixed ``, frame index = scroll fraction × frame count [^19^]. Content sections are one big master timeline with percentage-hand-picked timings; "fake pins" hold content in place [^18^]. requestAnimationFrame for tear-free frame swaps [^19^]. - -**[C] Tech stack (documented technique).** Canvas 2D + image preloading; no WebGL needed [^19^]. **Performance doctrine: on slow connections Apple ships a single fallback image instead of the sequence** — and offers smaller sequences per device class [^19^]. - -**[D] UX.** Scroll = product film. Information hierarchy: specs arrive only after desire is built. Accessibility: canvas content is mirrored by real DOM text below. - -**[E] Critical assessment.** -- ✅ **Strengths:** (1) the flipbook is the most copied award pattern alive — simple, robust, GPU-cheap; (2) **explicit slow-network fallback strategy** — exactly your 4G doctrine; (3) master-timeline percentage timing keeps everything in sync across viewports [^18^]. -- ⚠️ **Weaknesses:** (1) 148 frames is a data hog without fallbacks; (2) canvas imagery needs parallel DOM for a11y/SEO. -- 🔓 **Stealable pattern:** **the scroll flipbook with connection-aware loading** — `navigator.connection.effectiveType` decides: full sequence / reduced frame set / single hero image. Ship it as a Svelte action (see §5, bonus component). **This is the single most Gwada-appropriate award pattern in this list.** - ---- - ---- - -# PART 2 — THE SVELTEKIT RECIPE - -## 1. Core Principles (the common DNA) - -**Principle 1 — Scroll is the primary navigation driver.** 13 of 15 sites bind narrative progression to scroll. Canonical stack: **Lenis + GSAP ScrollTrigger, wrapped as Svelte actions/context** (Immersive Garden ships exactly this combo [^20^][^27^]). In SvelteKit: one Lenis instance in the root layout, exposed via context; never instantiate per component. - -**Principle 2 — Bake at build, not at runtime.** David Whyte bakes noise [^20^]; Noomo bakes camera, materials and character animation in Blender [^13^]; Immersive Garden compresses textures server-side to KTX [^27^]; Igloo compresses volumes to sub-image size [^1^]. Rule: **if a value doesn't depend on live user input, it has no business being computed in the browser.** Your ComfyUI/Blender pipeline is your "baking" layer — treat it as part of the build system. - -**Principle 3 — DOM first, WebGL only where it pays.** Zentry did its award-winning "3D" portals in pure DOM deliberately [^6^]; Apple's flipbook is Canvas 2D [^19^]. Reserve WebGL for: particle systems, fluid sims, real 3D assets with user-controlled cameras. Everything else: CSS transforms, clip-path, SVG. **For 4G Guadeloupe this principle is non-negotiable.** - -**Principle 4 — Motion is designed before pages.** Zentry specced its motion system before design started [^6^]; HAPE art-directed a walk cycle, then built a site around it [^40^]. Define your easing vocabulary, durations and rhythm (for you: gwoka cadences — see Part 3) as **design tokens**, before any component exists. - -**Principle 5 — Every state is a designed moment.** Studio375's animated 404 [^10^], KPR's terminal-theater loader [^41^], Noomo's per-element hover craft [^9^]. Loading, error, empty, offline: these are where personality lives when budget doesn't. - ---- - -## 2. SvelteKit Architecture Patterns - -### 2.1 Route structure for immersive experiences - -``` -src/routes/ -├── +layout.svelte ← SmoothScrollProvider (Lenis) + CursorTracker live HERE -├── +layout.ts ← export const ssr = true (default) -├── (site)/ ← layout group: classic content pages -│ ├── +page.svelte ← home (light hero, DOM effects) -│ ├── histoire/[slug]/ ← chaptered scroll-comic (Ten Years Away pattern) -│ └── patrimoine/[slug]/ ← case studies, "Backstage" pattern (Immersive Garden) -├── (immersive)/ ← layout group: canvas-heavy experiences -│ ├── +layout.svelte ← WebGLCanvas provider, ssr disabled per-page -│ └── mawonaj/+page.svelte -└── +error.svelte ← designed 404 (Principle 5) -``` - -Rules: -- **Layout groups** isolate the WebGL context to the routes that need it — the canvas provider never mounts on content pages. -- **Dynamic imports** for anything heavy: `const { WebGLCanvas } = await import('$lib/webgl/WebGLCanvas.svelte')` behind `{#await}` or `{#if browser}` gates. -- **Progressive enhancement**: every immersive route must render meaningful SSR HTML underneath the canvas (Apple mirrors its canvas with DOM text [^19^] — do the same). - -### 2.2 Where WebGL lives - -Use **Svelte context**, created once in the `(immersive)` layout: - -```ts -// $lib/webgl/context.ts -import { setContext, getContext } from 'svelte'; -import type * as THREE from 'three'; - -export interface WebGLContext { - renderer: THREE.WebGLRenderer; - scene: THREE.Scene; - camera: THREE.PerspectiveCamera; - canvas: HTMLCanvasElement; -} - -const KEY = Symbol('webgl'); -export const provideWebGL = (ctx: WebGLContext) => setContext(KEY, ctx); -export const useWebGL = () => getContext(KEY); -``` - -Child scenes register/unregister in `$effect` cleanup. **One renderer per app, many scenes.** Never two `` WebGL contexts on one page for low-end targets. - -For Three.js in Svelte, evaluate **Threlte** (the Svelte-native Three layer) for standard scenes, and raw Three.js for custom shader-heavy work (Igloo-style). Both coexist: Threlte components render into your single context. - -### 2.3 Animation orchestration - -| Need | Tool | Why | -|---|---|---| -| Component enter/leave, list transitions | **Svelte built-in transitions** (`transition:`, `in:`/`out:`) | Zero deps, SSR-safe, cancellable | -| Scroll-scrubbed timelines, pinning | **GSAP + ScrollTrigger** | Industry standard on 11/15 sites | -| Lightweight springs, draggable, text splitting | **Anime.js v4** (modular imports) [^5^] | ~5× smaller import surface when tree-shaken; `createScope` maps to component lifecycle | -| Physics cursor / spring values | Anime.js `createSpring` or a 12-line custom spring | No GSAP needed for this | -| One shared clock | GSAP `ticker` as the single rAF driver, Lenis hooked into it | Prevents competing rAF loops | - ---- - -## 3. CSS Architecture for Award Sites - -### 3.1 Tailwind + CSS variables for dynamic theming - -```css -/* app.css — the theme lives in variables, Tailwind references them */ -:root { - /* Cyber-mawonaj tokens (see Part 3) */ - --lagune-phospho: oklch(72% 0.13 210); - --roche-volcan: oklch(18% 0.02 260); - --corail: oklch(70% 0.16 25); - --or-circuit: oklch(80% 0.14 90); - --foret-neon: oklch(55% 0.15 155); - --ease-ka: cubic-bezier(0.22, 1, 0.36, 1); /* motion tokens too */ - --dur-mesure: 480ms; -} -@theme inline { - --color-lagune: var(--lagune-phospho); - --color-volcan: var(--roche-volcan); - /* … */ -} -``` - -Theme switching = swapping a `data-theme` attribute on ``, variables cascade, Tailwind utilities follow. No JS class churn, no FOUC if set in `%sveltekit.head%`. - -### 3.2 Container queries > media queries for components - -Media queries for page-level breakpoints; **container queries for every reusable component** (cards, chapters, nav). Award sites break layouts constantly because components are viewport-coupled; container queries make your `KineticText` or `ParallaxLayer` correct in a sidebar, a dialog, or a split-screen dollhouse room. - -### 3.3 CSS that replaces JS - -- **`animation-timeline: scroll()` / `view()`** — native scroll-driven animations for parallax and reveals. ⚠️ *Baseline 2023+: Chrome/Edge/FF OK; Safari 26+ only — keep a ScrollTrigger fallback for Safari < 26 (still common in Gwada's device pool).* Flag: **needs progressive enhancement wrapper.** -- **`scroll-snap`** for chaptered comics (Ten Years Away pattern) — free, native, accessible. -- **`:has()`** for stateful styling (hovered card dims siblings) instead of JS class toggles. -- **View Transitions API** for route morphs (see PageTransition, §5). ⚠️ *Chrome/Edge/Safari 18+; Firefox behind flag — design as enhancement.* - ---- - -## 4. Performance Budget & Optimization - -### 4.1 Budgets (mobile 4G, low-end Android — the Gwada baseline) - -| Resource | Budget | Rationale | -|---|---|---| -| JS initial (compressed) | **≤ 170 KB** | ~1.7 s parse on entry-level 4G Android | -| WebGL textures | ≤ 8 MB GPU RAM | use **KTX2/BasisU**, never raw PNG to GPU [^27^] | -| Models | ≤ 500 KB per scene | Draco or meshopt via gltf-transform [^27^] | -| Hero media | ≤ 400 KB before interaction | poster + lazy sequence (Apple doctrine [^19^]) | -| Total page weight (home) | ≤ 2 MB | reality check against award sites' 8-15 MB | -| Frame budget | 16 ms desktop / **target stable 30 fps on Mali-G52** | test on a real ~150 € Android, not DevTools throttling | - -### 4.2 WebGL asset pipeline - -``` -Blender → gltf-transform CLI: - gltf-transform optimize in.glb out.glb \ - --compress meshopt --texture-compress ktx2 -``` - -- **KTX2 + UASTC/ETC1S** textures (Immersive Garden's exact strategy [^27^]); channel-pack roughness/metallic/AO into one texture [^27^]. -- **LOD**: two model tiers; pick at runtime from `renderer.capabilities` + `deviceMemory`. -- **Instancing** for repeated elements (lambi shells, vegetation, stars). -- **Bake lighting** into textures wherever the camera path is fixed (Noomo doctrine [^13^]). - -### 4.3 Animation frame budget - -Concurrent JS-driven animations before jank on low-end: **~8-12 transform/opacity tweens**. Beyond that: batch into one timeline, move to CSS, or cull off-screen animations (`ScrollTrigger` with `toggleActions`, or IntersectionObserver gating). Animate **only `transform` and `opacity`** — layout properties cause reflow (Anime.js v4 docs say the same [^5^]). - -### 4.4 SSR vs CSR for canvas pages - -- Canvas/WebGL pages: **SSR the semantic content shell, hydrate the canvas client-side** (`{#if browser}` + dynamic import). Don't disable SSR route-wide unless the page is truly content-free — you lose SEO and slow-connection resilience for nothing. -- Lenis/GSAP init: `onMount` only, always. -- SvelteKit prerendering (`export const prerender = true`) for everything static → perfect on Cloudflare Pages/Netlify free tiers, mirroring Kriss.ai's edge-CDN architecture [^28^]. - ---- - -## 5. Component Library — Reusable Svelte 5 Modules - -All components: Svelte 5 runes syntax, TypeScript, reduced-motion aware, cleanup on destroy. - -### 5.1 SmoothScrollProvider — Lenis as layout-level context - -```svelte - - - -{@render children()} -``` - -### 5.2 WebGLCanvas — single renderer, context-provided scene graph - -```svelte - - - - -{#if ready}{@render children()}{/if} -``` - -### 5.3 KineticText — scroll-driven split typography - -```svelte - - - -{text} -``` - -### 5.4 ParallaxLayer — multi-plane depth, CSS-first - -```svelte - - - -
{@render children()}
- - -``` - -### 5.5 CursorTracker — physics cursor + velocity uniform (Igloo pattern) - -```svelte - - - - -``` - -### 5.6 PageTransition — GSAP route transitions (SvelteKit-safe) - -```svelte - - - -{#key page.url.pathname} -
-{/key} - - -``` - -*GSAP alternative for browsers without View Transitions:* animate out in `onNavigate`'s returned promise, animate in via `afterNavigate`. Keep durations in your CSS custom properties so both paths share the same motion tokens. - -### 5.7 ScrollProgressBar — zétwal minimal progress - -```svelte - - - - -
- -
- - -``` - -### 5.8 Bonus — FlipbookCanvas (Apple pattern, connection-aware) - -```ts -// $lib/actions/flipbook.ts — Svelte action -export function flipbook(canvas: HTMLCanvasElement, opts: { frames: (q: 'full'|'lite') => string[]; total: number }) { - const conn = (navigator as any).connection; - const quality = conn?.effectiveType === '4g' && !conn?.saveData ? 'full' : 'lite'; - const urls = opts.frames(quality); - if (conn?.effectiveType === 'slow-2g' || conn?.effectiveType === '2g' || conn?.saveData) { - // Apple doctrine: single fallback image, no sequence [^19^] - const img = new Image(); img.src = urls[0]; - img.onload = () => canvas.getContext('2d')?.drawImage(img, 0, 0); - return {}; - } - const imgs = urls.map((u) => { const i = new Image(); i.src = u; return i; }); - const ctx = canvas.getContext('2d')!; - const draw = (p: number) => { - const f = Math.min(urls.length - 1, Math.floor(p * urls.length)); - if (imgs[f]?.complete) ctx.drawImage(imgs[f], 0, 0, canvas.width, canvas.height); - }; - const onscroll = () => { - const max = document.documentElement.scrollHeight - innerHeight; - requestAnimationFrame(() => draw(max > 0 ? scrollY / max : 0)); - }; - addEventListener('scroll', onscroll, { passive: true }); - return { destroy: () => removeEventListener('scroll', onscroll) }; -} -``` - ---- - -## 6. Svelte-Specific Translations (React/Next.js → Svelte idioms) - -| React pattern (seen on these sites) | Svelte 5 idiom | -|---|---| -| `useRef` + `useEffect(() => {...}, [])` for GSAP init | `$effect(() => { /* init */; return () => cleanup })` — or better, a **Svelte action** `use:gsapThing` | -| `useContext(WebGLContext)` | `setContext`/`getContext` with a `Symbol` key (§2.2) | -| `useState` for animation params | `$state` rune; params read inside `$effect` re-run the tween — guard with `gsap.quickTo` or `quickSetter` for per-frame writes | -| Derived uniforms (`useMemo`) | `$derived(() => computeUniforms(pointer, scroll))` — recalculates only on dependency change | -| R3F `` + hooks | **Threlte** for declarative scenes; raw Three in `onMount` for shader-heavy work (Noomo avoided R3F for flexibility [^13^] — same logic applies) | -| `framer-motion` layout animations | Svelte built-in `flip` (from `svelte/animate`) + `crossfade` (from `svelte/transition`) — free, SSR-safe | -| Zustand/Redux for UI state | `$state` in a `.svelte.ts` module — a class with rune fields is your store | - -**Runes vs stores for animation state:** stores still work and are fine for cross-app state; but **animation state should live in `$state`/`$derived` inside components or `.svelte.ts` modules** — runes give finer-grained reactivity (no subscriber fan-out per frame). Critical rule: **never write per-frame values (scrollY, pointer) into reactive state that drives DOM** — write them to refs/plain variables and flush via rAF, or you'll re-render at 60 Hz. - -**GSAP + runes compatibility:** GSAP mutates the DOM directly — Svelte doesn't care as long as GSAP's targets aren't nodes Svelte also patches (avoid tweening attributes Svelte controls via bindings). Wrap GSAP targets in `{@html}`-free static markup or bind via `bind:this`, init in `$effect`, kill in the cleanup function. Anime.js v4's `createScope({ root })` + `scope.revert()` is the same lifecycle shape and tree-shakes better [^5^]. - ---- - -## 7. Accessibility & Fallbacks - -1. **Screen readers in immersive sites:** canvas is `aria-hidden`; a semantic DOM mirror carries all content (Apple pattern [^19^]). If you render UI text in WebGL (Igloo), ship a visually-hidden parallel DOM (`sr-only` list of the same links/labels). -2. **Reduced motion:** one global gate — `matchMedia('(prefers-reduced-motion: reduce)')` checked in `SmoothScrollProvider` (no Lenis), `KineticText` (no split/scrub), `ParallaxLayer` (static), flipbook (poster frame). Implement it **once, at the provider level**, not per component. -3. **Graceful degradation ladder** (the Gwada ladder): - - `navigator.connection.saveData` or `effectiveType` ≤ 3g → static images, no autoplay video, no sequence preloading [^19^] - - `deviceMemory ≤ 4` or WebGL context creation fails → DOM-effects-only mode (Zentry proves DOM-only can still win awards [^6^]) - - `