/* Fichier généré par npm run build. Ne pas modifier : éditez src/css/. */

/* ===== tokens.css ===== */
/* =========================================================================
   Jetons de design
   -------------------------------------------------------------------------
   Le mode sombre est le mode par défaut : c'est l'identité du site, pas une
   option. Le mode clair s'obtient par le bouton de l'en-tête, qui pose
   data-theme="clair" sur <html>.

   Deux bleus, deux métiers, et il ne faut jamais les confondir :
   --cnd est une couleur de SURFACE (elle porte du blanc dessus) ;
   --projecteur est une couleur d'ENCRE (elle se pose sur du sombre).
   Le bleu du logo sur le fond de scène ne donne que 2,45:1 de contraste :
   il est donc interdit pour du texte en mode sombre.
   ========================================================================= */

:root {
	/* Couleurs — mode sombre */
	--scene:       #070C18;
	--velours:     #0E1A33;
	--cnd:         #1F4E9D;
	--projecteur:  #5B9BFF;

	/* Rembourrage vertical de l en-tete. Il est nomme ici parce que DEUX
	   choses en dependent : la barre elle-meme, et la hauteur ci-dessous qui
	   sert de marge aux ancres. Deux nombres tenus a la main divergent. */
	--entete-air: 0.95rem;

	/* Hauteur de l en-tete collante, calculee a partir de ses propres valeurs
	   plutot que mesuree une fois : si le rembourrage change, ceci suit.
	   44 px de cible minimale + le rembourrage haut et bas + la bordure. */
	--entete-hauteur: calc(44px + var(--entete-air) * 2 + 1px);
	--or:          #E8B84B;
	--scene-blanc: #F2F5FA;
	--coulisse:    #2A3752;

	/* Nuances dérivées */
	--texte-doux:   color-mix(in srgb, var(--scene-blanc) 68%, transparent);
	/* 54 % et pas moins : en dessous, une fois la couleur composee sur le fond,
	   le contraste tombe a 4,28:1 et passe sous le minimum AA de 4,5:1 pour du
	   petit texte. Mesure sur --velours, le fond le plus clair des deux. */
	--texte-faible: color-mix(in srgb, var(--scene-blanc) 54%, transparent);
	--voile:        color-mix(in srgb, var(--scene) 82%, transparent);
	--halo:         color-mix(in srgb, var(--projecteur) 18%, transparent);

	/* Typographie */
	--titre: "Anybody", "Arial Narrow", system-ui, sans-serif;
	--texte: "Instrument Sans", system-ui, -apple-system, "Segoe UI", sans-serif;

	/* Échelle typographique fluide : elle respire avec la fenêtre plutôt que
	   de sauter à chaque point de rupture. */
	--t-xs:   clamp(0.78rem, 0.76rem + 0.1vw,  0.84rem);
	--t-s:    clamp(0.88rem, 0.85rem + 0.15vw, 0.96rem);
	--t-base: clamp(1rem,    0.96rem + 0.2vw,  1.12rem);
	--t-m:    clamp(1.18rem, 1.08rem + 0.5vw,  1.45rem);
	--t-l:    clamp(1.6rem,  1.3rem + 1.5vw,   2.6rem);
	--t-xl:   clamp(2.2rem,  1.4rem + 4vw,     4.6rem);
	--t-geant: clamp(3.4rem, 1rem + 9vw,       7.5rem);

	/* Rythme vertical et gouttières */
	--pas: clamp(1rem, 0.8rem + 1vw, 1.6rem);
	--bloc: clamp(3.5rem, 2rem + 7vw, 9rem);
	--marge: clamp(1.2rem, 0.6rem + 3vw, 4rem);
	--largeur: 1180px;
	--largeur-texte: 68ch;

	/* Formes — le côté vif et le côté arrondi ne sont jamais les mêmes */
	--arrondi-doux: 2px;
	--arrondi-fort: clamp(1.5rem, 4vw, 3.5rem);
	--trait-epaisseur: 2px;

	/* Mouvement */
	--vitesse-courte: 220ms;
	--vitesse: 480ms;
	--vitesse-longue: 900ms;
	--courbe: cubic-bezier(0.22, 1, 0.36, 1);

	color-scheme: dark;
}

:root[data-theme="clair"] {
	--scene:       #F2F5FA;
	--velours:     #FFFFFF;
	--cnd:         #1F4E9D;
	--projecteur:  #1F4E9D;
	--or:          #8A6410;
	--scene-blanc: #0E1A33;
	--coulisse:    #D4DCE9;

	/*
	 * Le mode clair a besoin de plus d opacite que le sombre : du texte fonce
	 * translucide se delave davantage sur fond clair qu un texte clair sur fond
	 * sombre. A 54 %, valeur du mode sombre, on tombe a 3,70:1 — sous le
	 * minimum AA. A 62 % on remonte a 4,75:1 sur scene et 4,90:1 sur velours.
	 */
	--texte-faible: color-mix(in srgb, var(--scene-blanc) 62%, transparent);

	--voile: color-mix(in srgb, var(--scene) 88%, transparent);
	--halo:  color-mix(in srgb, var(--projecteur) 12%, transparent);

	color-scheme: light;
}

/* -------------------------------------------------------------------------
   Polices auto-hébergées.
   Deux familles, pas trois. Variables, donc un seul fichier par famille au
   lieu de six graisses.
   ------------------------------------------------------------------------- */

@font-face {
	font-family: "Anybody";
	src: url("../fonts/anybody-variable.woff2") format("woff2-variations");
	font-weight: 100 900;
	font-stretch: 50% 150%;
	font-style: normal;
	font-display: swap;
}

@font-face {
	font-family: "Instrument Sans";
	src: url("../fonts/instrument-sans-variable.woff2") format("woff2-variations");
	font-weight: 400 700;
	font-style: normal;
	font-display: swap;
}


/* ===== base.css ===== */
/* =========================================================================
   Bases : remise à zéro, typographie, grille, accessibilité
   ========================================================================= */

*, *::before, *::after { box-sizing: border-box; }

html {
	-webkit-text-size-adjust: 100%;
	scroll-behavior: smooth;
}

body {
	margin: 0;
	background: var(--scene);
	color: var(--scene-blanc);
	font-family: var(--texte);
	font-size: var(--t-base);
	line-height: 1.6;
	overflow-x: hidden;
	font-synthesis-weight: none;
	-webkit-font-smoothing: antialiased;
}

img, svg, video, canvas {
	display: block;
	max-width: 100%;
	height: auto;
}

/* -------------------------------------------------------------------------
   Titres
   Casse de phrase partout. Aucune capitale pour les intitulés ni les
   étiquettes : c'est une règle du brief, pas une préférence.
   ------------------------------------------------------------------------- */

h1, h2, h3, h4 {
	font-family: var(--titre);
	font-weight: 700;
	line-height: 0.98;
	letter-spacing: -0.02em;
	text-wrap: balance;
	margin: 0 0 var(--pas);
	font-variation-settings: "wdth" 100;
}

h1 { font-size: var(--t-xl); }
h2 { font-size: var(--t-l); }
h3 { font-size: var(--t-m); line-height: 1.15; }
h4 { font-size: var(--t-base); letter-spacing: 0; }

p, li { text-wrap: pretty; }
p { margin: 0 0 var(--pas); max-width: var(--largeur-texte); }

a {
	color: var(--projecteur);
	text-decoration-thickness: 1px;
	text-underline-offset: 0.22em;
	transition: color var(--vitesse-courte) var(--courbe);
}
a:hover { color: var(--scene-blanc); }

strong { font-weight: 600; }

hr {
	border: 0;
	height: 1px;
	background: var(--coulisse);
	margin: var(--bloc) 0;
}

/* -------------------------------------------------------------------------
   Focus clavier : visible et dessiné, pas le contour bleu du navigateur
   ------------------------------------------------------------------------- */

:focus-visible {
	outline: 2px solid var(--projecteur);
	outline-offset: 3px;
	border-radius: 2px;
}

.saut-au-contenu {
	position: absolute;
	left: -9999px;
	top: 0;
	z-index: 200;
	padding: 0.8em 1.2em;
	background: var(--projecteur);
	color: var(--scene);
	font-weight: 600;
	text-decoration: none;
}
.saut-au-contenu:focus {
	left: var(--marge);
	top: var(--marge);
}

.lecteur-ecran {
	position: absolute !important;
	width: 1px; height: 1px;
	padding: 0; margin: -1px;
	overflow: hidden;
	clip: rect(0 0 0 0);
	white-space: nowrap;
	border: 0;
}

/* Le champ piège des formulaires : invisible pour l'humain, visible pour le
   robot qui le remplira et se trahira. */
.champ-piege {
	position: absolute !important;
	left: -9999px;
	width: 1px; height: 1px;
	overflow: hidden;
}

/* -------------------------------------------------------------------------
   Grille : 12 colonnes, avec des blocs volontairement décalés
   ------------------------------------------------------------------------- */

.enveloppe {
	width: min(100% - var(--marge) * 2, var(--largeur));
	margin-inline: auto;
}

.grille {
	display: grid;
	grid-template-columns: repeat(12, 1fr);
	gap: var(--pas);
}

/* Décalages nommés : chaque section démarre sur une colonne différente, pour
   qu'aucune ne soit calée sur la précédente. */
.decale-1 { grid-column: 1 / -1; }
.decale-2 { grid-column: 2 / -1; }
.decale-3 { grid-column: 3 / -1; }

@media (max-width: 800px) {
	.grille { grid-template-columns: 1fr; }
	.decale-1, .decale-2, .decale-3 { grid-column: 1 / -1; }
}

.section {
	position: relative;
	padding-block: var(--bloc);
}

.section--velours {
	background: var(--velours);
}

/* -------------------------------------------------------------------------
   Mouvement réduit
   Le coût est nul et, sans cela, une partie des visiteurs quitte le site
   avec la nausée.
   ------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
	html { scroll-behavior: auto; }

	*, *::before, *::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
	}

	/* Le trait est dessiné d'emblée, le bandeau s'arrête, le contenu apparaît
	   sans mouvement. */
	/* Le danseur est entièrement visible d’emblée, sans dévoilement. */
	.trait__voile { transform: none !important; animation: none !important; }
	.bandeau__piste { animation: none !important; transform: none !important; }
	.apparait { opacity: 1 !important; transform: none !important; }
	.curseur { display: none !important; }
}

/* -------------------------------------------------------------------------
   Apparition au défilement
   Sans JavaScript, tout est visible : la classe .apparait n'assombrit rien
   tant que le script n'a pas posé .js sur <html>.
   ------------------------------------------------------------------------- */

.js .apparait {
	opacity: 0;
	transform: translateY(1.4rem);
	transition:
		opacity var(--vitesse) var(--courbe),
		transform var(--vitesse) var(--courbe);
}
.js .apparait.est-visible {
	opacity: 1;
	transform: none;
}


/* -------------------------------------------------------------------------
   Feuille de style exigée par Lenis

   Recopiée telle quelle depuis node_modules/lenis/dist/lenis.css.

   Elle n est PAS optionnelle. Lenis pose la classe « lenis » sur <html> et
   compte sur cette règle pour libérer la hauteur du document. Sans elle,
   <html> reste contraint à la hauteur de la fenêtre, le défilement natif se
   dérègle et les positions calculées deviennent fausses.

   Recopiée plutôt qu importée parce que le build concatène nos feuilles :
   à chaque montée de version de Lenis, comparer ce bloc avec le fichier
   d origine.
   ------------------------------------------------------------------------- */

