/* ==================================================================== */
/* Fiona Lebre — LA PREMIÈRE ARRIVÉE                                    */
/* ==================================================================== */
/*
 * Ce qui se joue quand on ouvre le site, et SEULEMENT là : pas au
 * rechargement, pas en revenant d'un projet, pas en cliquant FIONA
 * LEBRE. La distinction est faite en JS (cf. header.php) ; ce fichier ne
 * décrit que le geste.
 *
 * LE GESTE, EN TROIS TEMPS :
 *
 *   0 ms          la table, le carton et la photo sont là — peints, nets
 *                 de géométrie, rien n'attend ;
 *   0 -> 1600     le tirage fait sa MISE AU POINT (flou 16px -> 0,
 *                 échelle 1,02 -> 1) ;
 *   0 -> 710      les MARGES se remplissent : les chiffres arrivent par
 *                 la gauche, les noms par la droite, 45ms d'écart entre
 *                 deux rangs ;
 *   900 -> 1700   le CARTEL s'écrit, ligne 1 puis ligne 2.
 *
 * ==================================================================
 * RIEN N'EST ANIMÉ DEPUIS L'OPACITÉ ZÉRO SUR LA PHOTO, et c'est une
 * contrainte technique, pas un choix esthétique.
 *
 * L'image d'ouverture porte fetchpriority="high" et decoding="sync"
 * précisément pour être peinte à la PREMIÈRE frame (cf.
 * template-parts/home-content.php). Un pixel transparent ne compte pas
 * comme peint : la faire apparaître depuis l'opacité zéro décalerait la
 * mesure du LCP de toute la durée de l'intro, et annulerait le travail
 * fait sur le poids des images.
 *
 * D'où le choix de la mise au point : la photo est là, à pleine
 * opacité, dès le premier instant. Seule sa NETTETÉ arrive. On obtient
 * une apparition sans rien retarder.
 * ==================================================================
 *
 * ON NE RÉÉCRIT AUCUNE ANIMATION, ON REJOUE CELLES QUI EXISTENT. La
 * mise au point est celle du carrousel (--fl-focus, --fl-blur,
 * --fl-scale) ; le fondu de l'index est celui du pli vers About ; le
 * cartel a ses propres temps depuis toujours. Ce fichier ne fait que
 * poser l'ÉTAT DE DÉPART et laisser les transitions existantes ramener
 * chaque chose à sa place.
 *
 * C'est la seule façon de garantir que l'intro ne jure pas avec le
 * reste : elle est faite des mêmes durées et des mêmes courbes, déjà
 * réglées à l'œil.
 *
 * ==================================================================
 * DEUX ATTRIBUTS, ET IL EN FAUT DEUX.
 *
 *   data-intro        « on est dans l'intro » — porte les TEMPOS.
 *   data-intro-start  « on est à l'état de départ » — porte les VALEURS.
 *
 * Le JS pose les deux avant le premier rendu, puis retire
 * data-intro-start à la frame suivante : les transitions partent. Il
 * retire data-intro à la fin.
 *
 * POURQUOI PAS UN SEUL. Une transition lit ses propriétés transition-*
 * sur l'état d'ARRIVÉE. Si le tempo de l'intro vivait sous le même
 * attribut que les valeurs de départ, il disparaîtrait à l'instant même
 * où la transition démarre — et on retomberait sur les durées du
 * carrousel et d'About, qui ne sont pas celles qu'on veut ici. Le
 * deuxième attribut est ce qui permet au tempo de SURVIVRE au
 * déclenchement.
 *
 * C'est le même piège que partout dans ce thème (« la transition vit sur
 * l'état de repos »), pris par l'autre bout.
 * ==================================================================
 *
 * FIREFOX, NAVIGATION PRIVÉE, RÉGLAGE « RÉDUIRE LES ANIMATIONS » : rien
 * ne se joue, les attributs ne sont simplement jamais posés. La page
 * s'affiche dans son état de repos, qui est un état complet.
 */

