À compléter avant l'envoi
[nom du serveur][nom du studio][ce qu'il conçoit, pour qui][ville, quartier][effectif, noms et rôles][3 services][email][téléphone][numéro WhatsApp][adresse][domaine][couleur ou "tu choisis"]
Sur mon serveur d'hébergement Opus Growth [nom du serveur], crée un site multipage rapide pour [nom du studio], dans l'esprit des sites de studios créatifs présentés sur Awwwards. Studio : [ce qu'il conçoit, pour qui], ville et quartier : [ville, quartier], équipe : [effectif, noms et rôles]. Services : [3 services]. Réalisations : [pour chacune, nom du client, type de travail, année, une phrase sur la problématique, une sur la solution, les livrables, lien de l'image]. Contact : [email], [téléphone], [numéro WhatsApp], [adresse]. Domaine : [domaine]. Préférence de couleur : [couleur ou "tu choisis"].
Pages : accueil (/ : hero avec un titre XXL, marquee défilant des services, réalisations sélectionnées, ce que nous faisons, méthode de travail, FAQ, appel à l'action final), réalisations (/isler/ : la problématique, ce que nous avons fait et ce que nous avons livré pour chaque projet), studio (/studyo/ : équipe et règles de travail), contact (/iletisim/), confidentialité et KVKK (/gizlilik/) et 404.html. Pas de formulaire sur la page de contact ; indique l'email, le téléphone et un lien WhatsApp avec message prérempli, ainsi qu'une liste de ce qu'il faut préciser dans le premier message. Sans chiffres validés par le client, décris les résultats de façon qualitative et n'écris aucun pourcentage ni chiffre de croissance.
Style : studio créatif façon Awwwards. Fond blanc cassé, texte noir et une seule couleur d'accent utilisée uniquement en fond (avec du texte noir dessus, contraste d'au moins 4,5:1). Une police d'affichage Fontshare qui tient la route à de très grandes tailles (par exemple Clash Display 600) et une police de texte sobre (par exemple Ranade). Le titre du hero remplit l'écran avec un clamp entre 3.2rem et 12.5rem et un interlettrage serré, sans déborder à 360 px. La liste des réalisations prend la forme de lignes avec de grandes images et de grands titres dans une grille asymétrique qui alterne colonnes 7/5 et 5/7.
Règles d'animation (la partie la plus délicate, à suivre à la lettre) :
1. Bibliothèques : GSAP 3.13 core, ScrollTrigger, SplitText et Lenis, uniquement sur les pages d'accueil et de réalisations. Aucun script sur les pages studio, contact et confidentialité. Ne charge ni Swiper, ni WebGL, ni vidéo.
2. SplitText : le h1 au-dessus de la ligne de flottaison est l'élément LCP ; ne le démarre donc jamais masqué ni glissant vers le haut. Le h1 démarre visible dans une couleur atténuée qui respecte tout de même le contraste AA, et SplitText amène ses lignes à la pleine couleur une à une (type "lines", mask "lines", aria "auto"). Garde l'entrée par glissement vers le haut sous masque, ligne par ligne, pour les titres h2 sous la ligne de flottaison, et déclenche-la avec ScrollTrigger once:true. Découpe après document.fonts.ready pour que les retours à la ligne soient corrects.
3. Marquee infini : écris les noms des services une seule fois dans le HTML. Sans JS et avec la réduction des animations, la liste s'affiche comme un groupe statique qui passe à la ligne ; réduis cet état statique sur téléphone, car dans la démo il remplissait l'écran d'un mur de six lignes. Le JS duplique le groupe une fois, marque la copie aria-hidden et déplace x en boucle infinie ; il accélère brièvement selon la vitesse de défilement et s'arrête quand le marquee est hors écran. Un mouvement de plus de cinq secondes exige un bouton "Pause" visible selon WCAG 2.2.2 (type="button", aria-pressed), affiché uniquement tant que le marquee bouge réellement. Le focus à l'intérieur du marquee le met aussi en pause.
4. Boutons magnétiques : uniquement sur les appareils correspondant à `(hover: hover) and (pointer: fine)`, utilise gsap.quickTo pour déplacer la transformation x et y de 30 à 40 % de la distance entre le pointeur et le centre du bouton, avec un retour élastique quand le pointeur s'éloigne. La zone cliquable du bouton ne doit pas changer.
5. Trainée d'images au curseur : desktop uniquement, sous la même condition de pointeur précis, dans la zone du hero. Le JS ajoute au hero une couche aria-hidden, avec pointer-events:none, placée SOUS le titre (z-index). Les images de la trainée ne doivent pas être téléchargées au chargement de la page ; les miniatures WebP de 280 px se chargent au premier mouvement du pointeur. Tous les 90 px de déplacement du pointeur, l'image suivante du lot apparait au niveau du pointeur, grossit depuis une petite taille, puis glisse vers le bas et s'estompe ; déplace-la avec transform, pas avec left/top.
6. Active Lenis uniquement sur les appareils `(pointer: fine)` et pilote-le depuis gsap.ticker ; les appareils tactiles gardent le défilement natif. Pour les liens internes à la page, déplace le focus vers la cible après le défilement.
Mise en place et pièges connus (chacun a couté des points ou cassé quelque chose lors de la mesure de la démo, n'en saute aucun) :
1. S'il existe déjà un site en ligne sur le serveur, préviens-moi d'abord, car l'installation écrase index.html et le dossier assets. Prévisualise scaffold_site avec confirm=false et appelle confirm=true après mon accord. Lis ensuite site_design_guide et site_seo_guide. Avant d'écrire du code, consigne l'orientation de design (typographie, couleur, grille, élément signature, langage d'animation et bibliothèques qui ne seront PAS chargées) dans un court ART.md hors du dossier assets et montre-le-moi.
2. Compile Tailwind, ne le charge pas depuis le CDN. Installe `npm i -D tailwindcss@3` avec site_run_command et background=true, et suis-le avec site_command_status. Les chemins content de `tailwind.config.js` doivent couvrir tous les fichiers HTML, tous les gabarits et tous les fichiers JS qui écrivent des classes. `_src/tw.css` contient une ligne `@import "../assets/app.css";` et les trois lignes `@tailwind` ; compile-le en un seul fichier avec `npx tailwindcss -c tailwind.config.js -i _src/tw.css -o assets/site.css --minify`. Retire le script cdn.tailwindcss.com et le tailwind.config en ligne des pages et ne lie que `/assets/site.css`. Recompile après chaque modification du HTML.
3. Auto-héberge les polices. Vérifie d'abord que la famille Fontshare choisie contient les lettres turques (ş, ğ, ı, İ, ç, ö, ü) : dans la démo, Tanker n'avait pas de ı sans point et Outfit n'avait ni ş, ni ğ, ni İ, si bien que ces lettres retombaient sur une autre police dans les titres. Télécharge le woff2 de chaque graisse séparément avec site_fetch dans `assets/fonts/`, écris les règles @font-face avec `font-display: swap` dans `assets/app.css` (design-check y cherche la police personnalisée) et vérifie le nom font-family dans le CSS téléchargé. Précharge les polices de titre et de texte utilisées au-dessus de la ligne de flottaison sur chaque page avec `<link rel="preload" as="font" type="font/woff2" crossorigin>`, avant la feuille de style ; ne précharge pas plus de deux fichiers, car précharger une troisième graisse dans la démo a allongé le LCP mobile de 0,2 seconde. La plupart des polices Fontshare n'ont pas le signe ₺ ; écris donc "TL" pour les prix.
4. Fais du menu et du pied de page du HTML statique. Ne charge ni chrome.js ni site.config.js sur les pages. Écris un petit `chrome-stamp.mjs` qui lit la liste de navigation dans site.config.js et estampille `_src/header.tpl` et `_src/footer.tpl` entre les marqueurs `<!-- nav:start --><!-- nav:end -->` et `<!-- footer:start --><!-- footer:end -->` sur chaque page, en ajoutant aria-current="page" au lien actif. Les gabarits ne doivent pas se terminer par .html et doivent utiliser des marqueurs comme `[[NAV]]` à la place de `{{...}}`. Construis le menu mobile sans JS avec `<details>`. Garde le nom de l'organisation, l'adresse et le téléphone en texte brut dans le pied de page, et donne à chaque cible tactile au moins 44x44 px, liens du pied de page et du fil d'Ariane compris.
5. Convertis les images au moment du téléchargement avec site_fetch : écris la même photo avec resize="480x", "800x" et "1200x", image_format="webp", quality=65 dans des fichiers séparés. site_fetch ne recadre jamais ; quand une photo Unsplash exige un autre ratio, télécharge la version recadrée en ajoutant à son URL des paramètres comme `?w=1600&h=1200&fit=crop`. Donne à chaque `<img>` srcset, sizes ainsi qu'une largeur et une hauteur correspondant au vrai ratio. L'image principale au-dessus de la ligne de flottaison reçoit fetchpriority="high" et n'est pas en lazy ; les autres reçoivent loading="lazy" decoding="async". Si l'image principale remplit l'écran sur mobile, sers un recadrage plus petit avec `<picture>`.
6. Écris la version SVG du logo en favicon.svg avec site_write_file et ajoute `<link rel="icon" href="/favicon.svg" type="image/svg+xml">` à chaque page. Sans favicon, le navigateur enregistre un 404 et Best Practices tombe à 96.
7. Règles du validateur HTML : commence par un `<!DOCTYPE html>` en majuscules, utilise ` ` pour les espaces dans le texte visible des liens tel:, n'utilise jamais d'attribut style="", donne à chaque bouton type="button", et ne place pas de `<details>` dans une `<figure>` après son figcaption.
8. Télécharge les bibliothèques d'animation (GSAP, ScrollTrigger, SplitText, Lenis) depuis jsdelivr dans `assets/vendor/` avec site_fetch, fige la version et ne les charge que sur les pages d'accueil et de réalisations. N'utilise pas `<script defer>` ; place en fin de page un petit loader qui attend l'événement load, deux appels requestAnimationFrame, puis requestIdleCallback, et ajoute les scripts dans l'ordre avec async=false. Un script d'une ligne dans `<head>` ajoute la classe `js` à `<html>` et la classe `anim` sauf si prefers-reduced-motion vaut "reduce" ; sans `anim`, le loader ne télécharge rien. Définis les états de départ masqués uniquement sous `.anim`, et ajoute comme filet de sécurité une animation CSS qui révèle tous les éléments masqués au bout de 2,5 secondes au cas où la bibliothèque n'arriverait jamais. Dans des démos précédentes, les bibliothèques chargées en différé ont fait monter le LCP mobile à 3,2 secondes ; avec ce loader, les pages ont mesuré entre 99 et 100. Nomme l'attribut des éléments révélés au défilement data-reveal ; design-check ne reconnait le mouvement que sous ce nom.
SEO, AEO et GEO :
1. Utilise des URL de type répertoire avec une barre oblique finale (/isler/, /studyo/, /iletisim/, /gizlilik/). Renseigne le bloc seo de site.config.js et exécute `node seo-stamp.mjs`. Écris le schema propre à chaque page (accueil WebPage et FAQPage ; réalisations CollectionPage avec un CreativeWork par projet dans hasPart ; studio AboutPage avec des entrées Person pour l'équipe ; contact ContactPage ; BreadcrumbList sur les pages internes. Pour un studio avec bureau, businessType ProfessionalService dans site.config.js) dans des blocs `<script type="application/ld+json">` séparés et relie-les au graphe de base par @id. N'imbrique pas BreadcrumbList dans @graph ; garde-le dans son propre bloc, car c'est la seule façon pour seo-check de le voir.
2. Garde les titres à 60 caractères ou moins (seo-check signale comme erreur tout ce qui dépasse 65), les descriptions entre 120 et 158 caractères, un seul h1 par page et aucun niveau de titre sauté (un h3 juste après le h1 a fait tomber l'accessibilité à 98). Chaque page exige au moins 150 mots de contenu principal ; les pages de contact et de confidentialité ont tendance à être trop courtes.
3. Le premier paragraphe de chaque page répond directement à la question de la page. Rédige des FAQ propres à chaque page avec `<details>` et balise-les en FAQPage. Affiche l'organisation éditrice et une date de "Dernière mise à jour" dans `<time>`.
4. Dans robots.txt, note et justifie ta décision pour GPTBot, OAI-SearchBot, ChatGPT-User, ClaudeBot, Claude-User, Claude-SearchBot, PerplexityBot, Perplexity-User, Google-Extended, Applebot-Extended, Bingbot et CCBot, et indique le sitemap. Donne à sitemap.xml de vraies dates lastmod. llms.txt contient un résumé exact du site en deux phrases, les faits clés et la liste des pages importantes.
5. Pas d'invention : n'écris ni avis, ni notes, ni récompenses, ni nombres de clients, ni certificats, ni horaires d'ouverture, ni coordonnées, ni prix sans me demander. Laisse totalement hors du schema tout champ que tu ne connais pas.
Portes de validation (dans l'ordre ; ne dis pas "terminé" avant qu'elles soient toutes franchies) :
1. Avec site_run_command, exécute `node chrome-stamp.mjs`, la compilation Tailwind, `node seo-stamp.mjs`, `node seo-check.mjs` (0 erreur, 0 avertissement), `node design-check.mjs` (0 erreur ; justifie tout avertissement restant) et `npx html-validate "**/*.html"` (0 erreur).
2. Affiche chaque page avec site_preview en view="mobile" et view="desktop". site_preview capture la page avec les animations désactivées (reduced-motion) ; si du contenu manque dans cette capture, l'état sans animation est cassé. Les images lazy plus bas dans la page peuvent apparaitre vides dans la capture pleine page ; ne le compte pas comme une erreur, mais vérifie leurs chemins.
3. Lance core_web_vitals avec strategy="mobile" et strategy="desktop" pour chaque page. Critères d'acceptation : sur mobile, Performance d'au moins 95 et Accessibility, Best Practices et SEO à 100 ; sur desktop, les quatre à au moins 95. Pour une page qui échoue, trouve le fichier lent avec resources=true, corrige-le et mesure à nouveau. Lance ensuite seo_audit sur la page d'accueil avec strategy="mobile" et runs=2. Aucune adresse extérieure à ton propre domaine ne doit subsister dans la liste des requêtes réseau.
4. Pas de défilement horizontal à 360, 390, 768 et 1440 px, cibles tactiles d'au moins 44 px et aucune erreur dans la console. Le site doit aussi s'afficher sans défaut dans un cadre de 390x790 et de 1440x898, comme sur les pages de prompts.
Contrôle des animations : site_preview ne peut pas montrer le mouvement ; dis-moi donc ce qu'il faut observer dans mon propre navigateur. Sur desktop, les lignes du titre du hero doivent se foncer l'une après l'autre, le marquee doit défiler, accélérer avec le défilement et s'arrêter avec le bouton Pause, les boutons doivent se pencher légèrement vers le pointeur, déplacer le pointeur sur le hero doit laisser derrière lui des images qui apparaissent et s'estompent, et le texte doit toujours rester au-dessus des images. Sur téléphone, il ne doit y avoir ni trainée ni effet magnétique, et le défilement reste natif. Avec la réduction des animations activée dans le système d'exploitation, rien ne doit bouger et le marquee s'affiche comme une liste statique. L'anneau de focus doit être visible partout lors de la navigation au clavier.
Après la publication : prévisualise avec site_headers la règle `/assets/* Cache-Control: public, max-age=31536000, immutable` et applique-la après mon accord ; à partir de là, versionne le nom du fichier à chaque modification du CSS ou du JS (site-v2.css, etc.). Soumets sitemap.xml avec gsc_submit_sitemap et vérifie la page d'accueil avec gsc_url_inspect. Pour finir, donne-moi : un tableau des scores par page (page, quatre scores mobile, quatre scores desktop, LCP, CLS), les résultats des portes de validation, le résultat des interactions testées dans un navigateur et la liste des corrections appliquées.