/*
 * SSR de la page de recherche : layout du contenu crawlable (partial _searchSsr.html.twig).
 *
 * RÉPLIQUE EXACTE du CSS de la SearchPage React (assets/react/components/SearchPage/style.css),
 * car ce CSS React est bundlé avec le JS et donc ABSENT au SSR. On reproduit ici les mêmes
 * valeurs pour que les cartes SSR soient aux mêmes positions/largeurs qu'après le montage React
 * => zéro décalage horizontal à la substitution (mesuré sur le rendu React).
 *
 * Correspondances React (valeurs mesurées) :
 *  - .ssrx-root    = .search-page-content : flex row, align-items flex-start, gap 10px
 *  - .ssrx-facets  = .left-panel          : flex 0 0 270px
 *  - .ssrx-results = .right-panel         : flex 1 1 auto
 *  - .ssrx-hits    = .infinite-hits-container : flex-wrap, gap 20px 50px, max-width 1050px centré (>=700px)
 *  - .ssrx-card    = .card React          : 300px fixe, 100% (pleine largeur) sous 480px
 *
 * Breakpoint sidebar = desktopBreakpoint React (assets/react/libs/mobileUtils.ts = 1280) :
 * isMobile = (max-width:1280px). <=1280 => pas de sidebar (filtres en tiroir), résultats centrés ;
 * >=1281 => sidebar facettes 270px. Cohérent avec la réservation de bande (search-page.css).
 *
 * /!\ Chargé UNIQUEMENT par les templates search.*.html.twig (via {% block stylesheets %}).
 */

/* ============================================================================
 * Double buffering du swap SSR -> React (anti-CLS).
 * React est monté CACHÉ (display:none) : aucun layout, donc ses reflows internes (vide -> hits -> pubs)
 * ne produisent AUCUN shift. Le SSR (.search-db-ssr, en flux) reste visible et tient la hauteur. Au signal
 * 'searchpage:ready' (hits + facettes prêts, cf. ReadyBeacon.tsx), public/js/search-double-buffer.js retire
 * le SSR ET affiche React en une seule frame : React s'affiche pour la 1ère fois (1er paint => NON compté)
 * à la même hauteur que le SSR (parité) => footer stable, zéro shift, aucune frame blanche.
 *
 * Pourquoi display:none et pas un hors-écran (transform/absolute) : ramener un élément hors-écran À l'écran
 * est compté par l'API layout-shift (elle mesure la position VISUELLE). display:none n'a pas de position du
 * tout => son affichage = 1er paint, non compté.
 * ========================================================================== */
.search-db-prewarm-hidden {
    display: none;
}
/* Le conteneur SSR doit avoir EXACTEMENT la même largeur que .search-react : ce dernier annule le
   padding de container-fluid >=1280px (cf. assets/css/v6/search-react.css). Sans ça, .search-db-ssr
   garde les ~40px de padding ⇒ colonne résultats trop étroite ⇒ 2 cartes/ligne au lieu de 3 et reflow
   visible au reveal. On réplique l'annulation pour parité parfaite. */
@media (min-width: 1280px) {
    .search-db-ssr.fluid {
        padding: unset;
    }
}

/* Conteneur 2 colonnes (= .search-page-content), >=1281 */
.ssrx-root {
    display: flex;
    flex-direction: row;
    align-items: flex-start;
    gap: 10px;
}

/* Colonne facettes skeleton (= .left-panel : flex 0 0 270px) */
.ssrx-facets {
    flex: 0 0 270px;
    max-width: 270px;
}

/* Colonne résultats (= .right-panel) */
.ssrx-results {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
}

/* Grille de cartes (= .infinite-hits-container) : flex-wrap, gouttières 20px (lignes) x 50px (colonnes) */
.ssrx-hits {
    display: flex;
    flex-wrap: wrap;
    gap: 20px 50px;
    justify-content: center;
}
@media (min-width: 700px) {
    .ssrx-hits {
        justify-content: flex-start;
        width: 100%; /* remplit la zone résultats comme .infinite-hits-container (flex:1 1 auto) côté React :
                        sinon, avec peu de cartes, margin-inline:auto rétrécit+centre le bloc → la carte
                        saute horizontalement au swap SSR→React. Le centrage ne joue qu'au-delà de 1050px. */
        max-width: 1050px; /* 3x300 + 2x50 */
        margin-inline: auto;
    }
}