:root {
	/* LE FONDU DES MARGES — ET IL SE MESURE CONTRE LE CARTEL, pas contre
	   le pli vers About.

	   Premier réglage : 0,35s. À l'écran, chaque titre POPPAIT — pas
	   parce que 0,35s est court dans l'absolu, mais parce que le cartel,
	   juste à côté, prend 0,8s (--fl-cap-in). Un même écran qui montre
	   deux apparitions dont l'une va deux fois plus vite que l'autre, ça
	   se lit comme un défaut de synchronisation, même quand chacune est
	   correcte prise seule.

	   Deuxième essai, 0,75s : aligné sur le cartel, et TROP. L'index
	   n'est pas le sujet de l'écran, il l'accompagne ; à la durée exacte
	   du cartel il se met à le concurrencer.

	   0,5s, retenu. Assez lent pour ne plus claquer à côté du cartel,
	   assez vif pour rester un accompagnement. L'ÉCHELONNEMENT NE CHANGE
	   PAS — c'était la durée de chaque titre qui était en cause, pas le
	   rythme entre eux, et les 45ms sont le tempo commun à quatre gestes
	   du site.

	   Conséquence sur la chaîne : le neuvième titre termine à 860ms au
	   lieu de 710 (8 x 45 + 500). Ça reste bien sous les 1,6s de la mise
	   au point, donc l'ordre voulu est préservé — les marges se posent,
	   la photo se révèle ensuite, le cartel nomme en dernier. */
	--intro-index-duration: 0.5s;

	/* LA COURBE DU CARTEL, EMPRUNTÉE TELLE QUELLE. Deuxième moitié du
	   même problème : l'index fondait sur --about-fold-ease, la courbe
	   symétrique du pli (0.65, 0, 0.35, 1), franche au milieu. Le cartel
	   fond sur --fl-cap-ease-in (0.4, 0, 0.6, 1), nettement plus douce.
	   À durées égales, deux courbes différentes se voient encore.

	   On ne redéclare pas la valeur : on pointe vers le token du cartel.
	   Si son réglage bouge un jour, l'index suivra — c'est bien ce qu'on
	   veut, puisque tout l'intérêt est qu'ils se ressemblent.

	   CET EMPRUNT A D'ABORD RENDU DU VIDE, et ça a coûté un aller-retour.
	   --fl-cap-ease-in était déclaré sur .home-caption, pas sur :root.
	   Une variable ne se lit que sur sa branche : ici, la déclaration
	   était invalide au calcul et --intro-index-ease valait la chaîne
	   vide. Le raccourci transition de l'index tombait avec elle, et
	   --about-fold-ease aussi, qu'on redéfinit plus bas à partir d'elle.
	   L'index n'apparaissait plus DU TOUT — il était là d'un coup, sans
	   fondu ni déplacement. Le CSS ne dit rien dans ce cas : pas
	   d'erreur, pas de console, la propriété est simplement absente.

	   Corrigé en montant les deux COURBES du cartel dans :root (les
	   durées, elles, restent contextuelles — cf. le pavé de theme.css).
	   LA RÈGLE À RETENIR : avant d'emprunter un token, vérifier OÙ il est
	   déclaré. getComputedStyle( document.documentElement ) rend la
	   chaîne vide si on ne peut pas le lire depuis la racine, et c'est le
	   test en une ligne.

	   ET C'EST CE QUI PERMET DE RESTER À 0,5s. Une courbe douce au départ
	   fait PARAÎTRE une apparition plus lente qu'elle n'est : le gros de
	   l'opacité arrive tard. On obtient donc l'effet cherché sans allonger
	   réellement la durée — ce qui est précieux quand on veut ralentir
	   « légèrement » sans repousser tout ce qui suit. */
	--intro-index-ease: var( --fl-cap-ease-in );
	/* MÊME ÉCART QUE PARTOUT AILLEURS : le pli vers About, les tuiles de
	   l'Overview, l'index du passage vers un projet. Quatre gestes, un
	   seul tempo — c'est ce qui fait qu'ils se ressemblent. */
	--intro-index-stagger: 45ms;

	/* DE COMBIEN LES DEUX BOUTS DE L'INDEX ARRIVENT. Petit, et ce n'est
	   pas de la timidité : l'index est déjà à sa place, il ne VIENT pas
	   d'ailleurs, il se pose. Au-delà d'une quinzaine de pixels on lit un
	   déplacement, ce qui raconterait autre chose.

	   Les chiffres viennent de la marge GAUCHE, les noms de la marge
	   DROITE — soit chacun de son propre bord, puisque l'index traverse
	   la page (grid-column 1/2 pour le chiffre, 8/-1 pour le nom, cf.
	   theme.css). C'est ce qui rend ce geste propre à CETTE composition :
	   la page se compose depuis ses marges vers l'intérieur. */
	--intro-index-shift: 10px;

	/* LE CARTEL ARRIVE APRÈS, ET C'EST UNE INVERSION ASSUMÉE.
	   La règle du carrousel est « le texte annonce, l'image confirme » :
	   la légende part avant que la photo ne devienne lisible (cf.
	   CAPTION_DELAY_MS dans js/main.js). À la première arrivée il n'y a
	   rien à annoncer — on découvre le tirage, PUIS on apprend son nom.
	   La règle s'inverse pour la raison même qui l'avait établie.

	   900ms : la mise au point est alors à 56% de sa course, donc la
	   photo est déjà lisible sans être posée. Le cartel s'écrit pendant
	   qu'elle finit de se régler. */
	--intro-caption-delay: 0.9s;
	/* L'écart entre les deux lignes du cartel. Même valeur que
	   CAPTION_STAGGER_MS dans js/main.js, qui fait ce décalage au
	   changement de projet. Une seule ondulation traverse les deux
	   lignes ; à 200ms on lisait deux événements séparés. */
	--intro-caption-line2: 100ms;

	/* QUAND L'INTRO EST FINIE. Le JS LIT cette valeur pour savoir quand
	   retirer data-intro — il ne la recopie pas. C'est le défaut qui a
	   coûté le plus cher sur ce projet : une durée qui existe à deux
	   endroits finit par diverger.

	   Doit rester >= à la plus longue chaîne, aujourd'hui le cartel :
	   0,9s de retard + 0,8s de fondu + 0,1s pour la ligne 2 = 1,8s. */
	--intro-total: 1.9s;
}

