/* Suite de style.css : tout ce qui est sous la première vue (DemoReel, About, Services, Best Projects, Portfolio, Contact, pied de page).
   Chargée sans bloquer l'affichage (voir index.html), avant detail.css. Le découpage est automatique : les règles gardent leur ordre. */


/* Bloque le scroll de la page quand le menu hamburger plein écran est ouvert */
.Overflow {
	overflow: hidden;
}


/*------------------------------------------------------------- */
/*--------------------- Titre de section ---------------------- */
/*------------------------------------------------------------- */

/* Composant commun à toutes les sections : le titre, un trait au gradient d'identité,
   puis deux à quatre mots de résumé. C'est lui qui porte l'espacement vertical. */
.SectionTitre {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--espace-3);

	padding: var(--espace-6) 0 var(--ecart-titre-contenu) 0;
	text-align: center;
}

/* Le trait se déploie depuis le centre quand la section entre à l'écran */
.SectionTitre-Ligne {
	width: clamp(6rem, 10vw, 11rem);
	height: var(--bordure-trait);

	background: var(--gradient-identité);
	border-radius: var(--rayon-pilule);

	transform: scaleX(0.2);
	transition: transform var(--duree-longue) var(--courbe);
}

.SectionTitre.AnimationScrollFrom .SectionTitre-Ligne {
	transform: scaleX(1);
}

.SectionTitre-Resume {
	margin: 0;
	padding: 0;

	font-size: var(--taille-texte-meta);
	font-weight: 600;
	letter-spacing: var(--interlettrage-etiquette);
	text-transform: uppercase;
	text-align: center;
	color: var(--couleur-texte-doux);
}


@media (max-width: 1200px) {
	.SectionTitre {
		padding: var(--espace-6) 0 var(--espace-4) 0;
		gap: var(--espace-2);
	}}

/* Sur un écran peu haut, le titre prend moins de place verticale pour que la section
   continue de tenir sans déborder */
@media (max-height: 820px) {
	.SectionTitre {
		padding: var(--espace-5) 0 var(--ecart-titre-contenu) 0;
		gap: var(--espace-2);
	}}

/* Réservé aux lecteurs d'écran : le libellé existe pour eux, l'icône suffit à l'œil.
   On ne peut pas utiliser display: none, qui le retirerait aussi de leur lecture. */
.LectureEcran {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	border: 0;
	clip-path: inset(50%);
	overflow: hidden;
	white-space: nowrap;
}

/* About et Contact suivent leur contenu : leur imposer un nombre d'écrans entier
   creusait du vide, soit sous le titre, soit en bas de section. */
#SectionAbout {
	--ecrans: 2;
	padding-bottom: 0;	/* Chaque moitié (présentation, Background) porte déjà son propre vide de fin */
}

#SectionContact {
	--ecrans: 1;

	/* Le pied de page tient dans l'écran, juste sous la section */
	min-height: calc(var(--ecran-utile) - var(--hauteur-pied));
}

/* Le Portfolio occupe deux écrans : de quoi montrer quatre lignes de cartes */
#SectionPortfolio {
	--ecrans: 1;	/* Essai : une seule ligne de cartes affichée, la section tient dans un écran */
}

/* Les projets mis en avant s'allongent avec leur nombre */
#SectionBestProjects {
	padding-bottom: var(--espace-fin-section);
}

/* Le bandeau intercalaire et le pied de section Contact suivent leur contenu */
#SectionInBetween {
	--ecrans: 0;
}

/* Le titre commence au même endroit dans toutes les sections : seul le contenu qui le
   suit se centre dans la hauteur restante. Centrer la section entière, comme avant,
   décalait le titre du Demo Reel de 160px vers le bas et celui du Contact de 320px. */
#SectionServices, #SectionContact {
	display: flex;
	flex-direction: column;
	justify-content: flex-start;
	padding-bottom: var(--espace-fin-section);
}

/* L'écart entre le titre d'une section et son contenu est le même partout : c'est le
   padding bas de .SectionTitre. Le contenu commence donc juste après le titre, et c'est
   l'espace qui reste EN DESSOUS qui se répartit entre les blocs — jamais au-dessus. */
/* Le contenu se centre verticalement dans ce qui reste sous le titre, entre l'espace minimum
   du titre et l'espace minimum avant le filet. */
.Contact {
	margin-block: auto;
}

/* Les cartes gardent leur hauteur naturelle et se centrent sous le titre ; les écarts verticaux
   grandissent un peu avec la hauteur d'écran, sans jamais créer de grand vide. */
.BioService {
	flex: 1 1 auto;
	margin: 0 auto;
	/* Adaptatif : les cartes gardent leur hauteur naturelle, et la place qui reste sous le titre se
	   répartit à parts égales au-dessus, entre les deux rangées et au-dessous. Plus l'écran est haut,
	   plus l'écart entre la rangée 1 et la rangée 2 grandit. */
	align-content: space-evenly;
	grid-auto-rows: auto;
}

/* Le Demo Reel est en trois rangées : sélecteur d'année, lecteur, pied. Les deux rangées
   extrêmes sont de même hauteur (1fr) : le centre du lecteur est exactement au centre de la
   place restante. */

#SectionContact {
	padding-bottom: var(--espace-fin-section);
}

/* Le Portfolio est plus large que les autres sections */
#SectionPortfolio {
	max-width: var(--largeur-portfolio);
	padding-inline: clamp(1.6rem, 3vw, 5rem);	/* Une marge : rien n'est collé aux bords de l'écran */
	padding-bottom: var(--espace-fin-section);	/* La place de la flèche : elle ne passe jamais sur les cartes, même sur un écran bas */
}

/* Un filet d'identité en bas de chaque section, du même style partout. Il est porté par un
   pseudo-élément : l'ancienne bordure disparaissait dès qu'une section changeait de
   mode d'affichage. Entre Best Projects et le Portfolio, le bandeau a ses propres filets. */
#SectionDemoReel, #SectionAbout, #SectionServices, #SectionBestProjects, #SectionPortfolio {
	position: relative;
}

@media (max-width: 480px) {
	#SectionInBetween {
		padding-left: 0;
		padding-right: 0;
	}}



/* Un bandeau de respiration entre les projets mis en avant et le portfolio complet.
   Les anciennes bordures de 1.2rem pleines sont remplacées par deux filets d'identité. */
#SectionInBetween {
	position: relative;
	width: 100%;
	max-width: none;	/* Seule section à dépasser la largeur de contenu */
	padding: var(--espace-6) 0;

	background-color: var(--couleur-surface-1);
}

/* Les deux filets : un en haut, un en bas, dans le dégradé de la palette */
#SectionInBetween::before,
#SectionInBetween::after {
	content: "";
	position: absolute;
	left: 0;

	width: 100%;
	height: var(--bordure-trait);

	background: var(--gradient-identité);
}

#SectionInBetween::before { top: 0; }
#SectionInBetween::after  { bottom: 0; }

/* Le contenu reste aligné sur les autres sections, même si le fond traverse la page */
.Bandeau {
	margin: 0 auto;
	padding: 0 var(--espace-3);
	width: 100%;
	max-width: var(--largeur-contenu);
}

.Bandeau-Entete {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--espace-1);

	margin-bottom: var(--espace-5);
	text-align: center;
}

.Bandeau-Accroche {
	margin: 0;
	font-size: var(--taille-titre-quatre);
	font-style: italic;
	color: var(--couleur-texte);
}

/* Le total des projets : un chiffre, puis ce qu'il compte */
.Bandeau-Total {
	display: flex;
	align-items: baseline;
	gap: 0.8rem;

	margin: 0;
	font-size: var(--taille-texte-meta);
	color: var(--couleur-texte-doux);
	text-transform: uppercase;
	letter-spacing: 0.1em;
}

.Bandeau-Total strong {
	font-family: var(--police-titre);
	font-size: var(--taille-titre-trois);
	font-weight: 400;
	letter-spacing: 0;

	background: var(--gradient-identité);
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent;
}

.SectionTitre-Ligne, .Background-Ligne {
	background: linear-gradient(90deg, var(--accent-1), var(--accent-2), var(--accent-3), var(--accent-2), var(--accent-1));
	background-size: 200% 100%;
	animation: circulation-couleur 8s linear infinite;
}

.DemoReel-Play {
	animation: respiration-lecture 3.2s ease-in-out infinite;
}

		

/* ------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------- Demo Reel ---------------------------------------------------------- */
/* ------------------------------------------------------------------------------------------------------------------------------- */

/* La section entière est une grille de trois rangées (1fr, lecteur, 1fr) : le lecteur est donc
   exactement au centre de la section. Le titre occupe le haut de la première rangée, les onglets
   d'année se centrent dans ce qui reste entre le titre et le lecteur, et le pied (outils, boutons)
   se range au début de la dernière rangée. .DemoReel ne sert que de regroupement logique. */
#SectionDemoReel {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	grid-template-rows: minmax(5.4rem, 1fr) auto minmax(5.4rem, 1fr);	/* 5.4rem : la place des miniatures sous le lecteur */
	justify-items: center;
	width: 100%;
	padding-bottom: 0;
}

#SectionDemoReel > .SectionTitre {
	grid-row: 1;
	grid-column: 1;
	align-self: start;
	justify-self: stretch;
}

.DemoReel {
	display: contents;
}

.DemoReel-Annees {
	grid-row: 1;
	grid-column: 1;
	align-self: stretch;
	justify-self: stretch;
	align-content: center;
	align-items: center;
	/* Sous le titre (moins son vide de fin) : les onglets sont à égale distance du titre et du lecteur */
	padding-top: calc(var(--hauteur-titre-section) - var(--ecart-titre-contenu));
}

.ÉcranYoutube {
	grid-row: 2;
	grid-column: 1;
}

.DemoReel-Pied {
	grid-row: 3;
	grid-column: 1;
	align-self: start;
	padding-top: var(--espace-4);
	padding-bottom: var(--espace-fin-section);
}


/*------------------------------------------------------------- */
/*--------------------- Sélecteur d'année --------------------- */
/*------------------------------------------------------------- */

.DemoReel-Annees {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: var(--espace-2);
}

.DemoReel-Annee {
	appearance: none;
	font-family: inherit;

	padding: var(--espace-1) var(--espace-4);

	border: var(--bordure-fine) solid var(--couleur-bordure-forte);
	border-radius: var(--rayon-pilule);
	background-color: transparent;
	color: var(--couleur-texte-doux);

	font-size: var(--taille-texte-meta);
	font-weight: 600;
	letter-spacing: var(--interlettrage-etiquette);
	text-transform: uppercase;
	cursor: var(--curseur-lien);

	transition: border-color var(--duree-courte) var(--courbe), color var(--duree-courte) var(--courbe), background-color var(--duree-courte) var(--courbe);
}

.DemoReel-Annee:hover {
	border-color: var(--accent-1-a50);
	color: var(--couleur-titre);
}

/* La bande démo affichée est marquée par un aplat bleu. Le gradient, sur une pastille
   pleine, laissait voir du bleu à gauche et du rose à droite. */
.DemoReel-Annee[aria-selected="true"] {
	border-color: transparent;
	background-color: var(--accent-1);
	color: #0a0a0c;
}


/*------------------------------------------------------------- */
/*------------------------- Lecteur --------------------------- */
/*------------------------------------------------------------- */

/* Le cadre est obtenu par un fond en gradient révélé sur 2px de padding : une bordure
   en dégradé ne se déclare pas directement en CSS. La lueur bleue remplace l'ancien
   drop-shadow verdâtre, qui n'avait aucun rapport avec l'identité couleur.

   La largeur est plafonnée par la hauteur disponible (42vh) autant que par la largeur :
   sans cela, la section dépassait la hauteur d'un écran. */
.ÉcranYoutube {
	position: relative;
	/* Le lecteur prend ce qu'il reste de l'écran une fois le titre, le sélecteur d'année,
	   la liste d'outils et les boutons déduits : il ne peut donc pas pousser la section
	   au-delà d'un écran, quelle que soit la hauteur de la fenêtre. */
	--hauteur-disponible: calc(var(--ecran-utile) - 2 * (var(--hauteur-titre-section) + 2.6rem));
	width: min(100%, 110rem, calc(var(--hauteur-disponible) * 16 / 9));

	aspect-ratio: 16 / 9;
	margin: 0 auto;
	padding: 2px;	/* Épaisseur du cadre gradient */

	border-radius: var(--rayon-3);
	background: linear-gradient(135deg, var(--accent-1), var(--accent-2), var(--accent-3), var(--accent-2), var(--accent-1));
	background-size: 300% 300%;
	animation: circulation-cadre 12s linear infinite;
	box-shadow: var(--ombre-3), 0 0 6rem var(--accent-1-a25);
}

.ÉcranYoutube > * {
	position: relative;
	display: block;
	width: 100%;
	height: 100%;

	border-radius: calc(var(--rayon-3) - 2px);
	background-color: var(--couleur-surface-1);
	overflow: hidden;
}


/*------------------------------------------------------------- */
/*-------------------------- Façade --------------------------- */
/*------------------------------------------------------------- */

/* La miniature tient lieu de lecteur tant qu'on n'a pas cliqué : une iframe YouTube
   coûte près d'un méga-octet, autant ne la charger que si la vidéo est demandée. */
.DemoReel-Facade {
	appearance: none;
	border: none;
	padding: 0;

	display: block;
	width: 100%;
	height: 100%;

	background: none;
	cursor: var(--curseur-lien);
	overflow: hidden;
}

.DemoReel-Facade--entrant {
	position: absolute;
	inset: 2px;
	width: auto;
	height: auto;
	opacity: 0;
	transition: opacity 0.5s var(--courbe);
	border-radius: calc(var(--rayon-3) - 2px);
	z-index: 2;
}

.DemoReel-Facade--entrant.DemoReel-Facade--vue {
	opacity: 1;
}

.DemoReel-Poster {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;

	transition: transform var(--duree-moyenne) var(--courbe), filter var(--duree-moyenne) var(--courbe);
}

.DemoReel-Facade:hover .DemoReel-Poster {
	transform: scale(1.03);
	filter: brightness(0.75);
}

.DemoReel-Play {
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);

	display: flex;
	align-items: center;
	justify-content: center;

	width: 8rem;
	height: 8rem;

	border-radius: 50%;
	background-color: var(--accent-1);
	color: #0a0a0c;
	font-size: 3rem;
	box-shadow: var(--ombre-2);

	transition: transform var(--duree-moyenne) var(--courbe);
}

.DemoReel-Facade:hover .DemoReel-Play {
	transform: translate(-50%, -50%) scale(1.1);
}

/* Le triangle est optiquement décentré dans son cercle : on le décale d'un cheveu */
.DemoReel-Play i {
	margin-left: 0.4rem;
}


/*------------------------------------------------------------- */
/*--------------------------- Pied ---------------------------- */
/*------------------------------------------------------------- */

.DemoReel-Pied {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--espace-5);

	width: min(100%, 96rem);
}

/* Outils employés dans les projets de la bande démo, lus dans le JSON */
.DemoReel-Outils {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	align-items: center;
	gap: var(--espace-3) var(--espace-5);
}

.DemoReel-Outil {
	display: inline-flex;
	align-items: center;
	gap: var(--espace-2);

	padding: var(--espace-1) var(--espace-3);

	border: var(--bordure-fine) solid var(--couleur-bordure);
	border-radius: var(--rayon-pilule);
	background-color: var(--couleur-surface-1);

	font-size: var(--taille-texte-micro);
	font-weight: 600;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--couleur-texte-doux);
}

.DemoReel-Outil img {
	width: 2rem;
	height: 2rem;
	object-fit: contain;
}

.DemoReel-Liens {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: var(--espace-3) var(--espace-5);
}


@media (max-width: 767px) {
	.DemoReel-Play {
		width: 5.5rem;
		height: 5.5rem;
		font-size: 2rem;
	}
	.DemoReel {
		gap: var(--espace-3);
	}
	.DemoReel-Pied {
		gap: var(--espace-3);
	}}


/* ------------------------------------------------------------------------------------------------------------------------------- */
/* ------------------------------------------------------------ About ------------------------------------------------------------ */
/* ------------------------------------------------------------------------------------------------------------------------------- */

/*------------------------------------------------------------- */
/*------------------------- Biographie ------------------------ */
/*------------------------------------------------------------- */

.Bio {
	display: flex;
	flex-direction: row;
	justify-content: center;
	align-items: center;

	gap: var(--espace-7);
	width: 100%;
	margin: 0;
	align-items: center;	/* Le centre du portrait et celui du texte sont au centre de la place restante */
	/* Premier écran : le titre et la présentation tiennent exactement dans un écran */
	min-height: calc(var(--ecran-utile) - var(--hauteur-titre-section));
	padding-bottom: var(--espace-fin-section);
}

/* Les deux CV côte à côte */
.Bio-CV {
	display: flex;
	flex-wrap: wrap;
	gap: var(--espace-3);
	margin-top: var(--espace-2);
}

.BioLeft {
	/* Le portrait occupe toute la place que laisse l'écran sous le titre : la
	   biographie remplit donc son écran au lieu de laisser un grand vide en dessous.
	   Sa hauteur est calculée, sa largeur déduite (format 4/5). */
	--portrait-hauteur: clamp(30rem, calc(var(--ecran-utile) - var(--hauteur-titre-section) - 16rem), 56rem);
	--portrait-largeur: calc(var(--portrait-hauteur) * 0.8);

	position: relative;
	display: flex;
	justify-content: center;
	align-items: center;

	flex: 0 0 auto;
	width: 38%;
}

/* Lueur bleutée derrière le portrait, qui le décolle du fond sans l'encadrer */
.BioLeft::before {
	content: "";
	position: absolute;
	z-index: 0;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);

	width: calc(var(--portrait-largeur) * 1.1);
	height: calc(var(--portrait-hauteur) * 1.1);

	border-radius: var(--rayon-3);
	/* La lueur évolue doucement entre la couleur principale (bleu) et le dégradé complet */
	background: linear-gradient(135deg, var(--accent-1-a25), var(--accent-1-a25), var(--accent-2-a25), var(--accent-3-a25), var(--accent-2-a25), var(--accent-1-a25), var(--accent-1-a25));
	background-size: 300% 300%;
	animation: evolution-lueur 14s ease-in-out infinite alternate;
	filter: blur(6rem);
	opacity: 0.8;	/* Une lueur, pas une tache colorée derrière l'image */
}

/* Format portrait 4/5 à coins arrondis : le cercle rognait les épaules et le haut du
   crâne. La hauteur est posée explicitement plutôt que déduite d'aspect-ratio — sans
   hauteur définie, le cadre pouvait s'étirer et le border-radius donnait alors un ovale. */
.BioLeft img {
	position: relative;
	z-index: 1;

	width: var(--portrait-largeur);
	height: var(--portrait-hauteur);

	object-fit: cover;
	object-position: center 18%;	/* Cadre le visage, pas le centre géométrique */

	border-radius: var(--rayon-3);
	border: var(--bordure-fine) solid var(--couleur-bordure-forte);
	box-shadow: var(--ombre-3);
}

.BioMiddle-Right {
	display: flex;
	justify-content: center;
	align-items: flex-start;
	width: 62%;
}

.BioMiddle {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	text-align: left;

	width: 100%;
	gap: var(--espace-3);
}

