/* Theme: Default — style.css

/* ── Carte portrait : image de fond, titre posé dessus ── */
/* Dans un répéteur, `.aw-repeat-row > .col > .module-card { height:100% }` étire
   chaque carte à la hauteur de la rangée pour les aligner. Les autres cartes
   comblent avec leur corps ; ici le corps est en ABSOLU, donc rien ne comble :
   l'image restait à son ratio en haut et le dégradé+titre se retrouvaient collés
   au bas de la CARTE, seuls au milieu du blanc. L'image prend donc toute la
   hauteur disponible — le ratio ne gouverne plus que la carte NON étirée (carte
   seule, mosaïque), où le pourcentage retombe sur `auto`. */
.module-card--portrait .module-card__media { height: 100%; }
/* Un titre de cinq lignes mangeait la moitié de la photo : on le borne. */
.module-card--portrait .module-card__title {
    display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}

/* Carte documents sans pièce jointe : l'enveloppe reste dans le DOM (balisage
   constant) mais `{files}` ne rend rien — on retire la gouttière qu'elle laisse. */
.module-card__files-wrap:empty { display: none; }
   Contient désormais aussi les styles génériques des modules (ex-modules.css)
   pour ne charger qu'un seul fichier CSS sur le front.
   Ordre : génériques .module-* d'abord, surcharges du thème ensuite. */

/* FontAwesome 7 donne une largeur explicite aux icônes → une icône « d-block »
   (icône empilée au-dessus du texte, états vides) se colle à gauche car text-align
   ne déplace pas une boîte block. On la recentre (équivaut à « mx-auto »). */
i.d-block[class*="fa-"] { margin-inline: auto; }

/* ==========================================================================
   DESIGN SYSTEM — Palette + boutons colorés (btn-1 … btn-6)
   --------------------------------------------------------------------------
   Les couleurs (--color-1..6) et surcharges bouton (--btn-N-*) sont INLINÉES
   dans le <head> par la config du thème (admin/themes/configure/default),
   AVANT ce fichier. Ici on ne fait que les CONSOMMER via var(), avec un repli
   (palette → valeur sûre) : ne JAMAIS redéclarer ces vars en :root sinon la
   config serait écrasée. Le survol est auto-dérivé en color-mix (pas besoin de
   configurer une 2e couleur), surchargeable via --btn-N-bg-hover.
   ========================================================================== */
:root {
    /* Globaux boutons (non pilotés par la palette) */
    --btn-padding-x   : 1rem;
    --btn-padding-y   : .45rem;
    --btn-radius      : 4px;
    --icon-arrow      : "\f061";

    /* ---- Largeur de contenu & marge extérieure (--container-out-margin) ----
       --container-width est en px FIXES par breakpoint (mêmes valeurs que le .container
       Bootstrap, cf. media queries plus bas). Conséquence : --container-out-margin est
       une VALEUR CONCRÈTE (px) à chaque breakpoint, donc utilisable PARTOUT — y compris
       sur des éléments positionnés en absolu (pagination : left:) ou hors du flux du
       container. (Un --container-width:100% « paresseux » ne se résoudrait qu'à la
       largeur du bloc conteneur de l'élément consommateur → inutilisable sur la nav.)
       --main-width = largeur de la FENÊTRE (v-w = width). --container-out-margin = pure
       marge extérieure container→bord d'écran (sans demi-gutter). */
    --main-width           : 100vw;
    --container-width      : 100%;   /* < 576px : pleine largeur */
    --container-out-margin : calc((var(--main-width) - var(--container-width)) / 2);
    --split-container-width: calc(var(--container-width) / 2 - var(--bs-gutter-x, .75rem));
}
/* --container-width suit les paliers du .container Bootstrap → --container-out-margin
   se recalcule tout seul à chaque breakpoint. */
@media (min-width: 576px)  { :root { --container-width: 540px;  } }
@media (min-width: 768px)  { :root { --container-width: 720px;  } }
@media (min-width: 992px)  { :root { --container-width: 960px;  } }
@media (min-width: 1200px) { :root { --container-width: 1140px; } }
@media (min-width: 1400px) { :root { --container-width: 1320px; } }

/* Sort un bloc du .container centré jusqu'aux bords de l'écran (bord perdu),
   de façon COMPOSABLE (contrairement à l'idiome 50%−50vw, symétrique et 100%
   uniquement). À poser sur un enfant direct du .container. */
.full-bleed {
    margin-left : calc(-1 * var(--container-out-margin));
    margin-right: calc(-1 * var(--container-out-margin));
}
/* Variantes asymétriques : ne déborde que d'un côté (garde la grille de l'autre). */
.full-bleed-left  { margin-left : calc(-1 * var(--container-out-margin)); }
.full-bleed-right { margin-right: calc(-1 * var(--container-out-margin)); }

.btn { text-transform: uppercase; }

/* Fabrique un bouton coloré : $bg (fond), $fg (texte), $fallback (couleur palette) */
.btn-1, .btn-2, .btn-3, .btn-4, .btn-5, .btn-6 {
    border-style: solid;
    transition  : background-color .18s ease, color .18s ease, border-color .18s ease;
}

