/* =========================================================
   MONSIEURWALTER — feuille de style principale
   Structure calquée sur les maquettes :
   hero panoramique, grille 3 colonnes collée, page projet en
   quatre temps (hero court, bloc texte, vidéo pleine largeur,
   images par deux).
   ========================================================= */

@font-face {
	font-family: "Archivo";
	src: url("../fonts/archivo.woff2") format("woff2");
	font-weight: 400 900;
	font-display: swap;
}
@font-face {
	font-family: "Mono HUD";
	src: url("../fonts/jetbrains-mono.woff2") format("woff2");
	font-weight: 400 700;
	font-display: swap;
}

:root {
	--paper: #ffffff;
	--ink: #0b0b0c;
	/* Pas de gris dans la palette : ces deux valeurs sont du noir
	   transparent. Même rendu à l'œil, mais elles s'adaptent au fond
	   qui les porte au lieu d'introduire une quatrième teinte. */
	--grey: rgba(11, 11, 12, 0.5);
	--line: rgba(11, 11, 12, 0.12);
	/* Trois couleurs, pas une de plus : noir, blanc, rouge. Le rouge
	   signale ce qui nomme ou ce qui répond — libellés, survols, repères —
	   jamais ce qui décore. */
	--red: #e0301c;
	--hud: var(--red);

	--display: "Archivo", "Helvetica Neue", Arial, sans-serif;
	--mono: "Mono HUD", ui-monospace, "SF Mono", Menlo, monospace;

	/* Marge de page : celle du bloc texte de la maquette projet. */
	--pad: clamp(1.25rem, 4.2vw, 3.5rem);
	/* Fine gouttière, utilisée uniquement dans les paires d'images. */
	--split: clamp(0.5rem, 1vw, 1rem);
	--logo: clamp(3.5rem, 7vw, 6.5rem);
}

*,
*::before,
*::after {
	box-sizing: border-box;
}

html {
	-webkit-text-size-adjust: 100%;
}

body {
	margin: 0;
	background: var(--paper);
	color: var(--ink);
	font-family: var(--display);
	line-height: 1.35;
	-webkit-font-smoothing: antialiased;
	overflow-x: hidden;
}

img,
video {
	display: block;
	max-width: 100%;
	height: auto;
}

a {
	color: inherit;
	text-decoration: none;
}

:focus-visible {
	outline: 2px solid var(--hud);
	outline-offset: 3px;
}

.skip-link {
	position: absolute;
	left: -9999px;
}
.skip-link:focus {
	left: var(--pad);
	top: 1rem;
	z-index: 100;
	background: var(--ink);
	color: #fff;
	padding: 0.5rem 1rem;
	font: 600 0.75rem/1 var(--mono);
}

/* =========================================================
   En-tête — le logo animé seul, posé sur le hero
   ========================================================= */

.masthead {
	position: absolute;
	z-index: 50;
	top: var(--pad);
	left: var(--pad);
}

.masthead__logo {
	display: block;
	width: var(--logo);
}

/* Le logo est affiché TEL QUEL. L'inversion était appliquée d'office en
   partant d'un logo noir, mais un logo animé en couleurs y perdait tout :
   le magenta devenait vert. Elle est devenue une option du personnalisateur,
   utile seulement pour un logo monochrome sombre posé sur une vidéo sombre. */
.masthead__logo img {
	width: 100%;
	height: auto;
}
.masthead__logo--invert img {
	filter: invert(1);
}

/* =========================================================
   Hero — panoramique, bord à bord
   ========================================================= */

.hero {
	position: relative;
	height: min(80svh, 44.8vw);
	min-height: 17rem;
	overflow: hidden;
	background: var(--ink);
}

.hero__stage {
	position: absolute;
	inset: 0;
}

.hero__video,
.hero__layer {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	will-change: transform;
}

.hero__layer {
	transform: translate3d(0, 0, 0) scale(1.02);
}

/* La phrase d'accroche ne s'impose pas : elle vit en bas, discrète. */
.hero__caption {
	position: absolute;
	inset: auto var(--pad) var(--pad) var(--pad);
	z-index: 3;
	display: flex;
	align-items: flex-end;
	justify-content: space-between;
	gap: 2rem;
	color: #fff;
	mix-blend-mode: difference;
}

.hero__title {
	margin: 0;
	max-width: 26ch;
	font: 500 0.72rem/1.5 var(--mono);
	letter-spacing: 0.14em;
	text-transform: uppercase;
}
.hero__title span {
	display: none;
}

.hero__scroll {
	margin: 0;
	font: 500 0.66rem/1 var(--mono);
	letter-spacing: 0.2em;
	text-transform: uppercase;
	white-space: nowrap;
	color: var(--red);
}

/* =========================================================
   Mosaïque — 3 colonnes, aucune gouttière, bord à bord
   ========================================================= */

