/**
 * Styles de blocs — thème enfant Alivio.
 *
 * Chargé sur le front et dans l'éditeur (voir functions.php).
 */

/* ==========================================================================
Compatibilité TT5 — slugs du parent absents de la palette Alivio
==========================================================================
Les tableaux de presets de l'enfant *remplacent* ceux du parent, ils ne
fusionnent pas : en redéfinissant `color.palette` et `typography.fontFamilies`,
on a supprimé les slugs de TT5 (`base`, `contrast`, `accent-1..6`, `manrope`,
`fira-code`) alors que ses `styles` continuent de les nommer.

Alias ici plutôt que huit entrées de plus dans `theme.json` : ces couleurs
sont le vocabulaire interne du parent, elles n'ont pas à être proposées au
client dans le sélecteur de l'éditeur. Corollaire assumé : seules les
références en `var()` sont couvertes, pas les classes `has-<slug>-color`.
Sans conséquence tant qu'aucun pattern de TT5 n'est inséré — si l'un l'est
un jour, il faudra basculer ces alias dans la palette de `theme.json`.
-------------------------------------------------------------------------- */

:root {
    /* Rôles de base : fond de page et couleur de contraste du parent. */
    --wp--preset--color--base: var(--wp--preset--color--white);
    --wp--preset--color--contrast: var(--wp--preset--color--accent);

    /* Accents, vers leur équivalent Alivio le plus proche. `accent-4` sert aux
       métadonnées d'article et au contour de focus des boutons, `accent-5` au
       fond des blocs de code, `accent-6` aux bordures et séparateurs. */
    --wp--preset--color--accent-1: var(--wp--preset--color--primary);
    --wp--preset--color--accent-2: var(--wp--preset--color--slate);
    --wp--preset--color--accent-3: var(--wp--preset--color--pink);
    --wp--preset--color--accent-4: var(--wp--preset--color--blue);
    --wp--preset--color--accent-5: var(--wp--preset--color--green);

    /* Expression de TT5 conservée telle quelle : elle ne dépend d'aucun slug. */
    --wp--preset--color--accent-6: color-mix(in srgb, currentColor 20%, transparent);

    /* Sans équivalent dans la maquette : valeurs de TT5 conservées.
       `manrope` habille core/navigation, `fira-code` et `xx-large` le bloc de
       code et le pullquote. */
    --wp--preset--font-family--manrope: var(--wp--preset--font-family--nunito);
    --wp--preset--font-family--fira-code: ui-monospace, "Fira Code", monospace;
    --wp--preset--font-size--xx-large: 2.15rem;

    /* Échelle d'espacement du parent, aliasée vers celle d'Alivio.

       L'enfant a remplacé `spacingSizes` par six paliers nommés (`xs` à `xxl`) :
       les slugs numériques de TT5 n'existent donc plus.  */
    --wp--preset--spacing--10: var(--wp--preset--spacing--xs);
    --wp--preset--spacing--20: var(--wp--preset--spacing--xs);
    --wp--preset--spacing--30: var(--wp--preset--spacing--s);
    --wp--preset--spacing--40: var(--wp--preset--spacing--m);
    --wp--preset--spacing--50: var(--wp--preset--spacing--l);
    --wp--preset--spacing--60: var(--wp--preset--spacing--xl);
    --wp--preset--spacing--70: var(--wp--preset--spacing--xl);
    --wp--preset--spacing--80: var(--wp--preset--spacing--xxl);
}

/* les trois paliers que theme.json ne sait pas exprimer */
:root {
    --alivio-espace-l: 2rem;
    --alivio-espace-xl: 5rem;
    --alivio-espace-xxl: 8rem;
}

@media (width < 1025px) {
    :root {
        --alivio-espace-xl: 3rem;
        --alivio-espace-xxl: 5rem;
    }
}

@media (width < 768px) {
    :root {
        --alivio-espace-l: 1.5rem;
        --alivio-espace-xl: 2rem;
        --alivio-espace-xxl: 3rem;
    }
}


:root main {
    margin-block-start: 0;
}

/* ==========================================================================
   Typographie — variantes qui ne tiennent pas dans theme.json
   ========================================================================== */
h1 {
    font-size: var(--wp--preset--font-size--h-1);
    font-weight: 800;
    color: white;
}

h1 em {
    font-style: italic;
    font-weight: 800;
    color: var(--wp--preset--color--accent-light);
}

h2 em, h3 em {
    font-style: normal;
}

/* PBadge — la pastille de la maquette : 20 / 13 px, marine, fond arrondi.*/
p.is-style-p-badge {
    font-size: var(--wp--preset--font-size--p-badge);
    line-height: 1.6;
    color: var(--wp--preset--color--navy);

    display: block;
    width: fit-content;
    padding: 0.3em 1.2em;
    border-radius: 15px;
    margin-bottom: 1rem;
}

/* Fond par défaut seulement : dès que le rédacteur choisit une couleur dans le
   panneau Couleur, le cœur ajoute `has-background` et cette règle se retire.
   Sans le `:not()`, son choix serait ignoré — blocks.css est chargé après
   global-styles, et les deux sélecteurs pèsent (0,2,0). */
p.is-style-p-badge:not(.has-background) {
    background-color: var(--wp--preset--color--accent-light);
}

/* Position de la pastille : au choix du rédacteur, via le bouton d'alignement
   de la barre d'outils du paragraphe. */
p.is-style-p-badge.has-text-align-center {
    margin-inline: auto;
}

p.is-style-p-badge.has-text-align-right {
    margin-inline-start: auto;
}

/* Étoile de fin de pastille. `etoile.svg` est dessinée en `currentColor` :
   chargée en `background-image`, elle sort noire — un SVG externe ne voit pas
   la couleur de la page. D'où le masque, qui laisse la teinte au CSS et garde
   le fichier utilisable tel quel en ligne ailleurs. */
p.is-style-p-badge.ao-etoile::after {
    content: '';
    display: inline-block;
    width: 1.1em;
    height: 1.1em;
    margin-inline-start: 0.4em;

    /* Assise sur la ligne de base plutôt que centrage vertical : le glyphe
       n'a pas de jambage, l'étoile s'aligne donc sur l'œil des capitales. */
    vertical-align: -0.18em;

    background-color: var(--wp--preset--color--accent);
    mask: url('../icons/etoile.svg') no-repeat center / contain;
}

/* LIENS */
a {
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-decoration-style: solid;
    text-decoration-color: var(--wp--preset--color--accent);
    text-underline-offset: 0.6em;
    font-weight: 700;
}

a:not(.wp-block-button__link):hover {
    position: relative;
    inset-block-start: -2px;
}

a:hover {
    text-decoration: underline;
    text-decoration-color: var(--wp--preset--color--accent);
}

/* Bascule en burger sous 895px, au lieu des 600px du cœur.
   À partir de 600px le cœur remet le conteneur en ligne et masque le bouton :
   on rétablit l'état « tiroir » sur l'intervalle restant. Portée limitée à
   .ao-menu-principal — le menu du méga-menu est en overlayMenu "never" et n'a
   donc pas de conteneur responsive. */

