/*
 * Bandeau photos.
 * Réf design : Figma 14749:5500 (bureau 1440), 14751:7735 (mobile 393).
 *
 * Une rangée de photos découpées dans un galet, qui traverse l'écran de droite
 * à gauche au défilement de la page.
 *
 * UNE RANGÉE, ET NON TROIS PHOTOS QUI SE SUIVENT
 *
 * Les photos sont posées en rangée dans les unités de la maquette, et c'est la
 * rangée entière que le défilement translate. --bp-p, porté par la bande,
 * est la position de cette rangée sur son trajet : 0 toute la rangée hors
 * champ à droite, 1 toute la rangée hors champ à gauche. Chaque photo s'en
 * déduit par sa place dans la rangée, --bp-decal.
 *
 * La première version donnait à chaque photo sa propre position de 0 à 1,
 * donc une position fonction de la largeur de la fenêtre, alors que la
 * largeur des photos est bornée à la cote de maquette. Au-delà de 1440 la
 * rangée se dilatait sans que les photos grossissent : écarts de 30 et 73 px
 * à 1280, de 126 et 180 à 1680. La composition n'était juste qu'à 1440.
 *
 * --bp-d, porté par chaque photo, est l'avancement de CETTE photo dans sa
 * propre traversée. Il ne sert qu'à l'arc et à l'inclinaison, qui doivent
 * culminer quand elle passe au milieu de l'écran, et non quand la rangée y
 * passe. C'est un
 * rapport de longueurs, que CSS ne sait pas calculer : le rendu l'écrit à sa
 * valeur de repos, le script de la traversée le recalculera image après image.
 *
 * Deux frontières, les mêmes que partout : 782 pour la mise en page, et une
 * rampe continue entre 393 et 1440 pour les cotes relevées sur les maquettes.
 * ------------------------------------------------------------------------- */

/*
 * LA BANDE COUPE À GAUCHE ET À DROITE, JAMAIS EN HAUT NI EN BAS
 *
 * Les photos sont plus hautes que la bande et montent encore avec l'arc : elles
 * doivent déborder en haut et en bas sans être rognées. Elles doivent en
 * revanche disparaître sur les côtés, sinon la page défile à l'horizontale.
 *
 * `overflow` ne sait pas faire : `overflow-x: hidden` force `overflow-y` à
 * `auto`, on ne coupe pas un seul axe. On a d'abord essayé de réserver la
 * hauteur du débord en retrait intérieur, comme --pc-badge-overflow sur la
 * piste du carrousel ; la réserve doit alors couvrir la plus grande photo ET
 * l'amplitude de l'arc, donc une valeur à retoucher à chaque réglage.
 *
 * `clip-path` dit exactement la chose voulue, et sans rien à régler : la
 * silhouette de coupe est le rectangle de la bande, étendu verticalement bien
 * au-delà de ce qu'une photo pourra jamais dépasser.
 */
