/**
 * CAROUSEL BASE — Socle structurel commun des carousels DivisCarousel
 * =============================================================================
 *
 * Ce fichier contient UNIQUEMENT la mécanique agnostique du carousel :
 * track, largeur des cards, dots, flèches, reduced-motion. Aucune couleur
 * de marque, aucune règle de carte : le cosmétique vit dans les skins.
 *
 * CONSOMMATEURS ACTUELS
 *   - .et_pb_row.carousel        rows Divi (skin : carousel.css)
 *   - .msp-liste.msp-carousel    shortcode [msp_liste] (skin : msp-liste.css)
 *
 * Pour brancher un nouveau consommateur : ajouter son sélecteur container
 * dans les :is() ci-dessous, puis surcharger les custom properties dans
 * son propre fichier. Le squelette HTML est celui produit par DivisCarousel :
 *
 *   <container>
 *     <div class="carousel-track">
 *       <div class="carousel-card">…</div> × N
 *     </div>
 *     <div class="carousel-dots">
 *       <button class="carousel-dot"> × N   (ou .carousel-dot-prev/-next)
 *     </div>
 *   </container>
 *
 * API — CUSTOM PROPERTIES (l'"extend" se fait par la cascade, pas par héritage)
 *   --cards-per-view          nb d'items visibles. Posé en style inline par
 *                             DivisCarousel depuis data-per-view : ne PAS
 *                             tenter de l'écraser en media query.
 *   --carousel-pv-max         plafond responsive : la largeur des cards est
 *                             calculée sur min(--cards-per-view, --carousel-pv-max).
 *                             C'est LUI qu'on pose dans les media queries des
 *                             skins (remplace les anciens !important).
 *   --carousel-gap            gouttière du track.
 *                             Compat legacy : retombe sur --gap, puis 20px.
 *   --carousel-transition     durée/easing du translateX. Défaut .45s ease.
 *   --carousel-dots-gap       espacement entre dots. Défaut 10px.
 *   --carousel-dots-mt        marge au-dessus des dots. Défaut 1.5rem.
 *   --carousel-dot-size       diamètre des dots. Défaut 12px.
 *   --carousel-dot-bg         fond dot inactif. Défaut #D9D9D9.
 *   --carousel-dot-bg-active  fond dot actif. Défaut currentColor.
 *   --carousel-arrow-size     taille des flèches (mode two-dots). Défaut 1.6rem.
 *   --carousel-arrow-color    couleur flèches. Défaut currentColor.
 *   --carousel-arrow-hover    couleur flèches au hover. Défaut idem.
 *
 * COHABITATION AVEC L'EXISTANT
 *   Spécificité volontairement basse (une classe via :is()). Tant que
 *   carousel.css (legacy) définit encore track/cards/dots avec ses sélecteurs
 *   .et-db #et-boc .et-l …, ce sont eux qui pilotent les rows Divi (id > classe) :
 *   AUCUNE régression au déploiement. Les .msp-carousel, eux, ne matchent
 *   aucune règle legacy et consomment ce socle immédiatement. Une fois les
 *   primitives retirées de carousel.css, les rows Divi basculent sur le socle.
 *
 * ORDRE D'ENQUEUE : carousel-base → carousel (legacy/skin Divi) → msp-liste.
 *
 * v1.1.0 : ajout de la section 7 « PRÉ-INITIALISATION » (anti-flash) —
 * avant que DivisCarousel ne construise le track, les modules/items ont déjà
 * la largeur d'une card : la première page du carrousel est en place dès le
 * premier rendu, sans saut de mise en page. Fonctionne avec carousel.js
 * v1.1.2+ (init au DOMContentLoaded).
 *
 * @version 1.1.0
 */

/* =============================================================================
   1. CONTAINERS
   ============================================================================= */

:is(.et_pb_row.carousel, .msp-liste.msp-carousel) {
    position: relative;
}

/* Le container du shortcode est son propre viewport de clipping.
   (Les rows Divi, elles, sont clippées au niveau de la section par le skin
   Divi — le débord visuel des cards y est un choix de design.) */
.msp-liste.msp-carousel {
    overflow: hidden;
}

/* =============================================================================
   2. TRACK
   ============================================================================= */

:is(.et_pb_row.carousel, .msp-liste.msp-carousel) .carousel-track {
    display: flex;
    gap: var(--carousel-gap, var(--gap, 20px));
    width: 100%;
    transition: transform var(--carousel-transition, 0.45s ease);
    will-change: transform;
}

/* =============================================================================
   3. CARDS — largeur pilotée par --cards-per-view, plafonnée par --carousel-pv-max
   ============================================================================= */

:is(.et_pb_row.carousel, .msp-liste.msp-carousel) .carousel-card {
    --pv: min(var(--cards-per-view, 4), var(--carousel-pv-max, 99));

    flex: 0 0 calc((100% - (var(--pv) - 1) * var(--carousel-gap, var(--gap, 20px))) / var(--pv));
    max-width: calc((100% - (var(--pv) - 1) * var(--carousel-gap, var(--gap, 20px))) / var(--pv));
    min-width: 0;
}

