/*
Theme Name: TG — Thème
Description: Thème sur mesure du site de Thomas Goumarre — aucune dépendance tierce. Toutes les valeurs viennent de docs/06-design-system.md.
Version: 0.1.0
Author: Thomas Goumarre
Text Domain: tg-theme
Requires PHP: 8.0
*/

/* ------------------------------------------------------------------ */
/* 1. Jetons — docs/06-design-system.md §2 à §4.                        */
/*    Toute valeur modifiée ici doit l'être aussi dans le document.     */
/* ------------------------------------------------------------------ */

:root {
	--fond: #FFFFFF; /* Blanc pur depuis le Lot 8.14 (demande de Thomas) ; était le crème #FAF8F4. */
	--texte: #2A2622;
	--texte-secondaire: #6B665E;
	--trait: #DEDACF;
	/* « Lin », plus utilisée comme fond depuis le Lot 8.14 : tout ce qui
	   portait --taupiniere prend maintenant --fond (demande de Thomas —
	   « remplacé par la couleur actuelle de l'arrière-plan »). Gardée en
	   référence pour la page de démonstration, comme les accents de
	   thématique ci-dessous. */
	--taupiniere: #D8D1CA;

	/* Couleur de marque (Lot 8.14, remplace les accents de thématique
	   ci-dessous). --vert est la teinte donnée par Thomas telle quelle : sur
	   un fond plein (barre de menu, étiquettes), le texte ou l'icône posés
	   dessus doivent être blancs, jamais --fond (4,4:1 seulement, sous le
	   seuil AA). --vert-texte est la même teinte assombrie, pour porter du
	   texte ou un filet directement sur --fond (6,0:1, quand --vert seul n'y
	   passe qu'à 4,4:1). */
	--vert: #3C8247;
	--vert-texte: #2E6B3B;

	/* Anciens accents des thématiques — plus utilisés dans les gabarits
	   depuis le Lot 8.14 (remplacés par --vert partout), gardés en
	   référence pour la page de démonstration et l'historique. Le champ
	   « Couleur d'accent » de chaque thématique existe toujours dans
	   l'administration ; rien n'y a été perdu, mais son réglage ne s'affiche
	   plus nulle part sur le site. */
	--accent-crassiers: #A34A1F;
	--accent-chats-libres: #4A6B2E;
	--accent-chemin-de-fer: #2E5266;

	--police: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
	--taille-corps: 1.125rem;  /* 18 px */
	--taille-petit: 0.875rem;  /* 14 px — plancher absolu, jamais en dessous */
	--taille-h1: clamp(2rem, 1.6rem + 1.6vw, 2.75rem);
	--taille-h2: 1.75rem;
	--taille-h3: 1.25rem;

	--s1: 8px;
	--s2: 16px;
	--s3: 24px;
	--s4: 32px;
	--s5: 48px;
	--s6: 64px;
	--s7: 96px;

	--mesure: 65ch;
	--largeur-page: 58rem;
}

/* ------------------------------------------------------------------ */
/* 2. Base                                                              */
/* ------------------------------------------------------------------ */

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

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

body {
	margin: 0;
	background: var(--fond);
	color: var(--texte);
	font-family: var(--police);
	font-size: var(--taille-corps);
	line-height: 1.5;
}

img {
	max-width: 100%;
	height: auto;
}

h1,
h2,
h3 {
	font-weight: 700;
	margin: 0 0 var(--s2);
}

h1 { font-size: var(--taille-h1); line-height: 1.1; }
h2 { font-size: var(--taille-h2); line-height: 1.2; }
h3 { font-size: var(--taille-h3); line-height: 1.25; }

p,
ul,
ol,
dl,
blockquote {
	margin: 0 0 var(--s2);
}

/* La règle qui règle la moitié des problèmes de lisibilité (06 §3). */
.contenu p,
.contenu li {
	max-width: var(--mesure);
}

/* Un lien est toujours souligné : jamais signalé par la couleur seule. */
a {
	color: var(--vert-texte);
	text-decoration: underline;
	text-decoration-thickness: 1px;
	text-underline-offset: 0.2em;
}

a:hover {
	text-decoration-thickness: 2px;
}

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

/* Les blocs pleine largeur (carte générale, registre de La Taupinière)
   mesurent 100vw, barre de défilement comprise : sans ceci, la page glisse
   de quelques pixels sur le côté dès qu'une barre est affichée (Windows,
   souris branchée). Il faut les deux règles, vérifié dans Chrome au Lot 8 :
   seule, celle de <body> remonte à la fenêtre et n'empêche rien ; seule,
   celle de <html> bloque la souris mais laisse un script ou le passage au
   clavier décaler la page. Ensemble, <body> coupe vraiment ce qui dépasse,
   sans devenir une zone de défilement. Réservé aux navigateurs qui
   connaissent « clip » : ailleurs, le petit décalage reste. */
@supports (overflow-x: clip) {
	html {
		overflow-x: hidden;
	}

	body {
		overflow-x: clip;
	}
}

/* ------------------------------------------------------------------ */
/* 3. Utilitaires                                                       */
/* ------------------------------------------------------------------ */

