/**
 * Fichier : abs-slider.css
 * Emplacement : assets/css/abs-slider.css
 *
 * Styles front du module slider AB-Story Reader.
 *
 * Philosophie :
 *   Ce fichier fournit la structure, les comportements visuels (animations,
 *   transitions, positionnement) et les états accessibles (focus, aria).
 *   Il n'impose aucune couleur, aucune typographie, aucune taille de police
 *   opinionnée. Le thème AB-Story-Reader surcharge les variables CSS définies
 *   sur :root pour personnaliser l'apparence sans toucher ce fichier.
 *
 * Variables CSS exposées (surchargeables par le thème) :
 *
 *   Dimensions :
 *     --abs-slider-hauteur          Hauteur du slider (défaut : 420px)
 *     --abs-slider-hauteur-mobile   Hauteur sur mobile (défaut : 260px)
 *     --abs-slider-rayon            Rayon de bordure du conteneur (défaut : 0)
 *
 *   Z-index (couches internes) :
 *     --abs-slider-z-fond           Fond décoratif (défaut : 0)
 *     --abs-slider-z-overlay        Overlay couleur (défaut : 1)
 *     --abs-slider-z-contenu        Contenu du slide (défaut : 2)
 *     --abs-slider-z-nav            Éléments de navigation (défaut : 3)
 *     --abs-slider-z-pause          Bouton pause/play (défaut : 4)
 *
 *   Navigation : flèches :
 *     --abs-slider-btn-taille       Taille des boutons flèches (défaut : 44px)
 *     --abs-slider-btn-bg           Couleur de fond des flèches (défaut : rgba(0,0,0,0.4))
 *     --abs-slider-btn-couleur      Couleur du texte des flèches (défaut : #fff)
 *     --abs-slider-btn-bg-hover     Fond au survol (défaut : rgba(0,0,0,0.7))
 *
 *   Navigation : bullets :
 *     --abs-slider-bullet-taille    Taille d'un bullet (défaut : 10px)
 *     --abs-slider-bullet-bg        Couleur inactive (défaut : rgba(255,255,255,0.5))
 *     --abs-slider-bullet-bg-actif  Couleur active (défaut : #fff)
 *     --abs-slider-bullet-gap       Espacement entre bullets (défaut : 8px)
 *
 *   Barre de progression :
 *     --abs-slider-barre-hauteur    Hauteur de la barre (défaut : 3px)
 *     --abs-slider-barre-bg         Fond de la barre (défaut : rgba(255,255,255,0.3))
 *     --abs-slider-barre-remplissage Couleur du remplissage (défaut : #fff)
 *
 *   Badges éditoriaux :
 *     --abs-slider-badge-trailer-bg   Fond badge bande-annonce (défaut : #e67e22)
 *     --abs-slider-badge-bonus-bg     Fond badge bonus (défaut : #27ae60)
 *     --abs-slider-badge-explicit-bg  Fond badge explicite (défaut : #c0392b)
 *     --abs-slider-badge-couleur      Couleur texte badges (défaut : #fff)
 *
 *   Surcharge Ken Burns :
 *     --abs-slider-kenburns-duree     Durée de l'animation (défaut : identique autoplayVitesse)
 *     --abs-slider-kenburns-echelle   Échelle de zoom finale (défaut : 1.08)
 *
 * Surcharge de la présentation :
 *   Toutes les couleurs, dimensions et durées passent par des variables CSS
 *   déclarées sur :root. Une extension propre au site redéfinit celles qui
 *   l'intéressent, sans cibler les sélecteurs du slider :
 *
 *     :root {
 *         --abs-slider-btn-bg:        rgba(20, 20, 20, 0.8);
 *         --abs-slider-btn-couleur:   #ffffff;
 *         --abs-slider-focus-couleur: #7fb8ff;
 *         --abs-slider-hauteur:       520px;
 *     }
 *
 *   La feuille portant ces redéfinitions déclare en dépendance l'identifiant
 *   de celle-ci, ce qui la place après dans l'ordre d'impression :
 *
 *     wp_enqueue_style(
 *         'mon-habillage-slider',
 *         plugin_dir_url( __FILE__ ) . 'css/habillage.css',
 *         [ ABS_Slider_Assets::HANDLE_FRONT_CSS ],
 *         '1.0.0'
 *     );
 *
 *   Les assets du slider entrent dans la file au moment du rendu, plus tard
 *   que la plupart des feuilles d'un site : la dépendance porte donc l'ordre.
 *
 *   Les valeurs par défaut conviennent à un fond sombre, avec des commandes
 *   claires posées sur un voile foncé. Sur fond clair, les variables de
 *   commande, de pastille de pagination et de contour de focus demandent
 *   une redéfinition.
 *
 * Classes de la diapositive :
 *   Les gabarits posent les seules classes employées par cette feuille. La
 *   hauteur du slider est fixe et le débordement masqué : la diapositive
 *   s'en tient à ce qui tient dans le cadre.
 *
 *     abs-slide                      Diapositive.
 *     abs-slide--carrousel           Disposition compacte, couverture au-dessus.
 *     abs-slide__couverture--left    Couverture placée à gauche.
 *     abs-slide__couverture--right   Couverture placée à droite.
 *     abs-slide__couverture--haut    Couverture placée au-dessus.
 *
 * Accessibilité WCAG 2.1 AA :
 *   - Focus visible sur tous les éléments interactifs (outline explicite).
 *   - Contraste suffisant pour les états par défaut.
 *   - prefers-reduced-motion : toutes transitions et animations désactivées.
 *   - Cible tactile minimale 44x44px sur tous les boutons interactifs.
 */