/* =============================================================================
   4. DOTS (navigation standard)
   ============================================================================= */

:is(.et_pb_row.carousel, .msp-liste.msp-carousel) .carousel-dots {
    display: flex;
    justify-content: center;
    align-items: center;
    gap: var(--carousel-dots-gap, 10px);
    margin-top: var(--carousel-dots-mt, 1.5rem);
}

:is(.et_pb_row.carousel, .msp-liste.msp-carousel) .carousel-dot {
    width: var(--carousel-dot-size, 12px);
    height: var(--carousel-dot-size, 12px);
    padding: 0;
    border: none;
    border-radius: 50%;
    background: var(--carousel-dot-bg, #D9D9D9);
    cursor: pointer;
    transition: background-color 0.2s ease, transform 0.2s ease;
}

:is(.et_pb_row.carousel, .msp-liste.msp-carousel) .carousel-dot.is-active {
    background: var(--carousel-dot-bg-active, currentColor);
}

:is(.et_pb_row.carousel, .msp-liste.msp-carousel) .carousel-dot:disabled {
    opacity: 0.4;
    cursor: default;
}

/* =============================================================================
   5. FLÈCHES (mode .carousel-two-dots : boutons prev / next)
   ============================================================================= */

:is(.et_pb_row.carousel, .msp-liste.msp-carousel) :is(.carousel-dot-prev, .carousel-dot-next) {
    width: calc(var(--carousel-arrow-size, 1.6rem) * 1.6);
    height: calc(var(--carousel-arrow-size, 1.6rem) * 1.6);
    border-radius: 50%;
    background: transparent;
    display: flex;
    align-items: center;
    justify-content: center;
}

:is(.et_pb_row.carousel, .msp-liste.msp-carousel) :is(.carousel-dot-prev, .carousel-dot-next)::before {
    font-family: 'ETmodules';
    font-size: var(--carousel-arrow-size, 1.6rem);
    line-height: 1;
    color: var(--carousel-arrow-color, currentColor);
    transition: color 0.2s ease;
}

:is(.et_pb_row.carousel, .msp-liste.msp-carousel) .carousel-dot-prev::before { content: '\34'; }
:is(.et_pb_row.carousel, .msp-liste.msp-carousel) .carousel-dot-next::before { content: '\35'; }

:is(.et_pb_row.carousel, .msp-liste.msp-carousel) :is(.carousel-dot-prev, .carousel-dot-next):hover::before {
    color: var(--carousel-arrow-hover, var(--carousel-arrow-color, currentColor));
}

/* =============================================================================
   7. PRÉ-INITIALISATION (anti-flash)
   Tant que DivisCarousel n'a pas posé data-carousel-init="true", on donne aux
   modules / items la largeur d'une card avec le MÊME calcul que la section 3 :
   la première « page » du carrousel apparaît correctement dès le premier
   rendu. Après init, ces règles ne matchent plus (les éléments sont déplacés
   dans .carousel-track et l'attribut est posé).
   ============================================================================= */

/* Rows Divi : la colonne est déjà en flex (carousel.css) — on dimensionne
   les modules avant leur transformation en cards. */
.et_pb_row.carousel:not([data-carousel-init="true"]) .et_pb_column .et_pb_module.et_pb_blurb,
.et_pb_row.carousel:not([data-carousel-init="true"]) .et_pb_column .et_pb_module.et_pb_image {
    --pv: min(var(--cards-per-view, 4), var(--carousel-pv-max, 99));

    flex: 0 0 calc((100% - (var(--pv) - 1) * var(--carousel-gap, var(--gap, 20px))) / var(--pv));
    min-width: 0;
}

/* Listes [msp_liste] : le container devient lui-même une ligne flex le temps
   de l'init (les items en sont des enfants directs à ce stade). */
.msp-liste.msp-carousel:not([data-carousel-init="true"]) {
    display: flex;
    gap: var(--carousel-gap, var(--gap, 20px));
}

.msp-liste.msp-carousel:not([data-carousel-init="true"]) > .msp-liste__item {
    --pv: min(var(--cards-per-view, 4), var(--carousel-pv-max, 99));

    flex: 0 0 calc((100% - (var(--pv) - 1) * var(--carousel-gap, var(--gap, 20px))) / var(--pv));
    min-width: 0;
}

/* =============================================================================
   6. ACCESSIBILITÉ
   ============================================================================= */

@media (prefers-reduced-motion: reduce) {
    :is(.et_pb_row.carousel, .msp-liste.msp-carousel) .carousel-track {
        transition: none;
    }

    :is(.et_pb_row.carousel, .msp-liste.msp-carousel) .carousel-dot {
        transition: none;
    }
}