/* ==========================================================================
   DIVI OVERRIDES – Ajustements ciblés des structures générées par Divi.
   Règle : on ne cible les classes internes Divi que lorsqu'une option du
   Customizer / Theme Builder ne suffit pas. Chaque !important est justifié.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Variables de mise en page Divi 5 (définies sur :root dans son CSS
   dynamique, chargé avant nous) : espacement entre modules supprimé,
   espacement entre sections réduit de 60 à 30px.
   -------------------------------------------------------------------------- */
:root {
  --module-gutter: 0px;
  --section-gutter: 30px;
}

/* Gouttière de 16px (maquette) — horizontale ET verticale.
   À poser sur une SECTION : Divi 5 dérive tous ses gaps flex de ces variables
   (section → --section-gutter entre lignes ; ligne → --row-gutter-* entre
   colonnes ; colonne → --module-gutter entre modules empilés). On les cale
   toutes à 16px pour un espacement uniforme, cascadé sur le sous-arbre. */
.km-gap-16 {
  --section-gutter: 16px;          /* écart vertical entre les lignes */
  --row-gutter-horizontal: 16px;   /* écart horizontal entre les colonnes */
  --row-gutter-vertical: 16px;     /* écart vertical entre lignes imbriquées */
  --module-gutter: 16px;           /* écart entre modules empilés dans une colonne */
}

/* Encadré beige : fond crème, padding intérieur fluide (40px à 1440px →
   5px vers 375px), gouttières internes de 16px. À poser sur une Section ou
   une Ligne. Le padding fluide « évolue » sans saut brutal entre desktop
   et mobile. */
.km-box-beige {
  background-color: var(--color-surface);
  padding: clamp(5px, calc(3.28vw - 7.25px), 40px) !important;
  height: 100%; /* remplit la colonne → encadrés de même hauteur côte à côte */
  --section-gutter: 16px;
  --row-gutter-horizontal: 16px;
  --row-gutter-vertical: 16px;
  --module-gutter: 16px;
}

/* La ligne parente étire ses colonnes à égalité (défaut Divi 5, forcé ici) */
.et_pb_row:has(> .et_pb_column .km-box-beige),
.et_pb_row:has(> .et_pb_column.km-box-beige) {
  align-items: stretch !important;
}

/* Modifieur de km-box-beige : l'encadré prend la hauteur de son contenu au
   lieu de s'aligner sur son voisin le plus haut. À ajouter en plus :
   km-box-beige km-box-auto */
.km-box-beige.km-box-auto {
  height: auto;
}

/* Cas où la classe est posée sur la COLONNE : la ligne l'étire malgré tout
   (align-items: stretch ci-dessus), il faut donc la désolidariser. Restreint
   à .et_pb_column à dessein — sur un module, la colonne Divi 5 étant un flex
   container vertical, align-self jouerait sur la largeur et non la hauteur. */
.et_pb_column.km-box-beige.km-box-auto {
  align-self: flex-start;
}

/* Chiffres clés en DESKTOP : grille 3 colonnes × 2 rangées → les rangées
   sont alignées (une rangée de grille a la hauteur de sa cellule la plus
   haute). Les colonnes Divi sont aplaties (display: contents) pour que les
   6 stats deviennent des cellules de la grille. grid-auto-flow: column place
   les stats colonne par colonne (comme la structure Divi d'origine).
   Classe DÉDIÉE (km-stats-grid) : ne pas confondre avec km-2col-mobile qui,
   elle, s'applique à plusieurs blocs et ne gère que le mobile.
   Réglable via --km-stats-col-gap / --km-stats-row-gap. */
@media (min-width: 768px) {
  body #page-container .et_pb_row.km-stats-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-template-rows: repeat(2, auto);
    grid-auto-flow: column;
    column-gap: var(--km-stats-col-gap, 5.5%);
    row-gap: var(--km-stats-row-gap, 48px);
    align-items: start;
  }

  .km-stats-grid > .et_pb_column {
    display: contents;
  }
}

/* Variante « collé » de km-box-beige : padding bas divisé par 2 (moitié du
   clamp de base), et marge négative pour annuler le gap flex entre modules
   de Divi 5 → le module image suivant se colle à l'encadré.
   À ajouter à côté : "km-box-beige km-box-flush". Gap réglable : --km-flush-gap. */
.km-box-beige.km-box-flush {
  padding-bottom: clamp(2.5px, calc(1.64vw - 3.63px), 20px) !important;
  margin-bottom: calc(-1 * var(--km-flush-gap, 16px)) !important;
}

/* Dans l'encadré beige : aucun espace sous les h6 (padding ET marge) ni les p.
   #page-container sur le p : bat la règle des paragraphes Divi. */
.km-box-beige h6 {
  padding-bottom: 0 !important;
  margin-bottom: 0 !important;
}

/* Dans le bloc vert en chevauchement : pas de padding ni de marge bas sous les h6 */
.km-overlap-up-bg h6 {
  padding-bottom: 0 !important;
  margin-bottom: 0 !important;
}

#page-container .km-box-beige p {
  padding-bottom: 0 !important;
}

/* Dans l'encadré beige : espace fluide sous les h3 (100px desktop → 30px mobile) */
.km-box-beige h3 {
  padding-bottom: clamp(30px, 6.94vw, 100px) !important;
}

/* --------------------------------------------------------------------------
   Conteneur : marges latérales fluides (90px à 1440px), sans largeur
   maximale — le contenu suit la taille de l'écran.
   Spécificité renforcée (body #page-container) : Divi injecte sa propre
   largeur (.et_pb_row { max-width: 1080px }) en style inline dans le <head>,
   après nos feuilles — une simple classe ne suffit pas à la battre.
   -------------------------------------------------------------------------- */
body #page-container .et_pb_row {
  max-width: var(--container-width);
  width: calc(100% - 2 * var(--container-padding));
  position: relative; /* ancre les modules absolus (km-img-right) sur la ligne */
}

