Aller au contenu
Démarrer un projet
Menu

Mouvement

Tout apparaît, rien ne saute : les lignes se tracent, le surlignage s’étend, les illustrations s’animent seules.

Une seule courbe

Tout le site prend la même courbe et trois durées, posées en tête de grinn.css. Ce qui dure plus longtemps est écrit en clair dans le bloc de la trame.

JetonValeurEmploi
--easela courbecubic-bezier(0.22, 0.7, 0.2, 1) : un départ franc, une arrivée longue. Toutes les transitions la prennent.
--fast200 msle fond d’une case de logo, d’une question, d’une carte de citation
--mid380 msle fond d’une carte, la flèche qui sort, la croix d’une question, le fond d’une cellule tracée (dont la case d’une offre de la démonstration qui s’allume)
--slow640 msl’apparition (data-reveal), les carrés qui s’allument
hors jetonsles durées écrites en clair236 ms (le fond du bouton), 320 ms (« Voir l’offre » et sa flèche, dans la démonstration), 400 ms (un trait de la démonstration qui s’allume), 420 ms (parallaxe, lueur), 480 ms (trait d’attache d’une annotation), 500 ms (le halo d’une cible, anciennes scènes seulement), 520 ms (le nom d’une offre de la démonstration qui s’allume ; sa case, elle, prend --mid), 700 ms (la scène qui s’approche, la vignette d’une offre), 760 ms (surlignage), 900 ms (lignes du titre ; le cadre d’une vitrine qui se soulève), 1100 ms (la trame), 1,2 s (la matière d’une vitrine qui s’approche)
les bouclesease-in-out ou lineartr-respire 3,6 s, tr-flotte 5,2 s, tr-etape 6,6 s, l’onde du dôme 4,8 s, tr-defile 5 s par case du bandeau des clients, le tour des annotations de /offres/ 850 ms par annotation ; sur l’accueil, le tour de la démonstration 1,8 s par offre, deux passages, le flux d’un trait allumé, tr-demo-flux 0,9 s, linear, et les carrés de l’anneau, 3 s ; dans la section IA, tr-ia-flotte 5 s, ease-in-out ; dans chaque illustration, écrits dans son SVG : le flottement 5 s, le vert qui respire 3,2 s, les nœuds qui s’allument (2,4 à 4,32 s selon le dessin), et dans ia-scene la vague du flux, 4,8 s, linear

Apparaître

Chaque élément marqué data-reveal apparaît quand il entre dans le cadre : il monte de 16 px et passe de 0 à 1. Tout vient de la fonction reveal de src/scripts/grinn.js.

ClasseZoneValeur
[data-reveal]l’état de départopacité 0, 16 px plus bas (translateY(16px)) ; seulement sous la classe .js
.is-inl’arrivéeopacité 1, en place ; opacité et transform en --slow (640 ms), courbe --ease, délai --d
data-reveal="fade"le fondu seulsans déplacement : les scènes, les cellules d’image, le dôme, le bandeau des clients, le titre de l’accueil (ses lignes montent dedans), la cellule de la scène d’un en-tête de page
scale, left, linedans la feuille.97, -22 px, scaleX(0) : définis pour le site précédent, la trame ne les appelle pas
[data-stagger]le décalage--d = rang × pas, en millisecondes ; 70 par défaut, 40 à 150 selon la grille ; posé par grinn.js sur chaque enfant [data-reveal]
l’observateurgrinn.js, reveal()seuil 0.08, marge basse -10 % ; une seule fois par élément ; en mouvement réduit, tout est .is-in d’emblée
le filetgrinn.js, failsafe()au bout de 1,2 s, tout ce qui est dans l’écran et demi est affiché, animation ou pas

La trame se trace

Quand une grille entre dans le cadre, sa ligne du haut s’étire, puis chaque cellule trace son bas et sa droite, l’une après l’autre. Les bandes allument leurs cellules de même.

