/* ═══════════════════════════════════════════════════════════════════════════
   SYSTÈME D'INTERFACE DU FRONT OFFICE

   POURQUOI CE FICHIER. Un relevé des feuilles du front a trouvé 184 règles de
   type « bouton » ou « pastille », réparties sur 25 feuilles, avec 15 tailles de
   texte, 6 hauteurs et 27 remplissages différents. Autrement dit : le même objet
   était redessiné à chaque page, un peu différemment. Le résultat se voyait,
   surtout dans la colonne de filtres, où quatre tailles de pastilles se
   côtoyaient et où les listes centrées s'échelonnaient n'importe comment.

   CE QUE CE FICHIER EST. La source unique des contrôles du front : champs,
   boutons, pastilles de sélection, panneaux repliables. Une seule échelle de
   tailles, un seul rayon par famille d'objet, un seul état actif.

   COMMENT S'EN SERVIR. Toute nouvelle interface du front utilise ces classes.
   On n'ajoute pas une variante « juste pour cette page » : soit le besoin existe
   ailleurs et il devient un modificateur ici, soit il n'existe pas et on se
   passe de la variante.

   RÈGLE DE MISE EN PAGE LA PLUS IMPORTANTE : les listes de pastilles sont
   ALIGNÉES À GAUCHE. Centrées, elles produisent des lignes de longueurs
   inégales et un dernier élément esseulé au milieu, ce qui donne exactement
   l'impression de désordre qu'on cherche à éviter.
   ═══════════════════════════════════════════════════════════════════════════ */

:root{
    /* Couleurs, reprises de la palette du site (front/css/variable.css) */
    --ui-accent: #B3C4FF;
    --ui-accent-strong: #8B78C4;
    --ui-surface: #ffffff;
    --ui-surface-soft: #F8F6FF;
    --ui-surface-active: #EDE7FF;
    --ui-border: #DADADA;
    --ui-border-soft: #EDE7FF;
    --ui-border-active: #B9A6FF;
    --ui-text: #1F1F1F;
    --ui-text-muted: #6B6B6B;
    --ui-dark: #000000;
    --ui-on-dark: #ffffff;

    /* Rayons : un par famille d'objet, pas un par page */
    --ui-r-field: 12px;
    --ui-r-card: 16px;
    --ui-r-pill: 999px;

    /* Hauteurs de contrôle : trois, pas quinze */
    --ui-h-sm: 34px;
    --ui-h-md: 44px;
    --ui-h-lg: 52px;

    /* Tailles de texte des contrôles */
    --ui-fs-sm: 15px;
    --ui-fs-md: 17px;
    --ui-fs-lg: 19px;

    --ui-gap: 8px;
    --ui-gap-lg: 14px;

    --ui-focus: 0 0 0 3px rgba(179, 196, 255, 0.55);

    /* Focus CLAVIER : contour net, posé sur les seules règles :focus-visible.
       Le halo --ui-focus ne faisait que 1,1 à 1,3:1 ; il reste pour les champs
       (qui le prennent aussi au toucher et à la souris : un contour y ferait un
       double trait) et pour l'état ouvert d'une liste. */
    --ui-focus-outline: 2px solid #4D3DFF;
}

/* ── Rythme vertical ─────────────────────────────────────────────────────── */

/* Empile des contrôles avec un écart constant. Remplace les <span> séparateurs
   posés à la main, qui n'avaient pas toujours le même espacement autour. */
.ui-stack{
    display: flex;
    flex-direction: column;
    gap: var(--ui-gap-lg);
    width: 100%;
}

.ui-stack--tight{
    gap: var(--ui-gap);
}

/* ── Icônes ──────────────────────────────────────────────────────────────────

   Le jeu est dans templates/front/_icons.html.twig. Elles sont DÉCORATIVES :
   elles accompagnent un texte qui se suffit à lui-même, jamais un texte qu'elles
   remplacent. Le trait prend la couleur du texte autour, elles se fondent donc
   dans leur contexte sans réglage. */