/* Ligne pleine largeur : supprime les marges latérales, les colonnes se
   répartissent sur toute la largeur avec une gouttière de 16px.
   Réf. maquette « Le projet ». À poser sur la LIGNE.
   Double classe (.et_pb_row.km-row-full) pour battre l'override ci-dessus. */
body #page-container .et_pb_row.km-row-full {
  width: 100%;
  max-width: none;
  --row-gutter-horizontal: 16px;
  --row-gutter-vertical: 16px;
}

/* Modificateur à AJOUTER sur une ligne pleine largeur (à côté de km-row-full,
   qui reste inchangée) : les IMAGES vont jusqu'aux bords de l'écran, seul le
   TEXTE de la PREMIÈRE colonne est rentré. Les autres colonnes ne reçoivent
   rien. Le retrait est un pourcentage de la largeur de la colonne (et non des
   marges du site), réglable via --km-text-inset. Ne cible que .et_pb_text :
   les modules Image ne sont pas touchés. */
.km-text-inset {
  --km-text-inset: 10%;
}

.km-text-inset > .et_pb_column:first-child .et_pb_text {
  padding-left: var(--km-text-inset);
}

/* Décalage vertical de 3 colonnes d'images (réf. « Localisation »).
   Version « images » de km-cols-stagger, sans les règles texte.
   À poser sur la LIGNE (avec km-row-full pour la gouttière 16px).
   Décalages réglables via --km-off1 / --km-off2 / --km-off3. Annulé mobile. */
.km-cols-offset {
  --km-off-base: 260px; /* descend tout le bloc (col 3 img1 arrive dans le texte) */
  --km-off1: 0px;
  --km-off2: 120px;     /* colonne 2 plus basse */
  /* négatif : la col 3 remonte de (hauteur 1re image col3 + 16px) → sa 2e
     image s'aligne avec l'image de la col 1. Fluide (colonne = ⅓ écran,
     1re image ratio 0.854). */
  --km-off3: calc(-28.5vw - 7px);
}

/* Descente de tout le bloc — spécificité + !important pour battre la marge
   de ligne de Divi. */
body #page-container .et_pb_row.km-cols-offset {
  margin-top: var(--km-off-base) !important;
}

/* z-index : la colonne remontée passe par-dessus le contenu précédent */
.km-cols-offset > .et_pb_column {
  position: relative;
  z-index: 2;
}

.km-cols-offset > .et_pb_column:nth-child(1) {
  margin-top: var(--km-off1);
}

.km-cols-offset > .et_pb_column:nth-child(2) {
  margin-top: var(--km-off2);
}

.km-cols-offset > .et_pb_column:nth-child(3) {
  margin-top: var(--km-off3);
}

/* Images : gouttière verticale de 16px entre 2 images empilées dans une colonne */
.km-cols-offset .et_pb_image + .et_pb_image {
  margin-top: 16px;
}

/* Rythme : décalage vertical des colonnes pour casser l'alignement plat.
   La colonne de droite sert de référence (0, la plus haute), le milieu descend
   le plus, la gauche se place entre les deux. Aucun décalage négatif → rien ne
   remonte par-dessus la section précédente. Réglable colonne par colonne.
   À poser sur la LIGNE. Annulé sur téléphone (colonnes empilées). */
.km-cols-rhythm {
  --km-rhythm1: 40px; /* gauche : intermédiaire */
  --km-rhythm2: 80px; /* milieu : la plus basse */
  --km-rhythm3: 0px;  /* droite : la plus haute, sert de référence */

  /* Respiration VERTICALE au-dessus du texte de la colonne centrale : le double
     du décalage de la première colonne. En pixels et non en pourcentage — un
     padding vertical en % se calcule sur la LARGEUR du conteneur, ce qui
     donnerait une valeur sans rapport avec le rythme voulu. */
  --km-rhythm-pad: calc(var(--km-rhythm1) * 2);
}

.km-cols-rhythm > .et_pb_column:nth-child(2) .et_pb_text {
  padding-top: var(--km-rhythm-pad);
}

.km-cols-rhythm > .et_pb_column:nth-child(1) {
  margin-top: var(--km-rhythm1);
}

.km-cols-rhythm > .et_pb_column:nth-child(2) {
  margin-top: var(--km-rhythm2);
}

.km-cols-rhythm > .et_pb_column:nth-child(3) {
  margin-top: var(--km-rhythm3);
}

/* Colonnes décalées verticalement (réf. « Le projet ») :
   - col 1 : texte aligné sur la marge du contenu, padding-top 80px
   - col 2 : alignée en haut (son texte s'aligne sur le haut de l'image col 1)
   - col 3 : abaissée pour que son texte tombe au bas de l'image de la col 2
   Décalages réglables : --km-col2-top / --km-col3-top.
   À poser sur la LIGNE (en plus de km-row-full). */
.km-cols-stagger {
  --km-col2-top: 0px;
  --km-col3-top: 240px;
  --km-col3-img-top: -400px; /* remonte l'image de la col 3 */
  --km-col2-pb: 12.5vw;      /* padding bas du texte col 2 (~180px à 1440) */
  --km-col3-pt: 22.2vw;      /* padding haut du texte col 3 (~320px à 1440) */
}

/* Texte col 1 : aligné sur la marge gauche du contenu, décalé de 80px vers le bas */
.km-cols-stagger > .et_pb_column:nth-child(1) .et_pb_text {
  padding-left: var(--margin-outer);
  padding-top: 80px;
}

/* Texte col 2 et 3 : padding de 16px */
.km-cols-stagger > .et_pb_column:nth-child(2) .et_pb_text,
.km-cols-stagger > .et_pb_column:nth-child(3) .et_pb_text {
  padding-left: 16px;
  padding-right: 16px;
}

/* Texte col 2 : espace en dessous */
.km-cols-stagger > .et_pb_column:nth-child(2) .et_pb_text {
  padding-bottom: var(--km-col2-pb);
}

/* Texte col 3 : espace au-dessus */
.km-cols-stagger > .et_pb_column:nth-child(3) .et_pb_text {
  padding-top: var(--km-col3-pt);
}

