/**
 * ET Astra — effets de défilement du bandeau d'annonce.
 *
 * Cette feuille est chargée par le site ET par l'aperçu de l'administration.
 * Les sélecteurs sont donc neutres — `eta-fx`, `eta-fx-track`, `eta-fx-copy` —
 * et posés sur les deux balisages. Une divergence entre ce qu'on voit dans les
 * réglages et ce qui sort en ligne devient impossible par construction.
 *
 * Toutes les animations bouclent en une passe : le texte se montre, sort du
 * cadre, puis revient. Rien n'est dupliqué, et la phrase n'apparaît jamais
 * deux fois à l'écran en même temps.
 */

.eta-fx {
	display: grid;
	overflow: hidden;

	/*
	 * Cadence d'un tour : la durée de l'effet, plus la pause.
	 *
	 * La pause n'est pas une animation de plus. Les huit effets se terminent
	 * tous phrase invisible ou hors cadre : il suffit donc de tenir cette
	 * dernière image un moment. L'animation dure le tour entier, et la
	 * fonction de cadencement atteint sa valeur finale à `durée / tour` puis
	 * s'y maintient. Une pause de zéro rend exactement le comportement
	 * d'origine.
	 */
	--eta-fx-pause: 0s;
	--eta-fx-total: calc( var( --eta-fx-speed, 22s ) + var( --eta-fx-pause, 0s ) );

	/*
	 * Ces trois fonctions sont remplacées par une courbe `linear()` à palier
	 * dès qu'une pause est demandée. Sans pause, ce sont les cadencements
	 * d'origine.
	 */
	--eta-fx-ease-linear: linear;
	--eta-fx-ease-soft: ease-in-out;
	--eta-fx-ease-steps: steps(28, end);
}

/* ------------------------------------------------------------------
   Relais entre plusieurs phrases
   ------------------------------------------------------------------
   Les phrases sont empilées dans la même cellule de grille : elles
   occupent donc le même espace, et le bandeau garde la hauteur d'une
   seule ligne.

   Chaque créneau est visible pendant une durée d'effet, puis cede la
   place au suivant. L'animation de relais dure N fois celle de l'effet,
   et son retard vaut -N × le rang : le créneau i devient donc visible à
   l'instant i × durée, exactement quand l'effet redémarre son cycle.
   Les deux restent alignés sans qu'aucun script n'ait à les synchroniser.
   ------------------------------------------------------------------ */

.eta-fx .eta-fx-slot {
	grid-area: 1 / 1;
	min-width: 0;
}

.eta-fx-n2 .eta-fx-slot,
.eta-fx-n3 .eta-fx-slot,
.eta-fx-n4 .eta-fx-slot {
	animation-timing-function: step-end;
	animation-iteration-count: infinite;
}

/*
 * Le retard vaut (rang − total) × durée, et non −rang × durée.
 *
 * Un retard négatif fait démarrer l'animation comme si elle avait déjà
 * tourné d'autant. Pour que le créneau i s'ouvre à l'instant i × durée, il
 * lui faut avoir consommé (total − i) durées, pas i. Les deux formules
 * coïncident à deux phrases, ce qui rend l'erreur invisible jusqu'à la
 * troisième : la phrase 2 sur 3 apparaissait au mauvais moment.
 */
.eta-fx-n2 .eta-fx-slot {
	animation-name: eta-fx-slot-2;
	animation-duration: calc( var( --eta-fx-total ) * 2 );
	animation-delay: calc( var( --eta-fx-total ) * ( var( --eta-fx-slot, 0 ) - 2 ) );
}

.eta-fx-n3 .eta-fx-slot {
	animation-name: eta-fx-slot-3;
	animation-duration: calc( var( --eta-fx-total ) * 3 );
	animation-delay: calc( var( --eta-fx-total ) * ( var( --eta-fx-slot, 0 ) - 3 ) );
}

.eta-fx-n4 .eta-fx-slot {
	animation-name: eta-fx-slot-4;
	animation-duration: calc( var( --eta-fx-total ) * 4 );
	animation-delay: calc( var( --eta-fx-total ) * ( var( --eta-fx-slot, 0 ) - 4 ) );
}

/*
 * `visibility` et non `display` : une piste retirée du flux perdrait sa
 * largeur, et les effets de défilement, qui se mesurent sur elle, sauteraient
 * à chaque changement de phrase.
 */