.BioMiddle h3 {
	margin: 0;
	padding: 0;
	border: none;

	font-family: var(--police-titre);
	font-size: var(--taille-titre-second);
	font-weight: 400;
	letter-spacing: var(--interlettrage-titre);
	text-transform: uppercase;
}

/* Texte aligné à gauche et non justifié : la justification creusait des rivières de blanc,
   le texte comportant des retours à la ligne manuels. La mesure est bornée à 68 caractères,
   au-delà l'œil perd la ligne suivante. */
.BioMiddle p {
	max-width: 68ch;
	margin: 0;
	padding: 0;

	font-size: var(--taille-texte-premier);
	line-height: 1.75;
	text-align: left;
	color: var(--couleur-texte);
}

/* La première phrase est mise en avant, le reste passe en gris doux */
.BioMiddle .Bio-Accroche {
	font-size: calc(var(--taille-texte-premier) + 0.2rem);
	color: var(--couleur-titre);
}

.BioMiddle .Bio-Suite {
	color: var(--couleur-texte-doux);
}

/* Les mots-clefs du métier ressortent en bleu, sans gras ni soulignement */
.BioMiddle strong {
	font-weight: 600;
	color: var(--accent-1-clair);
}


/* Empilées, les deux colonnes arrivent chacune du bas, quand elles entrent dans l'écran */
@media (max-width: 1199px) {
	.Background-Colonne[data-animate]:not(.AnimationScrollFrom) {
		translate: 0 var(--decalage-animation);
	}}

@media (max-width: 1199px) {
	.Bio {
		flex-direction: column;
		gap: var(--espace-4);
		min-height: 0;	/* Empilé, le bloc n'a plus à remplir un écran */
	}
	.BioLeft,
	.BioMiddle-Right {
		width: 100%;
	}
	.BioLeft {
		--portrait-largeur: min(28rem, 70%);
		--portrait-hauteur: calc(var(--portrait-largeur) * 1.25);
	}
	.BioMiddle {
		align-items: center;
	}
	.BioMiddle p {
		text-align: left;
	}}

@media (max-width: 480px) {
	.BioLeft {
		--portrait-largeur: min(20rem, 65%);
		--portrait-hauteur: calc(var(--portrait-largeur) * 1.25);
	}}



/*------------------------------------------------------------- */
/*------------------------- Background ------------------------ */
/*------------------------------------------------------------- */

.Background {
	display: flex;
	flex-direction: column;
	/* Second écran : Background est une sous-section qui occupe son propre écran, sans filet de séparation */
	min-height: var(--ecran-utile);
	padding-top: var(--ecart-titre-contenu);	/* Le même vide au-dessus que les titres de section */
	padding-bottom: var(--espace-fin-section);
}

.Background-Colonnes {
	margin-block: 0 auto;	/* Alignées en haut : quand une entrée s'ouvre, les cartes au-dessus et son propre haut ne bougent pas */

	--nb: 4;	/* Remplacé par script.js : nombre d'entrées de la plus longue frise */
	--ecart-entrees: clamp(1rem, 2.4vh, 2.4rem);
	/* Hauteur des frises : un écran moins le haut (vide, titre et aide) et le bas (vide de fin, titres de colonne) */
	--frise-hauteur: calc(var(--ecran-utile) - 2 * var(--ecart-titre-contenu) - 31.2rem);	/* 26rem + les marges haute et basse du rail (2 x 2,6rem) */
}

.Background-Entete {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--espace-2);

	margin-bottom: var(--ecart-titre-contenu);	/* Le même vide dessous que les titres de section */
	text-align: center;
}

.Background-Entete h3 {
	margin: 0;
	padding: 0;
	border: none;

	font-family: var(--police-titre);
	font-size: var(--taille-titre-second);
	font-weight: 400;
	letter-spacing: var(--interlettrage-titre);
	text-transform: uppercase;
	text-align: center;
}

.Background-Ligne {
	width: 6rem;
	height: var(--bordure-trait);
	background: var(--gradient-identité);
	border-radius: var(--rayon-pilule);
}

.Background-Aide {
	margin: 0;
	font-size: var(--taille-texte-micro);
	font-style: italic;
	text-align: center;
	color: var(--couleur-texte-doux);
}


/* Les deux frises sont affichées en parallèle, puis empilées sous 1200px */
.Background-Colonnes {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
	width: 100%;	/* Sans cela, la marge auto la ferait épouser son contenu : les colonnes bougeaient à l'ouverture d'une carte */
	gap: var(--espace-7);
	align-items: stretch;	/* Les deux colonnes ont la même hauteur */
}

/* Les frises se répartissent sur toute la hauteur de leur colonne : avec quatre entrées
   d'un côté et trois de l'autre, l'espace en trop s'ajoute entre les entrées de la
   plus courte, et la première comme la dernière s'alignent de part et d'autre. */
.Background-Colonne {
	display: flex;
	flex-direction: column;
	min-width: 0;	/* Autorise la colonne à se rétrécir au lieu de déborder */
}

.Frise {
	flex: 1 1 auto;
	display: flex;
	flex-direction: column;
	justify-content: flex-start;	/* Les entrées gardent le même pas dans les deux colonnes, même si l'une est plus courte */
}

.Background-Titre {
	display: flex;
	align-items: center;
	gap: var(--espace-2);

	margin: 0 0 var(--espace-4) 0;
	padding-bottom: var(--espace-2);
	border-bottom: var(--bordure-fine) solid var(--couleur-bordure);

	font-size: var(--taille-titre-quatre);
	font-weight: 700;
	letter-spacing: var(--interlettrage-etiquette);
	text-transform: uppercase;
	color: var(--couleur-titre);
}

.Background-Titre i {
	font-size: 0.9em;
	color: var(--accent-1);
}



/*------------------------------------------------------------- */
/*----------------------- Frise Chrono ------------------------ */
/*------------------------------------------------------------- */

/* L'année est portée par une pastille posée sur le rail, et non plus par la carte :
   la frise se lit ainsi de haut en bas d'un seul coup d'œil.
   L'ancienne frise reposait sur width: max-content et un calc() de décalage, ce qui
   la rendait impossible à tenir en responsif : elle est refaite en grille. */
.Frise {
	--rail: 2.6rem;		/* Abscisse du rail, aussi le centre des pastilles */
	--pastille: 5.2rem;	/* Largeur de la pastille d'année */

	position: relative;
	margin: 0;
	padding: 0 0 0 calc(var(--rail) + var(--pastille) / 2 + var(--espace-3));
	list-style: none;
}

/* Le rail : un simple filet neutre. Le gradient y était trop présent et tirait sur le
   magenta ; la couleur d'identité est réservée à la pastille de l'entrée en cours. */
.Frise::before {
	content: "";
	position: absolute;
	top: 1.4rem;
	bottom: 1.4rem;
	left: var(--rail);
	width: 2px;

	background-color: var(--couleur-bordure-forte);
}

.Frise-Item {
	position: relative;
	padding-bottom: var(--ecart-entrees);
}

.Frise-Item:last-child {
	padding-bottom: 0;
}


/*--------------------------- */
/*-- Pastille de l'année --- */
/*--------------------------- */

/* Une seule pièce : le fond, la bordure et le texte sont portés par le même élément,
   l'icône et son cercle ne peuvent donc plus se désaligner. */
.Frise-Annee {
	position: absolute;
	z-index: 1;

	/* Décalée d'une largeur de pastille plus la gouttière, elle se retrouve centrée
	   sur le rail ; le « top » aligne son milieu sur celui de l'icône de la carte. */
	top: 1.9rem;
	left: calc(-1 * var(--pastille) - var(--espace-3));

	display: flex;
	align-items: center;
	justify-content: center;

	width: var(--pastille);
	padding: 0.2rem 0;

	border: var(--bordure-fine) solid var(--couleur-bordure-forte);
	border-radius: var(--rayon-pilule);
	background-color: var(--couleur-fond);

	font-size: var(--taille-texte-micro);
	font-weight: 700;
	letter-spacing: 0.06em;
	color: var(--couleur-texte-doux);
}

/* L'entrée en cours est la seule dont la pastille est pleine */
.Frise-Item--encours .Frise-Annee {
	border-color: transparent;
	background-color: var(--accent-1);
	color: #0a0a0c;
}


/*--------------------------- */
/*-------- Dépliage --------- */
/*--------------------------- */

/* <details> natif : le dépliage fonctionne sans JavaScript et reste accessible au clavier */
.Frise-Details {
	border: var(--bordure-fine) solid var(--couleur-bordure);
	border-radius: var(--rayon-2);
	background-color: var(--couleur-surface-1);

	transition: border-color var(--duree-courte) var(--courbe), background-color var(--duree-courte) var(--courbe);
}

.Frise-Details:hover {
	border-color: var(--accent-1-a50);
	background-color: var(--couleur-surface-2);
}

.Frise-Details[open] {
	border-color: var(--accent-1-a50);
}

/* Replié : seuls l'établissement, l'intitulé et le niveau sont visibles */
.Frise-Resume {
	display: flex;
	align-items: center;
	gap: var(--espace-3);

	padding: clamp(var(--espace-3), 2vh, var(--espace-4));
	/* Même hauteur pour toutes les entrées repliées, des deux colonnes : la place disponible est
	   divisée par le nombre d'entrées de la plus longue frise (--nb, posé par script.js). */
	min-height: max(7.2rem, calc((var(--frise-hauteur) + var(--ecart-entrees)) / var(--nb) - var(--ecart-entrees)));
	cursor: var(--curseur-lien);
	list-style: none;	/* Masque le triangle natif de <summary> */
}

.Frise-Resume::-webkit-details-marker {
	display: none;
}

/* L'icône est dans la carte, dans un carré arrondi qui la contient vraiment.
   La boîte est un <span> neutre : le <i> de Font Awesome est à l'intérieur et ne
   porte aucune règle de mise en page, il ne peut donc plus sortir de son cadre. */
.Frise-Icone {
	flex: 0 0 auto;

	display: flex;
	align-items: center;
	justify-content: center;

	width: 3.4rem;
	height: 3.4rem;

	border-radius: var(--rayon-1);
	background-color: var(--couleur-surface-3);
	color: var(--accent-1);
}

.Frise-Icone i {
	display: block;
	font-size: 1.4rem;
	line-height: 1;
}

.Frise-Texte {
	flex: 1 1 auto;
	min-width: 0;
}

.Frise-Organisation {
	display: block;
	font-size: var(--taille-texte-second);
	font-weight: 700;
	line-height: 1.3;
	color: var(--couleur-titre);
}

.Frise-Intitule {
	display: block;
	font-size: var(--taille-texte-second);
	line-height: 1.35;
	color: var(--couleur-texte);
}

.Frise-Etiquettes {
	display: flex;
	flex: 0 0 auto;
	flex-wrap: nowrap;
	align-items: center;
	gap: var(--espace-1);
}


.Frise-Niveau, .Frise-EnCours {
	display: inline-block;
	padding: 0.1rem var(--espace-2);

	border-radius: var(--rayon-pilule);
	background-color: var(--couleur-surface-3);

	font-size: var(--taille-texte-micro);
	font-weight: 600;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--couleur-texte-doux);
}

/* Seule l'étiquette « Currently » est colorée */
.Frise-EnCours {
	background-color: var(--accent-1-a25);
	color: var(--accent-1-clair);
}

/* Chevron de dépliage, qui pivote à l'ouverture */
.Frise-Chevron {
	flex: 0 0 auto;
	font-size: 1.2rem;
	color: var(--couleur-texte-doux);

	transition: transform var(--duree-courte) var(--courbe), color var(--duree-courte) var(--courbe);
}

.Frise-Details[open] .Frise-Chevron {
	transform: rotate(180deg);
	color: var(--accent-1);
}


/*--------------------------- */
/*--------- Détail ---------- */
/*--------------------------- */

.Frise-Contenu {
	overflow-wrap: anywhere;	/* Un mot ou un lien trop long se coupe au lieu d'élargir la carte */
	margin: 0 var(--espace-3);
	padding: var(--espace-3) 0;
	border-top: var(--bordure-fine) solid var(--couleur-bordure);

	font-size: var(--taille-texte-second);
}

.Frise-Contenu .Frise-Periode {
	display: inline-flex;
	align-items: center;

	margin: 0 0 var(--espace-3) 0;
	padding: 0.4rem 1.2rem;

	background-color: var(--accent-1-a10);
	border: var(--bordure-fine) solid var(--accent-1-a50);
	border-radius: var(--rayon-pilule);

	font-size: var(--taille-texte-meta);
	font-style: normal;
	font-weight: 600;
	letter-spacing: 0.06em;
	color: var(--accent-1-clair);
}

.Frise-Contenu p {
	margin: 0 0 var(--espace-2) 0;
	font-size: var(--taille-texte-second);
	line-height: 1.6;
	text-align: left;
}

.Frise-BlocTitre {
	margin: var(--espace-5) 0 var(--espace-2) 0;	/* Les blocs (diplômes, études) sont nettement séparés */
	padding-top: var(--espace-3);
	border-top: var(--bordure-fine) solid var(--couleur-bordure);

	font-size: var(--taille-texte-micro);
	font-weight: 700;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--accent-1-clair);
}

.Frise-Contenu .Frise-Periode + .Frise-BlocTitre,
.Frise-Contenu p + .Frise-BlocTitre:first-of-type {
	border-top: none;
}

.Frise-Contenu ul {
	margin: 0;
	padding: 0;
	list-style: none;
}

.Frise-Contenu li {
	position: relative;
	padding-left: var(--espace-3);
	margin-bottom: var(--espace-1);
	line-height: 1.5;
}

/* Puce ronde, plutôt qu'un point de liste standard */
.Frise-Contenu li::before {
	content: "";
	position: absolute;
	left: 0;
	top: 0.72em;

	width: 4px;
	height: 4px;
	border-radius: 50%;
	background-color: var(--accent-1);
}

/* Renvoi vers le Portfolio, filtré sur le tag correspondant */
.Frise-Lien {
	display: inline-flex;
	align-items: center;
	gap: var(--espace-1);

	margin-top: var(--espace-3);
	font-size: var(--taille-texte-meta);
	font-weight: 600;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	text-decoration: none;
	color: var(--accent-1);

	transition: gap var(--duree-courte) var(--courbe), color var(--duree-courte) var(--courbe);
}

.Frise-Lien:hover {
	gap: var(--espace-2);
	color: var(--accent-3);
}


/* Une fois les deux frises empilées, la colonne est bornée et centrée : en pleine largeur
   les lignes devenaient trop longues et la page paraissait vide sur les côtés. */
@media (max-width: 1199px) {
	.Background {
		margin-top: var(--espace-6);
	}
	.Background-Colonnes {
		grid-template-columns: minmax(0, 1fr);	/* Largeur fixe : un contenu large ne doit jamais élargir la colonne à l'ouverture d'une carte */
		gap: var(--espace-6);

		width: 100%;	/* Dans un conteneur flex, une marge auto la ferait épouser son contenu : elle s'élargissait à l'ouverture d'une carte */
		max-width: 64rem;
		margin: 0 auto;
	}}

/* Sous 768px, la pastille d'année ne tient plus sur le côté : elle passe au-dessus de la
   carte, et le rail disparaît faute de place. */
@media (max-width: 767px) {
	.Frise {
		padding-left: 0;
	}
	.Frise::before {
		display: none;
	}
	.Frise-Annee {
		position: static;
		width: max-content;
		margin-bottom: var(--espace-1);
	}
	.Frise-Item {
		padding-bottom: var(--espace-3);
	}}



/* ------------------------------------------------------------------------------------------------------------------------------- */
/* ------------------------------------------------------------- Stats ----------------------------------------------------------- */
/* ------------------------------------------------------------------------------------------------------------------------------- */

/* La grille se recompose seule. Les anciens padding de 20rem, 10rem puis 5rem
   réglaient la largeur à la main, écran par écran. */
#tagCountsContainer {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: var(--espace-5) clamp(var(--espace-6), 6.5vw, 13rem);	/* Beaucoup d'air entre les tuiles : la place ne manque pas */

	margin: 0 auto;
	width: 100%;
}

/* Une tuile par moteur ou middleware. C'est un <a> quand le tag existe vraiment
   dans les projets, un <div> sinon : les deux partagent la même apparence. */
.SD-Stats-Container {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: var(--espace-1);

	padding: var(--espace-2);
	min-width: 8rem;

	/* Des tuiles plus petites qu'avant, mais toujours encadrées : l'écart entre elles les
	   sépare nettement. */
	background-color: var(--couleur-surface-2);
	border: var(--bordure-fine) solid var(--couleur-bordure);
	border-radius: var(--rayon-2);

	color: inherit;
	text-decoration: none;

	transition: transform var(--duree-courte) var(--courbe),
				border-color var(--duree-courte) var(--courbe),
				background-color var(--duree-courte) var(--courbe);
}

/* Seules les tuiles cliquables réagissent au survol : les autres ne mènent nulle part */
a.SD-Stats-Container:hover,
a.SD-Stats-Container:focus-visible {
	transform: translateY(-4px);
	background-color: var(--couleur-surface-3);
	border-color: var(--accent-1);
}

.SD-Stats-Images {
	width: 3.4rem;
	height: 3.4rem;
	object-fit: contain;
}

/* Le compteur est l'information principale de la tuile : il porte le dégradé */
.SD-Stats-Container .counter {
	font-family: var(--police-titre);
	font-size: clamp(2.6rem, 3.4vw, 3.6rem);
	line-height: 1;

	background: var(--gradient-identité);
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent;
}

.sound-design-label {
	font-size: var(--taille-texte-micro);
	color: var(--couleur-texte-doux);
	text-align: center;
	text-transform: uppercase;
	letter-spacing: 0.08em;
}

@media (max-width: 767px) {
	#tagCountsContainer {
		grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
		gap: var(--espace-2);
	}
	.SD-Stats-Container {
		padding: var(--espace-2) var(--espace-1);
	}
	.SD-Stats-Images {
		width: 3.6rem;
		height: 3.6rem;
	}}



/* ------------------------------------------------------------------------------------------------------------------------------- */
/* ----------------------------------------------------------- Services ---------------------------------------------------------- */
/* ------------------------------------------------------------------------------------------------------------------------------- */

/* Le nombre de colonnes est posé explicitement, et non déduit de la largeur : il doit
   diviser le nombre de services (six) pour que toutes les lignes en contiennent autant.
   Trois colonnes donnent deux lignes de trois ; deux colonnes, trois lignes de deux. */
.BioService {
	--services-colonnes: 3;

	display: grid;
	grid-template-columns: repeat(var(--services-colonnes), minmax(0, 1fr));
	gap: var(--espace-4);

	padding: 0 var(--espace-2);
	width: 100%;
	max-width: 156rem;	/* Assez large pour que deux étiquettes tiennent côte à côte dans chaque carte */
	row-gap: var(--espace-5);
}

@media (max-width: 1199px) {
	.BioService {
		--services-colonnes: 2;
	}}

@media (max-width: 767px) {
	.BioService {
		--services-colonnes: 1;
	}}

/* Cartes de services : verre dépoli sombre, un grand numéro en contour en filigrane, une icône dans une
   pastille teintée du dégradé d'identité et des listes à puces fines (plus d'étiquettes en pilules).
   Au survol, un cadre dégradé fait le tour de la carte, comme dans le Portfolio. */