html.lenis,
html.lenis body {
  height: auto;
}

.lenis:not(.lenis-autoToggle).lenis-stopped {
  overflow: clip;
}

.lenis [data-lenis-prevent],
.lenis [data-lenis-prevent-wheel],
.lenis [data-lenis-prevent-touch],
.lenis [data-lenis-prevent-vertical],
.lenis [data-lenis-prevent-horizontal] {
  overscroll-behavior: contain;
}

.lenis.lenis-smooth iframe {
  pointer-events: none;
}

.lenis.lenis-autoToggle {
  transition-property: overflow;
  transition-duration: 1ms;
  transition-behavior: allow-discrete;
}

/* -------------------------------------------------------------------------
   Les ancres et l'en-tête collante

   Sans cette règle, tout lien vers un « # » de la page pose sa cible SOUS
   l'en-tête : le titre visé disparaît derrière la barre, et le lecteur croit
   avoir atterri au mauvais endroit. Le défaut se voit d'autant plus que
   l'en-tête est translucide — on devine le titre à travers, ce qui est pire
   qu'une disparition franche.

   :where() donne à la règle une spécificité nulle : elle ne prendra jamais le
   pas sur un réglage plus précis posé ailleurs.
   ------------------------------------------------------------------------- */

:where([id]) {
	/* La hauteur mesuree si le script tourne, le calcul du jeton sinon. */
	scroll-margin-block-start: calc(var(--entete-mesuree, var(--entete-hauteur)) + 1.5rem);
}


/* ===== trait.css ===== */
/* =========================================================================
   Le trait
   -------------------------------------------------------------------------
   Le logo est un trait continu qui dessine un danseur. Ce trait est le fil
   conducteur du site entier : il se dessine à l'ouverture, se prolonge en
   ligne verticale sur le bord gauche, ondule au défilement, porte la
   silhouette dans le menu et relie les pages entre elles.

   Toutes les animations d'ici n'agissent que sur transform, opacity et
   stroke-dashoffset : aucune ne provoque de recalcul de mise en page.
   ========================================================================= */

/* -------------------------------------------------------------------------
   Rideau d'ouverture — une seule fois par session
   ------------------------------------------------------------------------- */

.rideau {
	position: fixed;
	inset: 0;
	z-index: 100;
	display: grid;
	place-items: center;
	background-color: var(--scene);
	transition:
		opacity var(--vitesse-longue) var(--courbe),
		background-color 600ms var(--courbe);
}

/*
 * Le fond de la salle s'efface pendant que le logo vole vers l'en-tête.
 * On anime le FOND, pas l'opacité de l'élément : sinon le logo s'effacerait
 * avec lui, et c'est précisément lui que l'on doit continuer à voir.
 */
.rideau--sort {
	background-color: transparent;
	pointer-events: none;
}

.rideau[hidden] { display: none; }

.rideau--parti {
	opacity: 0;
	pointer-events: none;
}

/* Le logo entier au lever de rideau : c'est lui que l'on doit reconnaître,
   pas une arabesque abstraite. */
.rideau__logo {
	width: min(58vw, 26rem);
	overflow: visible;
	/* Le vol vers l'en-tête n'agit que sur transform : rien à recalculer. */
	will-change: transform;
}

.rideau__aide {
	position: absolute;
	bottom: var(--marge);
	left: 50%;
	transform: translateX(-50%);
	color: var(--texte-faible);
	font-size: var(--t-xs);
	opacity: 0;
	animation: rideau-aide 1s var(--courbe) 1.2s forwards;
}

@keyframes rideau-aide { to { opacity: 1; } }

/* -------------------------------------------------------------------------
   Le tracé du logo

   Le danseur est le tracé RÉEL du logo officiel, vectorisé : ce sont des
   formes pleines, pas une ligne. On ne peut donc pas le « dessiner » en
   animant un pointillé comme on le ferait d'un trait.

   Le geste est rendu autrement, et plus fidèlement : un masque balaie la
   forme de gauche à droite, dans le sens même où l'arche est tracée. À l'œil,
   le danseur apparaît sous une main invisible.
   ------------------------------------------------------------------------- */

.trait {
	color: var(--projecteur);
	overflow: visible;
}

.trait path {
	fill: currentColor;
}

/* Sans JavaScript, aucun masque n'est posé : le danseur est simplement là. */
.js .rideau .trait__voile {
	transform: translateX(calc(var(--trait-largeur, 812) * -1px));
}

.rideau--dessine .trait__voile {
	/* 1,1 s : doit rester égal à DUREE_REVELATION dans src/js/rideau.js. */
	animation: devoiler 1.1s var(--courbe) forwards;
}

@keyframes devoiler {
	to { transform: translateX(0); }
}

/* -------------------------------------------------------------------------
   Le trait qui parcourt la page
   Il commence là où le danseur s'arrête : ce n'est pas une décoration
   ajoutée, c'est le prolongement du même geste.
   ------------------------------------------------------------------------- */

.fil {
	position: fixed;
	left: clamp(0.6rem, 2.4vw, 2.6rem);
	top: 0;
	bottom: 0;
	width: 3rem;
	pointer-events: none;
	z-index: 3;
}

.fil svg {
	height: 100%;
	width: 100%;
	overflow: visible;
}

.fil path {
	fill: none;
	stroke: var(--projecteur);
	stroke-width: 1.5;
	opacity: 0.45;
	vector-effect: non-scaling-stroke;
	transition: d var(--vitesse) var(--courbe);
}

/* La part du trait déjà parcourue est plus lumineuse : elle marque la
   progression dans la page. */
.fil__parcouru {
	stroke: var(--projecteur);
	opacity: 1;
	stroke-width: 2;
}

@media (max-width: 640px) {
	.fil { display: none; }
}

/* -------------------------------------------------------------------------
   Arcs de séparation
   Les sections ne se séparent pas par une ligne droite mais par une courbe
   dérivée du tracé du logo.
   ------------------------------------------------------------------------- */

.arc {
	display: block;
	width: 100%;
	height: clamp(3rem, 7vw, 7rem);
	fill: var(--velours);
	margin-bottom: -1px;
}

.arc--vers-scene { fill: var(--scene); }

/* -------------------------------------------------------------------------
   Curseur : une poursuite de théâtre qui éclaire ce qu'elle survole
   ------------------------------------------------------------------------- */

.curseur {
	position: fixed;
	top: 0;
	left: 0;
	width: 22rem;
	height: 22rem;
	margin: -11rem 0 0 -11rem;
	border-radius: 50%;
	pointer-events: none;
	z-index: 2;
	opacity: 0;
	background: radial-gradient(circle, var(--halo) 0%, transparent 62%);
	transition: opacity var(--vitesse) var(--courbe);
	will-change: transform;
}

.curseur--visible { opacity: 1; }

/* Aucun curseur au tactile : il n'y a pas de survol sur un téléphone. */
@media (hover: none), (pointer: coarse) {
	.curseur { display: none; }
}

/* -------------------------------------------------------------------------
   Titres révélés lettre par lettre, avec étirement de l'axe de largeur
   d'Anybody. Le titre s'allonge comme un corps qui s'étire : c'est le seul
   endroit où la typographie raconte le sujet.
   ------------------------------------------------------------------------- */

/*
 * Le span de mot est insécable : les retours à la ligne ne tombent qu'entre
 * les mots. Sans lui, chaque lettre en inline-block deviendrait un point de
 * coupure possible et les mots se briseraient en deux.
 */
.js .titre-anime .mot {
	display: inline-block;
	white-space: nowrap;
}

.js .titre-anime .lettre {
	display: inline-block;
	opacity: 0;
	transform: translateY(0.45em);
	font-variation-settings: "wdth" 78, "wght" 700;
	transition:
		opacity 420ms var(--courbe),
		transform 620ms var(--courbe),
		font-variation-settings 720ms var(--courbe);
	/* 18 ms de décalage, rang plafonné à 26 dans le script : la révélation
	   complète tient sous 500 ms, pour ne pas retarder le LCP. */
	transition-delay: calc(var(--rang, 0) * 18ms);
}

.js .titre-anime.est-visible .lettre {
	opacity: 1;
	transform: none;
	font-variation-settings: "wdth" 100, "wght" 700;
}

@media (prefers-reduced-motion: reduce) {
	.js .titre-anime .lettre {
		opacity: 1;
		transform: none;
		font-variation-settings: "wdth" 100, "wght" 700;
	}
}


/* ===== entete.css ===== */
/* =========================================================================
   En-tête, bandeau des disciplines, menu plein écran, pied de page
   ========================================================================= */

/* -------------------------------------------------------------------------
   Bandeau d'alerte temporaire
   ------------------------------------------------------------------------- */

.alerte {
	background: var(--or);
	color: #1A1204;
	font-size: var(--t-s);
	padding: 0.55rem var(--marge);
	text-align: center;
}
.alerte a { color: inherit; font-weight: 600; }

/* -------------------------------------------------------------------------
   En-tête
   ------------------------------------------------------------------------- */

.entete {
	position: sticky;
	top: 0;
	z-index: 40;
	background: color-mix(in srgb, var(--scene) 86%, transparent);
	backdrop-filter: blur(14px);
	border-bottom: 1px solid var(--coulisse);
}

.entete__barre {
	display: flex;
	align-items: center;
	gap: var(--pas);
	padding-block: var(--entete-air);
}

.entete__marque {
	/* Hauteur garantie : sans elle, la cible depend du chargement du logo et
	   frole le minimum de 24 px du critere WCAG 2.5.8. */
	min-height: 44px;
	display: flex;
	align-items: center;
	gap: 0.7rem;
	text-decoration: none;
	color: inherit;
	margin-right: auto;
}

.entete__logo {
	width: clamp(2.6rem, 5vw, 3.6rem);
	height: auto;
}

/* Le logo blanc en mode sombre, le logo bleu en mode clair. Le bleu du logo
   sur le fond de scène serait illisible. */
.logo--blanc { display: block; }
.logo--couleur { display: none; }
:root[data-theme="clair"] .logo--blanc { display: none; }
:root[data-theme="clair"] .logo--couleur { display: block; }

.entete__nom {
	font-family: var(--titre);
	font-size: var(--t-s);
	font-weight: 700;
	line-height: 1.1;
	font-variation-settings: "wdth" 88;
}

.entete__actions {
	display: flex;
	align-items: center;
	gap: 0.5rem;
}

/* -------------------------------------------------------------------------
   Boutons de l'en-tête
   ------------------------------------------------------------------------- */

.bouton-icone {
	display: grid;
	place-items: center;
	width: 2.6rem;
	height: 2.6rem;
	border: 1px solid var(--coulisse);
	border-radius: 50%;
	background: transparent;
	color: var(--scene-blanc);
	cursor: pointer;
	transition:
		border-color var(--vitesse-courte) var(--courbe),
		transform var(--vitesse-courte) var(--courbe);
}
.bouton-icone:hover {
	border-color: var(--projecteur);
	transform: translateY(-1px);
}