.grid {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	grid-auto-flow: dense;
	gap: 0;
	padding: 0;
}

.grid__empty {
	grid-column: 1 / -1;
	padding: var(--pad);
	font: 400 0.85rem/1.6 var(--mono);
	color: var(--grey);
}

.tile {
	grid-column: span 1;
	min-width: 0;
}
/* Formats exceptionnels, à réserver aux meilleurs projets. */
.tile--l {
	grid-column: span 2;
}
.tile--x {
	grid-column: span 3;
}

.tile.is-hidden {
	display: none;
}

.tile__link {
	position: relative;
	display: block;
}

.tile__media {
	position: relative;
	display: block;
	overflow: hidden;
	aspect-ratio: 1.44;
	background: var(--ink);
}
.tile--l .tile__media {
	aspect-ratio: 2.94;
}
.tile--x .tile__media {
	aspect-ratio: 4.5;
}
.tile--p .tile__media {
	aspect-ratio: 3 / 4;
}

.tile__poster,
.tile__video {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.tile__poster {
	transition: transform 0.8s cubic-bezier(0.2, 0, 0.1, 1);
}
.tile__poster--empty {
	background: repeating-linear-gradient(45deg, rgba(255,255,255,.06) 0 10px, transparent 10px 20px);
}

/* Sans image mise en avant, le titre et son voile sont visibles dès le
   repos : une tuile muette passe pour une panne, alors qu'il ne manque
   qu'un visuel. Ces deux règles l'emportent par leur spécificité, où
   qu'elles soient placées dans la feuille. */
.tile--noposter .tile__title,
.tile--noposter .tile__media::after {
	opacity: 1;
	transform: none;
}

.tile__video {
	opacity: 0;
	transition: opacity 0.35s;
}
.tile.is-playing .tile__video {
	opacity: 1;
}
.tile.is-playing .tile__poster {
	opacity: 0;
}

.tile__link:hover .tile__poster,
.tile__link:focus-visible .tile__poster {
	transform: scale(1.04);
}

/* Rien au repos. Au survol : un voile et le titre, rien d'autre. */
.tile__media::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 2;
	background: rgba(8, 8, 10, 0.5);
	opacity: 0;
	transition: opacity 0.4s;
	pointer-events: none;
}

.tile__title {
	position: absolute;
	inset: auto 0 0;
	z-index: 3;
	margin: 0;
	padding: clamp(1rem, 2vw, 1.75rem);
	color: #fff;
	font-size: clamp(0.95rem, 1.3vw, 1.4rem);
	font-weight: 700;
	letter-spacing: -0.01em;
	text-transform: uppercase;
	opacity: 0;
	transform: translate3d(0, 0.6rem, 0);
	transition: opacity 0.4s, transform 0.5s cubic-bezier(0.2, 0, 0.1, 1);
	pointer-events: none;
}

.tile__link:hover .tile__media::after,
.tile__link:focus-visible .tile__media::after,
.tile__link:hover .tile__title,
.tile__link:focus-visible .tile__title {
	opacity: 1;
	transform: none;
}

/* Sans survol possible, le titre reste lisible en permanence. */
@media (hover: none) {
	.tile__title,
	.tile__media::after {
		opacity: 1;
		transform: none;
	}
}

/* =========================================================
   Bandeau clients et filtres — masqués par défaut,
   activables dans Apparence → Personnaliser
   ========================================================= */

.clients {
	overflow: hidden;
	padding: clamp(1.25rem, 3vw, 2rem) 0;
	border-bottom: 1px solid var(--line);
}
.clients__track {
	display: flex;
	width: max-content;
	animation: mw-marquee 46s linear infinite;
}
.clients:hover .clients__track {
	animation-play-state: paused;
}
.clients__list {
	display: flex;
	align-items: center;
	gap: clamp(2.5rem, 6vw, 5rem);
	margin: 0;
	padding: 0 clamp(1.25rem, 3vw, 2.5rem);
	list-style: none;
}
.clients__list img {
	height: clamp(1.1rem, 2vw, 1.6rem);
	width: auto;
	opacity: 0.5;
	filter: grayscale(1) contrast(1.4);
	transition: opacity 0.3s;
}
.clients__list img:hover {
	opacity: 1;
}
@keyframes mw-marquee {
	to {
		transform: translate3d(-50%, 0, 0);
	}
}

.filters {
	display: flex;
	flex-wrap: wrap;
	gap: 0.4rem;
	padding: clamp(1.25rem, 3vw, 2rem) var(--pad);
}
.filters__btn {
	appearance: none;
	border: 1px solid var(--line);
	background: transparent;
	color: var(--grey);
	padding: 0.5em 1em;
	border-radius: 999px;
	cursor: pointer;
	font: 500 0.66rem/1 var(--mono);
	letter-spacing: 0.12em;
	text-transform: uppercase;
	transition: color 0.25s, border-color 0.25s, background-color 0.25s;
}
.filters__btn:hover {
	color: var(--red);
	border-color: var(--red);
}
.filters__btn.is-active {
	background: var(--ink);
	border-color: var(--ink);
	color: #fff;
}