/* Décalage vertical des colonnes */
.km-cols-stagger > .et_pb_column:nth-child(2) {
  margin-top: var(--km-col2-top);
}

.km-cols-stagger > .et_pb_column:nth-child(3) {
  margin-top: var(--km-col3-top);
}

/* Image de la col 3 remontée (marge négative) */
.km-cols-stagger > .et_pb_column:nth-child(3) .et_pb_image {
  margin-top: var(--km-col3-img-top);
}

/* Images à leur ratio naturel (aucun rognage hérité) */
.km-cols-stagger .et_pb_image img {
  height: auto !important;
  object-fit: initial;
}

/* --------------------------------------------------------------------------
   Header — header par défaut de Divi (#main-header).
   Maquette : bandeau blanc 100px, arrondi bas-gauche, mêmes marges latérales
   que le contenu, menu Outfit Medium 20/28 vert.
   `!important` justifiés au cas par cas : le JS de Divi injecte des styles
   inline (padding de navigation, hauteur de logo) recalculés au chargement.
   -------------------------------------------------------------------------- */
#main-header,
#main-header.et-fixed-header {
  background-color: var(--color-background);
  border-bottom-left-radius: var(--border-radius-lg);
  box-shadow: none;
}

/* Décalage fluide du bandeau : left/right + width auto garantissent que la
   marge réduit la largeur du header fixe au lieu de le faire déborder. */
#main-header {
  margin-left: var(--header-offset);
  left: 0;
  right: 0;
  width: auto;
}

/* Bandeau de 100px, contenu aligné sur les marges des lignes de contenu :
   la part de marge non consommée par le décalage du bandeau est reportée
   à l'intérieur, le logo reste donc calé sur la marge du site. */
#main-header .container {
  width: auto;
  max-width: none;
  margin-left: calc(var(--margin-outer) - var(--header-offset));
  margin-right: var(--margin-outer);
  min-height: var(--header-height);
  display: flex;
  align-items: center;
  justify-content: space-between;
}

/* Le ::after du clearfix Divi devient un 3e item flex : space-between
   pousse alors le menu au centre au lieu de la marge droite. */
#main-header .container::after {
  display: none;
}

/* Logo à la taille maquette (~60px de haut dans le bandeau de 100px).
   position/width : Divi place ce conteneur en absolute pleine largeur,
   ce qui le sort du flux flex et fait chevaucher le menu. */
#main-header .logo_container {
  position: static;
  width: auto;
  float: none;
  height: auto;
  align-self: stretch; /* occupe toute la hauteur du bandeau… */
  display: flex;
  align-items: center; /* …et centre le logo en son milieu */
}

/* Espaceur interne de Divi (vertical-align), inutile en flex */
#main-header .logo_helper {
  display: none;
}

/* Logo : proportions toujours intactes. Hauteur bornée, largeur libre
   (width/height auto + max-width none), y compris pour un logo SVG
   auquel Divi impose sinon une hauteur en % du header.
   Double id : bat `.et_pb_svg_logo #logo { height: 54% }`. */
#main-header #logo {
  max-height: 86px !important; /* Divi force une hauteur en % via style inline */
  width: auto;
  height: auto;
  max-width: none; /* le max-width:100% de Divi écraserait le logo à hauteur imposée */
}

/* Navigation : neutralise le padding vertical calculé en JS par Divi.
   align-self stretch + align-items center = menu exactement sur l'axe
   du logo, quelle que soit la hauteur interne des éléments Divi. */
#main-header #et-top-navigation {
  float: none;
  padding: 0 !important; /* style inline injecté par Divi au chargement */
  margin: 0;
  align-self: stretch;
  display: flex;
  align-items: center;
}

/* Items du menu en flex : espacement contrôlé, dernier lien calé sur la
   marge droite (Divi ajoute sinon un padding-right de 22px à chaque li,
   y compris le dernier, ce qui décale le menu par rapport au contenu). */
#top-menu {
  display: flex;
  align-items: center;
  gap: clamp(1.25rem, 2.5vw, 2.5rem);
}

#top-menu > li {
  padding-right: 0;
  margin: 0;
}

#main-header #et-top-navigation {
  margin: 0;
}

/* Centre le menu sur l'axe vertical du logo (le nav interne de Divi
   n'hérite pas du centrage flex du conteneur) */
#main-header #et-top-navigation nav {
  display: flex;
  align-items: center;
}

/* Neutralise le line-height: 0 et les hauteurs injectés par le CSS
   dynamique de Divi 5, qui décalent le menu vers le haut du bandeau */
#main-header #top-menu-nav,
#main-header #top-menu {
  line-height: var(--leading-body);
  height: auto;
  min-height: 0;
}

/* Liens du menu : Outfit Medium 20/28 (planche design system).
   Double id (#main-header + #top-menu / #et-top-navigation) : indispensable
   pour battre `.et_header_style_left #et-top-navigation nav>ul>li>a
   { padding-bottom: 33px }` du CSS dynamique de Divi, qui décentrait
   le menu vers le haut du bandeau. */
#main-header #top-menu li a,
#main-header #et-top-navigation nav > ul > li > a {
  font-family: var(--font-body);
  font-size: var(--font-size-base);
  font-weight: var(--weight-medium);
  line-height: var(--leading-body);
  letter-spacing: var(--tracking-base);
  color: var(--color-primary);
  padding: 0;
}

#main-header #top-menu li a:hover,
#main-header #top-menu li.current-menu-item > a {
  color: var(--color-secondary);
  opacity: 1; /* Divi applique une opacité .7 au survol */
}

/* Hamburger mobile : Divi lui ajoute aussi un padding-bottom de 24px */
#main-header #et-top-navigation .mobile_menu_bar {
  padding-bottom: 0;
}

/* Sous-menus éventuels : plus compacts */
#top-menu li li a {
  font-size: var(--font-size-sm);
}

/* Icône de recherche : absente de la maquette */
#et_top_search,
#main-header .et_search_outer {
  display: none;
}

