/*
 * Immopro974 — Carrousel vitrines promoteurs
 * Handle : immopro-carrousel (enquêté par CarrouselShortcode::enqueueAssets)
 * Dépend de splide.min.css (déclaré en tant que dépendance WP).
 *
 * Tokens --ipro-* (palette « Basalte & Vétiver » v3.0).
 * Chaque var() comporte un fallback hex pour survivre sans le thème enfant
 * (finding D9 — le plugin ne peut pas supposer que le thème est chargé).
 *
 * WCAG 2.1 AA :
 *   - Contraste scrim ≥ 4,5:1 (texte blanc sur dégradé sombre) — §1.4.3
 *   - Focus visible : outline Vétiver-600 + halo blanc — §2.4.7
 *   - Cibles tactiles ≥ 44×44 px — §2.5.5
 *   - prefers-reduced-motion : transitions et animations gelées — §2.3.3
 *
 * Markup émis par CarrouselShortcode::renderMarkup() :
 *   section.ipro-carrousel
 *     button.ipro-carrousel__pause  (premier focusable — WCAG 2.4.3)
 *     div.splide
 *       div.splide__track
 *         ul.splide__list
 *           li.splide__slide × N
 *             div.ipro-carrousel__photos
 *               img × N
 *             div.ipro-carrousel__accroches[data-accroches]
 *               p.ipro-carrousel__accroche × N
 *             a.ipro-carrousel__cta  (optionnel — absent si aucun CTA)
 *
 * Note : les flèches et la pagination Splide (.splide__arrow, .splide__pagination__page)
 * sont injectées par le JS d'init ; les règles focus les couvrent ici par anticipation.
 */

/* =============================================================================
   1. CONTENEUR RACINE
   ============================================================================= */