/* =========================================================
   Page projet — hero court, bloc texte, vidéo, paires
   ========================================================= */

.project__hero {
	position: relative;
	height: min(58svh, 30vw);
	min-height: 12rem;
	overflow: hidden;
	background: var(--ink);
}
.project__hero img,
.project__hero video {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* Le bloc d'introduction : titre au tiers gauche, texte à mi-largeur,
   et beaucoup de blanc en dessous — c'est la respiration de la maquette. */
.project__intro {
	padding: clamp(2.25rem, 5vw, 3.5rem) var(--pad) clamp(4rem, 9vw, 7rem);
}

.project__title {
	margin: 0;
	max-width: 16ch;
	font-size: clamp(1.6rem, 4.4vw, 3.25rem);
	font-weight: 800;
	line-height: 1;
	letter-spacing: -0.03em;
	text-transform: uppercase;
	text-wrap: balance;
}

.project__facts {
	display: flex;
	flex-wrap: wrap;
	gap: 0 clamp(1.5rem, 4vw, 3rem);
	margin: clamp(1.5rem, 3vw, 2.25rem) 0 0;
	font: 400 0.75rem/1.5 var(--mono);
}
.project__facts dt {
	font-size: 0.62rem;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--red);
}
.project__facts dd {
	margin: 0.25rem 0 0;
}

.project__body {
	max-width: 58ch;
	margin-top: clamp(1.5rem, 3vw, 2.25rem);
	font-size: clamp(0.95rem, 1.1vw, 1.1rem);
	line-height: 1.7;
}
.project__body > * + * {
	margin-top: 1.2em;
}

/* Vidéo principale : pleine largeur, aucune marge. */
.project__player {
	background: var(--ink);
}
.project__player iframe,
.project__player video,
.project__player img {
	display: block;
	width: 100%;
	aspect-ratio: 16 / 9;
	height: auto;
	border: 0;
	object-fit: cover;
}

/* Le contenu Gutenberg sort des marges pour les médias. */
.project__blocks {
	padding: var(--split) 0 0;
}
.project__blocks > * {
	margin: 0 auto var(--split);
	max-width: 62ch;
	padding-inline: var(--pad);
	font-size: clamp(0.95rem, 1.1vw, 1.1rem);
	line-height: 1.7;
}
.project__blocks > figure,
.project__blocks > .wp-block-image,
.project__blocks > .wp-block-video,
.project__blocks > .wp-block-gallery,
.project__blocks > .alignfull,
.project__blocks > .alignwide {
	max-width: none;
	padding-inline: 0;
}
.project__blocks img,
.project__blocks video {
	width: 100%;
}

/* Une galerie à deux colonnes reproduit la paire d'images du bas de maquette. */
.project__blocks .wp-block-gallery.columns-2,
.project__blocks .wp-block-columns {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: var(--split);
}
.project__blocks .wp-block-gallery.columns-2 figure,
.project__blocks .wp-block-columns > * {
	margin: 0;
}