.bouton-menu {
	display: flex;
	align-items: center;
	gap: 0.55rem;
	padding: 0.55rem 1rem;
	border: 1px solid var(--coulisse);
	border-radius: 2rem;
	background: transparent;
	color: var(--scene-blanc);
	font: inherit;
	font-size: var(--t-s);
	cursor: pointer;
}
.bouton-menu:hover { border-color: var(--projecteur); }

.bouton-menu__traits {
	display: grid;
	gap: 4px;
	width: 18px;
}
.bouton-menu__traits span {
	height: 1.5px;
	background: currentColor;
	transition: transform var(--vitesse-courte) var(--courbe);
}
.bouton-menu[aria-expanded="true"] .bouton-menu__traits span:first-child {
	transform: translateY(5.5px) rotate(45deg);
}
.bouton-menu[aria-expanded="true"] .bouton-menu__traits span:last-child {
	transform: translateY(-5.5px) rotate(-45deg);
}

.langues ul {
	display: flex;
	gap: 0.4rem;
	list-style: none;
	margin: 0;
	padding: 0;
	font-size: var(--t-xs);
}
.langues a { text-decoration: none; color: var(--texte-faible); }
.langues a[aria-current] { color: var(--scene-blanc); font-weight: 600; }

/* -------------------------------------------------------------------------
   Bandeau des disciplines
   ------------------------------------------------------------------------- */

.bandeau {
	overflow: hidden;
	border-top: 1px solid var(--coulisse);
	padding-block: 0.65rem;
	font-size: var(--t-xs);
	color: var(--texte-faible);
	mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
}

.bandeau__piste {
	display: flex;
	gap: 2.2rem;
	width: max-content;
	animation: defiler 46s linear infinite;
}

.bandeau:hover .bandeau__piste { animation-play-state: paused; }

/*
 * Hors du champ de vision, l'animation est mise en pause par le script.
 * Une animation infinie qui tourne derrière l'écran fait repeindre la page
 * pour rien — c'est invisible sur un ordinateur de bureau, et coûteux sur
 * un téléphone.
 */
.bandeau--dehors .bandeau__piste { animation-play-state: paused; }

.bandeau__mot { white-space: nowrap; }
.bandeau__mot::after {
	content: "·";
	margin-left: 2.2rem;
	color: var(--cnd);
}

@keyframes defiler {
	from { transform: translate3d(0, 0, 0); }
	to   { transform: translate3d(-50%, 0, 0); }
}

/* -------------------------------------------------------------------------
   Menu plein écran
   La silhouette du danseur se déplace le long du trait vers le lien survolé,
   en changeant de pose. Elle dérive du tracé du logo : ce n'est pas une icône.
   ------------------------------------------------------------------------- */

.menu {
	position: fixed;
	inset: 0;
	z-index: 60;
	background: var(--scene);
	/*
	 * Colonne flexible plutôt que grille centrée, et « margin-block: auto »
	 * sur le contenu : quinze entrées ne tiennent pas toujours dans la
	 * hauteur d'un écran. Un contenu centré à la grille se fait alors
	 * couper en HAUT, hors d'atteinte du défilement. Avec une marge
	 * automatique, il se centre quand il y a la place et se pose en haut
	 * quand il n'y en a plus.
	 */
	display: flex;
	flex-direction: column;
	overflow-y: auto;
	overscroll-behavior: contain;
	padding: calc(var(--marge) * 1.2) var(--marge);
	opacity: 0;
	/*
	 * Volontairement PAS de « visibility: hidden ».
	 *
	 * Un élément en visibility:hidden ne peut pas recevoir le focus, et comme
	 * la propriété est animée, il n'existe aucun instant fiable pour savoir
	 * quand elle a basculé. Le focus arrivait donc dans le vide à l'ouverture.
	 *
	 * C'est l'attribut « inert », posé par le script, qui retire réellement le
	 * menu fermé de la navigation clavier et des lecteurs d'écran. Il fait ce
	 * travail mieux que visibility, et sans dépendre d'une animation.
	 */
	pointer-events: none;
	transition: opacity var(--vitesse) var(--courbe);
}

.menu--ouvert {
	opacity: 1;
	pointer-events: auto;
}

.menu__contenu {
	width: min(100% - var(--marge) * 2, var(--largeur));
	margin-inline: auto;
	margin-block: auto;
	display: grid;
	grid-template-columns: minmax(0, 14rem) minmax(0, 1fr);
	gap: clamp(1.5rem, 5vw, 5rem);
	align-items: center;
}

.menu__silhouette {
	justify-self: center;
	width: 100%;
	max-width: 13rem;
}
/* Le logo officiel entier. C'est son déplacement vers le lien survolé qui
   porte le geste, pas une déformation du tracé. */
.menu__logo {
	width: 100%;
	height: auto;
}

.menu__liste {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	/* Un intervalle réel entre les entrées : c'est ce qui distingue une liste
	   que l'on parcourt d'un pavé de texte que l'on subit. */
	gap: clamp(0.2rem, 0.8vh, 0.6rem);
}

.menu__liste a {
	display: block;
	font-family: var(--titre);
	/*
	 * La contrainte n'est pas la largeur mais la hauteur : quinze entrées
	 * doivent tenir dans l'écran. On plafonne donc aussi en vh, sans quoi
	 * la liste déborde dès qu'un ordinateur portable est un peu bas.
	 */
	font-size: clamp(1.25rem, min(5.5vw, 3.2vh), 2.9rem);
	font-weight: 700;
	line-height: 1.15;
	color: var(--scene-blanc);
	text-decoration: none;
	padding-block: clamp(0.2rem, 0.9vh, 0.6rem);
	font-variation-settings: "wdth" 92;
	transition:
		color var(--vitesse-courte) var(--courbe),
		font-variation-settings var(--vitesse) var(--courbe),
		transform var(--vitesse) var(--courbe);
}

.menu__liste a:hover,
.menu__liste a:focus-visible {
	color: var(--projecteur);
	font-variation-settings: "wdth" 112;
	transform: translateX(0.5rem);
}

.menu__pied {
	margin-top: clamp(1.5rem, 5vh, 3.5rem);
	display: flex;
	flex-wrap: wrap;
	gap: var(--pas);
	font-size: var(--t-s);
	color: var(--texte-doux);
	grid-column: 1 / -1;
}

@media (max-width: 800px) {
	.menu__contenu { grid-template-columns: 1fr; }
	.menu__silhouette { display: none; }
}

/* Quand le menu est ouvert, la page dessous ne défile plus. */
body.menu-ouvert { overflow: hidden; }

/* -------------------------------------------------------------------------
   Pied de page
   Les mêmes mots que le bandeau de l'en-tête, mais ils se remplacent en
   fondu l'un après l'autre au lieu de défiler.
   ------------------------------------------------------------------------- */

.pied {
	background: var(--velours);
	border-top: 1px solid var(--coulisse);
	padding-block: var(--bloc) var(--pas);
	margin-top: var(--bloc);
}

.pied__grille {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(15rem, 100%), 1fr));
	gap: var(--bloc) var(--pas);
}

.pied h3 {
	font-size: var(--t-s);
	font-family: var(--texte);
	font-weight: 600;
	color: var(--texte-faible);
	margin-bottom: 0.8rem;
	letter-spacing: 0;
}

.pied ul { list-style: none; margin: 0; padding: 0; }
.pied li { margin-bottom: 0.45rem; }
.pied a { color: var(--scene-blanc); text-decoration: none; }
.pied a:hover { color: var(--projecteur); text-decoration: underline; }

.disciplines-fondu {
	font-family: var(--titre);
	font-size: var(--t-l);
	font-weight: 700;
	color: var(--cnd);
	min-height: 1.2em;
	margin-block: var(--bloc) var(--pas);
}
:root[data-theme="clair"] .disciplines-fondu { color: var(--projecteur); }

.disciplines-fondu span {
	display: inline-block;
	transition: opacity var(--vitesse) var(--courbe);
}
.disciplines-fondu span[aria-hidden="true"] { opacity: 0; }

.pied__bas {
	display: flex;
	flex-wrap: wrap;
	gap: var(--pas);
	justify-content: space-between;
	align-items: center;
	margin-top: var(--bloc);
	padding-top: var(--pas);
	border-top: 1px solid var(--coulisse);
	font-size: var(--t-xs);
	color: var(--texte-faible);
}
.pied__bas a { color: var(--texte-faible); }

/* -------------------------------------------------------------------------
   Taille des cibles tactiles du pied de page

   Les liens du pied ne mesuraient que 21 px de haut, sous le minimum de
   24 × 24 px du critère WCAG 2.5.8. Ce n'est pas visible sur un ordinateur,
   mais sur un téléphone on vise à côté — et c'est précisément là que se
   trouvent les numéros de téléphone du secrétariat.
   ------------------------------------------------------------------------- */

.pied li > a,
.pied__bas a,
.pied__legal a,
.menu__pied a {
	display: inline-block;
	padding-block: 0.28rem;
	min-height: 24px;
}

.pied li { margin-bottom: 0.15rem; }

/* -------------------------------------------------------------------------
   Navigation de secours

   Visible uniquement quand le JavaScript ne s'exécute pas : le menu plein
   écran est alors inatteignable, puisque son attribut « inert » n'est jamais
   retiré. Sobre volontairement — c'est un filet de sécurité, pas une
   deuxième identité graphique.
   ------------------------------------------------------------------------- */

.nav-secours {
	background: var(--velours);
	border-bottom: 1px solid var(--coulisse);
	padding: var(--pas) var(--marge);
}

.nav-secours__liste {
	display: flex;
	flex-wrap: wrap;
	gap: 0.4rem 1.4rem;
	list-style: none;
	margin: 0 auto;
	padding: 0;
	width: min(100%, var(--largeur));
	font-size: var(--t-s);
}

.nav-secours__liste a {
	display: inline-block;
	padding-block: 0.28rem;
	min-height: 24px;
	color: var(--scene-blanc);
	text-decoration: none;
}
.nav-secours__liste a:hover { color: var(--projecteur); text-decoration: underline; }


/* ===== accueil.css ===== */
/* =========================================================================
   Page d'accueil
   ========================================================================= */

/* -------------------------------------------------------------------------
   Compte à rebours — fond de scène
   ------------------------------------------------------------------------- */

.scene {
	position: relative;
	min-height: min(92svh, 60rem);
	display: grid;
	align-content: center;
	padding-block: var(--bloc);
	overflow: hidden;
}

/* Une lueur chaude, très basse en opacité, qui découpe la scène. Pas un
   dégradé décoratif : une source de lumière posée en haut à droite. */
.scene::before {
	content: "";
	position: absolute;
	inset: -20% -10% auto auto;
	width: min(70vw, 46rem);
	aspect-ratio: 1;
	background: radial-gradient(circle, color-mix(in srgb, var(--cnd) 34%, transparent) 0%, transparent 66%);
	pointer-events: none;
	z-index: 0;
}

/* -------------------------------------------------------------------------
   La scène volumétrique

   Un canevas WebGL posé derrière le contenu : des faisceaux de projecteurs
   qui traversent la brume d'une salle. Le fond de scène reste celui du CSS —
   le canevas ne fait qu'ajouter de la lumière par-dessus, en mode « screen ».

   Conséquence importante : le contraste du texte ne dépend jamais du shader.
   Si WebGL manque, si la carte graphique renonce, si le visiteur a demandé le
   calme, il ne se passe rien et la page reste exactement lisible.
   ------------------------------------------------------------------------- */