.visuellement-cache {
	position: absolute !important;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

.lien-evitement {
	position: absolute;
	top: -100px;
	left: var(--s2);
	z-index: 1200; /* Au-dessus de la barre fixe (1100, §4). */
	padding: var(--s1) var(--s2);
	background: var(--texte);
	color: var(--fond);
}

.lien-evitement:focus {
	top: var(--s2);
}

.conteneur {
	max-width: var(--largeur-page);
	margin-inline: auto;
	padding-inline: var(--s3);
}

/* ------------------------------------------------------------------ */
/* 4. En-tête — docs/04-specs-pages.md                                  */
/* ------------------------------------------------------------------ */

/* Barre en pilule flottante, fixe au défilement — demande de Thomas
   d'après jimmybeauquesne.com, avec un effet de verre dépoli en plus (§4
   bis). Fixe et non plus dans le flux (Lot 8.14, première version) : sans
   ça, rien ne passerait derrière elle et le verre n'aurait rien à
   dépolir. La page Cartes en profite le mieux (carte-panneau plus bas) :
   la carte touche maintenant le tout haut de l'écran, sous la barre.
   « entete » couvre toute la largeur mais reste transparente aux clics
   (pointer-events: none) hors de la pilule elle-même, sans quoi la bande
   vide de part et d'autre bloquerait la carte en dessous. */
.entete {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	z-index: 1100; /* Au-dessus du panneau de la page Cartes (1000, §9). */
	display: flex;
	justify-content: center;
	padding: var(--s3) var(--s3) 0;
	pointer-events: none;
}

.entete__barre {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: 2px;
	max-width: 100%;
	padding: 6px;
	/* 28px et non 999px : sur une seule ligne (44 + 12 px de haut), l'effet
	   est le même — pleinement arrondi ; sur un téléphone étroit, où le
	   menu passe sur 2 ou 3 lignes, 999px aurait donné un très grand rayon
	   des deux côtés du bloc, une forme disproportionnée. */
	border-radius: 28px;
	pointer-events: auto;
	/* Verre dépoli : fond --vert translucide (0,62 — assez pour rester
	   lisible comme « vert » sur n'importe quel arrière-plan, assez peu
	   pour qu'on voie franchement au travers) + flou de ce qui passe
	   dessous. Le filet blanc à 25 % vend l'effet de bord en verre. Sans
	   backdrop-filter (vieux navigateurs), le fond translucide seul reste
	   lisible, juste sans le flou. */
	background: rgba(60, 130, 71, 0.62);
	border: 1px solid rgba(255, 255, 255, 0.28);
	box-shadow: 0 4px 24px rgba(42, 38, 34, 0.22);
	backdrop-filter: blur(20px) saturate(180%);
	-webkit-backdrop-filter: blur(20px) saturate(180%);
}

/* Émoji maison plutôt qu'un monogramme texte (Thomas, Lot 8.14) : même
   traitement que les icônes du menu (Cartes, Taupinière) — taille et
   cercle assortis. */
.entete__logo {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	min-height: 44px;
	border-radius: 999px;
	color: #FFFFFF;
	font-size: 1.25rem;
	text-decoration: none;
}

.menu {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 2px;
	margin: 0;
	padding: 0;
	list-style: none;
}

.menu a {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 44px; /* « Bio » seul ne faisait que 25 px de large (Lot 8). */
	min-height: 44px;
	padding: 0 var(--s2);
	border-radius: 999px;
	color: #FFFFFF;
	font-weight: 700;
	text-decoration: none;
}

/* Cartes et Taupinière : une icône seule (émoji du système du visiteur —
   pas le rendu Apple partout, choix de Thomas au Lot 8.14), cercle plutôt
   que pilule, nom porté par aria-label puisque l'émoji seul ne se lit pas
   de façon fiable au lecteur d'écran. */
.menu a.menu__icone {
	width: 44px;
	padding: 0;
	font-size: 1.25rem;
}

/* Survol/focus — inspiré du « dock » de portfolio-magicui.vercel.app
   (demande de Thomas) : chaque bouton grandit légèrement au survol ou au
   clavier. Jamais de soulignement, remplacé par l'agrandissement ; pas de
   bulle de nom au survol (Thomas ne la voulait pas) ni d'effet
   d'aimantation sur les icônes voisines du site de référence (demanderait
   de suivre la souris en JavaScript) — seule l'icône survolée bouge. */
.entete__logo,
.menu a {
	transition: transform 150ms ease, background-color 150ms ease;
}

.entete__logo:hover,
.entete__logo:focus-visible,
.menu a:hover,
.menu a[aria-current="page"] {
	transform: scale(1.12);
	background: rgba(255, 255, 255, 0.28);
	z-index: 1; /* Passe au-dessus de ses voisins pendant l'agrandissement. */
}

/* Barre compacte sous 48rem (Thomas, Lot 8.14) : les 6 éléments à taille
   pleine (44 px, texte à 18 px) demandent environ 410 px, alors qu'un
   téléphone n'en offre que 270 à 380 px d'utile — ils passaient sur 2 ou
   3 lignes. Réduits, ils tiennent sur une seule ligne à partir de ~360 px
   (vérifié) ; en dessous (un vieil iPhone SE, 320 px), il reste possible
   qu'un élément déborde sur une deuxième ligne — accepté par Thomas,
   plutôt que de perdre le texte des boutons ou tout réduire encore. */
@media (max-width: 48rem) {
	.entete__barre {
		gap: 1px;
		padding: 4px;
	}

	.entete__logo,
	.menu a {
		min-width: 34px;
		min-height: 34px;
	}

	.entete__logo,
	.menu a.menu__icone {
		width: 34px;
		font-size: 1rem;
	}

	.menu a {
		padding: 0 8px;
		font-size: 0.8rem;
	}
}

/* Dégage la barre fixe (≈ 82 px : var(--s3) au-dessus + la pilule) avec
   une marge de respiration ; la page Cartes remet ce dégagement à zéro
   (§9) pour que la carte touche vraiment le haut de l'écran. */
.principal {
	padding-top: calc(var(--s7) + var(--s2));
	padding-bottom: var(--s5);
}

/* ⚠️ Sur téléphone, la barre compacte (ci-dessus) tient sur une seule
   ligne à partir de 360 px de large (vérifié à 360, 375, 390 px) ; en
   dessous, sur un très vieil iPhone SE (320 px), elle reste sur 2 lignes,
   79 px de haut. Un dégagement pensé pour ce pire cas plutôt que pour le
   cas courant, sans quoi la barre recouvrirait le haut de la page — c'est
   exactement ce que Thomas a vu sur son iPhone le 27/09/2026, avant ce
   correctif. */
@media (max-width: 48rem) {
	.principal {
		padding-top: calc(var(--s7) + var(--s4));
	}
}

@media (min-width: 48rem) {
	.principal {
		padding-bottom: var(--s6);
	}
}

/* ------------------------------------------------------------------ */
/* 5. Pied de page — docs/04-specs-pages.md                             */
/*    Un seul pied sur tout le site (Lot 8.11) : les deux liens         */
/*    légaux, centrés. Le pied à deux colonnes, qui répétait les liens  */
/*    de l'accueil sur chaque page, a été supprimé à la demande de      */
/*    Thomas.                                                           */
/* ------------------------------------------------------------------ */

.pied {
	padding: var(--s4) var(--s3);
	border-top: 1px solid var(--trait);
	text-align: center;
}

.pied__mentions {
	margin: 0;
	color: var(--texte-secondaire);
	font-size: var(--taille-petit);
}

.pied__mentions a {
	color: var(--texte);
}

/* Le logo de La Taupinière sur la page de démonstration : une gravure
   noire sur fond blanc, que « multiply » pose sur le marron en faisant
   disparaître son fond. (Il habillait le pied de page à deux colonnes
   jusqu'au Lot 8.11.) */
.demo-logo-taupiniere {
	display: block;
	width: 120px;
	height: auto;
	margin-bottom: var(--s2);
	mix-blend-mode: multiply;
}

/* ------------------------------------------------------------------ */
/* 6. Composants — docs/06-design-system.md §6                          */
/* ------------------------------------------------------------------ */

/* Boutons */

.bouton {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 44px;
	padding: 0 var(--s3);
	border: 1px solid var(--texte);
	border-radius: 2px;
	background: transparent;
	color: var(--texte);
	font: inherit;
	font-size: var(--taille-petit);
	font-weight: 700;
	text-decoration: none;
	cursor: pointer;
}

.bouton:hover {
	background: var(--texte);
	color: var(--fond);
}

.bouton--principal {
	background: var(--texte);
	color: var(--fond);
}

.bouton--principal:hover {
	background: transparent;
	color: var(--texte);
}

/* Étiquettes */

.etiquettes {
	display: flex;
	flex-wrap: wrap;
	gap: var(--s1);
	margin: 0 0 var(--s2);
	padding: 0;
	list-style: none;
}

.etiquette {
	display: inline-block;
	padding: 2px var(--s1);
	border: 1px solid var(--texte);
	border-radius: 2px;
	color: var(--texte);
	font-size: var(--taille-petit);
	line-height: 1.3;
}

/* Fond --vert, texte blanc (4,7:1) : --fond, plus crème, n'y passerait pas
   (4,4:1, sous le seuil AA) — voir la note sur --vert en tête de fichier. */
.etiquette--thematique {
	border-color: var(--vert);
	background: var(--vert);
	color: #FFFFFF;
}

/* Fiche de métadonnées (inspirée des fiches de forensic-architecture.org) */

.fiche {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
	margin: 0 0 var(--s4);
	border-top: 2px solid var(--vert-texte);
}

.fiche__item {
	padding: var(--s2) var(--s2) var(--s2) 0;
	border-bottom: 1px solid var(--trait);
}

.fiche dt {
	margin-bottom: 4px;
	color: var(--texte-secondaire);
	font-size: var(--taille-petit);
	letter-spacing: 0.06em;
	text-transform: uppercase;
}

.fiche dd {
	margin: 0;
}

/* Vignettes de projet */

.vignettes {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
	gap: var(--s5) var(--s4);
	margin: 0;
	padding: 0;
	list-style: none;
}

.vignette {
	padding-top: var(--s2);
	border-top: 3px solid var(--vert-texte);
}

.vignette__image {
	display: flex;
	align-items: center;
	justify-content: center;
	aspect-ratio: 4 / 3;
	margin-bottom: var(--s2);
	background: var(--trait);
	color: var(--texte);
	font-size: var(--taille-petit);
}

.vignette__titre {
	font-size: var(--taille-h3);
}

.vignette__titre a {
	color: var(--texte);
	text-decoration: none;
}

.vignette__titre a:hover {
	text-decoration: underline;
}

.vignette__meta,
.vignette__resume {
	color: var(--texte-secondaire);
	font-size: var(--taille-petit);
}

/* Citation et note en marge */

.citation {
	margin: var(--s4) 0;
	padding-left: var(--s3);
	border-left: 3px solid var(--texte);
}

.citation p {
	font-size: 1.25rem;
	line-height: 1.4;
}

.citation__source {
	color: var(--texte-secondaire);
	font-size: var(--taille-petit);
}

.note {
	max-width: 18rem;
	padding-top: var(--s1);
	border-top: 1px solid var(--trait);
	color: var(--texte-secondaire);
	font-size: var(--taille-petit);
	line-height: 1.45;
}

/* Registre Taupinière — section, bloc « dernières vidéos » */

.registre-taupiniere {
	padding: var(--s5) var(--s4);
	background: var(--fond);
	color: var(--texte);
}

.registre-taupiniere a {
	color: var(--texte);
}

/* --trait disparaîtrait sur le marron : les emplacements d'image prennent le fond crème. */
.registre-taupiniere .vignette__image {
	background: var(--fond);
}

/* ------------------------------------------------------------------ */
/* 7. Page de démonstration uniquement                                  */
/* ------------------------------------------------------------------ */

.demo-section {
	padding-block: var(--s5);
	border-top: 1px solid var(--trait);
}

.demo-rangee {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--s2);
	margin: 0 0 var(--s3);
	padding: 0;
	list-style: none;
}

.demo-nuancier {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
	gap: var(--s3);
	margin: 0;
	padding: 0;
	list-style: none;
	font-size: var(--taille-petit);
}

.demo-pastille {
	height: 72px;
	margin-bottom: var(--s1);
	border: 1px solid var(--trait);
}

.demo-code {
	font-family: ui-monospace, Menlo, monospace;
}

.demo-deux-colonnes {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--s4);
}

@media (min-width: 48rem) {
	.demo-deux-colonnes {
		grid-template-columns: minmax(0, var(--mesure)) 18rem;
		align-items: start;
	}
}

.demo-espace {
	height: 12px;
	margin-bottom: var(--s1);
	background: var(--texte);
}

/* ------------------------------------------------------------------ */
/* 8. Page projet — carnet de bord. docs/04-specs-pages.md §3 et        */
/*    docs/06-design-system.md §5.                                      */
/*                                                                      */
/*    Trois largeurs :                                                  */
/*    - moins de 68rem : une colonne, les blocs en marge passent sous   */
/*      leur passage, sommaire replié en haut ;                         */
/*    - de 68 à 86rem : marges gauche et droite, sommaire replié ;      */
/*    - à partir de 86rem : sommaire en colonne fixe à gauche.          */
/* ------------------------------------------------------------------ */

@media (prefers-reduced-motion: no-preference) {
	html {
		scroll-behavior: smooth;
	}
}

.projet {
	max-width: 96rem;
	margin-inline: auto;
	padding-inline: var(--s3);
}

.ariane {
	display: flex;
	flex-wrap: wrap;
	gap: 0 var(--s1);
	margin: 0 0 var(--s3);
	padding: 0;
	list-style: none;
	color: var(--texte-secondaire);
	font-size: var(--taille-petit);
}

.ariane li + li::before {
	content: "›";
	margin-right: var(--s1);
}

.projet__titre {
	max-width: 30ch;
	margin-bottom: var(--s4);
}

.projet__intro {
	display: grid;
	gap: var(--s4);
	margin-bottom: var(--s6);
}

@media (min-width: 60rem) {
	.projet__intro {
		grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
		align-items: start;
	}
}

/* Section Taupinière de la page projet — sobre, à la manière d'une
   discrète recommandation plutôt que d'un second en-tête. */

.projet__taupiniere {
	grid-column: 1 / -1;
	padding: var(--s3);
	border: 1px solid var(--trait); /* Sans lui, la carte se fondrait dans la page — même fond que tout le reste depuis le Lot 8.14. */
	border-radius: 12px;
	background: var(--fond);
	color: var(--texte);
}

.projet__taupiniere-titre {
	margin: 0 0 var(--s2);
	font-size: var(--taille-petit);
	font-weight: 700;
	letter-spacing: 0.08em;
	text-transform: uppercase;
}