.ao-btn-demo-mobile {
    display: none !important;
}
@media (width < 955px) {
    .ao-menu-principal .wp-block-navigation__responsive-container:not(.hidden-by-default):not(.is-menu-open) {
        display: none;
    }

    .ao-menu-principal .wp-block-navigation__responsive-container-open:not(.always-shown) {
        display: flex;
    }

    .ao-btn-connexion, .ao-btn-demo {
        display: none !important;
    }

    .ao-btn-demo-mobile {
        display: inline-flex !important;
    }
}

/* WCAG 2.3.3 */
@media (prefers-reduced-motion: reduce) {
    a {
        transition-duration: 1ms;
    }

    a:not(.wp-block-button__link):hover {
        inset-block-start: 0;
    }
}

/* --------------------------------------------------------------------------
    Items de menu vers l'extérieur

    `ao-lien-externe` se saisit à la main dans le panneau « Avancé » de l'item.
    WordPress la pose sur le `<li>` : le `::after` descend donc sur l'ancre, pour
    que l'icône entre dans la zone cliquable et suive la couleur du lien.
    -------------------------------------------------------------------------- */
 .ao-lien-externe > .wp-block-navigation-item__content::after {
     /* Les deux valeurs d'ajustement, isolées ici. */
     --ao-lien-externe-taille: 0.75em;
     --ao-lien-externe-ecart: 0.35em;

     content: '';
     display: inline-block;
     width: var(--ao-lien-externe-taille);
     height: var(--ao-lien-externe-taille);
     margin-inline-start: var(--ao-lien-externe-ecart);

     /* L'encre remplit sa boîte de haut en bas : sans ce rappel, le cadre
        flotte au-dessus de l'œil des capitales. */
     vertical-align: -0.05em;

     background-color: currentColor;
     mask: url('../icons/lien-externe.svg') no-repeat center / contain;
 }

/*============================================================================
BLOG
================================================================================*/

/* Variante de H3 pour le blog : violet au lieu de marine. */
.wp-block-post-title.is-style-h3-blog,
h3.is-style-h3-blog {
    color: var(--wp--preset--color--primary);
}

/* Mouvement flèches au survol */
.ao-query .is-style-carte-cliquable:hover .ao-post-arrow {
    animation: AoSlideRight .3s ease-in forwards;
}

@keyframes AoSlideRight {
    0% {
        transform: translateX(0);
    }
    100% {
        transform: translateX(4px);
    }
}

/* --------------------------------------------------------------------------
   Libellé de catégorie sur l'image mise en avant

   Le texte vient d'un champ saisi sur la catégorie, relié au paragraphe par la
   source « oniti-alivio/categorie ». Rien à faire ici pour choisir les
   catégories : champ vide, paragraphe vide, règle `:empty` plus bas.

   Le paragraphe est posé juste APRÈS l'image.

   Le repère du positionnement absolu est la carte elle-même : c'est le style
   `carte-cliquable` d'oniti-core qui lui pose `position: relative`. Ces règles
   n'ont donc de sens que sur une carte portant ce style.
   -------------------------------------------------------------------------- */

.wp-block-group.is-style-carte-cliquable .ao-cat-sur-image {
    /* Deux valeurs de maquette, isolées ici : le repère est le coin haut-gauche
       de la carte, donc celui de l'image. */
    --ao-cat-sur-image-haut: 2.5rem;
    --ao-cat-sur-image-cote: var(--wp--preset--spacing--s);

    position: absolute;
    inset-block-start: var(--ao-cat-sur-image-haut);
    inset-inline-start: var(--ao-cat-sur-image-cote);

    /* La disposition du groupe pose une marge de gouttière sur ses enfants ; sur
       un élément absolu, elle s'ajoute au décalage. Le sélecteur à deux classes
       est là pour battre `.wp-container-… > *`. */
    margin: 0;
    max-width: calc(100% - 2 * var(--ao-cat-sur-image-cote));

    /* Redondant avec l'ordre du DOM, mais garde la zone de clic intacte si le
       titre perdait son ancre (fonctionnalites-verrou.php retire ce lien), et
       évite le curseur texte sur l'image. */
    pointer-events: none;
}

/* Champ non rempli : le cœur laisse le paragraphe en place, vide. */
.wp-block-group.is-style-carte-cliquable .ao-cat-sur-image:empty {
    display: none;
}

/* Article sans image : le libellé viendrait se poser sur la pastille. */
.wp-block-group.is-style-carte-cliquable:not(:has(.wp-block-post-featured-image img)) .ao-cat-sur-image {
    display: none;
}

/*============================================================================
MEGA MENU (pas encore fait côté éditeur
================================================================================*/
.ao-mega-menu {
    position: relative;
    width: 100%;
    max-width: var(--wp--style--global--wide-size);
}

.ao-mega-content-fonctionnalites {
    position: absolute;
    z-index: 999;
    top: 0;
    left: 0;
    width: 100%;
    max-width: var(--wp--style--global--wide-size);
    opacity: 0;
    transform: translateY(-30px);
    visibility: hidden;
    transition: opacity 0.8s ease-out, transform 0.7s ease-out;
}

.mega-content.active {
    opacity: 1;
    transform: translateY(0);
    visibility: visible;
}

/* ==========================================================================
   Liste coche fond jaune avec indentation — style du bloc core/list
   ==========================================================================*/
.wp-block-list.is-style-liste-coche-fill {
    --ao-coche-taille: 20px;
    --ao-coche-ecart: 0.5rem;
    /* Tiret des sous-listes : marqueur, écart au texte, hauteur de ligne. */
    --ao-tiret: '–';
    --ao-tiret-ecart: 0.4em;
    /* Seule source de l'espacement vertical des sous-éléments : aucune marge
       n'est posée sur les `li`. Monter la valeur les écarte. */
    --ao-tiret-interligne: 1.2;

    list-style: none;
    padding: 0;
    margin: 0;
}

/* `> li` : la coche ne descend pas dans les sous-listes. */
.wp-block-list.is-style-liste-coche-fill > li {
    display: grid;
    grid-template-columns: var(--ao-coche-taille) 1fr;
    column-gap: var(--ao-coche-ecart);
}

.wp-block-list.is-style-liste-coche-fill > li::before {
    content: '';
    width: var(--ao-coche-taille);
    height: var(--ao-coche-taille);
    background: url('../icons/coche.svg') no-repeat center / contain;
    margin-top: calc((1.5em - var(--ao-coche-taille)) / 2);
    margin-top: calc((1lh - var(--ao-coche-taille)) / 2);
}

/* Sous-liste, à tous les niveaux : colonne 2 de l'élément qui la porte. Le
   `list-style` du cœur (`ul ul { circle }`) l'emporte sur l'héritage : il faut
   le retirer ici aussi. */