.Service-Section {
	position: relative;
	display: grid;
	grid-template-columns: auto minmax(0, 1fr);
	grid-template-rows: auto 1fr 1fr;	/* Sous le titre, l'espace est coupé en deux à égalité : description et liste, chacune centrée dans sa moitié */
	align-content: stretch;
	column-gap: var(--espace-3);
	row-gap: clamp(1.4rem, 2.7vh, 3rem);
	align-items: center;
	/* Hauteur adaptative : les deux rangées prennent 76 % de la place sous le titre, le reste devient
	   les écarts (au-dessus, entre les rangées, au-dessous). */
	min-height: calc((var(--ecran-utile) - var(--hauteur-titre-section) - var(--espace-fin-section)) * 0.38);

	padding: clamp(1.6rem, 2.9vh, 3.4rem) var(--espace-5) 0;	/* Pas de marge basse : la liste porte la sienne, symétrique */

	background:
		radial-gradient(120% 90% at 0% 0%, rgba(77, 165, 245, 0.08), transparent 55%),
		linear-gradient(180deg, rgba(255, 255, 255, 0.035), rgba(255, 255, 255, 0.01));
	background-color: var(--couleur-surface-2);
	border: var(--bordure-fine) solid var(--couleur-bordure);
	border-radius: var(--rayon-3);

	overflow: hidden;
	transition: var(--transition-apparition, opacity 0s),
				transform var(--duree-courte) var(--courbe),
				box-shadow var(--duree-courte) var(--courbe);
}

/* Le cadre dégradé, révélé au survol */
.Service-Section::before {
	content: "";
	position: absolute;
	inset: 0;
	padding: 1px;

	border-radius: inherit;
	background: var(--gradient-identité);
	-webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
	-webkit-mask-composite: xor;
	mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
	opacity: 0;
	transition: opacity var(--duree-moyenne) var(--courbe);
	pointer-events: none;
}

.Service-Section:hover {
	transform: translateY(-4px);
	box-shadow: var(--ombre-2);
}

.Service-Section:hover::before {
	opacity: 1;
}



/* L'icône vit dans une pastille ronde teintée du dégradé : le <span> porte toute la mise en
   page, la balise <i> de Font Awesome ne fait que dessiner le glyphe. */
.ServiceIcone {
	display: flex;
	align-items: center;
	justify-content: center;
	flex: 0 0 auto;

	width: clamp(4.6rem, 6vh, 6rem);
	height: clamp(4.6rem, 6vh, 6rem);

	background: linear-gradient(135deg, rgba(77, 165, 245, 0.22), rgba(168, 85, 247, 0.22));
	border-radius: 50%;
	color: var(--couleur-titre);
}

.ServiceIcone i {
	display: block;
	font-size: clamp(1.9rem, 2.6vh, 2.5rem);
	line-height: 1;
}

/* L'icône à gauche du titre, la description et la liste sur toute la largeur en dessous */
.Service-Section p,
.Service-Liste {
	grid-column: 1 / -1;
}

.Service-Section h3 {
	margin: 0;
	font-size: var(--taille-titre-trois);
	line-height: 1.1;
}

.Service-Section p {
	margin: 0;
	font-size: var(--taille-texte-premier);
	line-height: 1.5;
	color: var(--couleur-texte-doux);
	align-self: center;	/* Le texte explicatif se centre dans sa zone, entre le titre et le filet */
}

/* La liste est repoussée en bas : les cartes d'une même ligne alignent leurs listes. Deux
   colonnes égales, donc tous les points sont alignés d'une carte à l'autre. */
.Service-Liste {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));	/* Deux colonnes égales : les points s'alignent d'une carte à l'autre */
	gap: clamp(0.6rem, 1.2vh, 1.4rem) var(--espace-2);

	margin: 0;
	/* Les points sont centrés verticalement entre le filet du dessus et le bas de la carte */
	padding: clamp(0.8rem, 1.8vh, 2.4rem) 0;
	align-content: center;	/* Les 4 points sont centrés entre le filet qui les précède et le bas de la carte */
	align-self: stretch;	/* La liste va jusqu'au bas de la carte (les items de la carte sont centrés par défaut) */
	width: 100%;

	list-style: none;
	border-top: var(--bordure-fine) solid var(--couleur-bordure);

	font-size: var(--taille-texte-meta);
	color: var(--couleur-texte);
}

.Service-Liste li {
	position: relative;
	padding-left: 1.6rem;
	white-space: nowrap;	/* Un point = une ligne : plus de retour à la ligne qui déséquilibre les cartes */

	text-align: left;
	line-height: 1.3;
}

/* La puce : un petit losange au dégradé d'identité */
.Service-Liste li::before {
	content: "";
	position: absolute;
	left: 0.2rem;
	top: 0.65em;
	width: 0.6rem;
	height: 0.6rem;

	background: var(--gradient-identité);
	rotate: 45deg;
	translate: 0 -50%;
}

/* Écran peu haut : les cartes se compactent pour que les deux lignes de services restent
   dans un écran. */
@media (max-height: 950px) {
	.Service-Section {
		padding: 1.1rem var(--espace-3) 0;
		row-gap: 0.6rem;
	}
	.Service-Section p {
		font-size: var(--taille-texte-meta);
		line-height: 1.4;
	}
	.Service-Liste {
		font-size: var(--taille-texte-meta);
	}
	.ServiceIcone {
		width: 3.8rem;
		height: 3.8rem;
	}
	.Service-Liste {
		padding-block: 0.8rem;
		gap: 0.5rem var(--espace-3);
	}}

/* Puce dessinée en CSS plutôt qu'un caractère : elle reste alignée sur la ligne de texte */


@media (max-width: 767px) {
	.BioService {
		gap: var(--espace-3);
		padding: 0;
	}
	.Service-Section {
		padding: var(--espace-3) var(--espace-3);
	}
	.ServiceIcone {
		width: 4.4rem;
		height: 4.4rem;
	}}



/* ------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------- BestWorks ---------------------------------------------------------- */
/* ------------------------------------------------------------------------------------------------------------------------------- */


/*------------------------------------------------------------- */
/*-------------------------- Global --------------------------- */
/*------------------------------------------------------------- */

.BestProjectsContainerProjets {
	display: flex;
	flex-direction: column;
	gap: var(--espace-6);
}

.SectionBestWorks {
	display: grid;
	grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
	gap: var(--espace-6);
	align-items: center;

	padding: var(--espace-5);

	/* Deux lueurs dans les angles, bleue puis violette : la carte a du relief sans
	   que le fond cesse d'être sobre. Elles s'inversent un projet sur deux. */
	background:
		radial-gradient(ellipse 50% 60% at 100% 0%, var(--coin-haut), transparent 70%),
		radial-gradient(ellipse 50% 60% at 0% 100%, var(--coin-bas), transparent 70%),
		var(--couleur-surface-1);
	border: var(--bordure-fine) solid var(--couleur-bordure);
	border-radius: var(--rayon-2);
	box-shadow: var(--ombre-1);

	/* Les deux coins échangent lentement leur couleur : le bleu glisse vers la couleur secondaire
	   pendant que celle-ci glisse vers le bleu, et inversement (coins complémentaires). */
	animation: echange-coins 12s ease-in-out infinite alternate;

	transition: border-color var(--duree-moyenne) var(--courbe), box-shadow var(--duree-moyenne) var(--courbe);
}

.SectionBestWorks:hover {
	border-color: var(--accent-1-a50);
	box-shadow: var(--ombre-2);
}

.BestProjectsContainerProjets > .SectionBestWorks:nth-child(even) {
	background:
		radial-gradient(ellipse 50% 60% at 0% 0%, var(--coin-haut), transparent 70%),
		radial-gradient(ellipse 50% 60% at 100% 100%, var(--coin-bas), transparent 70%),
		var(--couleur-surface-1);
}

/* Un projet sur deux inverse ses colonnes : le regard ne suit pas toujours le même chemin.
   On déplace le média, pas le contenu du DOM : l'ordre de lecture reste correct. */
.BestProjectsContainerProjets > .SectionBestWorks:nth-child(even) .SectionBestWorks-Informations-Left {
	order: 2;
}

.SectionBestWorks-Informations-Left,
.SectionBestWorks-Informations-Right {
	min-width: 0;	/* Autorise les colonnes de grille à se réduire au lieu de déborder */
}

@media (max-width: 1199px) {
	.SectionBestWorks {
		grid-template-columns: 1fr;
		gap: var(--espace-4);
		padding: var(--espace-3);
	}
	/* Sur une colonne, l'alternance n'a plus de sens : le média reste au-dessus */
	.BestProjectsContainerProjets > .SectionBestWorks:nth-child(even) .SectionBestWorks-Informations-Left {
		order: 0;
	}}



/*------------------------------------------------------------- */
/*-------------------------- Gauche --------------------------- */
/*------------------------------------------------------------- */

/*--------------------------- */
/*---------- Vidéo ---------- */
/*--------------------------- */

.videoWrapper {
	position: relative;
	width: 100%;
	max-width: 100%;
	height: auto;
	padding-top: 56.25%; /* Ratio 16:9 */

	background-color: var(--couleur-fond);
	border-radius: var(--rayon-1);
	overflow: hidden;

	transition: filter var(--duree-courte) var(--courbe);
}

.videoWrapper.active {
	filter: none;
	background: transparent;
}

.video-container {
	position: relative;
}

.videoIframe {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	border: none;
	border-radius: var(--rayon-1);
}

/* Façade de la vidéo : l'affiche YouTube et un bouton lecture, remplacés par le lecteur au clic */
.videoFacade {
	position: absolute;
	inset: 0;
	display: block;
	width: 100%;
	height: 100%;
	padding: 0;
	border: none;
	border-radius: var(--rayon-1);
	background: #000;
	overflow: hidden;
	cursor: var(--curseur-lien);
}
.videoAffiche {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;	/* Rogne les bandes noires des affiches 4/3 de secours */
	transition: transform var(--duree-moyenne) var(--courbe), filter var(--duree-moyenne) var(--courbe);
}
.videoFacade:hover .videoAffiche { transform: scale(1.03); filter: brightness(0.75); }
/* Bouton Play de la vidéo d'un projet : verre sombre neutre, seul le contour est un dégradé bleu vers violet (anneau découpé par un masque, pour ne rien teinter dans le fond), triangle blanc */
.videoFacade .DemoReel-Play {
	width: 6rem; height: 6rem; font-size: 2.2rem;
	background-color: rgba(8, 10, 16, 0.6);
	color: #fff;
	box-shadow: none;
	animation: none;
	-webkit-backdrop-filter: blur(4px);
	backdrop-filter: blur(4px);
}
.videoFacade .DemoReel-Play::before {
	content: "";
	position: absolute;
	inset: 0;
	padding: 2px;
	border-radius: inherit;
	background: linear-gradient(135deg, var(--accent-1), var(--accent-2));
	-webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
	-webkit-mask-composite: xor;
	mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
	pointer-events: none;
}
.videoFacade:hover .DemoReel-Play { background-color: rgba(8, 10, 16, 0.8); }
.videoFacade:hover .DemoReel-Play { transform: translate(-50%, -50%) scale(1.1); }

.video-slide.slick-slide {
	margin: 0 0.4rem;
}

.videoBoite {
	position: relative;
}

.videoCadre {
	--trace: 0deg;
	position: absolute;
	inset: 0;
	z-index: 3;
	border-radius: var(--rayon-1);
	pointer-events: none;

	--depart: 0deg;	/* Point de départ du tracé, tiré au hasard à chaque activation (voir majVideoActive) */
	-webkit-mask-image: conic-gradient(from var(--depart), #000 var(--trace), transparent var(--trace));
	mask-image: conic-gradient(from var(--depart), #000 var(--trace), transparent var(--trace));
	transition: --trace 0.3s linear, opacity 0.3s ease-out;
}

/* Modes de tracé, tirés au hasard : sens horaire (par défaut), sens inverse, deux sens qui se
   rejoignent, ou simple fondu. */
.videoCadre[data-mode="inverse"] {
	transform: scaleX(-1);
}

.videoCadre[data-mode="double"] {
	-webkit-mask-image: conic-gradient(from var(--depart), #000 var(--trace), transparent var(--trace) calc(360deg - var(--trace)), #000 calc(360deg - var(--trace)));
	mask-image: conic-gradient(from var(--depart), #000 var(--trace), transparent var(--trace) calc(360deg - var(--trace)), #000 calc(360deg - var(--trace)));
}

.videoCadre[data-mode="fondu"] {
	-webkit-mask-image: none;
	mask-image: none;
	opacity: 0;
}

.videoBoite--active .videoCadre[data-mode="fondu"] {
	opacity: 1;
}

.videoBoite--active .videoCadre {
	--trace: 360deg;
}

.videoCadre::before {
	content: "";
	position: absolute;
	inset: 0;
	padding: 1px;

	border-radius: inherit;
	/* Diagonale à deux couleurs : les coins opposés sont complémentaires, et le dégradé glisse, donc
	   chaque coin passe du bleu à la couleur secondaire et inversement. */
	background: linear-gradient(135deg, var(--accent-1), var(--accent-2), var(--accent-3), var(--accent-2), var(--accent-1));
	background-size: 300% 300%;
	-webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
	-webkit-mask-composite: xor;
	mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
	animation: glissement-cadre 6s ease-in-out infinite alternate;
}

/* Les vidéos voisines restent visibles mais floutées : on sait qu'il y en a d'autres */
.videoWrapper {
	filter: blur(0) saturate(1);
	transition: filter 0.3s ease-out;
}

.videoWrapper.inactive {
	position: relative;
	filter: blur(3px) saturate(0.7);
	transition-duration: 0.25s;	/* Le flou se pose vite et se retire vite */
}

/* Nom du lien sous la vidéo : c'est une information, pas une décoration */
.slideCaption {
	padding: var(--espace-1) 0.4rem 0 0.4rem;

	font-size: var(--taille-texte-meta);
	color: var(--couleur-texte-doux);
	text-align: center;
}

.video-container .slick-current .slideCaption {
	color: var(--couleur-titre);
}


/*--------------------------- */
/*--------- Arrows ---------- */
/*--------------------------- */

/* Des boutons ronds de taille raisonnable. Les anciennes flèches étendaient leur zone
   cliquable de 14rem vers le haut avec un ::before : le moindre clic dans la vidéo
   changeait de diapositive. */
.prev-arrow, .next-arrow {
	--fleche: 4.4rem;	/* Diamètre du bouton */
	--bord: 0.4rem;	/* Retrait de la vidéo dans son conteneur (marge des diapositives) */
	position: absolute;
	top: 50%;
	z-index: 10;

	display: flex;
	align-items: center;
	justify-content: center;

	width: var(--fleche);
	height: var(--fleche);
	padding: 0;

	background-color: var(--couleur-bandeau);
	border: var(--bordure-fine) solid var(--couleur-bordure-forte);
	border-radius: 50%;
	color: var(--couleur-titre);

	cursor: var(--curseur-lien);
	transform: translateY(-50%);
	transition: background-color var(--duree-courte) var(--courbe),
				border-color var(--duree-courte) var(--courbe),
				color var(--duree-courte) var(--courbe),
				opacity var(--duree-courte) var(--courbe);
}

.prev-arrow i, .next-arrow i {
	display: block;
	font-size: 1.6rem;
	line-height: 1;
}

/* Le centre du bouton est posé exactement sur la bordure de la vidéo */
.prev-arrow { left: calc(var(--bord) - var(--fleche) / 2); }
.next-arrow { right: calc(var(--bord) - var(--fleche) / 2); }

.prev-arrow:hover:not(:disabled),
.next-arrow:hover:not(:disabled) {
	background-color: var(--accent-1);
	border-color: transparent;
	color: #0a0a0c;
}

/* Un bouton qui ne mène nulle part le dit : on est à la première ou à la dernière vidéo */
.prev-arrow:disabled, .next-arrow:disabled {
	opacity: 0.25;
	cursor: var(--curseur-base);
}

/* Un seul média : aucune navigation à proposer */
.SectionBestWorks--UneSeuleVideo .prev-arrow,
.SectionBestWorks--UneSeuleVideo .next-arrow,
.SectionBestWorks--UneSeuleVideo .video-thumbnails {
	display: none;
}

@media (max-width: 767px) {
	.prev-arrow, .next-arrow { --fleche: 3.6rem; }}


/*--------------------------- */
/*------- Thumbnails -------- */
/*--------------------------- */

.video-thumbnails {
	padding: var(--espace-2) 0 0 0;
}

.video-thumbnails .slick-slide {
	margin: 0 0.4rem;

	opacity: 0.55;
	transform: scale(0.88);

	cursor: var(--curseur-lien);
	transition: opacity var(--duree-courte) var(--courbe),
				transform var(--duree-courte) var(--courbe);
}

.video-thumbnails .slick-slide img {
	display: block;
	width: 12rem;
	aspect-ratio: 16 / 9;
	object-fit: cover;

	border: var(--bordure-fine) solid var(--couleur-bordure);
	border-radius: var(--rayon-1);
}

.video-thumbnails .slick-slide:hover {
	opacity: 0.85;
	transform: scale(1);
}

/* Le survol n'a plus d'effet sur la miniature déjà sélectionnée */
.video-thumbnails .slick-slide.active-thumbnail {
	cursor: var(--curseur-base);
	transform: scale(1);
}

.video-thumbnails .slick-center {
	opacity: 1;
	transform: scale(1);
}

/* Miniature active */
.video-thumbnails .slick-center img {
	border-color: var(--accent-1);
}


/* Écrans tablette paysage */
@media (max-width: 1199px) and (min-width: 768px) {
	.video-thumbnails .slick-slide img {
		width: 16rem;
	}}

/* Écrans smartphones portrait */
@media (max-width: 767px) {
	.video-thumbnails .slick-slide img {
		width: 9rem;
	}}



/*------------------------------------------------------------- */
/*-------------------------- Droite --------------------------- */
/*------------------------------------------------------------- */

.SectionBestWorks-Informations-Right {
	display: flex;
	flex-direction: column;
	gap: var(--espace-4);
}

/* Titre centré dans la colonne, souligné d'un filet dégradé de la largeur exacte du titre :
   plus fin que celui des titres de section, qui fait trois pixels. */
.Projet-Entete {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--espace-3);
}

.SectionBestWorks-Informations-Title {
	position: relative;
	margin: 0;
	padding: 0 0 var(--espace-2) 0;

	font-size: var(--taille-titre-trois);
	line-height: 1.1;
	text-align: center;
}

.Titre-Ligne {
	position: absolute;
	left: 0;
	bottom: 0;
	width: 100%;
	height: 1px;
	background: var(--gradient-identité);
}

.Projet-Description {
	margin: 0;
	text-align: justify;
	font-size: var(--taille-texte-second);
	color: var(--couleur-texte);
}


/*--------------------------- */
/*---------- Tags ----------- */
/*--------------------------- */

.Projet-Tags {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: var(--espace-3);

	margin: 0;
	padding: 0;
	list-style: none;
}

/* Une pastille cliquable : elle emmène au Portfolio avec son filtre appliqué */
.Projet-Tag {
	display: inline-block;
	padding: 0.35rem 1rem;

	background-color: var(--couleur-surface-3);
	border: var(--bordure-fine) solid var(--couleur-bordure);
	border-radius: var(--rayon-pilule);

	font-size: var(--taille-texte-micro);
	color: var(--couleur-texte-doux);
	text-decoration: none;
	white-space: nowrap;

	transition: background-color var(--duree-courte) var(--courbe),
				border-color var(--duree-courte) var(--courbe),
				color var(--duree-courte) var(--courbe);
}

.Projet-Tag:hover, .Projet-Tag:focus-visible {
	background-color: var(--accent-1-a10);
	border-color: var(--accent-1);
	color: var(--accent-1-clair);
}


/*--------------------------- */
/*----- Fiche technique ----- */
/*--------------------------- */

/* Deux colonnes : les libellés alignés à gauche, les valeurs en face. Les anciennes lignes
   étaient des flex indépendants, qui se décalaient l'un par rapport à l'autre. */
.Projet-Fiche {
	display: grid;
	gap: var(--espace-3);

	margin: 0;
	padding: var(--espace-4) 0 0 0;
	border-top: var(--bordure-fine) solid var(--couleur-bordure);
}

.Projet-Fiche-Ligne {
	display: grid;
	grid-template-columns: 15rem minmax(0, 1fr);
	gap: var(--espace-3);
	align-items: baseline;
}

/* Icône puis libellé : l'icône occupe une colonne de largeur fixe et se centre dedans, ce
   qui aligne les libellés d'une ligne à l'autre quelle que soit la largeur de chaque glyphe. */
.Projet-Fiche dt {
	display: grid;
	grid-template-columns: 2.6rem minmax(0, 1fr);
	align-items: baseline;

	margin: 0;
	font-size: var(--taille-texte-meta);
	color: var(--couleur-texte-doux);
	text-transform: uppercase;
	letter-spacing: 0.08em;
}

.Projet-Fiche dt i {
	text-align: center;
	color: var(--accent-1);
}


/* Les valeurs se suivent sur la même ligne et reviennent à la ligne si besoin */
.Projet-Fiche dd {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;

	margin: 0;
	font-size: var(--taille-texte-second);
	color: var(--couleur-texte);
}

/* Le séparateur est dessiné par le CSS : le texte lui-même reste propre */
.Projet-Fiche dd span + span::before {
	content: "·";
	margin: 0 0.8rem;
	color: var(--couleur-texte-doux);
}

@media (max-width: 480px) {
	/* Trop étroit pour deux colonnes : le libellé passe au-dessus de sa valeur */
	.Projet-Fiche-Ligne {
		grid-template-columns: 1fr;
		gap: 0.3rem;
	}}


/*--------------------------- */
/*--------- Boutique -------- */
/*--------------------------- */

.BestWorks-Icon a {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: max-content;

	transition: transform var(--duree-courte) var(--courbe);
}

.BestWorks-Icon a:hover {
	transform: translateY(-3px) scale(1.08);
}

.BestWorks-Icon img {
	display: block;
	transition: filter var(--duree-courte) var(--courbe);
	width: 3rem;
	height: 3rem;
	object-fit: contain;
}
.BestWorks-Icon a:hover img {
	filter: brightness(1.25);
}
.BestWorks-Icon a {
	text-decoration: none;	/* Pas de soulignement sous l'icône */
}



/* ------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------- Portfolio ---------------------------------------------------------- */
/* ------------------------------------------------------------------------------------------------------------------------------- */

/* Dimensions de la zone de défilement et des cartes, réunies ici.
   La hauteur d'une carte se déduit de la place réellement disponible dans la section :
   deux lignes entières tiennent dans un écran, sans valeur magique à régler à la main. */
#SectionPortfolio {
	--portfolio-reserve: calc(var(--hauteur-titre-section) + 8.4rem);	/* Titre de section + barre de filtres */

	/* La zone de défilement occupe tout ce que la section (deux écrans) laisse sous la barre */
	--portfolio-defilement: calc(var(--ecran-utile) - var(--portfolio-reserve) - var(--espace-fin-section));

	/* Hauteur du bandeau d'informations. Fixe : c'est le texte qui s'y adapte, par
	   troncature, et non l'inverse. Toutes les cartes ont ainsi la même hauteur,
	   donc des lignes régulières, ce dont dépend le calage du défilement. */
	--carte-infos: 25.6rem;

	/* Vingt-sept des quarante et un visuels sont au format 16/9 : l'image occupe donc
	   la largeur de la carte en 16/9, et s'affiche en entier. Elle était auparavant
	   rognée de près de moitié en hauteur.
	   La largeur est bornée pour qu'une ligne entière tienne toujours dans la zone de
	   défilement, même sur un écran bas : c'est elle qui règle toute la géométrie. */
	--carte-largeur: 36rem;
}

/*----------------------------------------------------------- */
/* --------------------- Barre de filtres ------------------- */
/*----------------------------------------------------------- */

/* Plusieurs boutons côte à côte, un par grande catégorie, plutôt qu'un seul menu
   déroulant dans lequel il fallait deviner où se trouvait chaque tag. */
.Portfolio-Barre {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--espace-2);

	margin: 0 0 var(--espace-3) 0;	/* Aucune marge en haut : l'écart au titre reste celui des autres sections */
	position: relative;
	z-index: 5;	/* Les panneaux de sous-filtres passent au-dessus des cartes */
}

.Filtres {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--espace-4);
}

