/*
 * Mouvement : animations sobres (docs/design.md, section « Mouvement »).
 * Jetons de durée et de courbe dans jetons.css (--duree-*, --courbe*, --decalage-liste…). Aucune durée en dur ici.
 * Couche composants : un thème (couche theme) peut surcharger. Tout mouvement est sous prefers-reduced-motion: no-preference ;
 * en reduce, rien ne bouge (seuls les états finaux s'affichent). Aucune animation en boucle. Aucune animation sur height/top/left.
 */

/* Navigation entre pages (hx-boost + globalViewTransitions, app.js inchangé) : fondu croisé, navigations classiques incluses. */
@view-transition {
	navigation: auto;
}

@layer composants {
	/* details : hauteur animable par mots-clés (Chrome 129+, sans effet ailleurs). */
	:root {
		interpolate-size: allow-keywords;
	}

	@keyframes mouvement-apparait {
		from { opacity: 0; transform: translateY(var(--mouvement-deplacement)); }
	}

	@keyframes mouvement-croit {
		from { transform: scaleX(0); }
	}

	@keyframes mouvement-progres {
		from { transform: scaleX(0); }
		to { transform: scaleX(.85); }
	}

	@keyframes mouvement-entete {
		from { box-shadow: 0 0 0 0 transparent; }
		to { box-shadow: 0 6px 12px -10px color-mix(in srgb, var(--texte) 45%, transparent); }
	}

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

	@media (prefers-reduced-motion: no-preference) {
		/* 1. Navigation : durée et courbe du fondu croisé ; l'en-tête ne bouge pas (zone de transition propre, sans animation). */
		::view-transition-old(root),
		::view-transition-new(root) {
			animation-duration: var(--duree);
			animation-timing-function: var(--courbe);
		}

		/* En-tête et bandeau bêta (un seul par page) : figés pendant la transition de vue, hors du fondu de la page. */
		header {
			view-transition-name: entete;
		}

		.banniere.beta {
			view-transition-name: bandeau-beta;
		}

		::view-transition-old(entete),
		::view-transition-new(entete),
		::view-transition-old(bandeau-beta),
		::view-transition-new(bandeau-beta) {
			animation: none;
		}

		/* 2. Barre de progression fine en haut, pendant une requête htmx. Apparaît après --delai-progres (pas de clignotement) ;
		   avec fill-mode « both », elle reste invisible (scaleX 0) avant ce délai. Ne boucle pas : elle s'arrête à 85 %. */
		:root:has(.htmx-request)::before {
			content: "";
			position: fixed;
			top: 0;
			left: 0;
			z-index: 100;
			width: 100%;
			height: 2px;
			background: var(--accent);
			transform-origin: left center;
			pointer-events: none;
			animation: mouvement-progres var(--duree-progres) var(--courbe) var(--delai-progres) both;
		}

		/* 3. Contenu htmx remplacé : entrée douce des enfants des cibles de swap. Transition et @starting-style portés par le sélecteur
		   (et non par la classe htmx-added, retirée dès le réglage par htmx, ce qui couperait une animation par classe). */
		:is(#resultats, #stats-corps, #volet-signets, #historique, #details, .historique-zone) > * {
			transition: opacity var(--duree-lente) var(--courbe-entree), transform var(--duree-lente) var(--courbe-entree);
		}

		@starting-style {
			:is(#resultats, #stats-corps, #volet-signets, #historique, #details, .historique-zone) > * {
				opacity: 0;
				transform: translateY(var(--mouvement-deplacement));
			}
		}

		/* 4. Menus et détails : ouverture en hauteur (interpolate-size), contenu rogné sans couper les contours de focus (overflow-clip-margin). */
		details::details-content {
			block-size: 0;
			overflow: clip;
			overflow-clip-margin: .5rem;
			transition: block-size var(--duree) var(--courbe), content-visibility var(--duree) allow-discrete;
		}

		details[open]::details-content {
			block-size: auto;
		}

		@starting-style {
			details[open]::details-content {
				block-size: 0;
			}
		}

		/* 5. Dialogue d'aide : entrée en fondu et glissement, voile en fondu. */
		dialog {
			opacity: 1;
			transform: none;
			transition: opacity var(--duree) var(--courbe), transform var(--duree) var(--courbe-entree),
				overlay var(--duree) allow-discrete, display var(--duree) allow-discrete;
		}

		dialog:not([open]) {
			opacity: 0;
			transform: translateY(var(--mouvement-deplacement));
		}

		@starting-style {
			dialog[open] {
				opacity: 0;
				transform: translateY(var(--mouvement-deplacement));
			}
		}

		dialog::backdrop {
			background: color-mix(in srgb, var(--texte) 35%, transparent);
			transition: background-color var(--duree) var(--courbe), overlay var(--duree) allow-discrete, display var(--duree) allow-discrete;
		}

		dialog:not([open])::backdrop {
			background-color: transparent;
		}

		@starting-style {
			dialog[open]::backdrop {
				background-color: transparent;
			}
		}

		/* 6. Messages (confirmation, erreur) : entrée douce à l'apparition. Jamais les bandeaux du haut (.banniere : bêta, annonces) :
		   la navigation boostée recrée tout le <body>, ils réapparaîtraient à chaque page. */
		.ok,
		.erreur {
			transition: opacity var(--duree) var(--courbe-entree), transform var(--duree) var(--courbe-entree);
		}

		@starting-style {
			.ok,
			.erreur {
				opacity: 0;
				transform: translateY(calc(var(--mouvement-deplacement) * -1));
			}
		}

		/* 7. Micro-interactions : boutons (élévation légère, pression à 98 %), liens, onglets, lignes de tableau, champs. */
		button,
		a.bouton {
			transition: background-color var(--duree-rapide) var(--courbe), border-color var(--duree-rapide) var(--courbe),
				color var(--duree-rapide) var(--courbe), box-shadow var(--duree-rapide) var(--courbe), transform var(--duree-rapide) var(--courbe);
		}

		button:not(.lien, .lien-bouton, .nav, .tri, .segments button):hover:not(:disabled),
		a.bouton:hover {
			box-shadow: 0 1px 2px color-mix(in srgb, var(--texte) 14%, transparent);
		}

		button:not(.lien, .lien-bouton, .nav, .tri):active:not(:disabled),
		a.bouton:active {
			transform: scale(.98);
			box-shadow: none;
		}

		a {
			transition: color var(--duree-rapide) var(--courbe);
		}

		header nav a,
		header nav summary,
		header button.nav {
			transition: color var(--duree-rapide) var(--courbe), background-color var(--duree-rapide) var(--courbe),
				border-bottom-color var(--duree) var(--courbe);
		}

		table tbody tr {
			transition: background-color var(--duree-rapide) var(--courbe);
		}

		input:not([type=checkbox], [type=radio], [type=hidden]),
		select,
		textarea {
			transition: border-color var(--duree-rapide) var(--courbe), background-color var(--duree-rapide) var(--courbe);
		}

		/* 8. Graphiques : croissance des barres de répartition (rect.serie), étagée quand sibling-index() est disponible. */
		svg.barre rect.serie {
			transform-box: fill-box;
			transform-origin: left center;
			animation: mouvement-croit var(--duree-lente) var(--courbe-entree) both;
		}

		@supports (animation-delay: calc(sibling-index() * 1ms)) {
			svg.barre rect.serie {
				animation-delay: calc((sibling-index() - 1) * var(--decalage-liste));
			}
		}

		/* Chiffres clés : fondu échelonné. Sans sibling-index(), décalage fixe limité aux quatre premières cartes. */
		.grille > .chiffre {
			animation: mouvement-apparait var(--duree-lente) var(--courbe-entree) both;
		}

		@supports (animation-delay: calc(sibling-index() * 1ms)) {
			.grille > .chiffre {
				animation-delay: min(calc((sibling-index() - 1) * var(--decalage-liste)), 4 * var(--decalage-liste));
			}
		}

		@supports not (animation-delay: calc(sibling-index() * 1ms)) {
			.grille > .chiffre:nth-child(2) { animation-delay: var(--decalage-liste); }
			.grille > .chiffre:nth-child(3) { animation-delay: calc(2 * var(--decalage-liste)); }
			.grille > .chiffre:nth-child(4) { animation-delay: calc(3 * var(--decalage-liste)); }
		}

		/* 9. En-tête collant : filet d'ombre qui apparaît au défilement (scroll-timeline, CSS pur). */
		@supports (animation-timeline: scroll()) {
			header {
				animation: mouvement-entete linear both;
				animation-timeline: scroll(root block);
				animation-range: 0 3rem;
			}
		}
	}
}