.scene {
	/* Confine le mélange au bloc : sans cela, « screen » irait chercher tout
	   ce qui se trouve derrière dans la page. */
	isolation: isolate;
}

.scene__volume {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	z-index: 0;
	pointer-events: none;
	mix-blend-mode: screen;
	/* Les projecteurs montent en puissance, comme une salle qui s'éclaire. */
	opacity: 0;
	transition: opacity 1600ms var(--courbe);
}

.scene__volume--allume {
	opacity: 1;
}

/* Quand les vrais faisceaux sont là, le dégradé de secours s'efface en partie :
   les deux ensemble satureraient le haut de l'écran. */
.scene:has(.scene__volume)::before {
	opacity: 0.4;
}

.scene__contenu {
	position: relative;
	z-index: 1;
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 22rem);
	gap: var(--bloc);
	align-items: center;
}

@media (max-width: 900px) {
	.scene__contenu { grid-template-columns: 1fr; gap: var(--pas); }
}

.accroche {
	font-size: var(--t-xl);
	max-width: 14ch;
	margin-bottom: var(--bloc);
}

/* -------------------------------------------------------------------------
   Les chiffres
   L'or n'apparaît qu'ici et sur le bouton du bon de commande. Nulle part
   ailleurs.
   ------------------------------------------------------------------------- */

.compteur {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: clamp(0.7rem, 2.2vw, 2rem);
	margin-bottom: var(--pas);
}

.compteur__bloc {
	display: grid;
	gap: 0.1rem;
}

.compteur__nombre {
	font-family: var(--titre);
	font-size: var(--t-l);
	font-weight: 800;
	line-height: 0.82;
	color: var(--or);
	font-variation-settings: "wdth" 84, "wght" 800;
	font-variant-numeric: tabular-nums;
	letter-spacing: -0.03em;
}

/* Les jours dominent. Le reste tient le second rang, sur la même ligne. */
.compteur__bloc:first-child .compteur__nombre {
	font-size: var(--t-geant);
}

.compteur__unite {
	font-size: var(--t-xs);
	color: var(--texte-faible);
}

.compteur--en-cours {
	font-family: var(--titre);
	font-size: var(--t-l);
	color: var(--or);
	font-variation-settings: "wdth" 92;
}

.scene__legende {
	font-size: var(--t-m);
	max-width: 34ch;
	color: var(--texte-doux);
}
.scene__legende strong {
	display: block;
	color: var(--scene-blanc);
	font-weight: 600;
}

.scene__repli {
	border-left: 2px solid var(--cnd);
	padding-left: var(--pas);
	max-width: 48ch;
}

/* Le logo entier, en décor du hero. Discret : il ne concurrence pas le
   compte à rebours, il rappelle simplement à qui appartient la page. */
.scene__logo {
	justify-self: center;
	width: 100%;
	max-width: 22rem;
	opacity: 0.55;
}

.scene__logo-image {
	width: 100%;
	height: auto;
}

@media (max-width: 900px) {
	.scene__logo { display: none; }
}

/* -------------------------------------------------------------------------
   Les deux concours — le régional domine, le national reste discret
   ------------------------------------------------------------------------- */

.duo {
	display: grid;
	grid-template-columns: 1.62fr 1fr;
	gap: var(--pas);
	align-items: start;
}

@media (max-width: 900px) {
	.duo { grid-template-columns: 1fr; }
}

.concours-carte {
	position: relative;
	display: block;
	padding: clamp(1.4rem, 3vw, 2.6rem);
	background: var(--velours);
	color: inherit;
	text-decoration: none;
	/* Un côté arrondi, un côté vif. Jamais quatre coins identiques. */
	border-radius: var(--arrondi-fort) var(--arrondi-doux) var(--arrondi-fort) var(--arrondi-doux);
	border: 1px solid var(--coulisse);
	overflow: hidden;
	transition:
		border-color var(--vitesse) var(--courbe),
		transform var(--vitesse) var(--courbe);
}

/* Le relief 3D des cartes vit maintenant dans composants.css, sur
   [data-relief] : il sert aussi aux stages et au document essentiel. */


.concours-carte--principal {
	min-height: 22rem;
	display: flex;
	flex-direction: column;
	justify-content: flex-end;
}

.concours-carte--principal::after {
	content: "";
	position: absolute;
	inset: auto -30% -40% auto;
	width: 22rem;
	aspect-ratio: 1;
	background: radial-gradient(circle, color-mix(in srgb, var(--cnd) 44%, transparent), transparent 70%);
	pointer-events: none;
}

.concours-carte__contenu { position: relative; z-index: 1; }

.concours-carte h3 {
	font-size: var(--t-l);
	margin-bottom: 0.4rem;
}

.concours-carte--secondaire h3 { font-size: var(--t-m); }

.concours-carte__meta {
	color: var(--texte-doux);
	font-size: var(--t-s);
	margin: 0;
}

.concours-carte__image {
	position: absolute;
	inset: 0;
	object-fit: cover;
	width: 100%;
	height: 100%;
	opacity: 0.28;
	z-index: 0;
}

/* .etiquette a rejoint composants.css : elle sert sur quatorze pages,
   elle n'appartenait pas a la feuille de l'accueil. */

/* -------------------------------------------------------------------------
   Chiffres du réseau national
   ------------------------------------------------------------------------- */

.chiffres {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(8rem, 100%), 1fr));
	gap: var(--pas);
	margin-bottom: var(--pas);
}

.chiffre__valeur {
	font-family: var(--titre);
	font-size: clamp(2.2rem, 6vw, 4.4rem);
	font-weight: 700;
	line-height: 1;
	color: var(--scene-blanc);
	font-variant-numeric: tabular-nums;
	font-variation-settings: "wdth" 86;
}

.chiffre__libelle {
	font-size: var(--t-s);
	color: var(--texte-faible);
}

.chiffres__note {
	font-size: var(--t-s);
	color: var(--texte-faible);
	max-width: 60ch;
}

/* -------------------------------------------------------------------------
   Le national 2026 à l'Arkéa Arena — bloc volontairement décalé
   ------------------------------------------------------------------------- */

.fait-marquant {
	display: grid;
	grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
	gap: var(--bloc);
	align-items: center;
}

@media (max-width: 900px) {
	.fait-marquant { grid-template-columns: 1fr; gap: var(--pas); }
}

.cadre-photo {
	overflow: hidden;
	border-radius: var(--arrondi-fort) var(--arrondi-doux) var(--arrondi-fort) var(--arrondi-doux);
	background: var(--velours);
}
.cadre-photo img { width: 100%; }

.cadre-photo--inverse {
	border-radius: var(--arrondi-doux) var(--arrondi-fort) var(--arrondi-doux) var(--arrondi-fort);
}

.cadre-photo__attente {
	display: grid;
	place-items: center;
	aspect-ratio: 4 / 3;
	color: var(--texte-faible);
	font-size: var(--t-s);
	text-align: center;
	padding: var(--pas);
	border: 1px dashed var(--coulisse);
}

/* -------------------------------------------------------------------------
   Le bureau
   ------------------------------------------------------------------------- */

.bureau {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(15rem, 100%), 1fr));
	gap: var(--bloc) var(--pas);
	margin-bottom: var(--bloc);
}

.membre {
	display: grid;
	gap: 0.6rem;
	justify-items: start;
}

.membre__portrait {
	width: clamp(5rem, 10vw, 7.5rem);
	aspect-ratio: 1;
	border-radius: 50%;
	object-fit: cover;
	border: 1px solid var(--coulisse);
}

.membre__portrait--vide {
	display: grid;
	place-items: center;
	background: var(--velours);
	color: var(--texte-faible);
	font-family: var(--titre);
	font-size: var(--t-m);
}

.membre__nom {
	font-family: var(--titre);
	font-size: var(--t-m);
	font-weight: 700;
	line-height: 1.1;
	margin: 0;
}

.membre__fonction {
	color: var(--texte-doux);
	font-size: var(--t-s);
	margin: 0;
	max-width: 26ch;
}

.membre__contact {
	font-size: var(--t-s);
	margin: 0;
}

.bureau-liste {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(13rem, 100%), 1fr));
	gap: 0.6rem var(--pas);
	border-top: 1px solid var(--coulisse);
	padding-top: var(--pas);
}
.bureau-liste li { font-size: var(--t-s); }
.bureau-liste span { color: var(--texte-faible); display: block; }

/* -------------------------------------------------------------------------
   Partenaires — la seule zone qui reste claire en mode sombre, parce que les
   logos partenaires sont dessinés pour du blanc.
   ------------------------------------------------------------------------- */

.partenaires {
	background: #FFFFFF;
	border-radius: var(--arrondi-fort) var(--arrondi-doux) var(--arrondi-fort) var(--arrondi-doux);
	padding: clamp(1.6rem, 4vw, 3rem);
}

.partenaires__grille {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(9rem, 100%), 1fr));
	gap: clamp(1.2rem, 3vw, 2.6rem);
	align-items: center;
}

.partenaire {
	display: grid;
	place-items: center;
	min-height: 5rem;
	transition: transform var(--vitesse-courte) var(--courbe);
}
.partenaire:hover { transform: scale(1.04); }
.partenaire img { max-height: 4.4rem; width: auto; object-fit: contain; }

.partenaire__vide {
	display: grid;
	place-items: center;
	min-height: 5rem;
	border: 1px dashed #C9D2E0;
	border-radius: 4px;
	/* #7C889B ne donnait que 3,59:1 sur blanc. */
	color: #5A6577;
	font-size: var(--t-xs);
	text-align: center;
	padding: 0.5rem;
}