/* Nombre de projets affichés, mis à jour à chaque filtre */
.Portfolio-Resultat {
	margin: 0;
	font-size: var(--taille-texte-meta);
	color: var(--couleur-texte-doux);
	text-transform: uppercase;
	letter-spacing: 0.1em;
	white-space: nowrap;
}


/*--------------------------- */
/*--------- Boutons --------- */
/*--------------------------- */

.Filtre {
	display: inline-flex;
	align-items: center;
	gap: 0.6rem;

	padding: 1rem 2.6rem;

	background-color: var(--couleur-surface-2);
	border: var(--bordure-fine) solid var(--couleur-bordure);
	border-radius: var(--rayon-pilule);

	font-family: var(--police-texte);
	font-size: var(--taille-texte-micro);
	color: var(--couleur-texte);

	cursor: var(--curseur-lien);
	transition: background-color var(--duree-courte) var(--courbe),
				border-color var(--duree-courte) var(--courbe),
				color var(--duree-courte) var(--courbe);
}

.Filtre:hover {
	border-color: var(--accent-1);
	background-color: var(--accent-1-a10);
	color: var(--accent-1-clair);
}

/* Le filtre appliqué est plein : impossible de se demander ce qu'on regarde */
.Filtre--actif {
	background-color: var(--accent-1);
	border-color: transparent;
	color: #0a0a0c;
}

.Filtre--actif:hover,
.Filtre--sous.Filtre--actif:hover {
	background-color: var(--accent-1-clair);
	border-color: transparent;
	color: #0a0a0c;	/* Texte sombre sur le bleu clair : le survol d'un filtre actif doit rester lisible */
}

/* Un groupe dont un sous-filtre est actif reste signalé, panneau fermé */
.Filtre--parentActif {
	border-color: var(--accent-1);
	color: var(--accent-1-clair);
}

/* Le nombre de projets du filtre : une information, pas un libellé */
.Filtre-Compte {
	font-size: 0.85em;
	color: var(--accent-2);	/* Le violet porte les chiffres : un détail, pas une couleur de plus */
}

.Filtre--actif .Filtre-Compte {
	color: rgba(10, 10, 12, 0.65);
}

.Filtre-Chevron {
	font-size: 0.8em;
	transition: transform var(--duree-courte) var(--courbe);
}

.Filtre--groupe[aria-expanded="true"] .Filtre-Chevron {
	transform: rotate(180deg);
}


/*--------------------------- */
/*--- Panneau sous-filtres -- */
/*--------------------------- */

.Filtre-Groupe {
	position: relative;
}

/* Le panneau s'ouvre au survol ou au clic sous son bouton. Fond flouté, liseré dégradé
   sur le haut, petite pointe vers son bouton, et ouverture en fondu glissant. */
.Filtre-Panneau {
	position: absolute;
	top: calc(100% + 1.2rem);
	left: 0;
	z-index: 20;

	--colonnes: 2;	/* Remplacé en ligne par le script selon le nombre de sous-filtres */
	display: grid;
	grid-template-columns: repeat(var(--colonnes, 2), 1fr);	/* Colonnes de même largeur */
	gap: var(--espace-2);

	padding: var(--espace-3);
	width: max-content;
	max-width: 90vw;

	background: linear-gradient(180deg, var(--couleur-surface-2), var(--couleur-surface-1));
	border: var(--bordure-fine) solid var(--couleur-bordure-forte);
	border-radius: var(--rayon-2);
	box-shadow: var(--ombre-3), 0 0 4rem var(--accent-2-a25);

	animation: panneau-ouverture var(--duree-moyenne) var(--courbe);
}

/* Liseré d'identité sur le bord haut */
.Filtre-Panneau::after {
	content: "";
	position: absolute;
	top: -1px;
	left: calc(var(--rayon-2) * 2);
	right: calc(var(--rayon-2) * 2);
	height: 1px;
	opacity: 0.7;
	background: var(--gradient-identité);
	border-radius: var(--rayon-pilule);
}

/* Pont invisible entre le bouton et son panneau : sans lui, la souris quitterait le
   groupe en traversant l'espace qui les sépare, et le panneau se refermerait. */
.Filtre-Panneau::before {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	top: -1.4rem;
	height: 1.4rem;
}

/* Sans cette règle, le display: flex ci-dessus l'emporte sur l'attribut hidden posé par
   le script : les panneaux restaient tous ouverts, les uns par-dessus les autres. */
.Filtre-Panneau[hidden] {
	display: none;
}

.Filtre--sous {
	justify-content: space-between;
	background-color: var(--couleur-surface-3);
	padding: 0.8rem 1.8rem;
	min-width: 18rem;
}

/* Le filtre actif d'un sous-menu : bordure et texte bleus, comme tous les autres éléments actifs */
.Filtre--sous:hover,
.Filtre--sous.Filtre--actif {
	background-color: var(--accent-1);
	border-color: transparent;
	color: #0a0a0c;
}

.Filtre--sous.Filtre--actif .Filtre-Compte,
.Filtre--sous:hover .Filtre-Compte,
.Filtre--actif:hover .Filtre-Compte {
	color: #0a0a0c;	/* Sur le plein bleu, le chiffre reste lisible */
	font-weight: 700;
}


/*----------------------------------------------------------- */
/* ---------------------- Défilement ------------------------ */
/*----------------------------------------------------------- */

/* La zone de défilement prend toute la hauteur que la section lui laisse. Les cartes
   ayant toutes la même hauteur, le scroll snap cale toujours une ligne sur le haut de
   la zone ; la ligne suivante dépasse en bas, ce qui signale qu'il y en a d'autres.
   L'ancienne hauteur, calc(100% - 21rem)!important, ne correspondait à rien de mesurable. */
.Portfolio-Defilement {
	position: relative;
	height: var(--portfolio-defilement);

	/* Marge haute et latérales : la carte survolée se soulève et rayonne, sans être rognée */
	/* Marges latérales réduites et adaptatives : le cadre des cartes tient dans 1px, il n'a plus besoin
	   de place pour déborder. Plus l'écran est étroit, plus elles se resserrent. */
	padding: 1.6rem clamp(0.4rem, 0.8vw, 1.2rem) 0;
	scroll-padding-top: 1.6rem;

	overflow-x: hidden;
	overflow-y: auto;
	scrollbar-gutter: stable;	/* La barre ne fait pas varier la largeur quand un filtre change le nombre de lignes */

	/* Chaque ligne de cartes est un point d'arrêt : le défilement s'arrête toujours sur la ligne
	   suivante ou précédente, jamais entre deux. Pendant un changement de filtre, le script
	   suspend l'accrochage le temps du réarrangement (voir appliquerFiltre). */
	scroll-snap-type: y mandatory;
	overscroll-behavior: contain;	/* Arrivé en bas, le défilement ne s'échappe pas vers la page */
}

/* Message affiché quand un filtre ne renvoie aucun projet */
.Portfolio-Vide {
	margin: 0;
	padding: var(--espace-5) 0;

	font-size: var(--taille-texte-premier);
	color: var(--couleur-texte-doux);
	text-align: center;
}


/*----------------------------------------------------------- */
/* ------------------------- Cartes ------------------------- */
/*----------------------------------------------------------- */

.PortfolioContainerProjets {
	position: relative;
	width: 100%;
}

/* Une carte verticale : l'image en haut, les informations en dessous sur un fond opaque.
   Largeur et hauteur sont fixes, ce qui donne des lignes régulières — nécessaire au
   cadrage du défilement — et laisse Isotope répartir l'espace restant entre les cartes. */
.SectionWorks {
	position: relative;
	display: flex;
	flex-direction: column;

	width: var(--carte-largeur);
	margin-bottom: var(--ecart-rangee, var(--espace-5));	/* Plus d'air entre les lignes ; l'écart s'ajuste en mode compact ou grille entière (script) */

	background-color: var(--couleur-surface-2);
	border: var(--bordure-fine) solid var(--couleur-bordure);
	border-radius: var(--rayon-2);

	scroll-snap-align: start;

	/* Isotope place les cartes avec transform : le soulèvement passe donc par translate,
	   une propriété distincte qui ne l'écrase pas. */
	transition: translate var(--duree-moyenne) var(--courbe),
				border-color var(--duree-moyenne) var(--courbe),
				box-shadow var(--duree-moyenne) var(--courbe);
}

/* Avant leur première apparition, les cartes sont invisibles ; elles entrent ensuite une seule fois. */
.Carte-Attente {
	visibility: hidden;
}

.Carte-Apparue {
	animation: carte-entree var(--duree-longue) var(--courbe) var(--delai, 0s) backwards;
}

/* Une fois entrée, la carte ne rejoue jamais son animation : un filtre qui la masque puis la
   ré-affiche la relancerait sinon, et les cartes « sautaient ». */
.Carte-Posee {
	animation: none;
}

/* Le survol anime la carte entière : elle se soulève, son bord passe au violet et une
   lueur l'entoure. L'image, elle, ne bouge plus. */
/* Au survol, un cadre dégradé fait tout le tour de la carte, à l'épaisseur de la bordure
   (1px). Dessiné par un pseudo-élément masqué : seul l'anneau reste visible. */
.SectionWorks::before {
	content: "";
	position: absolute;
	inset: -1px;
	z-index: 4;
	padding: 1px;

	border-radius: inherit;
	background: linear-gradient(90deg, var(--accent-1), var(--accent-2), var(--accent-3), var(--accent-2), var(--accent-1));
	background-size: 200% 100%;
	animation: circulation-couleur 7s linear infinite;
	-webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
	-webkit-mask-composite: xor;
	mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
	pointer-events: none;

	opacity: 0;
	transition: opacity var(--duree-moyenne) var(--courbe);
}

/* La carte ne bouge ni ne grossit : seul le cadre prend vie, la couleur y circule */
.SectionWorks:hover {
	box-shadow: none;
}

.SectionWorks:hover::before {
	opacity: 1;
}


/*--------------------------- */
/*--------- Visuel ---------- */
/*--------------------------- */

.Carte-Visuel {
	position: relative;
	flex: 0 0 auto;
	aspect-ratio: 16 / 9;	/* Le format des visuels : ils s'affichent donc en entier */

	background-color: var(--couleur-fond);
	border-radius: calc(var(--rayon-2) - var(--bordure-fine)) calc(var(--rayon-2) - var(--bordure-fine)) 0 0;
	overflow: hidden;	/* Seul le visuel rogne : le menu des liens peut sortir de la carte */
}