.project__pair {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: var(--split);
	margin-top: var(--split);
}
.project__pair > * {
	aspect-ratio: 16 / 9;
	overflow: hidden;
	background: var(--ink);
}
.project__pair img,
.project__pair video {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.project__next {
	margin-top: clamp(4rem, 9vw, 7rem);
}
.project__next h2 {
	margin: 0 var(--pad) 1.25rem;
	font: 500 0.68rem/1 var(--mono);
	letter-spacing: 0.2em;
	text-transform: uppercase;
	color: var(--grey);
}

/* =========================================================
   Page simple et pied de page
   ========================================================= */

/* Ce bloc s'appelait `.page`, et c'était un piège : WordPress pose la classe
   `page` sur le <body> de TOUTE page. La règle s'appliquait donc au body
   entier, qui héritait de ce rembourrage — logo décroché du haut, grande
   zone blanche, et marges sur les côtés. Le défaut n'apparaissait que
   lorsque l'accueil devenait une page statique, puisque c'est de là que
   vient la classe. Aucun nom de bloc du thème ne doit reprendre une classe
   de body de WordPress : page, home, blog, single, archive, search. */
.sheet {
	padding: calc(var(--logo) + var(--pad) * 2) var(--pad) clamp(4rem, 9vw, 7rem);
}
.sheet__title {
	margin: 0 0 1.5rem;
	font-size: clamp(1.8rem, 5vw, 3.5rem);
	font-weight: 800;
	line-height: 1;
	letter-spacing: -0.03em;
	text-transform: uppercase;
}
.sheet__body {
	max-width: 58ch;
	font-size: clamp(0.95rem, 1.1vw, 1.1rem);
	line-height: 1.7;
}
.sheet__body > * + * {
	margin-top: 1.2em;
}

/* Liste de résultats — recherche, archive. Réglée en mono comme les autres
   informations techniques du site. */
.listing {
	list-style: none;
	margin: 0;
	padding: 0;
}
.listing li + li {
	margin-top: 0.7em;
	padding-top: 0.7em;
	border-top: 1px solid var(--line);
}
.listing a {
	font: 500 0.78rem/1.4 var(--mono);
	letter-spacing: 0.06em;
	text-transform: uppercase;
}

.colophon {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 1.5rem;
	padding: clamp(2rem, 5vw, 3rem) var(--pad);
	border-top: 1px solid var(--line);
	font: 400 0.72rem/1 var(--mono);
	letter-spacing: 0.1em;
}
.colophon__contact {
	margin: 0;
}
.colophon__contact a {
	font-family: var(--display);
	font-size: clamp(0.95rem, 1.5vw, 1.15rem);
	font-weight: 700;
	letter-spacing: -0.01em;
}
.colophon__contact a:hover {
	color: var(--hud);
}
.colophon__social {
	display: flex;
	flex-wrap: wrap;
	gap: 1.25rem;
	margin: 0;
	padding: 0;
	list-style: none;
	text-transform: uppercase;
}
.colophon__social a:hover {
	color: var(--hud);
}
.colophon__legal {
	margin: 0;
	font-weight: 500;
	color: var(--red);
}

/* =========================================================
   Adaptations
   ========================================================= */

@media (max-width: 900px) {
	.grid {
		grid-template-columns: repeat(2, 1fr);
	}
	.tile--l,
	.tile--x {
		grid-column: span 2;
	}
	.tile--l .tile__media,
	.tile--x .tile__media {
		aspect-ratio: 2.94;
	}
	.hero {
		height: min(70svh, 62vw);
	}
	.project__hero {
		height: min(50svh, 46vw);
	}
}

@media (max-width: 560px) {
	.grid {
		grid-template-columns: 1fr;
	}
	.tile,
	.tile--l,
	.tile--x {
		grid-column: span 1;
	}
	.tile__media,
	.tile--l .tile__media,
	.tile--x .tile__media,
	.tile--p .tile__media {
		aspect-ratio: 1.44;
	}
	.project__pair,
	.project__blocks .wp-block-gallery.columns-2,
	.project__blocks .wp-block-columns {
		grid-template-columns: 1fr;
	}
	.hero__scroll {
		display: none;
	}
	.masthead__menu {
		font-size: 0.6rem;
		gap: 0.75rem;
	}
}

@media (prefers-reduced-motion: reduce) {
	*,
	*::before,
	*::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
	}
	.clients__track {
		animation: none;
	}
}

/* =========================================================
   Transition mosaïque → page projet

   L'animation est pilotée en JavaScript plutôt que par les View
   Transitions du navigateur : c'est le seul moyen d'obtenir le même
   écartement des tuiles sur tous les navigateurs.
   ========================================================= */

#mw-stage {
	position: fixed;
	inset: 0;
	z-index: 200;
	display: none;
	perspective: 1200px;
	pointer-events: none;
}
#mw-stage.is-on {
	display: block;
}

.flyer {
	position: fixed;
	overflow: hidden;
	transform-origin: 0 0;
	will-change: transform;
	background: var(--ink);
}
.flyer img,
.flyer video {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	will-change: transform;
}

.tile,
.hero,
.project__hero,
.project__intro,
.project__player,
.project__blocks {
	will-change: transform, opacity;
}

/* Les médias débordent de leur cadre pour pouvoir glisser dedans. */
.project__player > div,
.project__pair > div {
	position: relative;
	overflow: hidden;
}
.project__player img,
.project__player video,
.project__pair img,
.project__pair video {
	will-change: transform;
}

@media (prefers-reduced-motion: reduce) {
	.tile,
	.hero,
	.project__hero,
	.project__intro,
	.project__player,
	.project__blocks {
		will-change: auto;
		transform: none !important;
		opacity: 1 !important;
	}
}

/* =========================================================
   Page Studio — les logos en vague, puis le reste en fondu

   Tout est masqué par défaut dans le CSS, sans dépendre d'un script.
   Le repli .no-intro découvre la page si le JavaScript ne s'exécute pas.
   ========================================================= */

.hero--about {
	height: min(72svh, 40vw);
}

.planes {
	overflow: hidden;
}

.plane {
	position: relative;
	background: #fff;
	opacity: 0;
}

.cloud__logo {
	opacity: 0;
}

html.no-intro .plane,
html.no-intro .cloud__logo {
	opacity: 1;
}