/* ============================================================================
   Variables CSS
   ========================================================================= */

:root {
	/* Dimensions. */
	--abs-slider-hauteur:         420px;
	--abs-slider-hauteur-mobile:  260px;
	--abs-slider-rayon:           0px;

	/* Z-index internes. */
	--abs-slider-z-fond:    0;
	--abs-slider-z-overlay: 1;
	--abs-slider-z-contenu: 2;
	--abs-slider-z-nav:     3;
	--abs-slider-z-pause:   4;

	/* Flèches. */
	--abs-slider-btn-taille:   44px;
	--abs-slider-btn-bg:       rgba(0, 0, 0, 0.4);
	--abs-slider-btn-couleur:  #fff;
	--abs-slider-btn-bg-hover: rgba(0, 0, 0, 0.7);

	/* Bullets. */
	--abs-slider-bullet-taille:   10px;
	--abs-slider-bullet-bg:       rgba(255, 255, 255, 0.5);
	--abs-slider-bullet-bg-actif: #fff;
	--abs-slider-bullet-gap:      8px;

	/* Barre de progression. */
	--abs-slider-barre-hauteur:      3px;
	--abs-slider-barre-bg:           rgba(255, 255, 255, 0.3);
	--abs-slider-barre-remplissage:  #fff;

	/* Ken Burns. */
	--abs-slider-kenburns-duree:   5000ms;
	--abs-slider-kenburns-echelle: 1.08;

	/* Contour de focus. */
	--abs-slider-focus-couleur:    #ffffff;
	--abs-slider-focus-epaisseur:  3px;

	/* Miniatures de navigation. */
	--abs-slider-thumbnails-bg:      rgba(0, 0, 0, 0.5);
	--abs-slider-thumbnail-bg:       rgba(255, 255, 255, 0.1);
	--abs-slider-thumbnail-bordure:  transparent;
	--abs-slider-thumbnail-bordure-active: #ffffff;

	/* Bordure des commandes rondes. */
	--abs-slider-nav-bordure:      rgba(255, 255, 255, 0.7);

	/* Ombres portées, posées par les gabarits sur demande. */
	--abs-slider-couv-ombre:  3px 3px 10px rgba(0, 0, 0, 0.4);
	--abs-slider-texte-ombre: 1px 1px 4px rgba(0, 0, 0, 0.5);
}

/* ============================================================================
   Conteneur principal
   ========================================================================= */

.abs-slider {
	position:      relative;
	width:         100%;
	height:        var(--abs-slider-hauteur);
	overflow:      hidden;
	border-radius: var(--abs-slider-rayon);
	/* Contexte d'empilement isolé pour les z-index internes. */
	isolation:     isolate;
}

/* ============================================================================
   Liste des slides : mode "slide" (défaut)
   ========================================================================= */