/* --------------------------------------------------------------------------
   Boutons Divi : tout module Bouton hérite du style pilule de base.
   Les déclinaisons se font en posant km-button--… sur le module.
   `!important` requis : Divi inline ses styles de bordure/radius
   via l'attribut style et des sélecteurs body #page-container.
   -------------------------------------------------------------------------- */
body #page-container .et_pb_button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  min-height: 44px;
  padding: 0.65em 1.75em !important; /* Divi ajoute un padding droit pour son icône flèche */
  border-radius: var(--border-radius-pill) !important;
  font-family: var(--font-body) !important;
  font-size: 1rem;
  font-weight: var(--weight-medium);
  line-height: 1 !important; /* Divi impose 1.7em ; resserre l'interlignage des boutons multi-lignes */
  transition: background-color var(--transition-default),
              border-color var(--transition-default),
              color var(--transition-default);
}

/* Désactive l'icône flèche par défaut des boutons Divi (absente de la maquette) */
body #page-container .et_pb_button::after {
  display: none;
}

/* --------------------------------------------------------------------------
   Variantes de boutons sur les modules Divi.
   Les classes km-button--… de components.css (spécificité 0,1,0) perdent face
   aux sélecteurs de Divi (body #page-container …) : on les redéclare ici au
   même niveau de spécificité. Chaque règle couvre les deux emplacements
   possibles de la classe selon la version de Divi : sur le lien lui-même ou
   sur le wrapper du module.

   Prérequis côté Builder : onglet Design → « Utiliser des styles personnalisés
   pour le bouton » doit rester DÉSACTIVÉ (sinon Divi injecte ses propres
   couleurs en ligne, plus fortes que toute feuille de style).
   -------------------------------------------------------------------------- */

/* Bouton 01 – fond sable, texte vert */
body #page-container .et_pb_button.km-button--sand,
body #page-container .km-button--sand .et_pb_button {
  background-color: var(--color-secondary);
  border: 1px solid transparent;
  color: var(--color-primary);
}

body #page-container .et_pb_button.km-button--sand:hover,
body #page-container .km-button--sand .et_pb_button:hover {
  background-color: #B29A78;
  color: var(--color-primary);
}

/* Bouton 02 – contour sable, texte sable (sur fond vert) */
body #page-container .et_pb_button.km-button--outline-light,
body #page-container .km-button--outline-light .et_pb_button {
  background-color: transparent;
  border: 1px solid var(--color-secondary);
  color: var(--color-secondary);
}

body #page-container .et_pb_button.km-button--outline-light:hover,
body #page-container .km-button--outline-light .et_pb_button:hover {
  background-color: var(--color-secondary);
  color: var(--color-primary);
}

/* Bouton 03 – fond vert, texte blanc */
body #page-container .et_pb_button.km-button--primary,
body #page-container .km-button--primary .et_pb_button {
  background-color: var(--color-primary);
  border: 1px solid var(--color-primary);
  color: var(--color-on-primary);
}

body #page-container .et_pb_button.km-button--primary:hover,
body #page-container .km-button--primary .et_pb_button:hover {
  background-color: #0F2E1B; /* même assombrissement que components.css */
  color: var(--color-on-primary);
}

/* Bouton 04 – contour vert, texte vert (sur fond clair) */
body #page-container .et_pb_button.km-button--outline,
body #page-container .km-button--outline .et_pb_button {
  background-color: transparent;
  border: 1px solid var(--color-primary);
  color: var(--color-primary);
}

body #page-container .et_pb_button.km-button--outline:hover,
body #page-container .km-button--outline .et_pb_button:hover {
  background-color: var(--color-primary);
  color: var(--color-on-primary);
}

/* --------------------------------------------------------------------------
   Formulaire de contact Divi — disposition en grille 3 colonnes (maquette) :
   Nom | Prénom | Commentaire (grande zone à droite, pleine hauteur)
   Email | Téléphone |
   Choix de typologie (2 colonnes) |
   Consentement (2 colonnes) | Envoyer
   Placement par TYPE de champ via :has() → indépendant de l'ordre des champs.
   -------------------------------------------------------------------------- */
#page-container .km-form .et_pb_contact_form {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: var(--space-sm);
  align-items: start;
}

/* Neutralise le système de colonnes flottantes de Divi sur chaque champ */
#page-container .km-form .et_pb_contact_field {
  width: auto !important;
  margin: 0 !important;
  padding: 0 !important;
  float: none !important;
}

/* Commentaire (textarea) : colonne 3, hauteur = les 4 rangées de gauche, soit
   Civilité, Nom/Prénom, Email/Téléphone et Choix de typologie — son bas
   s'aligne donc sur celui de Choix de typologie. align-self stretch + flex :
   le champ occupe les 4 rangées, le textarea grandit pour les remplir.
   À ajuster si une rangée est ajoutée ou retirée au-dessus de la typologie. */
#page-container .km-form .et_pb_contact_field:has(textarea) {
  grid-column: 3;
  grid-row: 1 / span 4;
  align-self: stretch;
  display: flex;
  flex-direction: column;
}

/* Listes déroulantes (Civilité, Choix de typologie) : sur 2 colonnes */
#page-container .km-form .et_pb_contact_field:has(select) {
  grid-column: 1 / span 2;
}


/* Consentement (case à cocher) : sur 2 colonnes */
#page-container .km-form .et_pb_contact_field:has([type='checkbox']) {
  grid-column: 1 / span 2;
}

/* Résident Bernex : colonne 1 seule, pour laisser Adresse venir à côté */
#page-container .km-form .et_pb_contact_field:has([type='radio']) {
  grid-column: 1;
}

/* Bouton Envoyer : colonne 3, sur la dernière rangée, en face du consentement.
   Rangée explicite : sans elle il remonterait à la première case libre de la
   colonne 3, c'est-à-dire à côté de Résident Bernex et d'Adresse.
   Carte des rangées : 1 Civilité · 2 Nom/Prénom · 3 Email/Téléphone ·
   4 Choix de typologie · 5 Résident Bernex + Adresse · 6 Consentement.
   Le numéro est à décaler si une rangée est ajoutée dans la colonne de gauche. */