.taupiniere-videos {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
	gap: var(--s3) var(--s2);
	margin: 0;
	padding: 0;
	list-style: none;
}

.taupiniere-video a {
	display: block;
	color: var(--texte);
	text-decoration: none;
}

.taupiniere-video__vignette {
	display: flex;
	align-items: center;
	justify-content: center;
	aspect-ratio: 16 / 9;
	margin-bottom: var(--s1);
	background: var(--fond);
}

.taupiniere-video__vignette img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.taupiniere-video__titre {
	display: -webkit-box;
	overflow: hidden;
	font-size: var(--taille-petit);
	font-weight: 700;
	line-height: 1.35;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
}

.taupiniere-video a:hover .taupiniere-video__titre {
	text-decoration: underline;
}

.taupiniere-video__meta {
	display: block;
	margin-top: 2px;
	font-size: 0.75rem;
}

/* Carte du projet — voir §9 pour le détail (carte générale comprise). */
.carte {
	height: 20rem;
	border: 1px solid var(--trait);
	background: var(--fond);
}

/* Sur la page d'un lieu, la carte porte le lieu, ses sous-lieux, leurs
   promenades et leurs périmètres : il lui faut plus de hauteur (Lot 8.5). */
.transversale .carte {
	height: 28rem;
	margin-bottom: var(--s4);
}

.carnet {
	padding-top: var(--s5);
	border-top: 2px solid var(--vert-texte);
}

/* Sommaire */

.sommaire {
	margin-bottom: var(--s5);
	padding: 0 var(--s2);
	border: 1px solid var(--trait);
}

.sommaire__titre {
	display: flex;
	align-items: center;
	min-height: 44px;
	font-weight: 700;
	cursor: pointer;
}

.sommaire__liste {
	margin: 0 0 var(--s2);
	padding: 0;
	list-style: none;
	font-size: var(--taille-petit);
}

.sommaire__lien {
	display: flex;
	align-items: center;
	gap: var(--s1);
	min-height: 44px;
	padding: 4px 0 4px var(--s2);
	border-left: 2px solid var(--trait);
	color: var(--texte);
	line-height: 1.3;
	text-decoration: none;
}

.sommaire__lien:hover {
	text-decoration: underline;
}

/* Chapitre en cours : trait de couleur ET gras — jamais la couleur seule. */
.sommaire__lien[aria-current="true"] {
	border-left-color: var(--vert-texte);
	font-weight: 700;
}

.sommaire__numero {
	min-width: 1.25em;
	color: var(--texte-secondaire);
	font-variant-numeric: tabular-nums;
}

.sommaire__suivant {
	display: inline-flex;
	align-items: center;
	gap: var(--s1);
	min-height: 44px;
	margin-bottom: var(--s1);
	font-size: var(--taille-petit);
	font-weight: 700;
}

.sommaire__suivant[hidden] {
	display: none;
}

@media (min-width: 86rem) {
	.carnet {
		display: grid;
		grid-template-columns: 13rem minmax(0, 1fr);
		column-gap: var(--s4);
		align-items: start;
	}

	.sommaire-zone {
		position: sticky;
		top: var(--s3);
		max-height: calc(100vh - var(--s5));
		overflow-y: auto;
	}

	.sommaire {
		margin: 0;
		padding: 0;
		border: 0;
	}

	.sommaire__titre {
		display: none;
	}

	.sommaire__liste::before {
		content: "Sommaire";
		display: block;
		margin-bottom: var(--s1);
		font-weight: 700;
		letter-spacing: 0.08em;
		text-transform: uppercase;
	}
}

/* Chapitres */

.chapitre {
	scroll-margin-top: var(--s3);
}

.chapitre + .chapitre {
	margin-top: var(--s7);
}

/* Surtitres « Chapitre 1 » et « Étape A » : même style, demandé par Thomas. */
.chapitre__numero,
.rangee__etape {
	margin-bottom: var(--s1);
	color: var(--vert-texte);
	font-size: var(--taille-petit);
	font-weight: 700;
	letter-spacing: 0.08em;
	text-transform: uppercase;
}

.chapitre__entete h2 {
	margin-bottom: var(--s1);
	font-size: 2rem;
	line-height: 1.15;
}

.chapitre__date {
	color: var(--texte-secondaire);
	font-size: var(--taille-petit);
}

.chapitre__date--manquante {
	font-style: italic;
}

/* Rangées : un passage au centre, ses blocs en marge sur la même ligne */

.rangee {
	display: grid;
	grid-template-columns: minmax(0, var(--mesure));
	gap: var(--s2);
	margin-bottom: var(--s2);
}

.rangee--titre {
	margin-top: var(--s5);
}

.rangee__texte > :last-child {
	margin-bottom: 0;
}

.rangee__texte ul,
.rangee__texte ol {
	padding-left: 1.25em;
}

/* Intertitres du carnet, agrandis à la demande de Thomas : 24 px (chapitre : 32 px). */
.rangee__texte h3 {
	font-size: 1.5rem;
	line-height: 1.2;
}

.rangee__texte h4 {
	font-size: var(--taille-h3);
}

.rangee__marge {
	display: grid;
	gap: var(--s3);
	align-content: start;
}

@media (min-width: 68rem) {
	.rangee {
		grid-template-columns: minmax(0, 1fr) minmax(0, var(--mesure)) minmax(0, 1fr);
		column-gap: var(--s4);
		align-items: start;
	}

	.rangee__texte {
		grid-column: 2;
		grid-row: 1;
	}

	.rangee__marge {
		width: 100%;
		max-width: 18rem;
		grid-row: 1;
	}

	.rangee__marge--gauche {
		grid-column: 1;
		justify-self: end;
	}

	.rangee__marge--droite {
		grid-column: 3;
		justify-self: start;
	}
}

/* Blocs du carnet */

.figure {
	margin: 0;
}

.figure--centre {
	margin-block: var(--s2);
}

.figure__image {
	display: block;
	width: 100%;
	height: auto;
}

.figure figcaption {
	margin-top: var(--s1);
	color: var(--texte-secondaire);
	font-size: var(--taille-petit);
	line-height: 1.45;
}

.figure__credit {
	display: block;
}

.figure__vide {
	display: flex;
	align-items: center;
	justify-content: center;
	aspect-ratio: 4 / 3;
	background: var(--trait);
	color: var(--texte);
	font-size: var(--taille-petit);
}

/* Élément encore à ajouter (case à cocher Notion) — visible le temps de l'écriture. */
.a-ajouter {
	margin: 0;
	padding: var(--s1) var(--s2);
	border: 1px dashed var(--texte-secondaire);
	color: var(--texte);
	font-size: var(--taille-petit);
	line-height: 1.45;
}

.a-ajouter--centre {
	margin-block: var(--s2);
}

.a-ajouter__etiquette {
	display: block;
	font-weight: 700;
	letter-spacing: 0.06em;
	text-transform: uppercase;
}

.separateur {
	margin: var(--s4) 0;
	border: 0;
	border-top: 1px solid var(--trait);
}

/* Agrandir une image — le lien autour de l'image, et la visionneuse plein écran. */

.figure__agrandir {
	position: relative;
	display: block;
	text-decoration: none;
	cursor: zoom-in;
}

.figure__loupe {
	position: absolute;
	right: var(--s1);
	bottom: var(--s1);
	padding: 2px var(--s1);
	background: var(--fond);
	color: var(--texte);
	font-size: var(--taille-petit);
	line-height: 1.3;
}

.figure__agrandir:hover .figure__loupe,
.figure__agrandir:focus-visible .figure__loupe {
	text-decoration: underline;
}

.visionneuse {
	width: 100vw;
	height: 100vh;
	height: 100dvh;
	max-width: none;
	max-height: none;
	margin: 0;
	padding: var(--s6) var(--s3) var(--s3);
	border: 0;
	background: var(--texte);
	color: var(--fond);
}

.visionneuse[open] {
	display: flex;
	align-items: center;
	justify-content: center;
}

.visionneuse__figure {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--s2);
	width: 100%;
	height: 100%;
	margin: 0;
	justify-content: center;
}

.visionneuse__image {
	max-width: 100%;
	max-height: calc(100% - 4rem);
	object-fit: contain;
}

.visionneuse__legende {
	max-width: var(--mesure);
	font-size: var(--taille-petit);
	text-align: center;
}

.visionneuse__fermer {
	position: absolute;
	top: var(--s2);
	right: var(--s2);
	gap: var(--s1);
	border-color: var(--fond);
	color: var(--fond);
}

.visionneuse__fermer:hover {
	background: var(--fond);
	color: var(--texte);
}

.visionneuse :focus-visible {
	outline-color: var(--fond);
}

/* Pas de défilement de la page derrière l'image agrandie. */
html:has(.visionneuse[open]) {
	overflow: hidden;
}

/* ------------------------------------------------------------------ */
/* 9. Cartes — docs/04-specs-pages.md §3.1 et §4, docs/06 §6. Lot 4.    */
/*    Fond de carte et interactions : assets/carte.js (Leaflet).       */
/* ------------------------------------------------------------------ */

.carte--vide {
	display: flex;
	align-items: center;
	justify-content: center;
	color: var(--texte-secondaire);
	font-size: var(--taille-petit);
	text-align: center;
}

/* Habillage des contrôles Leaflet, pour qu'ils empruntent la police et les
   couleurs du site plutôt que le gris par défaut de la bibliothèque. */
.leaflet-popup-content-wrapper,
.leaflet-popup-tip {
	border-radius: 2px;
}

.leaflet-popup-content {
	margin: var(--s2);
	font-family: var(--police);
	font-size: var(--taille-petit);
}

.leaflet-popup-content a {
	font-weight: 700;
}

/* Boutons + et − à 44 px, la taille minimale d'une cible tactile (docs/06),
   au lieu de 30. Sélecteur renforcé : la feuille de Leaflet se charge après
   celle du thème (Lot 8). */
.carte.leaflet-container .leaflet-bar a {
	width: 44px;
	height: 44px;
	font-size: 22px;
	line-height: 44px;
}

