Principes
- De 7 à 77 ans. Corps de texte 17 px minimum, cibles tactiles ≥ 44 px, contrastes AA partout, une action principale par vue.
- Clair comme un lagon. Fonds clairs et chauds (écume, sable), l'eau en décor, le corail pour agir. Jamais de thème sombre sur les surfaces produit.
- La technique s'efface. Les animations accompagnent la lecture (glisse d'eau), ne la précèdent jamais. prefers-reduced-motion est un contrat.
- Vocabulaire de plongée, juste et accessible. Palier, palanquée, mise à l'eau — toujours compréhensibles en contexte par un non-plongeur.
- Tokens ou rien. Aucune valeur en dur (couleur, taille, ombre) : tout vient de tokens.css. Une valeur manquante = une PR sur les tokens, pas une exception locale.
Couleurs
Trois familles : la plage (fonds), l'eau (identité, décor) et le corail/soleil (action, chaleur). L'encre écrit tout.
Contrastes vérifiés (WCAG 2.2)
| Combinaison | Ratio | Verdict | Usage autorisé |
|---|---|---|---|
| encre / écume | ≈ 10,9 : 1 | AAA | Texte courant, titres |
| encre-soft / écume | ≈ 5,9 : 1 | AA | Texte secondaire |
| lagon-700 / écume | ≈ 5,6 : 1 | AA | Liens, texte coloré |
| corail-ink / corail-500 | ≈ 7,3 : 1 | AA+ | Boutons primaires |
| eau-100 / lagon-900 | ≈ 9,5 : 1 | AAA | Footer |
| lagon-500 / écume | ≈ 2,8 : 1 | ✗ | Décor uniquement — jamais du texte |
| encre-faint / écume | ≈ 4,0 : 1 | limite | Légendes ≥ 20 px uniquement |
✓ Faire
- Texte = encre ou encre-soft ; liens = lagon-700
- CTA corail-500 + texte corail-ink
- Soleil pour la mise en avant ponctuelle (1 élément max par vue)
✗ Éviter
- Texte en lagon-500 ou blanc sur corail-500
- Couleur hors palette, dégradés non documentés
- Fond sombre hors footer
Typographie
Gérez moins. Plongez plus.
Young Serif — titres (h1–h3, prix)
Nunito Sans — corps de texte 17 px, humaniste et ronde, extrêmement lisible. Graisse 700 pour appuyer, lien dans le texte.
IBM Plex Mono — −20 m · 19 € TTC/mois · données
| Token | Valeur | Usage |
|---|---|---|
| --vm-text-3xl | clamp(2.375rem → 4rem) | h1, un seul par page |
| --vm-text-2xl | clamp(1.75rem → 2.625rem) | h2 de section |
| --vm-text-xl | clamp(1.375rem → 1.75rem) | h3, titres de carte |
| --vm-text-l | 1.25rem | Lede, intro de section |
| --vm-text-m | 1.0625rem (17 px) | Corps — taille plancher du texte courant |
| --vm-text-s / -xs | 15 px / 13 px | Texte dense, légendes (jamais des paragraphes) |
✓ Faire
- Young Serif réservée aux titres et aux prix
- Webfonts en font-display: swap ; les fallbacks (Georgia, system-ui) font partie du contrat
- text-wrap: balance sur les titres
✗ Éviter
- Young Serif en corps de texte ou en italique
- Texte courant sous 17 px
- Plus de deux graisses par vue
Espacements, rayons, ombres, breakpoints
Échelle d'espacement (base 4 px)
--vm-space-1…10 : 4 · 8 · 12 · 16 · 24 · 32 · 48 · 64 · 96 · 128 px
Rayons & ombres
Les ombres sont teintées d'encre (jamais de gris neutre). Breakpoints mobile-first : 30rem, 48rem, 64rem, 80rem.
Boutons & liens
<a class="vm-btn vm-btn--primary" href="…">Essayer gratuitement</a> <a class="vm-btn vm-btn--secondary" href="…">Voir les tarifs</a> <a class="vm-link" href="…">Lien dans le texte</a>
✓ Faire
- Un seul bouton primaire (corail) par vue
- Libellés à l'infinitif, orientés bénéfice (« Essayer gratuitement »)
- Min-height 44 px déjà garanti par le composant
✗ Éviter
- Deux CTA corail côte à côte
- « Cliquez ici », « Soumettre »
- Bouton pour une navigation simple (utiliser .vm-link)
Badges
<span class="vm-badge vm-badge--ok">CACI à jour</span>
Les variantes sémantiques (ok / alerte / erreur) sont réservées à des états réels de données — jamais décoratives.
Cartes
Calendrier du club
Sorties, formations, piscine : tout le programme, les places restantes et l'équipe du jour.
<div class="vm-card vm-card--lift"> <span class="vm-card__icon" aria-hidden="true">📅</span> <h3>Titre</h3><p>Texte.</p> </div> <div class="vm-card vm-card--pricing vm-card--featured"> <span class="vm-badge vm-badge--corail">Recommandé</span> <h3>Exploration</h3> <p class="vm-price">19 €<small> TTC/mois</small></p> <ul><li>Inclus</li><li class="is-off">Non inclus</li></ul> <a class="vm-btn vm-btn--primary" href="…">Choisir</a> </div>
Une seule carte --featured par grille tarifaire. --lift uniquement si la carte entière est cliquable ou introduit une action.
Formulaires
Tel qu'il apparaîtra pour vos membres.
Cette adresse semble incomplète — il manque le domaine.
<div class="vm-field"> <label for="nom">Nom du club</label> <input class="vm-input" id="nom" type="text"> <p class="vm-field__hint">Aide contextuelle.</p> </div> <!-- erreur : .vm-field--error + aria-invalid + aria-describedby -->
✓ Faire
- Label visible toujours (jamais placeholder seul)
- Messages d'erreur en français complet, qui expliquent comment corriger
- aria-describedby relie erreur et champ
✗ Éviter
- Erreur signalée par la couleur seule
- Validation agressive pendant la frappe
- Champs obligatoires non signalés
Alertes & tableaux
Tableau : voir .vm-table (utilisé dans cette page). Sur mobile, préférer des cartes empilées à un tableau scrollable quand il y a plus de 3 colonnes.
FAQ (accordéon natif)
Mes données sont-elles récupérables si je change d'outil ?
Oui, intégralement et à tout moment : export CSV et JSON inclus dans toutes les offres, y compris la gratuite. La réversibilité est un droit, pas une option.
Exemple ouvert
Basé sur <details>/<summary> : accessible clavier nativement, zéro JavaScript requis.
Profondeur — la signature Vingt Mille
Héritée de l'étude architecturale : la page est une plongée. Trois composants la matérialisent :
- La jauge .vm-depth (fixe à droite, ≥ 64rem) affiche la « profondeur » de lecture, alimentée par JS (data-depth-max sur le body). Décorative : aria-hidden="true".
- Les marqueurs de palier .vm-palier ouvrent chaque section (« Palier −5 m · Le calendrier »).
- Les vagues .vm-wave (SVG inline) séparent les sections ; le fond s'assombrit imperceptiblement d'une section à l'autre (écume → eau-050 → eau-100) pour matérialiser la descente, sans jamais quitter le thème clair.
<span class="vm-palier">Palier −5 m · Le calendrier</span> <div class="vm-depth" aria-hidden="true"> <div class="vm-depth__value" data-depth-value>0 m</div> <div class="vm-depth__track"><div class="vm-depth__fill" data-depth-fill></div></div> </div>
Mouvement
| Usage | Recette |
|---|---|
| Révélation au scroll | .vm-reveal — scroll-driven animation CSS (animation-timeline: view()) avec repli IntersectionObserver (classe .in ajoutée par main.js) |
| Micro-interactions | Boutons : lift −2 px (--vm-ease-spring, 160 ms) ; cartes : lift −4 px (280 ms) |
| Décor | Bulles .vm-bubble en ascension lente (20–35 s), maximum 6 par page |
| Interdits | Parallaxe agressive, autoplay vidéo, animation > 600 ms sur du contenu, tout mouvement sous prefers-reduced-motion |
Anatomie d'une page
- .vm-nav sticky (72 px)
- Sections .vm-section (padding vertical space-9), contenu dans .vm-container (max 72rem) ou .vm-container--text (46rem) pour la prose
- Chaque section : .vm-palier → h2 → lede → contenu en .vm-grid--2/3
- Alternance des fonds : écume / sable / eau-050 (jamais deux fonds identiques adjacents), vagues en jonction
- .vm-footer (lagon-900)
Hiérarchie : un seul h1 par page ; les niveaux ne sautent jamais (h2 → h3, pas h2 → h4).
Voix, ton, iconographie
- Voix : chaleureuse, concrète, modeste. On vouvoie les clubs. Vocabulaire plongée juste mais toujours compréhensible hors contexte.
- Jamais de comparaison négative avec un autre outil, nommément ou par allusion. On décrit ce qu'on apporte.
- Icônes : pictogrammes au trait 2 px, bouts arrondis, monochromes (encre ou lagon-700), posés sur pastille .vm-card__icon. Les emojis sont tolérés en contenu éditorial, pas dans l'interface applicative.
- Nombres : typographie française (espace insécable avant € et %, « 19 € », « −20 m »), IBM Plex Mono pour les données alignées.
Checklist de l'agent (avant toute livraison)
- Toutes les valeurs viennent de tokens.css — zéro hex, taille ou ombre en dur.
- Un seul h1, hiérarchie de titres sans saut, landmarks (header/nav/main/footer) présents.
- Texte courant ≥ 17 px, contrastes conformes au tableau §Couleurs, focus visible sur tout élément interactif.
- Cibles tactiles ≥ 44 px, navigation 100 % clavier, prefers-reduced-motion respecté.
- Un seul CTA primaire corail par vue ; libellés orientés bénéfice.
- Images : SVG d'abord, alt systématique (vide si décorative + aria-hidden).
- Aucune dépendance externe obligatoire : la page doit rester fonctionnelle sans réseau (fallbacks de police inclus).
- Ton : pas de jargon inexpliqué, pas de comparaison négative, prix toujours en TTC.