/* La grille de logos. */
.cloud {
	padding: clamp(3rem, 7vw, 5.5rem) var(--pad) clamp(1.5rem, 3vw, 2.5rem);
	background: #fff;
	/* La perspective donne sa profondeur à la vague : sans elle, un
	   déplacement en Z ne produirait aucun changement d'échelle. */
	perspective: 900px;
	perspective-origin: 50% 50%;
}

.cloud__grid {
	transform-style: preserve-3d;
}

.cloud__grid {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	align-items: center;
	gap: clamp(1.75rem, 4.5vw, 4rem) clamp(2rem, 5vw, 4.5rem);
	max-width: 72rem;
	margin: 0 auto;
	padding: 0;
	list-style: none;
}

.cloud__logo img {
	height: clamp(1.4rem, 3vw, 2.4rem);
	width: auto;
	filter: grayscale(1) contrast(1.2);
	opacity: 0.75;
	transition: opacity 0.3s, filter 0.3s;
}
.cloud__logo img:hover {
	opacity: 1;
	filter: grayscale(0) contrast(1);
}

/* La vague se propage EN PROFONDEUR : chaque logo avance vers le
   spectateur puis recule. Avec la perspective posée sur .cloud, cela
   produit un léger grossissement à l'approche.

   Amplitude volontairement faible : la vague doit se sentir sans se
   voir. Un logo qui bouge beaucoup attire l'œil au détriment des
   autres, et la grille cesse de se lire comme une grille.

   Trois durées légèrement différentes, réparties par le script : les
   logos ne reviennent jamais tous en phase, donc chacun garde son
   mouvement propre au lieu de battre à l'unisson. */
@keyframes mw-wave {
	0%,
	100% {
		transform: translate3d(0, 0, -26px);
	}
	50% {
		transform: translate3d(0, 0, 26px);
	}
}

.cloud.is-waving .cloud__logo {
	animation-name: mw-wave;
	animation-timing-function: ease-in-out;
	animation-iteration-count: infinite;
	will-change: transform;
}


/* Le texte de présentation, centré comme sur la maquette. */
.about {
	background: #fff;
	padding: clamp(2rem, 5vw, 3.5rem) var(--pad) clamp(5rem, 10vw, 8rem);
}

/* Le paragraphe respire : mesure courte, interlignage large, et une
   taille un cran au-dessus du corps de texte courant — c'est le seul
   texte de la page, il peut prendre de la place. */
.about__body {
	max-width: 42rem;
	margin: 0 auto;
	text-align: center;
	font-size: clamp(0.92rem, 1.02vw, 1.02rem);
	line-height: 1.85;
	letter-spacing: -0.005em;
	text-wrap: pretty;
}
.about__body > * + * {
	margin-top: 1.5em;
}

/* Les compétences, nettement séparées du texte par un filet et par un
   traitement typographique opposé : petites capitales monospace contre
   grande prose. */
.skills {
	max-width: 44rem;
	margin: clamp(3rem, 7vw, 5rem) auto 0;
	padding-top: clamp(2rem, 5vw, 3rem);
	border-top: 1px solid var(--line);
	text-align: center;
}

.skills__row {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	align-items: center;
	gap: 0.5em 1.4em;
	margin: 0;
	padding: 0;
	list-style: none;
	font: 500 0.74rem/1.8 var(--mono);
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--red);
}
.skills__row + .skills__row {
	margin-top: 0.7em;
}

/* Une puce discrète entre les intitulés, plutôt qu'une barre oblique
   collée au texte. */
.skills__row li {
	position: relative;
}
.skills__row li + li::before {
	content: "";
	position: absolute;
	top: 50%;
	left: -0.75em;
	width: 3px;
	height: 3px;
	margin-top: -1px;
	border-radius: 50%;
	background: var(--red);
}

/* Le bandeau déborde de son cadre pour glisser dedans au défilement. */
.hero--about .hero__stage {
	will-change: transform;
}

@media (max-width: 900px) {
	.hero--about {
		height: min(60svh, 56vw);
	}
}

@media (prefers-reduced-motion: reduce) {
	.plane,
	.cloud__logo {
		opacity: 1;
	}
	.cloud.is-waving .cloud__logo {
		animation: none;
	}
}

/* =========================================================
   Navigation — discrète sur l'accueil, lisible ailleurs
   ========================================================= */

.masthead {
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	gap: 1rem;
	right: var(--pad);
}

.masthead__nav {
	padding-top: 0.5rem;
}

.masthead__menu {
	display: flex;
	flex-wrap: wrap;
	gap: clamp(0.9rem, 2.2vw, 2rem);
	margin: 0;
	padding: 0;
	list-style: none;
	font: 500 0.68rem/1 var(--mono);
	letter-spacing: 0.16em;
	text-transform: uppercase;
}