/* ------------------------------------------------------------------ */
/* 1. LE TIRAGE FAIT SON POINT                                         */
/* ------------------------------------------------------------------ */

/* On remet la photo à l'état FLOU du carrousel — celui que porte
   .fl-home-img au repos — alors qu'elle est déjà .is-active. Retirer
   data-intro-start rend la main à .is-active (flou 0, échelle 1), et la
   transition déclarée sur l'état de repos fait le trajet : --fl-focus,
   1,6s, sur la courbe de mise au point.

   L'OPACITÉ N'EST PAS TOUCHÉE. Cf. le pavé du haut : c'est ce qui
   préserve le LCP.

   --fl-gap-delay vaut 0s sur la home (cf. css/carousel.css), donc la
   mise au point démarre à l'instant zéro. Si ce token redevenait non
   nul un jour, l'intro attendrait d'autant — et il faudrait le
   neutraliser ici. */
html[data-intro-start] body.fl-home .fl-home-img.is-active {
	filter: blur( var( --fl-blur ) );
	transform: scale( var( --fl-scale ) );
}

/* ------------------------------------------------------------------ */
/* 2. LES MARGES SE REMPLISSENT                                        */
/* ------------------------------------------------------------------ */

/* LE TEMPO DE L'INDEX, posé sur .home-index et pas sur la racine : les
   deux tokens d'About y sont déclarés, et une valeur posée plus haut
   dans l'arbre serait masquée par la sienne.

   On ne déclare AUCUNE transition d'opacité ici — celle de css/about.css
   sur .home-index a existe déjà, avec son délai en
   calc( var(--fl-i) * var(--about-index-stagger) ). Poser une seconde
   déclaration "transition" sur le même sélecteur l'ÉCRASERAIT au lieu de
   s'y ajouter. On se contente donc de redéfinir ce qu'elle LIT. */
