/*
 * cards/rail — engagement 5 : aucun hexadecimal, valeurs de repli comprises.
 *
 * Tout est cadre sous .ivy-cards--rail. Le CSS de TOUTES les compositions
 * d'un rayon est charge sur chaque page qui l'emploie : sans ce cadre, deux
 * produits declarant .ivy-cards__card se repeindraient l'un l'autre selon
 * l'ordre de chargement. Defaut constate sur le rayon navbar, pas suppose.
 *
 * La distance de defilement vient de --ivy-rail-distance, publie par le
 * runtime : c'est elle qui cree le parcours. Elle vaut le debordement
 * multiplie par la cadence, ce qui permet de ralentir la piste sans la
 * raccourcir. Sans JavaScript, la propriete n'existe pas, le repli vaut 0, et
 * la section garde sa hauteur naturelle — une rangee qu'on fait defiler a la
 * main.
 */

.ivy-cards--rail {
	--ivy-cards-gap: clamp( 16px, 2vw, 28px );
	/* Le decalage de l'element epingle. Un theme a barre collante y met sa
	   hauteur ; a defaut, le haut de la fenetre. */
	--ivy-cards-top: 0px;

	position: relative;
	width: 100%;
	color: var( --ivy-ink, rgb( 17 17 17 ) );
}

/*
 * La distance est portee par une CALE, pas par une hauteur.
 *
 * C'est la difference qui compte : une hauteur suppose de connaitre celle de
 * l'element epingle, donc de la forcer — 100vh — et la piste, plus courte que
 * la fenetre, laisse alors un vide au-dessus et au-dessous d'elle. Defaut
 * constate a l'essai par Alex : un widget ne doit pas reclamer l'ecran
 * entier, il doit se poser dans une section a cote d'un intro.
 *
 * Pourquoi une cale et non une marge interieure : un element collant est
 * retenu par son BLOC CONTENEUR, c'est-a-dire la boite de CONTENU de son
 * parent. Une marge interieure est en dehors, et n'offre donc aucune course —
 * l'element se decolle immediatement. Mesure a l'appui, et le premier jet de
 * ce correctif est tombe dedans.
 */
.ivy-cards--rail .ivy-cards__scroller {
	position: relative;
}

.ivy-cards--rail .ivy-cards__spacer {
	height: var( --ivy-rail-distance, 0px );
}

/*
 * Le pin se pose au MILIEU de la fenetre, pas contre son bord haut.
 *
 * --ivy-pin-lead est la moitie du blanc, mesuree et publiee par le runtime :
 * la boite garde sa hauteur de contenu — elle ne reclame pas l'ecran, voir
 * la cale ci-dessus — et c'est le decalage collant qui la descend. Sans
 * JavaScript, la propriete n'existe pas, le repli vaut 0, et le pin retrouve
 * le comportement d'avant.
 *
 * max() et non une somme : --ivy-cards-top est la place qu'un theme a barre
 * collante se reserve. Le centrage l'emporte tant qu'il tombe plus bas que
 * la barre — le cas courant — et la barre l'emporte sinon, ce qui garantit
 * que le contenu ne passe jamais dessous.
 */
.ivy-cards--rail .ivy-cards__pin {
	position: sticky;
	display: grid;
	top: max( var( --ivy-cards-top ), var( --ivy-pin-lead, 0px ) );
}

/*
 * L'INTRO — label, titre, description, tous facultatifs — vit DANS le pin,
 * pas avant lui : c'est ce qui la garde a l'ecran pendant tout l'epinglage,
 * au lieu de defiler et disparaitre avant que la piste ne prenne le relais.
 * Defaut constate par Alex : sans elle, le centrage laissait un grand vide
 * au-dessus des cartes plutot que d'y mettre du contenu.
 *
 * Consequence directe : --ivy-pin-lead centre TOUT le pin, intro comprise —
 * measure() la mesure a chaque appel via pin.getBoundingClientRect().height,
 * sans qu'une ligne du runtime sache que l'intro existe (PASSATION §1).
 */