.bandeau-photos {

	/* Ombre et arc. Réglés une fois, ici. */
	--bp-couleur: var(--wp--preset--color--pink, #f8c9de);
	--bp-ombre: 16px;

	/*
	 * Rotation au défilement, ajoutée à l'inclinaison réglée en admin : la
	 * première valeur au début de la course, la seconde à la fin.
	 *
	 * Suit --bp-t, l'avancement LINÉAIRE au défilement, et non --bp-p : le
	 * trajet en trois temps de la rangée ralentit au milieu, juste quand les
	 * photos sont à l'écran, et la rotation y devenait imperceptible.
	 *
	 * --bp-t vaut 0,5 au repos (sans script ou en mouvement réduit) : les
	 * formes restent à mi-course, droites.
	 */
	--bp-t: 0.5;
	--bp-tour-depart: 40deg;
	--bp-tour: -40deg;

	/*
	 * L'ARC : SA HAUTEUR, PUIS SA FORME
	 *
	 * --bp-amplitude est la hauteur dont la photo s'élève au sommet de sa
	 * course. --bp-rondeur dit ce qui se passe entre les deux bouts.
	 *
	 * À 0 la courbe est une parabole : elle ne monte qu'au dernier moment et
	 * pique au sommet. À 1 c'est une quartique : elle monte tôt et s'aplatit
	 * en haut. Entre les deux on passe par la forme d'un arc de cercle, que
	 * 0,7 approche à deux centièmes près sur tout le milieu de la course.
	 *
	 * Le mélange est fait de multiplications, et c'est délibéré. sqrt() dirait
	 * le cercle exact et le navigateur le gère, mais sur un navigateur ancien
	 * --bp-arc deviendrait invalide, et c'est tout le `translate` qui sauterait
	 * avec : les photos perdraient leur position, pas seulement leur courbe.
	 */
	--bp-amplitude: 13rem;
	--bp-rondeur: 0.7;

	/*
	 * Position de la rangée au repos. 0,5 la centre ; 0,48 est la valeur de la
	 * maquette, où la rangée est posée 68 px plus à droite que son centre.
	 *
	 * render.php en garde une copie, pour en déduire l'arc de chaque photo au
	 * repos. Les deux doivent rester d'accord. Un écart ne décale pas la
	 * composition, il fausse seulement l'arc avant que le script ne démarre.
	 */
	--bp-repos: 0.48;
	--bp-p: var(--bp-repos);

	/*
	 * COURSE DE LA RANGÉE, et c'est le seul endroit où elle se règle.
	 *
	 * Position du HAUT DE LA BANDE dans l'écran, en part de hauteur de
	 * fenêtre : 1 la bande affleure le bas de l'écran, 0 son haut touche le
	 * haut de l'écran, négatif elle est déjà sortie par le haut.
	 *
	 * view.js les lit ici plutôt que de les porter en dur, pour que la media
	 * query reste le seul endroit où le mobile se règle.
	 *
	 * À 1 la course démarrait pile quand le haut de la bande touchait le bas de
	 * l'écran, donc avant qu'on ait rien pu voir : les photos étaient déjà
	 * lancées à l'apparition de la bande. À 0,85 elles ne s'ébranlent qu'une
	 * fois le premier septième de la bande à l'écran.
	 *
	 * Déplacer la bande dans la page ne produirait PAS cet effet : la course se
	 * mesure sur la position de la bande dans la FENÊTRE, pas dans le document.
	 * Un retrait au-dessus d'elle allonge le défilement avant qu'on l'atteigne,
	 * et l'animation repart exactement au même moment visuel.
	 */
	--bp-debut: 1.2;
	--bp-fin: -0.4;

	/*
	 * L'ÉCHELLE DE LA RANGÉE, EN UN SEUL ENDROIT
	 *
	 * --bp-unite est la longueur à l'écran d'une unité de maquette. Largeurs et
	 * écarts la multiplient tous les deux, donc la composition se met à
	 * l'échelle d'un bloc au lieu de se déformer.
	 *
	 * La rampe vaut 1px à 1440 et 0,5607px à 393, facteur mesuré entre les deux
	 * maquettes au millième près sur les trois galets. Les deux bornes sont donc
	 * exactes. Au-delà de 1440 elle est plafonnée : les photos de la maquette ne
	 * grossissent pas sur un grand écran, elles s'y espacent.
	 *
	 * Le plafond de hauteur se pose ensuite sur l'ÉCHELLE, pas sur chaque photo.
	 * Sur une photo il les aurait toutes ramenées à la même taille ; sur
	 * l'échelle, elles se réduisent du même facteur, écarts compris. --bp-max,
	 * écrit par le rendu, est la plus grande photo de la rangée en unités de
	 * maquette : c'est elle qui ne doit pas dépasser le plafond.
	 */
	--bp-plafond: 70vh;
	--bp-rampe: clamp(0.5607px, 0.39581px + 0.041958vw, 1px);
	--bp-unite: min(var(--bp-rampe), calc(var(--bp-plafond) / var(--bp-max, 1)));
	--bp-longueur: calc(var(--bp-unite) * var(--bp-long, 1));

	position: relative;
	clip-path: inset(-100vh 0);

	/*
	 * Les photos peignent par-dessus les sections voisines. C'est un décor : il
	 * n'intercepte ni clic ni survol de ce qu'il recouvre.
	 */
	pointer-events: none;
}

/*
 * Sortie du retrait du groupe parent.
 *
 * La bande doit partir du BORD DE L'ÉCRAN : le trajet compte en 100vw, et une
 * bande en retrait décalerait toute la rangée d'autant.
 *
 * main.css annule la marge négative que WordPress donne à un alignfull imbriqué
 * dans un autre alignfull. La règle est juste sur la home, où les sections
 * n'ont aucun retrait : le bloc y occupe déjà toute la largeur. Sur la fiche
 * produit le groupe qui enveloppe tout porte, lui, le retrait racine — la bande
 * s'arrêtait donc à 16 px des bords, et ses photos avec.
 *
 * Rétablir UNE marge négative ne suffisait pas : sur la fiche, la bande est
 * dans deux groupes en retrait l'un dans l'autre, et s'arrêtait encore à 16 px
 * des bords. Compter les retraits à annuler casserait à la prochaine
 * imbrication.
 *
 * La bande se cale donc directement sur la largeur de la PAGE, quel que soit
 * son parent : le <main> devient un conteneur de requête, 100cqw vaut sa
 * largeur, et `50% - 50cqw` ramène les deux bords à ceux de la page dès lors
 * que le parent est centré. Le <main> et non 100vw : il ne compte pas la barre
 * de défilement, qui décalerait la bande de la moitié de sa largeur.
 *
 * Le conteneur n'est déclaré que sur une page qui a un bandeau.
 *
 * Quatre classes : main.css annule la marge des alignfull imbriqués avec
 * `.site-main .alignfull > .alignfull`, trois classes, et passe après.
 */
.site-main:has(.bandeau-photos) {
	container-type: inline-size;
}

.site-main .wp-block-drache-bandeau-photos.bandeau-photos.alignfull {
	width: auto;
	max-width: none;
	margin-inline: calc(50% - 50cqw);
}

/*
 * La piste porte la hauteur de bande de la maquette : 233 à 393, 475 à 1440.
 * C'est la hauteur de la SECTION, pas celle des photos : elle suit la
 * fenêtre et non l'échelle de la rangée.
 */
.bandeau-photos__piste {
	position: relative;
	height: clamp(14.5625rem, 8.8852rem + 23.1137vw, 29.6875rem);
	margin: 0;
	padding: 0;
	list-style: none;
}

/*
 * Une photo.
 *
 * LA BOÎTE EST LA FORME, PAS UN CADRE AUTOUR D'ELLE. La photo la remplit
 * entièrement et le masque la découpe : ce qu'on voit fait donc exactement la
 * largeur du `li`.
 *
 * Cela n'est vrai QUE SI LE MASQUE EST RESSERRÉ SUR SON TRACÉ. Figma exporte la
 * boîte du calque, vide compris : masque-blob-2 n'y remplissait que 74 % de son
 * viewBox, sa fleur ne faisait donc que les trois quarts du `li` et elle
 * paraissait reculée par rapport à ses voisines, alors que les deux autres
 * remplissaient 97 %. Tout masque ajouté au catalogue doit être resserré, cf.
 * l'en-tête des fichiers assets/img/product/masque-*.svg.
 *
 * ABSCISSE : la rangée, puis la place de la photo dedans. Le trajet de la
 * rangée fait un écran plus sa longueur, la distance pour y entrer et en
 * ressortir en entier.
 */
.bandeau-photos__photo {
	--bp-largeur: calc(var(--bp-unite) * var(--bp-taille));
	--bp-decalage: calc(var(--bp-unite) * var(--bp-decal, 0));

	/*
	 * L'arc. Vaut 0 aux deux bouts de la course et 1 en son milieu, sans
	 * dépendre de la prise en charge de sin() ni de sqrt() en CSS.
	 *
	 * --bp-centre est l'écart au milieu de la course, de -1 à 1, et --bp-carre
	 * son carré. La parabole vaut alors (1 - carré) ; --bp-rondeur y ajoute de
	 * quoi relever les flancs, jusqu'à (1 - carré²) à 1. La courbe ne dépasse
	 * jamais 1, elle décroît de façon monotone depuis le sommet.
	 */
	--bp-centre: calc(1 - 2 * var(--bp-d));
	--bp-carre: calc(var(--bp-centre) * var(--bp-centre));
	--bp-releve: calc(1 + var(--bp-rondeur) * var(--bp-carre));
	--bp-arc: calc((1 - var(--bp-carre)) * var(--bp-releve));

	position: absolute;
	top: 50%;
	left: 0;
	width: var(--bp-largeur);
	aspect-ratio: 1;
	filter: drop-shadow(var(--bp-ombre) var(--bp-ombre) 0 var(--bp-couleur));

	/*
	 * translate en propriété distincte et non dans transform : rotate et scale
	 * se composent alors sans s'écraser, convention déjà posée dans
	 * media-text-decor.css.
	 *
	 * -50% en ordonnée recentre la photo sur la piste ; l'arc s'y ajoute.
	 */
	translate:
		calc(100vw - var(--bp-p) * (100vw + var(--bp-longueur)) + var(--bp-decalage))
		calc(-50% - var(--bp-arc) * var(--bp-amplitude));

	/*
	 * La rotation au défilement porte sur TOUTE la forme — masque, photo et
	 * ombre ensemble — d'où l'élément de liste et non l'image, qui garde pour
	 * elle seule l'inclinaison réglée en admin.
	 */
	rotate: calc(
		var(--bp-tour-depart, 0deg)
		+ var(--bp-t, 0.5) * (var(--bp-tour, 0deg) - var(--bp-tour-depart, 0deg))
	);
}

/*
 * La photo, découpée dans la SILHOUETTE NUE de la forme.
 *
 * Le fichier pointé par --bp-forme ne porte pas l'ombre : elle est générée sans
 * le filtre que Figma cuit dans les formes dessinées (cf.
 * drache_product_shape_url). Avec l'ombre, l'alpha du masque couvrait la forme
 * ET son décalage, et le découpage débordait du contour.
 *
 * DEUX CLASSES, ET C'EST NÉCESSAIRE. La fiche produit est une page
 * WooCommerce, et `woocommerce-layout.css` y pose `.woocommerce img`
 * avec `height: auto`, à deux de poids. Sur une seule classe la hauteur
 * restait donc en auto : les photos gardaient leur rapport d'origine au lieu de
 * remplir leur boîte carrée, et le masque, calé en `contain` sur une boîte
 * devenue haute, ne découpait plus rien de visible. C'est la quatrième fois
 * qu'une règle `.woocommerce <élément>` l'emporte sur une règle du thème à
 * une classe, après le champ quantité, le bouton d'achat et les images de
 * carte.
 */
.bandeau-photos__photo .bandeau-photos__image {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	mask: var(--bp-forme) center / contain no-repeat;
	-webkit-mask: var(--bp-forme) center / contain no-repeat;
	rotate: var(--bp-rotation, 0deg);
}

/* Bloc vide, en édition seulement. */
.bandeau-photos--vide {
	margin: 0;
	padding: var(--wp--preset--spacing--xl, 1.5rem);
	border: 1px dashed var(--wp--preset--color--rose-04, #664d9a);
	border-radius: var(--wp--custom--radius--md, 0.5rem);
	color: var(--wp--preset--color--noir, #1f2937);
	text-align: center;
}

@media (max-width: 781px) {

	.bandeau-photos {
		--bp-ombre: 8px;
		--bp-amplitude: 6.5rem;

		/* La bande est deux fois moins haute : elle traverse plus vite. */
		--bp-debut: 0.85;
		--bp-fin: -0.35;
	}
}

/*
 * MOUVEMENT RÉDUIT, GARDÉ UNE SECONDE FOIS
 *
 * view.js sort déjà avant de rien écrire. Cette règle couvre le cas où le
 * réglage système change APRÈS le montage : le script tourne alors toujours, et
 * ses valeurs sont EN LIGNE, donc gagnantes sur la feuille. D'où `!important`,
 * même geste que marque.css.
 *
 * La rangée revient à sa place de repos, et l'arc est coupé. On ne peut pas
 * rendre à chaque photo son --bp-d de repos, que le script a écrasé : c'est un
 * nombre par photo, écrit par le rendu. Annuler l'arc dit la même chose en CSS
 * seul, et la composition au repos est celle de la maquette, sans la courbe.
 */
@media (prefers-reduced-motion: reduce) {

	.bandeau-photos {
		--bp-p: var(--bp-repos) !important;
		--bp-t: 0.5 !important;
	}

	.bandeau-photos__photo {
		--bp-arc: 0 !important;
	}
}