.partenaires .titre-section { color: #0E1A33; }

/* =========================================================================
   L'assemblage du hero à l'arrivée

   Le contenu n'est masqué QUE si l'ouverture va réellement jouer : la classe
   « cnd-ouverture » est posée par le script en ligne de l'en-tête, juste
   avant de révéler le rideau. Si l'ouverture ne joue pas — deuxième visite,
   mouvement réduit, JavaScript absent — rien n'est masqué, le hero est
   visible dès le premier rendu et le LCP n'est pas retardé d'une seconde.
   ========================================================================= */

.cnd-ouverture .scene__legende,
.cnd-ouverture .scene__repli,
.cnd-ouverture .scene .bouton,
.cnd-ouverture .compteur__bloc,
.cnd-ouverture .compteur--en-cours,
.cnd-ouverture .scene__logo {
	opacity: 0;
}

.cnd-ouverture .compteur__bloc {
	/* Les chiffres montent : ils arrivent comme des volets qui se calent. */
	transform: translateY(0.6em);
}

.cnd-ouverture .scene__legende,
.cnd-ouverture .scene__repli,
.cnd-ouverture .scene .bouton {
	transform: translateY(1rem);
}

.cnd-ouverture .scene__logo {
	transform: scale(0.94);
}

/* -------------------------------------------------------------------------
   L'arrivée proprement dite

   Le décalage est court : quatre-vingts millisecondes entre chaque élément.
   Au-delà, on n'a plus l'impression d'un mouvement d'ensemble mais d'une
   liste qui s'affiche ligne à ligne.
   ------------------------------------------------------------------------- */

.scene.est-arrivee .scene__legende,
.scene.est-arrivee .scene__repli,
.scene.est-arrivee .bouton,
.scene.est-arrivee .compteur__bloc,
.scene.est-arrivee .compteur--en-cours,
.scene.est-arrivee .scene__logo {
	opacity: 1;
	transform: none;
	transition:
		opacity 520ms var(--courbe),
		transform 620ms var(--courbe);
}

/* Les quatre blocs du compte à rebours montent l'un après l'autre. */
.scene.est-arrivee .compteur__bloc:nth-child(1) { transition-delay: 120ms; }
.scene.est-arrivee .compteur__bloc:nth-child(2) { transition-delay: 200ms; }
.scene.est-arrivee .compteur__bloc:nth-child(3) { transition-delay: 280ms; }
.scene.est-arrivee .compteur__bloc:nth-child(4) { transition-delay: 360ms; }

.scene.est-arrivee .scene__legende,
.scene.est-arrivee .scene__repli { transition-delay: 440ms; }
.scene.est-arrivee .bouton       { transition-delay: 540ms; }

/* Le logo du décor arrive en dernier : le temps que celui du rideau ait fini
   son vol vers l'en-tête, pour qu'on n'en voie jamais deux à la fois. */
.scene.est-arrivee .scene__logo { transition-delay: 700ms; }

@media (prefers-reduced-motion: reduce) {
	.cnd-ouverture .scene__legende,
	.cnd-ouverture .scene__repli,
	.cnd-ouverture .scene .bouton,
	.cnd-ouverture .compteur__bloc,
	.cnd-ouverture .compteur--en-cours,
	.cnd-ouverture .scene__logo {
		opacity: 1;
		transform: none;
	}
}


/* ===== composants.css ===== */
/* =========================================================================
   Composants réutilisables : boutons, documents, tableaux, formulaires,
   mosaïque de photos, visionneuse, frise des stages
   ========================================================================= */

/* -------------------------------------------------------------------------
   Titres de section
   Les grands titres peuvent déborder de la grille : c'est voulu.
   ------------------------------------------------------------------------- */

.titre-section {
	font-size: var(--t-l);
	margin-bottom: var(--pas);
	max-width: 20ch;
}

.intro {
	font-size: var(--t-m);
	color: var(--texte-doux);
	max-width: 56ch;
	margin-bottom: var(--bloc);
}

/* -------------------------------------------------------------------------
   Boutons
   Les libellés disent ce qui va se passer : « Télécharger le bon de commande »
   et non « En savoir plus ». Aucune flèche collée au libellé.
   ------------------------------------------------------------------------- */

.bouton {
	display: inline-flex;
	align-items: center;
	gap: 0.6rem;
	padding: 0.85em 1.6em;
	border: 1px solid var(--projecteur);
	border-radius: 2rem;
	background: transparent;
	color: var(--projecteur);
	font: inherit;
	font-size: var(--t-s);
	font-weight: 600;
	text-decoration: none;
	cursor: pointer;
	transition:
		background var(--vitesse-courte) var(--courbe),
		color var(--vitesse-courte) var(--courbe),
		transform var(--vitesse-courte) var(--courbe);
}

.bouton:hover {
	background: var(--projecteur);
	color: var(--scene);
	transform: translateY(-2px);
}

.bouton--plein {
	background: var(--projecteur);
	color: var(--scene);
}
.bouton--plein:hover {
	background: transparent;
	color: var(--projecteur);
}

/* L'or, ici et sur les chiffres du compte à rebours. Nulle part ailleurs. */
.bouton--or {
	background: var(--or);
	border-color: var(--or);
	color: #1A1204;
	font-size: var(--t-base);
	padding: 1em 1.9em;
}
.bouton--or:hover {
	background: transparent;
	color: var(--or);
}
:root[data-theme="clair"] .bouton--or { color: #FFFFFF; }
:root[data-theme="clair"] .bouton--or:hover { color: var(--or); }

.bouton--discret {
	border-color: var(--coulisse);
	color: var(--scene-blanc);
}
.bouton--discret:hover {
	background: transparent;
	border-color: var(--projecteur);
	color: var(--projecteur);
}

.lien-suite {
	display: inline-block;
	font-weight: 600;
	margin-top: var(--pas);
}

/* -------------------------------------------------------------------------
   Documents à télécharger
   ------------------------------------------------------------------------- */

.documents {
	display: grid;
	gap: 1px;
	background: var(--coulisse);
	border: 1px solid var(--coulisse);
	border-radius: var(--arrondi-doux) var(--arrondi-fort) var(--arrondi-doux) var(--arrondi-fort);
	overflow: hidden;
}

.document {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--pas);
	padding: clamp(1rem, 2.4vw, 1.6rem);
	background: var(--velours);
	text-decoration: none;
	color: inherit;
	transition: background var(--vitesse-courte) var(--courbe);
}
.document:hover { background: color-mix(in srgb, var(--velours) 76%, var(--cnd)); }

.document__texte { flex: 1 1 16rem; }

.document__titre {
	font-family: var(--titre);
	font-size: var(--t-m);
	font-weight: 700;
	line-height: 1.15;
	margin: 0 0 0.2rem;
}

.document__note {
	font-size: var(--t-s);
	color: var(--texte-doux);
	margin: 0;
	max-width: 60ch;
}

.document__fichier {
	font-size: var(--t-xs);
	color: var(--texte-faible);
	font-variant-numeric: tabular-nums;
	white-space: nowrap;
}

.document__action {
	font-size: var(--t-s);
	font-weight: 600;
	color: var(--projecteur);
	white-space: nowrap;
}

/* -------------------------------------------------------------------------
   Filtres
   ------------------------------------------------------------------------- */

.filtres {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
	margin-bottom: var(--pas);
}

.filtre {
	padding: 0.4em 1em;
	border: 1px solid var(--coulisse);
	border-radius: 2rem;
	background: transparent;
	color: var(--texte-doux);
	font: inherit;
	font-size: var(--t-s);
	cursor: pointer;
	text-decoration: none;
}
.filtre:hover { border-color: var(--projecteur); color: var(--scene-blanc); }
.filtre[aria-pressed="true"],
.filtre[aria-current="true"] {
	border-color: var(--projecteur);
	background: var(--projecteur);
	color: var(--scene);
}

/* -------------------------------------------------------------------------
   Tableaux — le règlement rendu lisible
   ------------------------------------------------------------------------- */

.tableau-enveloppe {
	overflow-x: auto;
	border: 1px solid var(--coulisse);
	border-radius: var(--arrondi-doux);
	margin-bottom: var(--pas);
}

table {
	width: 100%;
	border-collapse: collapse;
	font-size: var(--t-s);
}

caption {
	text-align: left;
	padding: var(--pas);
	color: var(--texte-doux);
	font-size: var(--t-s);
}

th, td {
	text-align: left;
	padding: 0.85em 1em;
	border-bottom: 1px solid var(--coulisse);
	vertical-align: top;
}

thead th {
	background: var(--velours);
	font-weight: 600;
	color: var(--scene-blanc);
	position: sticky;
	top: 0;
}

tbody tr:last-child td { border-bottom: 0; }
tbody tr:hover { background: color-mix(in srgb, var(--velours) 60%, transparent); }


/* Le cadre défile ; il doit donc être atteignable au clavier, sinon la partie
   qui déborde n'appartient qu'à la souris. Le tabindex est posé par le
   JavaScript, et seulement quand le tableau déborde vraiment. */
.tableau-enveloppe:focus-visible {
	outline: var(--trait-epaisseur) solid var(--projecteur);
	outline-offset: 2px;
}

/* Sur un téléphone, un tableau de quatre colonnes se lit en faisant défiler.
   La colonne qui NOMME la ligne doit rester en vue, sans quoi « de 12 à 15 ans »
   arrive sans qu'on sache de quelle catégorie il s'agit. */
.tableau-enveloppe tbody th[scope="row"] {
	position: sticky;
	left: 0;
	background: var(--scene);
	font-weight: 600;
	color: var(--scene-blanc);
}

.tableau-enveloppe tbody tr:hover th[scope="row"] {
	background: color-mix(in srgb, var(--velours) 60%, var(--scene));
}

/* Le titre des tableaux de référence est posé au-dessus du cadre, et non dans
   un <caption> : une légende ne sait pas rester collée à gauche pendant un
   défilement horizontal, et partait donc hors de vue sur téléphone. */
.tableau-bloc {
	margin: var(--pas) 0;
}

.tableau-titre {
	margin: 0 0 0.5rem;
	font-family: var(--titre);
	font-size: var(--t-m);
	line-height: 1.15;
	color: var(--scene-blanc);
}

.tableau-bloc .tableau-enveloppe {
	margin-bottom: 0;
}


/* Une colonne de valeurs — « de 11 à 13 ans », « de 1 min 30 à 1 min 45 » —
   ne doit pas se replier sur quatre lignes parce que l'écran est étroit. On
   donne donc au tableau une largeur plancher proportionnelle au nombre de
   colonnes : en dessous, il défile au lieu de s'écraser, et la colonne qui
   nomme la ligne reste collée à gauche. */
.tableau-donnees {
	min-width: calc(var(--colonnes, 3) * 9rem);
}

.tableau-note {
	margin: 0.6rem 0 0;
	font-size: var(--t-xs);
	color: var(--texte-faible);
}

/* -------------------------------------------------------------------------
   Étapes numérotées — la procédure d'inscription
   La numérotation est justifiée ici : c'est une vraie séquence.
   ------------------------------------------------------------------------- */

.etapes {
	list-style: none;
	counter-reset: etape;
	margin: 0;
	padding: 0;
	display: grid;
	gap: var(--pas);
}

.etape {
	counter-increment: etape;
	display: grid;
	grid-template-columns: auto 1fr;
	gap: var(--pas);
	align-items: start;
	padding-bottom: var(--pas);
	border-bottom: 1px solid var(--coulisse);
}
.etape:last-child { border-bottom: 0; }

.etape::before {
	content: counter(etape);
	font-family: var(--titre);
	font-size: var(--t-l);
	font-weight: 700;
	line-height: 1;
	color: var(--cnd);
	font-variation-settings: "wdth" 80;
}
:root[data-theme="clair"] .etape::before { color: var(--projecteur); }

.etape h3 { font-size: var(--t-m); margin-bottom: 0.3rem; }
.etape p { margin-bottom: 0.4rem; }

/* -------------------------------------------------------------------------
   Liste à cocher imprimable — les pièces à réunir
   ------------------------------------------------------------------------- */

.checklist {
	list-style: none;
	margin: 0 0 var(--pas);
	padding: 0;
	display: grid;
	gap: 0.7rem;
	max-width: var(--largeur-texte);
}

.checklist li {
	display: grid;
	grid-template-columns: auto 1fr;
	gap: 0.9rem;
	align-items: start;
	padding-bottom: 0.7rem;
	border-bottom: 1px dashed var(--coulisse);
}

.checklist li::before {
	content: "";
	width: 1.1em;
	height: 1.1em;
	margin-top: 0.25em;
	border: 1.5px solid var(--projecteur);
	border-radius: 3px;
}

@media print {
	.entete, .pied, .fil, .curseur, .bouton, .menu { display: none !important; }
	body { background: #fff; color: #000; }
	.checklist li::before { border-color: #000; }
	a::after { content: " (" attr(href) ")"; font-size: 0.8em; }
}

/* -------------------------------------------------------------------------
   Formulaires
   ------------------------------------------------------------------------- */

.formulaire {
	display: grid;
	gap: var(--pas);
	max-width: 40rem;
}

.champ { display: grid; gap: 0.35rem; }

.champ label {
	font-size: var(--t-s);
	color: var(--texte-doux);
}

.champ input,
.champ textarea,
.champ select {
	width: 100%;
	padding: 0.8em 1em;
	background: var(--velours);
	border: 1px solid var(--coulisse);
	border-radius: var(--arrondi-doux);
	color: var(--scene-blanc);
	font: inherit;
	font-size: var(--t-s);
}

.champ input:focus,
.champ textarea:focus,
.champ select:focus {
	border-color: var(--projecteur);
	outline: 2px solid var(--halo);
	outline-offset: 0;
}

.champ textarea { min-height: 9rem; resize: vertical; }

.champ__aide {
	font-size: var(--t-xs);
	color: var(--texte-faible);
}

.message-formulaire {
	padding: 0.9em 1.2em;
	border-radius: var(--arrondi-doux);
	border-left: 3px solid;
	font-size: var(--t-s);
	max-width: 40rem;
}
.message-formulaire--succes {
	border-color: var(--projecteur);
	background: color-mix(in srgb, var(--projecteur) 12%, transparent);
}
.message-formulaire--erreur {
	border-color: var(--or);
	background: color-mix(in srgb, var(--or) 12%, transparent);
}

.mention-rgpd {
	font-size: var(--t-xs);
	color: var(--texte-faible);
	max-width: 44rem;
}

/* -------------------------------------------------------------------------
   Mosaïque de photos — irrégulière, jamais une grille de cartes identiques
   ------------------------------------------------------------------------- */

.mosaique {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(min(13rem, 100%), 1fr));
	grid-auto-rows: 11rem;
	gap: 0.6rem;
}

.mosaique__element {
	position: relative;
	overflow: hidden;
	border: 0;
	padding: 0;
	background: var(--velours);
	cursor: zoom-in;
	border-radius: var(--arrondi-doux);
}

/* Une photo sur quatre est plus haute, une sur sept plus large : le rythme
   n'est jamais régulier. */
.mosaique__element:nth-child(4n + 1) { grid-row: span 2; }
.mosaique__element:nth-child(7n + 3) { grid-column: span 2; }
.mosaique__element:nth-child(4n + 1) { border-radius: var(--arrondi-fort) var(--arrondi-doux) var(--arrondi-fort) var(--arrondi-doux); }

.mosaique__element img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform var(--vitesse-longue) var(--courbe);
}
.mosaique__element:hover img { transform: scale(1.05); }

.credit-photo {
	font-size: var(--t-xs);
	color: var(--texte-faible);
	margin-top: var(--pas);
}

/* -------------------------------------------------------------------------
   Vidéos YouTube en chargement différé
   La vidéo n'est chargée qu'au clic : YouTube ne dépose aucun cookie avant.
   ------------------------------------------------------------------------- */

.videos {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(20rem, 100%), 1fr));
	gap: var(--pas);
	margin-top: var(--bloc);
}