.masthead__menu a {
	position: relative;
	padding-bottom: 0.25em;
}
.masthead__menu a {
	transition: color 0.3s;
}
.masthead__menu a:hover,
.masthead__menu .current-menu-item a {
	color: var(--red);
}
.masthead__menu a::after {
	content: "";
	position: absolute;
	inset: auto 0 0;
	height: 1px;
	background: var(--red);
	transform: scaleX(0);
	transform-origin: left;
	transition: transform 0.35s cubic-bezier(0.4, 0, 0.1, 1);
}
.masthead__menu a:hover::after,
.masthead__menu .current-menu-item a::after {
	transform: scaleX(1);
}

/* Sur l'accueil et la page perso, le menu est posé sur un visuel :
   il passe en blanc et s'efface, pour ne pas concurrencer les images. */
/* Sur fond visuel, le menu est blanc et légèrement effacé. Pas de
   mix-blend-mode ici : il inverserait le rouge du survol en cyan. */
.home .masthead__menu,
.page-template-page-max-walter .masthead__menu {
	color: #fff;
	opacity: 0.6;
	transition: opacity 0.35s;
	text-shadow: 0 1px 12px rgba(0, 0, 0, 0.5);
}
.home .masthead__menu a:hover,
.page-template-page-max-walter .masthead__menu a:hover {
	color: var(--red);
}
.home .masthead__nav:hover .masthead__menu,
.home .masthead__menu:focus-within,
.page-template-page-max-walter .masthead__nav:hover .masthead__menu,
.page-template-page-max-walter .masthead__menu:focus-within {
	opacity: 1;
}

/* =========================================================
   Page Contact
   ========================================================= */

.contact {
	display: grid;
	place-items: center;
	min-height: 78svh;
	padding: calc(var(--logo) + var(--pad) * 2) var(--pad) clamp(4rem, 9vw, 7rem);
	background: #fff;
}

.contact__inner {
	max-width: 56rem;
	text-align: center;
}

.contact__eyebrow {
	margin: 0 0 clamp(1.5rem, 4vw, 2.5rem);
	font: 500 0.7rem/1.6 var(--mono);
	letter-spacing: 0.18em;
	text-transform: uppercase;
	color: var(--red);
}

/* L'adresse est le contenu de la page : elle en prend la taille. */
.contact__mail {
	display: inline-block;
	font-size: clamp(1.15rem, 2.6vw, 1.9rem);
	font-weight: 700;
	line-height: 1.2;
	letter-spacing: -0.02em;
	word-break: break-word;
}
.contact__mail::after {
	content: "";
	display: block;
	height: 2px;
	margin-top: 0.15em;
	background: currentColor;
	transform: scaleX(0);
	transform-origin: left;
	transition: transform 0.5s cubic-bezier(0.2, 0, 0.1, 1);
}
.contact__mail:hover::after,
.contact__mail:focus-visible::after {
	transform: scaleX(1);
}

.contact__body {
	max-width: 44ch;
	margin: clamp(2rem, 5vw, 3rem) auto 0;
	font-size: clamp(0.95rem, 1.1vw, 1.1rem);
	line-height: 1.7;
}

.contact__social {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: clamp(1rem, 3vw, 2rem);
	margin: clamp(2.5rem, 6vw, 4rem) 0 0;
	padding: 0;
	list-style: none;
	font: 500 0.72rem/1 var(--mono);
	letter-spacing: 0.14em;
	text-transform: uppercase;
}
.contact__social a:hover {
	color: var(--hud);
}

.contact__place {
	margin: clamp(2rem, 5vw, 3rem) 0 0;
	font: 500 0.68rem/1 var(--mono);
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--red);
}

/* Le pied de page ferait doublon avec le contenu de cette page. */
.page-template-page-contact .colophon {
	display: none;
}

/* =========================================================
   Page Max Walter — mur de travaux personnels
   ========================================================= */

.perso {
	padding: calc(var(--logo) + var(--pad) * 2) 0 0;
	background: var(--ink);
	color: #fff;
}

.perso__head {
	padding: 0 var(--pad) clamp(1.5rem, 4vw, 2.5rem);
}

.perso__title {
	margin: 0;
	font-size: clamp(2rem, 8vw, 6rem);
	font-weight: 800;
	line-height: 0.95;
	letter-spacing: -0.04em;
	text-transform: uppercase;
}

.perso__intro {
	max-width: 46ch;
	margin-top: clamp(1rem, 2.5vw, 1.75rem);
	font-size: clamp(0.95rem, 1.1vw, 1.1rem);
	line-height: 1.7;
	color: rgba(255, 255, 255, 0.72);
}

.page-template-page-max-walter .filters {
	padding-inline: var(--pad);
}
.page-template-page-max-walter .filters__btn {
	border-color: rgba(255, 255, 255, 0.28);
	color: rgba(255, 255, 255, 0.6);
}
.page-template-page-max-walter .filters__btn:hover {
	color: var(--red);
	border-color: var(--red);
}
.page-template-page-max-walter .filters__btn.is-active {
	background: #fff;
	border-color: #fff;
	color: var(--ink);
}

