Constructeur de Landing Page — Pattern CAE
Description Générale
Ce skill vous aide à créer une landing page de haute qualité (selon le pattern EEC de CAE Vietnam) à partir des informations fournies par l'utilisateur. L'ensemble du processus est effectué par Antigravity — l'utilisateur n'a qu'à répondre aux questions.
Livrables finaux :
index.html+styles.css— Landing page complète, responsive, avec animationsgoogle-apps-script.js— Backend qui reçoit les données du formulaire → écrit dans Google Sheets → envoie un email de notification- Instructions étape par étape pour le déploiement sur Cloudflare Pages
Architecture de la Page EEC (Blueprint Standard)
1. NAV — sticky, flou au défilement, logo + liens + bouton CTA
2. HERO — plein écran, dégradé rouge, particules, titre + sous-titre + 2 boutons
3. BARRE DE STATISTIQUES — 4 chiffres clés, compteur animé
4. POURQUOI NOUS — 6 cartes de fonctionnalités avec effets au survol (3 colonnes)
5. FORMATEUR (optionnel) — Intégration YouTube Short + diplômes
6. COURS — 3 cours, carte mise en avant au milieu, encadré de prix
7. TIMELINE — feuille de route sur N semaines en grille
8. TÉMOIGNAGES — 3 cartes d'avis avec étoiles
9. FAQ — accordéon avec extension/réduction
10. CTA + FORMULAIRE — section avec dégradé, formulaire d'inscription → Google Sheets + email
11. PIED DE PAGE — 3 colonnes : marque, cours, contact
PROCESSUS (À SUIVRE DANS L'ORDRE)
PHASE 0 : Scan & Contexte (À EXÉCUTER EN PREMIER)
Avant de poser la moindre question, vérifiez l'environnement et cherchez un contexte antérieur :
-
Vérifier si Mem0 est disponible :
- Essayez d'appeler
search_memoryavec la requête :"landing page preference couleur police domaine" - Si l'outil N'EXISTE PAS / signale une erreur → ignorez-le complètement, passez à la Phase 1 immédiatement, sans signaler l'erreur à l'utilisateur
- Si l'outil existe et trouve quelque chose → signalez : "Je me souviens que la dernière fois vous aviez utilisé [couleur X / police Y / domaine Z]. On garde la même chose ou on change ?"
- Si l'outil existe mais ne trouve rien → procédez normalement à la Phase 1
- Essayez d'appeler
-
Sauvegarder le nouveau contexte (si Mem0 est disponible) — après que l'utilisateur a confirmé les 7 groupes, appelez
add_memory:Landing page [nom de la campagne] : couleur=[hex], police=Be Vietnam Pro, domaine=[domaine], email=[email], sheet=[lien sheet]- Si Mem0 n'est pas disponible → ignorez cette étape, cela n'affecte pas le résultat
Principe de conception : Mem0 est une fonctionnalité supplémentaire (amélioration progressive), pas une dépendance obligatoire. Le skill doit fonctionner parfaitement sur une machine sans Mem0.
PHASE 1 : Collecte des Informations (Poser les questions groupe par groupe, attendre la réponse)
⚠️ IMPORTANT : Posez les questions UN GROUPE À LA FOIS. Ne posez pas toutes les questions en une fois. Après que l'utilisateur a répondu à un groupe, passez au suivant.
Groupe A — Marque & Couleurs
Demandez :
Pour créer la landing page, j'ai besoin de quelques informations de base.
**Groupe 1 : Marque**
1. Quel est le nom de votre marque/centre ? (Ex : CAE Vietnam, Centre ABC...)
2. URL du logo PNG (ou dites "pas de logo" pour utiliser du texte à la place)
3. Quelle couleur principale souhaitez-vous utiliser ?
- 🔴 Rouge CAE (comme la page EEC) — #8F1A1A + or #FEC46F
- 🔵 Bleu marine professionnel — #1A3A5C + cyan #00C9FF
- 🟢 Vert frais — #0D6E3F + or #FFD700
- ✏️ Je veux entrer une autre couleur (fournissez le code hex)
4. Nom de domaine prévu ? (Ex : offre.nomdecole.com ou "pas encore")
Groupe B — Contenu Hero
Après avoir reçu le Groupe A, demandez :
**Groupe 2 : Section d'en-tête (Hero Section)**
1. Quel titre principal souhaitez-vous afficher ? (Ex : "Bourse 100% Chinois Académique")
2. Petit slogan au-dessus du titre ? (Ex : "Programme pilote — Nombre limité")
3. Brève description (1-2 phrases) sous le titre ?
4. Texte du bouton CTA principal ? (Ex : "📝 Inscrivez-vous maintenant", "🎓 Obtenez la bourse")
5. Avez-vous 4 chiffres statistiques à afficher ? (Ex : 3 classes, 100% gratuit, 8 semaines, 15 élèves/classe)
Groupe C — Points Forts & Cours
Après avoir reçu le Groupe B, demandez :
**Groupe 3 : Points forts & Produits**
1. Énumérez 3 à 6 points forts (chacun comprend : une icône emoji, un titre court, une description de 1 à 2 phrases)
Ex : 🎓 Programme sous licence | Licence achetée auprès d'un partenaire international...
2. Énumérez 1 à 3 cours/packages de services (chacun comprend) :
- Nom du cours
- Petit badge (Ex : "En ligne · 8 semaines", "Présentiel · Hanoï")
- 3-4 fonctionnalités clés
- Prix original (à barrer)
- Prix promotionnel / "100% GRATUIT" / pourcentage de réduction
- Note (Ex : "Seulement 15 places")
- Quel cours est "le plus mis en avant" ?
Groupe D — Parcours & Formateur
Après avoir reçu le Groupe C, demandez :
**Groupe 4 : Contenu supplémentaire**
1. Avez-vous un parcours d'apprentissage par semaine ? (Si oui, énumérez N semaines avec le nom du thème)
2. Avez-vous un formateur/expert à présenter ?
- Nom, titre
- Lien vidéo YouTube (optionnel)
- 3 certifications/réalisations marquantes
3. Avez-vous 3 témoignages de clients ?
(Initiales, nom complet, rôle, contenu de la citation)
Groupe E — FAQ & Contact
Après avoir reçu le Groupe D, demandez :
**Groupe 5 : FAQ & Contact**
1. Énumérez 5 à 7 questions fréquemment posées et leurs réponses ?
2. Informations de contact :
- Adresse du bureau
- Hotline/Zalo
- Email
- URL de la page Facebook
3. Copyright du pied de page : "© 2025 [Nom de l'organisation]"
Groupe F — Formulaire & Backend
Après avoir reçu le Groupe E, demandez :
**Groupe 6 : Formulaire d'inscription & connexion des données**
1. Quels champs le formulaire doit-il collecter ?
- [x] Nom complet (obligatoire)
- [x] Numéro de téléphone (obligatoire)
- [ ] Email
- [ ] Adresse / Ville
- [ ] Case à cocher pour choisir le cours
- [ ] Zone de texte pour les notes
- [ ] Autre champ ?
2. Quel email recevra les notifications en cas d'inscription ?
(Ex : [email protected])
3. Quel objet d'email de notification souhaitez-vous utiliser ?
(Ex : "🔔 Nouvelle inscription depuis la Landing Page !")
4. Veuillez envoyer le lien Google Sheet dans lequel vous souhaitez enregistrer les données d'inscription.
(Je créerai le script en fonction des champs du formulaire ci-dessus, puis je vous guiderai pour l'exécuter sur cette feuille)
⚠️ Après que l'utilisateur a envoyé le lien Sheet → ARRÊTEZ-VOUS et exécutez immédiatement la PHASE 2.
Groupe G — Déploiement Cloudflare
Après avoir reçu le Groupe F, demandez :
**Groupe 7 : Informations de déploiement (dernière étape)**
1. Votre Cloudflare Account ID ?
(Allez sur dash.cloudflare.com → sélectionnez votre compte → regardez l'URL : cloudflare.com/ACCOUNT_ID)
2. Votre Cloudflare API Token ?
(Allez dans My Profile → API Tokens → Create Token → utilisez le template "Edit Cloudflare Pages")
3. Nom du projet Cloudflare Pages ? (minuscules, tirets, Ex : ma-landing-2025)
4. Domaine personnalisé à attribuer ? (Ex : offre.domaine.com ou "pas besoin")
PHASE 1.5 — VISION 10 ÉTOILES ⭐ (OBLIGATOIRE avant la génération)
"Ne concevez pas pour des millions de personnes. Concevez pour qu'UNE SEULE personne ait l'expérience la plus époustouflante qu'elle ait jamais vécue." — Garry Tan
Arrêtez-vous et répondez à ces 4 questions AVANT d'écrire une seule ligne de code :
-
Le titre est-il "percutant" ?
- Lisez le titre en 3 secondes : le client sait-il immédiatement que c'est pour lui ?
- Si ce n'est pas assez fort → appliquez la formule Copy Formula de ce skill pour le réécrire
-
Cette page a-t-elle UNE CHOSE INOUBLIABLE ?
- Un chiffre impressionnant ? Un engagement audacieux ? Un avantage inattendu ?
- Ex : "Apprenez gratuitement à 100% — Seulement 15 places" → clair, rare, action immédiate
-
Quel défaut mortel cette landing page pourrait-elle avoir ?
- Formulaire avec trop de champs ? Hero sans preuve sociale ? CTA fade ?
- Identifiez-le et corrigez-le immédiatement dans le design
-
Si Steve Jobs examinait cette page, que supprimerait-il ?
- Éliminez tout ce qui ne sert pas l'unique objectif : l'inscription
Livrable : Note de vision dans la réponse avant de continuer :
🎯 VISION 10 ÉTOILES :
- Point fort unique : [..]
- Titre final : [..]
- 1 chose inoubliable : [..]
- Déjà supprimé : [..]
RÈGLE DU FOUNDER CHALLENGE (Applicable à la Porte de la Vision)
"Jouez le rôle du CEO — la mission est de défier la médiocrité, pas de la reconnaître."
Si l'utilisateur fournit un titre faible (générique, pas de public cible clair, pas d'avantage spécifique), NE L'ACCEPTEZ PAS immédiatement. Proposez plutôt :
⚡ Mode Fondateur :
Le titre "[titre de l'utilisateur]" est encore générique. Je propose 3 alternatives plus percutantes :
[A] [Avantage spécifique] — [chiffre/temps] — [public cible clair]
Ex : "Apprenez le chinois académique gratuitement à 100% — Seulement 15 places"
[B] [Question d'accroche] + [résultat surprenant]
Ex : "Votre enfant apprend le chinois en 8 semaines — plus confiant que les élèves internationaux ?"
[C] [Engagement audacieux] + [preuve]
Ex : "Aucun progrès après 4 séances — remboursement 100%, sans poser de questions"
Quelle direction préférez-vous, ou souhaitez-vous que je réécrive autrement ?
Quand challenger : Le titre ne contient pas au moins 2 des 3 éléments : (1) public cible clair, (2) avantage spécifique, (3) chiffre/engagement.
PHASE 2 : Création du Google Apps Script (Backend)
Déclencheur : L'utilisateur a envoyé le lien Google Sheet (Groupe F.4).
Étape 1 — Générer le script personnalisé :
Basé sur le modèle dans templates/google-apps-script.js, créez un script personnalisé selon le formulaire exact de la landing page :
- Remplissez
NOTIFICATION_EMAIL= email du Groupe F.2 - Remplissez
EMAIL_SUBJECT= objet du Groupe F.3 - Remplissez
CAMPAIGN_NAME= nom de la campagne du Groupe A.1 - Mettez à jour la fonction
writeToSheet()pour avoir le bon nombre de colonnes correspondant aux champs du formulaire du Groupe F.1 - Mettez à jour la fonction
doPost()pour analyser correctement lese.parameterselon les champs sélectionnés
Étape 2 — Afficher le bloc de code à copier par l'utilisateur :
Après la génération, affichez la TOTALITÉ du code dans un seul bloc comme suit :
✅ J'ai terminé la création du script pour votre Google Sheet !
Voici le code à copier et coller dans votre Sheet :
[BLOC DE CODE]
📋 INSTRUCTIONS POUR L'EXÉCUTER SUR VOTRE GOOGLE SHEET (5 étapes) :
① Ouvrez le Google Sheet dont vous venez d'envoyer le lien → Allez dans le menu Extensions → Apps Script
(Ou cliquez sur le lien de ce Sheet, puis cherchez le menu Extensions dans la barre supérieure)
② Supprimez tout le code par défaut dans l'éditeur (Ctrl+A → Supprimer)
③ Collez tout le code que j'ai créé ci-dessus (Ctrl+V)
④ Appuyez sur Ctrl+S pour enregistrer → Nommez le projet "Gestionnaire Landing Page" → OK
⑤ Déployez le script :
• Cliquez sur le bouton "Déployer" (en haut à droite) → "Nouveau déploiement"
• Section "Type" : choisissez "Application Web"
• Section "Exécuter en tant que" : choisissez "Moi (votre email)"
• Section "Qui a accès" : choisissez "Tout le monde"
• Cliquez sur "Déployer" → Google demandera des autorisations → Cliquez sur "Autoriser l'accès" → Sélectionnez le compte Google
• Copiez l'URL longue qui apparaît (format : https://script.google.com/macros/s/.../exec)
📌 Une fois que vous avez cette URL, collez-la ici pour que je l'intègre dans la landing page.
Étape 3 — Attendez que l'utilisateur confirme l'URL SHEETS_ENDPOINT avant de continuer vers la PHASE 3.
PHASE 3 : Génération du HTML de la Landing Page
En fonction de toutes les informations collectées, créez le fichier index.html complet :
Structure du fichier à créer :
- Un seul fichier
index.html(CSS en ligne dans la balise<style>, NE PAS séparer en fichiers distincts) - JavaScript de soumission de formulaire en ligne dans la balise
<script> - Aucune dépendance à un framework, uniquement du HTML/CSS/JS vanille
- Entièrement responsive (mobile-first)
- Utilisez Be Vietnam Pro (chargé depuis le CDN Google Fonts) — prend en charge tous les accents vietnamiens, remplace Inter/Montserrat
Conception selon le pattern EEC :
- Palette de couleurs du Groupe A.3
- Toutes les sections du blueprint
- Si l'utilisateur ne fournit pas de formateur → supprimez cette section
- S'il n'y a pas de témoignages → supprimez cette section
- S'il n'y a pas de timeline → supprimez cette section
Modèle de soumission de formulaire (DOIT utiliser un iframe caché — éviter CORS) :
const SHEETS_ENDPOINT = 'URL_GAS_DE_L_UTILISATEUR'; // Remplissez l'URL de l'Étape 2
const hiddenFrame = document.createElement('iframe');
hiddenFrame.name = 'hidden_iframe';
hiddenFrame.style.display = 'none';
document.body.appendChild(hiddenFrame);
// Lors de la soumission : créer un formulaire caché, POST vers le point de terminaison GAS, cibler l'iframe caché
// N'utilisez pas fetch() — le POST de formulaire natif n'est pas bloqué par CORS
Sauvegarde localStorage :
// Faites toujours une sauvegarde dans localStorage avant la soumission
const regs = JSON.parse(localStorage.getItem('lp_registrations') || '[]');
regs.push(data);
localStorage.setItem('lp_registrations', JSON.stringify(regs));
UI Optimiste + Résilience GAS (OBLIGATOIRE) :
// 1. Afficher le succès IMMÉDIATEMENT — ne pas attendre la réponse GAS
function submitForm(data) {
// Sauvegarde localStorage d'abord
backupToLocal(data);
// Afficher le message de succès immédiatement (optimiste)
showSuccessMessage();
// Soumettre à GAS en arrière-plan — ne pas bloquer l'UI
submitToGAS(data).catch(() => {
// GAS échoue mais localStorage a la donnée → nouvelle tentative silencieuse
scheduleRetry(data);
});
}
// 2. Nouvelle tentative automatique si GAS échoue
function scheduleRetry(data, attempt = 1) {
if (attempt > 3) return; // Abandon après 3 tentatives
setTimeout(() => {
submitToGAS(data).catch(() => scheduleRetry(data, attempt + 1));
}, attempt * 3000); // 3s, 6s, 9s
}
// 3. Timeout GAS de 10s (ne pas faire attendre l'utilisateur indéfiniment)
async function submitToGAS(data) {
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 10000);
try {
// Utiliser le mode fetch no-cors (GAS ne renvoie pas de corps de réponse)
await fetch(SHEETS_ENDPOINT, {
method: 'POST', mode: 'no-cors',
body: new URLSearchParams(data),
signal: controller.signal
});
} finally {
clearTimeout(timeout);
}
}
Note : Le mode
no-corsavecfetch+URLSearchParamsest une alternative à l'iframe caché, non bloquée par CORS. Utilisez l'une ou l'autre selon le contexte.
PHASE 3.5 — VÉRIFICATION NAVIGATEUR (Avant le déploiement)
Déclencheur : Le fichier index.html a été créé.
Utilisez l'outil navigateur pour vérifier avant d'informer l'utilisateur :
- Ouvrez le fichier dans le navigateur (ou un serveur local)
- Vérification responsive :
- Mobile 375px : le menu ne casse pas, le formulaire tient à l'écran, le texte n'est pas coupé
- Desktop 1440px : pas trop large, mise en page équilibrée
- Vérification UX :
- Bouton CTA visible sans défilement
- Soumission du formulaire : remplissez des données de test → vérifiez qu'il n'y a pas d'erreur dans la console
- L'accordéon FAQ s'ouvre/se ferme
- Défilement fluide, pas de saccades
- Vérification visuelle :
- Couleurs conformes à la palette choisie
- Police chargée correctement (Be Vietnam Pro)
- Aucun texte placeholder restant
- Capture d'écran et rapport : Prenez des captures d'écran desktop + mobile, envoyez-les à l'utilisateur pour prévisualisation
⚠️ TOUS les points de cette checklist DOIVENT ÊTRE VALIDÉS avant d'exécuter la PHASE 3.6 Raffinement et la PHASE 4 Déploiement.
PHASE 3.6 — PASSAGE DE RAFFINEMENT (Polissage)
Après que l'utilisateur a confirmé le contenu, effectuez un tour de polissage :
- Micro-animations : Ajoutez
fade-inau défilement pour chaque section (IntersectionObserver) - Effets de survol : Légère mise à l'échelle du bouton au survol (
transform: scale(1.03)) - Pulsation CTA : Le bouton d'inscription principal a une animation de pulsation subtile pour attirer l'œil
- Animation des compteurs : Les chiffres des statistiques (3 classes, 500+ élèves) comptent vers le haut lors de l'entrée dans la zone d'affichage
- Retour du formulaire : Affichez l'état de chargement lors de la soumission, message de succès après l'envoi
- Flou de la barre de navigation : Lors du défilement, la barre de navigation a un arrière-plan flou
PHASE 4 : Déploiement sur Cloudflare Pages
Déclencheur : Tous les contenus sont finalisés et vérifiés.
Étape 1 — Demander à l'utilisateur AWAY MODE :
⚠️ Prêt à déployer ! Veuillez confirmer que ce qui précède est OK, puis le déploiement commencera.
Pendant le déploiement, veuillez NE PAS taper de message (l'agent a besoin d'attention exclusive).
✅ [Prêt à déployer] ou 🔄 [Modifier quelque chose]
Étape 2 — Exécuter 3 commandes Cloudflare :
Après avoir reçu la confirmation, utilisez les commandes suivantes (les variables d'environnement ont été collectées dans la Phase 1, Groupe G) :
# 1. Créer le dossier de déploiement
mkdir -p deploy-landing-{NOM_PROJET} && cd deploy-landing-{NOM_PROJET}
# 2. Créer le fichier index.html dans ce dossier
cat > index.html << 'EOF'
[CONTENU DU FICHIER INDEX.HTML]
EOF
# 3. Déployer sur Cloudflare Pages
npx wrangler pages project create {NOM_PROJET} --production-branch main
npx wrangler pages deploy . --project-name {NOM_PROJET}
Après le déploiement :
✅ Déploiement réussi !
🌐 URL de déploiement : [URL fournie par Cloudflare]
🔗 Domaine personnalisé : [si fourni]
📋 RÉCAPITULATIF COMPLET :
- Landing page : [URL]
- Google Sheet : [lien Sheet]
- Script Apps Script : déployé ✅
- Backend email : prêt ✅
- Formulaire : opérationnel ✅
🚀 PROCHAINES ÉTAPES :
- Vérifiez le bon fonctionnement en remplissant un test
- Surveillez les inscriptions dans Google Sheet
- Activez le cache Cloudflare si nécessaire
ANNEXE : Règles de Style & de Code
Structure de Base HTML
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Landing Page — [NOM DE LA MARQUE]</title>
<link href="https://fonts.googleapis.com/css2?family=Be+Vietnam+Pro:wght@300;400;500;600;700;800&display=swap" rel="stylesheet">
<style>
/* Reset CSS standard */
</style>
</head>
<body>
...
<script>
// Script de formulaire
</script>
</body>
</html>
Palette de Couleurs (Préréglages)
| Style | Couleur Principale | Couleur d'Accent | Texte Sombre | Arrière-plan Clair |
|---|---|---|---|---|
| 🔴 Rouge CAE | #8F1A1A | #FEC46F | #1a1a2e | #fef6f0 |
| 🔵 Bleu Marine | #1A3A5C | #00C9FF | #0d1b2a | #f0f4f8 |
| 🟢 Vert | #0D6E3F | #FFD700 | #1a2e1a | #f0f8f4 |
| ✏️ Personnalisée | [hex user] | Complémentaire | #1a1a2e | #f8f8f8 |
Principes de Responsive Design
- Mobile-first : Conçu d'abord pour 375px, puis élargi
- Breakpoints : 768px (tablette), 1024px (desktop), 1280px+ (large)
- Typographie :
clamp()pour les tailles de policeh1 { font-size: clamp(1.75rem, 4vw, 3.25rem); } p { font-size: clamp(0.95rem, 1.5vw, 1.15rem); } - Grille :
gridavecauto-fitetminmax.features-grid { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); } - Espacement : Padding des sections
clamp(3rem, 8vw, 6rem) - Formulaires : Pleine largeur sur mobile, largeur max de 400px sur desktop
Animations et Effets
Fade-in au défilement (IntersectionObserver) :
document.querySelectorAll('.section').forEach(s => {
const observer = new IntersectionObserver(([e]) => {
e.target.classList.toggle('visible', e.isIntersecting);
}, { threshold: 0.1 });
observer.observe(s);
});
.section { opacity: 0; transform: translateY(24px); transition: opacity 0.6s, transform 0.6s; }
.section.visible { opacity: 1; transform: translateY(0); }
Compteur animé :
function animateCounter(el, target, duration = 2000) {
const start = performance.now();
const update = (now) => {
const progress = Math.min((now - start) / duration, 1);
el.textContent = Math.floor(progress * target);
if (progress < 1) requestAnimationFrame(update);
};
requestAnimationFrame(update);
}