.Carte-Image {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* Affiche ou image qui n'est pas en 16/9 : vue en entier (posé par initImagesEntieres) */
.Image-Entiere { object-fit: contain; }

/* Léger voile en haut du visuel (sous la date) : plus de fondu en bas, l'image reste nette jusqu'au bandeau */
.Carte-Visuel::after {
	content: "";
	position: absolute;
	inset: 0;
	pointer-events: none;

	background: linear-gradient(to bottom, rgba(10, 10, 12, 0.35) 0%, rgba(10, 10, 12, 0) 40%);
}

/* Date et étoile posées sur le visuel, dans des pastilles opaques pour rester lisibles
   quelle que soit l'image en dessous. */
.Carte-Date, .Carte-Favori {
	position: absolute;
	top: var(--espace-2);
	z-index: 1;

	padding: 0.3rem 0.9rem;

	background-color: var(--couleur-bandeau);
	border: var(--bordure-fine) solid var(--couleur-bordure);
	border-radius: var(--rayon-pilule);

	font-size: var(--taille-texte-micro);
	color: var(--couleur-titre);
	letter-spacing: 0.04em;
}

.Carte-Date { left: var(--espace-2); }

/* Les favoris portent une vraie pastille dégradée : l'ancienne étoile rose sur fond noir
   se confondait avec la date. */
.Carte-Date, .Carte-Favori {
	z-index: 1;
}

/* L'étoile d'origine, plus grande et dorée, dans un disque sombre pour qu'elle ressorte
   sur n'importe quelle image. */
.Carte-Favori {
	right: var(--espace-2);
	top: var(--espace-2);
	display: flex;
	align-items: center;
	justify-content: center;

	width: 2.8rem;	/* 30 % de moins que les 4 rem d'origine */
	height: 2.8rem;
	padding: 0;

	/* Disque sombre semi-transparent, avec un halo sombre autour du cercle pour l'isoler de l'image */
	background-color: rgba(0, 0, 0, 0.6);
	border: none;
	box-shadow: 0 0 0.56rem 0.56rem rgba(0, 0, 0, 0.4);
}

.Carte-Favori i {
	font-size: 1.4rem;
	color: var(--accent-2);
	filter: drop-shadow(0 0 5px rgba(168, 85, 247, 0.9));
}

/* Le cercle : un anneau au dégradé qui se déplace, comme les autres traits du site */
.Carte-Favori::before {
	content: "";
	position: absolute;
	inset: 0;
	padding: 1.5px;

	border-radius: 50%;
	background: linear-gradient(90deg, var(--accent-1), var(--accent-2), var(--accent-3), var(--accent-2), var(--accent-1));
	background-size: 200% 100%;
	animation: circulation-couleur 4s linear infinite;
	-webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
	-webkit-mask-composite: xor;
	mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
}

.Carte-Favori i {
	color: #ffe27a;
	filter: drop-shadow(0 0 4px rgba(255, 210, 80, 0.8));
}



/*--------------------------- */
/*------- Informations ------ */
/*--------------------------- */

/* Le bandeau d'informations est opaque et toujours visible : plus besoin de survoler
   la carte pour savoir de quel projet il s'agit. */
.Carte-Infos {
	display: flex;
	flex-direction: column;
	gap: var(--espace-2);
	flex: 0 0 auto;
	height: var(--carte-infos);	/* Hauteur fixe : toutes les cartes se valent, les lignes sont régulières */

	padding: var(--espace-3) var(--espace-4);
}

/* Aucun bloc de la carte ne se laisse comprimer : faute de quoi les lignes de texte
   débordaient de leur boîte et se superposaient au bloc suivant. */
.Carte-Infos > * {
	flex: 0 0 auto;
}

.Carte-Titre {
	margin: 0;
	font-size: var(--taille-titre-quatre);
	line-height: 1.15;
	color: var(--couleur-titre);

	/* Deux lignes au maximum : au-delà, le titre est coupé proprement */
	display: -webkit-box;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: 2;
	line-clamp: 2;
	overflow: hidden;
}

.Carte-Description {
	margin: 0;
	font-size: var(--taille-texte-second);
	line-height: 1.45;
	color: var(--couleur-texte-doux);

	display: -webkit-box;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: 2;
	line-clamp: 2;
	overflow: hidden;
}


/*--------------------------- */
/*---------- Tags ----------- */
/*--------------------------- */

/* Les tags sont posés en bas de l'image, dans le fondu sombre : une seule rangée,
   ce qui dépasse est masqué. Dans le bandeau de texte, ils coûtaient une ligne entière
   de hauteur à chaque carte. */
.Carte-Tags {
	position: relative;
	flex: 0 0 auto;
	justify-content: center;
	height: 2.8rem;	/* Hauteur fixe : les titres sont au même niveau d'une carte à l'autre */

	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.8rem;

	margin: 0;
	padding: 0;

	list-style: none;
	overflow: hidden;
}

.Carte-Tag {
	padding: 0.3rem 1.1rem;

	background-color: var(--couleur-bandeau);
	border: var(--bordure-fine) solid var(--couleur-bordure);
	border-radius: var(--rayon-pilule);

	font-family: var(--police-texte);
	font-size: var(--taille-texte-micro);
	color: var(--couleur-texte-doux);
	white-space: nowrap;

	cursor: var(--curseur-lien);
	transition: background-color var(--duree-courte) var(--courbe),
				border-color var(--duree-courte) var(--courbe),
				color var(--duree-courte) var(--courbe);
}

.Carte-Tag:hover {
	background-color: #000;
	border-color: var(--accent-1);
	color: var(--accent-1-clair);
}

/* Le tag qui filtre actuellement le portfolio est mis en évidence sur toutes les cartes */
.Carte-Tag--actif {
	background-color: var(--accent-1-a10);
	border-color: var(--accent-1);
	color: var(--accent-1-clair);
}


/*--------------------------- */
/*-------- Métadonnées ------ */
/*--------------------------- */

/* Clients et tâches : une icône, puis les valeurs séparées par un point médian.
   Repoussées en bas de la carte, juste au-dessus des liens. */
.Carte-Meta {
	display: grid;
	gap: 0.3rem;

	margin: auto 0 0 0;
	padding: var(--espace-2) 0 0 0;
	border-top: var(--bordure-fine) solid var(--couleur-bordure);
}

.Carte-Meta-Ligne {
	display: grid;
	grid-template-columns: 2.4rem minmax(0, 1fr);
	align-items: baseline;

	font-size: var(--taille-texte-meta);
	color: var(--couleur-texte-doux);
}

.Carte-Meta dt {
	margin: 0;
	color: var(--accent-1);
}

.Carte-Meta dd {
	margin: 0;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}


/*--------------------------- */
/*---------- Liens ---------- */
/*--------------------------- */

.Carte-Liens {
	position: relative;
	z-index: 3;	/* Au-dessus des tags de l'image quand le menu de liens s'ouvre */
	display: flex;
	flex: 0 0 auto;
}

/* Un projet avec un seul lien l'affiche directement */
.Carte-Lien, .Link-DropDown-Menu-Btn {
	display: inline-flex;
	align-items: center;
	gap: 0.8rem;

	padding: 0.4rem 1.2rem;
	max-width: 100%;

	background-color: var(--couleur-surface-3);
	border: var(--bordure-fine) solid var(--couleur-bordure-forte);
	border-radius: var(--rayon-pilule);

	font-family: var(--police-texte);
	font-size: var(--taille-texte-micro);
	font-weight: 600;
	color: var(--couleur-titre);
	text-decoration: none;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;

	cursor: var(--curseur-lien);
	transition: background-color var(--duree-courte) var(--courbe),
				border-color var(--duree-courte) var(--courbe),
				color var(--duree-courte) var(--courbe);
}

.Carte-Lien:hover, .Link-DropDown-Menu-Btn:hover {
	border-color: var(--accent-1);
	color: var(--accent-1-clair);
}

.Carte-Lien i, .Link-DropDown-Menu-Btn i {
	flex: 0 0 auto;
	font-size: 0.9em;
}

/* Logo d'un lien : une colonne de taille fixe, pour que tous les logos soient alignés entre eux et que les textes commencent au même endroit */
.Logo-Lien {
	flex: 0 0 auto;
	display: inline-grid;
	place-items: center;
	width: 1.8em;
	height: 1.8em;
}
.Logo-Lien img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: contain;
}
.Logo-Lien i {
	font-size: 1.2em;
}


/*--------------------------- */
/*-------- Liens Menu ------- */
/*--------------------------- */

.Link-DropDown-Menu {
	position: relative;
	display: inline-block;
	max-width: 100%;
}

/* Le menu s'ouvre vers le haut, dans la hauteur de la carte : ouvert vers le bas,
   il sortait de la carte et se faisait rogner par la zone de défilement. */
.Link-DropDown-Menu-Content {
	position: absolute;
	bottom: calc(100% + 0.6rem);
	left: 0;
	z-index: 30;

	display: flex;
	opacity: 0;
	visibility: hidden;
	translate: 0 0.8rem;
	transition: opacity 0.18s var(--courbe), translate 0.18s var(--courbe), visibility 0s linear 0.18s;
	flex-direction: column;
	gap: 0.5rem;

	padding: var(--espace-2);

	/* Aussi large que la carte : un lien ne passe jamais sur deux lignes. Les noms vraiment
	   trop longs sont tronqués, et le titre complet s'affiche au survol. */
	width: calc(var(--carte-largeur) - 2 * var(--espace-4));
	max-height: 24rem;

	background-color: var(--couleur-surface-1);
	border: var(--bordure-fine) solid var(--couleur-bordure-forte);
	border-radius: var(--rayon-1);
	box-shadow: var(--ombre-3);

	overflow-y: auto;
}

/* Pont invisible entre le bouton et le menu, pour que le survol ne se perde pas */
.Link-DropDown-Menu::after {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	bottom: 100%;
	height: 0.8rem;
}

/* Ouverture et fermeture animées, pilotées par la classe « active » (voir initMenusLiens) */
.Link-DropDown-Menu-Content.active {
	opacity: 1;
	visibility: visible;
	translate: 0 0;
	transition: opacity 0.2s var(--courbe), translate 0.2s var(--courbe), visibility 0s;
}

.Link-DropDown-Menu-Btn i.fa-chevron-up {
	transition: transform var(--duree-courte) var(--courbe);	/* Comme le chevron des filtres */
}

.Link-DropDown-Menu-Btn[aria-expanded="true"] i.fa-chevron-up {
	transform: rotate(180deg);
}

.Link-span {
	display: flex;
	align-items: center;
	justify-content: flex-start;
	gap: var(--espace-2);

	padding: 0.7rem 1rem;

	background-color: var(--couleur-surface-2);
	border: var(--bordure-fine) solid var(--couleur-bordure);
	border-radius: var(--rayon-1);

	font-size: var(--taille-texte-meta);
	color: var(--couleur-texte);
	text-decoration: none;
	line-height: 1.35;

	transition: background-color var(--duree-courte) var(--courbe),
				border-color var(--duree-courte) var(--courbe),
				color var(--duree-courte) var(--courbe);
}

/* Le nom du lien se tronque ; le logo reste toujours visible à gauche */
.Link-Nom {
	min-width: 0;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

.Link-span i {
	flex: 0 0 auto;
	color: var(--accent-1);
}

.Link-span:hover {
	background-color: var(--accent-1-a10);
	color: var(--accent-1-clair);
}


/*--------------------------- */
/*------- Responsive -------- */
/*--------------------------- */

/* Sous 1200px, la section n'est plus contrainte en hauteur : la zone de défilement
   montre une ligne de cartes, et les cartes prennent toute la largeur disponible. */
@media (max-width: 1199px) {
	/* Empilées, les cartes prennent la largeur disponible ; la zone de défilement n'est
	   plus adossée à la hauteur d'écran, la section n'étant plus contrainte. */
	/* La largeur des cartes est calculée par script.js (miseEnPageCartes) */
	.Portfolio-Defilement {
		height: auto;
		max-height: 80vh;
	}}

@media (max-width: 767px) {
	.Portfolio-Barre {
		justify-content: flex-start;
	}
	.Filtre-Panneau {
		max-width: min(32rem, 86vw);
	}}




/* ------------------------------------------------------------------------------------------------------------------------------- */
/* ----------------------------------------------------------- Contact ----------------------------------------------------------- */
/* ------------------------------------------------------------------------------------------------------------------------------- */

/* Deux colonnes : l'invitation à gauche, quatre tuiles d'informations à droite.
   Sous 1200px, elles s'empilent. */
.Contact {
	display: grid;
	grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
	gap: var(--espace-7);
	align-items: center;
	width: 100%;
}

.Contact-Principal {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: clamp(var(--espace-4), 4vh, var(--espace-6));
}

/* Le slogan : la seule phrase en police d'affichage de la section, avec un mot en couleur */
.Contact-Slogan {
	margin: 0;
	font-family: var(--police-titre);
	font-size: clamp(2.2rem, 2.9vw, 4.6rem);
	white-space: nowrap;	/* Chaque ligne du slogan tient sur une seule ligne */
	line-height: 1.08;
	letter-spacing: var(--interlettrage-titre);
	text-transform: uppercase;
	text-align: left;
	color: var(--couleur-titre);
}

.Contact-SloganCouleur {
	background: var(--gradient-identité);
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent;
}

.Contact-Accroche {
	margin: 0;
	max-width: 52rem;
	font-size: var(--taille-texte-premier);
	line-height: 1.6;
	text-align: justify;
	color: var(--couleur-texte-doux);
}

.Contact-Actions {
	display: flex;
	flex-wrap: wrap;
	gap: var(--espace-3);
}


/*--------------------------- */
/*--------- Infos ----------- */
/*--------------------------- */

/* Deux lignes discrètes, alignées sur une colonne */
.Contact-Infos {
	display: grid;
	gap: clamp(var(--espace-4), 4.5vh, var(--espace-6));

	margin: 0;
	padding: 0 0 0 var(--espace-5);
	list-style: none;
	border-left: var(--bordure-fine) solid var(--couleur-bordure);
}

.Contact-Infos li {
	display: flex;
	align-items: center;
	gap: var(--espace-3);
}

.Contact-InfoIcone {
	display: flex;
	align-items: center;
	justify-content: center;
	flex: 0 0 auto;

	width: 4rem;
	height: 4rem;

	background-color: var(--couleur-surface-3);
	border: var(--bordure-fine) solid var(--couleur-bordure);
	border-radius: var(--rayon-1);
	color: var(--accent-1);
}

.Contact-InfoTexte {
	display: flex;
	flex-direction: column;
}

.Contact-InfoLien {
	text-decoration: none;
	transition: color var(--duree-courte) var(--courbe);
}

.Contact-InfoLien:hover {
	color: var(--accent-1-clair);
}

.Contact-InfoLibelle {
	font-size: var(--taille-texte-micro);
	letter-spacing: var(--interlettrage-etiquette);
	text-transform: uppercase;
	color: var(--couleur-texte-doux);
}

.Contact-InfoValeur {
	font-size: var(--taille-titre-quatre);
	font-weight: 600;
	color: var(--couleur-titre);
}


/*--------------------------- */
/*------- Responsive -------- */
/*--------------------------- */

@media (max-width: 1199px) {
	.Contact {
		grid-template-columns: 1fr;
		gap: var(--espace-4);
	}}

@media (max-width: 1199px) {
	.Contact-Infos {
		padding: var(--espace-4) 0 0 0;
		border-left: none;
		border-top: var(--bordure-fine) solid var(--couleur-bordure);
	}}

@media (max-width: 600px) {
	/* Sur petit écran, le slogan peut revenir à la ligne */
	.Contact-Slogan {
		white-space: normal;
	}}

.FooterLeft { text-align: left; }
.FooterMiddle { text-align: center; }

.FooterRight {
	display: flex;
	align-items: center;
	justify-content: flex-end;
	gap: var(--espace-2);
}

/* Retour en haut de page : l'ancre suffit, le défilement doux est déjà global */
.FooterHaut {
	display: inline-flex;
	align-items: center;
	text-decoration: none;	/* Le lien soulignait la flèche */

	font-size: 1.8rem;
	color: var(--couleur-texte-doux);

	transition: color var(--duree-courte) var(--courbe),
				transform var(--duree-courte) var(--courbe);
}

.FooterHaut:hover {
	color: var(--accent-1-clair);
	transform: translateY(-2px);
}

/* Sur petit écran, les trois mentions s'empilent et se centrent */
@media (max-width: 767px) {
	.FooterLeft, .FooterMiddle {
		text-align: center;
	}
	.FooterRight {
		justify-content: center;
	}}



/* ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------------ ADAPTATION TÉLÉPHONE ET TABLETTE ---------------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- */

/* Mêmes règles que sur ordinateur, adaptées à la hauteur d'écran de l'appareil :
   - Demo Reel, Services, Contact : un écran utile au minimum ;
   - About : un écran pour la présentation, un autre pour Background (leur contenu empilé peut dépasser) ;
   - Portfolio : une zone de défilement de deux écrans moins l'en-tête.
   Rien ne déborde en largeur : tout se range dans la largeur de l'appareil. */
@media (max-width: 1200px) {

	/* ---- Demo Reel : un écran, lecteur centré entre les onglets et le pied ---- */
	/* Cinq rangées : titre / onglets d'année (centrés entre le titre et le lecteur) / lecteur /
	   outils (collés sous le lecteur) / boutons (au bas de l'écran). L'espace en trop va aux
	   deux rangées souples, il ne s'accumule jamais d'un seul côté. */
	#SectionDemoReel {
		min-height: var(--ecran-utile);
		grid-template-rows: auto minmax(0, 1fr) auto auto minmax(0, 1fr);
		padding-bottom: var(--espace-fin-section);
	}
	.DemoReel-Pied { display: contents; }
	#SectionDemoReel > .SectionTitre { grid-row: 1; }
	.DemoReel-Annees {
		grid-row: 2;
		align-self: center;
		padding-top: 0;
	}
	.ÉcranYoutube {
		grid-row: 3;
		align-self: center;
		width: 100%;
	}
	.DemoReel-Outils {
		grid-row: 4;
		justify-self: center;
		margin-top: var(--espace-4);
		gap: var(--espace-2);
		max-width: 100%;
	}
	.DemoReel-Liens {
		grid-row: 5;
		align-self: end;
		justify-self: center;
		padding-top: var(--espace-4);
		gap: var(--espace-3);
	}

	/* ---- Services : une colonne, rien ne déborde ---- */
	.BioService {
		flex: 0 0 auto;
		align-content: start;
		grid-auto-rows: auto;
		padding: 0;
	}
	.Service-Section {
		min-height: 0;
		padding: var(--espace-4) var(--espace-4) 0;
		row-gap: var(--espace-3);
		align-content: start;
		grid-template-rows: auto auto auto;
	}
	.ServiceIcone { width: 4rem; height: 4rem; }
	.ServiceIcone i { font-size: 1.7rem; }
	.Service-Liste {
		grid-template-columns: 1fr;	/* Une puce par ligne : plus de texte qui passe sous le voisin */
		gap: var(--espace-2);
		padding: var(--espace-3) 0 var(--espace-4);
		align-self: auto;
	}
	.Service-Liste li {
		white-space: normal;
		overflow-wrap: anywhere;
	}
	#SectionServices { min-height: var(--ecran-utile); }

	/* ---- Bandeau de statistiques : centré, espacé ---- */
	.Bandeau-Entete {
		align-items: center;
		text-align: center;
	}
	.Bandeau-Accroche { text-align: center; }
	.Bandeau-Total {
		justify-content: center;
		flex-wrap: wrap;
		text-align: center;
	}
	#tagCountsContainer {
		gap: var(--espace-4) var(--espace-5);
		padding-inline: var(--espace-2);
	}
	.SD-Stats-Container { min-width: 9rem; }

	/* ---- Portfolio : barre de filtres alignée, zone de deux écrans ---- */
	.Portfolio-Barre {
		flex-direction: column;
		align-items: stretch;
		gap: var(--espace-3);
	}
	.Filtres {
		display: grid;
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: var(--espace-2);
		width: 100%;
	}
	.Filtres > * { min-width: 0; }
	/* Nombre impair de filtres : « All » prend la première ligne entière, les autres se rangent par deux */
	.Filtres:has(> :last-child:nth-child(odd)) > :first-child { grid-column: 1 / -1; }
	.Filtre, .Filtre-Groupe > .Filtre {
		width: 100%;
		justify-content: center;
		padding: 1rem var(--espace-2);
	}
	.Filtre-Groupe { width: 100%; }
	.Filtre-Panneau {
		left: 0;
		right: 0;
		width: auto;
		max-width: none;
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
	.Portfolio-Defilement {
		max-height: none;
		margin-inline: 0;
	}
	#SectionPortfolio { padding-bottom: var(--espace-fin-section); }}

/* ---- Téléphones ---- */
@media (max-width: 767px) {
	/* Années de la frise : une pastille propre au-dessus de chaque carte */
	.Frise-Annee {
		display: inline-flex;
		align-items: center;
		justify-content: center;
		width: auto;
		min-width: 5.2rem;
		height: 2.6rem;
		padding: 0 1.2rem;
		margin-bottom: var(--espace-2);
		border-radius: var(--rayon-pilule);
	}
	.Frise-Item { padding-bottom: var(--espace-4); }
	.Frise-Resume {
		min-height: 7.2rem;
		padding: var(--espace-3);
		gap: var(--espace-2);
	}
	.Frise-Etiquettes { flex-wrap: wrap; justify-content: flex-end; max-width: none; }
	.Background-Colonnes { gap: var(--espace-6); }

	/* Contact et pied de page */
	.Contact-Slogan { white-space: normal; }
	.FooterMiddle { order: 1; }
	.FooterRight { order: 2; }
	.FooterLeft { order: 3; font-size: var(--taille-texte-micro); }
	.FooterRight { gap: var(--espace-3); }
	.FooterHaut { font-size: 2.4rem; }}


/* ---- Compléments téléphone : menu, écrans de hauteur, fiche projet, pied de page ---- */
@media (max-width: 1200px) {

	/* About : la présentation (portrait + texte) occupe un écran, son contenu se répartit dedans */
	.Bio {
		min-height: calc(var(--ecran-utile) - var(--hauteur-titre-section));
		justify-content: space-evenly;
		align-items: center;
		gap: var(--espace-5);
		padding-bottom: var(--espace-fin-section);
	}

	/* Contact : avec le pied de page, un écran exactement ; ses blocs se répartissent la hauteur */
	#SectionContact {
		min-height: calc(var(--ecran-utile) - var(--hauteur-pied-mobile));
		padding-bottom: var(--espace-4);
	}
	.Contact {
		flex: 1 1 auto;
		display: flex;
		flex-direction: column;
		justify-content: space-evenly;
		gap: var(--espace-4);
		margin-block: 0;
	}
	.Contact-Principal {
		display: flex;
		flex-direction: column;
		justify-content: space-evenly;
		flex: 1 1 auto;
		gap: var(--espace-4);
	}
	.Contact-Infos { gap: var(--espace-4); }}