/* Le mur : grille fixe, quatre rectangles verticaux par ligne. Le
   format uniforme est un choix : sur des travaux personnels aux sujets
   très variés, c'est la régularité du cadre qui fait tenir l'ensemble.
   Les formats libres, eux, donnaient un patchwork. */
.wall {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: 1px;
	padding: 0;
	background: rgba(255, 255, 255, 0.08);
}

.wall__empty {
	grid-column: 1 / -1;
	padding: var(--pad);
	font: 400 0.85rem/1.6 var(--mono);
	color: rgba(255, 255, 255, 0.5);
}

.piece {
	position: relative;
	margin: 0;
	min-width: 0;
	background: var(--ink);
	grid-column: span 1;
}
.piece.is-hidden {
	display: none;
}

/* Une pièce paysage prend deux colonnes. La proportion 3:2 est choisie
   pour une raison précise : sur une grille de quatre colonnes, deux
   colonnes en 3:2 font exactement la même hauteur qu'une colonne en 3:4.
   Les rangées restent donc alignées et aucun trou n'apparaît, quel que
   soit l'ordre dans lequel les pièces sont publiées. */
.piece--landscape {
	grid-column: span 2;
}

.piece__open {
	display: block;
	position: relative;
	width: 100%;
	height: 100%;
	padding: 0;
	border: 0;
	background: none;
	cursor: zoom-in;
	overflow: hidden;
}

.piece__img,
.piece__loop video {
	display: block;
	width: 100%;
	height: 100%;
	aspect-ratio: 3 / 4;
	object-fit: cover;
	transition: transform 0.8s cubic-bezier(0.2, 0, 0.1, 1), opacity 0.4s;
}
.piece--landscape .piece__img,
.piece--landscape .piece__loop video {
	aspect-ratio: 3 / 2;
}
.piece__open:hover .piece__img {
	transform: scale(1.05);
	opacity: 0.8;
}

/* La couche vidéo. Comme sur la mosaïque, la vidéo n'est pas dans le HTML :
   elle est injectée après 150 ms de survol, donc parcourir le mur ne
   télécharge rien. */
.piece__loop {
	position: absolute;
	inset: 0;
	z-index: 1;
	display: block;
	opacity: 0;
	transition: opacity 0.35s;
	pointer-events: none;
}
.piece.is-playing .piece__loop {
	opacity: 1;
}
.piece.is-playing .piece__img {
	opacity: 0;
}
.piece__loop video {
	position: absolute;
	inset: 0;
	transition: none;
}

.piece__badge {
	position: absolute;
	z-index: 3;
	top: 0.75rem;
	left: 0.75rem;
	padding: 0.35em 0.6em;
	border: 1px solid var(--red);
	font: 500 0.56rem/1 var(--mono);
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--red);
	pointer-events: none;
}

.piece__caption {
	position: absolute;
	inset: auto 0 0;
	z-index: 3;
	padding: 0.85rem;
	font: 500 0.66rem/1.4 var(--mono);
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: #fff;
	background: linear-gradient(to top, rgba(8, 8, 10, 0.85), transparent);
	opacity: 0;
	transition: opacity 0.35s;
	pointer-events: none;
}
.piece__open:hover + .piece__caption,
.piece__open:focus-visible + .piece__caption {
	opacity: 1;
}

/* =========================================================
   Visionneuse
   ========================================================= */

/* Le verrou sert à la visionneuse comme à la page Studio. */
html.is-locked,
html.is-locked body {
	overflow: hidden;
}

.viewer {
	position: fixed;
	inset: 0;
	z-index: 250;
	display: none;
	place-items: center;
	padding: clamp(3rem, 8vw, 5rem) clamp(1rem, 6vw, 5rem);
	background: rgba(8, 8, 10, 0.94);
}
.viewer.is-open {
	display: grid;
}

.viewer__stage {
	display: grid;
	place-items: center;
	max-width: 100%;
	max-height: 78svh;
}
.viewer__stage img,
.viewer__stage video {
	max-width: 100%;
	max-height: 78svh;
	width: auto;
	height: auto;
	object-fit: contain;
}

.viewer__caption {
	position: absolute;
	inset: auto 0 clamp(1rem, 3vw, 2rem);
	margin: 0;
	text-align: center;
	font: 500 0.68rem/1.5 var(--mono);
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--red);
}

.viewer__close,
.viewer__nav {
	position: absolute;
	z-index: 2;
	border: 0;
	background: none;
	color: #fff;
	cursor: pointer;
	font: 500 0.7rem/1 var(--mono);
	letter-spacing: 0.14em;
	text-transform: uppercase;
	padding: 0.8em 1em;
	opacity: 0.65;
	transition: opacity 0.25s;
}
.viewer__close:hover,
.viewer__nav:hover {
	opacity: 1;
}

