/* ==========================================================================
   ADD'N LIST - CAROUSELS D'ANNONCES PAR CATÉGORIE (HOMEPAGE)

   Le défilement est 100 % CSS (scroll-snap). Le JS ne sert qu'aux flèches
   desktop : sans lui, le carousel reste parfaitement utilisable au doigt et
   au trackpad. Contrainte directrice : compatibilité WebView AppMySite.
   ========================================================================== */

.tfd-carousel {
    /* Largeur d'une carte. Les gouttières sont portées par le gap du rail, et
       non par les paddings de .hp-col-* : cette valeur correspond donc à la
       largeur réellement visible de la carte.

       Largeur de contenu du conteneur : 1140px (div.container fait 1204px de
       bord externe, moins 32px de padding de chaque côté — relevé DevTools).

       Formule, avec F la largeur du fragment de 6e carte à laisser visible :
           5 x carte + 5 x 16px de gap + F = 1140
           carte = (1060 - F) / 5
       204px laisse donc un fragment d'environ 40px : assez pour signaler
       qu'il reste du contenu, sans l'effet de mise en page tronquée.
       Pour un fragment plus large : 200px => 60px, 195px => 85px. */
    --tfd-carousel-card: 204px;
    --tfd-carousel-nav-size: 40px;

    /* Hauteur imposée à toutes les cartes, tous carousels confondus.
       auto = pas de contrainte : align-items: stretch aligne déjà les cartes
       entre elles au sein d'un même rail, et la hauteur naturelle donne un
       rendu plus compact. Contrepartie acceptée : deux carousels de
       catégories différentes peuvent avoir des hauteurs légèrement
       différentes — ils ne sont jamais côte à côte, l'écart ne se lit pas.
       Remettre une valeur en px (340px auparavant) pour forcer l'uniformité
       entre catégories. */
    --tfd-carousel-card-height: auto;

    position: relative;
    margin: 0 0 2.5rem;
}

/* --------------------------------------------------------------------------
   En-tête : titre + lien "View all"
   -------------------------------------------------------------------------- */

.tfd-carousel__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 0.75rem;
}

/* Le sélecteur reprend la balise pour passer devant h2:not(:last-child) de
   frontend.min.css (0-1-1), qui applique une marge basse au titre. Cette
   marge, absente du lien "View all", décalait les deux éléments malgré
   align-items: center. */
.tfd-carousel__header h2.tfd-carousel__title {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin: 0;
    font-size: 1.125rem;
    font-weight: 700;
    line-height: 1.2;
}

/* Neutralise la barre décorative ::before appliquée aux titres par le thème. */
.tfd-carousel__title::before,
.tfd-carousel__title::after {
    content: none;
}