.abs-slider__slides {
	display:         flex;
	flex-direction:  row;
	flex-wrap:       nowrap;
	height:          100%;
	margin:          0;
	padding:         0;
	list-style:      none;
	/* La transition est gérée par JS via style.transition inline. */
	will-change:     transform;
}

/* ============================================================================
   Slide individuel
   ========================================================================= */

.abs-slide {
	position:   relative;
	flex:       0 0 auto;
	/* La largeur est définie par JS selon slidesVisibles :
	   width: calc(100% / N) où N = slidesVisibles courant.
	   Valeur par défaut : 1 slide visible. */
	width:      100%;
	height:     100%;
	overflow:   hidden;
}

/* ============================================================================
   Mode d'animation par glissement

   La liste des slides se déplace par translation, les slides restant dans le
   flux, côte à côte. Ce mode ne demande aucune règle supplémentaire : la
   disposition de la liste et des slides suffit à le produire. La classe est
   posée par le script et sert de point d'accroche au thème.
   ========================================================================= */

.abs-slider--slide .abs-slider__slides {
	flex-direction: row;
}

/* ============================================================================
   Région d'annonce destinée aux lecteurs d'écran

   La région est masquée visuellement tout en restant lue par les technologies
   d'assistance. Le script pose ces mêmes propriétés en ligne, ce qui maintient
   le masquage même en l'absence de cette feuille.
   ========================================================================= */

.abs-slider__aria-live {
	position:    absolute;
	width:       1px;
	height:      1px;
	margin:      -1px;
	padding:     0;
	overflow:    hidden;
	clip:        rect(0, 0, 0, 0);
	clip-path:   inset(50%);
	white-space: nowrap;
	border:      0;
}

/* ============================================================================
   Modes d'animation par superposition
   Les slides passent en position absolue pour le fondu enchaîné.
   ========================================================================= */

.abs-slider--fade .abs-slide,
.abs-slider--kenburns .abs-slide {
	position: absolute;
	inset:    0;
	width:    100%;
	opacity:  0;
}

.abs-slider--fade .abs-slide:first-child,
.abs-slider--kenburns .abs-slide:first-child {
	opacity: 1;
}

/* En mode fade/kenburns, la liste n'a pas de translation. */
.abs-slider--fade .abs-slider__slides,
.abs-slider--kenburns .abs-slider__slides {
	transform: none !important;
}

/* ============================================================================
   Fond décoratif : image ou couleur
   ========================================================================= */

.abs-slide__fond-wrap {
	position: absolute;
	inset:    0;
	z-index:  var(--abs-slider-z-fond);
	/* overflow:hidden masque le débordement du fond flouté. */
	overflow: hidden;
}

.abs-slide__fond {
	position: absolute;
	inset:    0;
	overflow: hidden;
}

/* Couleur de fond, employée en l'absence d'image. Le gabarit la pose en
   ligne, la teinte étant choisie contenu par contenu. */
.abs-slide__fond-couleur {
	position: absolute;
	inset:    0;
}

/* Image de fond. Le navigateur retient la source adaptée à la largeur de
   son affichage parmi celles annoncées par l'attribut srcset. */
.abs-slide__fond-img {
	position:        absolute;
	inset:           0;
	width:           100%;
	height:          100%;
	object-fit:      cover;
	object-position: center center;
}

/* Le flou déborde du cadre de l'image et laisse paraître un bord clair. Une
   légère mise à l'échelle repousse ce bord hors du conteneur, que son
   débordement masqué découpe. Le gabarit pose les deux valeurs, calculées
   d'après l'intensité demandée. */
.abs-slide__fond-img--flou {
	filter:    blur(var(--abs-slide-flou, 0));
	transform: scale(var(--abs-slide-flou-echelle, 1));
}

.abs-slide__overlay {
	position: absolute;
	inset:    0;
	z-index:  var(--abs-slider-z-overlay);
}

/* ============================================================================
   Animation Ken Burns : zoom lent sur l'image de fond
   ========================================================================= */

/* Le zoom lent part de l'échelle en vigueur et l'amplifie. Un fond flouté
   porte déjà une échelle qui repousse son bord hors du cadre : l'animation
   la reprend comme point de départ, ce qui laisse les deux effets se
   combiner. */