@keyframes eta-fx-slot-2 {
	0%     { visibility: visible; }
	50%    { visibility: hidden; }
	100%   { visibility: hidden; }
}

@keyframes eta-fx-slot-3 {
	0%     { visibility: visible; }
	33.34% { visibility: hidden; }
	100%   { visibility: hidden; }
}

@keyframes eta-fx-slot-4 {
	0%     { visibility: visible; }
	25%    { visibility: hidden; }
	100%   { visibility: hidden; }
}

.eta-fx .eta-fx-track {
	display: block;
	width: 100%;
	white-space: nowrap;
	text-align: center;
	will-change: transform, opacity;
}

.eta-fx .eta-fx-copy {
	display: inline-block;
}

/*
 * Survoler suspend l'effet : le temps de lire, ou de cliquer sur le lien.
 * Le relais est figé lui aussi, sinon la phrase en cours de lecture
 * disparaîtrait au profit de la suivante.
 */
.eta-fx:hover .eta-fx-slot,
.eta-fx:hover .eta-fx-track,
.eta-fx:hover .eta-fx-copy {
	animation-play-state: paused;
}

/* ------------------------------------------------------------------
   Les deux défilements et le va-et-vient
   ------------------------------------------------------------------
   `padding-left: 100%` porte sur le bloc conteneur, donc sur la largeur
   du bandeau : la piste mesure une largeur d'écran plus le texte. Un
   déplacement de -100 % de la piste fait donc entrer le texte par la
   droite et le fait sortir par la gauche, quelle que soit sa longueur.
   C'est ce qui permet de se passer de toute duplication.
   ------------------------------------------------------------------ */

.eta-fx-slide .eta-fx-track,
.eta-fx-slideback .eta-fx-track,
.eta-fx-bounce .eta-fx-track {
	display: inline-block;
	width: auto;
	padding-left: 100%;
	text-align: left;
}

.eta-fx-slide .eta-fx-track {
	animation: eta-fx-travel var(--eta-fx-total) var(--eta-fx-ease-linear) infinite;
}

.eta-fx-slideback .eta-fx-track {
	animation: eta-fx-travel var(--eta-fx-total) var(--eta-fx-ease-linear) infinite reverse;
}

.eta-fx-bounce .eta-fx-track {
	animation: eta-fx-travel var(--eta-fx-total) var(--eta-fx-ease-soft) infinite alternate;
}

@keyframes eta-fx-travel {
	from { transform: translateX(0); }
	to   { transform: translateX(-100%); }
}

/* ------------------------------------------------------------------
   Effets sur place
   ------------------------------------------------------------------ */

.eta-fx-fade .eta-fx-copy {
	animation: eta-fx-fade var(--eta-fx-total) var(--eta-fx-ease-soft) infinite;
}

@keyframes eta-fx-fade {
	0%   { opacity: 0; }
	14%  { opacity: 1; }
	78%  { opacity: 1; }
	100% { opacity: 0; }
}

.eta-fx-rise .eta-fx-copy {
	animation: eta-fx-rise var(--eta-fx-total) var(--eta-fx-ease-soft) infinite;
}

@keyframes eta-fx-rise {
	0%   { transform: translateY(130%); opacity: 0; }
	12%  { transform: translateY(0);    opacity: 1; }
	80%  { transform: translateY(0);    opacity: 1; }
	100% { transform: translateY(-130%); opacity: 0; }
}

.eta-fx-zoom .eta-fx-copy {
	animation: eta-fx-zoom var(--eta-fx-total) var(--eta-fx-ease-soft) infinite;
}

@keyframes eta-fx-zoom {
	0%   { transform: scale(0.55); opacity: 0; }
	15%  { transform: scale(1);    opacity: 1; }
	78%  { transform: scale(1);    opacity: 1; }
	100% { transform: scale(1.6);  opacity: 0; }
}

.eta-fx-flip .eta-fx-track {
	perspective: 420px;
}

.eta-fx-flip .eta-fx-copy {
	transform-origin: center bottom;
	animation: eta-fx-flip var(--eta-fx-total) var(--eta-fx-ease-soft) infinite;
}

@keyframes eta-fx-flip {
	0%   { transform: rotateX(-92deg); opacity: 0; }
	13%  { transform: rotateX(0);      opacity: 1; }
	80%  { transform: rotateX(0);      opacity: 1; }
	100% { transform: rotateX(92deg);  opacity: 0; }
}

