/*
 * Page d'accueil.
 *
 * Les valeurs proviennent de mesures faites au pixel sur l'export 1:1 de la
 * maquette (frame 1920 × 1080, contenu aligné sur un conteneur de 1600 px).
 */

/* ==========================================================================
   Hero
   ========================================================================== */

/*
 * Superposition en CSS Grid : image de fond, dégradé et contenu occupent la
 * même cellule. Aucun position: absolute, la hauteur reste pilotée par le flux.
 */
.s-hero {
	/* Hauteur de la maquette : 1080 px sur une frame de 1920, soit le viewport. */
	--hero-height: 100svh;
	height: 100vh;
	display: grid;
	grid-template-areas: "stack";
	isolation: isolate;
	background-color: var(--color-violet-deep);
}

.s-hero > * {
	grid-area: stack;
	min-width: 0;
}

/* --- Arrière-plan --------------------------------------------------------- */

.s-hero__background {
	position: relative;
	display: grid;
	grid-template-areas: "layer";
	overflow: hidden;
	/*
	 * Le flou appliqué aux cercles crée un contexte d'empilement : sans ordre
	 * explicite, le dégradé se peindrait par-dessus le texte.
	 */
	z-index: 0;
}

.s-hero__background > * {
	grid-area: layer;
}

/*
 * Photographie de fond. Dans la maquette, le calque mesure 1967 × 1311 et est
 * ancré en haut à gauche de la frame, le débordement étant rogné.
 */
.s-hero__image {
	/* Hors flux : la hauteur du hero reste celle du viewport, pas celle de la photo. */
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: left top;
}

/*
 * Dégradé de marque, reconstruit d'après la maquette : six cercles empilés
 * dans une scène au format de la frame (1920 × 1080), l'ensemble étant flouté
 * d'un seul bloc — c'est un effet de calque appliqué au groupe, pas à chaque
 * cercle pris isolément.
 *
 * Aucun fichier image n'est chargé : le rendu reste net à toutes les
 * résolutions et le dégradé suit exactement les valeurs de la maquette.
 *
 * Les positions absolues sont ici inévitables (les cercles se chevauchent par
 * construction) mais restent cantonnées à cette couche décorative.
 */
.s-hero__gradient {
	display: grid;
	place-items: center;
	overflow: hidden;
	mix-blend-mode: var(--hero-gradient-blend, normal);
	opacity: var(--hero-gradient-opacity, 1);
}

/*
 * La scène reproduit le cadre de la maquette et le recouvre à la manière d'un
 * « cover » : les proportions sont préservées, donc les cercles restent ronds
 * quel que soit le format de l'écran.
 */
.s-hero__gradient-stage {
	--stage-width: max(100vw, calc(var(--hero-height) * 1920 / 1080));

	position: relative;
	width: var(--stage-width);
	aspect-ratio: 1920 / 1080;
}

.s-hero__blobs {
	position: absolute;
	inset: 0;
	/*
	 * Flou de calque Figma à 500. Figma exprime le double de l'écart-type
	 * (son export SVG donne stdDeviation="250") alors que blur() en CSS prend
	 * l'écart-type : la valeur est donc divisée par deux.
	 */
	filter: blur(calc(var(--stage-width) * 250 / 1920));
}

.s-hero__blob {
	position: absolute;
	display: block;
	aspect-ratio: 1;
	border-radius: 50%;
	background-color: var(--blob-color);
	/* Positions et diamètres exprimés en proportion de la frame de 1920 × 1080. */
	left: calc(var(--blob-x) / 1920 * 100%);
	top: calc(var(--blob-y) / 1080 * 100%);
	width: calc(var(--blob-size) / 1920 * 100%);
}

.s-hero__blob--1 {
	--blob-color: #2e136a;
	--blob-x: -81;
	--blob-y: 49;
	--blob-size: 1195;
}

.s-hero__blob--2 {
	--blob-color: #ff6922;
	--blob-x: 683;
	--blob-y: 266;
	--blob-size: 702;
}

.s-hero__blob--3 {
	--blob-color: #ff6922;
	--blob-x: 1435;
	--blob-y: 374;
	--blob-size: 485;
}