@media (max-width: 767px) {

	/* Fiche projet : icône + libellé et valeur sur la même ligne */
	.Projet-Fiche-Ligne {
		grid-template-columns: 11rem minmax(0, 1fr);
		gap: var(--espace-2);
		align-items: baseline;
	}
	.Projet-Fiche dt { grid-template-columns: 2rem minmax(0, 1fr); font-size: var(--taille-texte-micro); }
	.BestWorks-Icon { display: flex; justify-content: center; }
	.FooterRight { gap: var(--espace-2); }
	.FooterHaut { font-size: 1.8rem; }
	.FooterLeft { }}

@media (max-width: 767px) {

	/* Demo Reel : années plus espacées, outils décollés de la vidéo et sur deux lignes aérées */
	.DemoReel-Annees { gap: var(--espace-4); }
	.DemoReel-Outils {
		margin-top: clamp(var(--espace-5), 5vh, 6rem);
		gap: var(--espace-4) var(--espace-3);
	}}



/* ---- Petits écrans : About sur un écran, Background plus compact, Contact centré, accueil aéré ---- */
@media (max-width: 1200px) {
	.BioMiddle p { text-align: justify; hyphens: auto; }
	.BioMiddle-Right { width: 100%; }}

@media (max-width: 767px) {
	/* About : portrait, nom, texte et CV tiennent avec le titre dans un écran (tailles liées à la hauteur) */
	.BioLeft { --portrait-hauteur: clamp(14.5rem, 35vh, 32rem); --portrait-largeur: calc(var(--portrait-hauteur) * 0.8); }
	.Bio { gap: var(--espace-3); justify-content: space-evenly; padding-bottom: var(--espace-fin-section); }
	.BioMiddle { gap: clamp(0.8rem, 1.3vh, 1.4rem); }
	.BioMiddle h3 { font-size: clamp(1.8rem, 2.6vh, 2.4rem); text-align: center; align-self: center; }
	.BioMiddle p { font-size: clamp(1.2rem, 1.75vh, 1.5rem); line-height: 1.5; }
	.BioMiddle .Bio-Accroche { font-size: clamp(1.3rem, 1.9vh, 1.6rem); }
	.Bio-CV { justify-content: center; margin-top: 0; align-self: center; }

	/* Background : l'année devient une étiquette posée sur le bord haut de la carte (gain de hauteur) */
	.Frise-Item { position: relative; padding-top: 1.3rem; padding-bottom: var(--espace-3); }
	.Frise-Annee {
		position: absolute;
		top: 0;
		left: var(--espace-4);
		z-index: 2;
		margin: 0;
		height: 2.6rem;
		background-color: var(--couleur-surface-1);
	}
	.Frise-Item--encours .Frise-Annee { background-color: var(--accent-1); }
	.Frise-Resume { padding-top: calc(var(--espace-3) + 0.6rem); }

	/* Demo Reel : les années au centre exact entre le titre et le lecteur ; les outils au centre exact
	   entre le lecteur et les boutons. Chaque rangée souple reçoit la même part d'espace libre. */
	#SectionDemoReel { grid-template-rows: auto minmax(0, 1fr) auto minmax(0, 1fr) auto; }
	#SectionDemoReel > .SectionTitre { padding-bottom: 0; }
	.DemoReel-Annees { grid-row: 2; align-self: center; margin: 0; }
	.DemoReel-Outils { grid-row: 4; align-self: center; margin-top: 0; }
	.DemoReel-Liens { grid-row: 5; align-self: end; padding-top: 0; }

	/* Contact : réseaux sociaux et bouton centrés, comme le bloc des informations */
	.Contact-Principal { align-items: center; }
	.Contact-Principal > .Contact-Slogan, .Contact-Principal > .Contact-Accroche { align-self: stretch; }}

/* Petit écran / tactile : la barre de défilement du Portfolio reste visible en permanence.
   Les barres « flottantes » des téléphones disparaissent dès qu'on cesse de défiler ; en stylant la
   barre WebKit (et en retirant les propriétés standard, qui la désactiveraient), elle devient fixe. */
@media (max-width: 1200px) {
	.Portfolio-Defilement {
		scrollbar-width: auto;
		scrollbar-color: auto;
	}
	.Portfolio-Defilement::-webkit-scrollbar {
		width: 4px;
	}
	.Portfolio-Defilement::-webkit-scrollbar-track {
		background: var(--couleur-surface-2);
		border-radius: var(--rayon-pilule);
	}
	.Portfolio-Defilement::-webkit-scrollbar-thumb {
		background: var(--accent-1);
		border-radius: var(--rayon-pilule);
	}}

/* Sans souris, :hover reste « collé » après un toucher : un filtre relâché gardait sa couleur de survol.
   Sur ces appareils, le survol n'est donc jamais affiché ; seul l'état actif colore le filtre. */
@media (hover: none) {
	.Filtre:hover:not(.Filtre--actif):not(.Filtre--parentActif) {
		background-color: var(--couleur-surface-2);
		border-color: var(--couleur-bordure);
		color: var(--couleur-texte);
	}
	.Filtre--sous:hover:not(.Filtre--actif) {
		background-color: var(--couleur-surface-3);
		border-color: var(--couleur-bordure);
		color: var(--couleur-texte);
	}
	.Filtre--sous:hover:not(.Filtre--actif) .Filtre-Compte { color: var(--accent-2); font-weight: 400; }}

