Ce que c’est
Un site de resort, complet : accueil pleine hauteur avec sa barre de réservation, cinq tuiles de présentation dont une vidéo, quatre séjours numérotés, un carrousel de quatre chambres, les avis, cinq questions et un bloc d’appel derrière deux murs de photos qui dérivent. Une seule page, un seul fichier HTML.
Le design reprend celui d’un template Webflow. Tout le reste a été
refait : l’original tenait dans 345 Ko de CSS minifié, jQuery, trois
bundles Webflow, deux moteurs d’animation propriétaires
— l’ancien et le nouveau, tous deux chargés — GSAP avec ScrollTrigger et
SplitText, une bibliothèque de défilement fluide, et cinq blocs portant
un style="opacity:0" en ligne qu’une politique de sécurité
stricte bloque, ce qui suffit à rendre la page blanche.
Les 27 photographies ont été générées pour ce template, et la vidéo est calculée en local à partir de l’une d’elles. Rien ici ne dépend d’une licence qui n’est pas la nôtre — sauf les polices, sous licence libre.
C’est le point important : ce template n’est pas là pour être admiré, il est là pour être lu, cassé et remonté.
Ce que tu changes en premier
Les couleurs — une ligne
Tout en haut de assets/css/style.css :
--ink-rgb: 11 43 51; /* #0b2b33 */
Elle teint tout : le texte, les boutons, le pied, et chacun des gris de
la page — qui ne sont que cette encre à une opacité plus faible. La
changer suffit à reteindre le site entier. L’original était un bleu nuit
froid, #0b1f33 ; Motuvai le décale vers le bleu-vert du
lagon.
L’accent existe en trois nuances qui vont ensemble :
--ink pour le plein (14,9:1 sur blanc), --ink-strong
pour le survol (18,8:1) et --ink-light pour l’accent posé sur
une photographie (7,9:1 sur l’encre). En changer une oblige à changer les
trois, sinon l’état enfoncé cesse de se lire comme la même couleur. Le
gris des textes secondaires tient à 4,7:1 — juste
au-dessus du seuil AA : l’éclaircir le ferait passer dessous.
Le nom
Cherche « Motuvai » dans index.html : il apparaît dans le
titre, la barre, le pied, le mot géant du bas de page et deux questions.
Aucune classe CSS ne contient la marque, et le logo est du texte : un
rechercher-remplacer ne peut rien casser, et il n’y a aucune image à
refaire.
Les tailles
L’échelle typographique est déclarée une fois en haut de la feuille, puis
redéclarée à 767 et à 479 px. Un titre n’a donc jamais sa propre media
query : tu changes --h2-size et tous les h2 de
la page suivent.
Les quatorze effets, et comment ils sont faits
L’original porte deux moteurs d’animation à la fois. Les deux ont été extraits du bundle et lus : 296 événements pour 39 listes d’actions côté ancien moteur — il en crée un par élément, pas par effet — et 8 interactions côté nouveau. Après déduplication et croisement avec ce que la page d’accueil porte réellement, il reste quatorze effets distincts.
| Effet | Réglages d’origine | Comment |
|---|---|---|
| Apparition en fondu net (7 blocs) | opacité 0 → 1 en 1 000 ms ease, flou 5 → 0 px sur 1 000 ms retardé de 200 ms | [data-reveal] et un IntersectionObserver ; seuil déplacé à 15 % du bas de l’écran |
| La même, plus lente | 1 400 ms pour l’accueil | un seul jeton redéclaré, --reveal-time |
| Parallaxe des photos (8) | y −15 % → 0 % sur toute la traversée de l’écran | le script écrit une progression de 0 à 1 dans --p, le CSS en fait la translation. La photo est un cinquième plus haute que son cadre : c’est ce surplus qui défile |
| Redressement des séjours (3 sur 4) | y −100 px → 0 et rotation −3° → 0°, sur les 30 premiers pour cent de la traversée | le même --p, borné à 0,3 |
| Zoom au survol | échelle 1 → 1,1 en 500 ms outCirc | identique, même courbe |
| Flou des liens voisins | survol d’un lien du pied : les autres passent à 7 px de flou en 500 ms | deux règles CSS, zéro JavaScript |
| Voisins estompés | survol d’un lien de la barre : les autres tombent à 32 % en 300 ms | les deux mêmes règles, appliquées à la barre |
| Libellé de bouton qui roule | texte découpé en caractères, y → −1.5em en 635 ms, décalage réparti sur 100 ms | le script découpe et double le texte, le CSS transitionne chaque lettre avec son index. Sans script, le bouton reste un bouton |
| Fond de bouton qui s’enfonce | échelle → 0,95 au survol | identique |
| Murs de photos qui dérivent | y 0 → −50 % et −50 % → 0 en 25 s, linéaire, en boucle, colonnes inclinées de 31° | deux @keyframes sur deux bandes identiques empilées : glisser d’exactement la moitié remet la seconde là où la première commençait, donc pas de raccord visible |
| Compteur de la note | flou 6 → 0 px en 2,25 s power2.out, valeur 0 → 9,7 en 2 s | une boucle d’animation et la courbe 1 − (1 − t)² |
| Accordéon des questions | hauteur 0 ↔ auto en 400 / 500 ms outCirc, le « + » pivote | <details> natif ; la hauteur est animée par le script, parce qu’un <details> fermé est masqué par le navigateur et qu’aucune keyframe n’y rejoue |
| Carrousel des chambres | slider Webflow, fiche centrale nette, voisines réduites et floutées | scroll-snap natif : il glisse, se balaye et s’atteint au clavier sans JavaScript. Le script n’ajoute que les flèches, l’annonce de position et le flou des voisines |
| Menu et sous-menu | ouverture en 200 / 500 ms, hauteur 0 ↔ 100 %, chevron 0 ↔ 180° | identique, plus deux délais au survol pour laisser le curseur traverser le vide, la fermeture à l’Échap et au clic sur un lien |
Trois effets déclarés dans le registre ne jouent nulle part sur cette page — c’est exactement ce que la déduplication met au jour, et ils n’ont donc pas été repris : un décalage de texte lettre à lettre dont aucun élément ne porte l’attribut, une parallaxe qui appartient à une autre page du gabarit, et le bandeau promotionnel de l’éditeur.
Ce qu’il faut savoir
- Aucune requête externe. Vérifié en listant les requêtes du chargement : elles sont toutes locales. L’original chargeait jQuery, trois bundles Webflow, trois fichiers GSAP, une bibliothèque de défilement et deux polices depuis quatre domaines.
-
L’apparition au scroll ne peut pas masquer le contenu.
L’état caché n’existe que si le JavaScript a tourné. Vérifié en coupant
les scripts : les 19 titres restent visibles, le menu est déplié, les
cinq questions s’ouvrent et le carrousel se fait glisser. L’original,
lui, posait
opacity: 0en attribut de style sur cinq blocs — ce qu’une politique de sécurité stricte bloque, et la page devient blanche. - Zéro style et zéro script en ligne. Vérifié en servant le dossier avec la politique du site devant la page, pas supposé : zéro violation, zéro erreur JavaScript, aux trois largeurs.
- La vidéo ne se charge qu’au clic. La carte montre son image de repli et ne va chercher les 396 Ko que si on appuie sur le bouton de lecture. L’original téléchargeait deux fichiers de 3840 × 2160 dès l’ouverture, pour les afficher dans une carte de 448 × 360.
- Le déclencheur est à 15 % du bas de l’écran, mesuré sur l’écran et non sur l’élément : un seuil en pourcentage de l’élément laisserait invisible à jamais tout bloc plus haut que l’écran. Un filet révèle ce qui reste quand on atteint le bas de la page.
-
Accessibilité : lien d’évitement, état du menu et du
sous-menu annoncés, questions natives, position du carrousel annoncée en
role="status", focus visible unique, décorations masquées aux lecteurs d’écran, animations et délais coupés si le système le demande. - Responsive vérifié à 390, 1440 et 2560 px, au chargement comme après défilement complet, sans un pixel de débordement horizontal.
Ce qui n’est pas parfait
Autant le dire ici plutôt que te le laisser découvrir.
- Le fond du bloc d’appel n’est plus une vidéo. L’original y sert un plan d’eau de 1 280 × 720 étiré en 1 408 × 560, presque entièrement délavé derrière un voile blanc. Ici c’est une photographie fixe, désaturée, animée d’une lente dérive en CSS : même impression, aucun décodeur vidéo, et un mégaoctet en moins.
- La vidéo de la carte est un mouvement calculé. Une avancée lente dans l’allée de cocotiers, composée à partir d’une image générée puis jouée en aller-retour pour que la boucle n’ait pas de raccord. Comparé après ré-encodage : le WebM montait à 808 Ko contre 396 Ko pour le mp4, donc c’est le mp4 qui est servi, seul.
- Le défilement fluide n’est pas repris. L’original charge une bibliothèque qui détourne la molette de tout le monde, y compris de qui n’en veut pas. Le défilement natif est conservé, avec un lissage sur les ancres seulement.
- Les séjours font 9 % de moins à 479 px. Les quatre blocs empilés sont plus compacts qu’à l’original, dont les textes occupent une ligne de plus à cette largeur. Rien ne se chevauche. Le pied, lui, fait 6 % de plus à 767 et 479 px : ses colonnes comptent six entrées là où l’original en aligne sept.
-
Les flèches du carrousel ne bouclent pas. Arrivé à la
dernière fiche, le bouton se désactive au lieu de revenir au début : un
rail
scroll-snapne boucle pas sans dupliquer ses fiches, et une flèche grisée dit la vérité. - Les pages internes n’existent pas. L’original est un site multi-pages — blog, galerie, fiches de chambres, mentions : une vingtaine de pages. Tous ses liens sont ramenés à des ancres de la page unique, plutôt que de laisser des 404.
- Les formulaires n’ont pas de serveur. Le formulaire de réservation et l’infolettre valident avec les règles du navigateur puis affichent le message de confirmation que l’original montrait après un envoi réussi. Un template statique n’a pas de moteur de réservation.
- Un défaut de l’original corrigé. Le premier témoignage racontait un séjour en famille sous l’étiquette « Adventure Seeker », et le deuxième un séjour au calme sous « Family Traveler ». Les rôles ont été remis en face des citations.
-
Le flou du pied et les plaques de verre reposent sur
backdrop-filter. Un navigateur qui l’ignore affiche un fond net : le texte reste lisible, l’effet disparaît.
Prends-le, ouvre-le, casse-le.
Motuvai est gratuit. La bibliothèque complète — les autres templates et les composants — est incluse dans l’abonnement, avec la formation.
Accès immédiat · Sans engagement · Annulation en 1 clic