.ivy-cards--rail .ivy-cards__intro {
	display: grid;
	/* La grille couvre toute la section epinglee : les choix Left / Center /
	 * Right des trois parties se calculent donc contre le parent Cards, pas
	 * contre une colonne editorialement plafonnee. */
	width: 100%;
	justify-self: start;
	margin: 0 0 clamp( 24px, 4vw, 40px );
}

.ivy-cards--rail .ivy-cards__intro-eyebrow {
	display: block;
	margin-bottom: 12px;
	color: var( --ivy-intro_eyebrow-color, var( --ivy-muted, rgb( 82 82 82 ) ) );
	font-size: var( --ivy-font-label );
	font-weight: 700;
	letter-spacing: 0.14em;
	text-transform: uppercase;
}

.ivy-cards--rail .ivy-cards__intro-title {
	margin: 0;
	color: var( --ivy-intro_title-color, var( --ivy-ink, rgb( 17 17 17 ) ) );
	font-size: var( --ivy-font-h2 );
	line-height: 1.08;
	letter-spacing: -0.03em;
}

.ivy-cards--rail .ivy-cards__intro-text {
	max-inline-size: min( 100%, 58ch );
	margin: 12px 0 0;
	color: var( --ivy-intro_text-color, var( --ivy-muted, rgb( 110 110 110 ) ) );
	line-height: 1.6;
}

/* Chaque partie de l'intro porte son propre choix Elementor. `justify-self`
 * deplace donc vraiment le label, le titre ou le texte, tandis que
 * `text-align` aligne ses lignes une fois le bloc en place. */
.ivy-cards--rail .ivy-cards__intro-eyebrow,
.ivy-cards--rail .ivy-cards__intro-title,
.ivy-cards--rail .ivy-cards__intro-text {
	inline-size: fit-content;
	max-inline-size: 100%;
	justify-self: var( --ivy-alignment, start );
}

.ivy-cards--rail .ivy-cards__intro-text {
	max-inline-size: min( 100%, 58ch );
}

/*
 * overflow-x: auto, et c'est le point qui rend la piste parcourable. En
 * overflow: hidden elle resterait defilable par programme — le navigateur y
 * amenerait un element focalise en vue — mais les fleches, la molette et le
 * doigt n'y pourraient rien. Une piste qu'on ne parcourt qu'en tabulant d'un
 * lien au suivant n'est pas parcourable, et sans lien dans les cartes elle ne
 * l'est pas du tout. Critere WCAG 2.1.1.
 */
.ivy-cards--rail .ivy-cards__viewport {
	display: flex;
	/* Pas de hauteur imposee, donc rien a centrer : les cartes se
	   dimensionnent sur leur contenu. C'est le meme defaut, vu deux fois —
	   une fenetre plus haute que la piste finit toujours en blanc. */
	align-items: flex-start;
	width: 100%;
	overflow: hidden;
}

.ivy-cards--rail .ivy-cards__viewport::-webkit-scrollbar {
	display: none;
}

.ivy-cards--rail .ivy-cards__viewport:focus-visible {
	outline: 2px solid var( --ivy-accent, rgb( 17 17 17 ) );
	outline-offset: -2px;
}

.ivy-cards--rail .ivy-cards__track {
	display: flex;
	align-items: stretch;
	width: max-content;
	gap: var( --ivy-cards-gap );
	/*
	 * Le mouvement est applique ICI, par le CSS, a partir des deux nombres
	 * publies par le runtime. Une transformation est compositee par le GPU ;
	 * ecrire scrollLeft a chaque frame ne l'est pas, et se voit — c'est le
	 * defaut signale a l'essai.
	 */
	transform: translate3d(
		calc( -1 * var( --ivy-rail, 0 ) * var( --ivy-rail-travel, 0px ) ),
		0,
		0
	);
	will-change: transform;
}