#page-container .km-form .et_contact_bottom_container {
  grid-column: 3;
  grid-row: 6;
  margin: 0;
  padding: 0;
}

/* --------------------------------------------------------------------------
   Champs blancs sur section crème, coins arrondis, ombre douce (maquette).
   Préfixe #page-container : bat les styles de champs par défaut de Divi,
   sinon ces règles sont ignorées.
   -------------------------------------------------------------------------- */
#page-container .km-form .et_pb_contact_field input,
#page-container .km-form .et_pb_contact_field textarea,
#page-container .km-form .et_pb_contact_field select {
  background-color: var(--color-background);
  border: none;
  border-radius: 8px; /* arrondi des champs (maquette) */
  box-shadow: var(--shadow-soft);
  padding: 1.15em 1.4em;
  font-family: var(--font-body);
  font-size: var(--font-size-sm);
  font-weight: var(--weight-light);
  line-height: 1.3;
  color: var(--color-text);
  width: 100%;
}

/* La zone Commentaire remplit toute la hauteur du champ (les 3 lignes) */
#page-container .km-form .et_pb_contact_field:has(textarea) textarea {
  flex: 1;
  min-height: 8em;
  resize: vertical;
}

/* Libellés affichés en pleine teinte dans les champs (maquette) */
#page-container .km-form .et_pb_contact_field input::placeholder,
#page-container .km-form .et_pb_contact_field textarea::placeholder {
  color: var(--color-text);
  opacity: 1;
}

#page-container .km-form .et_pb_contact_field input:focus,
#page-container .km-form .et_pb_contact_field textarea:focus,
#page-container .km-form .et_pb_contact_field select:focus {
  outline: 2px solid var(--color-primary);
  outline-offset: 1px;
}

/* Select « Choix de typologie » : une seule flèche, le triangle sable de la
   maquette. !important : le CSS Customizer de Divi charge après le thème
   enfant et réactive sinon l'apparence native (flèche grise). */
#page-container .km-form .et_pb_contact_field select {
  appearance: none !important;
  -webkit-appearance: none !important;
  -moz-appearance: none !important;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='10'%3E%3Cpath d='M0 0h14L7 10z' fill='%23C3AD8F'/%3E%3C/svg%3E") !important;
  background-repeat: no-repeat !important;
  background-position: right 1.4em center !important;
  padding-right: 3em;
}

/* IE/Edge legacy : supprime la flèche native */
#page-container .km-form .et_pb_contact_field select::-ms-expand {
  display: none;
}

/* Seconde flèche, grise : Divi la trace en triangle de bordures (#666) sur le
   ::after du conteneur du champ, en plus du fond du select. On la retire pour
   ne garder que le triangle sable de la maquette. */
#page-container .km-form .et_pb_contact_field:has(select)::after {
  display: none;
}

/* Options du menu déroulant : fond beige clair au lieu du gris par défaut */
#page-container .km-form .et_pb_contact_field select option {
  background-color: var(--color-surface);
  color: var(--color-text);
}

/* Contrôles à cocher — consentement ET boutons Oui/Non : même présentation,
   cercle sable sur fond blanc. Les radios étaient restées natives (cercles
   gris système), le consentement seul était habillé : les deux partagent
   désormais la même règle. L'ombre douce, celle des champs de saisie, détache
   le contrôle du fond crème de la section — sans elle, une bordure sable de
   1px sur crème est presque invisible. */
#page-container .km-form input[type='checkbox'],
#page-container .km-form input[type='radio'] {
  appearance: none;
  -webkit-appearance: none;
  width: 20px;
  height: 20px;
  margin: 0 0.75em 0 0;
  border: 1px solid var(--color-secondary);
  border-radius: 50%;
  background-color: var(--color-background);
  box-shadow: var(--shadow-soft);
  background-repeat: no-repeat;
  background-position: center;
  background-size: 62%;
  flex-shrink: 0;
  cursor: pointer;
  transition: border-color var(--transition-default);
}

/* Coché : fond blanc conservé, coche (✓) verte */
#page-container .km-form input[type='checkbox']:checked {
  border-color: var(--color-primary);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2 6.2l2.6 2.6L10 3' fill='none' stroke='%23153F25' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}

/* Radio cochée : pastille verte pleine, convention attendue pour un choix
   exclusif (la coche reste réservée aux cases à cocher). */
#page-container .km-form input[type='radio']:checked {
  border-color: var(--color-primary);
  background-image: radial-gradient(
    circle,
    var(--color-primary) 0 45%,
    transparent 46%
  );
  background-size: 100%;
}

#page-container .km-form input[type='checkbox']:focus-visible,
#page-container .km-form input[type='radio']:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}

/* Sur ses champs « case à cocher » et « bouton radio », Divi masque l'input
   et dessine le contrôle visible dans un <i>, dont il bascule le ::before à la
   sélection — d'où la coche bleue #2EA3F2 d'origine, insensible aux règles
   ci-dessus qui ne portaient que sur l'élément masqué. C'est donc ce <i> qu'il
   faut habiller pour que consentement et boutons Oui/Non soient identiques.
   display : le <i> est un enfant de label, mis en inline-flex plus bas, mais
   on ne s'y fie pas — sans display de bloc, largeur et hauteur seraient
   ignorées si Divi changeait le balisage de l'un des deux types de champ. */
#page-container .km-form .et_pb_contact_field label > i {
  display: inline-block;
  position: relative; /* référence de la pastille, positionnée en absolu */
  width: 20px;
  height: 20px;
  margin-right: 0.75em;
  border: 1px solid var(--color-secondary);
  border-radius: 50%;
  background-color: var(--color-background);
  box-shadow: var(--shadow-soft);
  flex-shrink: 0;
}