.wp-block-list.is-style-liste-coche-fill .wp-block-list {
    grid-column: 2;
    padding-inline-start: 0;
    list-style: none;
    line-height: var(--ao-tiret-interligne);
}

.wp-block-list.is-style-liste-coche-fill .wp-block-list > li {
    display: grid;
    grid-template-columns: auto 1fr;
    column-gap: var(--ao-tiret-ecart);
}

.wp-block-list.is-style-liste-coche-fill .wp-block-list > li::before {
    content: var(--ao-tiret);
}

/* ==========================================================================
   Liste en ligne — style du bloc core/list
   ==========================================================================
   Aucune règle d'alignement ici : `core/list` n'a pas de contrôle de
   text-align. Pour centrer la rangée, mettre la liste dans un groupe en
   disposition Pile ou Rangée et régler sa Justification sur « Centre » — la
   liste devient élément flexible et se rétracte à la largeur de son contenu.
   -------------------------------------------------------------------------- */

.wp-block-list.is-style-liste-en-ligne {
  /* Écart entre un mot et la puce voisine ; appliqué des deux côtés. */
  --ao-liste-en-ligne-ecart: 0.45em;
  --ao-liste-en-ligne-puce: var(--wp--preset--color--accent);

  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  column-gap: var(--ao-liste-en-ligne-ecart);
  row-gap: 0.4em;

  /* Le retrait réservé au marqueur n'a plus lieu d'être. */
  padding-inline-start: 0;
  list-style: none;
}

/*
 * `list-style: none` retire la sémantique de liste dans VoiceOver / Safari.
 * `list-style-type: ""` masque le marqueur sans la retirer. Là où la valeur
 * chaîne n'est pas comprise, le bloc `@supports` est sauté et c'est le `none`
 * ci-dessus qui reste : aucune puce native ne ressuscite.
 */
@supports (list-style-type: "") {
  .wp-block-list.is-style-liste-en-ligne {
    list-style-type: "";
  }
}

/* Typographie de la maquette, par défaut seulement : les panneaux Typographie
   et Couleur de l'éditeur reprennent la main dès qu'ils sont renseignés. Même
   mécanique de garde que la pastille `p-badge` plus haut — sans elle, ces
   sélecteurs à deux classes écraseraient le choix du rédacteur. */
.wp-block-list.is-style-liste-en-ligne:not([class*="font-size"]) {
  font-size: var(--wp--preset--font-size--p-little);
}

.wp-block-list.is-style-liste-en-ligne:not(.has-text-color) {
  color: var(--wp--custom--couleur--texte-titre);
}

/*
 * La puce séparatrice. Texte alternatif vide (même idiome que le guillemet des
 * cartes témoignage) : les lecteurs d'écran qui restituent le contenu généré ne
 * liront pas une puce entre chaque élément.
 */
.wp-block-list.is-style-liste-en-ligne > li + li::before {
  content: "\2022";
  content: "\2022" / "";
  margin-inline-end: var(--ao-liste-en-ligne-ecart);
  color: var(--ao-liste-en-ligne-puce);
}


/* ==========================================================================
   Boutons — mouvement au survol
   ==========================================================================
   L'ombre du survol est déclarée dans `theme.json`, `elements.button:hover` :
   `shadow` y est une propriété prise en charge. `transform` et `transition`
   ne le sont pas — d'où ces quelques lignes. Fond et bordures ne changent pas
   au survol, c'est `theme.json` qui les y maintient identiques (sans quoi le
   `:hover` de TT5 les remplacerait).
   -------------------------------------------------------------------------- */

:root .wp-element-button {
    text-decoration: none;
    transition:
        box-shadow 200ms ease,
        transform 200ms ease;
}

:root .wp-element-button:hover {
    transform: translateY(-2px);
}

/* WCAG 2.3.3 */
@media (prefers-reduced-motion: reduce) {
    :root .wp-element-button {
        transition-duration: 1ms;
    }

    :root .wp-element-button:hover {
        transform: none;
    }
}

/* ==========================================================================
   Utilitaire
   ==========================================================================*/

.ao-full-width-mobile {
    padding: 0 1rem;
}

@media (width < 1025px) {
    .ao-paragraph-under-image {
        padding-top: 10rem !important;
    }
}

@media (width <= 855px) {
    .ao-paragraph-under-image {
        padding-top: 11rem !important;
    }
}

@media (width < 768px) {
    .ao-full-width-mobile {
        padding: 0;
    }
    .ao-left-mobile {
    justify-self: flex-start;
    }
}

/* ==========================================================================
   Carte cliquable — mesures Alivio
   ==========================================================================
   Mécanique dans oniti-core (style `carte-cliquable` de core/group) : lien
   empilé, zoom d'image, focus déporté sur la carte. Le lien de la carte est
   celui du titre — voir le contrat dans blocks/group-carte-cliquable.php.

   Aucun de ces tokens n'est optionnel : sans eux, le contour de focus n'est
   pas garanti à 3:1 (RGAA 1.4.11), l'image mise en avant sort à angles droits,
   et la carte ne montre aucun effet au survol — oniti-core livre la mécanique
   du zoom éteinte, l'affordance étant propre à chaque site.

   `:root` pour ne pas dépendre de l'ordre des deux feuilles, à poids égal.
   -------------------------------------------------------------------------- */

:root .is-style-carte-cliquable {
    --oniti-carte-focus-color: var(--wp--custom--couleur--texte);

    /* Doit valoir le rayon posé sur le bloc « Image mise en avant » dans
       l'éditeur : le cœur écrit ce rayon sur l'`<img>` et jamais sur la
       `<figure>`, or c'est la figure qui recadre le zoom. */
    --oniti-carte-image-rayon: var(--wp--custom--rayon--carte);

    /* Survol Alivio : l'image grossit, son cadre ne bouge pas. Le recadrage du
       débord et le `prefers-reduced-motion` viennent avec, côté oniti-core.
       Tout autre effet ajouté ici devrait porter les siens — voir l'en-tête du
       style dans oniti-core/assets/css/blocks.css. */
    --oniti-carte-zoom: 1.03;
    --oniti-carte-duration: 250ms;
}

/* Carte verrouillée — fiche de fonctionnalité pas encore rédigée. Le `<a>` du
   titre a été retiré du HTML côté serveur (oniti-alivio,
   inc/fonctionnalites-verrou.php) : la carte se reconnaît à son absence, sans
   classe à injecter au rendu. oniti-core retire déjà le zoom et le curseur ;
   reste la flèche, propre à Alivio. */
.is-style-carte-cliquable:not(:has(.wp-block-post-title a)) .ao-post-arrow {
    display: none;
}

/* Survol des cartes sans image mise en avant — fiches de fonctionnalité et
   avis. Le zoom d'oniti-core ne cible que `.wp-block-post-featured-image` :
   ces cartes n'en ont pas, l'affordance est donc ici. Classe posée à la main
   sur le Groupe de la carte cliquable. */