html[data-intro] body.fl-home .home-index {
	--about-text-duration: var( --intro-index-duration );
	--about-index-stagger: var( --intro-index-stagger );
	/* --about-fold-ease ne sert, sur ce sélecteur, qu'à l'opacité de
	   .home-index a (cf. css/about.css : la couleur, elle, a sa propre
	   courbe dans la même déclaration). Le redéfinir ici ne touche donc
	   que ce qu'on vise. */
	--about-fold-ease: var( --intro-index-ease );
}

html[data-intro-start] body.fl-home .home-index a {
	opacity: 0;
}

/* LE DÉPLACEMENT, LUI, EST NOUVEAU — et il vit sur les deux SPANS, pas
   sur le lien. Deux raisons, et la première suffit : les deux morceaux
   doivent aller dans des sens OPPOSÉS, ils ne peuvent donc pas partager
   un transform. La seconde est qu'on évite ainsi de toucher au raccourci
   "transition" d'about.css sur le lien.

   Déclarée sous data-intro, donc elle n'existe QUE pendant l'intro :
   aucune transition permanente ajoutée à des éléments qui n'en avaient
   pas. Elle est bien présente à l'instant du déclenchement, puisque
   data-intro survit au retrait de data-intro-start. */
html[data-intro] body.fl-home .home-index-num,
html[data-intro] body.fl-home .home-index-name {
	transition: transform var( --intro-index-duration ) var( --intro-index-ease )
		calc( var( --fl-i, 0 ) * var( --intro-index-stagger ) );
}

html[data-intro-start] body.fl-home .home-index-num {
	transform: translateX( calc( -1 * var( --intro-index-shift ) ) );
}

html[data-intro-start] body.fl-home .home-index-name {
	transform: translateX( var( --intro-index-shift ) );
}

/* ------------------------------------------------------------------ */
/* 3. LE CARTEL S'ÉCRIT                                                */
/* ------------------------------------------------------------------ */

/* La couche active des deux lignes part de l'opacité zéro. Sa transition
   de retour est celle de theme.css (--fl-cap-in, 0,8s) ; on ne remplace
   que le DÉLAI, en propriété longue — theme.css le pose lui aussi en
   longue, juste après son raccourci, donc les deux se superposent
   proprement.

   Ne pas confondre avec .caption-text tout court, qui est la couche
   inactive : elle est déjà à zéro et doit y rester. */
html[data-intro-start] body.fl-home .home-caption .caption-text.is-active {
	opacity: 0;
}

html[data-intro] body.fl-home #fl-caption-title .caption-text.is-active {
	transition-delay: var( --intro-caption-delay );
}

html[data-intro] body.fl-home #fl-caption-meta .caption-text.is-active {
	transition-delay: calc( var( --intro-caption-delay ) + var( --intro-caption-line2 ) );
}

/* ------------------------------------------------------------------ */
/* Réduire les animations                                              */
/* ------------------------------------------------------------------ */

/* Le JS ne pose déjà pas les attributs sous ce réglage, donc ce bloc ne
   sert jamais. Il est là comme FILET : si un jour la décision passait du
   JS au CSS, ou si les attributs étaient posés par un autre chemin, une
   intro figée laisserait la page dans son état de départ — photo floue,
   index invisible, légende vide. Un état de départ bloqué est bien pire
   qu'une absence d'animation.

   On neutralise donc les VALEURS, pas les transitions : la page doit se
   retrouver au repos, pas s'y rendre lentement. */
@media (prefers-reduced-motion: reduce) {
	html[data-intro-start] body.fl-home .fl-home-img.is-active {
		filter: blur( 0px );
		transform: scale( 1 );
	}

	html[data-intro-start] body.fl-home .home-index a,
	html[data-intro-start] body.fl-home .home-caption .caption-text.is-active {
		opacity: 1;
	}

	html[data-intro-start] body.fl-home .home-index-num,
	html[data-intro-start] body.fl-home .home-index-name {
		transform: none;
	}
}