/* Marque de sélection, UNE seule règle pour la case à cocher et les boutons
   radio : sans quoi ils ne peuvent pas être identiques, Divi dessinant une
   coche en glyphe d'un côté et une pastille de l'autre, de tailles
   différentes. On neutralise donc les deux marques d'origine (content: '')
   pour dessiner la même pastille ronde et centrée, en dimensions fixes.
   Conséquence : le contenu du ::before étant remplacé, on ne peut plus
   s'en remettre au mécanisme d'apparition de Divi — la pastille resterait
   visible décochée. L'opacité est donc pilotée ici. */
#page-container .km-form .et_pb_contact_field label > i::before {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 8px;
  height: 8px;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background-color: var(--color-primary);
  opacity: 0;
}

#page-container .km-form .et_pb_contact_field input:checked + label > i::before {
  opacity: 1;
}

/* CONSENTEMENT UNIQUEMENT — case CARRÉE avec une coche.
   Convention d'interface : la coche dans un carré signale un choix binaire
   que l'on accepte ou non, la pastille dans un rond un choix exclusif entre
   options. Les boutons Oui/Non gardent donc la présentation ronde définie
   au-dessus. Le ciblage est sans ambiguïté : Divi nomme le conteneur du
   consentement .et_pb_contact_field_checkbox et celui des Oui/Non
   .et_pb_contact_field_radio.
   Le sélecteur reprend .et_pb_contact_field en plus du conteneur pour
   passer devant la règle commune quel que soit l'ordre des fichiers. */
#page-container .km-form .et_pb_contact_field .et_pb_contact_field_checkbox label > i {
  border-radius: var(--border-radius-sm); /* 4px — mettre 0 pour un carré vif */

  /* Alignement vertical sur la première ligne du libellé. Le label est ancré
     en flex-start (le texte court sur plusieurs lignes), ce qui colle le haut
     de la case au haut de la LIGNE — alors que les lettres, elles, commencent
     plus bas dans cette ligne : la case paraissait donc remonter.
     On la descend de la demi-différence entre la hauteur de ligne (1.5em,
     posée sur le label) et la case (20px, définie plus haut). Formule plutôt
     que valeur en dur : elle suit tout changement de corps de texte.
     NB : la règle margin-top sur input[type='checkbox'] plus bas visait le
     même but, mais porte sur l'input que Divi masque — elle est sans effet. */
  margin-top: calc((1.5em - 20px) / 2);
}

/* La pastille ronde héritée cède la place à la MÊME coche SVG que celle des
   cases natives plus haut dans ce fichier, pour une marque identique partout.
   On repart de la boîte entière au lieu d'une pastille centrée : position,
   dimensions et forme sont donc toutes réinitialisées.
   L'opacité reste pilotée par la règle :checked commune — la coche
   n'apparaît qu'une fois la case cochée. */
#page-container .km-form .et_pb_contact_field .et_pb_contact_field_checkbox label > i::before {
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  transform: none;
  border-radius: 0;
  background-color: transparent;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2 6.2l2.6 2.6L10 3' fill='none' stroke='%23153F25' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center;
  background-size: 62%;
}

/* Le focus clavier arrive sur l'input masqué : on le reporte sur le contrôle
   dessiné, sans quoi la navigation au clavier n'afficherait plus rien. */
#page-container .km-form .et_pb_contact_field input:focus-visible + label > i {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}

/* Libellés des contrôles : lisibles, alignés avec le cercle */
#page-container .km-form .et_pb_contact_field_options_list label,
#page-container .km-form .et_pb_contact_field_checkbox label {
  font-size: var(--font-size-sm);
  line-height: 1.5;
  display: inline-flex;
  align-items: center;
  cursor: pointer;
}

/* Consentement : le texte court sur plusieurs lignes, la case se cale donc
   sur la PREMIÈRE ligne et non au milieu du paragraphe, où elle se perdait. */
#page-container .km-form .et_pb_contact_field_checkbox label {
  align-items: flex-start;
}

#page-container .km-form .et_pb_contact_field_checkbox input[type='checkbox'] {
  margin-top: 0.15em; /* recentre le cercle sur la hauteur d'x de la 1re ligne */
}

/* Bouton Envoyer = km-button--primary, mêmes proportions que les autres
   boutons. On refixe les propriétés de dimension car la grille du formulaire
   et les styles submit de Divi modifient sinon sa taille/largeur. */
#page-container .km-form .et_pb_contact_submit {
  display: inline-flex !important;
  align-items: center;
  justify-content: center;
  width: auto !important;          /* pas étiré par la grille */
  /* Plancher de largeur calé sur « Télécharger la brochure » du footer : son
     libellé est plus long, « Envoyer » serait sinon nettement plus étroit.
     À réajuster si le libellé de la brochure change. */
  min-width: var(--km-submit-width, 235px);
  min-height: 44px;
  padding: 0.65em 1.75em !important;
  font-size: 1rem !important;
  font-weight: var(--weight-medium) !important;
  line-height: 1 !important;
  background-color: var(--color-primary) !important;
  border: 1px solid var(--color-primary) !important;
  border-radius: var(--border-radius-pill) !important;
  color: var(--color-on-primary) !important;
}

#page-container .km-form .et_pb_contact_submit:hover {
  background-color: #0F2E1B !important; /* même assombrissement que km-button--primary */
}

/* --------------------------------------------------------------------------
   Accessibilité — libellés des champs du formulaire de contact.
   Divi masque le <label> natif de chaque champ (.et_pb_contact_form_label
   { display:none }, règle du thème parent) et compte sur le placeholder pour
   informer visuellement l'utilisateur. Problème : display:none retire aussi
   l'élément de l'arbre d'accessibilité — un lecteur d'écran ou un outil
   d'audit (agent IA, Lighthouse) ne trouve alors aucun nom accessible pour
   le champ, alors que le HTML associe pourtant bien le <label> via for/id.
   On le rend « visually-hidden » à la place : invisible à l'écran, mais
   toujours présent dans l'arbre d'accessibilité. S'applique à TOUS les
   formulaires de contact Divi du site, pas seulement .km-form.
   !important : bat le display:none du thème parent, qui charge après nous
   sur ce sélecteur à spécificité égale (même logique que pour les
   paragraphes de km-box-beige et km-legal plus haut dans ce fichier). */