.is-style-carte-cliquable.ao-fonctionnalite-card,
.is-style-carte-cliquable.ao-avis-card {
    transition:
        transform var(--oniti-carte-duration) ease,
        box-shadow var(--oniti-carte-duration) ease;
}

.is-style-carte-cliquable.ao-fonctionnalite-card:hover,
.is-style-carte-cliquable.ao-avis-card:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 12px var(--wp--custom--couleur--ombre);
}

/* WCAG 2.3.3 — seul le déplacement se neutralise. L'ombre n'est pas un
   mouvement : elle reste, et porte seule l'affordance. */
@media (prefers-reduced-motion: reduce) {
    .is-style-carte-cliquable.ao-fonctionnalite-card,
    .is-style-carte-cliquable.ao-avis-card {
        transition-duration: 1ms;
    }

    .is-style-carte-cliquable.ao-fonctionnalite-card:hover,
    .is-style-carte-cliquable.ao-avis-card:hover {
        transform: none;
    }
}

/* Survol propre aux cartes du CPT « fonctionnalités »
   `ao-fonctionnalite-card` est posée sur la carte cliquable. */

.is-style-carte-cliquable.ao-fonctionnalite-card {
    transition:
        transform var(--oniti-carte-duration) ease,
        box-shadow var(--oniti-carte-duration) ease;
}

.is-style-carte-cliquable.ao-fonctionnalite-card:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 12px var(--wp--custom--couleur--ombre);
}

/* WCAG 2.3.3 — seul le déplacement se neutralise. L'ombre n'est pas un
   mouvement : elle reste, et porte seule l'affordance. */
@media (prefers-reduced-motion: reduce) {
    .is-style-carte-cliquable.ao-fonctionnalite-card {
        transition-duration: 1ms;
    }

    .is-style-carte-cliquable.ao-fonctionnalite-card:hover {
        transform: none;
    }
}

/* ==========================================================================
   En-tête transparent en surimpression
   ==========================================================================

   L'en-tête sort du flux. La première section de la page remonte dessous et sa
   couleur de fond passe derrière le logo et le menu.
   Une seule classe ajoutée à poser : `ao-section-top`, dans le panneau Avancé
   du groupe, sur la section qui ouvre la page.
   La hauteur vient de theme.json (`settings.custom.header.hauteur`) pour que la
   compensation ci-dessous ne puisse pas diverger de la maquette.
   -------------------------------------------------------------------------- */

header.wp-block-template-part {
    position: absolute;
    inset-block-start: 0;
    inset-inline: 0;
    z-index: 10;
    background-color: transparent;
}

/* Dégagement par défaut. */
main {
    padding-block-start: var(--wp--custom--header--hauteur);
}

/* Annulé dès qu'une section de haut de page est présente */
main:has( .ao-section-top ) {
    padding-block-start: 0;
}

/*
 * La section elle-même : son fond atteint le haut de la fenêtre, son contenu est
 * repoussé sous l'en-tête. Elle doit être en pleine largeur.
 */
.ao-section-top {
    padding-block-start: calc(var(--wp--custom--header--hauteur) + 5rem);
    padding-block-end: 3rem;
}

@media (width < 768px) {
    :root { --wp--custom--header--hauteur: 2rem; }
}

/* ==========================================================================
   Rangée à débord droit
   ==========================================================================
   À poser sur une rangée réglée en PLEINE LARGEUR — sans quoi elle reste bornée
   par le groupe contraint parent et ne peut pas atteindre le bord.
   -------------------------------------------------------------------------- */
:root .ao-rangee-debord {
    --ao-colonne-texte: 600px;
    --ao-largeur-max: 1920px;

    display: grid;
    grid-template-columns:
        minmax(
            var(--wp--preset--spacing--50),
            calc((100% - var(--wp--style--global--content-size)) / 2)
        )
        minmax(0, var(--ao-colonne-texte))
        minmax(0, 1fr);
    align-items: center;
    padding-inline: 0;
}

.ao-hero-sous-titre-mobile {
    display: none;
}

.ao-rangee-debord > :first-child {
    grid-column: 2;
    margin-right: 2rem;
}
.ao-rangee-debord > :last-child  { grid-column: 3; }

.ao-rangee-debord > :last-child :is(img, video) {
    display: block;
    width: 90%;
    height: auto;
    margin-bottom: -14rem;
}


@media (width >= 1920px) {
    :root .ao-rangee-debord.ao-rangee-debord {
        max-width: var(--ao-largeur-max);
        margin-inline: auto;
    }
}

@media (width < 1025px) {
    :root .ao-rangee-debord {
        grid-template-columns:
            minmax(var(--wp--preset--spacing--50), 1fr)
            minmax(0, var(--wp--style--global--content-size))
            0;
    }

    .ao-rangee-debord > :first-child {
        grid-column: 2;
        padding: 0 1rem 0 0;
    }
    .ao-rangee-debord > :last-child  {
        grid-column: 2 / -1;
    }

    .ao-fonctionnalite-col {
        flex-basis: 100% !important;
    }
}

@media (width < 768px) {
    .ao-rangee-debord .ao-hero-sous-titre-desktop
    {
        display: none;
    }
    .ao-rangee-debord h1.ao-hero-titre {
        text-align: center;
    }
    .ao-rangee-debord .ao-hero-empilement {
        align-items: center;
    }
    .ao-hero-sous-titre-mobile {
    display: block;
    }
}

/* ==========================================================================
   Encadré — mesures Alivio
   ==========================================================================
   Mécanique et palier mobile dans oniti-core (style `encadre` de core/group).
   Ce rayon n'est pas optionnel : sans lui, core laisse les angles droits. La
   largeur reste au `wideSize` de theme.json, valeur par défaut du style.

   `:root` pour ne pas dépendre de l'ordre des deux feuilles, à poids égal.
   -------------------------------------------------------------------------- */

:root .is-style-encadre {
    --oniti-encadre-rayon: var(--wp--custom--rayon--carte);
}


/* ==========================================================================
   Icônes — fond coloré
   ==========================================================================
   La mécanique vit dans oniti-core ; seules les mesures de la maquette Alivio
   sont ici. La couleur, elle, se choisit bloc par bloc dans le panneau Couleur.
   -------------------------------------------------------------------------- */

.oniti-icon--has-background {
    --oniti-icon-background-padding: 0.625rem;
    --oniti-icon-background-radius: 0.9375rem;
}

/* ==========================================================================
   SVG sur deux fonds colorés
   ========================================================================== */
.ao-cta-duo {
  position: relative;
  isolation: isolate;
  overflow: hidden;
}

/*
 * Trois couches : fonds des deux groupes, puis la forme, puis le contenu.
 */
.ao-cta-duo::before {
  content: "";
  position: absolute; inset: 0;
  z-index: 1;                 /* au-dessus des fonds des deux groupes */
  pointer-events: none;
  /* Chemin relatif à assets/css/, pas à la racine du thème. */
  background: url("../images/ao-forme-duo.svg") left bottom no-repeat;
}