.tfd-carousel__title i {
    color: var(--tfd-color-primary, #f4623a);
    font-size: 1rem;
}

/* Lien "View all" : noir et gras plutôt qu'orange.
   L'orange est réservé aux actions principales (Post an ad, boutons de
   conversion) ; l'employer ici pour un lien de navigation secondaire
   diluerait cette hiérarchie. Même parti pris que Leboncoin. La flèche et la
   graisse suffisent à le signaler comme cliquable, l'orange n'apparaissant
   qu'au survol. */
.tfd-carousel__view-all {
    flex: 0 0 auto;
    font-size: 0.875rem;
    font-weight: 600;
    line-height: 1.2;
    margin: 0;
    color: #1a1a1a;
    text-decoration: none;
    white-space: nowrap;
    transition: color 0.15s ease;
}

.tfd-carousel__view-all:hover,
.tfd-carousel__view-all:focus {
    color: var(--tfd-color-primary, #f4623a);
}

/* --------------------------------------------------------------------------
   Rail scrollable

   HivePress produit .hp-listings.hp-grid > .hp-row > .hp-grid__item.
   C'est .hp-row qui porte les items : c'est donc lui le conteneur scrollable,
   pas .hp-grid.
   -------------------------------------------------------------------------- */

.tfd-carousel__viewport {
    position: relative;
}

.tfd-carousel .hp-row {
    display: flex;
    flex-wrap: nowrap;            /* écrase le wrap de la grille ListingHive */
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x mandatory;
    scroll-behavior: smooth;

    /* Gouttières gérées par gap plutôt que par les paddings de .hp-col-* :
       une seule valeur à régler, et pas de marges négatives à compenser sur
       un conteneur scrollable (elles décaleraient la position de départ). */
    margin-left: 0;
    margin-right: 0;
    gap: 16px;

    /* Empêche le geste horizontal de remonter au conteneur parent : sans ça,
       en WebView Android, le swipe déclenche la navigation arrière du système
       ou le pull-to-refresh au lieu de faire défiler le rail. */
    overscroll-behavior-x: contain;

    /* Défilement fluide au doigt sur iOS. */
    -webkit-overflow-scrolling: touch;

    /* Masquage de la scrollbar (l'affordance est portée par la carte
       tronquée en bord de rail). */
    scrollbar-width: none;
    -ms-overflow-style: none;
}

.tfd-carousel .hp-row::-webkit-scrollbar {
    display: none;
}

.tfd-carousel .hp-grid__item {
    flex: 0 0 var(--tfd-carousel-card);
    width: var(--tfd-carousel-card);
    max-width: none;              /* écrase hp-col-sm-3 / hp-col-xs-12 */
    padding-left: 0;              /* gouttières portées par le gap du rail */
    padding-right: 0;
    scroll-snap-align: start;
}

/* --------------------------------------------------------------------------
   Allègement de la carte en contexte carousel

   Les attributs secondaires (Availability / Shipping / Warranty) alourdissent
   la carte et ne figurent pas sur la maquette homepage.

   DETTE ASSUMÉE : masquage CSS seulement — le HTML reste transmis. Le retrait
   propre passera par un filtre sur hivepress/v1/templates/listing_view_block/
   blocks scopé au contexte carousel (phase 2).
   -------------------------------------------------------------------------- */

.tfd-carousel .hp-listing__attributes--secondary {
    display: none;
}

/* --------------------------------------------------------------------------
   Normalisation des cartes

   En grille classique, chaque ligne s'auto-aligne. Dans un rail flex d'une
   seule ligne, la moindre différence de hauteur (titre sur 3 lignes, image
   plus haute) désaligne toute la rangée. On impose donc une géométrie stable.
   -------------------------------------------------------------------------- */

/* Cartes calées en haut et étirées à hauteur égale. */
.tfd-carousel .hp-row {
    align-items: stretch;
}

/* Carte : coins arrondis sur l'enveloppe uniquement.
   overflow: hidden suffit à rogner la vignette au même rayon en haut, sans
   arrondir ses coins bas — l'image reste ainsi solidaire du bloc de texte
   plutôt que de flotter comme une vignette détachée.

   min-height fige la hauteur pour TOUS les carousels, et pas seulement au
   sein d'un même rail : sans elle, align-items: stretch aligne les cartes
   entre elles mais chaque catégorie prend une hauteur propre selon son
   contenu (tarif horaire sur Services, absent sur Fashion). Valeur à
   réajuster si la largeur de carte ou la taille de police change. */
.tfd-carousel .hp-grid__item > .hp-listing {
    display: flex;
    flex-direction: column;
    height: 100%;
    min-height: var(--tfd-carousel-card-height);
    border-radius: 12px;
    overflow: hidden;
}

/* Image.
   Rien à corriger côté géométrie : HivePress pose lui-même
   style="aspect-ratio: 1.3333 / 1" en inline sur .hp-listing__image, et le
   conteneur est déjà en position relative avec une hauteur cohérente
   (vérifié au panneau Computed). On se contente du recadrage.

   cover plutôt que contain : contain afficherait le visuel entier mais
   générerait des bandes sur tout ce qui n'est pas exactement 4/3 — bandes
   latérales très marquées sur les photos en portrait. Le recadrage peut
   amputer le watermark en bord d'image, sans conséquence à cette taille :
   il demeure intact sur la page de l'annonce. */
.tfd-carousel .hp-listing__image {
    background-color: #f5f5f5;
}

.tfd-carousel .hp-listing__image img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Annulation de la remontée du titre.
   style.css (ligne 634) applique margin-top: -25px à
   .hp-listing__content h4.hp-listing__title, pour combler l'espace du badge
   de catégorie affiché en overlay sur l'image. Ce badge étant masqué dans
   les carousels (voir plus bas), la marge négative n'a plus rien à compenser
   et fait passer le titre sous la vignette.
   Spécificité 0-3-1, supérieure à la règle d'origine : pas de !important. */
.tfd-carousel .hp-listing__content h4.hp-listing__title {
    margin-top: 0.625rem;
}

/* Le contenu absorbe l'espace restant : le footer reste collé en bas. */
.tfd-carousel .hp-listing__content {
    flex: 1 1 auto;
}

/* Titre : 2 lignes maximum.
   Pas de min-height : réserver systématiquement deux lignes creusait un vide
   sous les titres courts (visible sur Fashion, où tous tiennent sur une
   ligne). Le prix colle donc au titre, quitte à se placer à des hauteurs
   différentes d'une carte à l'autre — c'est le parti pris d'Eletrycos, et
   le bas des cartes reste aligné par align-items: stretch sur le rail.
   max-height sert de garde-fou : si -webkit-line-clamp n'est pas honoré
   (moteur ancien, WebView exotique), la troisième ligne serait rognée par
   overflow plutôt que de pousser tout le contenu vers le bas. */
.tfd-carousel .hp-listing__content .hp-listing__title {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    max-height: 2.6em;
    line-height: 1.3;
    font-size: 0.95rem;
}

/* Titre : retour visuel au survol. Le titre est le point de clic principal
   de la carte, il n'avait aucun état hover. */
.tfd-carousel .hp-listing__title a {
    transition: color 0.15s ease;
}

.tfd-carousel .hp-listing__title a:hover,
.tfd-carousel .hp-listing__title a:focus {
    color: var(--tfd-color-primary, #f4623a);
}

/* Badge "vérifié" : retiré des carousels.
   Rendu par HivePress à l'intérieur du <h4> du titre :
   <i class="hp-listing__verified-badge hp-listing__verified hp-icon ...">
   Il n'apparaît que sur une partie des annonces et déséquilibre le titre à
   cette taille. L'information reste sur la page de l'annonce. */
.tfd-carousel .hp-listing__verified-badge {
    display: none;
}

/* Prix : même taille que le titre, distingué par la seule graisse.
   Le prix est remonté sous le titre par tfd-listing-cards.js.
   !important sur le seul font-weight : style.css impose le poids des
   attributs de listing avec !important, qu'aucune spécificité ne peut
   battre. À nettoyer le jour où cette règle sera assouplie. */
.tfd-carousel .hp-listing__content .hp-listing__attribute--price {
    margin-bottom: 0.4rem;
    font-size: 0.95rem;
    font-weight: 700 !important;
    line-height: 1.2;
}

/* Le footer reste collé en bas (le contenu absorbe l'espace restant, cf. la
   règle .hp-listing__content plus haut). */
.tfd-carousel .hp-listing__footer {
    margin-top: auto;
}

/* Badge de catégorie : retiré des carousels.
   Sur 195px de large, "ELECTRONIC REPAIR SERVICES" ne tient pas et se
   tronquait en plein milieu d'un mot. L'information reste accessible sur la
   page de l'annonce et via le titre du carousel lui-même.
   Les deux classes sont reprises pour passer devant la règle
   .hp-listing__categories.hp-listing__category de style.css, de spécificité
   identique — à égalité, seul l'ordre de chargement départagerait. */
.tfd-carousel .hp-listing__categories.hp-listing__category,
.tfd-carousel .hp-listing__categories {
    display: none;
}

/* Notes et avis : retirés des carousels.
   Ils n'apparaissent que sur une partie des annonces, ce qui faisait varier
   la hauteur des cartes d'une catégorie à l'autre. L'information reste sur
   la page de l'annonce, où elle a plus de poids.
   Plusieurs variantes de classes sont couvertes selon la façon dont le bloc
   est rendu (extension Reviews ou attribut de listing). */
.tfd-carousel .hp-rating,
.tfd-carousel .hp-listing__rating,
.tfd-carousel .hp-listing__attribute--rating,
.tfd-carousel .hp-listing__details--secondary .hp-rating {
    display: none;
}

/* Localisation et date sur une seule et même ligne, accolées et séparées par
   un point médian — parti pris repris d'Eletrycos et de Leboncoin, qui
   traitent tous deux ce couple comme une méta-ligne discrète.
   flex-start plutôt que space-between : les adresses étant courtes
   (ville + code d'État), les écarter aux deux extrémités creusait un vide
   au milieu de la carte. */
.tfd-carousel .hp-listing__details--primary {
    display: flex;
    align-items: baseline;
    justify-content: flex-start;
    gap: 0.35rem;
    flex-wrap: nowrap;
}

/* Localisation : icône resserrée contre le texte.
   L'ellipsis n'agit qu'en filet de sécurité — les libellés normalisés
   (Neighborhood, City, ST) tiennent sur une ligne ; seules d'anciennes
   annonces à adresse complète pourraient déborder. */
.tfd-carousel .hp-listing__location {
    display: flex;
    align-items: center;
    gap: 0.2rem;
    min-width: 0;
    font-size: 0.8rem;
}

.tfd-carousel .hp-listing__location span {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* L'icône porte une marge droite héritée du thème, qui creusait l'écart
   avec l'adresse en s'ajoutant au gap. */
.tfd-carousel .hp-listing__location i {
    margin-right: 0;
    font-size: 0.75rem;
    color: var(--tfd-color-primary, #f4623a);
}

.tfd-carousel .hp-listing__location span {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Cœur favoris : repoussé vers l'angle de la vignette et glyphe recentré.
   Le bouton est placé en overlay par tfd-listing-cards.js ; en contexte
   carousel les cartes sont plus étroites, un retrait important le faisait
   flotter au milieu du coin plutôt que de le caler dessus.
   Le centrage flex corrige le décalage bas-gauche du glyphe : en rendu
   inline, le line-height hérité le pousse vers le bas et la chasse du
   caractère le décale à gauche du cercle. */
.tfd-carousel .hp-listing__action--favorite {
    top: 0.65rem;
    right: 0.4rem;
    display: flex;
    align-items: center;
    justify-content: center;
    line-height: 1;
    text-align: center;
}

.tfd-carousel .hp-listing__action--favorite i {
    display: block;
    margin: 0;
    line-height: 1;
}

/* Date d'ajout : petite, grise, précédée d'un point médian qui la relie à la
   localisation sans ponctuation dans le contenu lui-même. */
.tfd-carousel .hp-listing__created-date {
    flex: 0 0 auto;
    margin: 0;
    white-space: nowrap;
    font-size: 0.75rem;
    color: #767676;
}

.tfd-carousel .hp-listing__created-date::before {
    content: "•";
    margin-right: 0.35rem;
    color: #767676;
}

/* Footer sans attribut affiché : masqué.
   tfd-listing-cards.js remonte le prix sous le titre ; sur les catégories
   sans tarif horaire (Fashion...), le footer se retrouve vide mais conserve
   son padding — d'où la large bande grise en bas de carte.
   :has() n'est pas universellement supporté : sur un moteur ancien, la règle
   est ignorée et on retombe simplement sur le comportement actuel. */
.tfd-carousel .hp-listing__footer:not(:has(.hp-listing__attribute)) {
    display: none;
}

/* --------------------------------------------------------------------------
   Flèches de navigation

   Visibles en permanence dès que le rail déborde, et non au survol : même
   parti pris que Leboncoin et que les carousels TaskHive, où la flèche est
   toujours affichée. Elle complète le fragment de carte en bord de rail
   comme indice de défilement.

   La classe tfd-carousel--scrollable est posée par tfd-carousel.js seulement
   si le contenu dépasse réellement la largeur du rail.
   -------------------------------------------------------------------------- */

.tfd-carousel__nav {
    position: absolute;
    /* Centrage vertical sur la hauteur du rail. Une valeur fixe calée sur la
       vignette ne tenait pas : la hauteur d'image varie avec la largeur de
       carte et avec le point de rupture responsive. */
    top: 50%;
    transform: translateY(-50%);
    z-index: 2;
    display: none;
    align-items: center;
    justify-content: center;
    width: var(--tfd-carousel-nav-size);
    height: var(--tfd-carousel-nav-size);
    padding: 0;
    /* Bordure et ombre volontairement marquées : centré verticalement, le
       bouton se superpose au bloc de texte de la carte, dont le fond est
       clair. Sans contraste appuyé, le cercle blanc s'y fondait. */
    border: 1px solid rgba(0, 0, 0, 0.12);
    border-radius: 50%;
    background: #fff;
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
    color: #1a1a1a;
    font-size: 0.875rem;
    cursor: pointer;
    transition: box-shadow 0.15s ease, transform 0.15s ease, opacity 0.15s ease;
}

.tfd-carousel__nav:hover {
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.28);
    transform: translateY(-50%) scale(1.06);
}

.tfd-carousel__nav:focus-visible {
    outline: 2px solid var(--tfd-color-primary, #f4623a);
    outline-offset: 2px;
}

/* Extrémité de course : la flèche reste visible mais neutralisée, pour que
   la position dans le rail se lise d'un coup d'œil.
   Le transform reprend le centrage vertical, sinon la règle de base serait
   écrasée et le bouton sauterait. */
.tfd-carousel__nav:disabled {
    opacity: 0.4;
    pointer-events: none;
    transform: translateY(-50%);
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
}

.tfd-carousel__nav--prev {
    left: 8px;
}

.tfd-carousel__nav--next {
    right: 8px;
}

/* Affichage conditionnel : classe posée par le JS quand scrollWidth > clientWidth. */
.tfd-carousel--scrollable .tfd-carousel__nav {
    display: flex;
}

/* --------------------------------------------------------------------------
   Responsive
   -------------------------------------------------------------------------- */

@media all and (max-width: 1023px) {
    .tfd-carousel {
        --tfd-carousel-card: 30vw;
    }
}

@media all and (max-width: 767px) {
    .tfd-carousel {
        /* ~2,3 cartes visibles : la troisième est tronquée et signale le
           débordement, comme sur la capture Eletrycos mobile. */
        --tfd-carousel-card: 42vw;

        /* Pas de hauteur imposée non plus en mobile, cf. la déclaration
           desktop plus haut. */
        --tfd-carousel-card-height: auto;
    }

    /* Le swipe natif remplace les flèches. */
    .tfd-carousel--scrollable .tfd-carousel__nav {
        display: none;
    }

    .tfd-carousel__title {
        font-size: 1rem;
    }
}

/* Respect des préférences d'accessibilité système. */
@media (prefers-reduced-motion: reduce) {
    .tfd-carousel .hp-row {
        scroll-behavior: auto;
    }
}