.ipro-carrousel {
  position: relative;
  /* Fond basalte = garantit un rendu pendant le chargement des photos. */
  background: var(--ipro-ink-900, #20231F);
  overflow: hidden;
  /* Anti-CLS : espace réservé si l'aspect-ratio n'est pas encore résolu.
     ⚠️ DOIT valoir EXACTEMENT le `min-height` de `.ipro-carrousel .splide` (§3, plus
     bas). Les deux planchers ont été posés à des moments différents — 200 ici pour la
     réserve anti-CLS, 180 là-bas en repli d'`aspect-ratio` — et ne se sont jamais
     accordés : sous ~540 px de large, où les deux planchers l'emportent sur le ratio,
     le parent dépassait son contenu de 20 px et laissait voir une bande de fond
     basalte sous la photo (D104, mesuré à 375 px). Un conteneur ne doit jamais
     réserver plus de hauteur que ce que son contenu occupera. */
  min-height: 180px;
}

/* =============================================================================
   2. BOUTON PAUSE / PLAY
   Premier élément focusable (WCAG 2.4.3 / APG Carousel Pattern).
   ============================================================================= */

.ipro-carrousel__pause {
  position: absolute;
  top: var(--ipro-space-2, 8px);
  /* Aligné sur la GOUTTIÈRE DE CONTENU (--ipro-pad-x), pas sur une valeur en dur :
     le carrousel court bord à bord, mais le bouton de connexion de l'en-tête (44×44,
     juste au-dessus) est calé sur cette gouttière. Une valeur libre les décalait de
     20 px (32 contre 12) — visible à l'œil, les deux boutons étant l'un sous l'autre.
     Les deux faisant 44 px de large, un bord droit commun suffit à aligner les axes.
     Le token suit les paliers tout seul (16 / 24 / 32) : ne PAS le réécrire dans les
     media queries, sinon l'alignement se rompt au prochain changement de gouttière. */
  right: var(--ipro-pad-x, 16px);
  z-index: 20;
  /* Cible tactile ≥ 44×44 px (WCAG 2.5.5). */
  min-width: 44px;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  /* ATTÉNUÉ le 18/07 (demande porteur : « rends-le plus discret »).
     La pastille pleine — fond blanc 15 %, bordure 30 % — a disparu AU REPOS : ne reste
     que le glyphe, blanc plein. Elle revient au survol et au focus (voir plus bas).

     Ce qu'on ne fait PAS, et pourquoi :
     · pas d'`opacity` sur le glyphe — elle dégraderait le contraste sans qu'aucun token
       ne le montre (à 80 % sur fond clair, un gris passe déjà sous AA). L'atténuation
       est obtenue en retirant de la MATIÈRE, pas en rendant le reste translucide ;
     · pas d'affichage au survol seulement — un bouton qui n'apparaît qu'au `:hover`
       n'existe pas sur écran tactile, et WCAG 2.2.2 (niveau A) exige que le mécanisme
       de pause soit disponible, pas découvrable. Le glyphe reste donc visible en
       permanence, sur toutes les surfaces ;
     · la cible tactile reste 44 × 44 (ci-dessus) alors que le dessin visible fait
       ~13 px : la zone cliquable ne rétrécit pas avec l'apparence (WCAG 2.5.5).

     L'ombre portée remplace la pastille comme garantie de lisibilité : le carrousel
     défile sur des photos quelconques, et un glyphe blanc sans fond peut tomber sur
     une zone claire. `drop-shadow` suit le tracé du glyphe, là où `box-shadow` ne
     dessinerait que le carré du bouton. */
  background: transparent;
  border: 1.5px solid transparent;
  border-radius: 50%;
  color: #ffffff;
  /* DEUX ombres, pas une : la première est un liseré serré (rayon 1 px) qui cerne le
     glyphe et lui garantit une limite sombre même posé sur une façade claire — cas
     constaté à l'écran, le carrousel montrant des bâtiments en béton clair. La seconde
     est une ombre portée douce qui le décolle du fond. Sans le liseré, le blanc sur
     béton clair ne tenait pas les 3:1 attendus d'un composant d'interface (WCAG 1.4.11). */
  filter: drop-shadow(0 0 1px rgba(0, 0, 0, 0.9)) drop-shadow(0 1px 3px rgba(0, 0, 0, 0.6));
  font-size: 0.8rem;
  line-height: 1;
  cursor: pointer;
  transition:
    background var(--ipro-transition-fast, 150ms) var(--ipro-easing-standard, cubic-bezier(0.2, 0, 0, 1)),
    border-color var(--ipro-transition-fast, 150ms) var(--ipro-easing-standard, cubic-bezier(0.2, 0, 0, 1));
}

/* La pastille revient dès qu'on s'adresse au bouton — souris OU clavier. Le
   `:focus-visible` est ici ET dans la règle d'outline ci-dessous, à dessein : l'outline
   signale le focus, ce fond-là rend au bouton sa surface, pour que l'utilisateur au
   clavier voie le même objet que l'utilisateur à la souris. */
.ipro-carrousel__pause:hover,
.ipro-carrousel__pause:focus-visible {
  background: var(--ipro-on-dark-fill-200, rgba(255, 255, 255, 0.30));
  border-color: var(--ipro-on-dark-fill-200, rgba(255, 255, 255, 0.30));
}

/*
 * Focus : outline Vétiver-600 + halo blanc.
 * Pattern calqué sur components.css:466-467 (overlay photo).
 * Le box-shadow blanc garantit ≥ 3:1 quel que soit le fond photographique.
 */
.ipro-carrousel__pause:focus-visible {
  outline: 2px solid var(--ipro-vetiver-600, #2E5243);
  outline-offset: 3px;
  box-shadow: 0 0 0 5px #ffffff;
}

/* =============================================================================
   3. STRUCTURE SPLIDE (surcharge minimale)
   Splide gère le carrousel ; on fixe l'aspect-ratio et les hauteurs.
   ============================================================================= */

/* Ratio 16:9 anti-CLS (finding D9 brief Task 5.4). */
.ipro-carrousel .splide {
  /* Lot 4 : bandeau accueil aplati (16:9 → 3:1) pour réduire la hauteur. */
  aspect-ratio: 3 / 1;
  /* Fallback navigateurs sans support aspect-ratio (Safari ≤ 14).
     ⚠️ Toute modification de cette valeur doit être reportée sur le `min-height` de
     `.ipro-carrousel` (§1) : c'est leur désaccord qui a produit D104. */
  min-height: 180px;
}

.ipro-carrousel .splide__track {
  height: 100%;
}

.ipro-carrousel .splide__list {
  height: 100%;
}

.ipro-carrousel .splide__slide {
  position: relative;
  overflow: hidden;
  height: 100%;
}

/* --- Focus des flèches et de la pagination Splide (D3, 2026-08-02) — injectées par JS.
 *
 * DEUX règles de `splide.min.css` doivent être battues, et elles ne se battent pas
 * de la même façon. Mesuré au clavier le 02/08, pas déduit :
 *
 * 1. `.splide.is-focus-in .splide__arrow:focus` (0,4,0) pose `outline: 3px solid #0bf`.
 *    Splide ajoute `is-focus-in` sur le conteneur dès que le focus vient du CLAVIER —
 *    donc ce sélecteur gagne précisément dans le cas qui nous intéresse, et le repère
 *    ressortait en CYAN au lieu du vétiver. Le seul `:focus-visible` ne suffit pas :
 *    `.ipro-carrousel .splide__arrow:focus-visible` ne pèse que (0,3,0). D'où le second
 *    sélecteur ci-dessous, à (0,5,0). ⚠️ Chaque sélecteur d'une liste garde SA
 *    spécificité — les grouper ne les nivelle pas.
 *
 * 2. `.splide__arrow` (0,1,0) pose `opacity: .7`. Nos règles ne redéclaraient jamais
 *    `opacity`, donc le repère restait semi-transparent et se délavait sur un visuel
 *    clair — invisible pour une personne daltonienne, sur un écran mal calibré ou en
 *    plein soleil (le halo blanc, lui, s'appliquait déjà : Splide ne pose aucun
 *    `box-shadow`). `opacity: 1` est donc la moitié du correctif, pas un détail.
 *
 * Le repère lui-même n'invente rien : c'est le pattern déjà normé dans ce fichier pour
 * le bouton pause (§2) et le CTA (§6). Pas d'`!important` — la spécificité suffit.
 *
 * ⚠️ Une mise à jour de Splide peut réintroduire le défaut en changeant ces sélecteurs.
 * `CarrouselFocusInvariantTest` verrouille les deux côtés : nos surcharges ET les règles
 * du vendor qu'elles neutralisent. --- */
.ipro-carrousel .splide__arrow:focus-visible,
.ipro-carrousel .splide.is-focus-in .splide__arrow:focus {
  outline: 2px solid var(--ipro-vetiver-600, #2E5243);
  outline-offset: 3px;
  box-shadow: 0 0 0 5px #ffffff;
  opacity: 1;
}

.ipro-carrousel .splide__pagination__page:focus-visible,
.ipro-carrousel .splide.is-focus-in .splide__pagination__page:focus {
  outline: 2px solid var(--ipro-vetiver-600, #2E5243);
  outline-offset: 3px;
  box-shadow: 0 0 0 5px #ffffff;
  opacity: 1;
}

/* =============================================================================
   4. PHOTOS
   Fond de slide : photo en plein cadre, object-fit cover.
   ============================================================================= */

.ipro-carrousel__photos {
  position: absolute;
  inset: 0;
  /* Ratio local (filet de sécurité si le parent perd sa hauteur). */
  aspect-ratio: 3 / 1;
  min-height: 180px;
  overflow: hidden;
}

.ipro-carrousel__photos img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  display: block;
  /* loading et fetchpriority gérés par PHP (eager 1re image/1re slide, lazy sinon). */
}

/*
 * No-JS : si Splide n'est pas initialisé, n'afficher que la 1re photo de chaque slide.
 * Les suivantes peuvent exister (galerie multi-photos) mais resteraient empilées.
 */
.ipro-carrousel:not(.is-splide-ready) .ipro-carrousel__photos img:not(:first-child) {
  display: none;
}

/* =============================================================================
   5. ACCROCHES — SCRIM + TEXTE (contraste ≥ 4,5:1 — WCAG 1.4.3)
   ============================================================================= */

/*
 * Scrim : dégradé sombre, transparent en haut, opaque en bas.
 *
 * Le fond est une PHOTO D'ANNONCEUR : on n'en maîtrise ni la luminosité, ni le
 * cadrage. Le contraste du texte blanc ne dépend donc que du voile — il doit tenir
 * ses 4,5:1 (WCAG 1.4.3) même sur une façade blanche en plein soleil. L'accroche
 * fait 22px/600 : c'est du texte STANDARD, pas du « large text » (qui exigerait
 * ≥ 24px, ou ≥ 18,66px ET ≥ 700). Aucune tolérance à 3:1 ici.
 *
 * Les arrêts sont en PIXELS depuis le haut, pas en pourcentage. Le pourcentage
 * dérive : la boîte grandit avec le nombre d'accroches, et le texte — toujours collé
 * à son padding-top de 64px — remontait d'autant dans le dégradé. C'est ce qui s'est
 * produit : le bord haut du texte se posait à 59 % de la hauteur, là où le voile
 * n'était plus qu'à 0,45 → 3,0:1 sur une photo claire, ÉCHEC.
 *
 * Ici le palier de 0,70 est atteint à 56px, soit 8px AVANT que le texte ne commence.
 * Chaque pixel de texte repose donc sur ≥ 0,70, quelle que soit la hauteur de la
 * boîte. Mesure sur le pire fond possible (blanc pur) :
 *   0,70 → #575A56 → 6,9:1   ·   0,82 (bas) → #34372F → 10,4:1
 * La rampe de 56px conserve la transition douce : pas d'arête franche sur la photo.
 *
 * /!\ Toucher au padding-top de 64px sans remonter le palier de 56px rouvre le
 * défaut : le texte repasserait dans la zone où le voile s'éteint.
 *
 * padding-bottom : 56px ~ hauteur du CTA (44px) + marge 12px.
 */
.ipro-carrousel__accroches {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 5;
  background: linear-gradient(
    to bottom,
    rgba(16, 20, 14, 0) 0,
    rgba(16, 20, 14, 0.70) 56px,
    rgba(16, 20, 14, 0.82) 100%
  );
  padding: 4rem var(--ipro-pad-x, 16px) 3.5rem;
  display: flex;
  flex-direction: column;
  gap: var(--ipro-space-1, 4px);
}

.ipro-carrousel__accroche {
  margin: 0;
  /* Taille fluide : lisible sur 360 px et sur grand écran. */
  font-size: clamp(1rem, 2.5vw, 1.375rem);
  font-weight: 600;
  color: #ffffff;               /* blanc sur scrim sombre >> 4,5:1 */
  line-height: var(--ipro-leading-snug, 1.31);
  overflow-wrap: break-word;
}

/* =============================================================================
   6. CTA — BOUTON D'ACTION PRINCIPAL
   ============================================================================= */

.ipro-carrousel__cta {
  position: absolute;
  bottom: var(--ipro-space-3, 12px);
  right: var(--ipro-pad-x, 16px);
  z-index: 10;
  /* Cible tactile ≥ 44×44 px. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  min-width: 44px;
  padding: 0 var(--ipro-space-4, 16px);
  /* Couleur CTA principal Vétiver-700 / texte blanc (règle inversée charte V2). */
  background: var(--ipro-vetiver-700, #244034);
  color: #ffffff;
  font-size: 0.9375rem;
  font-weight: 600;
  line-height: 1;
  text-decoration: none;
  border-radius: var(--ipro-radius-md, 4px);
  border: 2px solid transparent;
  transition:
    background var(--ipro-transition-fast, 150ms) var(--ipro-easing-standard, cubic-bezier(0.2, 0, 0, 1));
}

.ipro-carrousel__cta:hover {
  background: var(--ipro-vetiver-800, #1C3128);
}

/* Focus : même pattern halo blanc que le bouton pause. */
.ipro-carrousel__cta:focus-visible {
  outline: 2px solid var(--ipro-vetiver-600, #2E5243);
  outline-offset: 3px;
  box-shadow: 0 0 0 5px #ffffff;
}

/* =============================================================================
   7. NO-JS — RENDU DÉGRADÉ SANS INITIALISATION SPLIDE
   La classe .is-splide-ready est posée par la glue JS (assets/js/carrousel.js)
   une fois Splide initialisé. Tant qu'elle est absente : no-JS graceful.
   ============================================================================= */

/*
 * Splide pose `visibility:hidden` sur `.splide` jusqu'à son init JS (qui ajoute
 * `is-initialized` → visibility:visible). Sans JS, ce hook n'arrive jamais : on
 * rétablit la visibilité pour que la première vitrine s'affiche (dégradation
 * gracieuse). Sinon, no-JS = carrousel totalement invisible.
 */
.ipro-carrousel:not(.is-splide-ready) .splide {
  visibility: visible;
}

/*
 * Masquer tous les slides sauf le premier.
 * Sans Splide actif, les slides empilés cassent le layout → on cache les suivants.
 */
.ipro-carrousel:not(.is-splide-ready) .splide__slide:not(:first-child) {
  display: none;
}

/*
 * Premier slide visible : occupe tout l'espace du conteneur.
 * L'aspect-ratio sur .splide reste actif → le slide s'affiche en 16:9.
 */
.ipro-carrousel:not(.is-splide-ready) .splide__slide:first-child {
  display: block;
  /* Largeur explicite : sans Splide JS, le flex-item n'a pas de largeur inline ;
     une vitrine sans photo aurait alors une largeur 0 (invisible). */
  width: 100%;
  height: 100%;
}

/*
 * Accroches en mode statique : affichage en colonne (déjà le cas par défaut).
 * Toutes les accroches du premier slide restent visibles, empilées.
 */
.ipro-carrousel:not(.is-splide-ready) .ipro-carrousel__accroches {
  /* Pas de surcharge : le comportement par défaut convient. */
}

/* =============================================================================
   8. RESPONSIVE (mobile-first, base 360 px)
   ============================================================================= */

@media (min-width: 640px) {
  .ipro-carrousel__accroches {
    padding-left: var(--ipro-pad-x, 24px);
    padding-right: var(--ipro-pad-x, 24px);
    padding-bottom: 3.5rem;
  }

  .ipro-carrousel__cta {
    bottom: var(--ipro-space-4, 16px);
    right: var(--ipro-pad-x, 24px);
  }

  .ipro-carrousel__pause {
    top: var(--ipro-space-3, 12px);
    /* Pas de `right` ici : il suit --ipro-pad-x (cf. § 2), qui passe seul à 24 px. */
  }
}

@media (min-width: 1024px) {
  .ipro-carrousel__accroche {
    /* Limiter la largeur des accroches sur grand écran. */
    max-width: 65%;
  }

  .ipro-carrousel__accroches {
    padding-left: var(--ipro-pad-x, 32px);
    padding-right: var(--ipro-pad-x, 32px);
    padding-bottom: 4rem;
  }

  .ipro-carrousel__cta {
    right: var(--ipro-pad-x, 32px);
    bottom: var(--ipro-space-4, 16px);
  }
}

/* =============================================================================
   9. MOUVEMENT RÉDUIT (WCAG 2.3.3 / prefers-reduced-motion)
   Gèle toutes les transitions et animations visuelles internes au carrousel.
   La glue JS (carrousel.js) lit également ce média pour couper l'autoplay.
   ============================================================================= */

@media (prefers-reduced-motion: reduce) {
  .ipro-carrousel,
  .ipro-carrousel *,
  .ipro-carrousel *::before,
  .ipro-carrousel *::after {
    transition: none !important;
    animation: none !important;
  }
}