.ao-cta-duo.ao-cta-tarifs:before {
    background: url("../images/ao-forme-duo-tarifs.svg") left bottom no-repeat;
}

.ao-cta-duo__top > *,
.ao-cta-duo__bottom > * {
  position: relative;
  z-index: 2;
}

/* ==========================================================================
   FORMULAIRES CF7
   ========================================================================== */

.ao-form {
  display: flex;
  flex-direction: column;
  width: 100%;
  justify-content: start;
  align-items: stretch;
}

.ao-form p {
    margin: 0 0 1rem 0;
}

.ao-form .ao-form__col,
.ao-form .ao-form__row,
.ao-form .wpcf7-list-item label /* checkbox */
{
  display: flex;
  gap: 1rem;
}

.ao-form .wpcf7-list-item label input {
    flex: 0 1 40px;
    height: 40px;
}

.ao-form .ao-form__col {
    flex-direction: column;
}

.ao-form .ao-form__col-50 {
    flex: 0 1 50%;
}

.ao-form .ao-form__col-100 {
    flex: 0 1 100%;
}

.ao-form .ao-form__row input,
.ao-form .ao-form__row select,
.ao-form .ao-form__row textarea
{
    width: 100%;
    border: 1px solid var(--wp--preset--color--slate);
    border-radius: 15px;
}

.ao-form .ao-form__row input,
.ao-form .ao-form__row select {
    height: 3rem;
}

.ao-form .wpcf7-list-item-label {
    font-size: 1rem;
}

.ao-form label {
    font-weight: 700;
}

.ao-form .ao-form-submit {
    background-color: var(--wp--preset--color--accent);
    color: var(--wp--preset--color--navy);
    border: 1px solid var(--wp--preset--color--accent);
    border-radius: 12px;
    padding: 0.5em 1.1em;
    font-weight: 700;
    font-size: var(--wp--preset--font-size--p-big);
    margin-top: 1rem;
}

.ao-form .ao-form__row select {
    background-color: var(--wp--preset--color--primary-lighter);
    border: 1px solid var(--wp--preset--color--primary-lighter);
}

@media (width < 1025px) {
    .ao-form .ao-form__row {
        flex-direction: column;
    }
}

@media (width < 768px) {
    .ao-form .ao-form-submit {
        width: 100%;
    }
}

/* ==========================================================================
   Colonnes Objectifs
   ========================================================================== */
.ao-objectif {
      position: relative;
  }

.ao-objectif:not(:last-child):after {
    content: "";
    position: absolute;
    inset: 0 0 auto auto;   /* top:0 right:0 */
    width: 2px;
    height: 100%;
    background-image: linear-gradient(
        to bottom,
        transparent 0%,
        var(--wp--preset--color--primary) 35%,
        var(--wp--preset--color--primary) 55%,
        transparent 100%
    );
}

@media (width < 782px) {
    .ao-objectif:not(:last-child):after {
        inset: auto 0 0 0;  /* bottom:0, left/right:0 */
        width: 100%;
        height: 2px;
        background-image: linear-gradient(
            to right,
            transparent 0%,
            var(--wp--preset--color--primary) 35%,
            var(--wp--preset--color--primary) 65%,
            transparent 100%
        );
    }
}

/* ==========================================================================
     Collection 01 — habillage du squelette
     ==========================================================================
     Le squelette grille ↔ carrousel vit dans oniti-core (bloc
     oniti-core/collection-01)
     -------------------------------------------------------------------------- */

  /* ----- Flèches du carrousel, aux couleurs de la maquette -----*/
  .oniti-collection-01 {
    --oniti-collection-01-nav-fill: var(--wp--preset--color--navy);
    --oniti-collection-01-nav-on-fill: var(--wp--preset--color--white);
    --oniti-collection-01-focus-color: var(--wp--custom--couleur--focus);

    /* Dégagement de bord, branché sur le padding racine */
    --oniti-collection-01-edge: var(--wp--style--root--padding-left, 1rem);
  }

  /* ----- Piste du carrousel : pas de débord plein cadre ----- */
  .oniti-collection-01__viewport {
    --oniti-collection-01-bleed: 0;
  }