.et_pb_contact_form_label {
  display: block !important;
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* --------------------------------------------------------------------------
   Paragraphes des modules Divi : même taille que H6 (20px maquette),
   graisse Light. L'id #page-container est nécessaire : le CSS Customizer
   de Divi (chargé après le thème enfant) impose sinon 14px aux .et_pb_text.
   -------------------------------------------------------------------------- */
#page-container .et_pb_text,
#page-container .et_pb_text p {
  font-family: var(--font-body);
  font-size: var(--font-size-base);
  font-weight: var(--weight-light);
  line-height: var(--leading-body);
  letter-spacing: var(--tracking-base);
}

/* Exception : légendes et crédits conservent leurs 16px (components.css) face
   à la règle générique ci-dessus. Sans ça elle l'emporte : spécificité
   identique (1 id + 1 classe + 1 élément), mais déclarée plus tard dans la
   cascade. La double classe .et_pb_text.km-* fait la différence. */
#page-container .et_pb_text.km-caption,
#page-container .et_pb_text.km-caption p,
#page-container .et_pb_text.km-credits,
#page-container .et_pb_text.km-credits p {
  font-size: 1rem; /* 16px */
}

/* Exception : le chapeau conserve son style Medium 23/30 (components.css)
   face à la règle générique ci-dessus. */
#page-container .et_pb_text.km-chapeau,
#page-container .et_pb_text.km-chapeau p {
  font-size: var(--font-size-lg);
  font-weight: var(--weight-medium);
  line-height: var(--leading-h3);
}

/* --------------------------------------------------------------------------
   Titres dans les modules Texte : Divi ajoute ses propres paddings aux
   headings — on garantit le collage chiffre (H5) / libellé (H6).
   -------------------------------------------------------------------------- */
.et_pb_text h5 {
  margin-bottom: 0;
  padding-bottom: 0;
}

.et_pb_text h6 {
  margin-top: 0;
  padding-top: 0;
}

/* --------------------------------------------------------------------------
   Galerie « masonry » — supprime l'alignement par rangée de la mise en page
   Grille de Divi 5, en conservant la grille elle-même.
   Une grille CSS aligne TOUJOURS ses rangées : un visuel plus haut que ses
   voisins creuse un blanc sous les plus courts, et aucun réglage (aligner les
   éléments, densité, gouttières) n'y change quoi que ce soit. La parade :
   remplacer les quelques rangées « auto » par une trame de rangées très
   fines, dans laquelle chaque visuel occupe le nombre de rangées de sa propre
   hauteur — il n'a alors plus de voisin de rangée à qui s'aligner. Mesure des
   hauteurs et placement sont faits par assets/js/km-masonry.js.
   Nombre de colonnes et étendue des visuels restent pilotés par le Builder ;
   la colonne de départ est calculée par le script. L'écart, lui, est imposé
   ici sur les deux axes (--km-masonry-gap) et ne suit plus la gouttière du
   Builder, pour rester identique partout.
   À poser sur la LIGNE.
   -------------------------------------------------------------------------- */
body #page-container .et_pb_row.km-masonry {
  --km-masonry-gap: 16px;

  /* Trame AU PIXEL. Le script arrondit la hauteur de chaque visuel au
     supérieur, sur un multiple de cette unité (km-masonry.js : Math.ceil).
     À 4px, le reste de la division ajoutait de 0 à 3,99px à l'espace réservé
     et les écarts verticaux variaient de 16 à 20px. À 1px, l'arrondi ne peut
     plus dépasser le pixel : l'écart est bien celui demandé. */
  --km-masonry-unit: 1px;

  /* Écart vertical, porté par la marge des colonnes (cf. plus bas) */
  --km-masonry-row-gap: var(--km-masonry-gap);

  /* Écart horizontal : variable lue par .et_grid_row de Divi pour son
     column-gap. On la surcharge ici, sinon elle vaut la gouttière réglée dans
     le Builder, qui peut différer et changer selon le point de rupture. */
  --horizontal-gap: var(--km-masonry-gap);
}

/* La trame fine n'est posée QUE par le script, via la classe is-masonry qu'il
   ajoute après avoir mesuré les hauteurs. Sans elle, une colonne déborderait
   de sa rangée de 4px et la ligne s'effondrerait : le script absent (fichier
   manquant, erreur JS, JS désactivé) laisse donc simplement la grille Divi
   d'origine, avec ses rangées alignées — dégradé, jamais cassé. */
body #page-container .et_pb_row.km-masonry.is-masonry {
  grid-template-rows: none; /* Divi impose repeat(var(--row-count), auto) */
  grid-auto-rows: var(--km-masonry-unit);
  row-gap: 0; /* reporté en marge des colonnes, cf. ci-dessous */
  align-items: start;
}

/* L'écart vertical est porté par les colonnes, pas par la grille : un row-gap
   s'ajouterait à CHACUNE des rangées de 4px franchies. */
.km-masonry.is-masonry > .et_pb_column {
  margin: 0 0 var(--km-masonry-row-gap);
}

/* Colonne vide générée par Divi en fin de grille : n'occupe aucune cellule */
.km-masonry > .et_pb_column_empty {
  display: none;
}

/* Images bord à bord : ni marge de module, ni espace sous l'image inline */
.km-masonry .et_pb_image {
  margin: 0;
}

/* Deux visuels empilés dans la MÊME colonne : la marge ci-dessus les collerait
   l'un à l'autre. Seul l'espace ENTRE eux est rétabli — le premier reste calé
   en haut de la colonne, le dernier en bas. */
.km-masonry .et_pb_image + .et_pb_image {
  margin-top: var(--km-masonry-gap);
}

.km-masonry .et_pb_image img {
  display: block;
  width: 100%;
  height: auto;
}

/* --------------------------------------------------------------------------
   Footer (Theme Builder) — poser km-footer sur la section du footer.
   -------------------------------------------------------------------------- */