@media (max-width: 1200px) {
	/* Le panneau s'ouvre sur toute la largeur de la barre (et non celle de son petit bouton) */
	.Filtre-Groupe { position: static; }
	.Portfolio-Barre { position: relative; }
	.Filtre-Panneau {
		top: calc(100% + 0.6rem);
		left: 0;
		right: 0;
		width: auto;
		padding: var(--espace-2);
		gap: var(--espace-2);
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
	.Filtre--sous {
		min-width: 0;
		padding: 0.9rem var(--espace-3);
		justify-content: space-between;
		gap: var(--espace-1);
	}
	.Filtre--sous .Filtre-Nom { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }}


/* Croix de fermeture du panneau de sous-filtres : seulement sur petit écran */
.Filtre-Fermer { display: none; }

@media (max-width: 1200px) {
	/* Bouton « Close » pleine largeur au bas du panneau : facile à atteindre au pouce, hors de la grille de filtres */
	.Filtre-Fermer {
		display: inline-flex;
		align-items: center;
		justify-content: center;
		gap: var(--espace-2);
		order: 99;
		grid-column: 1 / -1;
		width: 100%;
		height: 4rem;
		margin-top: var(--espace-1);
		padding: 0;

		background-color: transparent;
		border: var(--bordure-fine) solid var(--couleur-bordure-forte);
		border-radius: var(--rayon-pilule);
		color: var(--couleur-texte-doux);
		font-family: var(--police-texte);
		font-size: var(--taille-texte-micro);
		letter-spacing: 0.1em;
		text-transform: uppercase;
		cursor: var(--curseur-lien);
	}
	.Filtre-Fermer::after { content: "Close"; }
	.Filtre-Fermer:active { background-color: var(--accent-1); color: #0a0a0c; }}

/* Contact sur petit écran : marges latérales plus confortables (le texte était collé au bord gauche) */
@media (max-width: 767px) {
	#SectionContact {
		padding-inline: var(--espace-4);
	}
	.Contact, .Contact-Principal { gap: var(--espace-3); }
	.Contact-Infos { gap: var(--espace-3); }
	.Contact-Infos li { padding-block: 0; }}

/* ---- Tablette (768 à 1200 px) : mêmes principes que le téléphone, bloc centré et plus large ---- */
@media (min-width: 768px) and (max-width: 1200px) {
	/* Demo Reel : années et outils centrés dans leur espace, plus écartés ; outils sur deux lignes aérées */
	#SectionDemoReel { grid-template-rows: auto minmax(0, 1fr) auto minmax(0, 1fr) auto; }
	#SectionDemoReel > .SectionTitre { padding-bottom: 0; }
	.DemoReel-Annees { grid-row: 2; align-self: center; margin: 0; gap: var(--espace-5); }
	.DemoReel-Outils {
		grid-row: 4;
		align-self: center;
		margin-top: 0;
		max-width: 100%;	/* La largeur de répartition est posée par le script (equilibrerLignes) */
		gap: var(--espace-4) var(--espace-5);
	}
	.DemoReel-Liens { grid-row: 5; align-self: end; padding-top: 0; gap: var(--espace-4); }

	/* Contact : colonne centrée de largeur raisonnable, réseaux et bouton au centre */
	.Contact {
		width: 100%;
		max-width: 64rem;
		margin-inline: auto;
	}
	.Contact-Principal { align-items: center; }
	.Contact-Principal > .Contact-Slogan,
	.Contact-Principal > .Contact-Accroche { align-self: stretch; }
	.Contact-Infos { align-self: center; }}


/* Très petits écrans : puces d'outils plus compactes pour qu'au moins trois tiennent sur une ligne */
@media (max-width: 350px) {
	.DemoReel-Outil { padding: 0.4rem 0.8rem; gap: 0.5rem; letter-spacing: 0.02em; }
	.DemoReel-Outil img { width: 1.6rem; height: 1.6rem; }
	.DemoReel-Outils { gap: var(--espace-3) var(--espace-2); }}


/* Les outils du Demo Reel sont des liens vers le Portfolio filtré : même réaction que les autres petits éléments cliquables (bleu) */
a.DemoReel-Outil {
	text-decoration: none;
	cursor: var(--curseur-lien);
	transition: border-color var(--duree-courte) var(--courbe), color var(--duree-courte) var(--courbe), background-color var(--duree-courte) var(--courbe);
}

a.DemoReel-Outil:hover,
a.DemoReel-Outil:focus-visible {
	border-color: var(--accent-1);
	background-color: var(--accent-1-a10);
	color: var(--accent-1-clair);
}

/* ---- Tablette : pied de page empilé et centré, Services plus compact ---- */
@media (min-width: 768px) and (max-width: 1200px) {
	.FooterMiddle { order: 1; }
	.FooterRight { order: 2; justify-content: center; gap: var(--espace-3); }
	.FooterLeft { order: 3; text-align: center; font-size: var(--taille-texte-micro); }

	/* Services : deux colonnes, cartes compactes pour tenir (si possible) dans un écran */
	#SectionServices { min-height: var(--ecran-utile); }
	.BioService { --services-colonnes: 2; gap: var(--espace-3); }
	.Service-Section { padding: var(--espace-3) var(--espace-4) 0; row-gap: var(--espace-2); }
	.Service-Section p { font-size: var(--taille-texte-meta); line-height: 1.4; }
	.ServiceIcone { width: 3.6rem; height: 3.6rem; }
	.Service-Liste {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: var(--espace-1) var(--espace-2);
		padding: var(--espace-2) 0 var(--espace-3);
		font-size: var(--taille-texte-micro);
	}
	.Service-Liste li { white-space: normal; padding-left: 1.4rem; }}

/* Zone de défilement : au moins la hauteur d'une carte entière (image 16/9 + informations), pour que la
   première ligne soit toujours complètement visible ; la section s'allonge si l'écran est trop bas. */
.Portfolio-Defilement {
	height: max(var(--portfolio-defilement), calc(var(--carte-largeur) * 9 / 16 + var(--carte-infos) + 3.6rem));
}

/* Fermeture animée des panneaux de sous-filtres (voir definirPanneau) */
.Filtre-Panneau--sortie {
	animation: panneau-fermeture 0.18s var(--courbe) forwards;
	pointer-events: none;
}

/* Pied de page tablette : copyright centré sur la première ligne ; date à gauche et « Created by » + flèche à droite sur la seconde */
@media (min-width: 768px) and (max-width: 1200px) {
	.FooterMiddle { grid-area: centre; order: 0; text-align: center; }
	.FooterLeft { grid-area: gauche; order: 0; text-align: left; font-size: var(--taille-texte-meta); }
	.FooterRight { grid-area: droite; order: 0; justify-content: flex-end; }
	.FooterMiddle, .FooterLeft, .FooterRight { white-space: nowrap; }}

/* ---- Tablette et téléphone : cartes réduites à leur image, défilement latéral par « pack » ---- */
@media (max-width: 1200px) {
	.Portfolio-Defilement {
		height: auto;
		overflow-x: auto;
		overflow-y: hidden;
		scroll-snap-type: x mandatory;
		overscroll-behavior-x: contain;
		padding-bottom: var(--espace-3);
	}
	.PortfolioContainerProjets {
		display: grid;
		grid-auto-flow: column;	/* Remplit les lignes de haut en bas, puis passe à la colonne suivante */
		grid-template-rows: repeat(var(--lignes, 1), auto);
		grid-auto-columns: var(--carte-w, clamp(26rem, 42vw, 40rem));	/* Taille posée par majLignesCompactes selon la hauteur disponible */
		align-items: start;
		gap: var(--ecart-v, var(--espace-3)) var(--ecart-h, var(--espace-4));
		height: auto !important;
		max-width: none !important;
		margin-inline: 0 !important;
		width: max-content;
	}
	.PortfolioContainerProjets .SectionWorks {
		position: relative !important;	/* Cadre du contenu qui se superpose à l'image */
		left: auto !important;
		top: auto !important;
		transform: none !important;
		width: auto;
		margin-bottom: 0;
		scroll-snap-align: start;
	}
	.Portfolio-Defilement::-webkit-scrollbar { height: 4px; width: auto; }

	/* Pas d'animation d'entrée par rangée dans ce mode */
	.Carte-Attente { visibility: visible; }
	.Carte-Apparue { animation: none; }

	/* La carte est son image : date et étoile dessus, titre en bas */
	.Carte-Visuel { cursor: var(--curseur-lien); border-radius: calc(var(--rayon-2) - var(--bordure-fine)); }
	.Carte-Visuel::after { background: linear-gradient(to bottom, rgba(10,10,12,0.25) 0%, rgba(10,10,12,0) 35%, rgba(10,10,12,0.88) 100%); }
	.Carte-TitreImage {
		position: absolute;
		left: var(--espace-3);
		right: var(--espace-3);
		bottom: var(--espace-2);
		z-index: 2;
		margin: 0;
		font-size: clamp(1.1rem, calc(var(--carte-w, 300px) / 24), 2.4rem);	/* Suit la taille de la carte */
		line-height: 1.2;
		text-align: left;
		color: var(--couleur-titre);
		text-shadow: 0 1px 6px rgba(0,0,0,0.8);
		-webkit-text-stroke: 0.4rem rgba(0, 0, 0, 0.95);
		paint-order: stroke fill;	/* Contour noir derrière les lettres */
		pointer-events: none;
		transition: opacity 0.25s var(--courbe);
	}

	/* Au clic, tout le contenu passe SUR l'image, voilée et légèrement floutée pour que le texte reste lisible.
	   Toujours présent mais transparent : l'ouverture et la fermeture sont des fondus. */
	.SectionWorks .Carte-Infos {
		position: absolute;
		inset: 0;
		z-index: 3;

		height: auto;
		gap: 0.6rem;
		padding: 1rem var(--espace-3);
		overflow: hidden;

		background-color: rgba(0, 0, 0, 0.8);	/* Filtre noir : le texte ressort sur n'importe quelle image */
		-webkit-backdrop-filter: blur(2px);
		backdrop-filter: blur(2px);
		border-radius: calc(var(--rayon-2) - var(--bordure-fine));

		opacity: 0;
		visibility: hidden;
		pointer-events: none;
		transition: opacity 0.25s var(--courbe), visibility 0s linear 0.25s;
	}

	/* Contenu resserré : la place est celle de l'image */
	/* Le texte grandit avec la carte : une grande carte (iPad Pro) ne porte plus un texte minuscule */
	.SectionWorks .Carte-Infos { font-size: clamp(1.3rem, calc(var(--carte-w, 300px) / 34), 2.2rem); }
	.Carte-Infos .Carte-Tags { height: 2.4em; justify-content: flex-start; }
	.Carte-Infos .Carte-Tag { font-size: 0.85em; }
	.Carte-Infos .Carte-Titre { font-size: 1.2em; }
	/* Le synopsis est coupé par « … » à la dernière ligne qui tient (nombre posé par ajusterDescriptions) :
	   le texte ne dépasse jamais de la carte et ne défile pas. */
	.Carte-Infos > .Carte-Description {
		display: -webkit-box;
		-webkit-box-orient: vertical;
		-webkit-line-clamp: var(--lignes-desc, 99);
		line-clamp: var(--lignes-desc, 99);
		overflow: hidden;
		font-size: 1em;
		line-height: 1.4;
	}
	.Carte-Infos.Infos-Sans-Meta .Carte-Meta, .Carte-Infos.Infos-Sans-Tags .Carte-Tags { display: none; }
	.Carte-Infos .Carte-Meta-Ligne { font-size: 0.95em; grid-template-columns: 2.4em minmax(0, 1fr); }
	.Carte-Infos .Carte-Lien, .Carte-Infos .Link-DropDown-Menu-Btn { font-size: 0.9em; }
	.Carte-Infos .Carte-Meta { margin: 0; padding-top: var(--espace-1); }
	.Carte-Infos > .Carte-Description { color: var(--couleur-texte); }


	/* Plus de flash bleu du navigateur au toucher, ni de cadre de focus sur la carte */
	.SectionWorks, .Carte-Visuel, .Carte-Infos { -webkit-tap-highlight-color: transparent; }
	.SectionWorks:focus, .Carte-Visuel:focus, .Carte-Infos:focus { outline: none; }
	.Link-DropDown-Menu-Content { max-height: max(9rem, calc(var(--carte-h, 24rem) - 7rem)); }}


/* Compact : les cartes se centrent verticalement dans la place restante de la section (pas de grand vide en dessous) */
@media (max-width: 1200px) {
	#SectionPortfolio { display: flex; flex-direction: column; }
	#SectionPortfolio .Portfolio-Defilement { margin-block: auto; }}

/* Textes justifiés, sur toutes les plateformes : descriptions des services et des cartes du Portfolio.
   Les coupures de mots (lang="en") évitent les grands trous entre les mots sur les colonnes étroites. */
.Service-Section p,
.Carte-Description {
	text-align: justify;
	text-justify: inter-word;
	hyphens: auto;
	-webkit-hyphens: auto;
}


/* Slick 1.8.1 (feuille de base du carrousel), copiée ici : une requête externe de moins avant l'affichage.
   Placée en dernier, comme l'ancienne balise <link> qui suivait style.css. */
.slick-slider{position:relative;display:block;box-sizing:border-box;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-touch-callout:none;-khtml-user-select:none;-ms-touch-action:pan-y;touch-action:pan-y;-webkit-tap-highlight-color:transparent}.slick-list{position:relative;display:block;overflow:hidden;margin:0;padding:0}.slick-list:focus{outline:0}.slick-list.dragging{cursor:pointer;cursor:hand}.slick-slider .slick-list,.slick-slider .slick-track{-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);-o-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.slick-track{position:relative;top:0;left:0;display:block;margin-left:auto;margin-right:auto}.slick-track:after,.slick-track:before{display:table;content:''}.slick-track:after{clear:both}.slick-loading .slick-track{visibility:hidden}.slick-slide{display:none;float:left;height:100%;min-height:1px}[dir=rtl] .slick-slide{float:right}.slick-slide img{display:block}.slick-slide.slick-loading img{display:none}.slick-slide.dragging img{pointer-events:none}.slick-initialized .slick-slide{display:block}.slick-loading .slick-slide{visibility:hidden}.slick-vertical .slick-slide{display:block;height:auto;border:1px solid transparent}.slick-arrow.slick-hidden{display:none}


/* Flèches internes et écrans multiples ---------------------------------------------------------------------------- */

/* Flèche entre deux écrans d'une même section : autre couleur (accent 2), à droite, une chevron lente. Elle loge dans
   la zone de fin d'écran déjà réservée. */
.Bio, .Background, .Background-Colonne { position: relative; }
.FlecheInterne {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	z-index: 2;

	display: flex;
	align-items: center;
	justify-content: center;
	height: var(--espace-fin-section);
	padding: 0;
	text-decoration: none;
}
.FlecheInterne[hidden] { display: none; }
.FlecheInterne .Flèche span {
	width: 0.9rem;
	height: 0.9rem;
	border-width: 0 0.3rem 0.3rem 0;
	border-color: var(--accent-2);
	animation: FlecheInterne 3.4s ease-in-out infinite;
}

/* Background : un écran si tout tient, sinon Experience puis Education, un écran chacun */
.Background--separe { min-height: 0; padding-bottom: 0; }
.Background--separe .Background-Colonnes { grid-template-columns: minmax(0, 1fr); gap: 0; max-width: 64rem; margin: 0 auto; }
.Background--separe .Background-Colonne { min-height: var(--ecran-utile); padding-bottom: var(--espace-fin-section); }
.Background--separe .Background-Colonne:first-child { min-height: calc(var(--ecran-utile) - var(--haut-bg, 0px)); }
.Background--separe .Background-Colonne:last-child { padding-top: var(--ecart-titre-contenu); }

/* Best Projects : un écran par projet, centré, la flèche en bas de chaque écran (même rangée que son projet) */
.Ecrans--separes {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	grid-template-rows: minmax(calc(var(--ecran-utile) - var(--haut-titre, 0px)), auto);
	grid-auto-rows: minmax(var(--ecran-utile), auto);
	gap: 0;
}
.Ecrans--separes > * { grid-column: 1; }
.Ecrans--separes > .SectionBestWorks { align-self: center; }
/* Chaque projet réserve en bas la zone de la flèche (celle de fin de section pour le dernier) : la section fait
   alors exactement un nombre entier d'écrans, sans marge de plus */
#SectionBestProjects.Ecrans--section { padding-bottom: 0; }
.Ecrans--separes > .SectionBestWorks { margin-bottom: var(--espace-fin-section); }
.Ecrans--separes > .FlecheInterne { position: relative; left: auto; right: auto; bottom: auto; align-self: end; justify-self: stretch; }

/* Repère sans hauteur, en haut de la rangée d'un projet : cible des flèches (voir initEcransProjets) */
.RepereEcran { align-self: start; height: 0; pointer-events: none; }

/* Un écran par colonne : les cartes gardent leur taille et s'espacent verticalement sur toute la hauteur de l'écran */
.Background--separe .Frise { justify-content: space-between; }

/* Services : à plat, les groupes de trois disparaissent (la grille voit les six cartes). Si ça ne tient pas dans un
   écran, chaque groupe devient un écran : cartes réparties dans sa hauteur, flèche en bas. */
.Services-Groupe { display: contents; }
.BioService.Ecrans--separes { display: block; padding: 0; }
.BioService.Ecrans--separes > .Services-Groupe {
	position: relative;
	display: grid;
	grid-template-columns: repeat(var(--services-colonnes), minmax(0, 1fr));
	align-content: space-evenly;
	gap: var(--espace-3);
	padding-bottom: var(--espace-fin-section);
}
.BioService.Ecrans--separes .Service-Section { min-height: 0; }
#SectionServices.Ecrans--section { padding-bottom: 0; }
@media (min-width: 1000px) {
	.BioService.Ecrans--separes > .Services-Groupe { grid-template-columns: repeat(3, minmax(0, 1fr)); }}
.BioService.Ecrans--separes > .Services-Groupe > .RepereEcran { position: absolute; top: 0; grid-column: auto; }
.BioService:not(.Ecrans--separes) .RepereEcran { display: none; }

/* Pied de page sur téléphone, comme sur tablette : le copyright centré en haut ; dessous, la date au bord gauche et
   « Created by » avec sa flèche au bord droit (la flèche dans le coin), le plus écartés possible. */
@media (max-width: 767px) {
	.FooterMiddle { order: 1; flex: 1 1 100%; text-align: center; white-space: normal; }
	.FooterLeft { order: 2; text-align: left; }
	.FooterRight { order: 3; display: flex; align-items: center; justify-content: flex-end; gap: var(--espace-2); }
	.FooterHaut { font-size: 1.8rem; }}

/* Services, un écran par groupe sur petit écran : cartes compactes pour que trois tiennent ensemble */
@media (max-width: 767px) {
	.BioService.Ecrans--separes .Service-Section { padding: var(--espace-2) var(--espace-3) 0; row-gap: var(--espace-1); }
	.BioService.Ecrans--separes .ServiceIcone { width: 3.6rem; height: 3.6rem; }
	.BioService.Ecrans--separes .Service-Section p { font-size: var(--taille-texte-meta); line-height: 1.6; }
	.BioService.Ecrans--separes .Service-Liste {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: 0.3rem var(--espace-2);
		padding-block: var(--espace-2);
		font-size: var(--taille-texte-meta);
	}
	.BioService.Ecrans--separes .Service-Liste li { white-space: normal; padding-left: 1.4rem; }}	/* Suit la largeur sur téléphone : date et « Created by » tiennent sur une ligne */

/* Cartes un peu plus hautes quand l'écran a de la place (--extra, posée par script.js) : le reste devient des écarts */
.Background--separe .Frise-Resume { min-height: calc(7.2rem + var(--extra, 0px)); }
/* La place en plus se répartit dans la carte : un quart au-dessus du titre, un quart sous la liste, et le reste entre le
   titre, la description et la liste (un quart à chaque écart) */
.BioService.Ecrans--separes .Service-Section { padding-top: calc(var(--espace-2) + var(--extra, 0px) / 5); row-gap: calc(var(--espace-1) + var(--extra, 0px) / 4); }
.BioService.Ecrans--separes .Service-Liste { padding-bottom: calc(var(--espace-2) + var(--extra, 0px) * 0.3); }
.Ecrans--separes > .SectionBestWorks { padding-block: calc(var(--espace-5) * 0.55 + var(--extra, 0px) / 4); }
@media (max-width: 1199px) {
	.Ecrans--separes > .SectionBestWorks { padding-block: calc(var(--espace-3) * 0.55 + var(--extra, 0px) / 4); }}

/* Tablette : même disposition que sur téléphone (média au-dessus, fiche dessous), mais le média est un peu plus étroit
   et les écarts réduits, pour que la carte tienne dans son écran */
@media (min-width: 700px) and (max-width: 1199px) {
	.Ecrans--separes > .SectionBestWorks { gap: var(--espace-3); }
	.Ecrans--separes > .SectionBestWorks .SectionBestWorks-Informations-Left { width: var(--media-largeur, 64%); margin-inline: auto; }}

/* Description et liste alignées d'une carte à l'autre dans une même rangée (hauteurs posées par script.js) */
.Service-Section p { min-height: var(--desc-h, 0); }
.Service-Liste { min-height: var(--liste-h, 0); }
.Service-Liste { align-content: start; }

/* Best Projects : paliers de compaction quand un projet ne tient pas dans son écran (posés par script.js).
   On resserre d'abord les écarts, puis on limite le texte, et en dernier recours on retire les miniatures :
   la vidéo, elle, garde toute sa largeur. */
.Ecrans--separes > .Compact-1,
.Ecrans--separes > .Compact-2,
.Ecrans--separes > .Compact-3 { gap: var(--espace-2); }
.Ecrans--separes > .Compact-1 .SectionBestWorks-Informations-Right,
.Ecrans--separes > .Compact-2 .SectionBestWorks-Informations-Right,
.Ecrans--separes > .Compact-3 .SectionBestWorks-Informations-Right { gap: var(--espace-2); }
.Ecrans--separes > .Compact-1 .Projet-Fiche,
.Ecrans--separes > .Compact-2 .Projet-Fiche,
.Ecrans--separes > .Compact-3 .Projet-Fiche { gap: var(--espace-2); padding-top: var(--espace-3); }
.Ecrans--separes > .Compact-2 .Projet-Description,
.Ecrans--separes > .Compact-3 .Projet-Description {
	display: -webkit-box;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: 3;
	overflow: hidden;
}
.Ecrans--separes > .Compact-3 .video-thumbnails .slick-slide img { width: 7rem; }	/* Les miniatures restent, en plus petit */
/* Dernier palier (petit téléphone) : description sur deux lignes, marges et écarts resserrés, titre de section plus court */
.Ecrans--separes > .Compact-4 { padding: var(--espace-3); gap: var(--espace-1); }
.Ecrans--separes > .Compact-4 .Projet-Description { -webkit-line-clamp: 2; }
.Ecrans--separes > .Compact-4 .SectionBestWorks-Informations-Right { gap: var(--espace-1); }
.Ecrans--separes > .Compact-4 .Projet-Fiche { gap: var(--espace-1); padding-top: var(--espace-2); }
.Ecrans--separes > .Compact-4 .Projet-Entete { gap: var(--espace-1); }
.Ecrans--separes > .Compact-4 .Projet-Fiche-Ligne:nth-child(n+2) { display: none; }	/* Tâches et clients sont dans la fiche détaillée */
@media (max-width: 767px) and (max-height: 700px) {
	#SectionBestProjects .SectionTitre { padding-top: var(--espace-4); padding-bottom: var(--espace-3); }}

/* Chaque écran d'About est autonome (la présentation porte déjà son vide de fin) : pas de marge en plus devant le Background */
@media (max-width: 1199px) {
	.Background { margin-top: 0; }}

/* Téléphone étroit : l'étiquette (Training, Conservatory...) passe sous le texte, qui garde toute la largeur
   et ne se coupe plus en mots isolés */
@media (max-width: 480px) {
	.Frise-Resume {
		display: grid;
		grid-template-columns: auto minmax(0, 1fr) auto;
		grid-template-areas: "icone texte chev" ". etiq chev";
		align-items: center;
		align-content: center;	/* Le contenu reste centré dans la carte, même agrandie */
		column-gap: var(--espace-2);
		row-gap: 0;
	}
	.Frise-Icone { grid-area: icone; }
	.Frise-Texte { grid-area: texte; }
	.Frise-Etiquettes { grid-area: etiq; justify-content: flex-start; margin-top: var(--espace-1); }
	.Frise-Chevron { grid-area: chev; }}

/* Services : la place en plus s'ajoute aussi entre les points de la liste (un sixième du surplus, plafonné), et les trois blocs (titre,
   description, liste) sont moins marqués : filet plus doux, écarts plus réguliers */
.BioService .Service-Liste { row-gap: clamp(0.5rem, 1vh, 1rem); border-top-color: color-mix(in srgb, var(--couleur-bordure) 45%, transparent); }
.BioService.Ecrans--separes .Service-Liste { row-gap: 0.5rem; }

/* Background : dans une carte agrandie, les lignes de texte s'espacent aussi */
.Background--separe .Frise-Texte { display: flex; flex-direction: column; gap: calc(0.2rem + var(--extra, 0px) / 8); }
@media (max-width: 480px) {
	.Background--separe .Frise-Etiquettes { margin-top: calc(var(--espace-1) + var(--extra, 0px) / 8); }}

/* Frise : un point au bout du rail, comme une fin de ligne de temps */
.Frise::after {
	content: "";
	position: absolute;
	left: calc(var(--rail) - 3px);
	bottom: calc(1.4rem - 4px);
	width: 8px;
	height: 8px;
	border-radius: 50%;
	background-color: var(--couleur-bordure-forte);
}

/* Téléphone : le rail gris revient, derrière les cartes (visible entre elles) et les pastilles d'année, et se termine
   par son point sous la dernière carte */
@media (max-width: 767px) {
	.Frise { --rail: calc(var(--espace-4) + 2.6rem); }
	.Frise::before { display: block; top: 1.3rem; bottom: -1.2rem; }
	.Frise::after { bottom: calc(-1.2rem - 4px); }
	.Frise-Annee { width: 5.2rem; padding-inline: 0; justify-content: center; }}

/* Pointe de flèche tout en haut du rail : la frise se lit du plus récent (en haut) au plus ancien */
.Frise-Item:first-child::before {
	content: "";
	position: absolute;
	top: 0.55rem;
	left: calc(-1 * (var(--pastille) / 2 + var(--espace-3)) + 1px - 0.55rem);
	width: 1.1rem;
	height: 1.1rem;
	border-top: 2px solid var(--couleur-bordure-forte);
	border-left: 2px solid var(--couleur-bordure-forte);
	rotate: 45deg;
}
@media (max-width: 767px) {
	/* Même distance (2,6rem) avant la première carte, où s'élève la pointe, et après la dernière, où s'arrête le point */
	.Frise { padding-block: 2.6rem; }
	.Frise::before { top: 0.5rem; bottom: 0.1rem; }
	.Frise::after { bottom: calc(0.1rem - 4px); }
	.Frise-Item:first-child::before { top: -2.4rem; left: calc(var(--rail) + 1px - 0.55rem); }}

/* Tablette et ordinateur : même distance (2,6rem) avant la première carte, où s'élève la pointe du rail, et après la
   dernière, où s'arrête son point ; la pastille d'année est centrée sur sa carte (le bas de l'entrée est l'écart
   avant la suivante, il n'en fait pas partie) */
.Frise-Item { --ecart-item: var(--ecart-entrees); padding-bottom: var(--ecart-item); }
.Frise-Item:last-child { --ecart-item: 0px; }
@media (max-width: 1199px) { .Frise-Item { --ecart-item: var(--espace-4); } .Frise-Item:last-child { --ecart-item: 0px; }}
@media (min-width: 768px) {
	.Frise { padding-block: 2.6rem; }
	.Frise::before { top: 0.5rem; bottom: 0.1rem; }
	.Frise::after { bottom: calc(0.1rem - 4px); }
	.Frise-Item:first-child::before { top: -2.4rem; }
	.Frise-Annee { top: calc(50% - var(--ecart-item) / 2); translate: 0 -50%; }}

/* Liens boutique (itch, Steam...) centrés sous la fiche sur tablette comme sur téléphone */
@media (max-width: 1199px) {
	.BestWorks-Icon { display: flex; justify-content: center; }}

/* Background en un écran par colonne : l'icône et le texte des cartes grandissent un peu avec la place disponible */
.Background--separe .Frise-Icone { width: calc(3.4rem + var(--extra, 0px) / 8); height: calc(3.4rem + var(--extra, 0px) / 8); }
.Background--separe .Frise-Icone i { font-size: calc(1.4rem + var(--extra, 0px) / 24); }
.Background--separe .Frise-Organisation { font-size: calc(var(--taille-texte-second) + var(--extra, 0px) / 14); }
.Background--separe .Frise-Intitule { font-size: calc(var(--taille-texte-second) + var(--extra, 0px) / 14); }

/* Services en un seul écran : la place en plus est répartie dans chaque carte (un quart au-dessus du titre, un sixième
   avant la description, un sixième avant la liste, un quart sous la liste, le reste entre les points) : plus de vide en bas */
.BioService:not(.Ecrans--separes) .Service-Section > .ServiceIcone,
.BioService:not(.Ecrans--separes) .Service-Section > h3 { margin-top: calc(var(--extra, 0px) / 5); }
.BioService:not(.Ecrans--separes) .Service-Section > p { margin-top: calc(var(--extra, 0px) / 4); }
.BioService:not(.Ecrans--separes) .Service-Section > .Service-Liste {
	margin-top: calc(var(--extra, 0px) / 4);
	padding-bottom: calc(clamp(0.8rem, 1.8vh, 2.4rem) + var(--extra, 0px) * 0.3);
}

/* Description des services : interligne plus aéré, sur tous les formats */
.Service-Section p { line-height: 1.7; }
.BioService.Ecrans--separes .Service-Section p { line-height: 1.7; }

/* Le portrait d'About rétrécit si la présentation dépasse son écran (posé par script.js) */
.Bio .BioLeft { zoom: var(--echelle-portrait, 1); }

/* Ordinateur : un projet sur deux inverse ses colonnes ; le média garde la même largeur dans les deux cas (1,1fr) */
@media (min-width: 1200px) {
	.BestProjectsContainerProjets > .SectionBestWorks:nth-child(even) { grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr); }}

/* Fiche projet : date, tâches et clients plus rapprochés, et un peu moins d'écart entre les blocs de la colonne de droite */
.Projet-Fiche { gap: var(--espace-2); padding-top: var(--espace-3); }
.SectionBestWorks-Informations-Right { gap: var(--espace-3); }

/* Hors écran : les animations en boucle sont suspendues (posé par initPauseHorsEcran). Moins de dessin continu, donc
   plus de fluidité sur les PC modestes. */
.Hors-Ecran, .Hors-Ecran *, .Hors-Ecran::before, .Hors-Ecran::after, .Hors-Ecran *::before, .Hors-Ecran *::after {
	animation-play-state: paused !important;
}
.Leger-3 .videoWrapper.inactive { filter: none; opacity: 0.55; }

/* Contact sur grand écran : chaque colonne est centrée dans sa moitié, le vide se répartit des deux côtés de chacune
   au lieu de se concentrer entre le texte collé à gauche et les tuiles. */
@media (min-width: 1201px) {
	.Contact { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
	.Contact-Principal { justify-self: center; }
	.Contact-Infos { justify-self: center; }}

/* Best Projects sur grand écran : la colonne d'informations prend toute la hauteur de la carte et ses blocs (titre, étiquettes,
   texte, fiche, lien) s'espacent régulièrement, au lieu de former un bloc compact centré avec du vide autour. */
@media (min-width: 1200px) {
	.SectionBestWorks { align-items: stretch; }
	.SectionBestWorks-Informations-Left { align-self: center; }
	.SectionBestWorks-Informations-Left { align-self: center; }
	.SectionBestWorks-Informations-Right { justify-content: space-between; }}

/* Best Projects sur grand écran : la place libre de la colonne d'informations (mesurée par aererProjets dans script.js)
   sert d'abord à aérer l'intérieur de chaque bloc (titre et étiquettes, lignes du synopsis, lignes de la fiche), puis
   le reste s'ajoute entre les blocs : un ensemble lié, pas trois blocs séparés par du vide. */
@media (min-width: 1200px) {
	.SectionBestWorks .Projet-Entete { gap: calc(var(--espace-3) + var(--air-entete, 0px)); }
	.SectionBestWorks .Projet-Description { line-height: calc(1.5em + var(--air-texte, 0px)); }
	.SectionBestWorks .Projet-Fiche { gap: calc(var(--espace-2) + var(--air-fiche, 0px)); padding-top: calc(var(--espace-3) + var(--air-fiche, 0px)); }}

/* Best Projects sur grand écran : étiquettes plus écartées horizontalement */
@media (min-width: 1200px) {
	.SectionBestWorks .Projet-Tags { column-gap: var(--espace-4); }}

/* Bandeau d'informations des cartes du Portfolio réduit (écran bas) : le synopsis passe à une ligne pour que tout tienne */
#SectionPortfolio.Infos-Serrees .Carte-Description {
	-webkit-line-clamp: 1;
	line-clamp: 1;
}

/* Cartes du Portfolio sur grand écran : synopsis et lignes clients / tâches un peu plus petits par défaut */
@media (min-width: 1201px) {
	#SectionPortfolio .Carte-Description { font-size: calc(var(--taille-texte-second) * 0.85); }
	#SectionPortfolio .Carte-Meta-Ligne { font-size: calc(var(--taille-texte-meta) * 0.85); }}

/* ------------------------------------------------------------------------------------------------------------------- */
/* Fiche détaillée d'un projet du Portfolio (voir initDetailProjet) : même présentation que Best Projects, dans une fenêtre */
/* de taille commune à tous les projets, avec des flèches de chaque côté et une bande de vignettes                        */
/* ------------------------------------------------------------------------------------------------------------------- */

#SectionPortfolio .SectionWorks { cursor: var(--curseur-lien); }
.SectionWorks:focus-visible { outline: 2px solid var(--accent-1); outline-offset: 2px; }

/* Fiche technique (tâches, clients) : chaque valeur est une pastille, sans point séparateur qui se retrouve en début de ligne */
.Projet-Fiche dd { gap: 0.6rem 0.8rem; align-items: center; }
.Projet-Fiche dd span + span::before { content: none; }
.Projet-Fiche dd span {
	padding: 0.2rem 1.1rem;
	border: var(--bordure-fine) solid var(--couleur-bordure);
	border-radius: var(--rayon-pilule);
	line-height: 1.4;
}

/* Icônes de boutique (itch.io, Steam) toujours centrées sous le texte du projet, sur tous les formats */
.BestWorks-Icon { display: flex; justify-content: center; }


/* ------------------------------------------------------------------------------------------------------------------------------- */
/* ------------------------------------------- Affichage du Portfolio (boutons à droite) ------------------------------------------ */
/* ------------------------------------------------------------------------------------------------------------------------------- */

.Portfolio-Droite {
	display: flex;
	align-items: center;
	gap: var(--espace-4);
}

.Portfolio-Modes {
	display: flex;
	align-items: center;
	gap: var(--espace-2);
}

.Portfolio-Mode {
	display: inline-flex;
	gap: 0.2rem;
	padding: 0.25rem;
	background-color: var(--couleur-surface-2);
	border: var(--bordure-fine) solid var(--couleur-bordure);
	border-radius: var(--rayon-pilule);
}

.Portfolio-Mode button {
	display: grid;
	place-items: center;
	width: 2.4rem;
	height: 2.4rem;
	padding: 0;
	background: transparent;
	border: 0;
	border-radius: 50%;
	color: var(--couleur-texte-doux);
	cursor: var(--curseur-lien);
	transition: background-color var(--duree-courte) var(--courbe), color var(--duree-courte) var(--courbe);
}

.Portfolio-Mode button svg {
	width: 1.4rem;
	height: 1.4rem;
	fill: none;
	stroke: currentColor;
	stroke-width: 1.7;
	stroke-linecap: round;
	stroke-linejoin: round;
}

.Portfolio-Mode button:hover { color: var(--accent-1-clair); }

/* Le réglage choisi est plein, comme le filtre actif */
.Portfolio-Mode button[aria-pressed="true"] {
	background-color: var(--accent-1);
	color: #0a0a0c;
}

/* Sous 1200 px, les cartes sont toujours compactes : seul le défilement se choisit */
@media (max-width: 1200px) {
	.Portfolio-Mode[data-mode="style"] { display: none; }}

/* Grille entière : plus de zone défilante, toutes les cartes se suivent sur la page (la section prend un nombre entier d'écrans) */
#SectionPortfolio.Portfolio--complet .Portfolio-Defilement {
	height: auto;
	max-height: none;
	overflow: hidden;	/* Sans barre, mais la place de la barre reste réservée : les cartes gardent exactement leur taille */
	scroll-snap-type: none;
	overscroll-behavior: auto;
}

/* Flèches entre les écrans de la grille entière : posées en bas de chaque écran par le script (même style que Best Projects) */
.FlecheInterne--portfolio { bottom: auto; }
.RepereEcran--portfolio { position: absolute; left: 0; width: 0; }

@media (max-width: 1200px) {
	#SectionPortfolio.Portfolio--complet .PortfolioContainerProjets {
		grid-auto-flow: row;
		grid-template-rows: none;
		grid-template-columns: repeat(auto-fill, minmax(min(100%, 26rem), 1fr));
		grid-auto-columns: auto;
		gap: var(--espace-4);
		width: 100%;
	}}

/* Compact sur ordinateur : l'image et son titre dessus, comme sur tablette et téléphone ; le clic ouvre la fiche.
   Rien n'est retiré de la carte : le bandeau d'informations s'efface en fondu et la carte se referme sur l'image (hauteur posée ici,
   animée par le script), le titre et son voile apparaissent en fondu. */
/* Durée et courbe de tous les mouvements d'un changement d'affichage (identiques à DUREE_BASCULE et COURBE_BASCULE du script) */
#SectionPortfolio {
	--duree-bascule: 0.38s;
	--courbe-bascule: cubic-bezier(0.22, 0.61, 0.36, 1);
}
/* Pendant un changement, la hauteur de la section suit celle de la zone au lieu de sauter */
#SectionPortfolio.Portfolio--bascule { transition: min-height var(--duree-bascule) var(--courbe-bascule); }

/* Flèches entre les pages de la grille entière : elles apparaissent en fondu */
.FlecheInterne--portfolio { animation: fleche-portfolio-entree var(--duree-bascule) var(--courbe-bascule) backwards; }

@media (min-width: 1201px) {
	.Carte-Infos { transition: opacity var(--duree-bascule) var(--courbe-bascule); }
	.Carte-Visuel { transition: border-radius var(--duree-bascule) var(--courbe-bascule); }
	/* L'étoile grandit ou rapetisse avec la carte, au même rythme */
	.Carte-Favori { transition: width var(--duree-bascule) var(--courbe-bascule), height var(--duree-bascule) var(--courbe-bascule), box-shadow var(--duree-bascule) var(--courbe-bascule); }
	.Carte-Favori i { transition: font-size var(--duree-bascule) var(--courbe-bascule); }
	.Carte-Favori::before { transition: padding var(--duree-bascule) var(--courbe-bascule); }
	.Carte-Visuel::before {
		content: "";
		position: absolute;
		inset: 0;
		z-index: 1;
		pointer-events: none;
		background: linear-gradient(to bottom, rgba(10, 10, 12, 0) 0%, rgba(10, 10, 12, 0) 40%, rgba(10, 10, 12, 0.88) 100%);
		opacity: 0;
		transition: opacity var(--duree-bascule) var(--courbe-bascule);
	}
	.Carte-TitreImage {
		display: -webkit-box;
		position: absolute;
		left: var(--espace-3);
		right: var(--espace-3);
		bottom: var(--espace-2);
		z-index: 2;
		margin: 0;
		-webkit-box-orient: vertical;
		-webkit-line-clamp: 2;
		line-clamp: 2;
		overflow: hidden;
		font-size: clamp(1.1rem, calc(var(--carte-largeur, 300px) / 24), 2rem);	/* Suit la taille de la carte */
		line-height: 1.2;
		text-align: left;
		color: var(--couleur-titre);
		text-shadow: 0 1px 6px rgba(0, 0, 0, 0.8);
		-webkit-text-stroke: 0.45rem rgba(0, 0, 0, 0.95);
		paint-order: stroke fill;	/* Le contour noir passe derrière les lettres : seul son bord extérieur se voit */
		pointer-events: none;
		opacity: 0;
		transition: opacity var(--duree-bascule) var(--courbe-bascule);
	}

	.Portfolio--compact .SectionWorks {
		height: calc((var(--carte-largeur) - 2px) * 9 / 16 + 2px);	/* L'image seule */
		overflow: hidden;
	}
	.Portfolio--compact .Carte-Infos { opacity: 0; pointer-events: none; }
	.Portfolio--compact .Carte-Visuel { border-radius: calc(var(--rayon-2) - var(--bordure-fine)); }
	.Portfolio--compact .Carte-Visuel::before { opacity: 1; }
	.Portfolio--compact .Carte-TitreImage { opacity: 1; }

	/* La zone défilante n'a plus à réserver la place du bandeau */
	#SectionPortfolio.Portfolio--compact:not(.Portfolio--complet) .Portfolio-Defilement {
		height: max(var(--portfolio-defilement), calc(var(--carte-largeur) * 9 / 16 + 3.6rem));
	}

	/* En compact, l'étoile est plus petite de 40 % */
	.Portfolio--compact .Carte-Favori { width: 2.4rem; height: 2.4rem; box-shadow: 0 0 0.5rem 0.5rem rgba(0, 0, 0, 0.4); }
	.Portfolio--compact .Carte-Favori i { font-size: 1.2rem; }
	.Portfolio--compact .Carte-Favori::before { padding: 1.5px; }}