.ivy-cards--rail .ivy-cards__card {
	display: grid;
	grid-template-rows: auto minmax( 0, 1fr ) auto;
	width: clamp( 330px, 38vw, 520px );
	overflow: hidden;
	border: 1px solid color-mix( in srgb, var( --ivy-ink, rgb( 17 17 17 ) ) 14%, transparent );
	border-radius: var( --ivy-radius-surface, 24px );
	background: var( --ivy-surface, rgb( 255 255 255 ) );
	/* Le lien de titre couvre la carte : il lui faut un ancetre positionne. */
	position: relative;
}

.ivy-cards--rail .ivy-cards__top {
	display: flex;
	align-items: center;
	min-height: 78px;
	padding: 22px 28px;
	border-bottom: 1px solid
		color-mix( in srgb, var( --ivy-ink, rgb( 17 17 17 ) ) 14%, transparent );
}

.ivy-cards--rail .ivy-cards__number {
	color: var( --ivy-number-color, var( --ivy-accent, rgb( 17 17 17 ) ) );
	line-height: 1;
	letter-spacing: 0.08em;
}

.ivy-cards--rail .ivy-cards__media {
	position: relative;
	min-height: 0;
	aspect-ratio: 4 / 3;
	overflow: hidden;
	background: color-mix( in srgb, var( --ivy-muted, rgb( 110 110 110 ) ) 12%, transparent );
}

.ivy-cards--rail .ivy-cards__media img {
	position: absolute;
	inset: 0;
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform calc( 650ms * var( --ivy-motion, 1 ) ) cubic-bezier( 0.22, 0.61, 0.36, 1 );
	border-radius: inherit;
}

.ivy-cards--rail .ivy-cards__card:hover .ivy-cards__media img {
	transform: scale( 1.035 );
}

.ivy-cards--rail .ivy-cards__content {
	padding: 24px 28px 30px;
}

.ivy-cards--rail .ivy-cards__title {
	margin: 0 0 12px;
	color: var( --ivy-title-color, var( --ivy-ink, rgb( 17 17 17 ) ) );
}

/* Le lien herite : le controle de couleur du titre ecrit sur le <h3>, et une
   liste separee par des virgules est interdite par le contrat. */
.ivy-cards--rail .ivy-cards__title a {
	color: inherit;
	text-decoration: none;
}

/* La surface entiere devient cliquable sans envelopper la carte dans un <a>. */
.ivy-cards--rail .ivy-cards__title a::after {
	content: '';
	position: absolute;
	inset: 0;
}

.ivy-cards--rail .ivy-cards__text {
	margin: 0;
	color: var( --ivy-text-color, var( --ivy-muted, rgb( 110 110 110 ) ) );
}

/*
 * Des-epinglage. Le runtime interroge getComputedStyle(pin).position : des
 * que le pin n'est plus collant, il ne cable rien et ne publie aucune mesure.
 * C'est donc ICI, et nulle part dans le JavaScript, que vit le point de
 * rupture — et sous mouvement reduit, la meme regle produit le meme resultat.
 */
@media ( max-width: 1024px ) {
	.ivy-cards--rail .ivy-cards__spacer {
		display: none;
	}

	.ivy-cards--rail .ivy-cards__pin {
		position: static;
	}

	/* Des-epinglee, la piste redevient une region nativement defilable : le
	   clavier, le doigt et la barre y accedent. C'est la, et seulement la, que
	   ce mode a un sens. */
	.ivy-cards--rail .ivy-cards__viewport {
		overflow-x: auto;
		overflow-y: hidden;
	}

	.ivy-cards--rail .ivy-cards__track {
		transform: none;
	}
}

@media ( prefers-reduced-motion: reduce ) {
	.ivy-cards--rail .ivy-cards__spacer {
		display: none;
	}

	.ivy-cards--rail .ivy-cards__pin {
		position: static;
	}

	/* Des-epinglee, la piste redevient une region nativement defilable : le
	   clavier, le doigt et la barre y accedent. C'est la, et seulement la, que
	   ce mode a un sens. */
	.ivy-cards--rail .ivy-cards__viewport {
		overflow-x: auto;
		overflow-y: hidden;
	}

	.ivy-cards--rail .ivy-cards__track {
		transform: none;
	}

	.ivy-cards--rail .ivy-cards__media img {
		transition: none;
	}
}