.ui-icon{
    flex-shrink: 0;
    vertical-align: -0.18em;
}

/* Titre précédé de son icône : alignés sur leur première ligne, et non centrés,
   pour qu'un titre qui passe sur deux lignes garde son icône en tête. */
.ui-titleIcon{
    display: flex;
    align-items: flex-start;
    gap: 10px;
}

.ui-titleIcon .ui-icon{
    margin-top: 0.18em;
    color: var(--ui-accent-strong);
}

/* Ligne de liste : une puce dessinée plutôt qu'un tiret tapé dans le texte, qui
   se retrouvait lu à voix haute et se copiait avec le texte. L'icône est
   décorative, la ligne se lit sans elle. */
.ui-listItem{
    display: flex;
    align-items: flex-start;
    gap: 8px;
}

.ui-listItem .ui-icon{
    margin-top: 0.2em;
    color: var(--ui-accent-strong);
}

/* Ligne d'information d'une carte (lieu, tarif) : l'icône garde sa place quand le
   texte passe sur deux lignes, d'où le span autour du texte et l'alignement en
   tête de ligne. Le trait reste gris comme le texte : ces repères se rangent
   derrière le nom du professionnel, ils ne se disputent pas la lecture avec lui. */
.ui-metaLine{
    display: flex;
    align-items: flex-start;
    gap: 6px;
}

.ui-metaLine .ui-icon{
    margin-top: 0.15em;
    opacity: 0.75;
}

/* Ligne d'information qui tient sur une seule ligne et se coupe en « ... » quand
   elle déborde (cartes de carrousel, toutes de même hauteur). La coupure porte
   sur le texte, pas sur la ligne : sans min-width: 0 l'élément flex refuse de
   rétrécir sous la largeur de son contenu et déborde au lieu de se couper. */
.ui-metaLine--truncate{
    align-items: center;
}