@keyframes abs-kenburns {
	from {
		transform: scale(var(--abs-slide-flou-echelle, 1));
		transform-origin: center center;
	}
	to {
		transform: scale(calc(var(--abs-slide-flou-echelle, 1) * var(--abs-slider-kenburns-echelle)));
		transform-origin: 60% 40%;
	}
}

.abs-slide__fond-img--kenburns {
	animation-name:            abs-kenburns;
	animation-duration:        var(--abs-slider-kenburns-duree);
	animation-timing-function: ease-in-out;
	animation-fill-mode:       forwards;
	animation-iteration-count: 1;
}

/* ============================================================================
   Contenu interne du slide
   ========================================================================= */

.abs-slide__inner {
	position:        relative;
	z-index:         var(--abs-slider-z-contenu);
	display:         flex;
	flex-direction:  row;
	align-items:     center;
	height:          100%;
	/* Padding interne : le thème peut surcharger. */
	padding:         1.5rem;
	gap:             1.5rem;
	box-sizing:      border-box;
}

/* ---- Couverture (image à la une). ---- */

.abs-slide__couverture {
	flex:       0 0 auto;
	display:    flex;
	align-items: center;
}

.abs-slide__couverture--left {
	order: 0;
}

.abs-slide__couverture--right {
	order: 2;
}

.abs-slide__couverture-btn {
	display:    block;
	padding:    0;
	margin:     0;
	border:     0;
	background: transparent;
	cursor:     pointer;
	/* La taille est contrainte par le thème. */
}

.abs-slide__couverture-btn:focus-visible {
	outline:        3px solid currentColor;
	outline-offset: 3px;
}

.abs-slide__couverture-img {
	display:    block;
	max-height: calc(var(--abs-slider-hauteur) - 3rem);
	width:      auto;
	object-fit: contain;
}

/* Ombre portée de la couverture, demandée contenu par contenu depuis la
   metabox. La valeur passe par une variable, ce qui laisse une extension la
   redéfinir. */
.abs-slide__couverture-img--ombre {
	box-shadow: var(--abs-slider-couv-ombre);
}

/* ---- Contenu textuel. ---- */

.abs-slide__contenu {
	flex:     1 1 auto;
	order:    1;
	display:  flex;
	flex-direction: column;
	gap:      0.5rem;
	/* Empêche le texte de déborder sur la couverture. */
	min-width: 0;
}

/* ============================================================================
   Éléments de contenu des slides
   ========================================================================= */

/* Titre. */
.abs-slide__titre {
	margin:      0;
	/* La taille de police est définie par le thème. */
	line-height: 1.2;
}

.abs-slide__titre-btn {
	display:    inline;
	padding:    0;
	margin:     0;
	border:     0;
	background: transparent;
	color:      inherit;
	font:       inherit;
	text-align: inherit;
	cursor:     pointer;
	/* Cible tactile minimale. */
	min-height: 44px;
}

.abs-slide__titre-btn:focus-visible {
	outline:        3px solid currentColor;
	outline-offset: 2px;
	border-radius:  2px;
}

/* Texte d'accroche. */
.abs-slide__accroche {
	margin: 0;
}

.abs-slide__accroche--bold {
	font-weight: 700;
}

.abs-slide__accroche--italic {
	font-style: italic;
}

.abs-slide__accroche--bold-italic {
	font-weight: 700;
	font-style:  italic;
}

.abs-slide__accroche--left   { text-align: left; }
.abs-slide__accroche--center { text-align: center; }
.abs-slide__accroche--right  { text-align: right; }

/* Ombre portée du texte d'accroche, demandée contenu par contenu depuis la
   metabox. La valeur passe par une variable, ce qui laisse une extension la
   redéfinir. */
.abs-slide__accroche--ombre {
	text-shadow: var(--abs-slider-texte-ombre);
}

/* Bouton CTA. */
.abs-slide__cta {
	align-self:      flex-start;
	display:         inline-flex;
	align-items:     center;
	padding:         0.5em 1.25em;
	border:          2px solid currentColor;
	border-radius:   2em;
	background:      transparent;
	color:           inherit;
	font:            inherit;
	font-weight:     600;
	cursor:          pointer;
	text-decoration: none;
	transition:      background-color 0.2s ease, color 0.2s ease;
	/* Cible tactile minimale. */
	min-height:      44px;
}