.video {
	position: relative;
	aspect-ratio: 16 / 9;
	border: 0;
	padding: 0;
	background: var(--velours);
	border-radius: var(--arrondi-fort) var(--arrondi-doux) var(--arrondi-fort) var(--arrondi-doux);
	overflow: hidden;
	cursor: pointer;
	width: 100%;
}

.video img { width: 100%; height: 100%; object-fit: cover; opacity: 0.7; }
.video iframe { width: 100%; height: 100%; border: 0; }

.video__lecture {
	position: absolute;
	inset: 0;
	display: grid;
	place-items: center;
	gap: 0.6rem;
	align-content: center;
	color: var(--scene-blanc);
	pointer-events: none;
}

.video__rond {
	width: 4rem;
	height: 4rem;
	border-radius: 50%;
	background: var(--projecteur);
	display: grid;
	place-items: center;
	color: var(--scene);
	transition: transform var(--vitesse-courte) var(--courbe);
}
.video:hover .video__rond { transform: scale(1.12); }

.video__titre { font-size: var(--t-s); padding-inline: var(--pas); text-align: center; }

/* -------------------------------------------------------------------------
   Visionneuse
   ------------------------------------------------------------------------- */

.visionneuse {
	position: fixed;
	inset: 0;
	z-index: 90;
	background: color-mix(in srgb, var(--scene) 94%, transparent);
	display: grid;
	place-items: center;
	padding: var(--marge);
}
.visionneuse[hidden] { display: none; }

.visionneuse img {
	max-width: min(96vw, 1400px);
	max-height: 84svh;
	object-fit: contain;
	border-radius: var(--arrondi-doux);
}

.visionneuse__legende {
	position: absolute;
	bottom: var(--marge);
	left: 50%;
	transform: translateX(-50%);
	font-size: var(--t-s);
	color: var(--texte-doux);
	text-align: center;
	max-width: 60ch;
}

.visionneuse__bouton {
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	width: 3rem;
	height: 3rem;
	display: grid;
	place-items: center;
	border: 1px solid var(--coulisse);
	border-radius: 50%;
	background: var(--velours);
	color: var(--scene-blanc);
	cursor: pointer;
}
.visionneuse__bouton:hover { border-color: var(--projecteur); }
.visionneuse__precedent { left: var(--marge); }
.visionneuse__suivant { right: var(--marge); }
.visionneuse__fermer { top: var(--marge); right: var(--marge); transform: none; }

/* -------------------------------------------------------------------------
   Frise horizontale de la saison — le seul défilement latéral du site,
   parce qu'ici le mouvement de côté porte du sens : c'est une chronologie.
   ------------------------------------------------------------------------- */

.frise {
	display: grid;
	grid-auto-flow: column;
	grid-auto-columns: minmax(min(19rem, 82vw), 1fr);
	gap: var(--pas);
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	padding-bottom: var(--pas);
	scrollbar-width: thin;
}

.frise > * { scroll-snap-align: start; }

.frise::-webkit-scrollbar { height: 6px; }
.frise::-webkit-scrollbar-thumb { background: var(--coulisse); border-radius: 3px; }

.stage-carte {
	display: grid;
	gap: 0.5rem;
	align-content: start;
	padding: clamp(1.2rem, 2.6vw, 1.8rem);
	background: var(--velours);
	border: 1px solid var(--coulisse);
	border-radius: var(--arrondi-fort) var(--arrondi-doux) var(--arrondi-fort) var(--arrondi-doux);
	text-decoration: none;
	color: inherit;
	transition: border-color var(--vitesse-courte) var(--courbe);
}
.stage-carte:hover { border-color: var(--projecteur); }

.stage-carte__date {
	font-family: var(--titre);
	font-size: var(--t-m);
	font-weight: 700;
	color: var(--projecteur);
	font-variation-settings: "wdth" 86;
}

/* -------------------------------------------------------------------------
   États vides — soignés, jamais une page cassée
   ------------------------------------------------------------------------- */

.etat-vide {
	display: grid;
	gap: var(--pas);
	justify-items: start;
	padding: clamp(1.6rem, 4vw, 3rem);
	border: 1px dashed var(--coulisse);
	border-radius: var(--arrondi-fort) var(--arrondi-doux) var(--arrondi-fort) var(--arrondi-doux);
	max-width: 46rem;
}

.etat-vide p { color: var(--texte-doux); margin: 0; }

/* -------------------------------------------------------------------------
   Accordéon des archives par année
   ------------------------------------------------------------------------- */

.archive-annee {
	border-bottom: 1px solid var(--coulisse);
}

.archive-annee summary {
	cursor: pointer;
	padding: var(--pas) 0;
	font-family: var(--titre);
	font-size: var(--t-m);
	font-weight: 700;
	list-style: none;
	display: flex;
	justify-content: space-between;
	align-items: center;
	gap: var(--pas);
}
.archive-annee summary::-webkit-details-marker { display: none; }
.archive-annee summary::after {
	content: "+";
	color: var(--projecteur);
	font-size: var(--t-m);
	transition: transform var(--vitesse-courte) var(--courbe);
}
.archive-annee[open] summary::after { transform: rotate(45deg); }

/* -------------------------------------------------------------------------
   Contenu rédactionnel libre (éditeur WordPress)
   ------------------------------------------------------------------------- */

.contenu > * { max-width: var(--largeur-texte); }
.contenu h2 { margin-top: var(--bloc); }
.contenu h3 { margin-top: calc(var(--bloc) / 2); }
.contenu ul, .contenu ol { padding-left: 1.3em; }
.contenu li { margin-bottom: 0.4em; }
.contenu img { border-radius: var(--arrondi-doux); max-width: 100%; }
.contenu blockquote {
	border-left: 2px solid var(--cnd);
	padding-left: var(--pas);
	color: var(--texte-doux);
	font-size: var(--t-m);
	margin-inline: 0;
}

/* Carte du lieu, chargée sans cookie tiers via une image statique ou un lien */
.carte-lieu {
	display: grid;
	gap: var(--pas);
	padding: var(--pas);
	border: 1px solid var(--coulisse);
	border-radius: var(--arrondi-doux);
	max-width: 40rem;
}

/* -------------------------------------------------------------------------
   Le bloc Instagram

   Les images arrivent du serveur, jamais du navigateur du visiteur : c'est ce
   qui permet de se passer de bannière de consentement. Rien ici ne charge
   quoi que ce soit chez Meta.
   ------------------------------------------------------------------------- */

.instagram {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(9rem, 45%), 1fr));
	gap: 0.6rem;
	margin-bottom: var(--pas);
}

.instagram__vignette {
	position: relative;
	display: block;
	aspect-ratio: 1;
	overflow: hidden;
	/* Un côté arrondi, un côté vif, comme les autres cadres du site. */
	border-radius: var(--arrondi-fort) var(--arrondi-doux) var(--arrondi-fort) var(--arrondi-doux);
	background: var(--velours);
}

.instagram__vignette img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform var(--vitesse-longue) var(--courbe);
}

.instagram__vignette:hover img,
.instagram__vignette:focus-visible img {
	transform: scale(1.06);
}

.instagram__video {
	position: absolute;
	right: 0.6rem;
	bottom: 0.6rem;
	display: grid;
	place-items: center;
	width: 2rem;
	height: 2rem;
	border-radius: 50%;
	background: color-mix(in srgb, var(--scene) 72%, transparent);
	color: var(--scene-blanc);
}

/* -------------------------------------------------------------------------
   Le relief : une carte que l'on peut prendre

   L'inclinaison n'est pas un ornement. Elle dit « ceci est un objet », et
   c'est ce qui distingue une carte cliquable d'un simple encadré. Elle est
   volontairement faible — cinq degrés et demi — parce qu'au-delà l'effet
   devient un gadget et le texte se déforme.

   La perspective est posée sur la carte elle-même, par la fonction
   perspective() dans la transformation, et non sur un parent. C'est ce qui
   rend la règle universelle : n'importe quelle carte peut porter
   [data-relief] sans que son conteneur ait à s'y préparer.

   Le JavaScript n'écrit que deux angles dans des propriétés personnalisées.
   Toute la transformation se fait ici, sur le compositeur — donc sans
   repeindre, et sans toucher à la mise en page.
   ------------------------------------------------------------------------- */