.km-footer {
  background-color: var(--color-primary);
  color: var(--color-on-primary);
  /* Gouttières internes au minimum (variables de disposition Divi 5) */
  --row-gutter-horizontal: 0px;
  --row-gutter-vertical: 0px;
  --module-gutter: 0px;
  --section-gutter: 0px;
}

/* Barre légale à 40px du bas de page. Double classe (.et_pb_section.km-footer)
   pour battre la classe propre que Divi 5 génère sur la section du footer
   (.et_pb_section_N_tb_footer) et son padding de « hauteur de section ». */
.et_pb_section.km-footer {
  padding-bottom: 40px !important;
}

.km-footer h4,
.km-footer .km-footer__title {
  color: var(--color-secondary);
}

/* Pas d'espace sous les h6 du footer (marge + padding Divi) */
.km-footer h6 {
  margin-bottom: 0;
  padding-bottom: 0;
}

.km-footer p,
.km-footer a {
  color: var(--color-on-primary);
}

.km-footer a:hover {
  color: var(--color-secondary);
  opacity: 1;
}

/* Barre inférieure : mentions légales en petite taille (14px).
   #page-container + p/a : bat la taille des paragraphes Divi (20px), sinon
   la règle était ignorée. */
#page-container .km-footer__legal,
#page-container .km-footer__legal p,
#page-container .km-footer__legal a {
  font-size: var(--font-size-xs);
  font-weight: var(--weight-light);
}

/* --------------------------------------------------------------------------
   Pages légales (politique de confidentialité, mentions légales) — km-legal.
   Texte long et dense : titres de section détachés par un filet, listes
   collées à ce qui les introduit, espacement des paragraphes réduit de
   moitié. À poser sur le module Texte qui contient le corps de la page — ou
   sur la SECTION si le H1 est dans un module séparé.

   Sur tout ce qui touche aux espacements verticaux, le préfixe `body` et
   l'`!important` sont nécessaires : le CSS dynamique de Divi cible ces
   éléments à spécificité égale et charge APRÈS le thème enfant, sa valeur
   l'emporterait donc. Même traitement que les paragraphes de km-box-beige
   plus haut dans ce fichier.

   Réglables : --km-legal-space (air autour du filet),
   --km-legal-p-gap (espacement des paragraphes),
   --km-legal-bullet-gap (écart puce → texte),
   --km-legal-overhang (débord du filet, cf. explication plus bas).
   -------------------------------------------------------------------------- */
body #page-container .km-legal {
  --km-legal-space: 72px;
  --km-legal-p-gap: 0.5em;
  --km-legal-bullet-gap: 1.25em;
  --km-legal-overhang: 33.333%;
}

/* Titre de page : le texte enchaîne directement dessous. */
body #page-container .km-legal h1 {
  margin-bottom: 0 !important;
  padding-bottom: 0 !important;
}

/* Titre de section : filet centré dans son espace, autant d'air au-dessus
   qu'en dessous. Une seule variable pour les deux, ils ne peuvent donc plus
   diverger — margin-top au-dessus du filet, padding-top entre filet et titre. */
body #page-container .km-legal h3 {
  margin-top: var(--km-legal-space);
  padding-top: var(--km-legal-space);
  border-top: 1px solid var(--color-secondary);
}

/* Le premier titre n'a ni filet ni air : rien ne le précède. */
body #page-container .km-legal h3:first-child {
  margin-top: 0;
  padding-top: 0;
  border-top: none;
}

/* Filet en pleine largeur du bloc malgré km-col-width.
   Celle-ci réserve un padding droit de 25% de la largeur du MODULE, le
   contenu n'en fait donc plus que 75% et le filet s'arrêterait avant le bord.
   Une marge droite négative élargit la boîte du titre, et avec elle son
   filet. Le débord se calcule sur la largeur du CONTENU et non du module :
   25/75 = 33.333%. Formule générale si --km-pr change : p / (1 - p).
   Réservé au cas où km-col-width est posée, sinon le titre déborderait. */
body #page-container .km-legal.km-col-width h3,
body #page-container .km-col-width .km-legal h3 {
  margin-right: calc(-1 * var(--km-legal-overhang));
}

/* Paragraphes : moitié de l'espacement de Divi, qui vaut 1em par défaut. */
body #page-container .km-legal p {
  padding-bottom: var(--km-legal-p-gap) !important;
}

/* L'élément qui introduit une liste lui reste collé, quel qu'il soit —
   paragraphe, intertitre ou conteneur de bloc Gutenberg. Le second sélecteur
   traite le cas d'un paragraphe vide intercalé, résidu fréquent d'un collage. */
body #page-container .km-legal :has(+ :is(ul, ol)),
body #page-container .km-legal :has(+ p:empty + :is(ul, ol)) {
  margin-bottom: 0 !important;
  padding-bottom: 0 !important;
}

/* Paragraphe vide : il occupe une hauteur de ligne sans rien afficher. */
body #page-container .km-legal p:empty {
  display: none;
}

/* Listes : aucun espace vertical. */
body #page-container .km-legal ul,
body #page-container .km-legal ol {
  margin-top: 0 !important;
  margin-bottom: 0 !important;
  padding-top: 0 !important;
  padding-bottom: 0 !important;
}

/* Listes à puces : puce sur la marge gauche du texte, sans débord, et retrait
   pendu — la deuxième ligne d'une puce reste alignée sur la première.
   Le marqueur natif ne permet aucun des deux : « outside » le fait sortir du
   bloc une fois le retrait de wp-block-list supprimé, « inside » le remet
   dans le flux et ramène la deuxième ligne sous la puce. On le remplace donc
   par un ::before sorti du flux : la puce se pose à gauche, le texte est
   décalé du même écart sur TOUTES ses lignes. */
body #page-container .km-legal ul {
  padding-left: 0 !important;
  list-style: none;
}

body #page-container .km-legal ul > li {
  position: relative;
  padding-left: var(--km-legal-bullet-gap);
}

body #page-container .km-legal ul > li::before {
  content: '•';
  position: absolute;
  left: 0;
}

body #page-container .km-legal li {
  margin-bottom: 0 !important;
  padding-bottom: 0 !important;
}