.carte-popup__details {
	margin: 4px 0 0;
	color: var(--texte-secondaire);
}

/* La bulle d'un lieu : son nom, puis tout ce qui s'y rattache (Lot 8.1 —
   un marqueur par lieu, et non un par projet). */
.carte-popup__lieu {
	margin: 0 0 var(--s1);
	font-weight: 700;
}

.carte-popup__liste {
	margin: 0;
	padding: 0;
	list-style: none;
}

.carte-popup__liste li + li {
	margin-top: var(--s1);
	padding-top: var(--s1);
	border-top: 1px solid var(--trait);
}

.carte-popup__liste .carte-popup__details {
	display: block;
}

/* Symboles — jamais la couleur seule (docs/06 §6) : une forme par type
   d'intervention, plus une quatrième pour les contenus Taupinière. Un
   filet clair les détache du fond de carte, quelle que soit sa couleur. */
/* Le marqueur posé sur la carte occupe 24 px — la cible minimale des
   WCAG 2.2 — et centre dedans son symbole de 14 px : la zone qu'on peut
   viser grandit, le dessin ne bouge pas (Lot 8.1). */
.marqueur-carte {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: center;
}

/* Un lieu qui porte plusieurs projets ou vidéos le dit par un compteur —
   sans lui, deux marqueurs confondus n'en montraient qu'un (Lot 8.1).
   Le nombre est décoratif : le nom du marqueur l'annonce déjà en toutes
   lettres (« Saint-Étienne — 2 contenus »). */
.marqueur-nombre {
	position: absolute;
	top: -3px;
	right: -5px;
	min-width: 15px;
	height: 15px;
	padding: 0 3px;
	border-radius: 8px;
	background: var(--fond);
	box-shadow: 0 1px 2px rgba(0, 0, 0, 0.45);
	color: var(--texte);
	font-size: 10px;
	font-weight: 700;
	line-height: 15px;
	text-align: center;
}

/* filter et non box-shadow : reste correct avec clip-path (triangle),
   contrairement à un box-shadow qui serait découpé en même temps. */
.marqueur {
	display: block;
	width: 14px;
	height: 14px;
	background: var(--marqueur-couleur, var(--texte));
	filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.45));
}

.marqueur--enquete {
	border-radius: 50%;
}

.marqueur--realisation {
	clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
}

.marqueur--partenariat {
	border-radius: 2px;
}

.marqueur--taupiniere {
	border-radius: 2px;
	transform: rotate(45deg);
}

/* Petit aperçu de forme à côté d'une case de filtre — même classes que
   les marqueurs de la carte, sans les positionner en icône Leaflet. */
.carte-filtres__groupe .marqueur {
	display: inline-block;
	vertical-align: -2px;
	--marqueur-couleur: var(--texte);
}

/* Page Cartes en plein écran — Lot 8.6, demande de Thomas : la carte
   occupe tout ce qui reste sous la barre du haut, les filtres sont posés
   dessus dans un panneau à onglet, et la page ne défile pas. L'habillage
   est celui du site : coins arrondis, filets discrets, fond crème,
   transitions courtes. (Il venait des pastilles de l'accueil, retirées
   au Lot 8.7 ; il tient seul depuis. Voir docs/06 §6.) */

/* Colonne plutôt que calcul de hauteur : l'en-tête peut grandir (menu sur
   deux lignes à l'étroit) sans qu'on ait à le soustraire nulle part. */
body.carte-pleine-page {
	display: flex;
	flex-direction: column;
	min-height: 100svh;
	overflow: hidden;
}

/* Chaîne de hauteurs en flex jusqu'à la carte : un « height: 100% » ne
   donnerait rien ici, ses parents n'ayant pas de hauteur déclarée. */
body.carte-pleine-page .principal {
	display: flex;
	flex: 1 1 auto;
	flex-direction: column;
	min-height: 0;
	padding-block: 0; /* Le contenu respire ailleurs ; ici la carte touche l'en-tête et le bas. */
}

.carte-plein {
	position: relative;
	display: flex;
	flex: 1 1 auto;
	flex-direction: column;
	min-height: 0;
}

.carte-plein .carte {
	flex: 1 1 auto;
	height: auto; /* Annule les 20rem de la carte d'un projet (§8). */
	min-height: 0;
	border: 0;
	background: var(--fond); /* Le temps que les tuiles arrivent. */
}

/* ---- Le panneau des filtres, posé sur la carte ---- */

.carte-panneau {
	--largeur-panneau: 17rem;

	position: absolute;
	/* Dégage la barre fixe du haut (§4, ≈ 82 px) : même dégagement que
	   .principal ailleurs sur le site. */
	top: calc(var(--s7) + var(--s2));
	left: 0;
	bottom: var(--s4);
	z-index: 1000; /* Au-dessus des contrôles de Leaflet (800), sous la barre (1100, §4). */
	display: flex;
	align-items: flex-start;
	transition: transform 220ms ease;
}

/* Les boutons de zoom de Leaflet (topright, carte.js) partent du tout
   haut de la carte comme le panneau ci-dessus : même dégagement, sans
   quoi la barre fixe les couvrirait. */
body.carte-pleine-page .leaflet-top {
	top: calc(var(--s7) + var(--s2));
}

/* Sur un téléphone étroit, la barre passe sur 2 ou 3 lignes selon la
   largeur exacte (§4) : plutôt que deviner sa hauteur au pixel près, les
   boutons de zoom passent en bas de l'écran, où ils restent aussi plus
   faciles à atteindre du pouce. */
@media (max-width: 48rem) {
	body.carte-pleine-page .leaflet-top.leaflet-right {
		top: auto;
		bottom: var(--s3);
	}
}

/* Replié : seul l'onglet dépasse du bord gauche. */
.carte-panneau[data-ouvert="non"] {
	transform: translateX(calc(-1 * var(--largeur-panneau)));
}

.carte-panneau__corps {
	order: 1; /* L'onglet le précède dans le code (ordre du clavier), il se dessine après lui. */
	display: flex;
	flex-direction: column;
	gap: var(--s3);
	width: var(--largeur-panneau);
	max-height: calc(100svh - var(--s7) - var(--s2) - var(--s4) - var(--s4));
	padding: var(--s3);
	overflow-y: auto;
	border: 1px solid var(--trait);
	border-left: 0;
	border-radius: 0 6px 6px 0;
	background: rgba(250, 248, 244, 0.94); /* --fond, laissant deviner la carte dessous. */
	box-shadow: 0 2px 12px rgba(42, 38, 34, 0.12);
}

/* L'onglet : une poignée arrondie côté carte. 44 px de large, la cible
   tactile minimale (docs/06). */
.carte-panneau__onglet {
	order: 2;
	display: flex;
	align-items: center;
	gap: 6px;
	min-width: 44px;
	min-height: 44px;
	padding: var(--s1) 10px;
	border: 1px solid var(--trait);
	border-left: 0;
	border-radius: 0 16px 16px 0;
	background: rgba(250, 248, 244, 0.94);
	box-shadow: 0 2px 12px rgba(42, 38, 34, 0.12);
	color: var(--texte);
	font: inherit;
	font-size: var(--taille-petit);
	cursor: pointer;
	transition: background-color 150ms, border-color 150ms;
}

.carte-panneau__onglet:hover {
	border-color: var(--texte);
}

/* La flèche indique le geste : fermer quand le panneau est ouvert, ouvrir sinon. */
.carte-panneau__fleche {
	display: inline-block;
	width: 0;
	height: 0;
	border-top: 5px solid transparent;
	border-bottom: 5px solid transparent;
	border-right: 6px solid var(--texte);
}

.carte-panneau[data-ouvert="non"] .carte-panneau__fleche {
	border-right: 0;
	border-left: 6px solid var(--texte);
}

/* Replié, l'onglet ne garde que sa flèche : le mot « Filtres » s'efface. */
.carte-panneau[data-ouvert="non"] .carte-panneau__onglet-texte {
	display: none;
}

.carte-panneau__section {
	display: flex;
	min-height: 0;
	flex-direction: column;
	gap: var(--s1);
}

.carte-panneau__legende {
	margin: 0;
	color: var(--texte-secondaire);
	font-size: var(--taille-petit);
	font-weight: 400;
	letter-spacing: 0.06em;
	text-transform: uppercase;
}

.carte-panneau__legal {
	margin: 0;
	padding-top: var(--s2);
	border-top: 1px solid var(--trait);
	color: var(--texte-secondaire);
	font-size: var(--taille-petit);
}

/* Sur un écran étroit, le panneau couvrirait la carte : il s'ouvre moins
   large, et le script le laisse replié au chargement (assets/carte.js).
   La barre peut y passer sur 2 ou 3 lignes selon la largeur exacte (§4) :
   plutôt que deviner sa hauteur au pixel près (comme pour les boutons de
   zoom plus haut), le panneau s'accroche au bas de l'écran et grandit
   vers le haut, sans jamais s'approcher de la barre. */
@media (max-width: 48rem) {
	.carte-panneau {
		--largeur-panneau: min(80vw, 17rem);
		top: auto;
		bottom: var(--s3);
	}

	.carte-panneau__corps {
		/* Le contenu du panneau (thématiques, enquêtes, types) dépasse
		   presque toujours cette hauteur : la réserve du haut doit donc
		   vraiment tenir, pas juste correspondre au cas courant — testé
		   avec les cases à cocher au complet (Lot 8.14). */
		max-height: calc(100svh - var(--s3) - var(--s7) - var(--s7));
	}
}

.carte-filtres {
	display: flex;
	flex-direction: column;
	gap: var(--s3);
}

.carte-filtres__groupe {
	margin: 0;
	padding: 0;
	border: 0;
}

.carte-filtres__groupe legend {
	margin-bottom: var(--s1);
	color: var(--texte-secondaire);
	font-size: var(--taille-petit);
	letter-spacing: 0.06em;
	text-transform: uppercase;
}

.carte-filtres__groupe label {
	display: flex;
	align-items: center;
	gap: 6px;
	min-height: 28px;
	font-size: var(--taille-petit);
}