[data-relief] {
	/* La brillance en ::before se cale sur inset: 0. Sans bloc conteneur ici,
	   elle irait se poser sur un ancetre au hasard. La regle generique doit
	   donc garantir son propre reperage, sans compter sur la carte. */
	position: relative;
	transform:
		perspective(1400px)
		rotateX(var(--relief-x, 0deg))
		rotateY(var(--relief-y, 0deg));
	transform-style: preserve-3d;
	transition: transform var(--vitesse) var(--courbe);
}

/* La brillance suit le curseur : c'est elle qui fait lire le volume. Sans
   elle, l'inclinaison seule passe inaperçue. */
[data-relief]::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 2;
	border-radius: inherit;
	pointer-events: none;
	opacity: 0;
	background: radial-gradient(
		48rem circle at var(--brillance-x, 50%) var(--brillance-y, 50%),
		color-mix(in srgb, var(--projecteur) 18%, transparent),
		transparent 52%
	);
	transition: opacity var(--vitesse) var(--courbe);
}

[data-relief].est-en-relief {
	/* Pendant le survol, la carte doit coller au curseur : une transition
	   longue donnerait l'impression d'un élastique. */
	transition-duration: 120ms;
	box-shadow: 0 2rem 4rem -1.5rem color-mix(in srgb, var(--scene) 70%, transparent);
}

[data-relief].est-en-relief::before {
	opacity: 1;
}

.concours-carte:hover,
.concours-carte:focus-visible {
	border-color: var(--projecteur);
}

@media (prefers-reduced-motion: reduce) {
	[data-relief] {
		transform: none;
	}
}

/* -------------------------------------------------------------------------
   Les documents essentiels

   La mission première du site est de distribuer des documents. Une liste
   alphabétique traite le bon de commande des variations imposées comme le
   compte rendu d'assemblée générale — alors que l'un est attendu par toutes
   les écoles de la région et l'autre par personne.

   Ces cartes existent pour rompre cette égalité. Elles portent [data-relief],
   donc l'inclinaison et la brillance viennent de la règle générique.
   ------------------------------------------------------------------------- */

.vedettes {
	display: grid;
	gap: var(--pas);
	margin-block-start: var(--pas);
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
}

.document-vedette {
	display: grid;
	gap: 0.6rem;
	align-content: start;
	padding: clamp(1.4rem, 3vw, 2.1rem);
	background: var(--scene);
	border: 1px solid var(--coulisse);
	border-radius: var(--arrondi-fort) var(--arrondi-doux) var(--arrondi-fort) var(--arrondi-doux);
	text-decoration: none;
	color: inherit;
	/* La transition du relief est déjà posée par [data-relief] ; on n'ajoute
	   ici que la couleur du bord, pour ne pas écraser la première. */
	transition:
		transform var(--vitesse) var(--courbe),
		border-color var(--vitesse-courte) var(--courbe);
}

.document-vedette:hover,
.document-vedette:focus-visible {
	border-color: var(--or);
}

.document-vedette__titre {
	margin: 0;
	font-size: var(--t-l);
	line-height: 1.15;
}

.document-vedette__note {
	margin: 0;
	color: var(--texte-faible);
	font-size: var(--t-s);
}

/* L'action se détache du texte : c'est elle qui dit que la carte télécharge
   un fichier, et non qu'elle mène à une page de plus. */
.document-vedette__action {
	display: flex;
	align-items: center;
	gap: 0.5rem;
	flex-wrap: wrap;
	margin-block-start: 0.4rem;
	font-family: var(--titre);
	font-weight: 700;
	color: var(--or);
}

.document-vedette__action svg {
	inline-size: 1.1em;
	block-size: 1.1em;
	flex: none;
}

/* -------------------------------------------------------------------------
   La recherche

   L'étiquette est visible et non masquée pour lecteur d'écran seul. Une loupe
   sans mot oblige à deviner, et ce site est consulté par des parents pressés
   entre deux cours : deviner est un coût qu'on peut leur épargner.
   ------------------------------------------------------------------------- */

.recherche {
	display: grid;
	gap: 0.6rem;
	margin-block: var(--pas);
}

.recherche__etiquette {
	font-family: var(--titre);
	font-weight: 700;
	font-size: var(--t-s);
	color: var(--texte-faible);
}

/* Sur petit écran les deux éléments passent l'un sous l'autre : un champ de
   recherche écrasé à six caractères ne sert personne. */
.recherche__ligne {
	display: flex;
	flex-wrap: wrap;
	gap: 0.6rem;
}

.recherche__champ {
	flex: 1 1 14rem;
	min-inline-size: 0;
	padding: 0.85rem 1.1rem;
	font: inherit;
	color: var(--texte);
	background: var(--velours);
	border: 1px solid var(--coulisse);
	border-radius: var(--arrondi-doux);
	transition: border-color var(--vitesse-courte) var(--courbe);
}

.recherche__champ::placeholder {
	color: var(--texte-faible);
}

.recherche__champ:focus-visible {
	border-color: var(--projecteur);
}

/* Le navigateur ajoute sa propre croix d'effacement, qui ne suit pas la
   charte et se voit à peine sur fond sombre. Le champ est court : la
   sélection au clavier suffit. */
.recherche__champ::-webkit-search-cancel-button {
	appearance: none;
}

/* -------------------------------------------------------------------------
   Le sommaire des pages légales

   Cent vingt lignes de texte juridique sans point d'entrée obligent à lire
   pour trouver. Le sommaire est une liste ORDONNÉE : l'ordre des sections a un
   sens dans un texte légal, et le lecteur qui cherche « vos droits » a besoin
   de savoir qu'il y a six parties, pas seulement laquelle cliquer.
   ------------------------------------------------------------------------- */

.sommaire {
	margin-block: var(--pas);
	padding: clamp(1.1rem, 2.6vw, 1.6rem);
	background: var(--velours);
	border: 1px solid var(--coulisse);
	border-radius: var(--arrondi-fort) var(--arrondi-doux) var(--arrondi-fort) var(--arrondi-doux);
}

.sommaire__titre {
	margin: 0 0 0.7rem;
	font-size: var(--t-s);
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--texte-faible);
}

/* Deux colonnes dès que la place le permet : six entrées en une seule colonne
   font une liste plus haute que la première section du texte. */
.sommaire__liste {
	margin: 0;
	padding-inline-start: 1.3rem;
	display: grid;
	gap: 0.4rem 1.5rem;
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
}

.sommaire__liste a {
	color: inherit;
	text-decoration-color: var(--coulisse);
	text-underline-offset: 0.22em;
	transition: text-decoration-color var(--vitesse-courte) var(--courbe);
}

.sommaire__liste a:hover,
.sommaire__liste a:focus-visible {
	text-decoration-color: var(--projecteur);
}

/* Le titre visé s'allume brièvement : sans cela, rien ne confirme au lecteur
   que le saut a bien eu lieu à l'endroit voulu. */
.contenu h2:target {
	animation: cible-atteinte 1.6s var(--courbe);
}

@keyframes cible-atteinte {
	from { color: var(--projecteur); }
	to   { color: inherit; }
}

@media (prefers-reduced-motion: reduce) {
	.contenu h2:target { animation: none; }
}

/* -------------------------------------------------------------------------
   L'étiquette

   Elle vivait dans la feuille de l'accueil alors qu'elle sert sur quatorze
   pages. Elle est ici parce qu'elle appartient à tout le site.
   ------------------------------------------------------------------------- */

.etiquette {
	display: inline-block;
	font-size: var(--t-xs);
	color: var(--projecteur);
	border: 1px solid currentColor;
	border-radius: 1em;
	padding: 0.1em 0.7em;
	margin-bottom: 0.6rem;
}

.etiquette--or {
	color: var(--or);
}

/* Ce qui est terminé doit se lire sans attirer l'œil : le contraste reste
   conforme, mais l'étiquette ne concurrence plus les rendez-vous à venir. */
.etiquette--faible {
	color: var(--texte-faible);
}

/* -------------------------------------------------------------------------
   Le calendrier de la saison

   Une ligne de temps, pas un tableau. Un tableau imposerait des colonnes de
   largeur égale à des rendez-vous dont les titres vont de trois mots à douze,
   et forcerait un lecteur d'écran à annoncer « ligne 4, colonne 2 » là où il
   suffit de dire « 14 mars, concours régional ».
   ------------------------------------------------------------------------- */

.mois + .mois {
	margin-block-start: calc(var(--pas) * 2);
}

.mois__titre {
	font-size: var(--t-m);
	text-transform: capitalize;
	color: var(--texte-faible);
	padding-block-end: 0.5rem;
	border-block-end: 1px solid var(--coulisse);
	margin-block-end: 0.8rem;
}

/* Un mois entièrement passé s'efface, sans disparaître : le visiteur doit
   pouvoir vérifier qu'un concours a bien eu lieu. Il reprend sa pleine
   opacité au survol et au clavier. */
.mois--passe {
	opacity: 0.55;
	transition: opacity var(--vitesse) var(--courbe);
}

.mois--passe:hover,
.mois--passe:focus-within {
	opacity: 1;
}

.agenda {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	gap: 0.5rem;
}

.agenda__lien {
	display: grid;
	grid-template-columns: auto 1fr auto;
	align-items: center;
	gap: 1rem;
	padding: 0.8rem 1rem;
	text-decoration: none;
	color: inherit;
	background: var(--scene);
	border: 1px solid transparent;
	border-radius: var(--arrondi-doux);
	transition:
		border-color var(--vitesse-courte) var(--courbe),
		background var(--vitesse-courte) var(--courbe);
}

.agenda__lien:hover,
.agenda__lien:focus-visible {
	border-color: var(--projecteur);
}

/* Le quantième en gros, le mois en petit : c'est la forme d'un feuillet de
   calendrier, reconnue sans avoir à la lire. */
.agenda__date {
	display: grid;
	justify-items: center;
	min-inline-size: 3rem;
	line-height: 1.05;
}

.agenda__jour {
	font-family: var(--titre);
	font-size: var(--t-l);
	font-weight: 700;
	color: var(--projecteur);
	font-variation-settings: "wdth" 86;
}

.agenda__mois {
	font-size: var(--t-xs);
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: var(--texte-faible);
}

.agenda__texte {
	display: grid;
	gap: 0.1rem;
	min-inline-size: 0;
}

.agenda__type {
	font-size: var(--t-xs);
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: var(--texte-faible);
}

.agenda__titre {
	font-family: var(--titre);
	font-weight: 700;
}

.agenda__note {
	font-size: var(--t-s);
	color: var(--texte-faible);
}

.agenda__statut .etiquette {
	margin-bottom: 0;
	white-space: nowrap;
}

/* Sur petit écran l'étiquette de statut passe sous le texte : la garder en
   troisième colonne écraserait le titre à deux mots par ligne. */