.ui-metaLine--truncate > span{
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.ui-metaLine--truncate .ui-icon{
    margin-top: 0;
}

/* ── Libellés et aides ───────────────────────────────────────────────────── */

.ui-label{
    display: block;
    margin-bottom: 6px;
    font-family: 'Afacad';
    font-size: var(--ui-fs-sm);
    color: var(--ui-text-muted);
    text-align: left;
}

.ui-hint{
    margin: 0 0 10px;
    font-family: 'Afacad';
    font-size: var(--ui-fs-sm);
    line-height: 1.4;
    color: var(--ui-text-muted);
    text-align: left;
}

/* ── Champ de saisie ─────────────────────────────────────────────────────── */

.ui-field{
    display: flex;
    align-items: center;
    gap: 10px;
    box-sizing: border-box;
    width: 100%;
    min-height: var(--ui-h-md);
    padding: 0 16px;
    background-color: var(--ui-surface-soft);
    border: 1px solid transparent;
    border-radius: var(--ui-r-pill);
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.ui-field:focus-within{
    border-color: var(--ui-accent-strong);
    box-shadow: var(--ui-focus);
}

.ui-field__icon{
    flex-shrink: 0;
    color: var(--ui-text);
}

/* Points de suite : un texte indicatif plus long que le champ finit par « … »
   au lieu d'une lettre coupée en deux (« Nom, prestation, mot-clé... » dans
   la carte de filtres à 280 et 320 px, « Code postal ou ville » à 280 px). */
.ui-field__input{
    width: 100%;
    min-width: 0;
    border: 0;
    background: transparent;
    font-family: 'Afacad';
    font-size: var(--ui-fs-md);
    color: var(--ui-text);
    text-overflow: ellipsis;
}

.ui-field__input:focus{
    outline: none;
}

.ui-field__input::placeholder{
    color: var(--ui-text-muted);
}


/* ── Champ de formulaire ─────────────────────────────────────────────────────

   Rectangulaire et non en pastille : un champ de saisie long (un message, une
   adresse) se lit mieux dans une forme qui ne courbe pas ses extrémités. La
   pastille reste pour les champs courts d’une barre de recherche. */

.ui-input{
    box-sizing: border-box;
    width: 100%;
    min-height: var(--ui-h-md);
    padding: 10px 14px;
    /* Explicite, et non laissee au navigateur : une liste deroulante posee a
       cote doit tomber exactement a la meme hauteur. */
    line-height: 1.5;
    background-color: var(--ui-surface);
    border: 1px solid var(--ui-border);
    border-radius: var(--ui-r-field);
    color: var(--ui-text);
    font-family: 'Afacad';
    font-size: var(--ui-fs-md);
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.ui-input::placeholder{
    color: var(--ui-text-muted);
}

.ui-input:focus{
    outline: none;
    border-color: var(--ui-accent-strong);
    box-shadow: var(--ui-focus);
}

/* Champ en erreur. L'état vient de l'attribut aria-invalid, posé par le script de
   la page (ou par form_row de Symfony) : ce qui se voit est ce que lit le lecteur
   d'écran, sans classe à tenir à jour à côté. Même rouge que .ui-formError.
   Déclaré après :focus, pour que la bordure reste rouge quand le champ a le focus. */
.ui-input[aria-invalid='true']{
    border-color: #C01919;
}

.ui-input[aria-invalid='true']:focus{
    box-shadow: 0 0 0 3px rgba(192, 25, 25, 0.2);
}

.ui-input--area{
    min-height: 130px;
    resize: vertical;
    line-height: 1.45;
}

/* Libellé d’un champ de formulaire : plus affirmé que .ui-label, qui sert aux
   aides et aux groupes de pastilles. */
.ui-formLabel{
    display: block;
    margin-bottom: 6px;
    font-family: 'Afacad';
    font-size: var(--ui-fs-md);
    font-weight: 500;
    color: var(--ui-text);
}

.ui-formError{
    display: block;
    min-height: 18px;
    font-family: 'Afacad';
    font-size: var(--ui-fs-sm);
    color: #C01919;
}

/* ── Boutons ─────────────────────────────────────────────────────────────── */

.ui-btn{
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    box-sizing: border-box;
    min-height: var(--ui-h-md);
    padding: 0 22px;
    background-color: var(--ui-surface);
    border: 1px solid var(--ui-border);
    border-radius: var(--ui-r-pill);
    color: var(--ui-text);
    font-family: 'Afacad';
    font-size: var(--ui-fs-md);
    text-decoration: none;
    cursor: pointer;
    transition: background-color 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
}

/* SURVOLS RÉSERVÉS AUX POINTEURS QUI SURVOLENT (souris, pavé). Au doigt, l'état
   de survol reste posé sur l'élément touché jusqu'au toucher suivant : une
   pastille décochée gardait la bordure du survol, un bouton sa teinte. Chaque
   règle :hover du système est donc enveloppée dans @media (hover: hover) ; au
   doigt, le retour passe par l'état coché ou ouvert et par :focus-visible. */
@media (hover: hover){
    .ui-btn:hover{
        color: var(--ui-text);
        border-color: var(--ui-accent-strong);
    }
}

/* Sans box-shadow : le bouton accent garde son relief quand il a le focus */
.ui-btn:focus-visible{
    outline: var(--ui-focus-outline);
    outline-offset: 2px;
}

/* Lien posé dans un bouton (numéro révélé à la place de « Nous contacter », qui
   reçoit alors le focus) : le contour entoure le bouton entier et non le seul
   texte. Sans :has(), l'anneau du navigateur reste sur le lien. */
@supports selector(:has(a)){
    .ui-btn:has(> a:focus-visible){
        outline: var(--ui-focus-outline);
        outline-offset: 2px;
    }

    .ui-btn > a:focus-visible{
        outline: none;
    }
}

/* style.css impose Poppins 500 à TOUT élément (sélecteur *) : un <span> ou un
   lien posé dans un composant (« Nous contacter » et le numéro révélé à sa
   place, « Envoyer » du contact, libellés des options) perdait la police et la
   graisse du composant. Enfants directs seulement : une icône de police posée
   dans un bouton garde la sienne. */
.ui-btn > span,
.ui-btn > a,
.ui-select__optionLabel{
    font-family: inherit;
    font-weight: inherit;
}

/* QUATRE RÔLES, PAS UN PAR PAGE.

   (sans modificateur) Action ordinaire : blanche, bordée. C'est le défaut,
                       et c'est ce qu'on utilise quand on hésite.
   --accent            L'action signature du site, celle qu'on veut voir :
                       le bleu lavande et son relief, déjà ceux des fiches.
                       Une seule par écran.
   --strong            Validation dans un contexte dense, où le lavande se
                       noierait parmi les pastilles : le noir tranche.
   --quiet             Annuler, réinitialiser. Ne doit pas attirer l'oeil. */

.ui-btn--accent{
    background-color: var(--ui-accent);
    border-color: var(--ui-accent);
    color: var(--ui-text);
    box-shadow:
        0 1px 4px 0 rgba(0, 0, 0, 0.25),
        inset 0 4px 10px 6px rgba(255, 255, 255, 0.35),
        inset 0 -4px 4px 0 rgba(0, 0, 0, 0.15);
}

@media (hover: hover){
    .ui-btn--accent:hover{
        color: var(--ui-text);
        background-color: #9FB4FF;
        border-color: #9FB4FF;
    }
}

.ui-btn--strong{
    background-color: var(--ui-dark);
    border-color: var(--ui-dark);
    color: var(--ui-on-dark);
}

@media (hover: hover){
    .ui-btn--strong:hover{
        color: var(--ui-on-dark);
        background-color: #2a2a2a;
        border-color: #2a2a2a;
    }
}

.ui-btn--quiet{
    background-color: transparent;
    border-color: transparent;
    color: var(--ui-text-muted);
}

@media (hover: hover){
    .ui-btn--quiet:hover{
        background-color: var(--ui-surface-soft);
        border-color: transparent;
        color: var(--ui-text);
    }
}

/* Bouton rond, pour une icône seule (fermer, flèche de carrousel) */
.ui-btn--icon{
    width: var(--ui-h-md);
    min-height: var(--ui-h-md);
    padding: 0;
    border-radius: 50%;
}

/* padding: 0 répété ici, et ce n'est pas un doublon. .ui-btn--sm est déclarée
   PLUS BAS avec « padding: 0 16px », à specificité égale de .ui-btn--icon : elle
   l'emportait donc, et un bouton à la fois rond et petit se retrouvait avec
   32 px de retrait dans 34 px de large. Il restait 2 px pour l'icône, qui
   s'écrasait à 0 (mesuré sur le bouton de la barre de recherche flottante, dont
   la loupe avait disparu). */
.ui-btn--icon.ui-btn--sm{
    width: var(--ui-h-sm);
    min-height: var(--ui-h-sm);
    padding: 0;
}

/* Une icône ne se comprime jamais pour tenir dans son bouton : elle disparaît
   sans bruit au lieu de faire déborder, et le défaut passe inaperçu. Les SVG
   écrits à la main dans les gabarits ne portent pas tous la classe ui-icon,
   d'où la règle sur svg plutôt que sur .ui-icon. */
.ui-btn > svg{
    flex-shrink: 0;
}

.ui-btn--sm{
    min-height: var(--ui-h-sm);
    padding: 0 16px;
    font-size: var(--ui-fs-sm);
}

.ui-btn--lg{
    min-height: var(--ui-h-lg);
    padding: 0 28px;
    font-size: var(--ui-fs-lg);
}

.ui-btn--block{
    width: 100%;
}

.ui-btn[disabled],
.ui-btn.is-disabled{
    opacity: 0.5;
    pointer-events: none;
}

/* ── Barre de recherche horizontale ──────────────────────────────────────── */

/* Le bandeau de l'accueil et la barre flottante avaient chacun leur version de
   cet objet, avec des hauteurs et des rayons différents. C'est le même objet :
   une gouttière blanche qui contient des segments séparés par un filet, et une
   action au bout.

   Elle ne se replie PAS en colonne sous une certaine largeur : c'est le rôle de
   la page de décider, parce que le bandeau et la barre flottante n'ont pas les
   mêmes contraintes de place. */
.ui-searchbar{
    display: flex;
    align-items: center;
    box-sizing: border-box;
    width: 100%;
    padding: 7px;
    background-color: var(--ui-surface);
    border: 1px solid var(--ui-border-soft);
    border-radius: var(--ui-r-pill);
    box-shadow: 0 2px 12px rgba(15, 23, 42, 0.10);
}

.ui-searchbar__segment{
    display: flex;
    align-items: center;
    gap: 10px;
    flex: 1 1 0;
    min-width: 0;
    padding: 0 16px;
}

.ui-searchbar__segment > svg{
    flex-shrink: 0;
}

/* Points de suite, comme .ui-field__input (« Où ? Paris, 93200, Versailles... »
   du bandeau de l'accueil, plus large que son segment à 280 et 320 px). */
.ui-searchbar__input{
    width: 100%;
    min-width: 0;
    min-height: var(--ui-h-md);
    border: 0;
    background: transparent;
    font-family: 'Afacad';
    font-size: var(--ui-fs-md);
    color: var(--ui-text);
    text-overflow: ellipsis;
}

.ui-searchbar__input:focus{
    outline: none;
}

.ui-searchbar__input::placeholder{
    color: var(--ui-text-muted);
}

/* Filet de séparation entre segments, et non une marge : il dit que les
   segments appartiennent à la même barre. */
.ui-searchbar__rule{
    flex: 0 0 1px;
    align-self: stretch;
    margin: 8px 0;
    background-color: var(--ui-border-soft);
}

.ui-searchbar__action{
    flex-shrink: 0;
    margin-left: 6px;
}


/* ── Sélecteur déroulant dessiné ─────────────────────────────────────────────

   Le <select> natif était rendu par le système d'exploitation, d'où son aspect
   daté et impossible à accorder au reste. Celui-ci est bâti sur <details> et des
   boutons RADIO, et fonctionne sans JavaScript : le formulaire part quand même
   avec le choix fait, et le clavier parcourt les options. Le script des listes
   (front/js/ui-select.js, listes data-choice) ne fait que du confort : libellé
   replié à jour, fermeture après un choix à la souris ou au doigt, à Entrée ou
   à Échap (focus rendu au résumé) et quand le focus quitte la liste ; les
   flèches parcourent les options sans refermer.

   Il vit dans le système et non dans une feuille de page parce qu'il sert à deux
   endroits au moins (bandeau de l'accueil, barre flottante). */

.ui-select{
    position: relative;
    flex: 1;
    min-width: 0;
}

/* display:block et non flex : un <summary> en flex empêche <details> de replier
   son contenu. La mise en page est portée par l'élément interne. */
.ui-select__toggle{
    display: block;
    width: 100%;
    min-height: var(--ui-h-md);
    cursor: pointer;
    list-style: none;
}

.ui-select__toggle::-webkit-details-marker{ display: none; }
.ui-select__toggle::marker{ content: ''; }

.ui-select__toggle:focus-visible{
    outline: var(--ui-focus-outline);
    outline-offset: 2px;
    border-radius: var(--ui-r-pill);
}

/* Libellé et chevron sur une même ligne, le chevron toujours collé au texte.
   Sans ce conteneur, le chevron passe à la ligne dès que le champ se resserre. */
.ui-select__inner{
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
    min-height: var(--ui-h-md);
}

.ui-select__value{
    flex: 0 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-family: 'Afacad';
    font-size: var(--ui-fs-md);
    line-height: 1.2;
    color: var(--ui-text);
}

.ui-select__caret{
    flex-shrink: 0;
    transition: transform 0.25s ease;
}

.ui-select[open] .ui-select__caret{
    transform: rotate(180deg);
}

/* Panneau flottant : il recouvre la page au lieu de pousser la barre */
.ui-select__panel{
    position: absolute;
    top: calc(100% + 16px);
    left: -16px;
    z-index: 30;
    box-sizing: border-box;
    width: max(100%, 360px);
    max-width: 92vw;
    /* 70 % de l'écran au plus : 380 px dépassaient la hauteur d'un téléphone en
       paysage (inchangé dès 543 px de haut). svh, hauteur avec les barres du
       navigateur affichées ; la ligne vh sert de repli. */
    max-height: min(380px, 70vh);
    max-height: min(380px, 70svh);
    overflow-y: auto;
    padding: 10px;
    background-color: var(--ui-surface);
    border: 1px solid var(--ui-border-soft);
    border-radius: 18px;
    box-shadow: 0 12px 32px rgba(15, 23, 42, 0.16);
}

.ui-select__group{
    margin: 14px 0 6px 12px;
    font-family: 'Afacad';
    font-size: 13px;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: #8A8A8A;
}

.ui-select__group:first-of-type{
    margin-top: 8px;
}

.ui-select__option{
    display: block;
    padding: 9px 12px;
    border-radius: 10px;
    cursor: pointer;
    font-family: 'Afacad';
    font-size: var(--ui-fs-md);
    color: var(--ui-text);
    transition: background-color 0.15s ease;
}

@media (hover: hover){
    .ui-select__option:hover{
        background-color: var(--ui-surface-soft);
    }
}

/* La case reste une vraie case, seulement masquée à l'oeil */
.ui-select__option input{
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

.ui-select__option:has(input:checked){
    background-color: var(--ui-surface-active);
    font-weight: 600;
}

.ui-select__option:has(input:focus-visible){
    outline: var(--ui-focus-outline);
    outline-offset: 2px;
}

/* ── Liste déroulante posée seule ────────────────────────────────────────────

   Dans le bandeau de recherche, le cadre vient du segment qui l'entoure. Ailleurs
   (tri des résultats, formulaire de demande), le composant est seul et doit se
   dessiner son propre cadre : celui d'un champ du système, pour qu'une liste
   déroulante et une saisie posées côte à côte ne se distinguent pas. */
.ui-select--framed{
    flex: 0 0 auto;
}

/* Même garniture qu'un .ui-input, et non une hauteur minimale : la hauteur d'un
   champ est dictée par sa ligne de texte, qui dépasse le minimum. Reprendre le
   padding plutôt que le chiffre les garde alignés quoi qu'il arrive à la police. */
.ui-select--framed .ui-select__toggle{
    box-sizing: border-box;
    padding: 10px 16px;
    background-color: var(--ui-surface);
    border: 1px solid var(--ui-border);
    border-radius: var(--ui-r-pill);
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

/* Le minimum de l'élément interne sert au bandeau de recherche, où le champ n'a
   pas de garniture. Ici il ferait 2 px de trop. */
.ui-select--framed .ui-select__inner{
    min-height: 0;
}

.ui-select--framed .ui-select__value{
    line-height: 1.5;
}

@media (hover: hover){
    .ui-select--framed .ui-select__toggle:hover{
        border-color: var(--ui-accent-strong);
    }
}

.ui-select--framed[open] .ui-select__toggle{
    border-color: var(--ui-accent-strong);
    box-shadow: var(--ui-focus);
}

/* Le panneau se cale sur le bord du champ, et non 16 px en dehors comme dans le
   bandeau, où il déborde volontairement de la gouttière. */
.ui-select--framed .ui-select__panel{
    top: calc(100% + 8px);
    left: 0;
    width: max(100%, 260px);
}

/* Aligné à droite quand le champ touche le bord droit de son conteneur : sinon
   le panneau sort de l'écran sur une petite fenêtre. */
.ui-select--framed.ui-select--right .ui-select__panel{
    left: auto;
    right: 0;
}

/* En pleine largeur dans un formulaire, à côté des .ui-input */
.ui-select--block{
    display: block;
    width: 100%;
}

.ui-select--block .ui-select__inner{
    justify-content: space-between;
}

.ui-select--block .ui-select__toggle{
    border-radius: var(--ui-r-field);
}

/* En pleine largeur d'un formulaire, le panneau prend la largeur exacte du champ
   (déclaré après --framed, donc prioritaire) : son minimum de 260 px le faisait
   sortir de l'écran quand le champ était plus étroit (280 px de large) */
.ui-select--block .ui-select__panel{
    width: 100%;
    max-width: none;
}

/* ── Barre de recherche en grand format ──────────────────────────────────────

   Le bandeau de l'accueil a la place de respirer, la barre flottante non. Une
   variante de taille plutôt que deux composants. */
.ui-searchbar--lg .ui-searchbar__input,
.ui-searchbar--lg .ui-select__value,
.ui-searchbar--lg .ui-select__option{
    font-size: var(--ui-fs-lg);
}

.ui-searchbar--lg .ui-searchbar__input,
.ui-searchbar--lg .ui-select__toggle,
.ui-searchbar--lg .ui-select__inner{
    min-height: var(--ui-h-lg);
}

/* ── Pastilles de sélection ──────────────────────────────────────────────── */

/* ALIGNÉES À GAUCHE, toujours. Centrées, les lignes de longueurs inégales et le
   dernier élément esseulé au milieu donnent l'impression de désordre. */
.ui-chips{
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-start;
    gap: var(--ui-gap);
    margin: 0;
    padding: 0;
    list-style: none;
}

.ui-chip-item{
    display: contents;
}

/* La case reste une vraie case à cocher, seulement masquée à l'oeil : le clavier
   l'atteint, le formulaire part sans JavaScript, le script la lit comme avant. */
.ui-chip__input{
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

.ui-chip{
    display: inline-flex;
    align-items: center;
    box-sizing: border-box;
    min-height: var(--ui-h-sm);
    padding: 0 14px;
    background-color: var(--ui-surface);
    border: 1px solid var(--ui-border);
    border-radius: var(--ui-r-pill);
    color: var(--ui-text);
    font-family: 'Afacad';
    font-size: var(--ui-fs-sm);
    line-height: 1.2;
    cursor: pointer;
    user-select: none;
    transition: background-color 0.15s ease, border-color 0.15s ease;
}

@media (hover: hover){
    .ui-chip:hover{
        border-color: var(--ui-accent-strong);
    }
}

/* Un seul état actif dans tout le front */
.ui-chip__input:checked + .ui-chip{
    background-color: var(--ui-surface-active);
    border-color: var(--ui-border-active);
    font-weight: 600;
}

.ui-chip__input:focus-visible + .ui-chip{
    outline: var(--ui-focus-outline);
    outline-offset: 2px;
}

.ui-chip__input:disabled + .ui-chip{
    opacity: 0.45;
    cursor: default;
}

/* Raccourci de sélection : même forme, teinte plus douce, parce que ce n'est pas
   un critère mais un outil pour en cocher plusieurs d'un coup. */
.ui-chip--quiet{
    background-color: var(--ui-surface-soft);
    border-color: var(--ui-border-soft);
    color: #4a3d6b;
}

@media (hover: hover){
    .ui-chip--quiet:hover{
        background-color: var(--ui-surface-active);
    }
}

/* Raccourci actif : l'état tient dans aria-pressed (posé par le script des
   listes), lu par le lecteur d'écran comme par la feuille. Une classe à part
   n'était jamais posée sous le bon nom : seul le survol colorait le raccourci. */
.ui-chip--quiet[aria-pressed="true"]{
    background-color: var(--ui-surface-active);
    border-color: var(--ui-border-active);
    color: var(--ui-text);
    font-weight: 600;
}

/* ── Groupe de pastilles (titre + liste) ─────────────────────────────────── */

.ui-group + .ui-group{
    margin-top: var(--ui-gap-lg);
}

.ui-group__title{
    margin: 0 0 8px;
    font-family: 'Afacad';
    font-size: var(--ui-fs-sm);
    font-weight: 600;
    color: var(--ui-text);
    text-align: left;
}

/* ── Panneau repliable ───────────────────────────────────────────────────── */

/* Bâti sur <details>/<summary> natifs : s'ouvre au clavier, fonctionne sans
   script, et le lecteur d'écran annonce son état sans qu'on ait à le gérer.

   Un panneau fermé ne masque ses cases NI au formulaire NI au script : une
   sélection reste active même replié, ce qui permet de refermer sans rien perdre. */
.ui-disclosure{
    width: 100%;
}

.ui-disclosure__toggle{
    display: block;
    box-sizing: border-box;
    width: 100%;
    min-height: var(--ui-h-md);
    padding: 0 18px;
    background-color: var(--ui-surface);
    border: 1px solid var(--ui-border);
    border-radius: var(--ui-r-pill);
    cursor: pointer;
    list-style: none;
    transition: border-color 0.15s ease;
}

.ui-disclosure__toggle::-webkit-details-marker{ display: none; }
.ui-disclosure__toggle::marker{ content: ''; }

@media (hover: hover){
    .ui-disclosure__toggle:hover{
        border-color: var(--ui-accent-strong);
    }
}

.ui-disclosure[open] > .ui-disclosure__toggle{
    border-color: var(--ui-accent-strong);
}

.ui-disclosure__toggle:focus-visible{
    outline: var(--ui-focus-outline);
    outline-offset: 2px;
}

/* La mise en page va dans un élément INTERNE : un <summary> en display:flex fait
   perdre à <details> sa capacité à replier son contenu (Chrome le traite alors
   comme un enfant ordinaire et génère un résumé anonyme). */
.ui-disclosure__inner{
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: var(--ui-h-md);
}

.ui-disclosure__label{
    font-family: 'Afacad';
    font-size: var(--ui-fs-md);
    font-weight: 600;
    color: var(--ui-text);
}

/* Compte des choix actifs : dit ce qui est sélectionné quand le panneau est replié */
.ui-disclosure__count{
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 22px;
    height: 22px;
    padding: 0 6px;
    border-radius: var(--ui-r-pill);
    background-color: var(--ui-accent);
    font-family: 'Afacad';
    font-size: 13px;
    font-weight: 600;
    line-height: 1;
}

.ui-disclosure__caret{
    margin-left: auto;
    flex-shrink: 0;
    transition: transform 0.2s ease;
}

.ui-disclosure[open] .ui-disclosure__caret{
    transform: rotate(180deg);
}

.ui-disclosure__panel{
    padding: 14px 4px 4px;
}

/* Le même résumé posé sur un <button> (aria-expanded) quand le contenu commandé
   ne peut pas être un <details> : il doit rester déplié au bureau (bouton
   « Filtres » des listes, front/_filters_toggle.html.twig). Mêmes états que le
   panneau ouvert, portés par aria-expanded ; le bouton prend la police et
   l'alignement du résumé au lieu des siens. */
button.ui-disclosure__toggle{
    font: inherit;
    color: inherit;
    text-align: left;
}

.ui-disclosure__toggle[aria-expanded="true"]{
    border-color: var(--ui-accent-strong);
}

.ui-disclosure__toggle[aria-expanded="true"] .ui-disclosure__caret{
    transform: rotate(180deg);
}

/* ── Responsive ──────────────────────────────────────────────────────────── */

@media (max-width: 834px){
    :root{
        --ui-h-md: 42px;
        --ui-h-lg: 48px;
    }
}