/* ==========================================================================
     Carrousel d'écrans de l'application
     ==========================================================================
     Colonne de droite de la section « Disponible sur Android et iPhone » : un
     `oniti-core/collection-01` en carrousel permanent, un écran par vue.

     Trois choses tiennent ici et nulle part ailleurs : les badges des stores
     restent HORS du carrousel — seule l'image change —, les flèches quittent
     leur rangée sous la piste pour se poser à mi-hauteur de part et d'autre,
     et le semis de points est un décor du groupe, sans balisage.
     -------------------------------------------------------------------------- */

  .ao-app-slider {
    /* Largeur de l'écran de téléphone ; la piste, elle, occupe la colonne. */
    --ao-app-slider-ecran: 20rem;

    /* Ce qui sépare l'écran de chaque flèche. */
    --ao-app-slider-marge: 1rem;

    /* Semis de points : boîte du décor. */
    --ao-app-slider-decor-largeur: 14rem;
    --ao-app-slider-decor-hauteur: 8rem;

    /* Ce dont le semis passe sous l'écran, mesuré depuis le bord haut du groupe.
       Seul repère à régler : le décalage vers le haut s'en déduit, et reste juste
       si la hauteur du décor change. */
    --ao-app-slider-decor-recouvrement: 6rem;

    /* Gris très clair. Le SVG n'est pas recoloré, il sert de masque : une image
       de fond garderait les couleurs du fichier. */
    --ao-app-slider-decor-couleur: color-mix(
      in srgb,
      var(--wp--preset--color--slate) 20%,
      transparent
    );

    position: relative;

    /* Le décor passe en z-index négatif pour rester sous l'écran, qui n'est pas
       un élément positionné. Sans contexte d'empilement ici, ce négatif le ferait
       descendre sous le fond de la section : `isolation` le borne au groupe. */
    isolation: isolate;
  }

  .ao-app-slider::before {
    content: "";
    position: absolute;
    z-index: -1;
    inset-block-start: calc(
      var(--ao-app-slider-decor-recouvrement) - var(--ao-app-slider-decor-hauteur)
    );
    inset-inline-end: 0;
    inline-size: var(--ao-app-slider-decor-largeur);
    block-size: var(--ao-app-slider-decor-hauteur);

    background-color: var(--ao-app-slider-decor-couleur);

    /* Le semis découpe l'aplat au lieu d'être peint : c'est ce qui rend sa
       couleur réglable ici. Le masque suit le canal alpha du fichier, donc les
       points seuls laissent passer la couleur.

       `contain` et non `100% 100%` : le dessin garderait son ratio dans la boîte
       étirée et se centrerait, en laissant deux bandes vides. */
    -webkit-mask: url("../images/ao-fond-rond-paysage.svg") right top / contain
      no-repeat;
    mask: url("../images/ao-fond-rond-paysage.svg") right top / contain no-repeat;
  }

  /* ----- Piste : un écran par vue, centré entre les deux flèches ----- */
  .ao-app-slider .oniti-collection-01 {
    /* Place que prend une flèche avec sa marge, de chaque côté de l'écran.
       Déclaré ici et non sur le groupe : la taille dessinée arrive en style en
       ligne SUR le bloc, elle ne serait pas lisible un niveau au-dessus. */
    --ao-app-slider-couloir: calc(
      var(--oniti-collection-01-nav-size, 2.75rem) + var(--ao-app-slider-marge)
    );

    /* Largeur réelle de l'écran : celle qu'on veut, jamais plus que ce qui reste
       entre les deux couloirs. Une seule expression pour l'image ET le cadre des
       flèches — c'est ce qui les rend solidaires. Les deux `100%` valent la même
       chose, la piste n'ayant plus de dégagement latéral. */
    --ao-app-slider-ecran-reel: min(
      var(--ao-app-slider-ecran),
      calc(100% - 2 * var(--ao-app-slider-couloir))
    );

    /* Les flèches vont aux bords de la colonne : le dégagement de bord du
       squelette, qui sert de padding à leur rangée, tombe à zéro. */
    --oniti-collection-01-edge: 0;
    --oniti-collection-01-nav-space: 0;

    /* La piste n'ayant plus de dégagement, l'écart est tout ce qui tient l'écran
       suivant hors du champ : à zéro, les deux se toucheraient au bord. Le
       réglage d'écart du bloc reste au-dessus, arrivant en style en ligne. */
    --oniti-collection-01-gap: var(--wp--preset--spacing--s);

    position: relative;
  }

  .ao-app-slider .oniti-collection-01__viewport {
    /*
     * Aucun dégagement latéral, et c'est la condition pour ne rien voir de
     * l'écran voisin : le scrollport d'un conteneur de défilement est sa BOÎTE
     * DE PADDING, donc tout `padding-inline` reste dans le champ visible et y
     * laisse entrer la diapositive suivante — ce qu'on prenait pour une ombre.
     *
     * À zéro, une vue montre exactement une diapositive, et l'écart la sépare
     * de la suivante hors champ. Le squelette, lui, ouvre le dégagement du côté
     * départ pour faire justement dépasser la carte suivante.
     */
    --oniti-collection-01-inset: 0;
  }

  .ao-app-slider .oniti-collection-01__viewport img {
    display: block;
    margin-inline: auto;
    inline-size: 100%;

    max-inline-size: var(--ao-app-slider-ecran-reel);

    block-size: auto;
  }

  /* ----- Flèches : de part et d'autre de l'écran, à mi-hauteur ----- */
  .ao-app-slider .oniti-collection-01__nav:not([hidden]) {
    position: absolute;
    inset-block: 0;

    /* Rangée centrée, large de l'écran plus ses deux couloirs : `space-between`
       pose alors chaque flèche à `--ao-app-slider-marge` du bord de l'image, et
       non du bord de la colonne. Sur une colonne trop étroite pour la largeur
       voulue, la largeur réelle se réduit d'autant : la rangée retombe sur les
       bords de la colonne, sans jamais en sortir. */
    inline-size: calc(
      var(--ao-app-slider-ecran-reel) + 2 * var(--ao-app-slider-couloir)
    );
    inset-inline-start: 50%;
    translate: -50%;

    justify-content: space-between;
    max-inline-size: none;
    margin: 0;
    padding: 0;

    /* La rangée couvre toute la piste : sans cette réserve, elle intercepterait
       le glissement tactile entre les deux flèches. */
    pointer-events: none;
  }

  .ao-app-slider .oniti-collection-01__arrow {
    pointer-events: auto;
  }

/* ==========================================================================
     Signature — compte auteur
     ==========================================================================
     Pattern `signature-auteur` : photo, prénom nom, rôle du compte auteur.
     Tout l'habillage passe par les réglages des blocs.
     -------------------------------------------------------------------------- */
  .oniti-signature__fonction:empty {
    display: none;
  }

  /* Signature cliquable en entier avec UN seul lien : l'ancre du nom, rendue par
     la source de bindings, étirée par son ::after — `core/group` ne sait pas
     devenir un lien. Le nom plutôt que la photo, dont le nom accessible viendrait
     du `display_name` et contredirait le « Prénom Nom » affiché. Contrepartie : le
     calque empêche la sélection du texte.

     La classe peut manquer, un pattern étant copié dans le modèle à l'insertion :
     le repli `:has()` retrouve le groupe par sa forme, borné par `>` pour ne pas
     remonter aux ancêtres. `fit-content`, sinon la zone cliquable court sur toute
     la largeur du conteneur. */
  .oniti-signature,
  .wp-block-group:has(> .wp-block-avatar):has(.oniti-signature__lien) {
    position: relative;
    width: fit-content;
  }

  .oniti-signature__lien {
    color: inherit;
    text-decoration: none;
  }

  .oniti-signature__lien::after {
    content: "";
    position: absolute;
    inset: 0;
  }

  .oniti-signature__lien:hover {
    text-decoration: underline;
  }

  /* Le focus épouse la zone cliquable, pas le seul texte. */
  .oniti-signature__lien:focus-visible {
    outline: none;
  }

  .oniti-signature__lien:focus-visible::after {
    outline: 2px solid var(--wp--custom--couleur--focus);
    outline-offset: 3px;
    border-radius: 4px;
  }

  /* ==========================================================================
Tableau comparatif — core/table, style « Comparatif »
==========================================================================
La sémantique du tableau (scope, en-têtes de ligne) et la substitution de la
coche se font au rendu, dans functions.php : elles sont hors de portée du CSS.
-------------------------------------------------------------------------- */

.wp-block-table.is-style-comparatif {
    --ao-comparatif-filet: var(--wp--preset--color--light-darker);
    --ao-comparatif-rayon: 0.75rem;
    --ao-comparatif-colonne: 10rem;
}

.wp-block-table.is-style-comparatif table {
    /* `separate` obligatoire : en `collapse`, les rayons des cellules sautent. */
    border-collapse: separate;
    border-spacing: 0;
    border-radius: var(--ao-comparatif-rayon);

    /*
     * `fixed` : sans lui, les colonnes se dimensionnent au contenu et
     * « PREMIUM / Pastel de nata » sort plus large que « PRO / Brioche ». La
     * largeur des deux colonnes d'offre est donc posée plus bas, la première
     * prend le reste. Poser la règle ici rend aussi le tableau indifférent à
     * l'option « Cellules de largeur fixe » du bloc, qui sinon donnerait un
     * tiers de la largeur à la colonne des intitulés.
     */
    width: 100%;
    table-layout: fixed;
}

.wp-block-table.is-style-comparatif :is( th, td ):not( :first-child ) {
    width: var(--ao-comparatif-colonne);
}

/* Le cœur pose une bordure sur chaque cellule : les filets sont refaits ici,
   côté par côté, pour ne pas doubler les traits. */