.btn-1 {
    background-color: var(--btn-1-bg, var(--color-1, #F8B11F));
    color           : var(--btn-1-color, #212529);
    border-color    : var(--btn-1-border-color, transparent);
    border-width    : var(--btn-1-border-width, 0);
    border-radius   : var(--btn-1-radius, var(--btn-radius));
}
.btn-1:hover {
    background-color: var(--btn-1-bg-hover, color-mix(in srgb, var(--btn-1-bg, var(--color-1, #F8B11F)) 85%, #000));
    color           : var(--btn-1-color-hover, var(--btn-1-color, #212529));
}

.btn-2 {
    background-color: var(--btn-2-bg, var(--color-2, #143F6F));
    color           : var(--btn-2-color, #ffffff);
    border-color    : var(--btn-2-border-color, transparent);
    border-width    : var(--btn-2-border-width, 0);
    border-radius   : var(--btn-2-radius, var(--btn-radius));
}
.btn-2:hover {
    background-color: var(--btn-2-bg-hover, color-mix(in srgb, var(--btn-2-bg, var(--color-2, #143F6F)) 85%, #000));
    color           : var(--btn-2-color-hover, var(--btn-2-color, #ffffff));
}

.btn-3 {
    background-color: var(--btn-3-bg, var(--color-3, #EB5757));
    color           : var(--btn-3-color, #ffffff);
    border-color    : var(--btn-3-border-color, transparent);
    border-width    : var(--btn-3-border-width, 0);
    border-radius   : var(--btn-3-radius, var(--btn-radius));
}
.btn-3:hover {
    background-color: var(--btn-3-bg-hover, color-mix(in srgb, var(--btn-3-bg, var(--color-3, #EB5757)) 85%, #000));
    color           : var(--btn-3-color-hover, var(--btn-3-color, #ffffff));
}

.btn-4 {
    background-color: var(--btn-4-bg, var(--color-4, #ffffff));
    color           : var(--btn-4-color, #212529);
    border-color    : var(--btn-4-border-color, #d0d5dd);
    border-width    : var(--btn-4-border-width, 1px);
    border-radius   : var(--btn-4-radius, var(--btn-radius));
}
.btn-4:hover {
    background-color: var(--btn-4-bg-hover, color-mix(in srgb, var(--btn-4-bg, var(--color-4, #ffffff)) 92%, #000));
    color           : var(--btn-4-color-hover, var(--btn-4-color, #212529));
}

.btn-5 {
    background-color: var(--btn-5-bg, var(--color-5, #2B2E68));
    color           : var(--btn-5-color, #ffffff);
    border-color    : var(--btn-5-border-color, transparent);
    border-width    : var(--btn-5-border-width, 0);
    border-radius   : var(--btn-5-radius, var(--btn-radius));
}
.btn-5:hover {
    background-color: var(--btn-5-bg-hover, color-mix(in srgb, var(--btn-5-bg, var(--color-5, #2B2E68)) 85%, #fff));
    color           : var(--btn-5-color-hover, var(--btn-5-color, #ffffff));
}

.btn-6 {
    background-color: var(--btn-6-bg, var(--color-6, #F4BD3D));
    color           : var(--btn-6-color, #212529);
    border-color    : var(--btn-6-border-color, transparent);
    border-width    : var(--btn-6-border-width, 0);
    border-radius   : var(--btn-6-radius, var(--btn-radius));
}
.btn-6:hover {
    background-color: var(--btn-6-bg-hover, color-mix(in srgb, var(--btn-6-bg, var(--color-6, #F4BD3D)) 85%, #000));
    color           : var(--btn-6-color-hover, var(--btn-6-color, #212529));
}

/* Bouton fléché (icône FA à droite) — repris de ton style.css */
.btn-arrow { position: relative; padding-right: calc(var(--btn-padding-x) + 35px); }
.btn-arrow::after {
    content   : var(--icon-arrow);
    font-family: "Font Awesome 7 Pro";
    font-weight: 300;
    font-size : 18px;
    position  : absolute;
    right     : 20px;
    top       : 50%;
    transform : translateY(-50%);
    transition: right .2s ease;
}
.btn-arrow:hover::after { right: calc(var(--btn-padding-x) - 4px); }

/* Classes utilitaires couleur/fond de la palette (color-N / bg-N) */
.color-1 { color: var(--color-1); } .bg-1 { background-color: var(--color-1); }
.color-2 { color: var(--color-2); } .bg-2 { background-color: var(--color-2); }
.color-3 { color: var(--color-3); } .bg-3 { background-color: var(--color-3); }
.color-4 { color: var(--color-4); } .bg-4 { background-color: var(--color-4); }
.color-5 { color: var(--color-5); } .bg-5 { background-color: var(--color-5); }
.color-6 { color: var(--color-6); } .bg-6 { background-color: var(--color-6); }

/* ---- BASE : body / liens / typo / helpers -------------------------------
   Consomme les vars pilotées par la config (--body-bg, --body-text) : c'est ce
   qui rend enfin ACTIF le réglage « Body » de admin/themes/configure. Les vars
   NON pilotées (muted, bg-light, fonts) sont définies ici (sûr, jamais écrasé). */
:root {
    --text-muted : #797979;
    --bg-light   : #FEF9EF;
    --bg-light-2 : #F1F4FA;
    --text-font  : var(--font-body, "Raleway", system-ui, sans-serif);
    --title-font : var(--font-heading, "Raleway", system-ui, sans-serif);
}
html { scroll-behavior: smooth; }
body {
    color                  : var(--body-text, #212529);
    background-color        : var(--body-bg, #ffffff);
    font-family            : var(--text-font);
    -webkit-font-smoothing : antialiased;
    -moz-osx-font-smoothing: grayscale;
    display                : flex;
    flex-direction         : column;
    min-height             : 100vh;
    /* `clip` (et NON `hidden`) : empêche le débordement horizontal SANS créer de
       conteneur de défilement. `overflow-x:hidden` forçait `overflow-y:auto`
       (règle CSS : un axe non-visible rend l'autre `auto`), ce qui faisait du
       <body> le scroller et CASSAIT `position:sticky` de la barre. clip corrige. */
    overflow-x             : clip;
}
h1, h2, h3 { font-family: var(--title-font); }
a:not(.btn) { color: var(--link-color, var(--body-text, #111827)); text-decoration: none; }
/* RGAA 10.6 : affordance non chromatique au survol/focus (soulignement restauré). */
a:not(.btn):hover, a:not(.btn):focus-visible { text-decoration: underline; }
/* RGAA 10.6 : dans le CONTENU rédactionnel, les liens insérés dans le texte doivent
   être distinguables au repos (pas seulement par la couleur) → soulignés. La nav,
   les cartes et les boutons restent sans soulignement (nature évidente par contexte). */
.module-detail__content a:not(.btn),
.module-detail__excerpt a:not(.btn),
.pages-detail__content a:not(.btn) { text-decoration: underline; }

/* Helpers texte / fond */
.text-color  { color: var(--body-text); }
.text-muted  { color: var(--text-muted); }
.bg-light    { background-color: var(--bg-light); }
.bg-light-1  { background-color: var(--bg-light); }
.text-justify { text-align: justify; }
/* Helpers layout */
.flex-center { display: flex; justify-content: center; align-items: center; }
.flex-group  { display: flex; flex-wrap: wrap; gap: 1rem; }
.center-y    { display: flex; flex-direction: column; justify-content: center; }
.pointer     { cursor: pointer; }
/* Ancres (élément « Ancre » du builder) : le défilement vers une ancre doit s'arrêter
   SOUS la navbar sticky, en tenant compte du bandeau promo s'il est épinglé
   (--promo-banner-h posé par menu.js : 0 si absent, sinon sa hauteur), + 20px de marge
   pour ne pas coller. `.builder-anchor-element` = classe réellement produite par le
   builder (l'ancre porte AUSSI `anchor` depuis builderSave). */
.anchor,
.builder-anchor-element { scroll-margin-top: calc(var(--menu-height-desktop, 84px) + var(--promo-banner-h, 0px) + 20px); }
@media (max-width: 991.98px) {
    .anchor,
    .builder-anchor-element { scroll-margin-top: calc(var(--menu-height-mobile, 72px) + var(--promo-banner-h, 0px) + 20px); }
}
/* Helpers image */
.img-fit     { object-fit: cover;   width: 100%; height: 100%; }
.img-contain { object-fit: contain; width: 100%; height: 100%; }

/* Chaine de hauteur pour `img-fit` / `img-contain`.

   `height: 100%` ne se resout que contre un parent de hauteur DEFINIE. La
   cellule en a une — c'est un flex-item de `.row`, etire par `align-items:
   stretch` — mais les emballages que le builder pose entre elle et l'image
   (BlockElement, div de bloc) sont en `height: auto`. Le pourcentage devenait
   indefini, retombait sur `auto`, et `object-fit` n'avait plus rien a recadrer :
   `img-fit` se comportait exactement comme `img-fluid`.

   `:has()` remonte a n'importe quelle profondeur : chaque div de la cellule qui
   contient l'image etiree recoit la hauteur, et la chaine redevient continue,
   quels que soient les blocs intercales aujourd'hui ou demain. La cellule
   elle-meme n'est pas visee (elle est deja etiree), ni aucun ancetre au-dessus.

   Sans effet si aucune colonne voisine n'est plus haute que l'image : il n'y a
   alors aucune hauteur a remplir, et c'est le comportement attendu.

   ANCRAGE : la COLONNE Bootstrap, pas `[builder-element="CellElement"]`. Le
   front retire les attributs `builder-element` au rendu — la regle ne
   s'appliquait donc que dans le canevas du builder, et pas sur le site. Les
   classes `col-*`, elles, survivent, et suffisent : une colonne est toujours un
   flex-item de `.row`, donc etiree, donc de hauteur definie. */
:where(.col, [class^="col-"], [class*=" col-"]) div:has(img.img-fit),
:where(.col, [class^="col-"], [class*=" col-"]) div:has(img.img-contain) { height: 100%; }

/* ---- Module Pages : fil d'Ariane, sous-pages, fiche contact ----------------

   Le module n'a AUCUNE feuille servie : ses styles vivaient sous
   modules/Pages/Assets/, hors de public/, donc introuvables par le navigateur
   (d'ou le commentaire « retires (non servis -> 404) » dans Pages.php). Le fil
   d'Ariane s'affichait en texte brut, colle sous le menu, sans separateurs.

   Regroupes ici plutot que dans un asset de module : la feuille du theme est
   deja chargee et minifiee, donc rien de plus a mettre en file ni a servir.

   FIL D'ARIANE : rien a redefinir. `.aw-breadcrumb` (plus bas, ~l.1545) porte
   deja la police, les separateurs, les liens et la marge haute de 1.5rem — la
   respiration sous le menu qui manquait a l'origine.

   Une seule chose a reparer : ce meme `.aw-breadcrumb` declare
   `margin: 1.5rem 0 1rem`, dont les zeros lateraux ECRASENT le `margin-inline:
   auto` de `.container` que porte aussi le <nav>. Resultat, il gardait sa
   largeur de 1140 px mais restait colle au bord gauche. On rend les marges
   auto, avec une specificite superieure (0,2,0) pour passer devant. */
.pages-breadcrumb.container { margin-inline: auto; }

.pages-children {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 1rem;
    margin: 1.5rem 0;
}
.pages-children .page-card {
    border: 1px solid var(--border-color, #e5e7eb);
    border-radius: 0.5rem;
    padding: 1rem;
    text-decoration: none;
    color: inherit;
    transition: box-shadow 0.15s ease;
}
.pages-children .page-card:hover { box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08); }
.pages-children .page-card i     { font-size: 1.5rem; margin-bottom: 0.5rem; }

.pages-contact dl {
    display: grid;
    grid-template-columns: max-content 1fr;
    gap: 0.25rem 1rem;
}
.pages-contact dt { font-weight: 600; }

/* ---- THEME LAYER : Nav / Footer / Cartes / boutons Bootstrap + utilitaires
   Consomme les vars pilotées par la config (Nav, Footer, Cards). Porté depuis
   themes/default/css/style.css (couche qui n'était pas dans le fichier servi →
   nav/footer/cartes utilisaient les défauts Bootstrap au lieu de tes réglages). */
:root {
    --bs-border-radius       : var(--card-radius, 8px);
    --bs-border-color        : var(--card-border, #e5e7eb);
}

/* Footer */
.site-footer { background: var(--footer-bg, #1a2130); color: var(--footer-text, #9ca3af); font-size: .875rem; }
.site-footer a       { color: var(--footer-text, #9ca3af); }

/* Cartes Bootstrap pilotées par la config */
.card { background: var(--card-bg, #fff); color: var(--card-text, #111827); border: var(--card-border-width, 1px) solid var(--card-border, #e5e7eb); border-radius: var(--card-radius, 8px); box-shadow: var(--card-shadow, 0 1px 4px rgba(0,0,0,.06)); }
.card-img-top { border-radius: var(--card-radius, 8px) var(--card-radius, 8px) 0 0; object-fit: cover; }

/* En-tête des modales & offcanvas piloté par la config (--panel-header-*) */
.modal-header, .offcanvas-header { background: var(--panel-header-bg, transparent); color: var(--panel-header-text, inherit); }
.modal-header .modal-title, .offcanvas-header .offcanvas-title { color: var(--panel-header-text, inherit); }
.modal-body, .offcanvas-body     { background: var(--panel-body-bg, transparent);   color: var(--panel-body-text, inherit); }
.modal-footer, .offcanvas-footer { background: var(--panel-footer-bg, transparent); color: var(--panel-footer-text, inherit); }
/* Bouton d'action (primary) dans une modale/offcanvas piloté par la config panneaux */
.modal-footer .btn-primary, .modal-body .btn-primary, .offcanvas-footer .btn-primary, .offcanvas-body .btn-primary {
    background-color: var(--panel-btn-bg, var(--btn-1-bg, var(--color-1, #2c7a6e)));
    border-color:     var(--panel-btn-bg, var(--btn-1-bg, var(--color-1, #2c7a6e)));
    color:            var(--panel-btn-text, #fff);
}
.modal-footer .btn-primary:hover, .modal-body .btn-primary:hover, .offcanvas-footer .btn-primary:hover, .offcanvas-body .btn-primary:hover {
    background-color: color-mix(in srgb, var(--panel-btn-bg, var(--btn-1-bg, var(--color-1, #2c7a6e))) 85%, #000);
    border-color:     color-mix(in srgb, var(--panel-btn-bg, var(--btn-1-bg, var(--color-1, #2c7a6e))) 85%, #000);
    color:            var(--panel-btn-text, #fff);
}
/* Bouton fermer : suit la couleur du texte d'en-tête (masque sur l'icône Bootstrap → visible sur fond clair ET foncé) */
.modal-header .btn-close, .offcanvas-header .btn-close {
    background-color: var(--panel-header-text, #000); background-image: none; opacity: 1;
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414z'/%3E%3C/svg%3E") center/1em auto no-repeat;
            mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414z'/%3E%3C/svg%3E") center/1em auto no-repeat;
}

/* Boutons Bootstrap principal/secondaire (compat + suivent la palette) */
.btn-primary { background-color: var(--btn-primary-bg, var(--color-1, #2c7a6e)); border-color: var(--btn-primary-bg, var(--color-1, #2c7a6e)); color: var(--btn-primary-text, #fff); }
.btn-primary:hover, .btn-primary:focus { background-color: var(--btn-primary-hover-bg, color-mix(in srgb, var(--btn-primary-bg, var(--color-1, #2c7a6e)) 85%, #000)); border-color: transparent; color: var(--btn-primary-text, #fff); }
.btn-secondary, .btn-outline-secondary { background-color: var(--btn-secondary-bg, #fff); border-color: var(--btn-secondary-border, var(--color-2, #2c7a6e)); color: var(--btn-secondary-text, var(--color-2, #2c7a6e)); }
.btn-secondary:hover, .btn-outline-secondary:hover { background-color: var(--btn-secondary-hover-bg, var(--color-2, #2c7a6e)); border-color: var(--btn-secondary-hover-bg, var(--color-2, #2c7a6e)); color: var(--btn-secondary-hover-text, #fff); }

/* Focus / pagination liés à la marque */
/* Champs de formulaire pilotés par la config « Champs de formulaire » (--form-*) */
.form-control, .form-select {
    background-color: var(--form-bg, #fff);
    color:           var(--form-color, #212529);
    border:          var(--form-border-width, 1px) solid var(--form-border-color, #ced4da);
    border-radius:   var(--form-radius, 4px);
}
.form-control:focus, .form-select:focus {
    background-color: var(--form-bg, #fff);
    color:           var(--form-color, #212529);
    border-color:    var(--form-focus-color, var(--color-1, #2c7a6e));
    box-shadow:      0 0 0 .2rem color-mix(in srgb, var(--form-focus-color, var(--color-1, #2c7a6e)) 22%, transparent);
}
.page-link { color: var(--color-1, #2c7a6e); }
.page-item.active .page-link { background-color: var(--color-1, #2c7a6e); border-color: var(--color-1, #2c7a6e); }

/* ---- Variantes OUTLINE des 6 boutons (contour → plein au survol) ---------
   Tailles : combine avec Bootstrap → class="btn btn-1 btn-lg" / "btn btn-outline-3 btn-sm". */
.btn-outline-1, .btn-outline-2, .btn-outline-3, .btn-outline-4, .btn-outline-5, .btn-outline-6 {
    background-color: transparent; border-style: solid; border-width: 1px;
    transition: background-color .18s ease, color .18s ease, border-color .18s ease;
}
.btn-outline-1 { color: var(--btn-1-bg, var(--color-1, #F8B11F)); border-color: var(--btn-1-bg, var(--color-1, #F8B11F)); }
.btn-outline-1:hover { background-color: var(--btn-1-bg-hover, var(--btn-1-bg, var(--color-1, #F8B11F))); color: var(--btn-1-color-hover, var(--btn-1-color, #212529)); }
.btn-outline-2 { color: var(--btn-2-bg, var(--color-2, #143F6F)); border-color: var(--btn-2-bg, var(--color-2, #143F6F)); }
.btn-outline-2:hover { background-color: var(--btn-2-bg-hover, var(--btn-2-bg, var(--color-2, #143F6F))); color: var(--btn-2-color-hover, var(--btn-2-color, #ffffff)); }
.btn-outline-3 { color: var(--btn-3-bg, var(--color-3, #EB5757)); border-color: var(--btn-3-bg, var(--color-3, #EB5757)); }
.btn-outline-3:hover { background-color: var(--btn-3-bg-hover, var(--btn-3-bg, var(--color-3, #EB5757))); color: var(--btn-3-color-hover, var(--btn-3-color, #ffffff)); }
.btn-outline-4 { color: #495057; border-color: var(--btn-4-bg, var(--color-4, #d0d5dd)); }
.btn-outline-4:hover { background-color: var(--btn-4-bg-hover, var(--btn-4-bg, var(--color-4, #ffffff))); color: var(--btn-4-color-hover, var(--btn-4-color, #212529)); }
.btn-outline-5 { color: var(--btn-5-bg, var(--color-5, #2B2E68)); border-color: var(--btn-5-bg, var(--color-5, #2B2E68)); }
.btn-outline-5:hover { background-color: var(--btn-5-bg-hover, var(--btn-5-bg, var(--color-5, #2B2E68))); color: var(--btn-5-color-hover, var(--btn-5-color, #ffffff)); }
.btn-outline-6 { color: var(--btn-6-bg, var(--color-6, #F4BD3D)); border-color: var(--btn-6-bg, var(--color-6, #F4BD3D)); }
.btn-outline-6:hover { background-color: var(--btn-6-bg-hover, var(--btn-6-bg, var(--color-6, #F4BD3D))); color: var(--btn-6-color-hover, var(--btn-6-color, #212529)); }

/* ---- Utilitaires sémantiques (couleurs config, sans comportement) -------- */
.bg-nav      { background-color: var(--nav-bg, #1a2130); }
.text-nav    { color:            var(--nav-text, #ffffff); }
.rounded-nav { border-radius:    var(--nav-radius, 0); }
.bg-footer   { background-color: var(--footer-bg, #1a2130); }
.text-footer { color:            var(--footer-text, #9ca3af); }
.bg-card     { background-color: var(--card-bg, #ffffff); }
.text-card   { color:            var(--card-text, #111827); }
.border-card { border-color:     var(--card-border, #e5e7eb); }
.shadow-card { box-shadow:       var(--card-shadow, 0 1px 4px rgba(0,0,0,.06)); }
.rounded-card{ border-radius:    var(--card-radius, 8px); }
.theme-card  { background: var(--card-bg, #fff); color: var(--card-text, #111827); border: var(--card-border-width, 1px) solid var(--card-border, #e5e7eb); border-radius: var(--card-radius, 8px); box-shadow: var(--card-shadow, 0 1px 4px rgba(0,0,0,.06)); }
.text-brand  { color: var(--color-1, #2c7a6e); }
.bg-brand    { background-color: var(--color-1, #2c7a6e); }
.rounded-theme { border-radius: var(--card-radius, 8px); }
.img-cover   { object-fit: cover; width: 100%; }
.theme-promo-banner { display: flex; align-items: center; justify-content: center; gap: .75rem; padding: .55rem 1rem; font-size: .875rem; font-weight: 500; text-align: center; }
.theme-promo-banner__viewport { max-width: 100%; overflow: hidden; }
.theme-promo-banner__track { display: flex; width: max-content; }
.theme-promo-banner__item { flex: 0 0 auto; white-space: nowrap; }
.theme-promo-banner__link { color: inherit; text-decoration: underline; text-underline-offset: .18em; }
.theme-promo-banner__link:hover, .theme-promo-banner__link:focus { color: inherit; }
/* Mode défilant. Posé par menu.js UNIQUEMENT quand le texte ne tient pas dans la largeur : un bandeau qui tient reste statique et centré. La piste contient N copies identiques et se translate d'exactement UNE copie (-100% / N), donc la copie suivante entre à droite à l'instant où la précédente sort à gauche — pas de temps mort. La distance parcourue ne dépend que de la largeur du texte, jamais de celle de l'écran : la vitesse de lecture est la même sur mobile et sur grand écran. */
.theme-promo-banner.is-marquee { justify-content: flex-start; }
.theme-promo-banner.is-marquee .theme-promo-banner__viewport { width: 100%; }
.theme-promo-banner.is-marquee .theme-promo-banner__item { padding-right: var(--promo-gap, 3rem); }
.theme-promo-banner.is-marquee .theme-promo-banner__track { animation: themePromoMarquee var(--promo-duration, 20s) linear infinite; will-change: transform; }
@keyframes themePromoMarquee { from { transform: translate3d(0, 0, 0); } to { transform: translate3d(calc(-100% / var(--promo-copies, 2)), 0, 0); } }
/* Survol, focus clavier et appui prolongé (tactile : .is-paused posé par menu.js) figent le défilement — indispensable pour lire, et pour viser le lien sans courir après. */
.theme-promo-banner.is-marquee:hover .theme-promo-banner__track,
.theme-promo-banner.is-marquee:focus-within .theme-promo-banner__track,
.theme-promo-banner.is-marquee.is-paused .theme-promo-banner__track { animation-play-state: paused; }
/* Mouvement réduit : aucune animation et aucune copie (menu.js n'en clone pas), la bande devient simplement défilable au doigt/à la molette. */
@media (prefers-reduced-motion: reduce) {
    .theme-promo-banner.is-marquee .theme-promo-banner__track { animation: none; }
    .theme-promo-banner.is-marquee .theme-promo-banner__viewport { overflow-x: auto; scrollbar-width: none; }
    .theme-promo-banner.is-marquee .theme-promo-banner__viewport::-webkit-scrollbar { display: none; }
    .theme-promo-banner.is-marquee .theme-promo-banner__item { padding-right: 0; }
}
/* Bandeau « site non public » (maintenance / construction) — visible du staff connecté, masqué au public. En flux normal (pas de position:sticky), placé au-dessus du bandeau promo. */
.site-status-bar { display: flex; align-items: center; justify-content: center; flex-wrap: wrap; gap: .5rem; padding: .5rem 1rem; font-size: .875rem; font-weight: 600; line-height: 1.4; text-align: center; color: #fff; box-shadow: 0 1px 4px rgba(0,0,0,.25); }
.site-status-bar--maintenance  { background: #b42318; }
.site-status-bar--construction { background: #b54708; }
.site-status-bar a { color: #fff; text-decoration: underline; white-space: nowrap; }
/* ===================== FIN DESIGN SYSTEM ================================= */


/* ==========================================================
   Styles front partagés de tous les modules
   Génériques : .module-*  (carte, grille, détail, pagination…)
   Wrapper de page par module : .{module}-index / .{module}-detail
     → ex. .module-index, .module-detail
   Surcharge ciblée par module possible via le wrapper :
     ex. .module-index .module-card__body { ... }
   ========================================================== */

/* ----------------------------------------------------------
   Layout générique avec sidebar
   ---------------------------------------------------------- */
.modules-layout {
    display: flex;
    gap: 2rem;
    align-items: flex-start;
}
/* Le sens est porté par l'ORDRE DOM (la vue place l'aside avant/après .modules-main
   selon left/right) : un flex-direction:row suffit pour les deux. NE PAS remettre
   row-reverse sur sidebar-right, sinon la sidebar repasse à gauche. */
.modules-layout--sidebar-left  { flex-direction: row; }
.modules-layout--sidebar-right { flex-direction: row; }
/* Pleine largeur (sans sidebar) : en colonne, align-items:flex-start (hérité)
   empêcherait .modules-main de s'étirer → stretch pour occuper toute la largeur. */
.modules-layout--full          { flex-direction: column; align-items: stretch; }

.modules-main    { flex: 1; min-width: 0; }
.modules-sidebar { width: 280px; flex-shrink: 0; }

@media (max-width: 991px) {
    .modules-layout--sidebar-left,
    .modules-layout--sidebar-right { flex-direction: column; }
    .modules-sidebar { width: 100%; }
}

/* Sidebar — arborescence de catégories (page liste, layout sidebar-*) */
.module-sidebar-cats { font-size: .95rem; }
.module-sidebar-cats__title {
    font-weight: 700; font-size: .8rem; text-transform: uppercase; letter-spacing: .04em;
    color: #6b7280; margin: 0 0 8px; padding-bottom: 6px; border-bottom: 1px solid rgba(0,0,0,.08);
}
.module-cat-tree, .module-cat-tree__children { list-style: none; margin: 0; padding: 0; }
.module-cat-tree__children { margin-left: 14px; border-left: 1px solid rgba(0,0,0,.08); padding-left: 10px; }
.module-cat-tree__children[hidden] { display: none; }
.module-cat-tree__row { display: flex; align-items: center; gap: 2px; }
.module-cat-tree__link {
    flex: 1; min-width: 0; display: block; padding: 6px 8px; border-radius: 7px;
    color: #334155; text-decoration: none; transition: background-color .12s, color .12s;
}
.module-cat-tree__link:hover { background: rgba(0,0,0,.05); }
.module-cat-tree__item.is-active > .module-cat-tree__row > .module-cat-tree__link {
    background: var(--btn-1-bg, var(--color-1, #0f172a));
    color: var(--btn-1-color, #fff); font-weight: 600;
}
/* Chevron d'accordéon (seulement pour les nœuds avec enfants) */
.module-cat-tree__toggle {
    flex: none; width: 28px; height: 28px; display: inline-flex; align-items: center; justify-content: center;
    border: 0; background: transparent; color: #6b7280; cursor: pointer; border-radius: 7px;
}
.module-cat-tree__toggle:hover { background: rgba(0,0,0,.06); color: #111827; }
.module-cat-tree__toggle i { transition: transform .18s ease; font-size: .8rem; }
.module-cat-tree__item.is-open > .module-cat-tree__row > .module-cat-tree__toggle i { transform: rotate(180deg); }

/* Barre d'outils de la liste : filtres à gauche, recherche à droite. */
.module-index-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; margin-bottom: 16px; }
.module-index-toolbar__filters { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; flex: 1 1 auto; min-width: 0; }
.module-index-toolbar__filters .module-wfilter { margin: 0; }
.module-index-search { flex: 0 0 auto; margin-left: auto; min-width: 240px; max-width: 340px; }
.module-index-search .input-group { margin: 0; }
@media (max-width: 640px) {
    .module-index-search { width: 100%; max-width: none; margin-left: 0; }
}

/* ----------------------------------------------------------
   Vue liste — générique (.module-*)
   Wrapper de page propre au module (ex. .module-index)
   ---------------------------------------------------------- */
/* .module-index n'impose plus de padding vertical : l'espacement de la page
   liste est laissé au gabarit (section / conteneur du builder). */

/* Grille de la page « toutes les catégories » (/{seg}/categories). */
.module-categories-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 22px; margin-top: 8px; }
.module-cat-card { display: flex; flex-direction: column; border: 1px solid var(--bs-border-color, #e6e9ef); border-radius: 12px; overflow: hidden; background: var(--bs-body-bg, #fff); transition: box-shadow .15s ease, transform .15s ease; }
.module-cat-card:hover { box-shadow: 0 8px 24px rgba(16,24,40,.10); transform: translateY(-2px); }
.module-cat-cover { display: block; aspect-ratio: 16 / 9; background: #f2f4f7; overflow: hidden; }
.module-cat-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
.module-cat-cover__ph { display: flex; align-items: center; justify-content: center; width: 100%; height: 100%; font-size: 2rem; color: #b4bcca; }
.module-cat-body { padding: 14px 16px 16px; }
.module-cat-title { font-size: 1.05rem; margin: 0; }
.module-cat-title a { color: inherit; text-decoration: none; }
.module-cat-title a:hover { text-decoration: underline; }
.module-cat-desc { margin: 8px 0 0; font-size: .9rem; line-height: 1.5; color: var(--bs-secondary-color, #6b7280); }
.module-cat-card--child { border-left: 3px solid var(--brand-color, var(--bs-primary, #2c7a6e)); }
.module-cat-more { display: inline-flex; align-items: center; gap: 6px; margin-top: 10px; font-size: .82rem; font-weight: 600; color: var(--brand-color, var(--bs-primary, #2c7a6e)); }
.module-cat-card:hover .module-cat-more i { transform: translateX(3px); transition: transform .15s ease; }
.module-cat-children { list-style: none; margin: 8px 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: 6px 10px; font-size: .85rem; }
.module-cat-children a { color: var(--bs-secondary-color, #6b7280); text-decoration: none; }
.module-cat-children a:hover { text-decoration: underline; }
.module-empty { padding: 2rem 0; color: var(--bs-secondary-color, #6b7280); }

/* Bannière de couverture (page liste + page catégorie) : PLEINE LARGEUR (bord à bord,
   sort du conteneur centré) et collée au menu. Le décalage négatif a disparu AVEC le
   padding-top de .module-index qu'il servait à annuler : le garder tirerait désormais
   la bannière de 2rem SOUS le menu, qu'elle recouvrirait. */
.module-index-cover {
    width: 100vw;
    max-width: 100vw;
    margin-left: calc(50% - 50vw);
    margin-right: calc(50% - 50vw);
    margin-bottom: 2rem;
    line-height: 0;           /* supprime l'espace inline sous l'<img> */
}
.module-index-cover picture { display: block; }
.module-index-cover img { width: 100%; height: auto; display: block; }

/* ─── Composant sans rien à rendre ──────────────────────────────────────────
   Un composant qui n'a rien à dire ne doit pas occuper de place.

   Le rendu ne remplace que l'INTÉRIEUR de `<div data-aw-comp="…">` : l'enveloppe
   survit avec ses styles. Un « Filtre par date » posé sur un module qui n'est pas
   en mode événement, ou un « Attributs » sur une publication qui n'en a aucun,
   laissaient donc un trou de 16 px (leur `padding:8px 0`) — invisible à l'écran,
   inexplicable pour qui a composé la page.

   `:empty` ne s'applique qu'aux éléments SANS enfant ni texte : le rendu injecte
   exactement '' dans ces cas, jamais un blanc. Le canevas de l'éditeur n'est pas
   concerné — ses composants contiennent toujours un aperçu `.aw-comp-ph`, donc ils
   restent sélectionnables et supprimables. */
.aw-composant:empty { display: none; }
/* La vignette d'une carte GARDE sa place même sans visuel : son aplat gris est
   ce qui aligne les titres d'une rangée quand seuls certains articles ont une
   image. Depuis qu'elle est un composant (interrupteur « Composant actif »),
   `.aw-composant:empty` la masquait — le filet qui retire un `<img src="">`
   vide l'enveloppe, et la carte perdait sa colonne image. Pour ne PAS afficher
   de vignette, on désactive le composant : c'est le geste explicite. */
.module-card__media.aw-composant:empty { display: block; }

/* Titre de section d'un composant (réglage commun du panneau). Il fait partie du
   composant : il le suit quand on le déplace et disparaît avec lui. */
.aw-composant__title { margin: 0 0 .6rem; }

/* Largeur de lecture (composant Contenu). 70 caractères : au-delà, l'œil perd le
   début de la ligne suivante. `ch` suit la police choisie, contrairement à une
   largeur en pixels qui redeviendrait fausse au premier changement de typo. */
.aw-composant--readable { max-width: 70ch; }

/* Alignement d'un composant (option « Alignement » du panneau). Le composant
   devient une colonne flex : ses blocs internes (barre de filtres, réseaux,
   puces…) ET le texte suivent l'alignement horizontal choisi. Opt-in — sans
   classe, le composant garde son affichage bloc habituel. */
.aw-composant--align-left,
.aw-composant--align-center,
.aw-composant--align-right { display: flex; flex-direction: column; }
.aw-composant--align-left   { align-items: flex-start; text-align: left; }
.aw-composant--align-center { align-items: center; text-align: center; }
.aw-composant--align-right  { align-items: flex-end; text-align: right; }

/* ─── Composant « Image de couverture » ───────────────────────────────────────
   Quatre formats (réglage « Format » du panneau) : image seule — rendue telle
   quelle, sans enveloppe, donc sans règle ici —, bannière (texte par-dessus),
   image puis texte, et côte à côte.

   L'image reste le <picture> du thème (srcset + LCP) : on ne la passe jamais en
   background-image, ce qui coûterait le responsive. En bannière elle est donc
   posée en couche de fond et recadrée par object-fit. */
.aw-cover { position: relative; }
.aw-cover__media img,
.aw-cover__media picture { display: block; width: 100%; height: auto; }
.aw-cover__title { margin: 0 0 .5rem; }
.aw-cover__intro { margin: 0; }
.aw-cover__intro > :last-child { margin-bottom: 0; }

/* Bannière : le texte se superpose. Le voile assure la lisibilité quelle que
   soit l'image — sans lui, un titre sombre sur une photo claire disparaît. */
.aw-cover--banner { display: flex; align-items: center; overflow: hidden; }
.aw-cover--banner .aw-cover__media {
    position: absolute; inset: 0; z-index: 0;
}
.aw-cover--banner .aw-cover__media img,
.aw-cover--banner .aw-cover__media picture,
.aw-cover--banner .aw-cover__media picture img {
    width: 100%; height: 100%; object-fit: cover;
}
.aw-cover--banner::after {
    content: ''; position: absolute; inset: 0; z-index: 1;
    background: linear-gradient(90deg, rgba(0, 0, 0, .55) 0%, rgba(0, 0, 0, .15) 70%, rgba(0, 0, 0, 0) 100%);
}
.aw-cover--banner .aw-cover__inner {
    position: relative; z-index: 2; width: 100%;
    padding: 2rem clamp(1rem, 4vw, 3rem); color: #fff;
}
.aw-cover--banner .aw-cover__title { color: inherit; }
/* Hauteurs : « auto » suit l'image (aucune contrainte), les deux autres fixent
   une hauteur et recadrent dedans. */
.aw-cover--h-md { min-height: 320px; }
.aw-cover--h-lg { min-height: 460px; }
.aw-cover--h-auto .aw-cover__media { position: relative; inset: auto; }
.aw-cover--h-auto .aw-cover__inner { position: absolute; inset: auto 0 0 0; }

/* Image, puis texte dessous. */
.aw-cover--below .aw-cover__inner { padding-top: 1.25rem; }

/* Côte à côte — empilé sous 768px, l'image d'abord. */
.aw-cover--side { display: grid; gap: clamp(1rem, 3vw, 2rem); align-items: center; }
@media (min-width: 768px) {
    .aw-cover--side { grid-template-columns: 1fr 1fr; }
}

/* Couverture absente : seul le texte reste, sans enveloppe décorative. */
.aw-cover--text { padding: 0; }

@media (max-width: 575.98px) {
    .aw-cover--h-md { min-height: 220px; }
    .aw-cover--h-lg { min-height: 300px; }
    .aw-cover--banner .aw-cover__inner { padding: 1.25rem 1rem; }
}

/* ─── Vidéo différée ─────────────────────────────────────────────────────────
   Le serveur ne rend qu'un bouton portant la vignette ; l'iframe est créée au
   clic (app.js). La façade occupe exactement la place du lecteur pour éviter le
   décalage de mise en page au remplacement. */
/* Catégorie en pastille (réglage du composant Catégorie). */
.module-cat { display: inline-flex; align-items: center; gap: .35rem; }
.module-cat--chip {
    padding: .2rem .7rem; border-radius: 999px; font-size: .82rem; line-height: 1.5;
    background: var(--color-primary, #f5a623); color: #fff;
}

.module-video--defer { position: relative; }
.module-video__facade {
    display: block; width: 100%; height: 100%; min-height: 200px; padding: 0;
    border: 0; border-radius: inherit; cursor: pointer;
    background: #1c2431 center / cover no-repeat;
}
.module-video__play {
    position: absolute; inset: 0; margin: auto;
    width: 68px; height: 68px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    background: rgba(0, 0, 0, .62); color: #fff; font-size: 1.4rem;
    transition: transform .15s, background .15s;
}
.module-video__facade:hover .module-video__play { transform: scale(1.08); background: rgba(0, 0, 0, .78); }
.module-video__facade:focus-visible { outline: 3px solid var(--color-primary, #f5a623); outline-offset: 3px; }

/* Sommaire construit depuis les titres du contenu (réglage « ancres »). */
.module-toc { margin: 0 0 1.5rem; padding: .9rem 1.1rem; border-left: 3px solid var(--color-primary, #f5a623); background: rgba(0, 0, 0, .025); border-radius: 0 6px 6px 0; }
.module-toc__list { margin: 0; padding: 0; list-style: none; }
.module-toc__item { margin: .2rem 0; }
.module-toc__item--h3 { padding-left: 1.1rem; }
.module-toc__item a { text-decoration: none; }
.module-toc__item a:hover { text-decoration: underline; }
/* Le titre visé ne doit pas se coller au bord haut sous une navigation fixe. */
.module-detail h2[id], .module-detail h3[id] { scroll-margin-top: 90px; }

/* ─── Visibilité par appareil ────────────────────────────────────────────────
   `data-hide-on` existait dans le balisage sans AUCUNE règle pour le lire : le
   réglage n'aurait rien fait. Les seuils reprennent ceux de Bootstrap (lg = 992,
   md = 768) pour que « masqué sur tablette » veuille dire la même chose ici et
   dans les grilles du builder. */
@media (max-width: 767.98px)  { [data-hide-on~="mobile"]  { display: none !important; } }
@media (min-width: 768px) and (max-width: 991.98px) { [data-hide-on~="tablet"] { display: none !important; } }
@media (min-width: 992px)     { [data-hide-on~="desktop"] { display: none !important; } }

/* Cover posée en COMPOSANT builder (`.aw-composant--cover`) : bannière pleine largeur,
   image fluide (jamais de débordement). Le helper ajoute déjà `img-fluid`, ceci force
   le rendu bloc pleine largeur du <picture>/<img> quel que soit le contexte. */
.aw-composant--cover { padding: 0 !important; }          /* JAMAIS de padding sur la cover */
.aw-composant--cover, .aw-composant--cover picture { display: block; }
.aw-composant--cover img { display: block; width: 100%; height: auto; }

/* En-tête SUPERPOSÉ sur la bannière (option Site internet › page d'accueil →
   m_blogs_website_display_header_style = overlay). Titre + accroche en bas de
   l'image, sur un dégradé sombre pour la lisibilité. */
.module-cover--overlay { position: relative; }
/* Bande de légende CENTRÉE VERTICALEMENT sur l'image : pleine largeur, SANS fond ni
   padding — c'est le conteneur interne (.container / .container-fluid) qui aligne le
   bloc sur le contenu de la page en dessous, selon le mode choisi. */
.module-cover--overlay .module-cover-caption {
    position: absolute; left: 0; right: 0; top: 50%; bottom: auto;
    transform: translateY(-50%);         /* centrage vertical par rapport à l'image */
    line-height: normal;                 /* annule le line-height:0 du cover */
}
/* Boîte COMPACTE : dimensionnée au contenu (jamais toute la hauteur ni toute la
   largeur), alignée à gauche, coins arrondis. */
.module-cover--overlay .module-cover-caption__box {
    display: inline-flex; flex-direction: column; align-items: flex-start; gap: .3rem;
    width: fit-content; max-width: min(100%, 680px);
    padding: .9rem 1.35rem;
    background: rgba(0, 0, 0, .55);
    border-radius: 16px;
    color: #fff; text-align: left;
}
.module-cover--overlay .module-cover-caption .module-title {
    color: #fff; text-shadow: 0 1px 3px rgba(0,0,0,.45); margin: 0;
}
.module-cover--overlay .module-cover-caption .module-tagline {
    color: rgba(255,255,255,.92); text-shadow: 0 1px 2px rgba(0,0,0,.45); margin: 0;
}
@media (max-width: 575.98px) {
    .module-cover--overlay .module-cover-caption__box { padding: .75rem 1rem; }
    .module-cover--overlay .module-cover-caption .module-title { font-size: 1.5rem; }
}

/* Composant « Bannière » (2ᵉ variante de cover, `.aw-composant--cover-hero`) : image de
   couverture en FOND, Titre + Accroche superposés dans une boîte stylable (réutilise
   `.module-cover--overlay`). `min-height` + fond gris = aperçu builder correct AVANT que
   {cover} ne soit résolu (pas encore d'image). L'image définit la hauteur au front. */
.aw-composant--cover-hero { position: relative; min-height: 200px; background: #e9edf3; overflow: hidden; }
.aw-composant--cover-hero .module-cover__media,
.aw-composant--cover-hero .module-cover__media picture { display: block; }
.aw-composant--cover-hero .module-cover__media img { display: block; width: 100%; height: auto; }

/* Bandeau de tête : titre, accroche, puis description d'intro — EMPILÉS.

   Il était en `justify-content: space-between`, hérité d'un temps où il ne
   portait que le titre à gauche et la recherche à droite (voir .module-search
   juste dessous, sorti du bandeau depuis). Avec trois enfants sur une rangée,
   l'accroche partait se coller au bord opposé du titre, à hauteur de H1, au
   lieu de se lire dessous — et la description passait seule à la ligne. */
.module-header { display: flex; flex-direction: column; align-items: flex-start; margin-bottom: 2rem; gap: .5rem; }
.module-title  { font-size: 2rem; font-weight: 700; margin: 0; }
.module-tagline { margin: 0; font-size: 1.125rem; color: #666; }

/* Descriptions riches d'intro et de bas de page (/admin/blogs/home).
   Largeur de lecture bornée : ce sont des paragraphes, pas de la grille, et
   une ligne pleine largeur d'écran se relit mal. */
.module-intro > :last-child,
.module-outro > :last-child { margin-bottom: 0; }
.module-outro { margin-top: 2.5rem; }
.module-search .input-group { width: min(320px, 100%); }
.module-search .form-control { border-color: #ddd; }
.module-search .form-control:focus { border-color: var(--color-primary, #f5a623); box-shadow: none; }
.module-search .btn {
    display: inline-flex; align-items: center; justify-content: center;
    border: 1px solid #ddd; border-left: 0; background: #fff; color: #333; line-height: 1;
    transition: background-color .15s ease, color .15s ease, border-color .15s ease;
}
.module-search .btn:hover { background: var(--color-primary, #f5a623); border-color: var(--color-primary, #f5a623); color: #fff; }
.module-search .btn i { font-size: 1rem; }
.module-empty  { text-align: center; padding: 3rem; color: #999; }
.module-search-label { font-style: italic; margin-bottom: 1rem; color: #666; }

/* ── Barre de recherche (composant ComposantElement) — structure BEM, DISTINCTE
   du .module-search (input-group Bootstrap) de la page liste : d'où le modifier. ── */
.module-search--component { display: flex; max-width: min(360px, 100%); }
.module-search__input { flex: 1 1 auto; min-width: 0; border: 1px solid #ddd; border-radius: 6px 0 0 6px; padding: .5rem .75rem; font: inherit; }
.module-search__input:focus { outline: 0; border-color: var(--color-primary, #f5a623); }
.module-search__btn { flex: 0 0 auto; border: 1px solid #ddd; border-left: 0; border-radius: 0 6px 6px 0; background: #fff; padding: 0 .9rem; cursor: pointer; color: #666; }
.module-search__btn:hover { background: var(--color-primary, #f5a623); border-color: var(--color-primary, #f5a623); color: #fff; }

/* ── Attributs en TABLEAU (format « Tableau » du composant Attributs) ── */
.module-attrs-table { width: 100%; border-collapse: collapse; margin: .5rem 0; }
.module-attrs-table th, .module-attrs-table td { padding: .35rem .6rem; border-bottom: 1px solid rgba(0, 0, 0, .08); text-align: left; vertical-align: top; }
.module-attrs-table__label { font-weight: 600; white-space: nowrap; color: #444; }

/* ── Menu de catégories (composant ComposantElement du builder de gabarits) ──
   Rendu par ModuleTemplateRenderer::renderCompCategories. layout = vertical
   (défaut) | horizontal | tree (arbre via parent_id) ; style = menu | chips. */
.module-cat-menu, .module-cat-menu__children { list-style: none; margin: 0; padding: 0; }
.module-cat-menu__item { margin: 0; }
.module-cat-menu__link { text-decoration: none; color: inherit; display: inline-block; padding: .2rem 0; }
.module-cat-menu__link:hover { color: var(--color-primary, #f5a623); }
/* Horizontale : items sur une ligne */
.module-cat-menu--horizontal { display: flex; flex-wrap: wrap; gap: .35rem 1.1rem; align-items: center; }
/* Arbre : sous-listes indentées avec un guide vertical */
.module-cat-menu--tree .module-cat-menu__children { margin-left: 1rem; padding-left: .75rem; border-left: 1px solid rgba(0, 0, 0, .08); }
/* Chips : liens en pastilles */
.module-cat-menu--chips .module-cat-menu__link { padding: .25rem .8rem; border: 1px solid rgba(0, 0, 0, .15); border-radius: 999px; line-height: 1.7; }
.module-cat-menu--chips .module-cat-menu__link:hover { border-color: var(--color-primary, #f5a623); }

/* ── Carte événement (gabarit « Carte événement ») : pastille de date + titre en
   overlay sur l'image. Le token {event_badge} rend .module-ev-badge (jour/n°/mois). ── */
.module-card--event .module-card__media { position: relative; overflow: hidden; }
.module-card__ev-badge { position: absolute; top: 12px; left: 12px; z-index: 2; }
.module-ev-badge {
    display: inline-flex; flex-direction: column; align-items: center; justify-content: center;
    min-width: 54px; padding: 6px 9px; border-radius: 10px; line-height: 1.05; text-align: center;
    background: var(--color-primary, #f5a623); color: #fff; box-shadow: 0 2px 8px rgba(0, 0, 0, .28);
}
.module-ev-badge__dow { font-size: .7rem; text-transform: uppercase; letter-spacing: .04em; opacity: .95; }
.module-ev-badge__day { font-size: 1.5rem; font-weight: 800; }
.module-ev-badge__month { font-size: .72rem; text-transform: uppercase; }
.module-card__title-overlay {
    position: absolute; left: 0; right: 0; bottom: 0; z-index: 2; display: block;
    padding: 2.2rem .9rem .7rem; text-decoration: none;
    background: linear-gradient(to top, rgba(0, 0, 0, .78), rgba(0, 0, 0, 0));
}
.module-card__title--overlay { margin: 0; color: #fff; font-size: 1.15rem; line-height: 1.25; text-shadow: 0 1px 3px rgba(0, 0, 0, .5); }
.module-card--event .module-card__body { padding-top: .6rem; }

/* ── Carte horizontale sans image : bandeau ; contenu à gauche, méta (date + lien)
   à droite, liseré d'accent à gauche. Empilé sur mobile. ── */
.module-card--hnoimg .module-card__body { display: flex; gap: 1.25rem; align-items: flex-start; padding: 1rem 1.25rem; border-left: 4px solid var(--color-primary, #f5a623); }
.module-card--hnoimg .module-card__main { flex: 1 1 auto; min-width: 0; }
.module-card--hnoimg .module-card__aside { flex: 0 0 auto; display: flex; flex-direction: column; gap: .5rem; align-items: flex-end; text-align: right; }
/* La date se loge en haut à droite, exactement sous le bouton ⋮ du pont
   front→back (position:absolute, top/right 8px, 34px de côté) : les derniers
   caractères de l'année passaient dessous. On ne réserve la gouttière que
   lorsque ce bouton est là — c'est-à-dire pour un administrateur connecté —
   pour ne rien retirer à la largeur vue par un visiteur. Rembourrage sur la
   seule date : le bouton « Lire la suite », lui, reste aligné au bord. */
.module-card--hnoimg:has(.aw-card-actions) .module-card__date { padding-right: 2.5rem; }
@media (max-width: 575px) {
    .module-card--hnoimg .module-card__body { flex-direction: column; }
    .module-card--hnoimg .module-card__aside { align-items: flex-start; text-align: left; }
}

/* ── Carte portrait : image de fond, titre posé dessus ── */
/* Dans un répéteur, `.aw-repeat-row > .col > .module-card { height:100% }` étire
   chaque carte à la hauteur de la rangée pour les aligner. Les autres cartes
   comblent avec leur corps ; ici le corps est en ABSOLU, donc rien ne comble :
   l'image restait à son ratio en haut et le dégradé+titre se retrouvaient collés
   au bas de la CARTE, seuls au milieu du blanc. L'image prend donc toute la
   hauteur disponible — le ratio ne gouverne plus que la carte NON étirée (carte
   seule, mosaïque), où le pourcentage retombe sur `auto`. */
.module-card--portrait .module-card__media { height: 100%; }
/* Un titre de cinq lignes mangeait la moitié de la photo : on le borne. */
.module-card--portrait .module-card__title {
    display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}

/* Carte documents sans pièce jointe : l'enveloppe reste dans le DOM (balisage
   constant) mais `{files}` ne rend rien — on retire la gouttière qu'elle laisse. */
.module-card__files-wrap:empty { display: none; }

/* Grilles */
/* Widgets de filtre front (recherche/date/catégorie/attribut) — chips génériques
   multi-module. Comportement délégué dans public/assets/js/app.js. */
.module-wfilter        { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 14px; }
.module-wchip          { border: 1px solid rgba(0,0,0,.15); background: #fff; color: #334155;
                         border-radius: 999px; padding: 5px 14px; font-size: 13px; line-height: 1.2;
                         cursor: pointer; transition: background .15s, color .15s, border-color .15s; }
.module-wchip:hover    { background: #f1f5f9; }
.module-wchip.active   { background: var(--btn-1-bg, var(--color-1, #0f172a));
    border-color: var(--btn-1-border-color, var(--btn-1-bg, var(--color-1, #0f172a)));
    color: var(--btn-1-color, #fff); }

.module-grid           { display: grid; gap: 1.5rem; }
.module-grid--cards    { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
.module-grid--grid     { grid-template-columns: repeat(3, 1fr); }
.module-grid--list     { grid-template-columns: 1fr; }
.module-grid--masonry  { columns: 3; column-gap: 1.5rem; }
.module-grid--masonry .module-card { break-inside: avoid; margin-bottom: 1.5rem; }

/* Cartes à HAUTEUR ÉGALE (grille CSS `.module-grid--cards/--list` + grille Bootstrap
   `.row.module-grid--grid`) : la carte remplit sa cellule (étirement natif en grille
   CSS ; motif h-100 en .row Bootstrap), le corps s'étend, « Lire la suite » calé en
   bas. Exclut le masonry (colonnes). */
.module-grid:not(.module-grid--masonry) > .module-card,
.module-grid--grid > [class*="col"] > .module-card { height: 100%; }
.module-grid:not(.module-grid--masonry) .module-card,
.module-grid--grid .module-card { display: flex; flex-direction: column; }
.module-grid:not(.module-grid--masonry) .module-card__body,
.module-grid--grid .module-card__body { display: flex; flex-direction: column; flex: 1 1 auto; }
.module-grid:not(.module-grid--masonry) .module-card__more,
.module-grid--grid .module-card__more { margin-top: auto; align-self: flex-start; }

/* CARROUSEL de cartes (<aw-carousel class="module-grid--carousel">) : cartes à la
   MÊME HAUTEUR. awcarousel met `align-items:flex-start` sur la piste (.awc-wrapper)
   → on force `stretch` pour cette grille, et la carte remplit son slide. La carte
   n'est PAS enfant direct du .module-grid (elle est dans <aw-slide>), d'où ces règles
   dédiées en plus de celles ci-dessus. */
.module-grid--carousel .awc-wrapper { align-items: stretch; }
.module-grid--carousel aw-slide.awc-slide { display: flex; height: auto; }
.module-grid--carousel aw-slide .module-card { height: 100%; width: 100%; display: flex; flex-direction: column; }
.module-grid--carousel aw-slide .module-card__body { display: flex; flex-direction: column; flex: 1 1 auto; }
.module-grid--carousel aw-slide .module-card__more { margin-top: auto; align-self: flex-start; }

/* Cartes à HAUTEUR ÉGALE dans le RÉPÉTEUR du builder (`.row.aw-repeat-row`) — le
   répéteur n'utilise pas la classe `.module-grid`, d'où ces règles dédiées, calquées
   sur `.module-grid--grid` : la colonne Bootstrap s'étire (align-items:stretch natif),
   la carte la remplit (h-100), le corps s'étend et « Lire la suite » se cale en bas.
   Vaut pour tous les gabarits (standard / événement / carousel-en-grille…). Les cartes
   horizontales sans image conservent leur corps EN LIGNE (on ne force pas la colonne). */
.aw-repeat-row > [class*="col"] { display: flex; }
.aw-repeat-row > [class*="col"] > .module-card { height: 100%; width: 100%; }

/* Cartes HORS ÉCRAN : on saute leur mise en page tant qu'elles ne sont pas
   approchées du viewport. Une liste de 8 cartes fait ~4 500 px de document pour
   un écran de 823 px : l'essentiel n'est jamais regardé au chargement, et le
   navigateur le calculait quand même. Mesuré sur /fr/agenda : recalcul de style
   −61 %, mise en page −50 %. Cible « Style & Layout », premier poste du TBT.
   `contain-intrinsic-size: auto 420px` donne une hauteur PRÉSUMÉE tant qu'une
   carte n'a jamais été rendue ; le mot-clé `auto` fait ensuite mémoriser sa
   hauteur réelle — l'estimation ne sert donc qu'une fois, et seulement pour la
   longueur de la barre de défilement (aucun contenu visible ne bouge).
   Le confinement de peinture ne rogne rien : menu « … », badge date et titre en
   surimpression tiennent tous DANS la colonne (vérifié au rendu). */
.aw-repeat-row > [class*="col"] { content-visibility: auto; contain-intrinsic-size: auto 420px; }
.aw-repeat-row .module-card:not(.module-card--hnoimg):not(.module-card--horizontal) { display: flex; flex-direction: column; }
.aw-repeat-row .module-card:not(.module-card--hnoimg):not(.module-card--horizontal) .module-card__body { display: flex; flex-direction: column; flex: 1 1 auto; }
.aw-repeat-row .module-card:not(.module-card--hnoimg):not(.module-card--horizontal) .module-card__more { margin-top: auto; align-self: flex-start; }
.aw-repeat-row .module-card--hnoimg { display: flex; flex-direction: column; }
.aw-repeat-row .module-card--hnoimg .module-card__body { flex: 1 1 auto; }
/* Carte HORIZONTALE : image à GAUCHE, TOUT le texte à DROITE (flex row, jamais column).
   Le corps s'empile en colonne à droite, « Lire la suite » calé en bas. */
.aw-repeat-row .module-card--horizontal { display: flex; flex-direction: row; align-items: stretch; }
.aw-repeat-row .module-card--horizontal .module-card__body { display: flex; flex-direction: column; flex: 1 1 auto; min-width: 0; }
.aw-repeat-row .module-card--horizontal .module-card__more { margin-top: auto; align-self: flex-start; }

/* Mode LISTE : carte HORIZONTALE (image à gauche, contenu à droite), pleine largeur.
   ⚠️ Spécificité `.module-grid.module-grid--list` (0,3,0) pour battre la règle de
   hauteur égale `.module-grid:not(.module-grid--masonry) .module-card` (0,3,0 aussi,
   mais placée AVANT → celle-ci gagne car plus loin dans le fichier). */
.module-grid.module-grid--list .module-card { flex-direction: row; align-items: stretch; }
.module-grid.module-grid--list .module-card__media {
    flex: 0 0 38%;
    max-width: 38%;
    aspect-ratio: auto;      /* la hauteur vient de l'étirement flex (align-items:stretch) */
    align-self: stretch;
}
.module-grid.module-grid--list .module-card__body { flex: 1 1 auto; }
@media (max-width: 575.98px) {
    /* Repli mobile : on repasse en carte verticale classique. */
    .module-grid.module-grid--list .module-card { flex-direction: column; }
    .module-grid.module-grid--list .module-card__media { flex-basis: auto; max-width: none; aspect-ratio: 16 / 9; }
}

/* ── Cartes de module « composées » (.module-card--composed) — layout structurel.
   Déplacé depuis le <style> inline de _card_composed.php (statique, aucune valeur par
   instance) → mis en cache ici avec le reste du thème plutôt que ré-injecté au front. */
/* flex-direction: row !important — la carte composée est une grille de blocs en
   flex-wrap ; sa direction est intrinsèque. Sans ça, .module-grid--grid .module-card
   (et carrousel) du thème force flex-direction:column (spécificité supérieure) → les
   blocs « Pleine » (flex-basis:100%) prennent 100% de la HAUTEUR et s'empilent en
   colonnes horizontales au lieu de lignes. */
.module-card--composed { display: flex; flex-direction: row !important; flex-wrap: wrap; align-items: flex-start; overflow: hidden; position: relative; }
.module-card__col { box-sizing: border-box; flex: 0 0 100%; max-width: 100%; }
.module-card__col--12 { flex-basis: 100%; max-width: 100%; }
.module-card__col--6 { flex-basis: 50%; max-width: 50%; }
.module-card__col--4 { flex-basis: 33.3333%; max-width: 33.3333%; }
.module-card__col--3 { flex-basis: 25%; max-width: 25%; }
.module-card__col--media { padding: 0; }
.module-card--composed .module-card__media { display: block; }
.module-card--composed .module-card__media img { width: 100%; height: auto; display: block; }
.module-card--composed .module-card__el { padding: .4rem 1rem; }
/* Ligne conteneur (bloc « row ») : enfants en flex sur une même ligne. */
.module-card--composed .module-card__row { display: flex; flex-wrap: wrap; gap: .35rem 1rem; align-items: baseline; padding: .4rem 1rem; }
.module-card--composed .module-card__row .module-card__el { padding: 0; }
/* Champ posé SUR l'image : conteneur relatif + overlay absolu en pastille. */
.module-card__media--wrap { position: relative; display: block; }
.module-card__overlay { position: absolute; z-index: 2; display: flex; flex-wrap: wrap; gap: 6px; max-width: calc(100% - 16px); }
.module-card__overlay--tl { top: 8px; left: 8px; }
.module-card__overlay--tr { top: 8px; right: 8px; justify-content: flex-end; }
.module-card__overlay--bl { bottom: 8px; left: 8px; }
.module-card__overlay--br { bottom: 8px; right: 8px; justify-content: flex-end; }
/* Brique posée sur l'image = pastille sombre lisible (champs fixes ET attr:/cf:). */
.module-card__overlay .module-card__el { background: rgba(0,0,0,.6); color: #fff; padding: 3px 10px; border-radius: 999px; font-size: .72rem; line-height: 1.35; }
.module-card__overlay .module-card__el a { color: #fff; }
.module-card__overlay .module-attrs { display: flex; flex-wrap: wrap; gap: 6px; margin: 0; }
.module-card__overlay .module-attr { display: flex; gap: 4px; margin: 0; }
.module-card__overlay .module-attr__label, .module-card__overlay .module-attr__value { color: #fff; margin: 0; }
.module-card__overlay .module-card__tags { display: flex; gap: 5px; }
.module-card__overlay .module-card__tag { background: transparent; border: 0; padding: 0; color: #fff; }

/* Carte composée en mode LISTE : la composition reste la même, mais sa disposition
   s'adapte au gabarit → image à gauche (pleine hauteur), autres blocs empilés à droite,
   comme la carte code. Grille 2 colonnes appliquée SEULEMENT s'il y a une image
   (:has) ; sans image → la carte reste en pleine largeur (flex empilé). */
.module-grid--list .module-card--composed:has(> .module-card__col--media) {
    display: grid;
    grid-template-columns: clamp(120px, 26%, 200px) 1fr;  /* colonne image plus étroite → texte resserré */
    align-items: start;                                    /* image alignée en haut, non étirée */
    column-gap: 1rem;                                      /* petit écart image ↔ texte */
}
.module-grid--list .module-card--composed:has(> .module-card__col--media) > .module-card__col--media {
    grid-column: 1;
    grid-row: 1 / span 99;   /* réserve la colonne gauche pour l'image sur toute la hauteur */
    align-self: stretch;     /* la colonne image occupe toute la hauteur de la carte */
}
/* Le thème bride .module-card__media à 38% en liste (règle pour la carte CODE). Dans
   la carte COMPOSÉE c'est la colonne de grille qui gère la taille → on lève la contrainte
   ET on fait remplir toute la colonne (largeur + hauteur) pour un rendu vignette plein. */
.module-grid--list .module-card--composed:has(> .module-card__col--media) .module-card__media,
.module-grid--list .module-card--composed:has(> .module-card__col--media) .module-card__media--wrap {
    flex: initial;
    max-width: 100%;
    width: 100%;
    height: 100%;
}
.module-grid--list .module-card--composed:has(> .module-card__col--media) > .module-card__col--media img {
    width: 100%;
    height: 100%;
    object-fit: cover;       /* remplit toute la colonne (léger recadrage assumé) */
}
.module-grid--list .module-card--composed:has(> .module-card__col--media) > .module-card__col:not(.module-card__col--media) {
    grid-column: 2;   /* tous les autres blocs empilés dans la colonne de droite */
    min-width: 0;
}

/* ── Menu d'actions de carte PARTAGÉ (.aw-card-actions) : composant uniforme entre
   modules (Blogs, …). Aligné visuellement sur le composant Shops `.shops-card-actions`
   (modules/Shops). Bouton « ⋮ » qui déplie Favori/Partage au survol / focus / clic
   (.is-open posé par app.js). Le module Shops garde son propre composant + extras
   (liste d'envie, alerte stock). ── */
.module-card { position: relative; }
.aw-card-actions { position: absolute; top: 8px; right: 8px; z-index: 6; display: flex; flex-direction: column; align-items: flex-end; gap: 6px; }
.aw-card-action { width: 34px; height: 34px; padding: 0; border-radius: 50%; border: 0; background: rgba(255,255,255,.92); color: #333; display: flex; align-items: center; justify-content: center; cursor: pointer; box-shadow: 0 2px 6px rgba(0,0,0,.15); transition: transform .12s, background .12s, color .12s; font-size: .9rem; line-height: 1; }
.aw-card-action:hover { transform: scale(1.08); background: #fff; }
.aw-card-action.is-active { background: #e11d48; color: #fff; }
.aw-card-action:disabled { opacity: .6; cursor: default; }
.aw-card-actions__menu { display: flex; flex-direction: column; align-items: flex-end; gap: 6px; margin-top: 6px; opacity: 0; visibility: hidden; transform: translateY(-8px); pointer-events: none; transition: opacity .18s ease, transform .18s ease, visibility .18s; }
.aw-card-actions:hover .aw-card-actions__menu,
.aw-card-actions:focus-within .aw-card-actions__menu,
.aw-card-actions.is-open .aw-card-actions__menu { opacity: 1; visibility: visible; transform: translateY(0); pointer-events: auto; }
.aw-card-actions:hover .aw-card-toggle,
.aw-card-actions.is-open .aw-card-toggle { background: #111; color: #fff; }

/* Carte */
/* Connecté à la config « Cards » (--card-*) — plus de valeurs codées en dur. */
.module-card { background: var(--card-bg, #fff); color: var(--card-text, inherit); border: var(--card-border-width, 1px) solid var(--card-border, transparent); border-radius: var(--card-radius, 8px); box-shadow: var(--card-shadow, 0 2px 8px rgba(0,0,0,.08)); overflow: hidden; transition: transform .2s, box-shadow .2s, border-color .2s; }
.module-card:hover { transform: translateY(-2px); box-shadow: var(--card-shadow, 0 4px 16px rgba(0,0,0,.12)); filter: brightness(.99); }
.module-card__color   { height: 4px; }
.module-card__media   { display: block; aspect-ratio: var(--module-img-ratio, 16 / 9); overflow: hidden; background: #f0f0f0; }
.module-card__media img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .3s; }

/* Repli image manquante/cassée — placeholder DISCRET (fond gris clair + icône image).
   Le ::after d'un <img> ne se rend QUE lorsque l'image ne charge pas (src vide ou 404) ;
   une image chargée le recouvre → invisible quand tout va bien. `color:transparent`
   masque l'éventuel texte alt affiché par le navigateur derrière le placeholder. */
.module-card__img, .module-card__media img { position: relative; color: transparent; }
.module-card__img::after, .module-card__media img::after {
    content: ""; position: absolute; inset: 0; border-radius: inherit;
    background: #f1f3f5 url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='48' height='48' viewBox='0 0 24 24' fill='none' stroke='%23b8bfc9' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='3' width='18' height='18' rx='2'/%3E%3Ccircle cx='9' cy='9' r='1.6'/%3E%3Cpath d='M21 15l-4.5-4.5L6 21'/%3E%3C/svg%3E") center / 44px no-repeat;
}
.module-card:hover .module-card__media img { transform: scale(1.04); }
.module-card__body    { padding: 1.25rem; }
.module-card__date    { font-size: .8rem; color: #6c757d; /* >= 4.5:1 sur fond blanc (AA) */ display: block; margin-bottom: .4rem; }
.module-card__title   { font-size: 1.1rem; font-weight: 600; margin-bottom: .6rem; line-height: 1.4; }
.module-card__title a { color: inherit; text-decoration: none; }
.module-card__title a:hover { color: var(--brand-color, var(--bs-primary, #0d6efd)); }
.module-card__excerpt { font-size: .9rem; color: #555; margin-bottom: 1rem; line-height: 1.5; }
.module-card__more    { font-size: .85rem; font-weight: 600; color: var(--brand-color, var(--bs-primary, #0d6efd)); text-decoration: none; }
.module-card__more:hover { text-decoration: underline; }

/* Pagination */
/* Le wrap est injecté DANS la grille de cartes (.row.row-cols-*) juste après les
   cartes : sans largeur pleine il se place comme une colonne À CÔTÉ des cartes.
   flex-basis:100% le pousse sur sa propre ligne, en pleine largeur, sous les cartes. */
.module-pagination-wrap { flex: 0 0 100%; width: 100%; }
.module-pagination { display: flex; gap: .35rem; justify-content: center; align-items: center; margin-top: 2rem; flex-wrap: wrap; }
.module-pagination__item { display: inline-flex; align-items: center; justify-content: center; min-width: 2.35rem; height: 2.35rem; padding: 0 .5rem; border: 1px solid #e4e4e7; border-radius: 8px; background: #fff; text-decoration: none; color: #3f3f46; font-size: .9rem; font-weight: 500; line-height: 1; transition: background .15s, border-color .15s, color .15s; }
.module-pagination__item:hover:not(.active):not(.is-disabled) { border-color: var(--color-1, var(--brand-color, var(--bs-primary, #0d6efd))); color: var(--color-1, var(--brand-color, var(--bs-primary, #0d6efd))); }
.module-pagination__item.active { background: var(--color-1, var(--brand-color, var(--bs-primary, #0d6efd))); color: #fff; border-color: var(--color-1, var(--brand-color, var(--bs-primary, #0d6efd))); cursor: default; }
.module-pagination__item.is-disabled { opacity: .4; pointer-events: none; }
.module-pagination__ellipsis { display: inline-flex; align-items: flex-end; padding: 0 .15rem; color: #a1a1aa; }
/* Mode « Précédent / Suivant » : deux boutons libellés encadrant le repère de position. Les boutons gardent la pastille commune (.module-pagination__item) mais s'élargissent pour accueillir du texte traduit, dont la longueur varie d'une langue à l'autre. */
.module-pagination--prevnext { gap: .75rem; justify-content: space-between; max-width: 40rem; margin-left: auto; margin-right: auto; }
.module-pagination--prevnext .module-pagination__item { min-width: 0; gap: .4rem; padding: 0 1rem; }
.module-pagination__arrow { font-size: 1.15em; line-height: 1; }
.module-pagination__status { color: #71717a; font-size: .85rem; font-variant-numeric: tabular-nums; text-align: center; white-space: nowrap; }
/* Sous 480 px, un libellé long ferait déborder la rangée : les deux boutons passent en pleine largeur et le repère se place entre eux, plutôt que de tronquer le texte. */
@media (max-width: 480px) {
    .module-pagination--prevnext { flex-direction: column; gap: .5rem; }
    .module-pagination--prevnext .module-pagination__item { width: 100%; }
}

/* Layout avec sidebar — grille adaptée */
.modules-layout--sidebar-left  .module-grid--cards,
.modules-layout--sidebar-right .module-grid--cards { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
.modules-layout--sidebar-left  .module-grid--grid,
.modules-layout--sidebar-right .module-grid--grid  { grid-template-columns: repeat(2, 1fr); }
.modules-layout--sidebar-left  .module-grid--masonry,
.modules-layout--sidebar-right .module-grid--masonry { columns: 2; }

/* ----------------------------------------------------------
   Vue détail — générique (.module-detail__*)
   Wrapper de page propre au module (ex. .module-detail)
   ---------------------------------------------------------- */
.module-detail { max-width: 800px; margin: 0 auto; padding: 2rem 0; }

/* Bannière « En-tête de page » de l'article : sort de la colonne centrée 800px →
   PLEINE LARGEUR (bord à bord) et COLLÉE AU MENU (annule le padding-top de .module-detail). */
/* Bannière à bord perdu. `100vw` INCLUT la largeur de la barre de défilement :
   sur une fenêtre de 1440 px dont 15 sont pris par la barre, la bannière fait
   1440 pour 1425 disponibles, et la page défile de 15 px latéralement.
   `--largeur-fenetre` est posée par app.js à partir de `clientWidth`, qui lui
   exclut la barre ; le repli sur 100vw garde l ancien comportement si le
   script ne s exécute pas. */
.module-detail-banner {
    width: var(--largeur-fenetre, 100vw);
    max-width: var(--largeur-fenetre, 100vw);
    margin-left: calc(50% - var(--largeur-fenetre, 100vw) / 2);
    margin-right: calc(50% - var(--largeur-fenetre, 100vw) / 2);
    margin-top: -2rem;
    margin-bottom: 2rem;
    line-height: 0;
}
.module-detail-banner picture { display: block; }
.module-detail-banner img { width: 100%; height: auto; display: block; }

.module-detail__header { margin-bottom: 2rem; }
.module-detail__category { font-size: .8rem; font-weight: 700; text-transform: uppercase; letter-spacing: .1em; color: var(--brand-color, var(--bs-primary, #0d6efd)); }
.module-detail__title { font-size: 2.2rem; font-weight: 700; margin: .5rem 0; line-height: 1.3; }
.module-detail__meta { font-size: .9rem; color: #888; margin-bottom: 1rem; }
.module-detail__excerpt { font-size: 1.1rem; color: #555; font-style: italic; }
.module-detail__cover { margin: 1.5rem 0; border-radius: 8px; overflow: hidden; }
.module-detail__cover img { width: 100%; height: auto; display: block; }
/* Carrousel d'images du détail (awcarousel) — plusieurs images « m_blogs_img ». */
.module-detail__cover--carousel { overflow: visible; }
.module-detail__carousel { display: block; border-radius: 8px; overflow: hidden; }
.module-detail__carousel aw-slide { display: block; }
.module-detail__carousel img { width: 100%; height: auto; display: block; }
/* Galerie détail rendue par le COMPOSANT builder (.aw-composant--gallery) : awcarousel
   égalise la hauteur des slides → sans object-fit l'<img> par défaut (fill) s'étire.
   Scopé au composant pour ne PAS modifier le rendu natif (_detail_body). */
.aw-composant--gallery .module-detail__carousel img { object-fit: cover; }
.module-detail__content { line-height: 1.8; font-size: 1rem; color: #333; }
.module-detail__content img { max-width: 100%; height: auto; border-radius: 4px; }
.module-detail__video { position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; margin: 2rem 0; border-radius: 8px; }
.module-detail__video iframe { position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: 0; }
.module-detail__contact { background: #f8f9fa; padding: 1.25rem; border-radius: 8px; margin: 2rem 0; }
.module-detail__contact p { margin: .3rem 0; }
.module-detail__socials { display: flex; gap: 1rem; margin: 1.5rem 0; flex-wrap: wrap; }
.module-detail__socials a { font-size: .85rem; font-weight: 600; text-decoration: none; padding: .3rem .8rem; border-radius: 4px; background: #f0f0f0; color: #333; }
.module-detail__nav { display: flex; justify-content: space-between; margin-top: 3rem; padding-top: 1.5rem; border-top: 1px solid #eee; gap: 1rem; flex-wrap: wrap; }
.module-detail__nav a { text-decoration: none; color: var(--brand-color, var(--bs-primary, #0d6efd)); font-size: .9rem; max-width: 45%; }
.module-detail__nav-next { text-align: right; }
.module-detail__faqs { margin: 2rem 0; }
.module-detail__faqs h2 { font-size: 1.4rem; margin-bottom: 1rem; }
.module-faq-item { border: 1px solid #e5e7eb; border-radius: 6px; margin-bottom: .5rem; }
.module-faq-item summary { padding: 1rem; font-weight: 600; cursor: pointer; list-style: none; }
.module-faq-item summary::before { content: '+ '; color: var(--brand-color, var(--bs-primary, #0d6efd)); }
.module-faq-item[open] summary::before { content: '− '; }
.module-faq-item p { padding: 0 1rem 1rem; color: #555; line-height: 1.6; margin: 0; }

/* Documents rattachés (PDF, fichiers…) */
.module-detail__documents { margin: 2rem 0; }
.module-detail__documents-title { font-size: 1.4rem; margin-bottom: 1rem; }
.module-detail__documents-list { list-style: none; margin: 0; padding: 0; display: grid; gap: .5rem; }
.module-detail__document { display: flex; align-items: center; gap: .25rem; border: 1px solid #e5e7eb; border-radius: 8px; background: #fff; transition: border-color .15s, box-shadow .15s; }
.module-detail__document:hover { border-color: var(--brand-color, var(--bs-primary, #0d6efd)); box-shadow: 0 1px 6px rgba(0,0,0,.06); }
.module-detail__document-link { flex: 1 1 auto; display: flex; align-items: center; gap: .75rem; padding: .75rem 1rem; text-decoration: none; color: #222; min-width: 0; }
.module-detail__document-link > i { font-size: 1.4rem; color: var(--brand-color, var(--bs-primary, #0d6efd)); flex-shrink: 0; }
.module-detail__document-name { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.module-detail__document-meta { margin-left: auto; padding-left: 1rem; font-size: .8rem; color: #888; white-space: nowrap; flex-shrink: 0; }
.module-detail__document-dl { display: flex; align-items: center; justify-content: center; width: 44px; align-self: stretch; border-left: 1px solid #eee; color: #555; text-decoration: none; border-radius: 0 8px 8px 0; }
.module-detail__document-dl:hover { background: #f6f7f9; color: var(--brand-color, var(--bs-primary, #0d6efd)); }

/* ----------------------------------------------------------
   Vue détail — TEMPLATES d'affichage (.module-detail--*)
   Choix résolu côté serveur : publication (P1) > catégorie (P2) > module (P3).
   Chaque variante réutilise les mêmes blocs .module-detail__*.
   ---------------------------------------------------------- */

/* — basic : colonne centrée classique (= comportement par défaut) — */
.module-detail--basic { max-width: 800px; }

/* Hero + Deux colonnes : l'image de couverture doit être TOUT EN HAUT → on annule le
   padding-top de .module-detail (sinon 2rem de vide au-dessus de l'image). Dans ces
   gabarits, la bannière ne doit plus remonter (padding déjà nul). */
.module-detail--hero,
.module-detail--split { padding-top: 0; }
.module-detail--hero > .module-detail-banner,
.module-detail--split > .module-detail-banner { margin-top: 0; }

/* — hero : couverture pleine largeur en bannière, en-tête en carte flottante — */
.module-detail--hero { max-width: 1080px; display: flex; flex-direction: column; }
.module-detail--hero .module-detail__cover { order: -1; margin: 0; border-radius: 0 0 18px 18px; }
.module-detail--hero .module-detail__cover img { max-height: 520px; object-fit: cover; }
.module-detail--hero .module-detail__header { max-width: 780px; margin: -5rem auto 2.25rem; background: var(--bs-body-bg, #fff); padding: 1.75rem 2rem; border-radius: 16px; box-shadow: 0 12px 40px rgba(16,24,40,.14); text-align: center; position: relative; z-index: 2; }
.module-detail--hero .module-detail__title { font-size: 2.6rem; }
.module-detail--hero > *:not(.module-detail__cover):not(.module-detail__header) { width: 100%; max-width: 780px; margin-left: auto; margin-right: auto; }

/* — split : couverture et en-tête côte à côte, puis contenu pleine largeur — */
.module-detail--split { max-width: 1140px; display: grid; grid-template-columns: 1fr 1fr; gap: 2.5rem; align-items: center; }
.module-detail--split > * { grid-column: 1 / -1; }
.module-detail--split .module-detail__cover { grid-column: 1; grid-row: 1; margin: 0; height: 100%; }
.module-detail--split .module-detail__cover img { height: 100%; object-fit: cover; }
.module-detail--split .module-detail__header { grid-column: 2; grid-row: 1; margin: 0; }

/* — full_sidebar : 1) image de couverture EN PREMIER (pleine largeur, tout en haut),
     2) EN DESSOUS le contenu principal à gauche + la sidebar (contact/réseaux/docs) à droite — */
.module-detail--full_sidebar { max-width: 1160px; display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: .5rem 2.5rem; align-items: start; }

/* 1) Bannière pleine largeur ; image de couverture EN PREMIER mais à la MÊME LARGEUR
      que le titre (colonne de gauche), pas sur toute la largeur. */
.module-detail--full_sidebar .module-detail-banner { grid-column: 1 / -1; order: -2; }
.module-detail--full_sidebar .module-detail__cover  { grid-column: 1; order: -1; margin: 0 0 1.5rem; }

/* 2a) Contenu principal à GAUCHE (titre, dates, corps, vidéo, FAQ…) */
.module-detail--full_sidebar .module-detail__header,
.module-detail--full_sidebar .module-detail__events,
.module-detail--full_sidebar .module-detail__content,
.module-detail--full_sidebar [class*="module-detail__content-"],
.module-detail--full_sidebar .module-detail__video,
.module-detail--full_sidebar .module-detail__faqs { grid-column: 1; }

/* 2b) Sidebar à DROITE */
.module-detail--full_sidebar .module-detail__documents,
.module-detail--full_sidebar .module-detail__contact,
.module-detail--full_sidebar .module-detail__socials { grid-column: 2; margin: 0 0 1.25rem; }
.module-detail--full_sidebar .module-detail__contact { position: sticky; top: 1rem; }

/* Navigation prev/next : pleine largeur, tout en bas */
.module-detail--full_sidebar .module-detail__nav { grid-column: 1 / -1; }

/* — magazine : éditorial, gros titre serif, lettrine, texte en 2 colonnes — */
.module-detail--magazine { max-width: 900px; }
.module-detail--magazine .module-detail__header { text-align: center; border-bottom: 3px double #111; padding-bottom: 1.5rem; }
.module-detail--magazine .module-detail__title { font-family: Georgia, 'Times New Roman', serif; font-size: 3rem; line-height: 1.12; }
.module-detail--magazine .module-detail__excerpt { font-size: 1.25rem; }
.module-detail--magazine .module-detail__content { column-count: 2; column-gap: 2.5rem; text-align: justify; }
.module-detail--magazine .module-detail__content img { break-inside: avoid; }
.module-detail--magazine .module-detail__content > *:first-child::first-letter { font-family: Georgia, serif; font-weight: 700; font-size: 3.4em; line-height: .8; float: left; padding: .05em .12em 0 0; color: var(--brand-color, var(--bs-primary, #0d6efd)); }

/* — minimal : sobre, mesure étroite, sans fond, beaucoup de blanc — */
.module-detail--minimal { max-width: 680px; }
.module-detail--minimal .module-detail__category { color: #999; font-weight: 600; }
.module-detail--minimal .module-detail__title { font-size: 1.9rem; font-weight: 600; }
.module-detail--minimal .module-detail__meta { font-size: .8rem; }
.module-detail--minimal .module-detail__excerpt { font-style: normal; color: #666; }
.module-detail--minimal .module-detail__cover { border-radius: 0; }
.module-detail--minimal .module-detail__contact { background: transparent; border: 1px solid #eee; }

/* — modern : audacieux, arrondi, ombres, accents dégradés/pilules — */
.module-detail--modern { max-width: 880px; }
.module-detail--modern .module-detail__cover { border-radius: 20px; box-shadow: 0 20px 50px rgba(16,24,40,.18); }
.module-detail--modern .module-detail__category { display: inline-block; padding: .3rem .8rem; border-radius: 999px; background: color-mix(in srgb, var(--brand-color, #0d6efd) 12%, transparent); }
.module-detail--modern .module-detail__title { font-size: 2.7rem; font-weight: 800; letter-spacing: -.02em; background: linear-gradient(90deg, var(--brand-color, var(--bs-primary, #0d6efd)), #7c3aed); -webkit-background-clip: text; background-clip: text; color: transparent; }
.module-detail--modern .module-detail__meta { display: inline-flex; gap: .5rem; padding: .35rem .85rem; border-radius: 999px; background: #f4f5f7; }
.module-detail--modern .module-detail__content { font-size: 1.05rem; }
.module-detail--modern .module-detail__contact { border-radius: 16px; background: #f7f8fa; }

@media (max-width: 992px) {
    .module-detail--split,
    .module-detail--full_sidebar { grid-template-columns: 1fr; }
    .module-detail--magazine .module-detail__content { column-count: 1; }
}
@media (max-width: 768px) {
    .module-detail--hero .module-detail__header { margin-top: -3rem; }
    .module-detail--hero .module-detail__title,
    .module-detail--magazine .module-detail__title,
    .module-detail--modern .module-detail__title { font-size: 1.9rem; }
}

/* ----------------------------------------------------------
   Sidebar widgets
   ---------------------------------------------------------- */
.modules-sidebar__widget { margin-bottom: 1.5rem; }
.modules-sidebar__widget-title { font-size: 1rem; font-weight: 700; margin-bottom: .75rem; padding-bottom: .5rem; border-bottom: 2px solid var(--brand-color, var(--bs-primary, #0d6efd)); }

/* ----------------------------------------------------------
   Responsive
   ---------------------------------------------------------- */
@media (max-width: 768px) {
    .module-grid--grid    { grid-template-columns: 1fr 1fr; }
    .module-grid--masonry { columns: 2; }
    .module-detail { padding: 1rem; }
    .module-detail__title { font-size: 1.6rem; }
}

@media (max-width: 480px) {
    .module-grid--grid,
    .module-grid--cards   { grid-template-columns: 1fr; }
    .module-grid--masonry { columns: 1; }
}


/* ===================================================================
   Auth pages (login / forgot-password / reset-password / 2FA)
   Generic, theme-targetable classes — built on Bootstrap utilities.
   =================================================================== */
/* Accent unique = couleur de marque du thème (repli --bs-primary puis vert Arkana).
   Défini sur .auth-section → hérité par toute la carte (custom property). */
.auth-section {
    display        : flex;
    align-items    : flex-start;   /* carte remontée sous l'en-tête (pas centrée = trop bas) */
    justify-content: center;
    min-height     : calc(100vh - var(--header-height, 0px));
    padding        : 2.5rem 0 4rem; /* espace au-dessus réduit */
    /* Accent de l'EN-TÊTE / focus / liens = couleur de marque du thème (dégradé
       foncé → texte blanc lisible). Les CTA, eux, utilisent .btn-1 (couleur de
       bouton configurée du thème), stylé par le thème. */
    --auth-accent  : var(--brand-color, var(--bs-primary, #2c7a6e));
}

.auth-card {
    width        : 100%;
    border       : 0;
    border-radius: calc(var(--card-radius, 8px) + 6px);
    box-shadow   : 0 1rem 3rem rgba(0, 0, 0, .08);
    overflow     : hidden;
}

.auth-card .card-body { padding: 2.5rem; }

.auth-card__header  { margin-bottom: 1.5rem; }
.auth-card__title,
.auth-card-header h1 { font-family: var(--title-font, inherit); }
.auth-card__title {
    font-size    : 1.5rem;
    font-weight  : 700;
    margin-bottom: .5rem;
}
.auth-card__subtitle {
    color    : var(--text-muted, #6c757d);
    font-size: .9rem;
    margin   : 0;
}

.auth-form .btn { width: 100%; }

.auth-links {
    margin-top: 1.25rem;
    text-align: center;
    font-size : .9rem;
}
.auth-link {
    color          : var(--auth-accent);
    text-decoration: none;
}
.auth-link:hover { text-decoration: underline; }

.auth-code-input {
    text-align    : center;
    letter-spacing: .5em;
    font-size     : 1.25rem;
}

.auth-honeypot {
    position: absolute;
    left    : -9999px;
    opacity : 0;
    height  : 0;
    width   : 0;
}

/* En-tête dégradé (couleur de marque du thème) + champs de la carte. Overrides
   génériques SCOPÉS sous .auth-card pour ne pas déborder sur le reste du front. */
.auth-card-header {
    background: linear-gradient(135deg, var(--auth-accent), color-mix(in srgb, var(--auth-accent) 65%, #000));
    color    : #fff;
}
.auth-logo-icon { color: #fff; }
.auth-card .input-group-text { border-color: var(--bs-border-color); }
.auth-card .form-control:focus {
    border-color: var(--auth-accent);
    box-shadow  : 0 0 0 .2rem color-mix(in srgb, var(--auth-accent) 20%, transparent);
}
/* Les CTA de l'auth utilisent .btn-1 (bouton configuré du thème). */
.auth-card .btn-1 { width: 100%; }
.auth-card .link-primary { color: var(--auth-accent); }
.auth-step-back {
    border-bottom : 1px solid var(--bs-border-color);
    padding-bottom: .75rem;
    margin-bottom : 1rem;
}

/* Bascule connexion ↔ inscription (liens sous chaque formulaire). */
.auth-switch {
    margin-top    : 1.25rem;
    padding-top   : 1.15rem;
    border-top    : 1px solid var(--bs-border-color, #e5e7eb);
    text-align    : center;
    font-size     : .9rem;
    color         : var(--text-muted, #6c757d);
}
.auth-switch .auth-switch-btn {
    background     : none;
    border         : 0;
    padding        : 0 .15rem;
    font-weight    : 600;
    color          : var(--auth-accent);
    cursor         : pointer;
    text-decoration: none;
}
.auth-switch .auth-switch-btn:hover { text-decoration: underline; }
/* ==========================================================================
   Widget chatbot natif (.awcb) — structure statique.
   La couleur (--awcb) et le côté (left) restent pilotés par les options du module
   Chatbot, appliqués par le JS du widget sur l’élément racine (aucun style inline).
   ========================================================================== */
.awcb{position:fixed;bottom:20px;right:20px;z-index:99998;--awcb:#2c7a6e}
.awcb__btn{width:46px;height:46px;border-radius:50%;border:0;background:var(--awcb);color:#fff;font-size:20px;cursor:pointer;box-shadow:0 6px 20px rgba(0,0,0,.25);display:flex;align-items:center;justify-content:center;transition:transform .15s}
.awcb__btn:hover{transform:scale(1.06)}
.awcb__panel{position:absolute;bottom:62px;right:0;width:360px;max-width:calc(100vw - 40px);height:520px;max-height:calc(100vh - 120px);background:#fff;border-radius:14px;box-shadow:0 12px 40px rgba(0,0,0,.22);display:none;flex-direction:column;overflow:hidden}
.awcb.open .awcb__panel{display:flex}
/* Bouton custom « retour en haut » (.to-top, injecté par le JS perso du site) :
   remonté AU-DESSUS de la rangée chatbot/notifications (bas-droite) pour ne plus
   être masqué. !important car le JS pose la position en style inline.
   ADAPTATIF : s'il n'y a NI chatbot (.awcb) NI bouton notif (#arkana-webpush-btn)
   dans le coin, il redescend prendre la place (bottom:20). `:has()` réévalue en
   DIRECT quand le bouton notif est injecté/retiré. Vieux navigateurs sans :has()
   → garde bottom:78 (sûr, jamais de chevauchement). */
.to-top{right:20px !important;bottom:78px !important;z-index:99996 !important}
body:not(:has(.awcb, #arkana-webpush-btn)) .to-top{bottom:20px !important}
.awcb__head{background:var(--awcb);color:#fff;padding:14px 16px}
.awcb__head h4{margin:0;font-size:15px;font-weight:600}
.awcb__head p{margin:2px 0 0;font-size:12px;opacity:.85}
.awcb__body{flex:1;overflow-y:auto;padding:14px;background:#f6f7f9;display:flex;flex-direction:column;gap:8px}
.awcb__msg{max-width:80%;padding:9px 12px;border-radius:14px;font-size:14px;line-height:1.4;white-space:pre-wrap;word-wrap:break-word}
.awcb__msg--bot{align-self:flex-start;background:#fff;border:1px solid #e6e8ec;border-bottom-left-radius:4px}
.awcb__msg--user{align-self:flex-end;background:var(--awcb);color:#fff;border-bottom-right-radius:4px}
.awcb__choices{display:flex;flex-wrap:wrap;gap:6px;margin-top:2px}
.awcb__choice{border:1px solid var(--awcb);color:var(--awcb);background:#fff;border-radius:16px;padding:6px 12px;font-size:13px;cursor:pointer}
.awcb__choice:hover{background:var(--awcb);color:#fff}
.awcb__foot{display:flex;gap:6px;padding:10px;border-top:1px solid #eceef1;background:#fff}
.awcb__foot input{flex:1;border:1px solid #d8dbe0;border-radius:20px;padding:9px 14px;font-size:14px;outline:none}
.awcb__foot input:focus{border-color:var(--awcb)}
.awcb__send{border:0;background:var(--awcb);color:#fff;width:40px;border-radius:50%;cursor:pointer;font-size:16px}
.awcb__send:disabled{opacity:.5;cursor:default}

/* ------------------------------------------------------------------
   Chat + Notifications : deux PASTILLES côte à côte.

   Seul le lanceur est habillé — panneaux, messages et cartes gardent
   leur présentation d'origine juste au-dessus.

   Le libellé du chat vient du CSS (le bouton ne porte qu'une icône) ;
   le nom accessible reste l'aria-label posé par le JS, il ne dépend
   donc pas de cette règle. Guillemets obligatoires sur --awcb-label.

   La hauteur commune est indispensable : la cloche n'a pas de libellé
   et retombait 11 px plus bas que le chat.
   ------------------------------------------------------------------ */
:root{
    --awcb-surface-2: #fffdfa;
    --awcb-ink:       #2b2622;
    --awcb-line:      rgba(43, 38, 34, .12);
    --awcb-pill-h:    40px;
    --awcb-label:     "Chat";
}

.awcb__btn,
.awpush-btn{
    display: flex; align-items: center; justify-content: center;
    width: auto; height: auto; min-height: var(--awcb-pill-h);
    padding: 9px 15px; gap: 7px;
    border: 1px solid var(--awcb-line); border-radius: 999px;
    background: var(--awcb-surface-2); color: var(--awcb-ink);
    font-size: 14px; font-weight: 500; line-height: 1; cursor: pointer;
    box-shadow: 0 4px 16px rgba(43, 38, 34, .16);
    transition: transform .15s, box-shadow .15s;
}
.awcb__btn::after{ content: var(--awcb-label); }
.awcb__btn:hover,
.awpush-btn:hover{ transform: translateY(-1px); box-shadow: 0 8px 22px rgba(43, 38, 34, .22); }

@media (prefers-reduced-motion: reduce){
    .awcb__btn, .awpush-btn{ transition: none; }
    .awcb__btn:hover, .awpush-btn:hover{ transform: none; }
}


/* Recherche mobile — overlay FIXE qui glisse depuis le haut (même principe que le
   volet de recherche de l'admin). En position:fixed, focus du champ = PAS de
   défilement de la page (corrige « ça remonte tout » quand on ouvrait la
   recherche en bas de page, l'input étant en flux tout en haut du DOM). */
.site-search-bar{
    position:fixed;top:var(--nav-bottom-mobile,72px);left:0;right:0;z-index:990;
    background:var(--menu-background,#fff);border-bottom:1px solid var(--menu-border-color,rgba(0,0,0,.08));
    box-shadow:0 8px 24px rgba(0,0,0,.14);
    transform:translateY(-100%);transition:transform .28s ease;
}
.site-search-bar.is-open{transform:translateY(0)}
/* Marge sur les côtés : la barre ne colle pas aux bords de l'écran. */
.site-search-bar .container{display:flex;align-items:center;gap:.5rem;padding-left:16px;padding-right:16px}
.site-search-bar form{flex:1 1 auto}
.site-search-close{
    flex:0 0 auto;border:0;background:transparent;color:var(--menu-color,#1f1f1f);
    width:40px;height:40px;border-radius:8px;cursor:pointer;font-size:18px;line-height:1;
}
.site-search-close:hover{background:rgba(0,0,0,.06)}
/* Backdrop : assombrit la page, clic pour fermer, fondu synchronisé. */
.site-search-overlay{
    position:fixed;inset:0;z-index:985;background:rgba(0,0,0,.35);
    opacity:0;transition:opacity .28s ease;
}
.site-search-overlay.is-open{opacity:1}
@media (prefers-reduced-motion:reduce){
    .site-search-bar,.site-search-overlay{transition:none}
}


/* Boutons désactivés : on NEUTRALISE seulement la couleur du texte, l'opacité et
   les interactions — le fond et la bordure restent ceux du bouton (background-color
   et border-color volontairement non surchargés). */
.btn.disabled,
.btn:disabled,
fieldset:disabled .btn {
    color: var(--bs-btn-disabled-color);
    pointer-events: none;
    /* background-color: var(--bs-btn-disabled-bg); */
    /* border-color: var(--bs-btn-disabled-border-color); */
    opacity: var(--bs-btn-disabled-opacity);
}

/* Iframes de contenu — responsive après nettoyage de width/height/frameborder
   à l'enregistrement (clean_html). Sans dimensions dans le markup, le CSS prend
   le relais : ne jamais déborder + un ratio par type d'embed pour garder une
   hauteur correcte (sinon vidéos/cartes s'écrasent à ~150px). */
iframe{max-width:100%;border:0}
/* Vidéos → 16/9 pleine largeur */
iframe[src*="youtube.com"],
iframe[src*="youtu.be"],
iframe[src*="youtube-nocookie.com"],
iframe[src*="vimeo.com"],
iframe[src*="dailymotion.com"],
iframe[src*="player."]{width:100%;height:auto;aspect-ratio:16/9}
/* Cartes (Google Maps / OpenStreetMap) → 4/3 pleine largeur */
iframe[src*="google.com/maps"],
iframe[src*="maps.google."],
iframe[src*="openstreetmap.org"]{width:100%;height:auto;aspect-ratio:4/3}

/* ==========================================================================
   Sections « split » du builder (image + contenu côte à côte).
   Le builder insère .split (+ éventuel suffixe .split-{bp}) contenant
   .split-container et/ou .split-container-fluid — chacun aussi taggé bootstrap
   .col-12. Par DÉFAUT : 2 colonnes 50/50. Un suffixe -sm/-md/-lg/-xl/-xxl fait
   passer en colonne empilée SOUS ce breakpoint (mobile-first inversé, comme le
   thème de référence). Auto-suffisant : ne dépend d'aucune variable de thème.
   ========================================================================== */
.split { display: flex; flex-wrap: nowrap; align-items: stretch; }
.split > .split-container,
.split > .split-container-fluid {
  flex: 1 1 0;
  width: 50%;
  max-width: 50%;            /* bat bootstrap .col-12 : spécificité 0,2,0 > 0,1,0 */
}
.split > .split-container-fluid { padding: 0; }
/* Le côté « fluide » (le plus souvent l'image) remplit toute sa moitié. */
.split > .split-container-fluid img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Image à droite / contenu à gauche. */
.split.split-reverse { flex-direction: row-reverse; }
/* Rangées alternées quand le parent porte .alternate (1 section sur 2 inversée). */
.alternate > .split:nth-child(even) { flex-direction: row-reverse; }

/* Empilage responsive : chaque suffixe empile SOUS son seuil, et repasse les
   deux moitiés en pleine largeur. */
@media (max-width: 575.98px) {
  .split-sm { flex-direction: column; }
  .split-sm > .split-container,
  .split-sm > .split-container-fluid { width: 100%; max-width: 100%; }
}
@media (max-width: 767.98px) {
  .split-md { flex-direction: column; }
  .split-md > .split-container,
  .split-md > .split-container-fluid { width: 100%; max-width: 100%; }
}
@media (max-width: 991.98px) {
  .split-lg { flex-direction: column; }
  .split-lg > .split-container,
  .split-lg > .split-container-fluid { width: 100%; max-width: 100%; }
}
@media (max-width: 1199.98px) {
  .split-xl { flex-direction: column; }
  .split-xl > .split-container,
  .split-xl > .split-container-fluid { width: 100%; max-width: 100%; }
}
@media (max-width: 1399.98px) {
  .split-xxl { flex-direction: column; }
  .split-xxl > .split-container,
  .split-xxl > .split-container-fluid { width: 100%; max-width: 100%; }
}

/* --------------------------------------------------------------------------
   Canvas du BUILDER uniquement (body.builderjs-layout, jamais le front).
   Le cadre d'édition est plus étroit que 768px → les media-queries ci-dessus
   empileraient toutes les sections split, cassant le WYSIWYG « desktop ». On
   force donc 2 colonnes dans l'éditeur, quelle que soit la largeur du canvas.
   Spécificité 0,2,0 / 0,3,0 → bat les règles empilées des media-queries.
   -------------------------------------------------------------------------- */
.builderjs-layout .split { flex-direction: row; flex-wrap: nowrap; }
.builderjs-layout .split > .split-container,
.builderjs-layout .split > .split-container-fluid { flex: 1 1 0; width: 50%; max-width: 50%; }
.builderjs-layout .split.split-reverse,
.builderjs-layout .alternate > .split:nth-child(even) { flex-direction: row-reverse; }

/* ----------------------------------------------------------
   Footer COMPOSÉ (composeur /admin/themes/footer) — .footer-composed
   Grille de N colonnes (--footer-cols) + barre basse. Tokens surchageables :
   --footer-bg / --footer-color / --footer-title-color.
   ---------------------------------------------------------- */
.site-footer.footer-composed { background: var(--footer-bg, #0d1117); color: var(--footer-text, #c9d1d9); margin-top: auto; }
/* « Alignée au contenu » : le FOND reste toujours pleine largeur ; seule la largeur
   du CONTENU change. Contained → conteneur centré (max-width). Sinon → pleine largeur. */
/* Padding piloté par le composeur (Apparence › Pied de page). Les 48px/20px ne
   sont que les REPLIS : le footer n'émet --footer-padding-y / -x que si le
   réglage correspondant est > 0. */
.footer-composed .footer-inner { max-width: 100%; margin: 0 auto; padding: var(--footer-padding-y, 48px) var(--footer-padding-x, 20px); }
.footer-composed.footer-contained .footer-inner { max-width: var(--footer-max-width, var(--content-width, 1200px)); }

/* Encart « carte » du footer (composeur : marges/arrondis DESKTOP). Mobile = pleine
   largeur (les marges/arrondis ne s'appliquent qu'≥768px). Le fond étant sur <footer>,
   overflow:hidden clippe le radius. */
@media (min-width: 768px) {
    .footer-composed.footer-boxed {
        margin: var(--footer-margin-block, 0) var(--footer-margin-inline, 0);
        border-radius: var(--footer-radius, 0);
        overflow: hidden;
    }
    /* Encart + « aligné au contenu » : carte centrée à largeur max (les marges
       latérales laissent place au centrage automatique). */
    .footer-composed.footer-boxed.footer-contained {
        max-width: var(--footer-max-width, var(--content-width, 1200px));
        margin-left: auto;
        margin-right: auto;
    }
}
.footer-composed .footer-grid { display: grid; grid-template-columns: repeat(var(--footer-cols, 4), minmax(0, 1fr)); gap: 32px; align-items: var(--footer-valign, start); }
/* Fusion de colonnes : chaque colonne occupe --fc-span unités de la grille (1..6). */
.footer-composed .footer-col { grid-column: span var(--fc-span, 1); }
/* Alignement « Milieu » : les colonnes AVEC un titre sont CENTRÉES verticalement (à
   hauteur du logo/image) tout en gardant leurs titres alignés entre eux. Pour que le
   centrage n'écarte pas les titres, les colonnes à titre sont égalisées en hauteur (JS
   du footer) : à hauteurs identiques, `align-self:center` place leurs hauts — donc leurs
   titres — sur la même ligne. Repli sans JS = centrage simple (titres ~alignés). */
.footer-composed.footer-va-center .footer-col--titled { align-self: center; }
.footer-composed .footer-col-title { font-size: var(--footer-col-title-size, 1rem); font-weight: 700; color: var(--footer-col-title-color, var(--footer-title-color, #fff)); margin: 0 0 14px; }
.footer-composed a { color: inherit; text-decoration: none; }
.footer-composed a:hover { text-decoration: underline; }
.footer-composed .footer-menu,
.footer-composed .footer-contact,
.footer-composed .footer-hours { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; font-size: .9rem; }
.footer-composed .footer-submenu { list-style: none; margin: 4px 0 4px 12px; padding: 0; opacity: .8; }
.footer-composed .footer-logo img,
.footer-composed .footer-logo svg { width: 100%; height: auto; max-width: 100%; }
.footer-composed .footer-brand { text-align: center; }
.footer-composed .footer-brand-text { font-size: .9rem; opacity: .8; margin-top: 12px; line-height: 1.6; }
.footer-composed .footer-brand-name { font-size: 1rem; font-weight: 700; margin-top: 12px; }
.footer-composed .footer-brand-tagline { font-size: .9rem; opacity: .8; margin-top: 8px; line-height: 1.6; }
.footer-composed .footer-hours-day { font-weight: 600; margin-right: 6px; }
.footer-composed .footer-hours-time { opacity: .85; }
.footer-composed .footer-social { display: flex; gap: 12px; flex-wrap: wrap; }

/* Réseaux sociaux (composeur navbar + footer) — icônes FontAwesome brands */
.social-links { display: inline-flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.social-links .social-link { display: inline-flex; align-items: center; justify-content: center; font-size: 1.15rem; line-height: 1; color: inherit; text-decoration: none; transition: opacity .15s ease, transform .15s ease; }
.social-links .social-link:hover { opacity: .7; transform: translateY(-1px); }
/* Mode « dropdown » : déclencheur (icône partage) ouvrant un panneau <details>
   avec les icônes (JS-free, accessible clavier). */
.social-dropdown { position: relative; display: inline-flex; }
.social-dropdown > summary { list-style: none; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; font-size: 1.15rem; line-height: 1; color: inherit; }
.social-dropdown > summary::-webkit-details-marker { display: none; }
.social-dropdown > summary::marker { content: ''; }
.social-dropdown[open] > summary { opacity: .75; }
.social-dropdown__menu { position: absolute; top: 100%; right: 0; margin-top: .4rem; z-index: 1001; display: flex; flex-direction: column; flex-wrap: nowrap; align-items: center; gap: 14px; padding: 12px 14px; background: #fff; border: 1px solid rgba(0,0,0,.10); border-radius: 10px; box-shadow: 0 10px 28px rgba(0,0,0,.16); }
.social-dropdown__menu .social-link { font-size: 1.25rem; }
.social-dropdown__menu .social-link { color: #1f1f1f; }
/* Footer : le panneau s'ouvre vers le HAUT (composant en bas de page). */
.social-dropdown.footer-social .social-dropdown__menu { top: auto; bottom: 100%; margin: 0 0 .4rem; }
/* Dans la navbar : rester sur UNE ligne (la zone a min-width:0 → sinon le
   conteneur est rétréci à 1 icône de large et empile verticalement). */
.menu-social { gap: 10px; flex-wrap: nowrap; flex: 0 0 auto; white-space: nowrap; }
/* En mode mobile (menu off-canvas), au contraire : autoriser le retour à la
   ligne pour que les 8 icônes se répartissent dans le panneau étroit. */
#main-menu.menu-breakpoint .menu-social { flex-wrap: wrap; white-space: normal; }

/* Réseaux sociaux tout en bas du menu mobile (bloc menu-mobile-actions) :
   centré, sur toute la largeur, icônes plus grandes. */
.menu-social--mobile { width: 100%; margin-top: 16px; justify-content: center; flex-wrap: wrap; white-space: normal; font-size: 1.4rem; gap: 18px; }

/* Menu mobile OUVERT : le bouton flottant « Notifications » (webpush, z-index
   1030) et la bulle chatbot (.awcb, position:fixed z-index 99998) vivent au
   niveau <body>. #main-menu est sticky z-index 1000 (contexte d'empilement) →
   son panneau off-canvas (z 99999 interne) et son masque (99998) restaient
   PIÉGÉS sous ces widgets. On remonte #main-menu au-dessus de 99998 seulement
   à l'ouverture : le panneau et le masque passent alors DEVANT, donc le
   chatbot et les notifications repassent DERRIÈRE le menu. */
#main-menu.menu-open { z-index: 100000; }

/* En mode replié (mobile/tablette), les réseaux sociaux ne doivent PAS rester
   dans la barre du haut : uniquement dans le menu déroulant (bloc --mobile).
   On masque donc le composant social de la zone (topbar) quand la barre est
   repliée — via la media query native ET le collapse forcé par JS (.menu-breakpoint).
   Sur desktop (barre non repliée), le composant reste affiché normalement. */
@media (max-width: 991.98px) { .menu-social:not(.menu-social--mobile) { display: none; } }
#main-menu.menu-breakpoint .menu-social:not(.menu-social--mobile) { display: none; }
.footer-composed .footer-newsletter-text { font-size: .9rem; opacity: .85; margin: 0; }
.footer-composed .footer-newsletter-form { display: flex; gap: 6px; margin-top: 10px; flex-wrap: wrap; }
.footer-composed .footer-newsletter-form input { flex: 1 1 160px; padding: 9px 12px; border-radius: 6px; border: 1px solid rgba(255, 255, 255, .2); background: rgba(255, 255, 255, .06); color: inherit; }
.footer-composed .footer-newsletter-form input::placeholder { color: rgba(255, 255, 255, .5); }
.footer-composed .footer-newsletter-form button { padding: 9px 16px; border-radius: 6px; border: 0; background: var(--brand-color, var(--bs-primary, #0d6efd)); color: #fff; cursor: pointer; font-weight: 600; }
.footer-composed .footer-text { font-size: .9rem; opacity: .85; line-height: 1.6; }
.footer-composed .footer-bottom { border-top: 1px solid rgba(255, 255, 255, .1); background: var(--footer-bottom-bg, transparent); color: var(--footer-bottom-text, inherit); }
.footer-composed .footer-bottom-inner { padding: 18px 20px; display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 12px; font-size: .82rem; opacity: .85; }
.footer-composed .footer-legal { display: flex; gap: 16px; flex-wrap: wrap; }
/* Tablette (769–1024px) : plafonne à 3 colonnes (sinon 5-6 colonnes se tassent). */
@media (min-width: 769px) and (max-width: 1024px) {
    .footer-composed .footer-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 28px; }
    .footer-composed .footer-col { grid-column: auto; } /* la fusion (span) ne vaut qu'en desktop */
}
@media (max-width: 768px) {
    .footer-composed .footer-grid { grid-template-columns: 1fr 1fr; gap: 24px; }
    .footer-composed .footer-col { grid-column: auto; }
      /* Repli mobile RÉDUIT, mais le réglage du composeur reste prioritaire s'il est
     défini — sinon un padding choisi dans l'interface était ignoré sous 768px. */
  .footer-composed .footer-inner { padding: var(--footer-padding-y, 32px) var(--footer-padding-x, 18px); }
    .footer-composed .footer-bottom-inner { flex-direction: column; text-align: center; justify-content: center; }
}
@media (max-width: 480px) {
    .footer-composed .footer-grid { grid-template-columns: 1fr; }
    .footer-composed .footer-col { grid-column: auto; }
}

/* Dropdowns front (sélecteur de langue, etc.) : retirer le BLEU Bootstrap de
   l'item actif/cliqué → highlight neutre clair (le texte reste lisible). */
.dropdown-item.active,
.dropdown-item:active {
    background-color: #f1f5f9;
    color: inherit;
}

/* -- Carte module : actions (favoris + partage) ------------------------------ */
.module-card__actions { display: flex; align-items: center; gap: .5rem; margin-top: .6rem; }
.module-card__fav {
    width: 34px; height: 34px; flex: 0 0 auto;
    display: inline-flex; align-items: center; justify-content: center;
    border: 1px solid var(--menu-border-color, #e5e7eb); border-radius: 50%;
    background: #fff; color: #6b7280; cursor: pointer; padding: 0;
    transition: color .15s, border-color .15s, background .15s;
}
.module-card__fav:hover { color: #e11d48; border-color: #e11d48; }
.module-card__fav.is-active { color: #e11d48; border-color: #e11d48; background: #fff5f6; }
.module-card__fav.is-active i { font-weight: 900; }


/* ============================================================================
   Popups (module Popups) — modale visiteur. JS = assets/js/akpopup.js ; seule
   la donnée window.__akPopups reste inline (par page). S'appuie sur les
   variables de la charte du site (--card-bg, --btn-primary-bg, --font-*…).
   ============================================================================ */
.akpopup-ov{position:fixed;inset:0;z-index:2147483000;display:flex;padding:20px;opacity:0;visibility:hidden;transition:opacity .25s ease,visibility .25s ease}
.akpopup-ov.is-open{opacity:1;visibility:visible}
.akpopup-ov[data-overlay="1"]{background:rgba(15,23,42,.55);backdrop-filter:saturate(120%) blur(2px)}
.akpopup-ov[data-pos="center"]{align-items:center;justify-content:center}
.akpopup-ov[data-pos="top"]{align-items:flex-start;justify-content:center}
.akpopup-ov[data-pos="bottom"]{align-items:flex-end;justify-content:center}
.akpopup-ov[data-pos="top-right"]{align-items:flex-start;justify-content:flex-end}
.akpopup-ov[data-pos="top-left"]{align-items:flex-start;justify-content:flex-start}
.akpopup-ov[data-pos="bottom-right"]{align-items:flex-end;justify-content:flex-end}
.akpopup-ov[data-pos="bottom-left"]{align-items:flex-end;justify-content:flex-start}
.akpopup{position:relative;width:100%;background:var(--pp-bg,var(--card-bg,#fff));color:var(--pp-text,var(--body-text,#111827));
  border-radius:var(--card-radius,14px);box-shadow:0 24px 60px -12px rgba(0,0,0,.35),0 8px 24px rgba(0,0,0,.18);
  overflow:hidden;font-family:var(--font-body,inherit);transform:translateY(0) scale(1);transition:transform .3s cubic-bezier(.16,1,.3,1),opacity .3s}
.akpopup--sm{max-width:380px}.akpopup--md{max-width:520px}.akpopup--lg{max-width:720px}
.akpopup__media{display:block;width:100%;object-fit:cover}
.akpopup--img-top .akpopup__media{max-height:260px}
.akpopup--img-left{display:flex;align-items:stretch}
.akpopup--img-left .akpopup__media{width:42%;max-height:none;object-fit:cover;flex:none}
.akpopup--img-bottom .akpopup__media{max-height:260px}
.akpopup--img-right{display:flex;align-items:stretch}
.akpopup--img-right .akpopup__media{width:42%;max-height:none;object-fit:cover;flex:none}
.akpopup--img-background{background-size:cover;background-position:center}
.akpopup--img-background .akpopup__body{background:linear-gradient(180deg,rgba(0,0,0,.05),rgba(0,0,0,.72));color:#fff;min-height:300px;display:flex;flex-direction:column;justify-content:flex-end}
.akpopup__body{padding:30px 30px 34px;flex:1}
.akpopup__title{margin:0 0 12px;font-size:1.5rem;line-height:1.25;font-weight:700;font-family:var(--font-heading,inherit)}
.akpopup__content{font-size:.98rem;line-height:1.6;opacity:.92}
.akpopup__content p:last-child{margin-bottom:0}
.akpopup__content img{max-width:100%;height:auto;border-radius:8px}
.akpopup .akpopup__cta{display:inline-block;margin-top:22px;padding:12px 26px;border-radius:var(--btn-primary-radius,8px);
  background:var(--pp-accent,var(--btn-primary-bg,#2c7a6e));color:var(--pp-accent-text,var(--btn-primary-text,#fff));font-weight:600;
  text-decoration:none;border:0;cursor:pointer;transition:filter .15s,transform .15s}
.akpopup .akpopup__cta:hover{filter:brightness(1.07);transform:translateY(-1px)}
.akpopup__close{position:absolute;top:12px;right:12px;z-index:2;width:34px;height:34px;border:0;border-radius:50%;
  background:rgba(255,255,255,.9);color:#111;font-size:20px;line-height:1;cursor:pointer;display:flex;align-items:center;
  justify-content:center;box-shadow:0 2px 8px rgba(0,0,0,.2);transition:transform .15s}
.akpopup__close:hover{transform:rotate(90deg) scale(1.05)}
.akpopup--img-background .akpopup__close{background:rgba(0,0,0,.4);color:#fff}
/* animations d'entrée */
.akpopup-ov[data-anim="zoom"] .akpopup{transform:scale(.9);opacity:0}
.akpopup-ov[data-anim="slide-up"] .akpopup{transform:translateY(40px);opacity:0}
.akpopup-ov[data-anim="slide-down"] .akpopup{transform:translateY(-40px);opacity:0}
.akpopup-ov[data-anim="fade"] .akpopup{opacity:0}
.akpopup-ov.is-open .akpopup{transform:none;opacity:1}
@media(max-width:560px){.akpopup--img-left{flex-direction:column}.akpopup--img-left .akpopup__media{width:100%;max-height:200px}.akpopup--img-right{flex-direction:column}.akpopup--img-right .akpopup__media{width:100%;max-height:200px}
  .akpopup__body{padding:24px 20px 28px}.akpopup__title{font-size:1.3rem}}
@media(prefers-reduced-motion:reduce){.akpopup,.akpopup-ov{transition:none}}

/* ============================================================================
   Page protégée par mot de passe (module Pages — Views/front/password.php).
   ============================================================================ */
.page-pw-gate{display:flex;align-items:center;justify-content:center;min-height:60vh;padding:40px 20px}
.page-pw-card{width:100%;max-width:420px;background:var(--card-bg,#fff);color:var(--body-text,#111827);
  border-radius:var(--card-radius,14px);box-shadow:0 24px 60px -12px rgba(0,0,0,.18),0 8px 24px rgba(0,0,0,.10);
  padding:34px 30px 30px;text-align:center;font-family:var(--font-body,inherit)}
.page-pw-icon{width:56px;height:56px;margin:0 auto 16px;border-radius:50%;display:flex;align-items:center;
  justify-content:center;font-size:1.4rem;background:var(--btn-primary-bg,#2c7a6e);color:var(--btn-primary-text,#fff)}
.page-pw-title{margin:0 0 8px;font-size:1.35rem;font-weight:700;font-family:var(--font-heading,inherit)}
.page-pw-sub{margin:0 0 20px;font-size:.95rem;line-height:1.5;opacity:.8}
.page-pw-error{margin:0 0 16px;padding:10px 12px;border-radius:8px;background:#fee2e2;color:#991b1b;font-size:.9rem;font-weight:600}
.page-pw-form{display:flex;flex-direction:column;gap:12px}
.page-pw-input{width:100%;box-sizing:border-box;padding:12px 14px;border:1px solid #cbd5e1;border-radius:var(--btn-primary-radius,8px);
  font-size:1rem;background:#fff;color:#111827;outline:none}
.page-pw-input:focus{border-color:var(--btn-primary-bg,#2c7a6e);box-shadow:0 0 0 3px rgba(44,122,110,.15)}
.page-pw-btn{width:100%;padding:12px 14px;border:0;border-radius:var(--btn-primary-radius,8px);cursor:pointer;
  background:var(--btn-primary-bg,#2c7a6e);color:var(--btn-primary-text,#fff);font-weight:600;font-size:1rem;
  transition:filter .15s,transform .15s}
.page-pw-btn:hover{filter:brightness(1.07);transform:translateY(-1px)}

/* ============================================================================
   Dates d'événement (module Blogs, mode « events ») — fiche détail.
   ============================================================================ */
.module-event-dates{margin:18px 0;padding:16px 18px;border:1px solid var(--card-border,#e8ebf1);
  border-left:3px solid var(--btn-primary-bg,#2c7a6e);border-radius:12px;background:var(--card-bg,#fafbfc)}
.module-event-dates__title{margin:0 0 10px;font-size:1rem;font-weight:700;display:flex;align-items:center;gap:8px}
.module-event-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:10px}
.module-event-item{display:flex;flex-wrap:wrap;align-items:center;gap:8px 14px;padding-bottom:10px;border-bottom:1px dashed var(--card-border,#e8ebf1)}
.module-event-item:last-child{padding-bottom:0;border-bottom:0}
.module-event-when{font-weight:600;display:inline-flex;align-items:center;gap:8px;flex-wrap:wrap}
.module-event-sep{opacity:.55}
.module-event-tag{display:inline-flex;align-items:center;gap:5px;font-size:.85rem;font-weight:500;opacity:.85}
.module-event-infos{flex-basis:100%;font-size:.85rem;opacity:.75}

/* ============================================================================
   Gabarit « Agenda » du bloc dynamique Blogs (display=agenda) — badge date + contenu.
   ============================================================================ */
.module-agenda{display:flex;flex-direction:column;gap:12px}
.module-agenda__item{display:flex;gap:16px;align-items:stretch;text-decoration:none;color:inherit}
.module-agenda__badge{flex:0 0 auto;width:78px;display:flex;flex-direction:column;align-items:center;justify-content:center;
  padding:10px 6px;border-radius:10px;background:var(--agenda-accent,var(--btn-primary-bg,#33547a));color:#fff;text-align:center;line-height:1.05}
.module-agenda__dow{font-size:.62rem;font-weight:600;text-transform:uppercase;letter-spacing:.05em;opacity:.92}
.module-agenda__day{font-size:1.7rem;font-weight:800;margin:1px 0}
.module-agenda__month{font-size:.62rem;font-weight:600;text-transform:uppercase;letter-spacing:.05em;opacity:.92}
.module-agenda__body{display:flex;flex-direction:column;justify-content:center;gap:3px;min-width:0}
.module-agenda__category{font-size:.72rem;font-weight:700;text-transform:uppercase;letter-spacing:.04em;color:var(--agenda-accent,var(--btn-primary-bg,#b58a00))}
.module-agenda__title{font-weight:700;font-size:1.05rem;line-height:1.25;color:var(--body-text,#1e293b)}
.module-agenda__excerpt{font-size:.9rem;opacity:.75;line-height:1.4}
.module-agenda__item:hover .module-agenda__title{text-decoration:underline}

/* =====================================================================
   Modules — styles sortis des vues
   Ces règles vivaient dans des balises <style> à l'intérieur des gabarits
   (index.php, _detail_body.php, map.php). Un <style> écrit par la page ne
   se met pas en cache, échappe à la minification, et se duplique à chaque
   bloc posé sur la même page.
   Les valeurs qui dépendent d'un réglage de site passent par des variables
   CSS portées par l'élément : voir --module-cols-* et --module-img-ratio.
   ===================================================================== */

/* --- Repli des filtres derrière un bouton (option filters_nav) -------- */
.module-filters { display: flex; flex-direction: column; margin-bottom: 1rem; }
.module-filters > summary.module-filters-toggle {
    align-self: flex-end; list-style: none; cursor: pointer;
    display: inline-flex; align-items: center; gap: .5em; padding: .5em 1em;
    border: 1px solid currentColor; border-radius: 999px;
    font-weight: 600; user-select: none; line-height: 1;
}
.module-filters > summary.module-filters-toggle::-webkit-details-marker { display: none; }

/* Repli explicite : `display:flex` sur <details> peut neutraliser la règle
   du navigateur qui masque le contenu fermé — on le masque nous-mêmes. */
.module-filters:not([open]) > .module-index-toolbar { display: none; }
.module-filters[open] > .module-index-toolbar { margin-top: .75rem; }

/* Un filtre actif se signale sur le bouton lui-même : replié ou déplié, le
   visiteur sait que la liste est restreinte. */
.module-filters > summary.has-filters { border-width: 2px; }

/* Pastille teintée à partir de la couleur courante : lisible sur n'importe
   quel fond de thème, sans supposer la couleur de la page. */
.module-filters-count {
    display: inline-grid; place-items: center; min-width: 1.4em; height: 1.4em;
    padding: 0 .35em; border-radius: 999px;
    font-size: .72em; line-height: 1; font-weight: 700;
    background: color-mix(in srgb, currentColor 18%, transparent);
}

/* --- Colonnes par appareil ------------------------------------------
   Les nombres viennent de l'élément (--module-cols-*), la règle est ici.
   Les valeurs de repli reproduisent la grille par défaut du thème, si bien
   qu'un bloc sans réglage s'affiche comme avant. */
.module-grid--cols { grid-template-columns: repeat(var(--module-cols-m, 1), minmax(0, 1fr)); }

@media (min-width: 768px) {
    .module-grid--cols { grid-template-columns: repeat(var(--module-cols-t, 2), minmax(0, 1fr)); }
}
@media (min-width: 1024px) {
    .module-grid--cols { grid-template-columns: repeat(var(--module-cols-d, 3), minmax(0, 1fr)); }
}

/* Masonry : colonnes CSS à hauteur libre. `grid-template-columns` n'a pas
   de prise ici, d'où la redéfinition en column-count. */
.module-grid--masonry {
    display: block;
    column-count: var(--module-cols-m, 1);
    column-gap: 1.25rem;
}
.module-grid--masonry > * {
    display: inline-block; width: 100%; margin: 0 0 1.25rem;
    break-inside: avoid; -webkit-column-break-inside: avoid;
}
@media (min-width: 768px) {
    .module-grid--masonry { column-count: var(--module-cols-t, 2); }
}
@media (min-width: 1024px) {
    .module-grid--masonry { column-count: var(--module-cols-d, 3); }
}

/* --- galerie de la page detail --------------------------------------------- */
.module-detail__gallery{display:flex;gap:10px;align-items:flex-start}
            .module-detail__gallery--left{flex-direction:row-reverse}
            .module-detail__gallery--bottom{flex-direction:column}
            .module-detail__gallery-main{flex:1 1 auto;min-width:0}
            /* Bottom : la zone principale prend TOUTE la largeur. Sans ça, en flex
               align-items:flex-start elle se réduit au contenu, le carrousel n'a
               aucune largeur pour disposer ses slides (images jamais dimensionnées). */
            .module-detail__gallery--bottom .module-detail__gallery-main{width:100%;align-self:stretch}
            .module-detail__gallery-main .module-detail__carousel{display:block;width:100%;position:relative}
            .module-detail__gallery-main img{width:100%;height:auto;display:block;border-radius:8px}
            /* Pagination SUPERPOSÉE en bas de l'image : supprime la bande blanche
               « à la fin » (pagination sinon en flux, 20px sous l'image) et évite que
               le point actif agrandi soit rogné par le clip du conteneur. */
            .module-detail__gallery-main .awc-pagination{position:absolute;left:0;right:0;bottom:10px;padding:0;z-index:2;margin:0}
            .module-detail__gallery-main .awc-bullet{background:rgba(255,255,255,.6);box-shadow:0 0 3px rgba(0,0,0,.4)}
            .module-detail__gallery-main .awc-bullet-active{background:#fff}
            .module-detail__gallery-thumbs{display:flex;gap:8px;flex:0 0 auto}
            .module-detail__gallery--left .module-detail__gallery-thumbs,
            .module-detail__gallery--right .module-detail__gallery-thumbs{flex-direction:column;width:86px;max-height:520px;overflow:auto}
            .module-detail__gallery--bottom .module-detail__gallery-thumbs{flex-wrap:wrap}
            .module-detail__thumb{border:2px solid transparent;border-radius:6px;padding:0;background:none;cursor:pointer;overflow:hidden;width:78px;height:78px;flex:0 0 auto}
            .module-detail__thumb img{width:100%;height:100%;object-fit:cover;display:block}
            .module-detail__thumb.is-active{border-color:var(--brand-color,var(--bs-primary,#2C7A6E))}
            @media(max-width:640px){.module-detail__gallery,.module-detail__gallery--left{flex-direction:column}.module-detail__gallery-main{width:100%}.module-detail__gallery--left .module-detail__gallery-thumbs,.module-detail__gallery--right .module-detail__gallery-thumbs{flex-direction:row;width:auto;flex-wrap:wrap;max-height:none}}

/* --- carte du bloc --------------------------------------------- */
/* Pleine page, à ras des bords : la carte touche la gauche et le bas. C'est le
     PANNEAU (styles app.js) qui porte son propre padding, pas la section. */
  .module-map{padding:0;max-width:none}
  /* Repli si app.js n'a pas encore injecté ses styles (classe identique). */
  .awmap-sronly{position:absolute;width:1px;height:1px;padding:0;margin:-1px;
                overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}

/* --- Tableaux insérés via l'éditeur awtext (rendu FRONT, hors .awt-area) ------
   L'éditeur style .awt-area .awt-table dans awtext.css ; sur la page publiée le
   contenu n'a pas .awt-area → on reprend le rendu (bordures + 1re ligne en-tête). */
.awt-table{border-collapse:collapse;width:100%;margin:1em 0}
.awt-table td,
.awt-table th{border:1.5px solid var(--awt-border,#d7dce5);padding:8px 12px;min-width:60px}
.awt-table tr:first-child td{background:#f5f7fb;font-weight:600}
.awt-table th{background:#f5f7fb;font-weight:600;text-align:left}

/* Images insérées via l'éditeur awtext : responsive sur le front. */
.awt-img{max-width:100%;height:auto}

/* Utilitaire flex : autorise un enfant à rétrécir sous sa largeur de contenu
   (Bootstrap 5 ne fournit pas .min-w-0 par défaut). Sans ça, un titre/texte long
   pousse les éléments voisins hors de leur conteneur (ex. cœur des favoris). */
.min-w-0{min-width:0}

/* --- Champs personnalisés (valeurs) — rendu front (fiche + carte) ----------- */
.module-customfields{margin:0}
.module-customfields--detail{display:grid;grid-template-columns:auto 1fr;gap:.4rem 1.1rem;margin:1.1rem 0;align-items:baseline}
.module-customfields--detail dt{margin:0;font-weight:600;color:var(--brand-color,var(--bs-primary,#2C7A6E))}
.module-customfields--detail dd{margin:0;min-width:0;word-break:break-word}
.module-customfields--card{display:flex;flex-wrap:wrap;gap:.2rem .7rem;margin:.45rem 0 0;font-size:.8rem;color:#6b7280}
.module-customfields--card .cf-item{display:inline-flex;gap:.25rem;min-width:0}
.module-customfields--card .cf-label{font-weight:600}
.module-customfields--card .cf-value{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:16rem}
/* Trombinoscope : `.module-customfields--card` est pensée comme un BANDEAU en
   ligne — libellé et valeur côte à côte, valeur coupée à 16rem. La carte contact
   est centrée et large d'environ 150 px : dans cette colonne le libellé se casse
   en deux et les deux-points se retrouvent seuls sur une ligne. On empile la
   valeur SOUS son libellé et on recale la coupe sur la largeur réelle. */
.module-card--contact .module-customfields--card { flex-direction: column; align-items: center; gap: .35rem; }
.module-card--contact .module-customfields--card .cf-item { display: block; max-width: 100%; }
.module-card--contact .module-customfields--card .cf-label { display: block; }
.module-card--contact .module-customfields--card .cf-value { display: block; max-width: 100%; }
.cf-swatch{display:inline-block;width:.9em;height:.9em;border-radius:3px;vertical-align:middle;border:1px solid rgba(0,0,0,.15)}
.cf-img{max-height:130px;max-width:100%;border-radius:6px;display:block}


/* =====================================================================
   Champs de contenu supplémentaires (content_1 à content_6)
   Trois présentations pilotées par la config du module : à la suite,
   accordéons, onglets. Voir _detail_contents.php.
   ===================================================================== */
.module-detail__contents { margin: 2rem 0; }
.module-detail__contents > section + section,
.module-detail__contents--stack > section { margin-top: 2rem; }

.module-detail__content-titre { font-size: 1.25rem; margin: 0 0 .75rem; }

/* --- Accordéons -------------------------------------------------------
   Composant Bootstrap 5 (accordion). On ne redéfinit que ce que le thème
   doit reprendre : le titre, dont Bootstrap ne suppose pas la taille, et
   la teinte de l en-tête ouvert. Le reste vient de bootstrap.min.css. */
.module-detail__contents--accordion .accordion-header { margin: 0; }
.module-detail__contents--accordion .accordion-button {
    font-size: 1.0625rem; font-weight: 600;
}
.module-detail__contents--accordion .accordion-button:not(.collapsed) {
    color: var(--bs-primary, #1d4ed8);
    background: var(--tr-primary-clair, #eff4ff);
}
.module-detail__contents--accordion .accordion-item + .accordion-item { margin-top: 0; }

/* --- Onglets ----------------------------------------------------------
   Les panneaux sont TOUS rendus et visibles ; c'est app.js qui masque les
   inactifs. Sans script, la liste d'onglets ne sert à rien mais le contenu
   reste entier — d'où son retrait, plutôt qu'une barre de boutons morts. */
.module-detail__tablist {
    display: flex; flex-wrap: wrap; gap: .25rem;
    border-bottom: 2px solid var(--bs-border-color, #e2e8f0);
    margin-bottom: 1.25rem;
}
.module-detail__tab {
    border: 0; background: none; cursor: pointer;
    padding: .625rem 1rem; margin-bottom: -2px;
    border-bottom: 2px solid transparent;
    font-weight: 600; color: var(--tr-encre-3, #64748b);
}
.module-detail__tab:hover { color: var(--bs-primary, #1d4ed8); }
.module-detail__tab.est-actif {
    color: var(--bs-primary, #1d4ed8);
    border-bottom-color: var(--bs-primary, #1d4ed8);
}
.module-detail__tab:focus-visible { outline: 2px solid var(--bs-primary, #1d4ed8); outline-offset: 2px; }
.module-detail__panel:focus-visible { outline: 2px solid var(--bs-primary, #1d4ed8); outline-offset: 4px; }

/* Sans JavaScript la barre d'onglets n'a aucun effet : on la masque et les
   panneaux s'empilent, ce qui est exactement le mode « à la suite ». */
.no-js .module-detail__tablist { display: none; }

/* --- Valeurs d'attributs (EAV) ---------------------------------------
   Rendues par Blogs/Views/front/_attributes_values.php, sur la carte et
   sur la fiche. À ne pas confondre avec .module-wattrs, qui est le widget
   de FILTRE — même mot, autre chose. */
.module-attrs { margin: 0; padding: 0; display: flex; flex-direction: column; gap: .25rem; }
.module-attr { display: flex; gap: .5rem; align-items: baseline; }
.module-attr__label {
    flex-shrink: 0; margin: 0; font-weight: 600;
    color: var(--color-text-muted, #666);
}
.module-attr__label::after { content: " :"; }
.module-attr__value { margin: 0; min-width: 0; }
.module-attr__color {
    display: inline-block; width: .75rem; height: .75rem;
    border-radius: 3px; border: 1px solid rgba(0,0,0,.15);
    vertical-align: -1px; margin-right: .25rem;
}

/* Sur la carte : compact, et on ne laisse pas trois lignes d'attributs
   pousser le bouton « Lire la suite » hors de la vue. */
.module-attrs--card { font-size: .8125rem; margin: .5rem 0; }
.module-attrs--card .module-attr__value {
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}


/* ─── Attributs INTERRUPTEUR : un marqueur, pas une phrase ───────────────────
   Un interrupteur allumé n a qu une valeur possible : allumé. L écrire
   (« Le carmel : Oui ») remplit la carte sans rien apprendre — ce qui parle,
   c est son icône. La valeur reste dans le HTML pour les lecteurs d écran.
   Les interrupteurs se rangent donc EN LIGNE, comme une série de pastilles,
   pendant que les autres attributs gardent leur mise en page en colonnes. */
.module-attrs--card { flex-flow: row wrap; align-items: center; gap: .35rem .75rem; }
.module-attrs--card .module-attr { display: flex; align-items: center; min-width: 0; }
.module-attrs--card .module-attr[data-attr-type="switch"] .module-attr__label::after { content: none; }
.module-attrs--card .module-attr[data-attr-type="switch"] .module-attr__value { margin: 0; }
/* Sans libellé, l attribut se réduit à son icône : on retire l espace mort. */
.module-attrs--card .module-attr__label { display: inline-flex; align-items: center; gap: .3rem; }
.module-attrs--card .module-attr__label:empty { display: none; }

.module-attrs--detail { font-size: .9375rem; gap: .375rem; }
.module-detail__attrs { margin: 1.5rem 0; }

/* ─── Icône d'un attribut ────────────────────────────────────────────────────
   La taille se règle ICI, plus dans le PHP. `attribute_marker_icon()` écrivait
   `width:1em;height:1em` en `style=` : c'était la seule taille possible, et
   aucune feuille de style ne pouvait la reprendre sans `!important`. Le PHP ne
   pose désormais que ce qui dépend de la donnée (fichier du masque, couleur).

   Conséquence pratique : un emblème détaillé (le SVG « Le carmel » fait 32×39)
   rendu à 1em sur une carte tombe à 13px — illisible. On l'agrandit par
   attribut, sans toucher aux autres, via la classe `module-attr-{id}` déjà
   émise par la vue :

       .module-attr-3 { --module-attr-icon-size: 1.6em; }

   Le masque conserve le ratio (`contain`) : un SVG non carré n'est pas déformé,
   il est centré dans la boîte. */
/* La valeur par défaut est le REPLI du `var()`, pas une déclaration sur
   l'élément : déclarer `--module-attr-icon-size` sur `.module-attr__icon`
   battrait toute valeur posée sur un ancêtre, et le réglage par attribut
   ci-dessus n'aurait aucun effet (vérifié : il restait à 13px). */
.module-attr__icon { flex-shrink: 0; }
.module-attr__icon--svg {
    display: inline-block; vertical-align: -0.125em;
    width: var(--module-attr-icon-size, 1em);
    height: var(--module-attr-icon-size, 1em);
}
img.module-attr__icon--svg { object-fit: contain; }
/* SVG collé en ligne (2ᵉ chemin du helper) : il n'avait AUCUNE taille et
   sortait donc à sa dimension naturelle, seul cas visiblement cassé. */
.module-attr__icon--svg > svg { display: block; width: 100%; height: 100%; }
.module-attr__icon--mask {
    -webkit-mask: var(--module-attr-mask) no-repeat center / contain;
            mask: var(--module-attr-mask) no-repeat center / contain;
}

/* ─── Variante « puces » (opt-in) ────────────────────────────────────────────
   Pour les interrupteurs, `Le carmel : Oui` n'apprend rien : l'information est
   « cette publication porte Le carmel ». On retire le « : » et le « Oui »
   (gardé pour les lecteurs d'écran, sinon le <dl> perd son couple), et les
   attributs s'alignent en ligne au lieu de s'empiler.

   Opt-in délibéré : basculer `.module-attrs--card` en ligne changerait l'aspect
   des cartes de TOUS les sites déjà en place.

   Le levier est un ANCÊTRE portant `attrs-chips` — une classe que l'on peut
   réellement poser : champ « Classe CSS » du widget (`dw_section`), ou classe
   d'un conteneur dans le gabarit du builder. La classe `module-attrs--chips`
   sur le <dl> lui-même est prévue pour une vue qui la demanderait, mais aucune
   ne la pose aujourd'hui : ne pas compter sur elle. */
.attrs-chips .module-attrs,
.module-attrs--chips { flex-direction: row; flex-wrap: wrap; gap: .375rem .625rem; align-items: center; }
.attrs-chips .module-attr,
.module-attrs--chips .module-attr { align-items: center; gap: .375rem; }
.attrs-chips .module-attr__label,
.module-attrs--chips .module-attr__label { font-weight: 500; color: inherit; }
.attrs-chips [data-attr-type="switch"] .module-attr__label::after,
.module-attrs--chips [data-attr-type="switch"] .module-attr__label::after { content: none; }
.attrs-chips [data-attr-type="switch"] .module-attr__value,
.module-attrs--chips [data-attr-type="switch"] .module-attr__value {
    position: absolute; width: 1px; height: 1px;
    overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}

/* « En savoir plus » réduit à un pictogramme : le lien doit rester une cible
   confortable au doigt, ce que le texte assurait jusque-là. */
.module-card__more--icone {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 2.75rem; min-height: 2.75rem;
}
.module-card__more--icone svg { width: 1.25rem; height: 1.25rem; }

/* Menu d'actions posé DANS le flux de la carte (brique « Menu actions » du
   composeur), par opposition à son ancrage par défaut en haut à droite. */
.aw-card-actions--inline { position: static; align-self: flex-start; }

/* « Publié le » devant la date de carte. Dans son propre span pour rester
   masquable sans toucher au gabarit : .module-card__date-label{display:none} */
.module-card__date-label { opacity: .75; margin-right: .2em; }

/* ── Fil d'Ariane unifié (helper breadcrumb() : Pages, Blogs, …) ───────────────
   Markup sémantique <nav><ol><li> ; séparateurs « / » en CSS (pas de nœud
   décoratif dans le DOM SEO/AT). Couleurs héritées (s'intègre au thème). */
.aw-breadcrumb { margin: 1.5rem 0 1rem; font-size: .875rem; }
.aw-breadcrumb__list {
    list-style: none; margin: 0; padding: 0;
    display: flex; flex-wrap: wrap; align-items: center; gap: .35rem;
}
.aw-breadcrumb__item { display: flex; align-items: center; gap: .35rem; }
.aw-breadcrumb__item:not(:first-child)::before { content: "/"; opacity: .5; }
.aw-breadcrumb a { color: inherit; text-decoration: none; }
.aw-breadcrumb a:hover { text-decoration: underline; }
.aw-breadcrumb [aria-current="page"] { opacity: .7; }

/* AW-BUTTONS:START — généré par admin/themes/configure, ne pas éditer à la main */
.btn-1,.btn.btn-1{background-color:var(--btn-1-bg, var(--color-1, #2c7a6e));color:var(--btn-1-color, #fff);border-color:var(--btn-1-border-color, transparent);border-width:var(--btn-1-border-width, 0);border-style:solid;border-radius:var(--btn-1-radius, var(--btn-radius, 4px));transition:background-color .18s ease,color .18s ease,border-color .18s ease}.btn-1:hover,.btn.btn-1:hover{background-color:var(--btn-1-bg-hover, color-mix(in srgb, var(--btn-1-bg, var(--color-1, #2c7a6e)) 85%, #000));color:var(--btn-1-color-hover, var(--btn-1-color, #fff))}.btn-outline-1,.btn.btn-outline-1{background:transparent;color:var(--btn-1-bg, var(--color-1, #2c7a6e));border:1px solid var(--btn-1-bg, var(--color-1, #2c7a6e));border-radius:var(--btn-1-radius, var(--btn-radius, 4px))}.btn-outline-1:hover,.btn.btn-outline-1:hover{background-color:var(--btn-1-bg-hover, var(--btn-1-bg, var(--color-1, #2c7a6e)));color:var(--btn-1-color-hover, var(--btn-1-color, #fff))}.btn-2,.btn.btn-2{background-color:var(--btn-2-bg, var(--color-2, #2c7a6e));color:var(--btn-2-color, #fff);border-color:var(--btn-2-border-color, transparent);border-width:var(--btn-2-border-width, 0);border-style:solid;border-radius:var(--btn-2-radius, var(--btn-radius, 4px));transition:background-color .18s ease,color .18s ease,border-color .18s ease}.btn-2:hover,.btn.btn-2:hover{background-color:var(--btn-2-bg-hover, color-mix(in srgb, var(--btn-2-bg, var(--color-2, #2c7a6e)) 85%, #000));color:var(--btn-2-color-hover, var(--btn-2-color, #fff))}.btn-outline-2,.btn.btn-outline-2{background:transparent;color:var(--btn-2-bg, var(--color-2, #2c7a6e));border:1px solid var(--btn-2-bg, var(--color-2, #2c7a6e));border-radius:var(--btn-2-radius, var(--btn-radius, 4px))}.btn-outline-2:hover,.btn.btn-outline-2:hover{background-color:var(--btn-2-bg-hover, var(--btn-2-bg, var(--color-2, #2c7a6e)));color:var(--btn-2-color-hover, var(--btn-2-color, #fff))}.btn-3,.btn.btn-3{background-color:var(--btn-3-bg, var(--color-3, #2c7a6e));color:var(--btn-3-color, #fff);border-color:var(--btn-3-border-color, transparent);border-width:var(--btn-3-border-width, 0);border-style:solid;border-radius:var(--btn-3-radius, var(--btn-radius, 4px));transition:background-color .18s ease,color .18s ease,border-color .18s ease}.btn-3:hover,.btn.btn-3:hover{background-color:var(--btn-3-bg-hover, color-mix(in srgb, var(--btn-3-bg, var(--color-3, #2c7a6e)) 85%, #000));color:var(--btn-3-color-hover, var(--btn-3-color, #fff))}.btn-outline-3,.btn.btn-outline-3{background:transparent;color:var(--btn-3-bg, var(--color-3, #2c7a6e));border:1px solid var(--btn-3-bg, var(--color-3, #2c7a6e));border-radius:var(--btn-3-radius, var(--btn-radius, 4px))}.btn-outline-3:hover,.btn.btn-outline-3:hover{background-color:var(--btn-3-bg-hover, var(--btn-3-bg, var(--color-3, #2c7a6e)));color:var(--btn-3-color-hover, var(--btn-3-color, #fff))}.btn-4,.btn.btn-4{background-color:var(--btn-4-bg, var(--color-4, #2c7a6e));color:var(--btn-4-color, #fff);border-color:var(--btn-4-border-color, transparent);border-width:var(--btn-4-border-width, 0);border-style:solid;border-radius:var(--btn-4-radius, var(--btn-radius, 4px));transition:background-color .18s ease,color .18s ease,border-color .18s ease}.btn-4:hover,.btn.btn-4:hover{background-color:var(--btn-4-bg-hover, color-mix(in srgb, var(--btn-4-bg, var(--color-4, #2c7a6e)) 85%, #000));color:var(--btn-4-color-hover, var(--btn-4-color, #fff))}.btn-outline-4,.btn.btn-outline-4{background:transparent;color:var(--btn-4-bg, var(--color-4, #2c7a6e));border:1px solid var(--btn-4-bg, var(--color-4, #2c7a6e));border-radius:var(--btn-4-radius, var(--btn-radius, 4px))}.btn-outline-4:hover,.btn.btn-outline-4:hover{background-color:var(--btn-4-bg-hover, var(--btn-4-bg, var(--color-4, #2c7a6e)));color:var(--btn-4-color-hover, var(--btn-4-color, #fff))}.btn-5,.btn.btn-5{background-color:var(--btn-5-bg, var(--color-5, #2c7a6e));color:var(--btn-5-color, #fff);border-color:var(--btn-5-border-color, transparent);border-width:var(--btn-5-border-width, 0);border-style:solid;border-radius:var(--btn-5-radius, var(--btn-radius, 4px));transition:background-color .18s ease,color .18s ease,border-color .18s ease}.btn-5:hover,.btn.btn-5:hover{background-color:var(--btn-5-bg-hover, color-mix(in srgb, var(--btn-5-bg, var(--color-5, #2c7a6e)) 85%, #000));color:var(--btn-5-color-hover, var(--btn-5-color, #fff))}.btn-outline-5,.btn.btn-outline-5{background:transparent;color:var(--btn-5-bg, var(--color-5, #2c7a6e));border:1px solid var(--btn-5-bg, var(--color-5, #2c7a6e));border-radius:var(--btn-5-radius, var(--btn-radius, 4px))}.btn-outline-5:hover,.btn.btn-outline-5:hover{background-color:var(--btn-5-bg-hover, var(--btn-5-bg, var(--color-5, #2c7a6e)));color:var(--btn-5-color-hover, var(--btn-5-color, #fff))}.btn-6,.btn.btn-6{background-color:var(--btn-6-bg, var(--color-6, #2c7a6e));color:var(--btn-6-color, #fff);border-color:var(--btn-6-border-color, transparent);border-width:var(--btn-6-border-width, 0);border-style:solid;border-radius:var(--btn-6-radius, var(--btn-radius, 4px));transition:background-color .18s ease,color .18s ease,border-color .18s ease}.btn-6:hover,.btn.btn-6:hover{background-color:var(--btn-6-bg-hover, color-mix(in srgb, var(--btn-6-bg, var(--color-6, #2c7a6e)) 85%, #000));color:var(--btn-6-color-hover, var(--btn-6-color, #fff))}.btn-outline-6,.btn.btn-outline-6{background:transparent;color:var(--btn-6-bg, var(--color-6, #2c7a6e));border:1px solid var(--btn-6-bg, var(--color-6, #2c7a6e));border-radius:var(--btn-6-radius, var(--btn-radius, 4px))}.btn-outline-6:hover,.btn.btn-outline-6:hover{background-color:var(--btn-6-bg-hover, var(--btn-6-bg, var(--color-6, #2c7a6e)));color:var(--btn-6-color-hover, var(--btn-6-color, #fff))}
/* AW-BUTTONS:END */

/* Section « En-tête + Img » du builder (classe .header-page) */
.header-page{
    position: relative;
    height: 380px;
    display: flex;
    align-items: center;
}
.header-page .container{position:relative;z-index:2;}
.header-page:after{
    content:'';
    position:absolute;
    top:0;left:0;
    width:90%;
    height:100%;
}

/* ── Menu de catégories (composant « Catégories » du builder de gabarits) ──
   Liens vers les catégories. 3 dispositions : verticale (défaut), horizontale,
   arbre (arborescence via parent_id). Rendu par ModuleTemplateRenderer. */
.module-cat-menu{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.35rem}
.module-cat-menu__item{margin:0}
.module-cat-menu__link{color:inherit;text-decoration:none}
.module-cat-menu__link:hover,.module-cat-menu__link:focus-visible{text-decoration:underline}
/* Horizontale : ligne de liens qui reviennent à la ligne si besoin. */
.module-cat-menu--horizontal{flex-direction:row;flex-wrap:wrap;gap:.5rem 1.1rem;align-items:center}
/* Chips : pastilles (combinable avec vertical/horizontal). */
.module-cat-menu--chips{flex-direction:row;flex-wrap:wrap;gap:.5rem}
.module-cat-menu--chips .module-cat-menu__link{display:inline-block;padding:.25rem .8rem;border:1px solid var(--card-border,#e5e7eb);border-radius:999px;background:var(--card-bg,#fff)}
.module-cat-menu--chips .module-cat-menu__link:hover{text-decoration:none;border-color:var(--color-1,#2c7a6e)}

/* Catégorie ACTIVE (page catégorie) dans le menu liste/chips : « bouton plein » identique
   à .module-wchip.active (btn-1). Vaut pour les 3 dispositions plates. */
.module-cat-menu__item.is-active>.module-cat-menu__link{
  background:var(--btn-1-bg, var(--color-1, #0f172a));
  border-color:var(--btn-1-border-color, var(--btn-1-bg, var(--color-1, #0f172a)));
  color:var(--btn-1-color, #fff);
  border:1px solid var(--btn-1-border-color, var(--btn-1-bg, var(--color-1, #0f172a)));
  border-radius:999px;padding:.25rem .8rem;text-decoration:none;
}
.module-cat-menu__item.is-active>.module-cat-menu__link:hover,
.module-cat-menu__item.is-active>.module-cat-menu__link:focus-visible{
  color:var(--btn-1-color, #fff);
  border-color:var(--btn-1-border-color, var(--btn-1-bg, var(--color-1, #0f172a)));
  text-decoration:none;
}
/* Arbre : arborescence indentée (parent › enfants). */
.module-cat-menu--tree,.module-cat-menu__children{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.3rem}
.module-cat-menu__children{margin-top:.3rem;padding-left:1rem;border-left:1px solid var(--card-border,#e5e7eb)}

/* Arbre de catégories REPLIABLE (composant Catégories, mode « arbre ») — CSS pur
   (astuce checkbox, aucun JS) : le chevron plie/déplie les enfants, décalés à gauche.
   Clic sur le NOM = navigation vers la catégorie ; clic sur le CHEVRON = plier/déplier. */
.cat-tree.module-cat-menu--tree{
  display:block;gap:0;
  background:var(--card-bg,#fff);
  color:var(--card-text,inherit);
  border:var(--card-border-width,1px) solid var(--card-border,transparent);
  border-radius:var(--card-radius,8px);
  box-shadow:var(--card-shadow,0 2px 8px rgba(0,0,0,.08));
  padding:.5rem .4rem;
}
.cat-tree,.cat-tree__children{list-style:none;margin:0;padding:0}
.cat-tree__cb{position:absolute;width:0;height:0;opacity:0;pointer-events:none}
.cat-tree__row{display:flex;align-items:stretch;gap:.15rem;border-radius:6px}
.cat-tree__row:hover{background:var(--hover-bg,rgba(0,0,0,.04))}
.cat-tree__link{flex:1 1 auto;min-width:0;display:block;padding:.45rem .4rem;color:inherit;text-decoration:none;line-height:1.3}
.cat-tree__link:hover,.cat-tree__link:focus-visible{color:var(--color-primary,#f5a623);text-decoration:none}
.cat-tree__node--branch>.cat-tree__row>.cat-tree__link{font-weight:600}
.cat-tree__node--leaf>.cat-tree__row>.cat-tree__link{color:var(--muted,#6b7280);font-weight:400}
.cat-tree__link--active{color:var(--color-primary,#f5a623)!important;font-weight:700}
.cat-tree__toggle{flex:0 0 auto;width:2rem;display:flex;align-items:center;justify-content:center;cursor:pointer;color:inherit}
.cat-tree__toggle::before{content:"";width:.48rem;height:.48rem;border:solid currentColor;border-width:0 2px 2px 0;transform:rotate(-45deg);transition:transform .18s ease}
.cat-tree__children{display:none;margin-left:.7rem;padding-left:.65rem;border-left:1px solid var(--card-border,#e5e7eb)}
.cat-tree__cb:checked~.cat-tree__children{display:block}
.cat-tree__cb:checked~.cat-tree__row>.cat-tree__toggle::before{transform:rotate(45deg)}
.cat-tree__cb:focus-visible~.cat-tree__row .cat-tree__toggle{outline:2px solid var(--color-primary,#f5a623);outline-offset:2px;border-radius:4px}

/* ============================================================================
   Page 404 (front) — vue app/Views/front/errors/404.php
   Aucune couleur en dur : l'accent vient du bouton 1 du thème, le texte de la
   couleur de corps. Un thème qui change de palette change sa 404 avec elle.
   ========================================================================== */
.aw404{--aw404-accent:var(--btn-1-bg,#0d6efd);--aw404-ink:var(--body-text,#212529);padding:clamp(3rem,10vh,7rem) 0}
.aw404__num{position:relative;display:inline-block;font-weight:800;line-height:.85;
  font-size:clamp(6rem,22vw,13rem);letter-spacing:-.04em;color:var(--aw404-accent)}
/* Calque « fantôme » décalé : effet d'impression décalée, sans image ni police extérieure. */
.aw404__num::before{content:"404";position:absolute;inset:0;transform:translate(.09em,.07em);
  color:var(--aw404-ink);opacity:.10;z-index:-1}
.aw404__num span{display:inline-block;animation:aw404-float 6s ease-in-out infinite}
.aw404__num span:nth-child(2){animation-delay:-2s}
.aw404__num span:nth-child(3){animation-delay:-4s}
@keyframes aw404-float{0%,100%{transform:translateY(0)}50%{transform:translateY(-.045em)}}
.aw404__lead{max-width:34rem;margin-inline:auto;color:var(--aw404-ink);opacity:.75}
.aw404__search{max-width:30rem;margin-inline:auto}
.aw404__sugg a{color:var(--aw404-ink);opacity:.8;text-decoration:none;border-bottom:1px solid currentColor}
.aw404__sugg a:hover{opacity:1}
/* Mouvement réduit : l'animation est un ornement, jamais une information. */
@media (prefers-reduced-motion:reduce){.aw404__num span{animation:none}}

/* ============================================================================
   Formulaires — retour après soumission (app.js : showSuccess / showError)
   Le panneau de confirmation remplace le formulaire ; le bloc d'erreur reste
   au-dessus. Coche dessinée en CSS : Font Awesome est chargé en asynchrone,
   une icône de fonte clignoterait au premier rendu.
   ========================================================================== */
.form-success-msg--panel{display:flex;flex-direction:column;align-items:center;gap:.9rem;
  text-align:center;padding:2.25rem 1.5rem;border-radius:14px;
  background:var(--body-bg,#fff);border:1px solid rgba(25,135,84,.35);box-shadow:0 6px 24px rgba(0,0,0,.10)}
.form-success-msg--panel:focus{outline:2px solid rgba(25,135,84,.45);outline-offset:2px}
.form-success-msg__icon{position:relative;flex:0 0 auto;width:56px;height:56px;border-radius:50%;
  background:#198754;animation:awform-pop .28s cubic-bezier(.34,1.56,.64,1) both}
.form-success-msg__icon::after{content:"";position:absolute;left:50%;top:47%;
  width:12px;height:22px;border:solid #fff;border-width:0 3px 3px 0;
  transform:translate(-50%,-50%) rotate(45deg);transform-origin:center}
.form-success-msg__text{margin:0;font-size:1.05rem;font-weight:600;color:var(--body-text,#212529)}
.form-success-msg__again{align-self:center}
@keyframes awform-pop{from{transform:scale(.4);opacity:0}to{transform:scale(1);opacity:1}}

.form-error-msg:not(.d-none){display:flex;align-items:flex-start;gap:.6rem;
  padding:.85rem 1rem;margin-bottom:1rem;border-radius:10px;
  background:var(--body-bg,#fff);border:1px solid rgba(220,53,69,.38);color:#842029;box-shadow:0 4px 16px rgba(0,0,0,.08)}
.form-error-msg:not(.d-none)::before{content:"!";flex:0 0 auto;width:1.35rem;height:1.35rem;
  border-radius:50%;background:#dc3545;color:#fff;font-weight:700;line-height:1.35rem;
  text-align:center;font-size:.9rem}
.form-error-msg:focus{outline:2px solid rgba(220,53,69,.45);outline-offset:2px}

/* L'animation est un ornement : jamais requise pour comprendre le message. */
@media (prefers-reduced-motion:reduce){.form-success-msg__icon{animation:none}}

/* ─── Carte événement avec marqueurs d attributs ────────────────────────────
   Variante de `.module-card--event` : sous l image, une ligne « marqueurs +
   catégorie » puis l accroche. Les interrupteurs y sont des icônes (leur
   valeur « Oui » n est pas imprimée), d où une rangée compacte. */
/* Dégondé de la variante : la rangée de marqueurs vaut pour TOUTE carte où l on
   dépose le composant Attributs, pas pour un gabarit particulier. Auparavant ces
   règles exigeaient la classe .module-card--event-attrs, que seul un gabarit livré
   portait — ajouter des attributs à une autre carte donnait une pile au lieu d une
   ligne. Le ciblage passe donc par la PRÉSENCE de la rangée. */
.module-card__markers {
    display: flex; align-items: center; flex-wrap: wrap; gap: .35rem .75rem; margin-bottom: .5rem;
}
.module-card__markers .module-card__attrs { min-width: 0; }
.module-card__markers .module-card__attrs .module-attrs { margin: 0; }
.module-card__markers .module-card__category { margin: 0; font-weight: 600; }
.module-card:has(.module-card__markers) .module-card__excerpt { margin: 0; }

/* Publication SANS attributs : `.module-card__attrs` reste dans le DOM (markup constant,
   pas de PHP conditionnel) mais, VIDE, il compte quand même comme élément flex → le `gap`
   de `.module-card__markers` décalait la catégorie. `:empty` le retire du flux (et retire
   la rangée entière si elle est vide) → plus aucun décalage. */
.module-card__attrs:empty,
.module-card__markers:empty { display: none; }

/* …mais `:empty` ne suffit pas : l'enveloppe contient souvent un `<dl>` VIDE, et
   n'est donc pas elle-même vide. Cas courant — la publication a bien des attributs
   déclarés, mais aucun ne s'affiche (interrupteurs éteints, cf.
   `_attributes_values.php` qui ouvre le <dl> puis saute chaque ligne). L'élément
   mesure alors 0 × 0, reste un enfant flex, et consomme le `gap` du conteneur :
   la catégorie se retrouve décalée par rapport aux cartes voisines. */
.module-attrs:empty { display: none; }
.module-card__attrs:has(> .module-attrs:empty) { display: none; }
.module-card__markers:has(> .module-card__attrs:only-child > .module-attrs:empty) { display: none; }

/* ─── Filtre par attributs (composant de gabarit) ───────────────────────────
   Mêmes puces que les autres filtres ; l icône de l attribut précède son nom. */
.module-attrfilter--component { display: flex; flex-wrap: wrap; gap: .5rem; margin: 0 0 1rem; }
.module-attrfilter--component .module-wchip { display: inline-flex; align-items: center; gap: .4rem; }

/* ===================================================================
   Filtres (catégories / attributs / dates) — couleur de la CHARTE
   -------------------------------------------------------------------
   L'état actif était figé sur le bouton 1 de la charte. Les gabarits
   peuvent désormais choisir lequel des 7 styles de bouton colore leurs
   puces : le wrapper porte `--btn-N` et pose trois variables locales,
   consommées par une règle unique. Sans classe → bouton 1, comme avant.
=================================================================== */
.module-wfilter--btn-1,.module-cat-menu--btn-1{--f-bg:var(--btn-1-bg,var(--color-1,#0f172a));--f-color:var(--btn-1-color,#fff);--f-border:var(--btn-1-border-color,var(--btn-1-bg,var(--color-1,#0f172a)))}
.module-wfilter--btn-2,.module-cat-menu--btn-2{--f-bg:var(--btn-2-bg,var(--color-2,#0f172a));--f-color:var(--btn-2-color,#fff);--f-border:var(--btn-2-border-color,var(--btn-2-bg,var(--color-2,#0f172a)))}
.module-wfilter--btn-3,.module-cat-menu--btn-3{--f-bg:var(--btn-3-bg,var(--color-3,#0f172a));--f-color:var(--btn-3-color,#fff);--f-border:var(--btn-3-border-color,var(--btn-3-bg,var(--color-3,#0f172a)))}
.module-wfilter--btn-4,.module-cat-menu--btn-4{--f-bg:var(--btn-4-bg,var(--color-4,#0f172a));--f-color:var(--btn-4-color,#fff);--f-border:var(--btn-4-border-color,var(--btn-4-bg,var(--color-4,#0f172a)))}
.module-wfilter--btn-5,.module-cat-menu--btn-5{--f-bg:var(--btn-5-bg,var(--color-5,#0f172a));--f-color:var(--btn-5-color,#fff);--f-border:var(--btn-5-border-color,var(--btn-5-bg,var(--color-5,#0f172a)))}
.module-wfilter--btn-6,.module-cat-menu--btn-6{--f-bg:var(--btn-6-bg,var(--color-6,#0f172a));--f-color:var(--btn-6-color,#fff);--f-border:var(--btn-6-border-color,var(--btn-6-bg,var(--color-6,#0f172a)))}
.module-wfilter--btn-7,.module-cat-menu--btn-7{--f-bg:var(--btn-7-bg,var(--color-7,#0f172a));--f-color:var(--btn-7-color,#fff);--f-border:var(--btn-7-border-color,var(--btn-7-bg,var(--color-7,#0f172a)))}

/* Consommation : une seule règle pour les puces ET les catégories actives. */
.module-wfilter[class*="--btn-"] .module-wchip.active{
  background:var(--f-bg);border-color:var(--f-border);color:var(--f-color);
}
.module-cat-menu[class*="--btn-"] .module-cat-menu__item.is-active>.module-cat-menu__link,
.module-cat-menu[class*="--btn-"] .module-cat-menu__item.is-active>.module-cat-menu__link:hover,
.module-cat-menu[class*="--btn-"] .module-cat-menu__item.is-active>.module-cat-menu__link:focus-visible{
  background:var(--f-bg);border-color:var(--f-border);color:var(--f-color);
}

/* Filtre par attributs : disposition et style, alignés sur la barre de
   catégories — les deux rendent les mêmes puces, elles se règlent pareil. */
.module-wfilter--vertical{flex-direction:column;align-items:flex-start}
.module-wfilter--menu .module-wchip{
  border-radius:0;border:0;background:none;padding:.25rem 0;margin-right:1rem;
}
.module-wfilter--menu .module-wchip.active{
  background:none;color:var(--f-bg,var(--btn-1-bg,var(--color-1,#0f172a)));font-weight:600;
}

/* Puces d'étiquettes. Le thème n'habillait `.module-card__tag` QUE sous
   `.module-card__overlay`, où la règle le remet À PLAT (fond transparent, sans
   rembourrage) pour qu'il tienne sur une image — un dégrossissage qui suppose
   une puce de base. Cette base-là manquait : hors overlay, les <span> se
   suivaient sans séparation (« 2026barbentanecompétition »). Même vocabulaire
   que `.module-wchip` — pilule 999px — mais en retrait : une étiquette se lit,
   elle ne se clique pas. À garder AVANT `--more`, qui n'override que la
   bordure et la couleur et hérite d'ici son gabarit. */
.module-card__tags { display: flex; flex-wrap: wrap; gap: 6px; }
.module-card__tag {
  display: inline-block; border: 1px solid var(--card-border, #e5e7eb);
  border-radius: 999px; padding: 3px 10px; font-size: 12px; line-height: 1.35;
  background: #f8fafc; color: var(--text-muted, #64748b);
}
/* Variante TEXTE (`{tags}` en style « texte ») : un <p> de noms séparés par des
   virgules, sans <span>. La puce ci-dessus en ferait un conteneur flex — le
   texte deviendrait UN seul élément anonyme, donc plus de retour à la ligne et
   débordement dès que la liste s'allonge. Elle reste du texte qui coule. */
.module-card__tags--text { display: block; }
/* Tags repliés : le bouton « +N » reprend l'aspect d'un tag, en plus discret.
   `hidden` sur le bloc replié → réellement absent de l'arbre d'accessibilité. */
.module-card__tag--more{
  border:1px dashed var(--card-border,#e5e7eb);background:none;cursor:pointer;
  color:var(--text-muted,#64748b);font:inherit;font-size:12px;
}
.module-card__tag--more:hover{border-style:solid}
.module-card__tag--more[aria-expanded="true"]{border-style:solid}
/* Mention format/poids d'un fichier : lisible mais en retrait du nom. */
.module-card__file-meta{color:var(--text-muted,#64748b);font-size:.85em}

/* ------------------------------------------------------------------
   Filtres en tiroir (mobile / tablette) — cf. app.js
   Les filtres sont DÉPLACÉS dans un offcanvas sous 992 px ; au-dessus ils
   retournent à leur place dans le gabarit. Ce bloc n'habille que le tiroir et
   son bouton : il ne redéfinit RIEN sur les filtres eux-mêmes, qui doivent
   rester identiques dans les deux emplacements.
   ------------------------------------------------------------------ */
.aw-filters__ouvrir {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    margin: .25rem 0 .75rem;
}

.aw-filters {
    /* Un tiroir pleine largeur écrase la page ; on garde le contexte visible. */
    max-width: 90vw;
    width: 22rem;
    background: var(--body-bg, #fff);
    color: var(--body-text, #111827);
}

.aw-filters .offcanvas-header {
    border-bottom: 1px solid var(--border-color, rgba(0, 0, 0, .1));
}

.aw-filters .offcanvas-body {
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
}

/* Pied collé en bas, hors de la zone défilante : « Voir les résultats » doit
   rester atteignable même avec une longue liste de catégories. */
.aw-filters__pied {
    padding: 1rem;
    border-top: 1px solid var(--border-color, rgba(0, 0, 0, .1));
}

/* Dans le tiroir, les filtres passent en pleine largeur : les alignements posés
   par le gabarit (recherche calée à droite d'une colonne 4/12, par exemple) n'ont
   plus de sens dans une colonne étroite. */
.aw-filters .aw-composant,
.aw-filters .module-index-toolbar,
.aw-filters .module-index-toolbar__filters {
    width: 100%;
    max-width: none;
    padding: 0;
    display: block;
}

.aw-filters .module-search {
    max-width: none;
}

/* Les groupes de puces s'empilent plutôt que de déborder de la colonne étroite. */
.aw-filters .module-wfilter,
.aw-filters .module-cats,
.aw-filters .module-cat-menu {
    flex-wrap: wrap;
    gap: .5rem;
}

/* La recherche EN PREMIER : dans un tiroir, c'est l'action directe ; les puces
   viennent après. `order` suffit — aucun déplacement de nœud, donc rien à défaire
   au retour desktop. Requiert que le conteneur soit en colonne (ci-dessous). */
.aw-filters .module-index-toolbar,
.aw-filters .module-index-toolbar__filters {
    display: flex;
    flex-direction: column;
    /* Faible : l'espacement ENTRE GROUPES est porté par le filet de l'intitulé. Un
       grand `gap` s'appliquerait aussi entre un intitulé et ses propres puces, qui
       se retrouvaient séparés de 56 px alors qu'ils forment un bloc. */
    gap: .5rem;
}

.aw-filters .module-index-search,
.aw-filters .aw-composant--search {
    order: -1;
}

/* Intitulé de groupe (posé par app.js depuis l'aria-label du groupe). Sans lui,
   périodes et catégories forment un seul pavé de puces indistinct.

   Le FILET est porté par l'intitulé, pas par « chaque enfant sauf le premier » :
   l'intitulé et ses puces sont deux enfants distincts du conteneur, si bien qu'une
   règle générique traçait le trait ENTRE le titre et ses propres puces — soit
   exactement l'inverse du regroupement voulu (constaté). */
.aw-filters__legende {
    /* La barre d'outils centre ses enfants ; dans le tiroir les puces sont calées à
       gauche, un intitulé centré jurerait — et son filet, réduit à la largeur du
       texte, ne lisait plus comme un séparateur de groupe. */
    align-self: stretch;
    text-align: left;
    margin: 0 0 .75rem;
    font-size: .8125rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .04em;
    opacity: .6;
}

.aw-filters__legende:not(:first-child) {
    border-top: 1px solid var(--card-border, rgba(0, 0, 0, .08));
    padding-top: 1.25rem;
}

/* Cibles tactiles : les puces mesuraient 28 px de haut, sous le minimum
   confortable au doigt. Portée au tiroir UNIQUEMENT — le desktop, pointé à la
   souris, garde sa densité. */
.aw-filters .module-wchip,
.aw-filters .module-cat-menu__link {
    min-height: 40px;
    display: inline-flex;
    align-items: center;
    padding: .5rem .9rem;
}

/* Dans une liste verticale, une catégorie non stylée en pastille (disposition
   « horizontale » du gabarit) n'a aucune zone cliquable évidente : on lui en donne
   une, sans toucher à son rendu hors tiroir.

   ⚠️ `:not(.is-active)` INDISPENSABLE. Sans lui, cette règle — plus tardive dans le
   fichier, à spécificité égale — écrasait le fond de la catégorie ACTIVE tout en
   laissant sa couleur de texte blanche : pastille pâle et libellé illisible dans le
   tiroir, alors qu'il est plein sur le bureau (constaté). L'état actif garde donc
   entièrement la main. */
.aw-filters .module-cat-menu--horizontal .module-cat-menu__item:not(.is-active) > .module-cat-menu__link {
    border: 1px solid var(--card-border, #e5e7eb);
    border-radius: 999px;
    background: var(--card-bg, #fff);
}

/* Le champ de recherche occupe la largeur : dans un tiroir, rien ne justifie de le
   plafonner comme dans une colonne de gabarit.

   ⚠️ Champ et bouton doivent rester SUR UNE LIGNE. Un simple `width:100%` sur
   l'input le faisait occuper toute la rangée et renvoyait la loupe en dessous
   (constaté) : c'est `flex:1` qui donne la largeur, pas `width`. */
.aw-filters .module-search {
    display: flex;
    flex-wrap: nowrap;
    align-items: stretch;
    width: 100%;
    max-width: none;
}

.aw-filters .module-search input {
    flex: 1 1 auto;
    width: auto;
    min-width: 0; /* sans quoi la largeur intrinsèque de l'input déborde du flex */
    max-width: none;
}

.aw-filters .module-search .module-search__btn,
.aw-filters .module-search .btn {
    flex: 0 0 auto;
}

/* Composant « Articles similaires » (maillage interne SEO) */
.module-detail__related{margin-top:2.5rem;padding-top:2rem;border-top:1px solid var(--aw-border,rgba(0,0,0,.08))}
.module-detail__related-title{font-size:1.35rem;line-height:1.2;margin:0 0 1.25rem}

/* ===================================================================
   AWShare — modale de partage : tenue mobile (jamais de débordement).
   La modale (construite en JS, classes Bootstrap) rendait plus large que
   l'écran sur mobile : le dialogue en width auto n'était pas plafonné → le
   côté droit (✕, dernier réseau, bouton « Copier ») était coupé. On plafonne
   fermement la largeur, on coupe toute fuite et on laisse l'input du lien
   rétrécir dans son groupe (un lien long ne doit pas élargir la modale).
   =================================================================== */
#awShareModal .modal-dialog{max-width:460px}
@media (max-width:575.98px){
    /* Marges nettes de chaque côté, sans plafond en 100vw (qui compte la barre de
       défilement → léger débordement). width auto = remplit .modal (en %) moins les
       marges → jamais plus large que l'écran. */
    #awShareModal .modal-dialog{max-width:none;margin:.75rem}
}
#awShareModal .modal-content{overflow:hidden}          /* respecte l'arrondi + coupe toute fuite */
#awShareModal .aw-share-url{min-width:0}                /* input flex : peut rétrécir (lien long) */
/* Rangée des réseaux : les boutons s'ADAPTENT à la largeur dispo — ils grandissent
   pour remplir la ligne (base ~72px, plafonnés) et s'enroulent selon la place ;
   la dernière ligne reste recentrée (justify-content-center déjà présent). Résultat :
   plus de « 2e ligne vide », et un rendu qui suit l'espace disponible. */
#awShareModal .aw-share-net{flex:1 1 72px;max-width:96px;min-width:0}

/* Ligne de date d'une carte dont le jeton ne résout rien (module hors mode
   « événements ») : sans cette règle il resterait une icône de calendrier suivie
   du vide. On teste le span porteur du jeton, l'icône étant un frère — même motif
   que `.module-card__attrs:empty` plus haut. */
.module-card__date--range:has(> .module-card__date-val:empty) { display: none; }

/* Ligne de date dont le jeton ne resout rien (module hors mode evenements) :
   sans cette regle il resterait une icone de calendrier suivie du vide. On teste
   le SPAN porteur du jeton, l icone etant un frere — meme motif que
   `.module-card__attrs:empty` plus haut. */
.module-card__date--range:has(> .module-card__date-val:empty) { display: none; }