.s-hero__blob--4 {
	--blob-color: #7b3dff;
	--blob-x: 258;
	--blob-y: 49;
	--blob-size: 702;
}

.s-hero__blob--5 {
	--blob-color: #e134ee;
	--blob-x: 525;
	--blob-y: 105;
	--blob-size: 435;
}

.s-hero__blob--6 {
	--blob-color: #ffffff;
	--blob-x: 918;
	--blob-y: 129;
	--blob-size: 435;
}

/* --- Contenu -------------------------------------------------------------- */

.s-hero__inner {
	position: relative;
	/* Le contenu reste au premier plan, au-dessus de l'image et du dégradé. */
	z-index: 1;
	display: flex;
	flex-direction: column;
	justify-content: center;
	/*
	 * Le padding supérieur reproduit le décalage du bloc de texte sous le
	 * centre optique : contenu à 400 px du haut et 276 px du bas sur l'écran
	 * de référence.
	 */
	min-height: var(--hero-height);
	padding-top: 124px;
	color: var(--color-white);
}

.s-hero__content {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
}

.s-hero__title {
	max-width: 1120px;
	margin: 0;
	font-size: 4.75rem;      /* 76 px */
	font-weight: 900;
	line-height: 1.2;        /* 91 px */
	text-transform: uppercase;
	/* Le retour à la ligne suit la maquette grâce à la largeur maximale. */
	text-wrap: initial;
}

.s-hero__text {
	max-width: 1120px;
	margin-top: 12px;
	color: rgba(255, 255, 255, 0.9);
	font-size: 1.125rem;     /* 18 px */
	line-height: 1.222;      /* 22 px */
}

.s-hero__actions {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-md);
	margin-top: 24px;
}

/* --- Adaptations ---------------------------------------------------------- */

@media (max-width: 1199px) {
	.s-hero__inner {
		padding-top: calc(var(--header-height) + var(--header-offset) * 2);
		padding-bottom: var(--space-3xl);
	}

	.s-hero__title {
		font-size: clamp(2.25rem, 1.1rem + 4.8vw, 4.75rem);
	}
}

@media (max-width: 767px) {
	.s-hero {
		--hero-height: 90svh;
	}

	.s-hero__inner {
		justify-content: flex-end;
	}

	.s-hero__actions {
		width: 100%;
	}

	.s-hero__actions .c-button {
		flex: 1 1 auto;
	}
}

/* ==========================================================================
   Notre mission
   ========================================================================== */

/*
 * Deux colonnes : surtitre à gauche (472 px), discours à droite (1128 px),
 * sur un conteneur de 1600 px. Mesures relevées sur la maquette.
 */
.s-mission {
	padding-block: 162px 146px;
}

.s-mission__inner {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-start;
}

.s-mission__aside {
	flex: 0 0 29.5%;   /* 472 / 1600 */
}

.s-mission__content {
	flex: 1 1 320px;
	min-width: 0;
}

/*
 * L'accroche et le paragraphe forment un seul bloc de texte continu : même
 * corps, même interligne, seule la graisse les distingue.
 */
.s-mission__title,
.s-mission__text {
	margin: 0;
	font-size: 2rem;      /* 32 px */
	line-height: 1.4;     /* 140 % */
}

.s-mission__title {
	font-weight: 500;     /* Medium */
	text-wrap: initial;
}

.s-mission__text {
	font-weight: 300;     /* Light */
}

.s-mission__action {
	margin: 24px 0 0;
}

@media (max-width: 1023px) {
	.s-mission {
		padding-block: var(--space-3xl) var(--space-2xl);
	}

	.s-mission__aside {
		flex: 1 1 100%;
		margin-bottom: var(--space-lg);
	}

	.s-mission__title,
	.s-mission__text {
		font-size: clamp(1.25rem, 0.9rem + 1.6vw, 2rem);
	}
}

/* --- Les quatre cartes ---------------------------------------------------- */

/*
 * Quatre colonnes séparées de 18 px sur le conteneur de 1600 px, soit
 * 386,5 px par carte. Les largeurs sont calculées à partir de l'espacement
 * plutôt que codées en dur : la répartition tient à toutes les tailles.
 */