/* Sur tablette et téléphone, les cartes sont toujours compactes : même étoile réduite */
@media (max-width: 1200px) {
	.Carte-Favori { width: 2.4rem; height: 2.4rem; box-shadow: 0 0 0.5rem 0.5rem rgba(0, 0, 0, 0.4); }
	.Carte-Favori i { font-size: 1.2rem; }
	.Carte-Favori::before { padding: 1.5px; }}

/* Sur ordinateur, la barre de filtres a les mêmes bords gauche et droit que les cartes (valeurs posées par le script) */
@media (min-width: 1201px) {
	.Portfolio-Barre { padding-inline: var(--barre-gauche, 0) var(--barre-droite, 0); }}

/* Lien d'une carte et bouton « N links » : même hauteur, pour que le contenu de toutes les cartes soit aligné */
.Carte-Lien, .Link-DropDown-Menu-Btn { box-sizing: border-box; height: 3rem; }
.Carte-Lien .Logo-Lien { width: 1.4em; height: 1.4em; }

/* Tablette ou téléphone en paysage : les filtres se rangent sur une seule ligne (au lieu de trois lignes qui prennent tout l'écran bas) */
@media (min-width: 700px) and (max-width: 1200px) and (orientation: landscape) {
	.Filtres { display: flex; flex-wrap: wrap; justify-content: center; }
	.Filtre, .Filtre-Groupe > .Filtre { width: auto; padding: 0.8rem var(--espace-3); }
	.Filtre-Groupe { width: auto; }
	.Filtres:has(> :last-child:nth-child(odd)) > :first-child { grid-column: auto; }}


/* About en paysage (téléphone, tablette) : le portrait à gauche, le texte à droite, au lieu de tout empiler */
@media (orientation: landscape) and (max-width: 1199px) {
	.Bio { flex-direction: row; align-items: center; justify-content: center; gap: var(--espace-5); min-height: 0; }
	.BioLeft { width: 34%; }
	.BioMiddle-Right { width: 66%; }
	.BioMiddle { align-items: flex-start; }
	.BioMiddle h3 { text-align: left; align-self: flex-start; }
	.BioMiddle p { text-align: left; hyphens: manual; }
	.Bio-CV { justify-content: flex-start; align-self: flex-start; }}
@media (orientation: landscape) and (max-height: 520px) {
	.BioMiddle p { font-size: var(--taille-texte-meta); line-height: 1.55; }
	.BioMiddle .Bio-Accroche { font-size: calc(var(--taille-texte-meta) + 0.1rem); }
	.BioMiddle { gap: var(--espace-2); }}

/* Services, téléphone en paysage : cartes compactes (deux par écran avec le titre) */
@media (orientation: landscape) and (max-height: 520px) {
	.Service-Section { min-height: 0; grid-template-rows: auto auto auto; padding: var(--espace-2) var(--espace-3) 0; row-gap: var(--espace-1); }
	.ServiceIcone { width: 3.6rem; height: 3.6rem; }
	.Service-Section p { font-size: var(--taille-texte-meta); line-height: 1.4; }
	.Service-Liste { padding-block: var(--espace-2); gap: 0.3rem var(--espace-2); font-size: var(--taille-texte-meta); }
	.Service-Liste li { white-space: normal; }}

/* Best Projects en paysage : empilé (média puis texte), le média borné par la hauteur de l'écran pour que le projet tienne */
@media (orientation: landscape) and (max-width: 1199px) {
	.SectionBestWorks .SectionBestWorks-Informations-Left,
	.Ecrans--separes > .SectionBestWorks .SectionBestWorks-Informations-Left { width: 100%; max-width: calc(32dvh * 16 / 9); margin-inline: auto; }}

/* Paysage (téléphone, tablette) : lecteur du Demo Reel moins grand, bandeau de statistiques sur peu de hauteur, barre du Portfolio sur une ligne */
@media (orientation: landscape) and (max-width: 1199px) {
	#SectionDemoReel .ÉcranYoutube { max-width: calc(50dvh * 16 / 9); margin-inline: auto; }

	#SectionInBetween { padding: var(--espace-3) 0; }
	.Bandeau-Entete { margin-bottom: var(--espace-3); }
	#tagCountsContainer { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); justify-content: center; }
	.SD-Stats-Container { min-width: 0; width: 100%; }

	.Portfolio-Barre { flex-direction: row; flex-wrap: wrap; align-items: center; justify-content: space-between; }
	.Portfolio-Barre .Filtres { display: flex; flex-wrap: wrap; justify-content: flex-start; width: auto; flex: 1 1 auto; }
	.Portfolio-Droite { margin-left: auto; }}
@media (orientation: landscape) and (max-height: 520px) {
	/* Best Projects : les projets se suivent (pas d'écrans entiers), le média peut donc être plus grand */
	.SectionBestWorks .SectionBestWorks-Informations-Left,
	.Ecrans--separes > .SectionBestWorks .SectionBestWorks-Informations-Left { max-width: calc(64dvh * 16 / 9); }}
@media (orientation: landscape) and (max-height: 520px) {
	/* Background : les colonnes suivent leur contenu, cartes à taille normale et rapprochées (pas de grands vides) */
	.Background--separe .Background-Colonne,
	.Background--separe .Background-Colonne:first-child { min-height: 0; }
	.Background--separe .Frise { justify-content: flex-start; }
	.Background--separe .Frise-Resume { min-height: 0; }}

/* Paysage (téléphone, tablette) : pas d'écrans entiers, chaque section suit son contenu ; écarts réguliers dans le Demo Reel ;
   portrait d'About aussi haut que le texte à côté */
@media (orientation: landscape) and (max-width: 1199px) {
	#SectionDemoReel, #SectionServices, #SectionContact, .Bio, .Background, .Service-Section { min-height: 0; }
	.BioService { --services-colonnes: 2; }
	.DemoReel-Outils { margin-block: var(--espace-3); }

	.Bio { align-items: center; }
	.BioLeft { flex: 0 0 auto; width: 38%; }
	.BioMiddle-Right { width: 62%; }
	.BioLeft img { width: 100%; height: auto; aspect-ratio: 4 / 5; }
	.BioLeft::before { width: 90%; height: 90%; }}
@media (orientation: landscape) and (min-width: 1000px) and (max-width: 1199px) {
	.BioService { --services-colonnes: 3; }}

/* Grille entière en paysage (téléphone, tablette) : cartes plus petites, trois colonnes sur téléphone */
@media (orientation: landscape) and (max-width: 1200px) {
	#SectionPortfolio.Portfolio--complet .PortfolioContainerProjets { grid-template-columns: repeat(auto-fill, minmax(min(100%, 20rem), 1fr)); }}

/* Paysage (téléphone, tablette) : les miniatures gardent un rapport constant avec le lecteur (un peu plus d'un quart de sa largeur) */
@media (orientation: landscape) and (max-width: 1199px) {
	.SectionBestWorks-Informations-Left { container-type: inline-size; }
	.SectionBestWorks .video-thumbnails .slick-slide img { width: clamp(6.4rem, 24cqw, 14rem); }}

/* About, téléphone en portrait : le portrait garde de la place sans réduire le texte (titre de section plus court, écarts resserrés) */
@media (max-width: 767px) and (orientation: portrait) {
	#SectionAbout .SectionTitre-Resume { display: none; }
	#SectionAbout > .SectionTitre { padding-bottom: var(--espace-3); }
	.Bio { gap: var(--espace-2); }}

@keyframes circulation-cadre {
	from { background-position: 0% 0%; }
	to   { background-position: 300% 300%; }
}

@keyframes respiration-lecture {
	0%, 100% { box-shadow: var(--ombre-2), 0 0 0 0 rgba(77, 165, 245, 0.45); }
	50%      { box-shadow: var(--ombre-2), 0 0 0 1.2rem rgba(77, 165, 245, 0); }
}





@keyframes respiration {
	from { opacity: 0.8; transform: scale(0.99); }
	to   { opacity: 1;   transform: scale(1.03); }
}

/* Un anneau violet, fin, qui reste dans l'espace propre du bouton */
@keyframes onde-bouton {
	0%   { box-shadow: 0 0 0 0 rgba(168, 85, 247, 0.85); }
	70%  { box-shadow: 0 0 0 0.9rem rgba(168, 85, 247, 0); }
	100% { box-shadow: 0 0 0 0 rgba(168, 85, 247, 0); }
}

@keyframes evolution-lueur {
	from { background-position: 0% 0%; }
	to   { background-position: 100% 100%; }
}

@keyframes echange-coins {
	from { --coin-haut: rgba(77, 165, 245, 0.3);  --coin-bas: rgba(168, 85, 247, 0.22); }
	to   { --coin-haut: rgba(168, 85, 247, 0.22);  --coin-bas: rgba(77, 165, 245, 0.3); }
}

@keyframes glissement-cadre {
	from { background-position: 0% 0%; }
	to   { background-position: 100% 100%; }
}

@keyframes panneau-ouverture {
	from { opacity: 0; translate: 0 -0.8rem; }
	to   { opacity: 1; translate: 0 0; }
}

@keyframes carte-entree {
	/* Balayage de la gauche vers la droite. Le fondu passe par filter et non par opacity : Isotope
	   anime lui-même l'opacité des cartes (et attend la fin de sa transition) ; une animation CSS
	   sur opacity la bloquait, et la carte n'apparaissait vraiment qu'à la fin de l'animation. */
	from { filter: opacity(0); translate: -4rem 0; }
	to   { filter: opacity(1); translate: 0 0; }
}
@keyframes panneau-fermeture {
	from { opacity: 1; translate: 0 0; }
	to   { opacity: 0; translate: 0 -0.8rem; }
}

@keyframes infos-entree {
	from { opacity: 0; translate: 0 0.8rem; }
	to   { opacity: 1; translate: 0 0; }
}

/* Flèche interne : toujours visible, son opacité va et vient doucement avec un léger mouvement vers le bas */
@keyframes FlecheInterne {
	0%, 100% { opacity: 0.35; transform: translateY(-0.2rem) rotate(45deg); }
	50%      { opacity: 0.9;  transform: translateY(0.25rem) rotate(45deg); }
}
@keyframes fleche-portfolio-entree { from { opacity: 0; } to { opacity: 1; } }