.carte-liste {
	margin: 0;
	padding: 0;
	overflow-y: auto;
	list-style: none;
	font-size: var(--taille-petit);
}

.carte-liste li {
	padding: var(--s1) 0;
	border-bottom: 1px solid var(--trait);
}

/* 24 px de haut au moins : c'est la taille de cible minimale du niveau AA
   des WCAG 2.2 (critère 2.5.8), que ces liens de 14 px n'atteignaient pas. */
.carte-liste a,
.carte-liste__lieu {
	display: inline-block;
	min-height: 24px;
	line-height: 24px;
}

/* Les liens de l'attribution (Leaflet, Esri) ne se distinguaient que par
   leur couleur, dans un bloc de texte — le soulignement les détache. */
.leaflet-container .leaflet-control-attribution a {
	text-decoration: underline;
}

.carte-liste__lieu {
	color: var(--texte-secondaire);
	font-size: var(--taille-petit);
}

/* Le lieu porte une promenade ou un périmètre, pas seulement un point (Lot 8.5). */
.carte-liste__forme {
	color: var(--texte-secondaire);
	font-size: var(--taille-petit);
	font-variant: all-small-caps;
	letter-spacing: 0.04em;
}

.carte-liste__vide {
	color: var(--texte-secondaire);
	border-bottom: none;
}

/* ------------------------------------------------------------------ */
/* 10. Index Projets — docs/04-specs-pages.md §2. Lot 5.                */
/* ------------------------------------------------------------------ */

/* Carrousel de productions — défilement manuel uniquement, jamais
   automatique (demande explicite du cahier des charges). */

.carrousel {
	position: relative;
	margin-bottom: var(--s5);
}

.carrousel__liste {
	display: flex;
	gap: var(--s3);
	margin: 0;
	padding: 0 0 var(--s1);
	list-style: none;
	overflow-x: auto;
	scroll-snap-type: x proximity;
}

.carrousel__item {
	flex: 0 0 auto;
	width: 14rem;
	scroll-snap-align: start;
}

.carrousel__item a {
	color: var(--texte);
	text-decoration: none;
}

.carrousel__item img {
	display: block;
	width: 100%;
	aspect-ratio: 4 / 3;
	object-fit: cover;
}

.carrousel__legende {
	display: block;
	margin-top: var(--s1);
	font-size: var(--taille-petit);
}

.carrousel__fleche {
	position: absolute;
	top: 50%;
	z-index: 1;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 2.5rem;
	height: 2.5rem;
	margin-top: -1.25rem;
	border: 1px solid var(--texte);
	border-radius: 50%;
	background: var(--fond);
	color: var(--texte);
	font-size: 1.25rem;
	line-height: 1;
	cursor: pointer;
}

.carrousel__fleche--gauche {
	left: -0.75rem;
}

.carrousel__fleche--droite {
	right: -0.75rem;
}

@media (max-width: 40rem) {
	/* Pas assez de place pour des flèches en débord sur petit écran — le doigt suffit, le défilement tactile reste actif. */
	.carrousel__fleche {
		display: none;
	}
}

/* Onglets des quatre vues — cases radio pilotées en CSS pur (:has()),
   jamais de JavaScript pour un besoin aussi simple. Un navigateur trop
   ancien pour :has() affiche simplement les quatre vues à la suite :
   rien n'est perdu. */

.vues-projets__onglets {
	display: flex;
	flex-wrap: wrap;
	margin: 0 0 var(--s4);
	padding: 0;
	border: 0;
	border-bottom: 1px solid var(--trait);
}

.vues-projets__onglets label {
	margin-bottom: -1px;
	padding: var(--s2) var(--s3) var(--s2) 0;
	border-bottom: 3px solid transparent;
	color: var(--texte-secondaire);
	font-weight: 700;
	cursor: pointer;
}

.vues-projets__onglets label:hover {
	color: var(--texte);
}

.vues-projets__onglets input:checked + label {
	border-bottom-color: var(--texte);
	color: var(--texte);
}

.vues-projets__onglets input:focus-visible + label {
	outline: 2px solid var(--texte);
	outline-offset: 2px;
}

.vues-projets__panneau {
	display: none;
}