.viewer__close {
	top: clamp(0.75rem, 2vw, 1.5rem);
	right: clamp(0.75rem, 2vw, 1.5rem);
}
.viewer__nav {
	top: 50%;
	transform: translateY(-50%);
	font-size: 1.4rem;
}
.viewer__nav--prev {
	left: clamp(0.25rem, 1.5vw, 1rem);
}
.viewer__nav--next {
	right: clamp(0.25rem, 1.5vw, 1rem);
}

/* =========================================================
   Adaptations des nouvelles pages
   ========================================================= */

@media (max-width: 900px) {
	.wall {
		grid-template-columns: repeat(3, 1fr);
	}
	/* Sur trois colonnes, deux colonnes en 3:2 ne font plus la hauteur
	   d'une colonne en 3:4 : le paysage passe en pleine rangée. */
	.piece--landscape {
		grid-column: span 3;
	}
	.piece--landscape .piece__img,
	.piece--landscape .piece__loop video {
		aspect-ratio: 21 / 9;
	}
	.masthead__menu {
		font-size: 0.6rem;
		gap: 0.85rem;
	}
}

@media (max-width: 560px) {
	.wall {
		grid-template-columns: repeat(2, 1fr);
	}
	.piece--landscape {
		grid-column: span 2;
	}
	.piece--landscape .piece__img,
	.piece--landscape .piece__loop video {
		aspect-ratio: 3 / 2;
	}
	.piece__caption {
		opacity: 1;
		font-size: 0.58rem;
		padding: 0.6rem;
	}
	.viewer__nav {
		top: auto;
		bottom: clamp(3rem, 9vw, 4.5rem);
		transform: none;
	}
}

/* =========================================================
   Curseur personnalisé

   Le curseur natif n'est masqué que lorsque le remplaçant est en place
   (classe posée par le script après chargement de l'image). Sans cette
   précaution, une image manquante laisserait le site sans curseur.
   ========================================================= */

/* `cursor` est héritée : la poser sur <html> suffit, et évite d'écrire
   une liste de sélecteurs qu'il faudrait tenir à jour. */
html.has-custom-cursor,
html.has-custom-cursor * {
	cursor: none;
}

/* Exception : dans un champ de saisie, le curseur texte est une
   information, pas une décoration. */
html.has-custom-cursor input,
html.has-custom-cursor textarea,
html.has-custom-cursor [contenteditable] {
	cursor: text;
}

/* Le conteneur ne porte QUE la position. Aucune autre transformation
   ici : mélanger `transform` et la propriété `scale` sur un même élément
   multiplie la translation par l'échelle, et le curseur dérive. */
.mw-cursor {
	position: fixed;
	top: 0;
	left: 0;
	z-index: 9999;
	width: 0;
	height: 0;
	pointer-events: none;
	opacity: 0;
	will-change: transform;
	transition: opacity 0.2s;
	/* Le curseur ne doit jamais peser sur la mise en page ni élargir la
	   zone de défilement, même projeté hors de l'écran. */
	contain: layout style;
}
.mw-cursor.is-visible {
	opacity: 1;
}

/* L'enfant porte l'image et le grossissement, centré sur le point du
   pointeur. Son échelle est donc totalement indépendante de la position. */
.mw-cursor__art {
	display: block;
	position: absolute;
	top: 0;
	left: 0;
	translate: -50% -50%;
	background-repeat: no-repeat;
	background-position: center;
	background-size: contain;
	pointer-events: none;
	transition: transform 0.25s cubic-bezier(0.2, 0.8, 0.25, 1);
	transform: scale(1);
}

/* Au-dessus d'un élément cliquable : le curseur grossit. C'est ce qui
   remplace le changement de forme que le système assurait. */
.mw-cursor.is-active .mw-cursor__art {
	transform: scale(1.35);
}

/* Les deux images du curseur — repos et clic — sont superposées en
   permanence et ne font que permuter leur opacité. Rien n'est créé au
   moment du clic : la réaction est donc immédiate, sans l'attente d'un
   chargement. L'opacité n'est volontairement pas animée ; une transition,
   même courte, se verrait comme un flottement au clic. */
.mw-cursor__art--click {
	opacity: 0;
}
.mw-cursor.is-clicking .mw-cursor__art--still {
	opacity: 0;
}
.mw-cursor.is-clicking .mw-cursor__art--click {
	opacity: 1;
}

/* Le curseur masqué est une gêne pour qui navigue au clavier ou a
   demandé moins d'animations : dans ces cas, on garde le curseur système. */
@media (prefers-reduced-motion: reduce) {
	html.has-custom-cursor,
	html.has-custom-cursor * {
		cursor: auto;
	}
	.mw-cursor {
		display: none;
	}
}