.wp-block-table.is-style-comparatif :is( th, td ) {
    border: 0;
    padding: var(--wp--preset--spacing--xs) var(--wp--preset--spacing--s);
    vertical-align: middle;
    text-align: center;

    /* En `table-layout: fixed`, `width` désigne la boîte : sans ceci, le
       remplissage s'ajoute et les colonnes d'offre mangent les intitulés. */
    box-sizing: border-box;
}

.wp-block-table.is-style-comparatif :is( th, td ):first-child {
    text-align: left;
}

.wp-block-table.is-style-comparatif tbody tr + tr :is( th, td ) {
    border-top: 1px solid var(--ao-comparatif-filet);
}

.wp-block-table.is-style-comparatif tbody :is( th, td ) + :is( th, td ) {
    border-left: 1px solid var(--ao-comparatif-filet);
}

/* ---- En-tête de colonne ---- */

.wp-block-table.is-style-comparatif thead th {
    color: var(--wp--preset--color--navy);
    font-size: var(--wp--preset--font-size--p-medium);
}

/* Les deux offres : pastilles arrondies posées en haut des colonnes. Le filet
   les séparant est blanc, pour lire comme un écart et non comme une bordure. */
.wp-block-table.is-style-comparatif thead th:not( :first-child ) {
    background: var(--wp--preset--color--primary-lighter);
    border-radius: var(--ao-comparatif-rayon) var(--ao-comparatif-rayon) 0 0;
}

.wp-block-table.is-style-comparatif thead th + th {
    border-left: 2px solid var(--wp--preset--color--white);
}

/* Sous-titre de l'offre : saisi en Maj+Entrée puis mis en italique. */
.wp-block-table.is-style-comparatif thead th em {
    display: block;
    font-size: 0.8em;
    font-style: italic;
    font-weight: 400;
}

/* ---- Corps ---- */

.wp-block-table.is-style-comparatif tbody th {
    color: var(--wp--preset--color--navy);
    font-weight: 700;
}

/* Les filets entre lignes sont posés en `border-top` : la dernière ligne ferme
   donc le tableau elle-même. */
.wp-block-table.is-style-comparatif tbody tr:last-child :is( th, td ) {
    border-bottom: 1px solid var(--ao-comparatif-filet);
}

.wp-block-table.is-style-comparatif tbody tr:last-child :is( th, td ):first-child {
    border-bottom-left-radius: var(--ao-comparatif-rayon);
}

.wp-block-table.is-style-comparatif tbody tr:last-child :is( th, td ):last-child {
    border-bottom-right-radius: var(--ao-comparatif-rayon);
}

/* Le tableau est transparent : seule une ligne sur deux pose un fond. Basculer
   sur `even` inverse l'alternance. */
.wp-block-table.is-style-comparatif tbody tr:nth-child( odd ) :is( th, td ) {
    background: var(--wp--preset--color--white);
}

/* Repérage de la ligne survolée. Même spécificité que l'alternance ci-dessus :
   c'est l'ordre des règles qui le fait gagner, ne pas les intervertir.
   Décoratif — rien n'est cliquable ici, pas d'état de focus à doubler. */
.wp-block-table.is-style-comparatif tbody tr:hover :is( th, td ) {
    background: var(--wp--preset--color--accent-lighter);
}

/* ---- Coche ---- */

/* Le fichier porte ses propres couleurs (disque accent, trait marine) : rien à
   teinter ici. Pour les rattacher à la palette, passer ses `fill`/`stroke` à
   `currentColor` et poser la couleur ici. */
.ao-comparatif__coche {
    display: inline-block;
    width: 1.375rem;
    height: 1.375rem;
    vertical-align: middle;
}

/*
 * Mobile : le tableau tient en entier, sans défilement horizontal. Les deux
 * colonnes d'offre se resserrent sur leur contenu — « ∞ Illimité » est le plus
 * large — et tout l'espace restant va aux intitulés, qui passent sur plusieurs
 * lignes. Descendre `--ao-comparatif-colonne` plus bas casserait « Illimité »
 * en deux lignes avant de gagner quoi que ce soit.
 */
@media (width < 768px) {
    .wp-block-table.is-style-comparatif {
        --ao-comparatif-colonne: 5.5rem;
    }

    .wp-block-table.is-style-comparatif :is( th, td ),
    /* Répété : la règle de l'en-tête est plus spécifique que celle des cellules. */
    .wp-block-table.is-style-comparatif thead th {
        padding: 0.75rem 0.5rem;
        font-size: var(--wp--preset--font-size--p-little);
    }

    /* `table-layout: fixed` ne protège pas d'un mot plus large que sa colonne. */
    .wp-block-table.is-style-comparatif tbody th {
        overflow-wrap: break-word;
        hyphens: auto;
    }

    .ao-comparatif__coche {
        width: 1.25rem;
        height: 1.25rem;
    }
}

@media (width < 768px) {
    .ao-partenaires-logos figure {
        width: 50%;
    }
}

/* ==========================================================================
     Signature — compte auteur
==========================================================================*/
.calendly-inline-widget {
    width: 100%;
}

/* ==========================================================================
    Accordeon FAQ
==========================================================================*/
.ao-accordeon .wp-block-accordion-item  {
    padding-bottom: 1.5rem;
    border-bottom: 1px solid rgba(0,0,0,.1);
}

.ao-accordeon .wp-block-accordion-heading__toggle {
    padding-top: 0.5rem;
}

/* ==========================================================================
    Événement — date, heure et lieu
==========================================================================*/

/*
 * Ce n'est pas la catégorie qui décide de l'affichage, mais le champ : les règles
 * d'emplacement du groupe ACF disent où les champs existent, ces trois règles
 * effacent ce qui n'est pas rempli. Aucun slug de catégorie ici.
 *
 * Un paragraphe relié dont le champ est vide est rendu `<p></p>` par le cœur —
 * les classes ne gênent pas `:empty`, seul un blanc à l'intérieur le ferait.
 */
.ao-evenement p:empty {
    display: none;
}

/* La ligne part avec ses valeurs, ce qui emporterait un libellé statique ajouté
   à côté. */
.ao-evenement__ligne:not(:has(p:not(:empty))) {
    display: none;
}

/* Article ordinaire, aucun des trois champs : le bloc entier, son écart compris. */
.ao-evenement:not(:has(p:not(:empty))) {
    display: none;
}

/* ==========================================================================
   Page Tarifs
==========================================================================*/
.ao-offre-complete {
    margin-top: -4rem !important;
}

@media (width < 768px) {
    .ao-offre-complete {
        margin-top: 0rem !important;
    }
}