ClasseZoneValeur
[data-lignes]la ligne du hautbackground-size de 0 % à 100 % en 1100 ms, courbe --ease, dès que la grille entre dans le cadre (.is-trace)
[data-lignes] > .tr-celchaque celluleson bas et sa droite, 1100 ms, après --l
--lle tour de chaque cellule70 ms × son rang, posé par src/scripts/trame.ts sur chaque enfant
l’observateurtrame.tsseuil 0.1, marge basse -8 % ; une seule fois ; en mouvement réduit, .is-trace d’emblée
[data-allume]les bandeschaque cellule scaleX de 0 à 1 en 640 ms, 55 ms × son rang (--i), depuis la gauche
.tr-cel--allume ila cellule alluméescaleX en 640 ms, 90 ms × son rang (--k), depuis la gauche puis la droite ; attend que sa grille soit tracée
tr-respireaprèsopacité à 45 % au milieu du cycle, 3,6 s, ease-in-out, décalée de -0,5 s × --i
sans scriptla pagetout est tracé d’emblée : les règles n’existent que sous .js
  • Le chef de projet

    Votre interlocuteur unique, du premier échange au suivi.

  • Le design UX/UI

    Les parcours et les écrans, pensés pour être utiles.

  • La stratégie

    Ce qu’il faut construire, pour qui, et ce que ça doit rapporter.

  • Le développement

    Web, mobile, logiciel et IA, reliés à vos outils.

SpécimenQuatre cellules sur la grille tr-cas : la ligne du haut en 1100 ms, puis chaque cellule 70 ms après la précédente. La grille se trace au défilement, une seule fois : rechargez la page pour la revoir.
Appelsrc/components/trame/Grille.astro
<Grille classe="tr-cas" stagger={70}>
  <Cellule><Etiquette>Le design</Etiquette><h3>Les écrans qui mènent à l’appel.</h3></Cellule>
</Grille>

Le surlignage, le titre, les annotations

Trois apparitions de plus, chacune avec sa durée et son retard, puis les boucles lentes qui suivent.

