/**
 * Visiora Core — Composant : Spinner
 *
 * Indicateur de chargement SVG utilisable seul
 * ou à l’intérieur d’un overlay local ou plein écran.
 *
 * Dépendances :
 * - colors.css
 * - spacing.css
 * - containers.css
 * - animation.css
 * - opacity.css
 * - z-index.css
 *
 * @package Visiora_Core
 */

/* ======================================================
   1. SPINNER — BASE
   ====================================================== */

.v-spinner {
	display: inline-flex;
	flex: 0 0 auto;
	align-items: center;
	justify-content: center;
	inline-size: var(--v-size-spinner-md);
	block-size: var(--v-size-spinner-md);
	max-inline-size: 100%;
	color: currentColor;
	line-height: var(--v-line-height-none);
	vertical-align: middle;
}

/* ======================================================
   2. SVG
   ====================================================== */

.v-spinner__svg {
	display: block;
	inline-size: 100%;
	block-size: 100%;
	overflow: visible;
	fill: none;
	transform-origin: center;
	animation:
		v-spinner-rotate
		var(--v-duration-slower)
		var(--v-easing-linear)
		infinite;
}

.v-spinner__track,
.v-spinner__indicator {
	fill: none;
	stroke: currentColor;
	stroke-width: var(--v-size-spinner-stroke-width);
	stroke-linecap: round;
}

/*
 * L’épaisseur du tracé reste proportionnelle aux dimensions
 * du SVG.
 *
 * Ne pas utiliser :
 *
 * vector-effect: non-scaling-stroke;
 *
 * Cette propriété empêcherait l’épaisseur visuelle de suivre
 * correctement les tailles xs, sm, md, lg et xl.
 */

.v-spinner__track {
	opacity: var(--v-opacity-20);
}

.v-spinner__indicator {
	/*
	 * Le SVG utilise pathLength="100".
	 *
	 * L’indicateur occupe 75 % de la circonférence et laisse
	 * un espace structurel de 25 %.
	 *
	 * Ces valeurs appartiennent à la géométrie du Spinner
	 * et ne nécessitent pas de Design Token supplémentaire.
	 */
	stroke-dasharray: 75 25;
}

/* ======================================================
   3. TAILLES
   ====================================================== */

.v-spinner--xs {
	inline-size: var(--v-size-spinner-xs);
	block-size: var(--v-size-spinner-xs);
}

.v-spinner--sm {
	inline-size: var(--v-size-spinner-sm);
	block-size: var(--v-size-spinner-sm);
}

.v-spinner--md {
	inline-size: var(--v-size-spinner-md);
	block-size: var(--v-size-spinner-md);
}

.v-spinner--lg {
	inline-size: var(--v-size-spinner-lg);
	block-size: var(--v-size-spinner-lg);
}

.v-spinner--xl {
	inline-size: var(--v-size-spinner-xl);
	block-size: var(--v-size-spinner-xl);
}

/* ======================================================
   4. ÉTATS DU SPINNER
   ====================================================== */

.v-spinner.is-muted {
	opacity: var(--v-opacity-muted);
}

.v-spinner.is-hidden,
.v-spinner[hidden] {
	display: none;
}

/* ======================================================
   5. SURFACE DE POSITIONNEMENT
   ====================================================== */

/*
 * À appliquer au conteneur devant recevoir un overlay local.
 *
 * Exemple :
 *
 * <section
 *     class="v-spinner-surface"
 *     aria-busy="true"
 * >
 *     ...
 * </section>
 */

.v-spinner-surface {
	position: relative;
	min-inline-size: 0;
}

.v-spinner-surface[aria-busy="true"] {
	cursor: progress;
}

/* ======================================================
   6. OVERLAY LOCAL
   ====================================================== */

/*
 * L’overlay local reste dans le niveau d’élévation du
 * composant qui le contient.
 *
 * Il ne doit pas passer au-dessus des couches globales comme :
 *
 * - l’overlay de page ;
 * - les dialogs ;
 * - les popovers ;
 * - les tooltips ;
 * - les notifications.
 */

.v-spinner-overlay {
	position: absolute;
	z-index: var(--v-z-card-raised);
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	min-inline-size: 0;
	padding: var(--v-space-component-md);
	overflow: hidden;
	background-color: var(--v-color-overlay);
	color: var(--v-color-text-inverse);
	cursor: progress;
}

/*
 * L’overlay intercepte les interactions avec la région
 * temporairement indisponible.
 *
 * Il doit être retiré du DOM ou masqué dès la fin réelle
 * du chargement.
 */

/* ======================================================
   7. OVERLAY PLEIN ÉCRAN
   ====================================================== */

/*
 * Seul l’overlay fixe utilise le niveau global Page Overlay.
 *
 * La propriété inset: 0 est héritée de .v-spinner-overlay
 * et couvre donc l’intégralité du viewport.
 */

.v-spinner-overlay--fixed {
	position: fixed;
	z-index: var(--v-z-page-overlay);
}