/* ==========================================================================
   Onglets — bloc oniti-core/tabs
==========================================================================
Le bloc d'oniti-core gère nativement l'orientation, l'icône par onglet, l'icône
de fin et l'échange de couleurs de l'onglet actif. Il ne reste ici que les
valeurs de la maquette, posées en tokens.

Ce sont des DÉFAUTS, pas des verrous : les réglages pris dans l'inspecteur
arrivent en style inline sur l'enveloppe, donc ils passent devant cette feuille.
Un onglet inséré sans un clic ressemble malgré tout à la maquette.

L'onglet actif n'est pas décrit ici : sans token `-selected`, oniti-core échange
les deux couleurs du repos — blanc sur marine devient marine sur blanc, ce qui
est exactement la maquette. Le survol reprend le même dessin.
-------------------------------------------------------------------------- */

.oniti-tabs {
    --oniti-tabs-tab-background: var(--wp--preset--color--white);
    --oniti-tabs-tab-color: var(--wp--preset--color--navy);
    --oniti-tabs-tab-ring: var(--wp--preset--color--navy);
    --oniti-tabs-tab-stroke: 1px;
    --oniti-tabs-tab-radius: 0.75rem;
    --oniti-tabs-tab-padding: 1rem 1.25rem;
    --oniti-tabs-tab-font-weight: 700;
    --oniti-tabs-list-gap: 0.75rem;
    --oniti-tabs-trailing-color: var(--wp--preset--color--accent);
}

/* ==========================================================================
   À PROPOS — cartes de l'équipe
   ==========================================================================

   Carte cliquable dont le lien unique est une icône de réseau social. Classes à
   poser sur le Groupe : `is-style-carte-cliquable ao-equipe`. Et `oniti-carte-lien`
   sur le bloc Icônes de réseaux sociaux, pour qu'oniti-core y accroche la zone
   de clic étendue — une seule icône par carte, c'est le contrat du style.

   Les couleurs de l'icône se règlent ICI, pas dans l'inspecteur : le cœur écrit
   les siennes en style inline sur le `<li>`, et aucun sélecteur ne bat l'inline.
   Laisser le panneau Couleurs des Icônes de réseaux sociaux intact.
   -------------------------------------------------------------------------- */

.ao-equipe {
    /* L'inversion tient dans ces deux valeurs : le survol les échange. */
    --ao-equipe-icone-fond: var(--wp--preset--color--navy);
    --ao-equipe-icone-couleur: var(--wp--preset--color--accent);
}

/* La photo, pas la carte. `> img` ne marchait pas : le cœur enveloppe l'image
   dans une `<figure>`. */
.ao-equipe :is(.wp-block-image, .wp-block-post-featured-image) img {
    border-radius: 50%;
    transition:
        transform 200ms ease,
        box-shadow 200ms ease;
}

/* `focus-within` : au clavier, le lien de l'icône déclenche le même effet. */
.ao-equipe:hover :is(.wp-block-image, .wp-block-post-featured-image) img,
.ao-equipe:focus-within :is(.wp-block-image, .wp-block-post-featured-image) img {
    transform: translateY(-2px);
    box-shadow: 0 4px 12px var(--wp--custom--couleur--ombre);
}

/* Icône au repos. Quatre classes pour battre les couleurs de marque du cœur,
   qui en alignent trois. */
.ao-equipe .wp-block-social-links .wp-block-social-link.wp-social-link {
    background-color: var(--ao-equipe-icone-fond);
    color: var(--ao-equipe-icone-couleur);
    transition:
        background-color 200ms ease,
        color 200ms ease;
}

/* Inversion au survol de la CARTE — le `<svg>` du cœur est en `fill: currentColor`. */
.ao-equipe:hover .wp-block-social-links .wp-block-social-link.wp-social-link,
.ao-equipe:focus-within .wp-block-social-links .wp-block-social-link.wp-social-link {
    background-color: var(--ao-equipe-icone-couleur);
    color: var(--ao-equipe-icone-fond);
}

/* Indispensable, et invisible à la lecture du HTML : le cœur agrandit l'icône
   au survol (`.wp-block-social-link:hover { transform: scale(1.1) }`). Un
   `transform` fait du `<li>` le bloc conteneur du `::after` absolu qui porte la
   zone de clic — laquelle se rétracte sur l'icône dès que la souris entre dans
   la carte, ressort, rentre : la carte clignote et le clic devient erratique. */
.ao-equipe .wp-block-social-links .wp-block-social-link.wp-social-link,
.ao-equipe .wp-block-social-links .wp-block-social-link.wp-social-link:hover {
    transform: none;
}

/* WCAG 2.3.3 — seul le déplacement se neutralise ; ombre et inversion restent
   et portent seules l'affordance. */
@media (prefers-reduced-motion: reduce) {
    .ao-equipe :is(.wp-block-image, .wp-block-post-featured-image) img,
    .ao-equipe .wp-block-social-links .wp-block-social-link.wp-social-link {
        transition-duration: 1ms;
    }

    .ao-equipe:hover :is(.wp-block-image, .wp-block-post-featured-image) img,
    .ao-equipe:focus-within :is(.wp-block-image, .wp-block-post-featured-image) img {
        transform: none;
    }
}

.ao-pastel-de-nata:after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 1;
    pointer-events: none;
    background-image: url("../icons/etoile.svg");
    background-repeat: no-repeat;
    background-position: center bottom;
}

/* ── Puce de couleur ────────────────────────────────────────────────────────
   * Fond et liseré ne sont pas écrits ici : ce sont les contrôles natifs de
   * core/button, prix puce par puce dans l'inspecteur. Le `:not(.has-border-color)`
   * ne pose un défaut que tant que le rédacteur n'a rien choisi.
   *
   * En (0,2,0) pour passer devant `elements.button` de theme.json, qui pose
   * padding, rayon 12px et bordure 2px sur tous les boutons du site.
   */
  .is-style-puce .wp-element-button {
    --ao-puce-taille: 2.5rem;

    display: block;
    inline-size: var(--ao-puce-taille);
    block-size: var(--ao-puce-taille);
    padding: 0;
    border-radius: 50%;
    border-width: 1px;

    /* Hors du champ visuel, pas hors de l'arbre d'accessibilité : `display: none`
       et `visibility: hidden` retireraient le nom du lien. */
    text-indent: 100%;
    white-space: nowrap;
    overflow: hidden;
  }

  /* Sans liseré, une puce claire sur fond clair n'a plus de contour perceptible
     (RGAA 3.2) — et la puce blanche de la maquette disparaîtrait tout court. */
  .is-style-puce .wp-element-button:not(.has-border-color) {
    border-color: var(--wp--preset--color--light-darker);
  }

  /* L'ombre portée d'`elements.button:hover` n'a pas de sens sur un disque. */
  .is-style-puce .wp-element-button:hover {
    box-shadow: none;
    transform: scale(1.12);
  }

  .is-style-puce .wp-element-button:focus-visible {
    outline-offset: 2px;
  }

  /* WCAG 2.3.3 */
  @media ( prefers-reduced-motion: reduce ) {
    .is-style-puce .wp-element-button {
      transition-duration: 1ms;
    }

    .is-style-puce .wp-element-button:hover {
      transform: none;
    }
  }