ClasseZoneValeur
.tr-surlignele surlignagebackground-size de 0 % à 100 % en 760 ms, après 320 ms, quand le titre est .is-in
.tr-ligne > spanles deux lignes du titre de l’accueilmontent de 112 % en 900 ms ; la seconde 110 ms après la première
.tr-puce::afterle trait d’attachescaleY de 0 à 1 en 480 ms, après 380 ms, depuis le point d’attache
tr-flottel’annotationmonte de 4 px au milieu du cycle, 5,2 s, ease-in-out, décalée de -1,3 s × n ; pas dans la section IA de l’accueil, qui flotte d’un bloc (tr-ia-flotte)
tr-ia-flottela boîte du schéma de la section IA (accueil)la boîte entière, dessin (ia-scene.svg#fixe) et annotations ensemble, monte de 24 unités du dessin (1,243 % de la boîte 4/3, 1,418 % sous 700 px, au format du dessin) et redescend en 5 s, ease-in-out, le rythme du SVG : les traits restent sur leurs objets ; en CSS, donc aussi sans script ; rien en mouvement réduit
tr-etapeles trois temps de la section IAfond vert, bord vert profond, encre pendant 28 % du cycle, puis blanc ; 6,6 s, linear, décalée de 2,2 s × n ; dans la section IA, seule animation des annotations (leur tr-flotte est retiré)
tr-respireles cellules allumées3,6 s, voir ci-dessus
SpécimenUne annotation dans un cadre de 200 px : son trait se trace 380 ms après son apparition, puis elle flotte. Masquée sous 700 px.

À la souris

La parallaxe de l’en-tête des pages intérieures et la lueur sous le pointeur n’existent qu’avec un pointeur fin ; la scène qui s’approche et les survols, en CSS, suivent :hover. Rien en mouvement réduit. Le premier écran de l’accueil n’a plus de parallaxe depuis le 12 octobre.

ClasseZoneValeur
[data-parallaxe]la cellule de la scène d’un en-tête de page--px et --py de -1 à 1 selon le pointeur (trame.ts, partie 3) ; la scène se déplace de -5 px / -4 px ; les annotations ancrées sur une illustration v2 la suivent du même pas, pour que leur trait reste sur l’objet (les autres partent à l’opposé, de 9 px / 7 px) ; translate en 420 ms. Posé par EnTetePage (offres, pages d’offre, suivi) ; l’accueil ne l’a plus depuis le 12 octobre : la scène de la démonstration reste en place
[data-lueur]une carte d’offre ou de réalisation--mx et --my en pixels ; un cercle de 280 px de vert à 38 % sous le pointeur, opacité en 420 ms
.tr-carte:hover .tr-carte__scenela scène de la carteune illustration v2 : la boîte entière, dessin et annotations, à scale 1.04 en 700 ms, pour que les traits restent sur leurs objets ; une ancienne scène : scale(1.06) sur le dessin seul, en 700 ms. C’est du CSS : il ne demande pas un pointeur fin
.tr .btn::beforele boutonle fond vert profond (pâle pour le bouton au trait) monte de 100 % en 236 ms
.tr-demo__offre:hoverune offre de la démonstrationla case passe au vert clair et allume son trait, comme au tour ; « Voir l’offre » passe à l’encre et sa flèche sort de 2 px, en 320 ms ; la même chose au focus. Ce survol n’attend pas un pointeur fin : c’est du CSS, et trame.ts allume le trait sur pointerenter et focus
.tr-vitla vitrine d’un casau survol du lien qui la porte (une carte de la page Réalisations, le cas suivant), à son focus, ou au survol de la vitrine : la matière passe de 104 % à 108 % en 1,2 s, le cadre monte de 6 px (8 px pour le téléphone) en 0,9 s. C’est du CSS, comme le survol de la démonstration ; en mouvement réduit, rien ne bouge
.tr-cc__corps, .tr-suivantune carte de cas, le cas suivantau survol et au focus : la case pâlit ; le bouton dessiné passe au trait d’encre (carte) ou se remplit (cas suivant), et sa flèche sort de 3 px ; en mouvement réduit, la flèche reste en place
la conditiontrame.tsseulement si (hover: hover) and (pointer: fine), et jamais en mouvement réduit : rien au doigt
SpécimenLe bouton plein et le bouton au trait : au survol, le fond monte en 236 ms et la flèche sort de 3 px.

Le dôme

Un champ de petits signes sur canevas, dans un demi-cercle, parcouru par une onde verte, avec la scène du suivi dedans. Tout est dans la quatrième partie de trame.ts.

QuoiOùValeur
le canevas.tr-dome__champun champ de signes dessiné par trame.ts, à la densité de l’écran (2 au plus) ; hauteur du dôme clamp(300px, 34vw, 440px), 280 px sous 700 px
les glyphesGLYPHES· · · · + × / : quatre points pour un plus, une croix et une barre, tirés par hachage de la position
le pasPAS14 px ; chaque signe en Inter 500 11 px, dans l’encre, à une opacité de 14 à 30 % qui baisse vers le bord
le demi-cercleRle plus grand de min(W/2 - 10, H × 1,02) et H × 0,9, centré en bas ; sur un écran étroit, il déborde les côtés
l’ondedessine()un anneau de 34 px, en vert profond, qui parcourt le rayon en 4,8 s ; un scintillement de 7 % à côté
hors écranIntersectionObserverseuil 0.05 : le dessin s’arrête, et repart au retour (et au retour d’onglet)
en mouvement réduitreduitune seule image : les signes, sans onde ni scintillement

Ce qui vit en continu

Pour que la page ne soit jamais tout à fait immobile, quelques mouvements lents tournent : des cases de la grille qui s’allument, des chiffres qui comptent, des bandes qui glissent avec le défilement, le bandeau des clients qui défile, les offres du premier écran et les annotations de /offres/ qui s’allument à tour de rôle, des scènes qui montent à leur place, des illustrations qui flottent et respirent. Les scripts s’arrêtent hors du cadre ; le bandeau, tout en CSS, s’arrête au survol ou à son bouton ; les illustrations, en CSS dans leur SVG, ne s’arrêtent pas. Aucun ne tourne en mouvement réduit.

OùQuoiComment
[data-cellules]les cellules vivantestrame.ts, partie 5 : un canevas sous le contenu ; des cases de 48 px, calées sur le trait de la grille, s’allument en 25 % de leur vie, tiennent, s’éteignent sur les 30 derniers ; vie de 2,6 à 4,8 s, une case de plus toutes les 0,4 à 0,9 s, une case pour 18 au plus ; teintes lues dans --grinn, --grinn-light et --grinn-deep (une sur huit), ou dans --cellules-tons ; sous le pointeur, la case s’éclaire à .6 et s’éteint en 1,5 s ; posé dans la tête en cellule, et dans la cellule de la scène de l’accueil et de l’en-tête de page, où il est masqué derrière une illustration v2 depuis le 13 octobre (choix à valider par JB) ; en « calme » (deux à la fois, une de plus toutes les 1,4 à 1,9 s) sur la grille de l’affiche de l’accueil, les cases vides du mur et la tête du point de contact. La grille de l’affiche ne reçoit pas le pointeur : ses cases ne s’éclairent pas dessous
.tr-chiffres__v, .tr-faits liles chiffres comptenttrame.ts, partie 6 : le premier nombre du texte (2 à 9999) part de zéro quand la case est aux six dixièmes dans le cadre ; 0,5 s plus 40 ms par unité, 1,4 s au plus, en ralentissant ; le texte final est celui de la page
.tr-bande iles bandes glissenttrame.ts, partie 7 : --defile vaut 1 quand le milieu de la bande est en bas de l’écran, 0 au milieu, −1 en haut ; chaque carré se décale de --defile × --s × 48 px (--s : 1 pour la première rangée, −1 pour la seconde, posé par Bande). En descendant, la première rangée glisse vers la gauche, de 48 px à droite de sa place à 48 px à gauche, la seconde vers la droite : une case de chaque côté, 96 px de course ; à mi-écran, les carrés sont sur la grille
.tr-logos__pistele bandeau défilegrinn.css, tr-defile, sans script : deux pistes identiques glissent ensemble d’une largeur de piste (translateX de 0 à -100 %), en calc(var(--n) × 5 s), linéaire, infini, de droite à gauche ; pause au survol (la règle vise aussi :focus-within, mais rien dans le bandeau ne prend le focus), et au bouton pause, au clavier et au doigt (trame.ts, partie 8) ; il tourne aussi hors du cadre. La lumière qui passait d’une case à l’autre (trame.ts, partie 8, .is-vif) est retirée le 12 octobre
.tr-demo__offrele tour de la démonstrationtrame.ts, partie 10 : sur l’accueil, une offre s’allume toutes les 1,8 s avec son trait, dans le sens des aiguilles d’une montre autour de la scène dès 1000 px, dans l’ordre de lecture en dessous ; deux passages, puis tout s’éteint ; voir la rubrique 08
.tr-une__puces .tr-pucele tour des annotationstrame.ts, partie 9 : à l’en-tête de /offres/ (le premier écran de l’accueil n’en a plus depuis le 12 octobre ; les annotations qui restent sur l’accueil, sur les scènes des cartes d’offre, de la section IA et du dôme du suivi, ne sont pas dans un .tr-une__puces et ne prennent pas ce tour ; les trois étapes de la section IA ont le leur, tr-etape), chaque annotation s’allume à son tour, toutes les 850 ms, dans le sens des aiguilles d’une montre autour du centre de la scène (.is-allumee : fond --grinn, bord --grinn-deep, encre, en 500 ms) ; un seul tour, puis tout s’éteint ; il recommence quand l’ouverture revient à l’écran (seuil 0.3) ; le survol de la scène l’arrête (le script écoute aussi le focus, mais rien dans la scène ne le prend) ; rien sur une ouverture qui a déjà une annotation verte (pages d’offre, suivi)
.tr-page__dessin .tr-une__scenela scène d’en-tête reculegrinn.css, animation-timeline : en quittant l’écran, la scène d’un en-tête de page monte de 44 px, passe à .96 et à l’opacité .55, et ses annotations ancrées avec elle ; la frise --tr-une est nommée sur le cadre, qui coupe ce qui dépasse. La scène de l’accueil ne recule plus depuis le 12 octobre : la règle vise .tr-une__dessin et .tr-page__dessin, et la démonstration n’est ni l’un ni l’autre
.tr-carte__scene, .tr-role .tr-sceneles scènes montentgrinn.css, animation-timeline : de 44 px plus bas et .35 d’opacité à leur place, entre l’entrée dans l’écran et le tiers de la traversée
.tr-scene--v2les illustrations s’animent seulesle CSS écrit dans chaque SVG par anime-svg.py, sans script : à l’arrivée, les objets entrent en fondu l’un après l’autre (0,7 s chacun, décalés de 0,15 s), puis les liaisons (0,6 s) ; ensuite, sans fin, l’image entière flotte d’un bloc (24 unités du dessin, 5 s, ease-in-out), le vert respire (3,2 s) et, sur sept dessins, les nœuds des liaisons s’allument en vert profond l’un après l’autre ; jamais une pièce seule ne bouge. La scène hero ajoute son G, qui se pose en 0,9 s, puis dont le point vert saute toutes les 4 s ; appelée en hero.svg#fixe sur l’accueil, elle ne flotte pas d’elle-même : c’est la page qui la fait flotter (rubrique 08). Le schéma de la section IA ajoute une vague verte qui parcourt les tirets de son flux, du mail au tampon, toutes les 4,8 s, en couleur seulement ; appelé en ia-scene.svg#fixe, il ne flotte pas de lui-même : c’est sa boîte qui flotte, avec les annotations (tr-ia-flotte). Chaque SVG coupe tout en mouvement réduit (animation: none) : l’image finale, fixe. Aucun script ne les arrête hors écran

Les animations liées au défilement (animation-timeline) ne tournent que dans les navigateurs qui les connaissent ; ailleurs, la scène est simplement à sa place. En mouvement réduit, les cellules vivantes posent trois cases, immobiles, et le bandeau des clients ne bouge plus : sa seconde piste est masquée, et la rangée se fait défiler à la main. Hors mouvement réduit, le bandeau a un bouton pause, qui l’arrête au clavier et au doigt (trame.ts, partie 8). Les illustrations, elles, n’en ont pas : leur mouvement sans fin, comme le tour des offres, est noté dans Accessibilité, ce qui reste à faire.

La démonstration

Sur le premier écran de l’accueil, depuis le 12 octobre : chaque offre est reliée par un trait à l’objet qu’elle nomme dans la scène, et les offres s’allument l’une après l’autre, deux tours, puis plus rien. Le script est la dixième partie de trame.ts ; les durées sont dans le bloc « le grand titre centré » de grinn.css. La parallaxe et le recul de la scène ont quitté l’accueil : ils restent à l’en-tête des pages intérieures (rubriques 05 et 07).

QuoiOùValeur
les traitstrame.ts, partie 10un svg par démonstration : l’anneau de la scène hero à toutes les largeurs ; dès 1000 px, quand toutes les offres entourent la scène, une ligne droite de chaque case à sa cible, un carré de 7 px à chaque bout (plus de halo sur un schéma v2) ; vidé et retracé quand la démonstration change de taille (ResizeObserver), au retour d’onglet (visibilitychange) et quand l’image est chargée (load)
l’anneauanimateMotionsur chaque côté de l’anneau, un carré vert profond de 6 px circule d’un objet à son voisin : 3 s, sans fin, chaque côté décalé de 0,5 s ; aucun en mouvement réduit
le flottementFLOTTE, DUREE, T0la scène hero (hero.svg#fixe) ne flotte plus d’elle-même : la page fait monter l’image, l’anneau et les cibles de 24 unités du dessin et les fait redescendre en 5 s, ease-in-out, sans fin, et chaque trait pivote sur sa case (skewY) ; toutes ces animations (Web Animations) partent du même instant : recréées à chaque tracé, elles gardent leur phase ; aucune en mouvement réduit
le tourPAS, PASSAGES1800 ms par offre, deux passages : dès 1000 px, dans le sens des aiguilles d’une montre autour du centre de la scène, depuis le haut ; sous 1000 px, dans l’ordre de lecture ; puis tout s’éteint
l’offre allumée.tr-demo__offre.is-allumeele fond de la case passe au vert clair en 380 ms (--mid : la transition des cellules tracées, [data-lignes] > .tr-cel, l’emporte sur les 520 ms écrits pour l’offre) ; le nom passe en pastille verte en 520 ms ; la vignette passe à 1,06 en 700 ms
son trait.tr-demo__lien.is-allumeele trait passe au vert profond en 400 ms, ses deux carrés aussi
le fluxtr-demo-fluxles tirets du trait allumé (4 px de trait, 4 px de vide) courent de l’offre vers l’objet : stroke-dashoffset de 0 à -16, 0,9 s, linear, sans fin, tant que l’offre est allumée
la repriseIntersectionObserverseuil 0.3 : hors du cadre, le tour s’arrête et tout s’éteint ; il repart du premier pas quand la démonstration revient à l’écran ; les deux passages faits, il attend ce retour
les pausespointerenter, focusin, visibilitychangele pointeur ou le focus dans la démonstration arrête le tour et éteint tout ; il reprend à l’offre suivante quand le pointeur sort ou que le focus quitte la démonstration ; onglet caché, il s’arrête, et reprend au retour
le survol d’une offremarque()la case s’allume en CSS (:hover, :focus-visible) ; trame.ts allume son trait sur pointerenter et focus, l’éteint sur pointerleave et blur
mouvement réduitreduitles traits et l’anneau sont tracés et restent, rien ne tourne ni ne flotte ; si le réglage passe au mouvement réduit pendant la visite, le tour s’arrête et tout s’éteint ; dans grinn.css, ni transition, ni flux, ni zoom de la vignette au survol

Le spécimen, les offres, leurs cibles et l’ordre du tour sont dans L’accueil, rubriques 02 et 03.

Toujours un moyen d’arrêter

Le mouvement est une apparition, jamais une condition de lecture. Quatre garde-fous, lus dans la feuille et dans les scripts.

  • prefers-reduced-motion coupe tout. Dans grinn.css : transitions à none, trame tracée d’emblée, surlignage plein, lignes du titre en place, traits d’attache tracés, flux des traits de la démonstration coupé, flottement et étapes coupés (la boîte du schéma IA ne flotte pas), bandes et cellules sans respiration, bandeau des clients immobile (piste muette masquée, rangée défilable à la main), scène sans zoom, barre de lecture masquée. Dans grinn.js : tout est .is-in sans attendre. Dans chaque illustration v2 : animation: none sur tout, l’image finale, fixe. Dans trame.ts : aucune ancienne scène en boucle n’est lancée (il n’y en a plus en service), la scène hero ne flotte pas, l’anneau n’a pas de carrés, trame tracée, ni parallaxe ni cellules sous la souris, dôme fixe, aucun tour des offres (les traits de la démonstration restent tracés, et le survol ou le focus d’une offre allume encore son trait, sans transition ni flux).
  • Rien ne reste caché : 1,2 s après le chargement, tout ce qui est près du haut apparaît ; puis, à chaque défilement (250 ms après), tout ce qui est déjà passé apparaît, même si l’observateur l’a manqué pendant un défilement très rapide (grinn.js, failsafe).
  • Plus aucune vidéo depuis le 13 octobre : la section IA de l’accueil a reçu son schéma v2. Les illustrations v2 bougent en CSS dans le SVG ; trame.ts sait toujours lancer une ancienne scène en boucle quand un quart d’elle est visible et la mettre en pause dès qu’elle sort, si un nom sans SVG y retombe.
  • Sans la classe .js, rien n’est masqué. Page.astro la pose avant le rendu ; toutes les règles de départ (opacité 0, lignes à 0 %, carrés à 0) sont écrites sous .js. Sans script, la page est entière ; seul bouge encore ce qui est écrit en CSS hors de .js : les illustrations, par leur propre CSS, la boîte du schéma IA (tr-ia-flotte), le bandeau des clients (sans son bouton pause), les cellules de la page contact, de la candidature et du pied, et ce qui suit le défilement (animation-timeline).

RègleTout apparaît, rien ne saute ; et en mouvement réduit, tout est là, immobile.