.s-mission__cards {
	--cards-gap: 18px;
	--cards-per-row: 4;

	flex: 1 1 100%;
	display: flex;
	flex-wrap: wrap;
	gap: var(--cards-gap);
	margin: 146px 0 0;
}

.s-mission__card {
	display: flex;
	flex-direction: column;
	flex: 1 1 calc(
		(100% - var(--cards-gap) * (var(--cards-per-row) - 1)) / var(--cards-per-row)
	);
	min-width: 0;
}

/* 386,5 × 431 dans la maquette : la proportion est conservée au fil des tailles. */
.s-mission__card-media {
	overflow: hidden;
	aspect-ratio: 386.5 / 431;
}

.s-mission__card-image {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.s-mission__card-title {
	margin: 18px 0 0;
	color: var(--color-violet);
	font-size: 1.375rem;    /* 22 px */
	font-weight: 600;
	line-height: 1.3;
	text-transform: uppercase;
}

.s-mission__card-text {
	margin: 4px 0 0;
	font-size: 1rem;        /* 16 px */
	font-weight: 400;
	line-height: 1.6;       /* 160 % */
}

@media (max-width: 1199px) {
	.s-mission__cards {
		--cards-per-row: 2;
	}
}

@media (max-width: 1023px) {
	.s-mission__cards {
		margin-top: var(--space-2xl);
	}
}

@media (max-width: 639px) {
	.s-mission__cards {
		--cards-per-row: 1;
	}
}

/* ==========================================================================
   Nos événements
   ========================================================================== */

/*
 * Deux cartes jointives, hors conteneur : chacune occupe la moitié de la
 * largeur de page. Proportions de la maquette : 960 × 1020 par carte.
 */
.s-events__list {
	display: flex;
	flex-wrap: wrap;
}

.s-events__card {
	--card-width: 50vw;

	position: relative;
	flex: 1 1 50%;
	display: grid;
	grid-template-areas: "stack";
	aspect-ratio: 960 / 1020;
	min-width: 0;
	overflow: hidden;
	isolation: isolate;
	background-color: var(--color-black);
}

.s-events__card > * {
	grid-area: stack;
	min-width: 0;
}

/* --- Photographie --------------------------------------------------------- */

.s-events__media {
	position: relative;
	z-index: 0;
	overflow: hidden;
}

.s-events__image {
	/* Hors flux : la proportion de la carte prime sur celle de la photo. */
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* --- Halo coloré ---------------------------------------------------------- */

/*
 * Trois cercles floutés cantonnés au bas de la carte, qui assoient la
 * lisibilité du texte. La couche est rendue deux fois, comme dans la maquette,
 * pour densifier la couleur : deux passes ne donnent pas le même résultat
 * qu'une seule à opacité doublée.
 */
.s-events__glow {
	position: relative;
	z-index: 1;
}

.s-events__blobs {
	position: absolute;
	inset: 0;
	/*
	 * Flou de calque Figma à 279 : divisé par deux, Figma exprimant le double
	 * de l'écart-type attendu par blur().
	 */
	filter: blur(calc(var(--card-width) * 139.5 / 960));
}

.s-events__blob {
	position: absolute;
	display: block;
	aspect-ratio: 1;
	border-radius: 50%;
	background-color: var(--blob-color);
	/* Coordonnées relevées dans le repère de la carte (960 × 1020). */
	left: calc(var(--blob-x) / 960 * 100%);
	top: calc(var(--blob-y) / 1020 * 100%);
	width: calc(var(--blob-size) / 960 * 100%);
}

.s-events__blob--1 {
	--blob-color: #7b3dff;
	--blob-x: 198.37;
	--blob-y: 603.83;
	--blob-size: 489;
}

.s-events__blob--2 {
	--blob-color: #ff6922;
	--blob-x: -84.65;
	--blob-y: 528;
	--blob-size: 489;
}

.s-events__blob--3 {
	--blob-color: #ffffff;
	--blob-x: -188;
	--blob-y: 679.97;
	--blob-size: 303;
}

/* --- Contenu -------------------------------------------------------------- */

.s-events__content {
	z-index: 2;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	justify-content: flex-end;
	padding: 64px;
	color: var(--color-white);
}

.s-events__title {
	margin: 0;
	font-size: 2.9375rem;   /* 47 px */
	font-weight: 700;
	line-height: 1.1;
	text-transform: uppercase;
}

.s-events__text {
	margin: 12px 0 0;
	font-size: 1rem;
	font-weight: 400;
	line-height: 1.5;
}

.s-events__actions {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-md);
	margin: 28px 0 0;
}

/*
 * Le bouton secondaire (site de l'événement) reste en retrait : le contour
 * suffit à le rendre cliquable sans concurrencer le bouton principal.
 */
.s-events__actions .c-button--ghost {
	font-weight: 400;
}

/* --- Adaptations ---------------------------------------------------------- */

@media (max-width: 1199px) {
	.s-events__content {
		padding: clamp(1.5rem, 0.6rem + 3.7vw, 4rem);
	}

	.s-events__title {
		font-size: clamp(1.5rem, 0.6rem + 3.7vw, 2.9375rem);
	}
}

@media (max-width: 767px) {
	.s-events__card {
		--card-width: 100vw;

		flex: 1 1 100%;
	}
}

/* ==========================================================================
   Articles et communiqués
   ========================================================================== */

.s-news {
	/*
	 * Hauteur d'une carte et espace occupé par l'en-tête : ces deux valeurs
	 * servent à centrer l'ensemble « en-tête + pile » dans la fenêtre.
	 * --news-header-space est mesurée par assets/js/card-stack.js, la valeur
	 * ci-dessous n'étant qu'un repli avant exécution du script.
	 */
	--card-height: 530px;
	--news-header-space: 180px;
	--news-header-gap: 76px;
	--news-stack-top: max(
		var(--space-lg),
		calc((100svh - var(--card-height) - var(--news-header-space)) / 2)
	);

	padding-block: 146px;
}

/* --- En-tête -------------------------------------------------------------- */

.s-news__stage {
	position: relative;
}

/*
 * Un élément collant reste bloqué jusqu'à la fin de son conteneur. Placer
 * l'en-tête dans un rail qui s'arrête une hauteur de carte avant la fin de la
 * pile le fait se détacher au même instant que la dernière carte : les deux
 * remontent ensemble et l'ordre « titre puis carte » n'est jamais inversé.
 *
 * Le rail ne capte pas les clics, seul son contenu le fait.
 */
.s-news__rail {
	position: absolute;
	inset: 0 0 var(--card-height) 0;
	z-index: 5;
	pointer-events: none;
}

/*
 * L'en-tête se fige en même temps que la première carte : sans cela, il
 * quitterait l'écran pendant que la pile reste centrée, laissant un vide.
 */
.s-news__header {
	position: sticky;
	pointer-events: auto;
	top: var(--news-stack-top);
	display: flex;
	flex-wrap: wrap;
	align-items: flex-end;
	justify-content: space-between;
	gap: var(--space-lg);
	/*
	 * Le fond opaque et le retrait bas permettent à l'en-tête de masquer la
	 * pile qui remonte derrière lui en fin de section.
	 */
	padding-bottom: var(--news-header-gap);
	background-color: var(--color-bg);
	/* Au-dessus des cartes, dont le z-index va de 1 à n. */
	z-index: 5;
}

.s-news__title {
	margin: 8px 0 0;
	font-size: 3rem;        /* 48 px */
	font-weight: 700;
	line-height: 1.1;
	text-transform: uppercase;
}

.s-news__text {
	margin: 12px 0 0;
	font-size: 1rem;
	font-weight: 400;
}

.s-news__all {
	margin: 0;
}

/* --- Empilement au défilement --------------------------------------------- */

/*
 * Chaque carte se fige au centre de l'écran, exactement à la place de la
 * précédente : c'est le regard qui reste immobile pendant que le contenu se
 * substitue. Toutes partagent la même position de blocage, sinon la carte du
 * dessous dépasserait et laisserait une bande visible en haut.
 */
.s-news__list {
	/* Le rail est hors flux : la liste réserve la place de l'en-tête. */
	padding-top: var(--news-header-space);
	display: flex;
	flex-direction: column;
	gap: 24px;
}

.s-news__item {
	position: sticky;
	/* Juste sous l'en-tête figé, l'ensemble restant centré dans la fenêtre. */
	top: calc(var(--news-stack-top) + var(--news-header-space));
	/* Chaque carte passe devant la précédente. */
	z-index: calc(var(--rang, 0) + 1);
}

/* --- Adaptations ---------------------------------------------------------- */

@media (max-width: 1199px) {
	.s-news__title {
		font-size: clamp(1.75rem, 1rem + 3.1vw, 3rem);
	}

	.s-news__media,
	.s-news__content {
		padding: clamp(1.5rem, 0.8rem + 2.9vw, 3rem);
	}
}

@media (max-width: 899px) {
	.s-news {
		padding-block: var(--space-3xl);
	}

	.s-news__header {
		margin-bottom: var(--space-2xl);
	}

	.s-news__card {
		min-height: 0;
	}

	.s-news__media {
		flex: 1 1 100%;
		aspect-ratio: 16 / 10;
	}

	.s-news__content {
		flex: 1 1 100%;
	}

	/* L'empilement n'a plus de sens sur une colonne étroite. */
	.s-news__rail,
	.s-news__header,
	.s-news__item {
		position: static;
	}

	.s-news__list {
		padding-top: 0;
	}
}

/* L'empilement est un effet de confort : il est retiré si l'on préfère moins d'animations. */
@media (prefers-reduced-motion: reduce) {
	.s-news__rail,
	.s-news__header,
	.s-news__item {
		position: static;
	}

	.s-news__list {
		padding-top: 0;
	}
}

/* ==========================================================================
   Appel à l'action
   ========================================================================== */

/*
 * Image de fond et contenu partagent une même cellule de grille. Le dégradé
 * de marque viendra s'insérer entre les deux.
 */
.s-cta {
	/*
	 * Hauteur de la maquette. En min-height plutôt qu'en height : si le texte
	 * saisi est plus long que prévu, la section s'étire au lieu de rogner son
	 * contenu.
	 */
	min-height: 781px;

	display: grid;
	grid-template-areas: "stack";
	isolation: isolate;
	background-color: var(--color-violet-deep);
	color: var(--color-white);
}

.s-cta > * {
	grid-area: stack;
	min-width: 0;
}

/*
 * L'image est sortie du flux : sinon sa hauteur naturelle dicterait celle de
 * la section, qui s'étirerait bien au-delà de la maquette.
 */
.s-cta__background {
	position: relative;
	z-index: 0;
	overflow: hidden;
}

.s-cta__image {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.s-cta__inner {
	z-index: 2;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	/* Marge interne de la maquette. */
	padding: 160px 0;
	margin-inline: auto;
	width: min(var(--container-max), 100% - var(--container-gutter) * 2);
}

.s-cta__title {
	margin: 0;
	font-size: 3.875rem;    /* 62 px */
	font-weight: 700;
	line-height: 1;         /* 61 px */
	text-transform: uppercase;
	text-wrap: initial;
}

.s-cta__text {
	max-width: 62ch;
	margin-top: 24px;
	font-size: 1.375rem;    /* 22 px */
	font-weight: 400;
	line-height: 1.6;       /* 160 % */
}

/* Le champ enrichi produit plusieurs paragraphes : ils sont espacés entre eux. */
.s-cta__text > * {
	margin: 0;
}

.s-cta__text > * + * {
	margin-top: 34px;
}

.s-cta__text strong {
	font-weight: 600;
}

.s-cta__actions {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--space-lg);
	margin-top: 24px;
}

/* Variante claire du lien fléché, sur fond sombre. */
.c-link-arrow--light {
	color: var(--color-white);
}

.c-link-arrow--light:hover {
	color: rgba(255, 255, 255, 0.8);
}


/* --- Adaptations ---------------------------------------------------------- */

@media (max-width: 1199px) {
	.s-cta__inner {
		padding: clamp(2.5rem, 1rem + 6.3vw, 10rem);
	}

	.s-cta__title {
		font-size: clamp(1.75rem, 0.9rem + 3.6vw, 3.875rem);
	}

	.s-cta__text {
		font-size: clamp(1rem, 0.85rem + 0.6vw, 1.375rem);
	}
}