/* Item carte (= .card React, 300px fixe). La carte Twig (width:100%) remplit ce conteneur.
   Sous 480px : pleine largeur (= @media max-width:479px .card{width:100%} côté React). */
.ssrx-card {
    flex: 0 0 300px;
    max-width: 300px;
    width: 300px;
}
@media (max-width: 479.98px) {
    .ssrx-card {
        flex-basis: 100%;
        max-width: 100%;
        width: 100%;
    }
}

/* Pas de slot pub réservé en SSR (décision « collapse sur invendu, pas de réservation ») : la pub est
   gérée par React/GoogleAdsManager (max-height + collapseDiv ON_NO_FILL). Réserver ici créerait un shift
   de remontée au swap quand la pub s'effondre sur no-fill. */

/* <=1280 (= isMobile React) : pas de sidebar, résultats centrés pleine largeur */
@media (max-width: 1280px) {
    .ssrx-root {
        display: block;
    }
    .ssrx-facets {
        display: none;
    }
}

/* Skeleton shimmer (facettes + pub) */
.ssrx-sk {
    position: relative;
    overflow: hidden;
    background: #ececec;
    border-radius: 8px;
}
.ssrx-sk::after {
    content: "";
    position: absolute;
    inset: 0;
    transform: translateX(-100%);
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.55), transparent);
    animation: ssrxShim 1.4s infinite;
}
@keyframes ssrxShim {
    100% {
        transform: translateX(100%);
    }
}
/* Skeleton de la colonne facettes — partagé SSR (Twig) + chargement React (FacetsSkeleton.tsx).
   Header "Filtres" réel (icône + texte sur fond page, bordée) comme le vrai .filter-header React,
   puis corps gris animé. Calqué sur .left-panel / .filter-header / .filter-facet-container de la
   SearchPage React (mêmes variables --GMI-*). */
.facets-skeleton {
    display: flex;
    flex-direction: column;
    position: sticky;
    top: var(--header-body-offset);
    height: calc(100vh - var(--header-body-offset));
}
.facets-skeleton-header {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 10px;
    height: 40px;
    padding: 13px 20px;
    box-sizing: border-box;
    border: 1px solid var(--GMI-cardbordercolor);
    border-radius: var(--GMI-filtersearchradius) var(--GMI-filtersearchradius) 0 0;
    background: var(--GMI-pagecolor);
}
/* Icône : SVG inline (robuste, l'asset /assets/icons/... n'est pas servi tel quel). Dimensions +
   preserveAspectRatio="xMidYMid slice" sur le <svg> = équivalent background-size:cover du vrai
   .filter-symbol React ⇒ même épaisseur de traits. */
.facets-skeleton-icon {
    flex: 0 0 auto;
    width: 14.58px;
    height: 13.24px;
    overflow: hidden;
}
.facets-skeleton-icon svg {
    width: 100%;
    height: 100%;
    display: block;
}
/* Titre = exactement .filter-header .filters-title (mêmes variables ⇒ même graisse/police que React). */
.facets-skeleton-title {
    color: var(--GMI-black);
    font-family: var(--filter-title-font-family);
    font-size: 18px;
    font-style: var(--filter-title-font-style);
    font-weight: var(--filter-title-font-weight);
    letter-spacing: var(--filter-title-letter-spacing);
    line-height: 20px;
    white-space: nowrap;
}
.facets-skeleton-body {
    flex: 1 1 auto;
    min-height: 0;
    border: 1px solid var(--GMI-cardbordercolor);
    border-top: unset;
}
.facets-skeleton-body.ssrx-sk {
    border-radius: 0 0 8px 8px; /* coins carrés en haut pour prolonger le header */
}

/* Mode carte (?mode=map) : la map vient de React => skeleton seul. */
.ssrx-map {
    height: 60vh;
    background: #ececec;
    border-radius: 8px;
}
