Retour au portfolio
WaterBaby Serres — École de Natation pour Bébés & Enfants

WaterBaby Serres — École de Natation pour Bébés & Enfants

WaterBaby Serres accueille des bébés dès quatre mois et des enfants jusqu'à dix ans, dans une piscine intérieure chauffée de l'Elpida Resort. Le site devait s'adresser d'abord aux parents grecs, ensuite aux visiteurs anglophones, sans devenir deux sites. Chaque texte visible est donc écrit deux fois dans le même fichier et le sélecteur ne fait que masquer l'un des deux : une URL par page, aucun rechargement, aucun fetch, aucun second jeu de pages à maintenir, et le grec se lit intégralement sans JavaScript. Six pages portent l'ensemble — accueil, à propos, les deux programmes, galerie et contact — avec les quatre niveaux enfants du débutant à l'avancé, le matériel et les documents nécessaires aux parents, et une FAQ. GSAP et ScrollTrigger sont hébergés localement plutôt que sur un CDN, et chaque animation est additive : rien n'est pré-masqué en CSS, donc un script en échec laisse une page complète et non une page blanche. L'animation d'arrivée fait descendre une vague une fois par session et se retire d'elle-même via des keyframes CSS : elle ne peut pas enfermer un visiteur derrière un calque, même si tout le JavaScript meurt. Les données structurées couvrent les cours, la FAQ, la galerie et le fil d'Ariane ; un llms.txt énonce les faits vérifiés pour les assistants IA et les tests l'arriment aux pages, pour que les deux ne divergent pas. Vingt et un tests Node tiennent l'ensemble — structure des pages, textes grecs, redirections, propriétés de sûreté du loader et contraste WCAG sur chaque surface orange.

Technologies

HTML5 CSS3 Vanilla JS (ES Modules) GSAP 3 ScrollTrigger JSON-LD i18n (EL/EN) Node Test Runner WCAG 2.2 AA SEO

Défis

Un site bilingue, c'est d'ordinaire tout en double — deux jeux de pages, deux URL, deux occasions de mettre l'un à jour en oubliant l'autre. Ici, une seule monitrice le maintient : une deuxième copie de chaque page aurait été une charge, pas une fonctionnalité. Le grec devait aussi être la vraie langue par défaut, lisible avant qu'un script ne s'exécute, puisque le public, ce sont des parents du coin. Et les touches qu'une école de natation réclame — animation d'arrivée, révélations au défilement, une visionneuse — sont précisément ce qui laisse une page blanche quand un script échoue sur un téléphone mal couvert.

Solutions

Les deux langues sont en ligne dans chaque fichier et le sélecteur ne fait que basculer un attribut hidden : une page à modifier, une URL à partager, rien à synchroniser ; la préférence vit dans le localStorage et le changement émet un événement personnalisé que la galerie écoute. Les chaînes non textuelles — aria-labels, placeholders, méta-descriptions, jusqu'au titre du document — se traduisent via des paires d'attributs data traitées par la même fonction, pour qu'une page traduite n'ait aucun recoin oublié. Le mouvement est additif par règle et un test l'impose : le CSS n'a jamais le droit de pré-masquer un élément animé, donc un GSAP qui ne charge pas ne coûte que l'animation. Le calque d'arrivée part masqué et n'est révélé que par une classe ajoutée en JavaScript, tandis que sa sortie est un keyframe CSS en fill-mode forwards — script désactivé, bloqué ou planté, le calque se retire quand même. Les bibliothèques sont hébergées localement pour qu'une panne de CDN n'emporte pas le mouvement du site, et chacun des vingt et un tests a été vérifié en cassant volontairement ce qu'il protège.