.vues-projets:has(#vue-thematique:checked) #panneau-thematique,
.vues-projets:has(#vue-enquete:checked) #panneau-enquete,
.vues-projets:has(#vue-projet:checked) #panneau-projet,
.vues-projets:has(#vue-geographie:checked) #panneau-geographie {
	display: block;
}

/* Vue Thématique — accordéon à deux niveaux, en <details> imbriqués. */

.accordeon-thematique {
	padding: var(--s3) 0;
	border-bottom: 1px solid var(--trait);
}

.accordeon-thematique__titre,
.accordeon-enquete__titre {
	display: flex;
	align-items: center;
	min-height: 44px; /* Cible tactile : le titre d'une enquête ne faisait que 27 px de haut (Lot 8). */
	cursor: pointer;
	list-style: none;
}

.accordeon-thematique__titre::-webkit-details-marker,
.accordeon-enquete__titre::-webkit-details-marker {
	display: none;
}

.accordeon-thematique__titre {
	font-size: var(--taille-h2);
	font-weight: 700;
}

.accordeon-thematique__titre::before {
	display: inline-block;
	margin-right: var(--s1);
	color: var(--vert-texte);
	content: "▶";
	font-size: var(--taille-petit);
}

.accordeon-thematique[open] > .accordeon-thematique__titre::before {
	content: "▼";
}

.accordeon-enquete {
	margin: var(--s3) 0 var(--s3) var(--s4);
	padding-left: var(--s3);
	border-left: 2px solid var(--trait);
}

.accordeon-enquete__titre {
	font-weight: 700;
}

.accordeon-enquete__meta,
.accordeon-enquete__vide,
.accordeon-thematique__vide {
	margin: 4px 0 0;
	color: var(--texte-secondaire);
	font-size: var(--taille-petit);
}

.accordeon-enquete__projets {
	margin: var(--s2) 0 0;
	padding: 0;
	list-style: none;
}

.accordeon-enquete__projets li {
	padding: 2px 0;
}

/* Vue Enquête — à plat, en cartes. */

.liste-enquetes {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
	gap: var(--s4);
	margin: 0;
	padding: 0;
	list-style: none;
}

.liste-enquetes__item {
	padding-top: var(--s2);
	border-top: 3px solid var(--vert-texte);
}

.liste-enquetes__titre {
	margin: var(--s1) 0 4px;
	font-size: var(--taille-h3);
}

.liste-enquetes__meta {
	margin: 0 0 var(--s1);
	color: var(--texte-secondaire);
	font-size: var(--taille-petit);
}

.liste-enquetes__projets {
	margin: 0;
	padding: 0;
	list-style: none;
	font-size: var(--taille-petit);
}

.liste-enquetes__projets li {
	padding: 2px 0;
}

/* Vue Projet — filtres, réutilise .vignettes (docs/06 §8). */

.index-filtres {
	display: flex;
	flex-wrap: wrap;
	gap: var(--s4);
	margin-bottom: var(--s4);
}

.index-filtres__groupe {
	margin: 0;
	padding: 0;
	border: 0;
}

.index-filtres__groupe legend {
	margin-bottom: var(--s1);
	color: var(--texte-secondaire);
	font-size: var(--taille-petit);
	letter-spacing: 0.06em;
	text-transform: uppercase;
}

.index-filtres__groupe label {
	display: block;
	margin-bottom: 4px;
	font-size: var(--taille-petit);
}

/* Vue Géographie — groupes de vignettes par territoire. */

.groupe-territoire {
	margin-bottom: var(--s5);
}

.groupe-territoire__titre {
	padding-bottom: var(--s1);
	border-bottom: 2px solid var(--trait);
}

.groupe-territoire__carte {
	margin-top: var(--s4);
}

/* ------------------------------------------------------------------ */
/* 11. Accueil — docs/04-specs-pages.md §1. Lot 8.4.                    */
/*    D'après portfolio-magicui.vercel.app (choix de Thomas) : une      */
/*    colonne étroite, huit blocs empilés (inc/accueil.php). Un bloc    */
/*    vide disparaît entièrement.                                       */
/* ------------------------------------------------------------------ */

/* Élargi à la largeur commune du site (58rem) à la demande de Thomas
   (Lot 8.11) : la colonne étroite de la référence laissait trop de vide
   à côté des cartes, et l'accueil ne s'alignait ni sur l'en-tête ni sur
   les autres pages. */
.accueil {
	display: flex;
	flex-direction: column;
	gap: var(--s6);
	max-width: var(--largeur-page);
	margin-inline: auto;
	padding-inline: var(--s3);
}

/* 1. Présentation — le nom, la phrase, la photo ronde. */

.accueil-presentation {
	display: flex;
	flex-direction: column;
	gap: var(--s3);
}

.accueil-presentation__nom {
	margin-bottom: var(--s1);
	letter-spacing: -0.02em;
}

.accueil-presentation__phrase {
	margin: 0;
	color: var(--texte-secondaire);
	font-size: var(--taille-h3);
	line-height: 1.4;
}

/* Au-dessus du nom sur téléphone, à sa droite au-delà. */
.accueil-presentation__photo {
	order: -1;
	flex: none;
	width: 96px;
	height: 96px;
	border: 1px solid var(--trait);
	border-radius: 50%;
	box-shadow: 0 0 0 4px color-mix(in srgb, var(--trait) 45%, var(--fond)), 0 12px 24px -12px rgb(42 38 34 / 35%);
	object-fit: cover;
}

@media (min-width: 48rem) {
	.accueil-presentation {
		flex-direction: row;
		align-items: flex-start;
		justify-content: space-between;
		gap: var(--s4);
	}

	.accueil-presentation__photo {
		order: 0;
		width: 128px;
		height: 128px;
	}
}

/* Titres des blocs : simples pour les listes, grands et centrés ailleurs. */

.accueil-bloc__titre {
	margin-bottom: var(--s3);
	font-size: var(--taille-h3);
}

.accueil-bloc--grand .accueil-bloc__titre {
	margin-bottom: var(--s4);
	/* Réduits de moitié (Lot 8.15, demande de Thomas) : clamp(1.875rem, 1.5rem + 1.5vw, 2.5rem) à l'origine. */
	font-size: clamp(0.9375rem, 0.75rem + 0.75vw, 1.25rem);
	letter-spacing: -0.02em;
	text-align: center;
}

.accueil-bloc__suite {
	margin: var(--s2) 0 0;
	font-size: var(--taille-petit);
}

.accueil-bloc--grand .accueil-bloc__suite {
	text-align: center;
}

.accueil-bloc__suite a {
	display: inline-flex;
	align-items: center;
	min-height: 44px;
	color: var(--texte);
}

/* 2. À propos. */

.accueil-a-propos p {
	color: var(--texte-secondaire);
	line-height: 1.65;
}

.accueil-a-propos p:last-of-type {
	margin-bottom: 0;
}

.accueil-a-propos a {
	color: var(--texte);
}

/* 3 et 4. Rangées — Enquêtes en cours, Derniers articles. */

.accueil-rangees {
	display: grid;
	gap: var(--s2);
	margin: 0;
	padding: 0;
	list-style: none;
}

.accueil-rangee__entete {
	display: flex;
	align-items: center;
	gap: 12px;
	min-height: 44px;
}

summary.accueil-rangee__entete {
	cursor: pointer;
	list-style: none;
}

summary.accueil-rangee__entete::-webkit-details-marker {
	display: none;
}

.accueil-rangee__logo {
	display: flex;
	flex: none;
	align-items: center;
	justify-content: center;
	width: 40px;
	height: 40px;
	overflow: hidden;
	border: 1px solid var(--trait);
	border-radius: 50%;
	background: var(--fond);
	box-shadow: 0 0 0 2px color-mix(in srgb, var(--trait) 45%, var(--fond));
	color: var(--texte-secondaire);
}

.accueil-rangee__logo img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* Sans image : un point de la couleur de la thématique, sur un fond qui en
   est teinté — ou une icône, pour les articles. */
.accueil-rangee__logo--vide {
	background: color-mix(in srgb, var(--vert-texte) 16%, var(--fond));
}

.accueil-rangee__logo--vide::after {
	width: 10px;
	height: 10px;
	border-radius: 50%;
	background: var(--vert-texte);
	content: "";
}

.accueil-rangee__logo--icone {
	background: var(--fond);
}

.accueil-rangee__logo--icone::after {
	content: none;
}

.accueil-rangee__textes {
	display: flex;
	flex: 1;
	flex-direction: column;
	gap: 2px;
	min-width: 0;
}

.accueil-rangee__titre {
	font-size: 1rem;
	font-weight: 700;
	line-height: 1.3;
}

.accueil-rangee__titre a {
	color: var(--texte);
}

.accueil-rangee__sous-titre,
.accueil-rangee__date {
	color: var(--texte-secondaire);
	font-size: var(--taille-petit);
	line-height: 1.35;
}

.accueil-rangee__date {
	flex: none;
	font-variant-numeric: tabular-nums;
	text-align: right;
}

/* Le chevron dit qu'une rangée se déplie ; il pivote quand elle est ouverte. */
.accueil-rangee__chevron::after {
	display: inline-block;
	margin-left: 6px;
	color: var(--texte-secondaire);
	content: "›";
	transition: transform 200ms ease-out;
}

.accueil-rangee__details[open] .accueil-rangee__chevron::after {
	transform: rotate(90deg);
}

.accueil-rangee__depliant {
	margin: var(--s1) 0 var(--s1) 52px; /* Aligné sur le texte, après la pastille (40 + 12 px). */
	color: var(--texte-secondaire);
	font-size: var(--taille-petit);
}

.accueil-rangee__depliant p {
	margin-bottom: var(--s1);
}

.accueil-rangee__legende {
	margin-top: var(--s2);
	letter-spacing: 0.06em;
	text-transform: uppercase;
}

.accueil-rangee__projets {
	margin: 0;
	padding: 0;
	list-style: none;
}

.accueil-rangee__projets a {
	display: inline-flex;
	align-items: center;
	min-height: 44px;
	color: var(--texte);
}

/* 5. Compétences — des pastilles, comme les mots-clés des cartes (§6 et 7),
   mais plus grandes et rondes ; compactes pour ne pas prendre de place
   (Lot 8.15, demande de Thomas). */

.accueil-competences {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	margin: 0;
	padding: 0;
	list-style: none;
}

.accueil-competence {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 6px 14px;
	border: 1px solid var(--trait);
	border-radius: 999px;
	font-size: var(--taille-petit);
	font-weight: 600;
	line-height: 1.2;
}

.accueil-competence__emoji {
	font-size: 1.05em;
	line-height: 1;
}

/* 6 et 7. Cartes — Projets et La Taupinière. */

.accueil-cartes {
	display: grid;
	grid-template-columns: 1fr;
	gap: 12px;
	margin: 0;
	padding: 0;
	list-style: none;
}

@media (min-width: 40rem) {
	.accueil-cartes {
		grid-template-columns: 1fr 1fr;
	}
}

/* Trois par ligne dès que la page est à sa pleine largeur (Lot 8.11,
   demande de Thomas) : les quatre cartes tiennent alors sur deux lignes
   au lieu de deux rangées de deux très larges. */
@media (min-width: 56rem) {
	.accueil-cartes {
		grid-template-columns: repeat(3, 1fr);
	}
}

.accueil-carte {
	position: relative;
	display: flex;
	flex-direction: column;
	overflow: hidden;
	border: 1px solid var(--trait);
	border-radius: 12px;
	background: var(--fond);
	transition: box-shadow 200ms;
}

.accueil-carte:hover {
	box-shadow: 0 0 0 3px color-mix(in srgb, var(--trait) 60%, var(--fond));
}

/* 16:9, le format conseillé à Thomas pour ses animations. En attendant une
   image, un fond teinté de la couleur de la thématique. */
.accueil-carte__media {
	position: relative;
	overflow: hidden;
	aspect-ratio: 16 / 9;
	background: color-mix(in srgb, var(--vert-texte) 14%, var(--trait));
}

/* Position absolue plutôt que « height: 100% » (Lot 8.16, bug constaté par
   Thomas) : avec une image qui porte ses propres largeur/hauteur HTML
   (donc son propre rapport), « height: 100% » entre en boucle avec
   l'aspect-ratio du cadre — qui perd alors 16:9 pour le rapport de
   l'image. En position absolue, l'image ne compte plus dans ce calcul et
   remplit exactement le cadre 16:9, quitte à en recadrer les bords : les
   vignettes YouTube basse définition (hqdefault.jpg, 4:3 avec des bandes
   noires intégrées en haut et en bas) perdent ainsi ces bandes au recadrage
   plutôt que de les montrer. */
.accueil-carte__media img,
.accueil-carte__video {
	position: absolute;
	inset: 0;
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.accueil-carte__duree {
	position: absolute;
	right: var(--s1);
	bottom: var(--s1);
	padding: 0 6px;
	border-radius: 4px;
	background: var(--texte);
	color: var(--fond);
	font-size: var(--taille-petit);
	font-variant-numeric: tabular-nums;
}

.accueil-carte__corps {
	display: flex;
	flex: 1;
	flex-direction: column;
	gap: var(--s1);
	padding: var(--s3);
}

.accueil-carte__titre {
	margin: 0;
	font-size: 1.125rem;
	line-height: 1.3;
}

.accueil-carte__titre a {
	color: var(--texte);
	text-decoration: none;
}

/* Le lien du titre couvre toute la carte. */
.accueil-carte__titre a::after {
	position: absolute;
	inset: 0;
	content: "";
}

.accueil-carte:hover .accueil-carte__titre a {
	text-decoration: underline;
}

/* Le contour de focus entoure la carte entière, là où :has() est compris. */
@supports selector(:has(a)) {
	.accueil-carte__titre a:focus-visible {
		outline: none;
	}

	.accueil-carte:has(.accueil-carte__titre a:focus-visible) {
		outline: 2px solid var(--texte);
		outline-offset: 3px;
	}
}

.accueil-carte__infos,
.accueil-carte__resume {
	margin: 0;
	color: var(--texte-secondaire);
	font-size: var(--taille-petit);
}

.accueil-carte__resume {
	line-height: 1.55;
}

.accueil-carte__mots-cles {
	display: flex;
	flex-wrap: wrap;
	gap: 4px;
	margin: auto 0 0;
	padding: var(--s1) 0 0;
	list-style: none;
}

.accueil-carte__mots-cles li {
	padding: 1px 8px;
	border: 1px solid var(--trait);
	border-radius: 6px;
	font-size: var(--taille-petit);
	line-height: 1.5;
}

/* La Taupinière : le fond « lin » du registre (§6), en panneau arrondi ; les
   cartes y gardent le fond crème, sans filet (--trait disparaît sur le lin).
   Largeur pleine écran essayée puis abandonnée au Lot 8.16 (demande de
   Thomas : ça élargissait trop, il voulait garder les marges du reste de
   la page) — revenu à la colonne normale de l'accueil. */
.accueil-bloc.registre-taupiniere {
	padding: var(--s5) var(--s3);
	border-radius: 16px;
}

@media (min-width: 40rem) {
	.accueil-bloc.registre-taupiniere {
		padding-inline: var(--s4);
	}
}

/* Bordure sans épaisseur, pas seulement transparente : sinon la vignette
   reste en retrait d'un pixel au lieu de toucher le coin arrondi de la
   carte (constaté par Thomas, Lot 8.16). */
.registre-taupiniere .accueil-carte {
	border: 0;
}

.registre-taupiniere .accueil-carte__media {
	background: var(--texte);
}

/* Vignette et titre seuls (Lot 8.15, demande de Thomas) : le système
   d'affichage de youtube.com/@taupiniere, plus resserré que les cartes
   Projets (§6), sans résumé ni mots-clés. Deux lignes de titre au plus.
   Coins arrondis sur la vignette elle-même, pas sur la carte entière (Lot
   8.16, sa demande — « il faut vraiment copier le design de YouTube ») :
   chaque vignette reste une image à coins arrondis posée sur le fond de
   page, pas un bloc dont seul le haut est arrondi. */
.accueil-cartes--videos .accueil-carte {
	overflow: visible;
	border-radius: 0;
}

/* Pas de halo au survol sur ce bloc (Lot 8.16, demande de Thomas) : la
   règle générale (.accueil-carte:hover, plus haut) reste pour les cartes
   Projets, annulée ici. */
.accueil-cartes--videos .accueil-carte:hover {
	box-shadow: none;
}

.accueil-cartes--videos .accueil-carte__media {
	border-radius: 12px;
}

.accueil-cartes--videos .accueil-carte__corps {
	padding: var(--s2) var(--s2) var(--s3);
}

.accueil-cartes--videos .accueil-carte__titre {
	display: -webkit-box;
	overflow: hidden;
	font-size: 1rem;
	font-weight: 600;
	line-height: 1.4;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
}

/* 8. Biographie — la frise, comme « Hackathons » dans la référence. */

.accueil-frise {
	margin: 0;
	padding: 0;
	list-style: none;
}

.accueil-frise__etape {
	position: relative;
	padding: 0 0 var(--s4) var(--s5);
}

.accueil-frise__etape:last-child {
	padding-bottom: 0;
}

/* Le trait qui relie les étapes… */
.accueil-frise__etape::before {
	position: absolute;
	top: 22px;
	bottom: -4px;
	left: 12px;
	width: 1px;
	background: var(--trait);
	content: "";
}

.accueil-frise__etape:last-child::before {
	content: none;
}

/* … et le point de chaque étape. */
.accueil-frise__etape::after {
	position: absolute;
	top: 4px;
	left: 5px;
	width: 15px;
	height: 15px;
	border: 1px solid var(--trait);
	border-radius: 50%;
	background: var(--fond);
	box-shadow: 0 0 0 3px color-mix(in srgb, var(--trait) 45%, var(--fond));
	content: "";
}

.accueil-frise__date,
.accueil-frise__lieu {
	margin: 0;
	color: var(--texte-secondaire);
	font-size: var(--taille-petit);
}

.accueil-frise__date {
	font-variant-numeric: tabular-nums;
}

.accueil-frise__titre {
	margin: 2px 0;
	font-size: 1.0625rem;
	line-height: 1.35;
}

/* 9. Contact — les liens de Thomas et de La Taupinière. */

.accueil-contact {
	display: grid;
	grid-template-columns: 1fr;
	overflow: hidden;
	border: 1px solid var(--trait);
	border-radius: 16px;
}

@media (min-width: 40rem) {
	.accueil-contact {
		grid-template-columns: 1fr 1fr;
	}
}

.accueil-contact__groupe {
	padding: var(--s4);
}

.accueil-contact__groupe--taupiniere {
	position: relative;
	background: var(--fond);
	/* Même fond que la colonne Thomas Goumarre depuis le Lot 8.14 (plus de
	   marron) : un filet sépare les deux, sans quoi rien ne les distingue
	   sur cette carte hors des titres. */
	border-top: 1px solid var(--trait);
}

@media (min-width: 40rem) {
	.accueil-contact__groupe--taupiniere {
		border-top: 0;
		border-left: 1px solid var(--trait);
	}
}

/* Gravure noire sur fond blanc : « multiply » n'y change plus rien depuis
   que le fond du site est blanc lui aussi (Lot 8.14), gardé au cas où
   Thomas remette une teinte ici. Dans le coin, pour que les deux titres
   restent alignés. */
.accueil-contact__logo {
	position: absolute;
	top: var(--s3);
	right: var(--s3);
	width: 88px;
	height: auto;
	mix-blend-mode: multiply;
}

.accueil-contact__titre {
	margin-bottom: var(--s1);
	font-size: var(--taille-petit);
	letter-spacing: 0.08em;
	text-transform: uppercase;
}

.accueil-contact__liens {
	margin: 0;
	padding: 0;
	list-style: none;
}

.accueil-contact__liens a {
	display: inline-flex;
	align-items: center;
	min-height: 44px;
	color: var(--texte);
	overflow-wrap: anywhere;
}

/* Newsletter (Lot 8.9, retouche du 23/09/2026) : sous les deux colonnes,
   pleine largeur — reprend la charte de la carte plutôt qu'un bloc à part
   (le formulaire lui-même est en §17, plus bas). */
.accueil-contact__newsletter {
	grid-column: 1 / -1;
	padding: var(--s4);
	border-top: 1px solid var(--trait);
}

.accueil-contact__newsletter-texte {
	max-width: var(--mesure);
	margin-bottom: var(--s2);
	color: var(--texte-secondaire);
}

/* Apparitions en fondu, comme la référence : le haut de page dès
   l'affichage, les autres blocs au défilement (assets/accueil.js). Jamais
   pour qui a demandé moins d'animations. */
@media (prefers-reduced-motion: no-preference) {
	.accueil-presentation__textes,
	.accueil-presentation__photo,
	.accueil-a-propos {
		animation: accueil-apparition 700ms cubic-bezier(0.22, 1, 0.36, 1) both;
	}

	.accueil-presentation__photo {
		animation-delay: 100ms;
	}

	.accueil-a-propos {
		animation-delay: 200ms;
	}

	.accueil-bloc {
		transition: opacity 700ms cubic-bezier(0.22, 1, 0.36, 1), filter 700ms cubic-bezier(0.22, 1, 0.36, 1), transform 700ms cubic-bezier(0.22, 1, 0.36, 1);
	}

	.accueil-bloc--attente {
		opacity: 0;
		filter: blur(6px);
		transform: translateY(-6px);
	}
}

@keyframes accueil-apparition {
	from {
		opacity: 0;
		filter: blur(6px);
		transform: translateY(-6px);
	}
}

@media print {
	.accueil-bloc--attente {
		opacity: 1;
		filter: none;
		transform: none;
	}
}

/* ------------------------------------------------------------------ */
/* 12. Pages transversales — /lieu/ et /contributeur/. docs/04 §8.      */
/*    Lot 5.5. Rendent les métadonnées réellement cliquables.           */
/* ------------------------------------------------------------------ */

.transversale__entete {
	margin-bottom: var(--s4);
}

.transversale__genre {
	margin: 0 0 var(--s1);
	color: var(--texte-secondaire);
	font-size: var(--taille-petit);
	letter-spacing: 0.06em;
	text-transform: uppercase;
}

.transversale__soustitre {
	color: var(--texte-secondaire);
}

.transversale__bio {
	max-width: var(--mesure);
}

.transversale__entete--personne {
	display: flex;
	flex-wrap: wrap;
	gap: var(--s3);
	align-items: flex-start;
}

.transversale__photo {
	flex: 0 0 auto;
	width: 8rem;
	overflow: hidden;
	border-radius: 50%;
}

.transversale__photo img {
	display: block;
	width: 100%;
	aspect-ratio: 1 / 1;
	object-fit: cover;
}

.transversale__section {
	padding-top: var(--s3);
	margin-top: var(--s4);
	border-top: 1px solid var(--trait);
}

.transversale-liste {
	margin: 0;
	padding: 0;
	list-style: none;
}

.transversale-liste li {
	padding: var(--s1) 0;
	border-bottom: 1px solid var(--trait);
}

/* Ce que porte un sous-lieu : une promenade, une zone (Lot 8.5). */
.transversale-liste__mention {
	color: var(--texte-secondaire);
	font-size: var(--taille-petit);
	font-variant: all-small-caps;
	letter-spacing: 0.04em;
}

/* ------------------------------------------------------------------ */
/* 13. La Taupinière — docs/04-specs-pages.md §5. Lot 5.3.              */
/*    Registre marron : voir .registre-taupiniere (§6) pour le fond.    */
/* ------------------------------------------------------------------ */

/* Pleine largeur d'écran, même technique que la carte générale (§9). */
.registre-taupiniere--pleine-page {
	width: 100vw;
	margin-left: calc(50% - 50vw);
	margin-right: calc(50% - 50vw);
	padding-block: var(--s6);
}

.taupiniere-entete {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--s4);
	margin-bottom: var(--s5);
}

.taupiniere-entete__logo {
	width: 8rem;
	height: auto;
}

.taupiniere-serie {
	margin-bottom: var(--s5);
}

.taupiniere-serie:last-child {
	margin-bottom: 0;
}

.taupiniere-saison {
	margin-top: var(--s3);
}

.taupiniere-saison__titre {
	display: flex;
	align-items: center;
	min-height: 44px; /* Cible tactile : 27 px de haut auparavant (Lot 8). */
	cursor: pointer;
	list-style: none;
	font-weight: 700;
}

.taupiniere-saison__titre::-webkit-details-marker {
	display: none;
}

.taupiniere-saison__titre::before {
	display: inline-block;
	margin-right: var(--s1);
	content: "▶";
	font-size: var(--taille-petit);
}

.taupiniere-saison[open] > .taupiniere-saison__titre::before {
	content: "▼";
}

.taupiniere-saison .vignettes {
	margin-top: var(--s3);
}

/* Fil d'Ariane et fiche d'un épisode — réutilisent .ariane et .fiche
   (docs/06 §6), déjà posées pour la page projet. */

.episode-taupiniere .ariane {
	margin-bottom: var(--s3);
}

.episode-taupiniere h1 {
	margin-top: var(--s3);
}

/* Lecteur différé — une vignette tant qu'on n'a pas cliqué (Lot 5.3). */

.lecteur-youtube {
	position: relative;
	aspect-ratio: 16 / 9;
	margin-bottom: var(--s4);
	background: var(--texte);
}

.lecteur-youtube__declencheur {
	position: absolute;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	height: 100%;
	padding: 0;
	border: 0;
	background: none;
	cursor: pointer;
}

.lecteur-youtube__declencheur img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.lecteur-youtube__play {
	position: relative;
	z-index: 1;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 4rem;
	height: 4rem;
	border-radius: 50%;
	background: rgba(0, 0, 0, 0.6);
	color: #fff;
	font-size: 1.5rem;
}

.lecteur-youtube__declencheur:hover .lecteur-youtube__play {
	background: rgba(0, 0, 0, 0.8);
}

.lecteur-youtube__cadre {
	width: 100%;
	height: 100%;
	border: 0;
}

/* Intervenant et sa mini-bio déroulante — un lien, puis un déclencheur
   séparé (jamais un lien imbriqué dans un <summary>, docs/04 §5). */

.intervenant__bio {
	display: inline;
}

.intervenant__bio summary {
	display: inline;
	cursor: pointer;
	color: var(--texte-secondaire);
	font-size: var(--taille-petit);
	list-style: none;
}

.intervenant__bio summary::-webkit-details-marker {
	display: none;
}

.intervenant__bio summary::after {
	content: " ▾";
}

.intervenant__bio[open] summary::after {
	content: " ▴";
}

.intervenant__bio p {
	max-width: var(--mesure);
	margin: 4px 0 0;
	color: var(--texte-secondaire);
	font-size: var(--taille-petit);
}

/* ------------------------------------------------------------------ */
/* 14. Articles — docs/04-specs-pages.md §6 et §7. Lot 5.4.             */
/* ------------------------------------------------------------------ */

.article__entete {
	margin-bottom: var(--s4);
}

.article__date {
	color: var(--texte-secondaire);
	font-size: var(--taille-petit);
}

.article__chapeau {
	max-width: var(--mesure);
	font-size: var(--taille-h3);
	color: var(--texte-secondaire);
}

/* Listes en lignes compactes : page Articles et dernières publications de
   la page Bio. (Nom hérité de l'ancien accueil, Lot 5.2.) */

.accueil-lignes {
	margin: 0;
	padding: 0;
	list-style: none;
}

.accueil-ligne {
	padding: var(--s1) 0;
	border-bottom: 1px solid var(--trait);
}

.accueil-ligne::before {
	margin-right: var(--s1);
	color: var(--texte-secondaire);
	content: "▸";
}

.accueil-ligne__meta {
	color: var(--texte-secondaire);
	font-size: var(--taille-petit);
}

/* ------------------------------------------------------------------ */
/* 15. Page Bio / CV — docs/04-specs-pages.md §7.                       */
/*    La charte de l'accueil, reprise telle quelle : la page emprunte   */
/*    ses classes (titres de bloc, frise, bloc Contact) et n'ajoute ici */
/*    que son titre, les titres de chapitre, les deux colonnes du CV et */
/*    ce qu'une entrée de CV a de plus qu'une étape de frise.           */
/* ------------------------------------------------------------------ */

/* Plus large que l'accueil (42 rem) : les deux colonnes du CV demandent
   de la place. Les textes suivis, eux, gardent la mesure de lecture. */
.bio {
	display: flex;
	flex-direction: column;
	gap: var(--s6);
	max-width: 58rem;
	margin-inline: auto;
	padding-inline: var(--s3);
}

.bio__titre {
	margin-bottom: 0;
	letter-spacing: -0.02em;
}

.bio-ouverture p:last-child {
	margin-bottom: 0;
}

/* Le chapitre Presse reprend les lignes compactes de la page Articles
   (« accueil-ligne »), mais sans leur triangle « ▸ » : Thomas ne le veut
   pas ici (22/09/2026). Le filet du bas suffit à séparer les articles. */
.bio-presse .accueil-ligne::before {
	content: none;
}

/* Un chapitre atteint par une ancre ne se colle pas au bord de l'écran :
   les liens vers « #etudes » ou « #publications » existent toujours. */
.bio-partie,
.bio-chapitre {
	scroll-margin-top: var(--s4);
}

/* Titre d'un chapitre du CV : l'étiquette en petites capitales du bloc
   Contact, posée sur un filet qui sépare les chapitres. */

.bio-chapitre {
	margin-top: var(--s5);
}

.bio-chapitre__titre {
	margin-bottom: var(--s3);
	padding-top: var(--s2);
	border-top: 1px solid var(--trait);
	font-size: var(--taille-petit);
	letter-spacing: 0.08em;
	text-transform: uppercase;
}

/* Le texte suivi de la page — la biographie en ouverture, le texte d'un
   chapitre. En contraste plein, et non dans le gris du « À propos » de
   l'accueil : ici ce n'est pas un encart sous un grand nom, c'est ce qu'on
   vient lire. La mesure de lecture le tient au large des lignes trop
   longues (06 §3). */
.bio-texte {
	max-width: var(--mesure);
	line-height: 1.65;
}

.bio-texte:last-child {
	margin-bottom: 0;
}

/* Une entrée : l'étape de frise de l'accueil, plus les lignes de détail
   (l'école, les partenaires, la personne avec qui c'est fait) qu'une
   ligne de CV a de plus qu'une étape de frise. */

.bio-frise .accueil-frise__etape {
	padding-bottom: var(--s4);
}

.bio-entree__titre {
	font-weight: 700;
}

.bio-entree__details {
	max-width: var(--mesure);
	margin: 4px 0 0;
	color: var(--texte-secondaire);
	font-size: var(--taille-petit);
	line-height: 1.5;
}

/* Le lieu ferme l'entrée : un peu d'air le détache des détails, sans quoi
   les deux gris se lisent comme un seul bloc. */
.bio-frise .accueil-frise__lieu {
	margin-top: var(--s1);
}

/* Une frise sur deux colonnes dès qu'il y a la place : le CV de la page
   Bio (22/09/2026) et, depuis le Lot 8.11, le bloc « Bio » de l'accueil.
   La liste est coupée en deux au rendu (inc/accueil.php, inc/bio.php) et
   non versée dans des colonnes CSS : chaque moitié garde ainsi sa propre
   frise, dont le trait s'arrête net sur son dernier point. Versée dans
   des colonnes CSS, la liste n'aurait qu'un seul « dernier point », et le
   trait de la première colonne pendrait dans le vide. */

.frise-colonnes {
	display: grid;
	gap: 0 var(--s5);
}

@media (min-width: 56rem) {
	.frise-colonnes {
		grid-template-columns: 1fr 1fr;
		align-items: start;
	}

	/* Les entrées se serrent contre leur trait : chaque colonne est deux
	   fois plus étroite, autant en rendre au texte. */
	.frise-colonnes .accueil-frise__etape {
		padding-left: var(--s4);
	}

	.frise-colonnes .accueil-frise__etape::before {
		left: 7px;
	}

	.frise-colonnes .accueil-frise__etape::after {
		left: 0;
	}
}

/* Sur une seule colonne, les deux moitiés se suivent : le trait de la
   première doit continuer jusqu'à la seconde, au lieu de s'arrêter sur son
   dernier point comme il le fait en haut de colonne. */
@media (max-width: 55.999rem) {
	.accueil-frise--premiere .accueil-frise__etape:last-child::before {
		content: "";
	}
}

/* ------------------------------------------------------------------ */
/* 16. Monticules de taupe — docs/01 §8, docs/04. Lot 8.3.              */
/* ------------------------------------------------------------------ */

/* Un des dessins de Thomas sort du bas de l'écran, puis s'enfonce
   (assets/monticules.js). Sa largeur est celle du dessin, fixée par le
   script. Au-dessus de tout, carte comprise, mais sans jamais capter un
   clic. Le script ne l'ajoute pas si le visiteur a demandé moins
   d'animations : la dernière règle n'est qu'un filet. */
.monticule {
	position: fixed;
	bottom: 0;
	z-index: 1000;
	line-height: 0;
	pointer-events: none;
	transform: translateY(110%);
	transition: transform 900ms cubic-bezier(0.22, 1, 0.36, 1);
}

.monticule img {
	display: block;
}

.monticule--sorti {
	transform: translateY(0);
}

@media (prefers-reduced-motion: reduce) {
	.monticule {
		display: none;
	}
}

/* ------------------------------------------------------------------ */
/* 17. Newsletter — docs/04-specs-pages.md. Lot 8.9.                    */
/*    Un seul formulaire (inc/newsletter.php), posé trois fois : sous   */
/*    les liens du bloc Contact (accueil et Bio, §9 plus haut — même    */
/*    charte que .accueil-contact) et sur la page dédiée /newsletter/.  */
/*    Le pied de page minimal (§5) ne porte qu'un lien texte.           */
/* ------------------------------------------------------------------ */

/* Champ piège anti-robots : hors champ visuel, absent de l'arbre
   d'accessibilité (aria-hidden côté PHP) — jamais rencontré par personne. */
.newsletter__piege {
	position: absolute;
	left: -9999px;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

.newsletter__champs {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-end;
	gap: var(--s2);
}

.newsletter__champ {
	display: flex;
	flex: 1 1 12rem;
	flex-direction: column;
	gap: var(--s1);
	margin: 0;
}

.newsletter__champ label {
	font-size: var(--taille-petit);
}

.newsletter__facultatif {
	color: var(--texte-secondaire);
	font-weight: 400;
}

.newsletter__champ input {
	min-height: 44px;
	padding: 0 var(--s2);
	border: 1px solid var(--trait);
	border-radius: 2px;
	background: var(--fond);
	color: var(--texte);
	font: inherit;
	font-size: var(--taille-corps);
}

.newsletter__champ input:focus-visible {
	outline: 2px solid var(--texte);
	outline-offset: 2px;
}

/* Message de retour (succès ou erreur) : la distinction tient au texte
   lui-même (« Erreur : … »), jamais à la seule couleur. */
.newsletter__message {
	max-width: var(--mesure);
	margin: 0 0 var(--s2);
	padding: var(--s2);
	border-left: 3px solid var(--texte);
	font-size: var(--taille-petit);
}

/* Sur la page dédiée : la présentation, avant le même formulaire. */
.newsletter-presentation {
	max-width: var(--mesure);
	margin-bottom: var(--s4);
}