.abs-slide__cta:hover,
.abs-slide__cta:focus-visible {
	background-color: currentColor;
}

.abs-slide__cta:focus-visible {
	outline:        3px solid currentColor;
	outline-offset: 3px;
}

/* ============================================================================
   Template carrousel : disposition spécifique
   ========================================================================= */

.abs-slide--carrousel .abs-slide__inner {
	flex-direction: column;
	align-items:    stretch;
	padding:        1rem;
	gap:            0.75rem;
}

.abs-slide--carrousel .abs-slide__couverture,
.abs-slide__couverture--haut {
	order: 0;
	width: 100%;
}

.abs-slide--carrousel .abs-slide__couverture-btn {
	width:  100%;
	aspect-ratio: 3 / 4;
	overflow: hidden;
}

.abs-slide--carrousel .abs-slide__couverture-img {
	width:      100%;
	height:     100%;
	max-height: none;
	object-fit: cover;
}

.abs-slide--carrousel .abs-slide__contenu {
	order: 1;
}

/* ============================================================================
   Flèches de navigation
   ========================================================================= */

.abs-slider__btn {
	position:    absolute;
	top:         50%;
	transform:   translateY(-50%);
	z-index:     var(--abs-slider-z-nav);
	display:     flex;
	align-items: center;
	justify-content: center;
	width:       var(--abs-slider-btn-taille);
	height:      var(--abs-slider-btn-taille);
	padding:     0;
	border:      0;
	border-radius: 50%;
	background:  var(--abs-slider-btn-bg);
	color:       var(--abs-slider-btn-couleur);
	font-size:   1.5rem;
	cursor:      pointer;
	transition:  background-color 0.2s ease;
	/* Dépasse légèrement du conteneur pour la lisibilité : clippé par overflow. */
}

.abs-slider__btn--precedent {
	left: 0.75rem;
}

.abs-slider__btn--suivant {
	right: 0.75rem;
}

.abs-slider__btn:hover {
	background-color: var(--abs-slider-btn-bg-hover);
}

.abs-slider__btn:focus-visible {
	outline:        var(--abs-slider-focus-epaisseur) solid var(--abs-slider-focus-couleur);
	outline-offset: 2px;
}

/* ============================================================================
   Bullets de pagination
   ========================================================================= */

.abs-slider__bullets {
	position:   absolute;
	bottom:     1rem;
	left:       0;
	right:      0;
	z-index:    var(--abs-slider-z-nav);
	text-align: center;
}

.abs-slider__bullets-liste {
	display:         inline-flex;
	flex-wrap:       wrap;
	justify-content: center;
	gap:             var(--abs-slider-bullet-gap);
	margin:          0;
	padding:         0;
	list-style:      none;
}

.abs-slider__bullet {
	display:       block;
	width:         var(--abs-slider-bullet-taille);
	height:        var(--abs-slider-bullet-taille);
	padding:       0;
	border:        2px solid var(--abs-slider-nav-bordure);
	border-radius: 50%;
	background:    var(--abs-slider-bullet-bg);
	cursor:        pointer;
	transition:    background-color 0.2s ease, transform 0.2s ease;
	/* Cible tactile étendue via padding invisible. */
	position:      relative;
}

.abs-slider__bullet::after {
	content:  '';
	position: absolute;
	inset:    -8px;
}

.abs-slider__bullet--actif,
.abs-slider__bullet[aria-current="true"] {
	background-color: var(--abs-slider-bullet-bg-actif);
	transform:        scale(1.3);
}

.abs-slider__bullet:hover {
	background-color: var(--abs-slider-bullet-bg-actif);
}

.abs-slider__bullet:focus-visible {
	outline:        var(--abs-slider-focus-epaisseur) solid var(--abs-slider-focus-couleur);
	outline-offset: 2px;
}

/* ============================================================================
   Thumbnails de navigation
   ========================================================================= */

.abs-slider__thumbnails {
	position:   absolute;
	bottom:     0;
	left:       0;
	right:      0;
	z-index:    var(--abs-slider-z-nav);
	background: var(--abs-slider-thumbnails-bg);
	overflow:   hidden;
}