/* ======================================================
   8. CONTENU DE L’OVERLAY
   ====================================================== */

.v-spinner-overlay__content {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: var(--v-space-component-sm);
	min-inline-size: 0;
	max-inline-size: 100%;
	color: inherit;
	text-align: center;
}

.v-spinner-overlay__label {
	margin: 0;
	overflow-wrap: anywhere;
	color: inherit;
	font: inherit;
}

/* ======================================================
   9. ÉTATS DE L’OVERLAY
   ====================================================== */

.v-spinner-overlay.is-hidden,
.v-spinner-overlay[hidden] {
	display: none;
}

/* ======================================================
   10. ACCESSIBILITÉ
   ====================================================== */

/*
 * Spinner autonome :
 *
 * <span
 *     class="v-spinner"
 *     role="status"
 *     aria-label="Chargement"
 * >
 *     <svg
 *         class="v-spinner__svg"
 *         aria-hidden="true"
 *         focusable="false"
 *     >
 *         ...
 *     </svg>
 * </span>
 *
 * La région réellement concernée porte :
 *
 * aria-busy="true"
 *
 * role="status" crée implicitement une région live polie.
 *
 * Si un texte visible décrit déjà le chargement, éviter
 * d’ajouter une seconde annonce redondante.
 *
 * Le SVG interne reste toujours décoratif.
 */

/* ======================================================
   11. FORCED COLORS
   ====================================================== */

@media (forced-colors: active) {
	.v-spinner {
		color: CanvasText;
		forced-color-adjust: auto;
	}

	.v-spinner-overlay {
		background-color: Canvas;
		border:
			var(--v-size-border-thin)
			solid
			CanvasText;
		color: CanvasText;
		forced-color-adjust: auto;
	}
}

/* ======================================================
   12. REDUCED MOTION
   ====================================================== */

@media (prefers-reduced-motion: reduce) {
	.v-spinner__svg {
		animation: none;
	}
}

/* ======================================================
   13. COMPATIBILITÉ WORDPRESS
   ====================================================== */

.v-root .v-spinner,
.v-root .v-spinner-surface,
.v-root .v-spinner-overlay,
.editor-styles-wrapper .v-spinner,
.editor-styles-wrapper .v-spinner-surface,
.editor-styles-wrapper .v-spinner-overlay {
	box-sizing: border-box;
}

.v-root .v-spinner *,
.v-root .v-spinner *::before,
.v-root .v-spinner *::after,
.v-root .v-spinner-overlay *,
.v-root .v-spinner-overlay *::before,
.v-root .v-spinner-overlay *::after,
.editor-styles-wrapper .v-spinner *,
.editor-styles-wrapper .v-spinner *::before,
.editor-styles-wrapper .v-spinner *::after,
.editor-styles-wrapper .v-spinner-overlay *,
.editor-styles-wrapper .v-spinner-overlay *::before,
.editor-styles-wrapper .v-spinner-overlay *::after {
	box-sizing: border-box;
}

/* ======================================================
   14. COMPATIBILITÉ GUTENBERG
   ====================================================== */

.wp-block .v-spinner {
	flex-shrink: 0;
}

.wp-block .v-spinner-surface,
.wp-block .v-spinner-overlay {
	max-inline-size: 100%;
}

/* ======================================================
   15. COMPATIBILITÉ SPECTRA
   ====================================================== */

.uagb-container__content .v-spinner,
.uagb-infobox .v-spinner,
.uagb-buttons__outer-wrap .v-spinner {
	flex-shrink: 0;
}

.uagb-container__content .v-spinner-surface,
.uagb-container__content .v-spinner-overlay,
.uagb-infobox .v-spinner-surface,
.uagb-infobox .v-spinner-overlay {
	max-inline-size: 100%;
}

/* ======================================================
   16. ANIMATION
   ====================================================== */

@keyframes v-spinner-rotate {
	to {
		transform: rotate(1turn);
	}
}

/*
 * rotate(1turn) constitue une constante structurelle
 * exprimant une rotation complète.
 *
 * Elle ne dépend pas du thème et ne nécessite pas
 * de Design Token supplémentaire.
 */

/* ======================================================
   17. PERFORMANCE ET SÉCURITÉ
   ====================================================== */

/*
 * - Une seule animation basée sur transform.
 * - Aucun JavaScript requis pour la présentation.
 * - Aucun gestionnaire d’événement inline.
 * - Aucun SVG fourni par l’utilisateur.
 * - Aucune dépendance externe.
 * - Compatible CSP.
 * - DOM minimal.
 * - Compatible RTL.
 * - Propriétés dimensionnelles logiques.
 * - Overlay local limité à --v-z-card-raised.
 * - Overlay fixe limité à --v-z-page-overlay.
 * - Aucun contexte d’empilement supplémentaire inutile.
 * - Aucune propriété isolation inutile.
 * - Bordure Forced Colors utilisant un token officiel.
 */