/*
 * Frappe machine. Le dévoilement passe par `clip-path` et non par une
 * animation de largeur : la largeur d'un texte n'est pas connue à l'avance,
 * et `width: 100%` désignerait celle du bandeau, pas celle de la phrase.
 * Le curseur, lui, est un pseudo-élément posé au bord droit du texte.
 */
.eta-fx-type .eta-fx-copy {
	position: relative;
	padding-right: 0.7ch;
	animation: eta-fx-type var(--eta-fx-total) var(--eta-fx-ease-steps) infinite;
}

.eta-fx-type .eta-fx-copy::after {
	content: "";
	position: absolute;
	top: 0.1em;
	right: 0;
	bottom: 0.1em;
	width: 2px;
	background: currentColor;
	animation: eta-fx-caret 0.9s step-end infinite;
}

@keyframes eta-fx-type {
	0%   { clip-path: inset(0 100% 0 0); }
	55%  { clip-path: inset(0 0 0 0); }
	88%  { clip-path: inset(0 0 0 0); }
	100% { clip-path: inset(0 100% 0 0); }
}

@keyframes eta-fx-caret {
	50% { opacity: 0; }
}

/* ------------------------------------------------------------------
   Écrans étroits
   ------------------------------------------------------------------
   Cinq effets sur huit supposent que la phrase tienne dans la largeur du
   bandeau : fondu, montée, zoom, bascule et frappe machine ne déplacent
   pas le texte, ils le montrent sur place. Sur un téléphone, une phrase
   d'annonce dépasse presque toujours — elle est alors rognée des deux
   côtés, et le visiteur n'en lit jamais la fin.

   En dessous de 782 px, ces cinq effets cèdent donc la place au
   défilement, seul comportement qui garantit que la phrase entière passe
   sous les yeux. Les trois autres — les deux defilements et le va-et-vient
   — sont déjà adaptés par construction.
   ------------------------------------------------------------------ */

@media ( max-width: 782px ) {

	.eta-fx-fade .eta-fx-track,
	.eta-fx-rise .eta-fx-track,
	.eta-fx-zoom .eta-fx-track,
	.eta-fx-flip .eta-fx-track,
	.eta-fx-type .eta-fx-track {
		display: inline-block;
		width: auto;
		padding-left: 100%;
		text-align: left;
		perspective: none;
		animation: eta-fx-travel var( --eta-fx-total ) var( --eta-fx-ease-linear ) infinite;
	}

	/*
	 * La copie reprend son état neutre : sans cela, le fondu la laisserait
	 * transparente ou la frappe machine la garderait rognée pendant qu'elle
	 * défile.
	 */
	.eta-fx-fade .eta-fx-copy,
	.eta-fx-rise .eta-fx-copy,
	.eta-fx-zoom .eta-fx-copy,
	.eta-fx-flip .eta-fx-copy,
	.eta-fx-type .eta-fx-copy {
		animation: none;
		opacity: 1;
		transform: none;
		clip-path: none;
	}

	.eta-fx-type .eta-fx-copy {
		padding-right: 0;
	}

	.eta-fx-type .eta-fx-copy::after {
		display: none;
	}
}

/* ------------------------------------------------------------------
   Mouvement réduit
   ------------------------------------------------------------------
   Le réglage système l'emporte sur tous les effets : le texte s'affiche
   une fois, centré et immobile. Un bandeau qui bouge sans fin est un
   obstacle de lecture, et le respect de ce réglage est une exigence WCAG.
   ------------------------------------------------------------------ */

@media ( prefers-reduced-motion: reduce ) {

	.eta-fx .eta-fx-slot,
	.eta-fx .eta-fx-track,
	.eta-fx .eta-fx-copy,
	.eta-fx .eta-fx-copy::after {
		animation: none;
	}

	/*
	 * Les phrases sont superposées : sans relais, elles s'afficheraient
	 * toutes en même temps au même endroit. Seule la première est gardée.
	 */
	.eta-fx .eta-fx-slot {
		visibility: hidden;
	}

	.eta-fx .eta-fx-slot:first-child {
		visibility: visible;
	}

	.eta-fx .eta-fx-track {
		display: block;
		width: 100%;
		padding-left: 0;
		text-align: center;
		white-space: normal;
		transform: none;
	}

	.eta-fx .eta-fx-copy {
		clip-path: none;
		opacity: 1;
		transform: none;
	}

	.eta-fx-type .eta-fx-copy::after {
		display: none;
	}
}