.abs-slider__thumbnails-liste {
	display:          flex;
	flex-direction:   row;
	overflow-x:       auto;
	overflow-y:       hidden;
	scroll-snap-type: x mandatory;
	gap:              4px;
	margin:           0;
	padding:          4px;
	list-style:       none;
	/* Masque la scrollbar sur Webkit. */
	-webkit-overflow-scrolling: touch;
	scrollbar-width:  thin;
}

.abs-slider__thumbnail {
	flex:          0 0 auto;
	scroll-snap-align: start;
	display:       block;
	width:         60px;
	height:        60px;
	padding:       0;
	border:        2px solid var(--abs-slider-thumbnail-bordure);
	border-radius: 4px;
	overflow:      hidden;
	background:    var(--abs-slider-thumbnail-bg);
	cursor:        pointer;
	transition:    border-color 0.2s ease;
}

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

.abs-slider__thumbnail:hover,
.abs-slider__thumbnail:focus-visible {
	border-color: var(--abs-slider-thumbnail-bordure-active);
}

.abs-slider__thumbnail:focus-visible {
	outline:        var(--abs-slider-focus-epaisseur) solid var(--abs-slider-focus-couleur);
	outline-offset: 2px;
}

/* ============================================================================
   Barre de progression
   ========================================================================= */

.abs-slider__barre-progression {
	position:   absolute;
	bottom:     0;
	left:       0;
	right:      0;
	z-index:    var(--abs-slider-z-nav);
	height:     var(--abs-slider-barre-hauteur);
	background: var(--abs-slider-barre-bg);
}

.abs-slider__barre-remplissage {
	height:     100%;
	width:      0%;
	background: var(--abs-slider-barre-remplissage);
	/* La transition est injectée dynamiquement par JS. */
}

/* ============================================================================
   Bouton pause/play (WCAG 2.2.2)
   ========================================================================= */

.abs-slider__btn-pause-play {
	position:        absolute;
	top:             0.75rem;
	right:           0.75rem;
	z-index:         var(--abs-slider-z-pause);
	display:         flex;
	align-items:     center;
	justify-content: center;
	width:           var(--abs-slider-btn-taille);
	height:          var(--abs-slider-btn-taille);
	padding:         0;
	border:          2px solid var(--abs-slider-nav-bordure);
	border-radius:   50%;
	background:      var(--abs-slider-btn-bg);
	color:           var(--abs-slider-btn-couleur);
	font-size:       1rem;
	cursor:          pointer;
	transition:      background-color 0.2s ease;
}

.abs-slider__btn-pause-play:hover {
	background-color: var(--abs-slider-btn-bg-hover);
}

.abs-slider__btn-pause-play:focus-visible {
	outline:        var(--abs-slider-focus-epaisseur) solid var(--abs-slider-focus-couleur);
	outline-offset: 2px;
}

/* ============================================================================
   Responsive : mobile
   ========================================================================= */

@media (max-width: 767px) {
	.abs-slider {
		height: var(--abs-slider-hauteur-mobile);
	}

	.abs-slide__inner {
		padding: 1rem;
		gap:     1rem;
	}

	/* Masquer les thumbnails sur mobile : trop petits pour être utiles. */
	.abs-slider__thumbnails {
		display: none;
	}

	/* Flèches plus proches des bords sur mobile. */
	.abs-slider__btn--precedent { left:  0.375rem; }
	.abs-slider__btn--suivant   { right: 0.375rem; }

	/* Couverture plus petite sur mobile. */
	.abs-slide__couverture-img {
		max-height: calc(var(--abs-slider-hauteur-mobile) - 2rem);
	}
}

/* ============================================================================
   prefers-reduced-motion : désactivation complète des animations
   ========================================================================= */

@media (prefers-reduced-motion: reduce) {

	.abs-slider__slides {
		transition: none !important;
	}

	.abs-slide {
		transition: none !important;
		animation:  none !important;
	}

	.abs-slide__fond {
		animation: none !important;
	}

	.abs-slide__fond-img--kenburns {
		animation: none !important;
	}

	.abs-slider__btn,
	.abs-slider__bullet,
	.abs-slider__thumbnail,
	.abs-slider__btn-pause-play,
	.abs-slide__cta {
		transition: none !important;
	}

	.abs-slider__barre-remplissage {
		transition: none !important;
	}
}