@media (max-width: 34rem) {
	.agenda__lien {
		grid-template-columns: auto 1fr;
	}

	.agenda__statut {
		grid-column: 2;
	}
}

/* -------------------------------------------------------------------------
   Les questions fréquentes

   Bâties sur <details> et <summary>. Le navigateur fournit gratuitement
   l'ouverture au clic et au clavier, l'état annoncé au lecteur d'écran, et la
   recherche dans la page qui déplie la bonne réponse.

   On ne masque donc QUE la flèche native, en gardant le comportement intact.
   Poser display:none sur le summary lui-même le rendrait non focalisable, ce
   qui casserait tout ce qu'on vient d'obtenir sans effort.
   ------------------------------------------------------------------------- */

.faq {
	display: grid;
	gap: 0.6rem;
	margin-block: var(--pas);
}

.faq__entree {
	background: var(--velours);
	border: 1px solid var(--coulisse);
	border-radius: var(--arrondi-doux);
	overflow: hidden;
	transition: border-color var(--vitesse-courte) var(--courbe);
}

.faq__entree[open] {
	border-color: var(--projecteur);
}

.faq__question {
	display: flex;
	align-items: baseline;
	gap: 0.8rem;
	/* 44 px de haut au minimum : c'est la cible tactile du critère 2.5.8. */
	min-block-size: 44px;
	padding: 0.9rem 1.1rem;
	font-family: var(--titre);
	font-weight: 700;
	cursor: pointer;
	list-style: none;
}

/* Les deux syntaxes sont nécessaires : la première pour les navigateurs
   WebKit, la seconde pour les autres. */
.faq__question::-webkit-details-marker { display: none; }
.faq__question::marker { content: ""; }

.faq__question:hover {
	color: var(--projecteur);
}

/* Le chevron est dessiné en CSS plutôt qu'en SVG : deux traits suffisent, et
   cela évite un aller-retour dans le jeu d'icônes pour une décoration. */
.faq__question::before {
	content: "";
	flex: none;
	inline-size: 0.55em;
	block-size: 0.55em;
	margin-block-start: 0.25em;
	border-inline-end: 2px solid var(--projecteur);
	border-block-end: 2px solid var(--projecteur);
	transform: rotate(-45deg);
	transition: transform var(--vitesse) var(--courbe);
}

.faq__entree[open] .faq__question::before {
	transform: rotate(45deg);
}

.faq__reponse {
	padding: 0 1.1rem 1.1rem;
	/* Aligné sur le texte de la question, pas sur le chevron. */
	padding-inline-start: calc(1.1rem + 0.55em + 0.8rem);
}

.faq__reponse > :first-child { margin-block-start: 0; }
.faq__reponse > :last-child { margin-block-end: 0; }

@media (prefers-reduced-motion: reduce) {
	.faq__question::before { transition: none; }
}

/* -------------------------------------------------------------------------
   Les disciplines

   Huit cartes égales : aucune discipline ne prime sur une autre, et une
   hiérarchie visuelle inventée ici serait un message que le comité n'a pas
   voulu envoyer.
   ------------------------------------------------------------------------- */

.disciplines {
	display: grid;
	gap: var(--pas);
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
}

.discipline {
	display: grid;
	gap: 0.4rem;
	align-content: start;
	padding: clamp(1.2rem, 2.8vw, 1.8rem);
	background: var(--scene);
	border: 1px solid var(--coulisse);
	border-radius: var(--arrondi-fort) var(--arrondi-doux) var(--arrondi-fort) var(--arrondi-doux);
	text-decoration: none;
	color: inherit;
	transition:
		transform var(--vitesse) var(--courbe),
		border-color var(--vitesse-courte) var(--courbe);
}

a.discipline:hover,
a.discipline:focus-visible {
	border-color: var(--projecteur);
}

.discipline__nom {
	margin: 0;
	font-size: var(--t-m);
	line-height: 1.1;
}

.discipline__note {
	margin: 0;
	font-size: var(--t-s);
	color: var(--texte-faible);
}

.discipline__compte {
	margin: 0.2rem 0 0;
	font-size: var(--t-xs);
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: var(--projecteur);
}

/* Le résumé d'un palmarès, sous sa ligne : décalé sur le texte, pas sur
   l'année, pour qu'on lise l'un comme la suite de l'autre. */
.agenda__resume {
	padding: 0.2rem 1rem 0.8rem calc(3rem + 2rem);
	font-size: var(--t-s);
	color: var(--texte-faible);
}

.agenda__resume > :last-child { margin-block-end: 0; }

@media (max-width: 34rem) {
	.agenda__resume { padding-inline-start: 1rem; }
}

/* -------------------------------------------------------------------------
   La lueur des pages intérieures

   L'accueil a sa scène en WebGL. Les autres pages en gardent une trace : un
   dégradé radial dont le centre suit le curseur.

   Tout tient en un pseudo-élément et deux propriétés personnalisées. Le
   JavaScript ne fait que déplacer le centre — la composition reste au
   navigateur, donc au compositeur, sans recalcul de mise en page.

   Le repli à 50 % compte autant que le reste : sans JavaScript, sur écran
   tactile, ou quand le visiteur a demandé le calme, la lueur reste centrée et
   la page garde exactement la même allure.
   ------------------------------------------------------------------------- */

.a-lueur {
	position: relative;
	isolation: isolate;
}

.a-lueur::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	pointer-events: none;
	background: radial-gradient(
		52rem circle at var(--lueur-x, 50%) var(--lueur-y, 50%),
		color-mix(in srgb, var(--projecteur) 13%, transparent),
		transparent 62%
	);
	/* La transition rattrape le curseur avec un temps de retard : une lueur
	   qui colle au pixel près ressemble à un curseur, pas à une lumière. */
	transition: background-position var(--vitesse) var(--courbe);
}

/* Sur fond clair, la même quantité de lumière écraserait le texte. */
:root[data-theme="light"] .a-lueur::before {
	background: radial-gradient(
		52rem circle at var(--lueur-x, 50%) var(--lueur-y, 50%),
		color-mix(in srgb, var(--projecteur) 7%, transparent),
		transparent 62%
	);
}

@media (prefers-reduced-motion: reduce) {
	.a-lueur::before { transition: none; }
}

/* ---------------------------------------------------------------------------
   Repères : un terme, son sens
   --------------------------------------------------------------------------- */

.reperes {
	display: grid;
	gap: var(--pas);
	margin: var(--pas) 0 0;
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
}

.repere {
	padding: clamp(1rem, 2.4vw, 1.5rem);
	background: var(--scene);
	border: 1px solid var(--coulisse);
	border-radius: var(--arrondi-fort) var(--arrondi-doux) var(--arrondi-fort) var(--arrondi-doux);
}

.repere__nom {
	margin: 0 0 0.35rem;
	font-family: var(--titre);
	font-size: var(--t-base);
	line-height: 1.2;
	color: var(--scene-blanc);
}

.repere__texte {
	margin: 0;
	font-size: var(--t-s);
	color: var(--texte-doux);
}

.reperes--serre {
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 21rem), 1fr));
}

/* ---------------------------------------------------------------------------
   Listes titrées : tenues, pièces du dossier
   --------------------------------------------------------------------------- */

.listes {
	display: grid;
	gap: var(--pas);
	margin: var(--pas) 0;
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 19rem), 1fr));
}

.liste-bloc {
	padding: clamp(1rem, 2.4vw, 1.5rem);
	background: var(--scene);
	border: 1px solid var(--coulisse);
	border-radius: var(--arrondi-fort) var(--arrondi-doux) var(--arrondi-fort) var(--arrondi-doux);
}

.liste-bloc__titre {
	margin: 0 0 0.6rem;
	font-size: var(--t-base);
	line-height: 1.2;
	color: var(--scene-blanc);
}

.liste-bloc__points {
	margin: 0;
	padding-left: 1.1rem;
	display: grid;
	gap: 0.5rem;
	font-size: var(--t-s);
	color: var(--texte-doux);
}

.liste-bloc__points li::marker { color: var(--projecteur); }


/* ===== transitions.css ===== */
/* =========================================================================
   Transitions entre les pages

   Le brief demande un fondu « sur le trait, sans écran blanc ». Autrement
   dit : en passant d'une page à l'autre, l'en-tête et la ligne verticale ne
   doivent pas clignoter — seul le contenu change.

   Fait avec l'API native de transition de vue, et non en JavaScript.

   Pourquoi c'est le bon choix ici, et pas un caprice technique :

   L'approche courante consiste à intercepter chaque clic, jouer une
   animation, puis naviguer. Elle casse tout ce à quoi on ne pense pas :
   le bouton retour, le clic du milieu, Ctrl+clic, les liens de
   téléchargement, les ancres, les liens externes. Sur un site dont la mission
   première est de distribuer des documents à télécharger, casser les liens de
   téléchargement serait une faute grave.

   L'API native ne casse rien : le navigateur navigue normalement et se charge
   du fondu. Là où elle n'existe pas — Firefox aujourd'hui — la navigation est
   simplement instantanée, comme sur n'importe quel site. Personne ne voit
   d'erreur, personne ne perd de fonction.
   ========================================================================= */

@view-transition {
	navigation: auto;
}

/*
 * Les éléments qui portent un nom sont reconnus d'une page à l'autre : le
 * navigateur les considère comme le MÊME élément et ne les fait donc pas
 * clignoter. C'est exactement ce que demande le brief : le trait et l'en-tête
 * restent en place, seul le contenu se renouvelle.
 */
.entete {
	view-transition-name: entete;
}

.fil {
	view-transition-name: fil;
}

#contenu {
	view-transition-name: contenu;
}

.pied {
	view-transition-name: pied;
}

/* -------------------------------------------------------------------------
   Le fondu lui-même

   Court et asymétrique : la page qui part s'efface plus vite que la nouvelle
   n'arrive. C'est ce décalage qui donne l'impression d'un enchaînement plutôt
   que d'un remplacement.

   Rien d'autre que opacity et transform, comme partout ailleurs sur le site.
   ------------------------------------------------------------------------- */

::view-transition-old(contenu) {
	animation: page-sort 180ms var(--courbe) both;
}

::view-transition-new(contenu) {
	animation: page-entre 320ms var(--courbe) 60ms both;
}

@keyframes page-sort {
	to {
		opacity: 0;
		transform: translateY(-0.6rem);
	}
}

@keyframes page-entre {
	from {
		opacity: 0;
		transform: translateY(1rem);
	}
}

/*
 * L'en-tête, le trait et le pied de page ne bougent pas du tout. Sans cette
 * règle, le navigateur leur applique un fondu croisé par défaut — et on
 * retrouverait le clignotement que l'on cherche précisément à éviter.
 */
::view-transition-old(entete),
::view-transition-new(entete),
::view-transition-old(fil),
::view-transition-new(fil),
::view-transition-old(pied),
::view-transition-new(pied) {
	animation: none;
	mix-blend-mode: normal;
}

/* -------------------------------------------------------------------------
   Mouvement réduit

   La navigation reste instantanée, sans fondu. On ne désactive pas l'API :
   on met simplement les animations à zéro, ce qui revient au comportement
   d'un site ordinaire.
   ------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
	::view-transition-old(contenu),
	::view-transition-new(contenu) {
		animation: none;
	}
}
