diff --git a/CLAUDE.md b/CLAUDE.md index 89cb52f..0cdd1cd 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -373,7 +373,9 @@ plein ont tous les deux été essayés et jugés trop nets avant ça. Les PDF portent des métadonnées (titre, auteur, langue) posées par `scripts/generate-pdf.js` via `pdf-lib`. Titres ≤ 60 caractères, descriptions ≤ 160 (Google coupe au-delà ; textes de la mission SEO du - 24/09/2026 dans `PROFILE.seo` et `results.metaDescription`) ; `favicon.ico` + 24/09/2026 dans `PROFILE.seo` et `results.metaDescription`, suffixe des + pages projet et description FR de l'accueil raccourcis le 25/09 avec + l'accord d'Antoine), vérifiés sans exception par `check-seo.mjs` ; `favicon.ico` multi-tailles à la racine, rendu depuis `assets/favicon.svg`. - **Site considéré fonctionnellement complet** (sept. 2026) : bilingue, PDF, Fit-Checker IA, hero cliquable + études de cas STAR, side project diff --git a/README.md b/README.md index 38fd0cf..93ce766 100644 --- a/README.md +++ b/README.md @@ -361,7 +361,9 @@ détail ne demande de toucher qu'à `data.js`, jamais à le projet en ligne) comme d'habitude. 2. Ajoute une clé correspondante dans `PROJECT_DETAILS` (juste après `SIDE_PROJECTS` dans `data.js`) : le plus simple est de **copier l'entrée - `tour-de-growth` et de remplacer les textes**. Champs : `title`, + `tour-de-growth` et de remplacer les textes**. Champs : `title` (le titre + de l'onglet devient « — étude de cas · Antoine Berthaud », 60 + caractères au plus : un nom de projet de plus de 26 caractères dépasse), `tagline`, `metaDescription` (`{fr, en}`, 160 caractères au plus : ce que Google affiche), `liveUrl`, `problem`, `whatItIs` (+ `whatItIsPoints` et `whatItIsClosing` optionnels), `teachingMoment` (optionnel, `{title, diff --git a/en/projects/tour-de-growth.html b/en/projects/tour-de-growth.html index bbc96c1..f98b947 100644 --- a/en/projects/tour-de-growth.html +++ b/en/projects/tour-de-growth.html @@ -9,7 +9,7 @@ entièrement générées : on ne modifie que ce gabarit (structure) et data.js / i18n.js (textes). Titre, description et og:/twitter: sont posés par le générateur dans la langue de la page. --> -<title>Tour de Growth — case study · Antoine Berthaud, Product Manager +Tour de Growth — case study · Antoine Berthaud @@ -24,7 +24,7 @@ - + @@ -32,7 +32,7 @@ - + @@ -48,7 +48,7 @@ "@type": "WebPage", "@id": "https://cv.antoine.berthaud.me/en/projects/tour-de-growth.html#page", "url": "https://cv.antoine.berthaud.me/en/projects/tour-de-growth.html", - "name": "Tour de Growth — case study · Antoine Berthaud, Product Manager", + "name": "Tour de Growth — case study · Antoine Berthaud", "description": "Tour de Growth, a side project by Antoine Berthaud: a check-up that maps your growth strategy onto the 5 AARRR pillars, no jargon. Product approach and stack.", "inLanguage": "en", "author": { diff --git a/index.html b/index.html index 3e8c736..55b1061 100644 --- a/index.html +++ b/index.html @@ -22,7 +22,7 @@ lisent les robots sans JavaScript ; app.js ne les touche plus que s'ils diffèrent de data.js (page pas encore régénérée, signalée en console). --> Antoine Berthaud · Senior Product Manager Growth à Nantes - + -Tour de Growth — étude de cas · Antoine Berthaud, Product Manager +Tour de Growth — étude de cas · Antoine Berthaud @@ -24,7 +24,7 @@ - + @@ -32,7 +32,7 @@ - + @@ -48,7 +48,7 @@ "@type": "WebPage", "@id": "https://cv.antoine.berthaud.me/projets/tour-de-growth.html#page", "url": "https://cv.antoine.berthaud.me/projets/tour-de-growth.html", - "name": "Tour de Growth — étude de cas · Antoine Berthaud, Product Manager", + "name": "Tour de Growth — étude de cas · Antoine Berthaud", "description": "Tour de Growth, side project d'Antoine Berthaud : un check-up qui situe sa stratégie growth sur les 5 piliers AARRR, sans jargon. Démarche produit et stack.", "inLanguage": "fr", "author": { diff --git a/scripts/check-seo.mjs b/scripts/check-seo.mjs index 478aec8..0a5a25e 100644 --- a/scripts/check-seo.mjs +++ b/scripts/check-seo.mjs @@ -849,17 +849,11 @@ async function lot4(browser) { const cp = ld && ld["@graph"].find((n) => n["@type"] === "CollectionPage"); check(4, "4.1-description", `${pg.path} : description de la mission dans la meta, og:, twitter: et le JSON-LD`, info.description === d && sameDesc(d) && cp && cp.description === d && cp.name === info.title, `${(info.description || "").length} car.`); } - // Longueurs. Les textes que la mission a fixés doivent tenir ; ceux - // qu'elle ne fournit pas (titre des pages projet, description de - // l'accueil) sont signalés sans faire échouer, en attendant une décision. - const fixedTitle = pg.kind === "home" || pg.kind === "results"; - const fixedDesc = pg.kind === "results" || pg.kind === "project"; + // Longueurs : tous les titres et descriptions doivent tenir. const tl = info.title.length, dl = (info.description || "").length; - if (tl <= MAX_TITLE || fixedTitle) check(4, "4.1-len-title", `${pg.path} : titre ≤ ${MAX_TITLE} caractères`, tl <= MAX_TITLE, `${tl} car.`); - else skip(4, "4.1-len-title", `${pg.path} : titre ≤ ${MAX_TITLE} caractères`, `⚠ ${tl} car. — texte hors mission, à décider (voir le rapport)`); - if (dl <= MAX_DESCRIPTION || fixedDesc) check(4, "4.1-len-desc", `${pg.path} : description ≤ ${MAX_DESCRIPTION} caractères`, dl <= MAX_DESCRIPTION, `${dl} car.`); - else skip(4, "4.1-len-desc", `${pg.path} : description ≤ ${MAX_DESCRIPTION} caractères`, `⚠ ${dl} car. — texte hors mission, à décider (voir le rapport)`); + check(4, "4.1-len-title", `${pg.path} : titre ≤ ${MAX_TITLE} caractères`, tl <= MAX_TITLE, `${tl} car.`); + check(4, "4.1-len-desc", `${pg.path} : description ≤ ${MAX_DESCRIPTION} caractères`, dl <= MAX_DESCRIPTION, `${dl} car.`); } await rawCtx.close(); diff --git a/sitemap.xml b/sitemap.xml index bd9b3d1..a49d419 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -13,7 +13,7 @@ https://cv.antoine.berthaud.me/ - 2026-09-24 + 2026-09-25 @@ -41,14 +41,14 @@ https://cv.antoine.berthaud.me/projets/tour-de-growth.html - 2026-09-24 + 2026-09-25 https://cv.antoine.berthaud.me/en/projects/tour-de-growth.html - 2026-09-24 + 2026-09-25