/**
 * RH-16 — Formulaire de contact.
 *
 * CSS pur, aucune dépendance, aucune chaîne de build. Chargé uniquement sur les pages qui
 * rendent réellement un formulaire de contact (cf. functions.php).
 *
 * CONTEXTE DE COULEUR — À LIRE AVANT DE TOUCHER AUX TEINTES
 * --------------------------------------------------------
 * Le formulaire est posé sur une colonne dont le fond est `palette-color-2`, soit le SAUMON
 * #FF9EA2. Ce fond vient du thème de démo Blocksy, où `palette-color-2` était un vert foncé
 * (#053631, encore visible en valeur de repli dans le CSS inline de Greenshift) — c'est
 * pourquoi le contenu de démo y met du texte blanc.
 *
 * Sur saumon, le blanc tombe à ~1,9:1 : illisible, et incompatible avec le critère WCAG AA de
 * la story. Tout le texte du formulaire est donc en `palette-color-3` (#283836), qui donne
 * ~6,6:1 sur ce fond. Ce n'est PAS une remise en cause de la charte : on ne fait que choisir
 * laquelle de ses couleurs va où.
 *
 * ⚖️ DÉCISION CHARTE (Etienne, 29/07/2026) — LE ROUGE EST LA COULEUR D'ACTION DU SITE
 * ------------------------------------------------------------------------------------
 * Relevé sur la home : tous les CTA du contenu (« Découvrir Heights », « Découvrir Rise »,
 * « En savoir plus ») sont des boutons **#F54E16 à texte blanc, 16 px poids 600, angles droits,
 * padding 18/32, sans capitales**. Et le thème lui-même pose
 * `--theme-button-background-initial-color: var(--theme-palette-color-1)`.
 *
 * Le formulaire s'aligne : **bordure des champs et bouton d'envoi en rouge**. Une première
 * version les mettait en #283836 pour maximiser le contraste ; c'était plus accessible mais
 * étranger au site. La cohérence de marque tranche.
 *
 * Conséquence assumée, écrite une fois ici : **blanc sur #F54E16 = 3,51:1**, sous les 4,5:1 de
 * WCAG AA pour du texte normal (le seuil de 3:1 du grand texte demanderait 18,66 px en gras).
 * C'est la charte du client, déjà appliquée sur TOUS les CTA du site — la corriger ici seulement
 * créerait une incohérence sans régler le site. Le TEXTE du formulaire (libellés, aide, erreurs)
 * reste lui en #283836 à 6,24:1 : c'est là que la lisibilité compte vraiment.
 * En revanche la bordure rouge des champs **tient** le critère : 3,51:1 contre le blanc du
 * champ, au-dessus des 3:1 exigés pour un composant non textuel (SC 1.4.11).
 *
 * Ratios retenus (calculés sur les valeurs réelles de la palette) :
 *   #283836 sur #FF9EA2 (texte sur le panneau) ......... 6,24:1  ✅ AA
 *   #283836 sur #ffffff (texte dans les champs) ........ 12,29:1 ✅ AAA
 *   #ffffff sur #283836 (bouton d'envoi, radio cochée) . 12,29:1 ✅ AAA
 *   #011412 sur #FF9EA2 (anneau de focus) .............. 9,61:1  ✅
 *   #F54E16 sur #ffffff (bordure des champs) ........... 3,51:1  ✅ SC 1.4.11 (≥ 3:1)
 *   #ffffff sur #F54E16 (bouton d'envoi, radio cochée) . 3,51:1  ⚠️ charte client, cf. ci-dessus
 *
 * Valeurs RECALCULÉES en revue : les précédentes (6,6 / 13 / 12,3) étaient approximatives.
 *
 * Toutes les couleurs passent par les variables de palette du thème, avec un repli en dur au
 * cas où le formulaire serait rendu hors du contexte Blocksy.
 */

.rh-form {
  /* Alias locaux : une seule ligne à changer si la charte bouge. */
  --rh-form-encre: var(--theme-palette-color-3, #283836);
  --rh-form-encre-forte: var(--theme-palette-color-4, #011412);
  --rh-form-champ-fond: var(--theme-palette-color-8, #ffffff);
  --rh-form-accent: var(--theme-palette-color-1, #F54E16);
  /*
   * BORDURE DES CHAMPS EN ROUGE — couleur d'action du site (cf. la décision charte en tête).
   *
   * Trois passes ont été nécessaires :
   *   - `rgba(40,56,54,0.28)` d'origine → 1,57:1 sur saumon, 1,71:1 sur blanc. Échec SC 1.4.11.
   *   - `rgba(…,0.65)` puis l'encre pleine → conformes, mais étrangers à la charte.
   *   - le **rouge de charte** → 3,51:1 contre le blanc du champ, au-dessus des 3:1 requis. ✅
   *
   * Sur la page EN (fond clair), c'est ce liseré qui rend les champs identifiables ; sur la page
   * FR, il s'ajoute au contraste du remplissage blanc contre le panneau saumon.
   */
  --rh-form-bordure: var(--rh-form-accent);
  --rh-form-rayon: 2px;
  --rh-form-gap: 18px;

  /* Tempo : aligné sur les micro-interactions de RH-5. Neutralisé plus bas en
     prefers-reduced-motion. */
  --rh-form-duree: 180ms;
  --rh-form-easing: cubic-bezier(0.4, 0, 0.2, 1);

  color: var(--rh-form-encre);

  /*
   * Largeur de lecture bornée, en toutes circonstances.
   *
   * Dans la colonne saumon de la page Contact FR, cette borne ne change rien : la colonne fait
   * déjà ~450px. Sur la page Contact EN, qui est en pleine largeur de contenu, elle évite des
   * champs d'une seule ligne étirés sur ~1150px — pénibles à lire comme à viser.
   */
  max-width: 560px;
}

/* ---------------------------------------------------------------------------
 * Libellés — réels, associés, mais discrets
 *
 * Le modèle de référence (levillage-bettembourg.lu) ne porte ses intitulés que par
 * `placeholder`. La story impose de VRAIS `<label>` pour l'AA, tout en gardant le rendu
 * épuré : d'où des libellés petits, en capitales espacées, plutôt que masqués.
 * ------------------------------------------------------------------------ */

.rh-form .ff-el-input--label label {
  color: var(--rh-form-encre);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  margin-bottom: 6px;
  display: inline-block;
  line-height: 1.3;
}

/* L'astérisque des champs obligatoires : visible, et sur la même encre (sur saumon, le rouge
   d'accent tomberait à 1,8:1). La mention en bas de formulaire en donne le sens. */
/*
 * Pas d'`opacity` : à 0.75 l'astérisque tombait à 3,81:1 sur saumon (échec AA pour un glyphe de
 * ~11,5 px). En encre pleine il est à 6,24:1.
 */
.rh-form .ff-el-is-required.asterisk-right label::after,
.rh-form .ff-el-is-required.asterisk-left label::before {
  color: var(--rh-form-encre);
}

/*
 * ⚠️ ASTÉRISQUE DU GROUPE RADIO — à ne pas retirer.
 *
 * Le plugin rend l'astérisque en CSS, via `.ff-el-is-required.asterisk-right label::after`. Or
 * notre correctif d'accessibilité remplace le `<label>` orphelin du groupe par un `<span>` :
 * l'astérisque disparaissait donc pour « Vous souhaitez », **le seul champ obligatoire à ne pas
 * en avoir**. Un visiteur en déduisait que le champ était optionnel, et se faisait refuser la
 * soumission. Trouvé en revue.
 */
.rh-form .ff-el-is-required.asterisk-right .rh-form__legende::after {
  content: " *";
  color: var(--rh-form-encre);
}

/* ---------------------------------------------------------------------------
 * Champs de saisie
 * ------------------------------------------------------------------------ */

.rh-form .ff-el-form-control {
  /*
   * Blocksy peint la bordure des champs via `var(--theme-border-color)` (#FFCBB8 ici) avec une
   * règle qui bat la nôtre : surcharger `border-color` ne suffisait pas — la bordure restait à
   * 1,45:1. On redéfinit donc la VARIABLE sur l'élément, comme pour le bouton d'envoi.
   * `--fluentform-border-color` couvre le même besoin côté CSS du plugin.
   */
  --theme-border-color: var(--rh-form-bordure);
  --fluentform-border-color: var(--rh-form-bordure);

  background: var(--rh-form-champ-fond);
  color: var(--rh-form-encre);
  border: 1px solid var(--rh-form-bordure);
  border-radius: var(--rh-form-rayon);
  padding: 12px 14px;
  font-size: 1rem;
  line-height: 1.4;
  width: 100%;
  /*
   * DÉLIMITATION PAR `box-shadow` ET NON PAR `border` — WCAG SC 1.4.11.
   *
   * Le `border` ci-dessus ne suffit pas : Blocksy et Fluent Forms peignent tous deux la bordure
   * des champs, et la leur gagne (constaté à l'écran : bordure rendue en #FFCBB8, soit 1,45:1
   * contre le blanc du champ — les champs apparaissaient sans contour). Redéfinir
   * `--theme-border-color` sur l'élément n'a pas suffi non plus.
   *
   * Un `box-shadow` interne n'entre pas en concurrence avec les règles `border` : il dessine un
   * liseré **rouge de charte**, à 3,51:1 contre le blanc du champ — au-dessus des 3:1 exigés
   * pour un composant non textuel. Sur la page EN (fond clair), c'est ce liseré qui rend les
   * champs identifiables.
   */
  box-shadow: inset 0 0 0 1px var(--rh-form-accent);
  transition: box-shadow var(--rh-form-duree) var(--rh-form-easing);
}

.rh-form textarea.ff-el-form-control {
  min-height: 110px;
  resize: vertical;
}

/* Le survol épaissit le liseré : la couleur est déjà l'encre pleine. */
.rh-form .ff-el-form-control:hover {
  box-shadow: inset 0 0 0 2px var(--rh-form-accent);
}

/*
 * Focus des champs de saisie.
 *
 * L'indicateur passe par un `box-shadow` plutôt que par `outline` : Blocksy et Fluent Forms
 * posent tous deux des règles `outline` sur les contrôles de formulaire, et un `box-shadow`
 * n'entre pas en concurrence avec elles. Ce n'est pas un contournement d'un bug constaté, c'est
 * un choix de robustesse.
 *
 * `:focus` ET `:focus-visible` : le premier garantit le repère y compris quand le focus est
 * donné par programme — Fluent Forms déplace le focus sur le premier champ invalide après une
 * validation en échec.
 *
 * ⚠️ NON VÉRIFIÉ AUTOMATIQUEMENT. Dans un navigateur piloté sans focus fenêtre, `:focus` ne
 * matche pas : toute mesure de `getComputedStyle` sur un état de focus y est un artefact.
 * Ces règles demandent une passe clavier humaine (Tab dans le formulaire, œil sur l'anneau).
 */
.rh-form .ff-el-form-control:focus,
.rh-form .ff-el-form-control:focus-visible {
  border-color: var(--rh-form-accent);
  /* Le liseré rouge est conservé, l'anneau de focus foncé s'y ajoute — deux signaux distincts. */
  box-shadow:
    inset 0 0 0 2px var(--rh-form-accent),
    0 0 0 2px var(--rh-form-encre-forte);
}

/* ---------------------------------------------------------------------------
 * « Vous souhaitez » — 3 radios rendus en boutons
 *
 * Patron repris du modèle : de VRAIS `input[type=radio]` avec de VRAIS `<label for>`. L'input
 * n'est pas masqué avec `display:none` (il perdrait le focus clavier) : il est rendu
 * transparent et étendu sur tout le bouton, de sorte que le focus reste natif.
 * ------------------------------------------------------------------------ */

/* Nom de groupe accessible, injecté par le thème (Fluent Forms 6.2.5 free ne le rend pas). */
.rh-form .rh-form__legende {
  display: inline-block;
  color: var(--rh-form-encre);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  margin-bottom: 8px;
}

/*
 * CONTRÔLE SEGMENTÉ — un seul bloc à trois segments jointifs.
 *
 * Demande d'Etienne (29/07/2026) : remplacer les trois boutons détachés par un élément
 * « segmented ». Les trois options forment donc un contrôle unique, aux bordures mutualisées,
 * plutôt que trois boutons séparés par un espace.
 *
 * Le markup n'est PAS touché : ce sont toujours de vrais `input[type=radio]` dans de vrais
 * `<label for>` — l'accessibilité durement acquise (nom de groupe, focus, astérisque) est
 * intacte. Seule la mise en forme change.
 *
 * ⚠️ Le conteneur des options est `.ff-el-input--content`, PAS `.ff-el-form-check-group` :
 * Fluent Forms n'émet ce dernier qu'avec certaines dispositions, et ici les `.ff-el-form-check`
 * sont des enfants directs. Cibler le mauvais nœud laissait les options en blocs pleine
 * largeur, empilés.
 *
 * Pas de bordure sur le conteneur, mais une bordure par segment avec chevauchement de 1px
 * (`margin-left: -1px`) : c'est ce qui permet au message d'erreur, que le plugin injecte DANS
 * ce même conteneur, de se placer proprement sous le contrôle au lieu de devenir un 4ᵉ segment.
 */
.rh-form .rh-form__souhait .ff-el-input--content {
  display: flex;
  flex-wrap: wrap;
  /* `stretch` : tous les segments ont la même hauteur, même si un libellé passe sur 2 lignes. */
  align-items: stretch;
  gap: 0;
}

/*
 * Le message d'erreur passe TOUTE la largeur.
 *
 * Fluent Forms injecte l'erreur avec `closest('.ff-el-input--content').append(...)` — soit
 * exactement le conteneur qu'on vient de passer en flex. Sans cette règle, « Ce champ est
 * requis » devient le 4ᵉ bouton de la rangée, coincé à côté de « bureaux ». C'est le seul champ
 * obligatoire dont on modifie le conteneur d'erreur.
 */
.rh-form .rh-form__souhait .ff-el-input--content > .error {
  flex: 1 1 100%;
}

/*
 * Segments de largeur égale. `flex: 1 1 0` + `min-width: 0` : les trois font la même largeur
 * quelle que soit la longueur du libellé — « bureaux » n'écrase pas « acheter pour habiter ».
 */
.rh-form .rh-form__souhait .ff-el-form-check {
  flex: 1 1 0;
  min-width: 0;
  padding: 0;
  display: flex;
  /* Chevauchement d'1px : les bordures voisines se superposent au lieu de doubler. */
  margin: 0 0 0 -1px;
  /* Le segment survolé, coché ou focalisé passe au-dessus, sinon sa bordure serait
     recouverte par celle du segment suivant. */
  position: relative;
  z-index: 0;
}

.rh-form .rh-form__souhait .ff-el-form-check:first-child {
  margin-left: 0;
}

.rh-form .rh-form__souhait .ff-el-form-check:hover,
.rh-form .rh-form__souhait .ff-el-form-check:focus-within,
.rh-form .rh-form__souhait .ff-el-form-check:has(.ff-el-form-check-input:checked) {
  z-index: 1;
}

/*
 * Le message d'erreur est injecté par le plugin DANS ce conteneur flex. `flex-basis: 100%` +
 * `order` le renvoient sur sa propre ligne, sous le contrôle, et on annule le chevauchement.
 */
.rh-form .rh-form__souhait .ff-el-input--content > .error {
  flex: 1 1 100%;
  order: 9;
  margin-left: 0;
  margin-top: 8px;
}

.rh-form .rh-form__souhait .ff-el-form-check-label {
  position: relative;
  display: flex;
  align-items: center;
  /* Explicite : sans cela, un `text-align` hérité de la colonne pourrait décaler le libellé. */
  justify-content: center;
  text-align: center;
  /* Cible tactile : les 44px sont obtenus par un PADDING SYMÉTRIQUE et non par min-height.
     Sur un élément flex, min-height étire la boîte en laissant le texte collé en haut —
     c'est exactement ce qui avait décalé le « EN » du header en RH-20. */
  /* Le label remplit son segment : c'est lui qui porte la bordure et la cible de clic. */
  flex: 1;
  padding: 13px 12px;
  /* Bordure rouge comme les champs ; le LIBELLÉ reste en encre foncée (6,24:1) — du texte rouge
     sur saumon tomberait à 1,78:1. */
  border: 1px solid var(--rh-form-accent);
  /* Angles droits, comme tous les CTA du site. */
  border-radius: 0;
  /*
   * Aucune déclaration `background` ici, volontairement : un <label> est transparent par
   * défaut, et déclarer `background: transparent` créait un conflit avec la règle de l'état
   * coché plus bas — l'état sélectionné restait invisible. Moins de déclarations, moins de
   * cascade à arbitrer.
   */
  color: var(--rh-form-encre);
  font-size: 0.95rem;
  line-height: 1.2;
  cursor: pointer;
  transition:
    background-color var(--rh-form-duree) var(--rh-form-easing),
    color var(--rh-form-duree) var(--rh-form-easing);
}

/*
 * L'input reste dans le DOM et focusable — jamais `display: none`, qui le retirerait de
 * l'ordre de tabulation — mais réduit à 1px et transparent.
 *
 * ⚠️ On n'essaie PAS de le sortir du flux avec `position: absolute` : le CSS de Fluent Forms
 * impose `position: relative` sur cet élément et gagne la cascade. L'input restait donc dans
 * le flux, en pleine largeur, et poussait le texte du bouton à droite (constaté à l'écran).
 * Le réduire à 1px atteint le même but sans dépendre de qui gagne sur `position`.
 *
 * Le clic fonctionne par le `for` du label, et l'anneau de focus est porté par le label
 * (cf. la règle `:has(:focus-visible)` plus bas).
 */
.rh-form .rh-form__souhait .ff-el-form-check-input {
  width: 1px;
  height: 1px;
  min-width: 0;
  flex: 0 0 1px;
  margin: 0;
  padding: 0;
  opacity: 0;
  cursor: pointer;
}

/* Survol : léger voile rouge, pour annoncer la couleur de l'état sélectionné. */
.rh-form .rh-form__souhait .ff-el-form-check-label:hover {
  background: color-mix(in srgb, var(--rh-form-accent) 14%, transparent);
}

/*
 * État coché — porté par `:checked` via `:has()`, donc par le CSS et non par une classe JS :
 * l'état reste juste même si le JS de Fluent Forms ne s'exécute pas.
 * On ne cible PAS `input:checked + span` : le span vit à l'intérieur du label paddé, la
 * couleur ne couvrirait que le texte et donnerait une pastille au milieu du bouton.
 */
/* Coché : rouge plein + texte blanc, exactement le rendu des CTA du site. */
.rh-form .rh-form__souhait .ff-el-form-check-label:has(.ff-el-form-check-input:checked) {
  background: var(--rh-form-accent);
  border-color: var(--rh-form-accent);
  color: var(--rh-form-champ-fond);
}

/*
 * Repli pour les navigateurs sans `:has()` : Fluent Forms ajoute la classe
 * `ff_item_selected` sur le conteneur au clic. C'est du JS, donc secondaire — mais cumulé
 * au `:has()` ci-dessus, l'état coché est visible dans tous les cas.
 */
.rh-form .rh-form__souhait .ff_item_selected .ff-el-form-check-label {
  background: var(--rh-form-accent);
  border-color: var(--rh-form-accent);
  color: var(--rh-form-champ-fond);
}

/*
 * Focus clavier sur un bouton radio.
 *
 * L'anneau porte sur le LABEL : l'input ne fait qu'1px et un `outline` dessus serait
 * invisible. Sans cette règle, naviguer au clavier dans le groupe ne montre absolument rien —
 * c'est le point le plus sensible du montage, et il a effectivement échoué au premier essai.
 *
 * `:focus-within` et non `:has(:focus)` : plus lisible, fait exactement pour ce cas, et
 * supporté partout. (Un test `:has(:focus)` en navigateur piloté était revenu négatif, mais
 * c'était un artefact de mesure — sans focus fenêtre, `:focus` ne matche pas. Le choix de
 * `:focus-within` reste le bon pour sa clarté.)
 *
 * Contrepartie assumée : l'anneau apparaît aussi au clic à la souris, faute d'équivalent
 * `:focus-visible-within`. Sur un bouton radio c'est acceptable — l'utilisateur vient
 * précisément de désigner cette option.
 */
.rh-form .rh-form__souhait .ff-el-form-check-label:focus-within,
.rh-form .rh-form__optin .ff-el-form-check-label:focus-within {
  outline: 2px solid var(--rh-form-encre-forte);
  outline-offset: 2px;
}

/* ---------------------------------------------------------------------------
 * Bloc « être rappelé » : date + heure côte à côte
 * ------------------------------------------------------------------------ */

.rh-form .rh-form__hint,
.rh-form .rh-form__mention {
  color: var(--rh-form-encre);
  line-height: 1.45;
}

.rh-form .rh-form__hint {
  font-size: 0.95rem;
  margin-bottom: 2px;
}

.rh-form .rh-form__mention {
  font-size: 0.8rem;
  opacity: 0.85;
}

/* ---------------------------------------------------------------------------
 * Optin marketing
 * ------------------------------------------------------------------------ */

.rh-form .rh-form__optin .ff-el-form-check-label {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  /* Cible tactile confortable sans casser l'alignement du texte sur plusieurs lignes. */
  padding: 6px 0;
  color: var(--rh-form-encre);
  font-size: 0.88rem;
  line-height: 1.45;
  cursor: pointer;
}

.rh-form .rh-form__optin .ff-el-form-check-input {
  /* 20px : assez grand pour être visé au doigt, et le padding du label complète la cible. */
  width: 20px;
  height: 20px;
  min-width: 20px;
  margin: 0;
  accent-color: var(--rh-form-encre);
  cursor: pointer;
}

/* ---------------------------------------------------------------------------
 * Bouton d'envoi
 *
 * Fond `palette-color-3` (#283836) et texte blanc : 12,3:1. Le saumon de charte est déjà le
 * fond du panneau — un bouton saumon y serait invisible. Le rouge #F54E16 n'y donnerait que
 * 1,8:1 contre le fond, insuffisant même pour un composant non textuel (3:1 requis).
 * ------------------------------------------------------------------------ */

.rh-form .ff-btn-submit {
  /*
   * Blocksy pilote TOUS les boutons par variables : sa règle
   * `.button, [type="submit"], … { background-color: var(--theme-button-background-initial-color) }`
   * s'applique à ce bouton. Redéfinir la variable ICI est plus sûr que de surcharger
   * `background` — la valeur est juste quelle que soit la règle qui gagne la cascade, et on
   * évite un `!important`. Constaté : sans ces quatre lignes, le bouton restait en #F54E16
   * (blanc sur rouge = 3,5:1, échec AA) malgré une règle plus spécifique.
   */
  --theme-button-background-initial-color: var(--rh-form-accent);
  --theme-button-background-hover-color: var(--rh-form-encre);
  --theme-button-text-initial-color: var(--rh-form-champ-fond);
  --theme-button-text-hover-color: var(--rh-form-champ-fond);

  /*
   * Valeurs relevées sur les CTA Greenshift de la home (« Découvrir Heights », « En savoir
   * plus ») : #F54E16, blanc, 16 px, poids 600, angles droits, padding 18/32, PAS de capitales.
   * Le formulaire ne doit pas avoir son bouton à lui.
   */
  background: var(--rh-form-accent);
  color: var(--rh-form-champ-fond);
  border: 1px solid var(--rh-form-accent);
  border-radius: 0;
  padding: 18px 32px;
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: normal;
  text-transform: none;
  cursor: pointer;
  transition:
    background-color var(--rh-form-duree) var(--rh-form-easing),
    transform var(--rh-form-duree) var(--rh-form-easing);
}

/*
 * Typographie et gabarit du bouton : sélecteur plus spécifique.
 *
 * Fluent Forms applique `ff-btn ff-btn-md` avec ses propres `font-size`/`font-weight`/`padding`,
 * qui battaient `.rh-form .ff-btn-submit` (constaté : 15 px / 500 / 5px 30px au lieu de
 * 16 px / 600 / 18px 32px). On cumule les deux classes du plugin pour reprendre la main, sans
 * `!important`.
 */
.rh-form button.ff-btn.ff-btn-submit,
.rh-form .ff-btn.ff-btn-md.ff-btn-submit {
  font-size: 1rem;
  font-weight: 600;
  line-height: 1.2;
  padding: 18px 32px;
  border-radius: 0;
  letter-spacing: normal;
  text-transform: none;
}

/* Survol : bascule vers le foncé de charte — le contraste du texte y monte à 12,29:1. */
.rh-form .ff-btn-submit:hover {
  background: var(--rh-form-encre);
  border-color: var(--rh-form-encre);
}

/*
 * Les deux mécanismes : l'`outline` sert les modes contrastes forcés du système (qui ignorent
 * les `box-shadow`), le `box-shadow` donne un anneau à double liseré lisible sur le fond
 * saumon comme sur un fond clair. À vérifier au clavier par un humain (cf. plus haut).
 */
.rh-form .ff-btn-submit:focus,
.rh-form .ff-btn-submit:focus-visible {
  outline: 2px solid var(--rh-form-encre-forte);
  outline-offset: 3px;
  box-shadow: 0 0 0 2px var(--rh-form-champ-fond), 0 0 0 4px var(--rh-form-encre-forte);
}

.rh-form .ff-btn-submit:active {
  transform: translateY(1px);
}

/* ---------------------------------------------------------------------------
 * Erreurs de validation
 *
 * Jamais signalées par la seule couleur (critère de la story) : le texte du message porte le
 * sens, et le champ reçoit une bordure épaissie en plus de la teinte.
 * ------------------------------------------------------------------------ */

.rh-form .ff-el-is-error .ff-el-form-control,
.rh-form .ff-el-form-control[aria-invalid="true"] {
  border-color: var(--rh-form-accent);
  border-width: 2px;
}

/*
 * Le message d'erreur est sur le fond SAUMON, où le rouge d'accent ne donnerait que 1,8:1.
 * Il est donc rendu sur l'encre foncée, avec un liseré rouge qui porte le signal visuel —
 * la couleur seule n'étant de toute façon pas un moyen d'information acceptable.
 */
/* `.ff-el-form-check-error` retiré : ce sélecteur n'existe pas dans Fluent Forms 6.2.5. */
.rh-form .error.text-danger,
.rh-form .ff-el-is-error .error {
  color: var(--rh-form-encre);
  font-size: 0.82rem;
  font-weight: 600;
  line-height: 1.4;
  margin-top: 6px;
  padding-left: 9px;
  border-left: 3px solid var(--rh-form-accent);
}

/* ---------------------------------------------------------------------------
 * Le titre et l'introduction qui accompagnent le formulaire
 *
 * Ils vivent dans des blocs Greenshift de la page, hérités du thème de démo, et sont en
 * BLANC — parce que la colonne était vert foncé à l'origine. Sur le saumon actuel, le blanc
 * tombe à ~1,9:1 : le titre de la page Contact est illisible.
 *
 * Corrigé ici, en CSS, et non dans le contenu de la page : un réglage de contenu ne part pas
 * avec le déploiement et serait à rejouer sur chaque environnement (le travers récurrent du
 * projet).
 *
 * ⚠️ PORTÉE VOLONTAIREMENT ÉTROITE — et c'est une correction de revue.
 * La première version ciblait `[class*="gspb_col-id"]:has(.rh-form) .gspb_heading, … .gspb_text`,
 * soit TOUT descendant `.gspb_heading`/`.gspb_text` de n'importe quelle colonne ancêtre du
 * formulaire, à n'importe quelle profondeur. Le commentaire présentait même cette largeur comme
 * un avantage (« survivra à RH-25 ») : c'était l'inverse. Le jour où RH-25 remet le formulaire
 * dans une colonne contenant d'autres blocs — un titre blanc sur photo sombre, par exemple —
 * tous ces titres passeraient en #283836 avec un `!important` que rien ne peut battre.
 *
 * On se limite donc aux **frères directs** du conteneur du formulaire : c'est exactement le
 * titre et l'introduction que RH-16 réécrit, et rien d'autre.
 *
 * ⚠️ `!important` ASSUMÉ, et c'est le seul du fichier. Greenshift écrit ses couleurs dans des
 * règles portant un SÉLECTEUR D'ID (`#gspb_heading-id-… { color: … }`) injectées en <style>
 * dans la page : aucune règle de classe, même très spécifique, ne peut les battre. Le choix
 * est donc entre `!important` et une édition du contenu en base — et l'édition en base est
 * précisément ce qu'on cherche à éviter.
 * ------------------------------------------------------------------------ */

[class*="gspb_col-id"]:has(> .fluentform .rh-form) > .gspb_heading,
[class*="gspb_col-id"]:has(> .fluentform .rh-form) > .gspb_text {
  color: var(--theme-palette-color-3, #283836) !important;
}

/*
 * Message de confirmation après envoi (le formulaire se masque et laisse la place).
 * Scopé au conteneur de NOS formulaires : non scopé, cette règle restylerait le message de
 * confirmation de n'importe quel autre formulaire Fluent Forms de la même page.
 */
.fluentform:has(.rh-form) .ff-message-success,
.rh-form ~ .ff-message-success,
.rh-form .ff-message-success {
  color: var(--theme-palette-color-3, #283836);
  background: var(--theme-palette-color-8, #ffffff);
  border: 1px solid rgba(40, 56, 54, 0.28);
  border-radius: 2px;
  padding: 20px 22px;
  font-size: 1rem;
  line-height: 1.5;
}

/* ---------------------------------------------------------------------------
 * Espacements et responsive
 *
 * Breakpoints alignés sur ceux du thème (Greenshift/Blocksy travaillent en 575.98 / 767.98 /
 * 991.98) et sur les paliers de QA de la story : 320 / 768 / 1440 / 3440.
 * ------------------------------------------------------------------------ */

.rh-form .ff-el-group {
  margin-bottom: var(--rh-form-gap);
}

/*
 * `:last-child` et non `:last-of-type` : l'enveloppe `role="group"` du groupe radio fait de sa
 * `.ff-el-group` le seul `div` de son parent, donc `:last-of-type` matchait et supprimait sa
 * marge basse — les boutons collaient au texte suivant.
 */
.rh-form .ff-el-group:last-child {
  margin-bottom: 0;
}

/* L'enveloppe du groupe porte la marge à la place de la .ff-el-group qu'elle contient. */
.rh-form .rh-form__groupe {
  margin-bottom: var(--rh-form-gap);
}

/*
 * PALIER 768 — date et heure restent EMPILÉES, et c'est acté.
 *
 * La version précédente portait une règle sur `.ff-t-cell` en annonçant « date et heure
 * partagent une ligne ». Cette classe n'existe nulle part dans le markup rendu : la règle était
 * morte et le commentaire faux. Les mettre côte à côte demanderait un conteneur commun posé
 * par le script de provisionnement (`container_class` partagé + grille) — ce n'est pas fait, et
 * le gabarit de la story l'autorisait (« peuvent revenir sur une ligne », pas « doivent »).
 *
 * Deux champs optionnels empilés sur un formulaire à une colonne de 560 px : c'est lisible, et
 * ça évite d'introduire une structure de mise en page dans un script de contenu.
 */

/* < 576px (320px inclus) : les 3 boutons radio passent en pleine largeur, empilés. Trois
   boutons côte à côte sur 320px donneraient des libellés tronqués ou des cibles minuscules. */
@media (max-width: 575.98px) {
  /*
   * Sous 576px, le contrôle segmenté devient VERTICAL — il reste un bloc unique, mais ses
   * segments sont empilés. Trois segments côte à côte sur 320px donneraient des libellés
   * illisibles ou des cibles minuscules ; les détacher casserait l'effet « un seul contrôle ».
   */
  .rh-form .rh-form__souhait .ff-el-input--content {
    flex-direction: column;
  }

  .rh-form .rh-form__souhait .ff-el-form-check {
    flex: 1 1 auto;
    /* Le chevauchement passe du bord gauche au bord haut. */
    margin: -1px 0 0 0;
  }

  .rh-form .rh-form__souhait .ff-el-form-check:first-child {
    margin-top: 0;
  }

  .rh-form .rh-form__souhait .ff-el-input--content > .error {
    margin-top: 8px;
  }

  .rh-form .rh-form__souhait .ff-el-form-check-label {
    /* Cible tactile pleine largeur, texte centré. */
    justify-content: center;
    text-align: center;
    padding: 14px 16px;
  }

  .rh-form .ff-btn-submit {
    width: 100%;
  }
}

/*
 * Très grands écrans (palier 3440 de la QA) : rien de spécifique à faire — la borne
 * `max-width: 560px` posée sur `.rh-form` s'applique déjà à toutes les tailles.
 */

/* ---------------------------------------------------------------------------
 * prefers-reduced-motion
 *
 * Aucune transition n'est porteuse de sens ici : on les coupe toutes. Les ÉTATS
 * (hover, focus, checked) restent parfaitement visibles — ils ne dépendent que de couleurs et
 * de contours, jamais d'une animation.
 * ------------------------------------------------------------------------ */

@media (prefers-reduced-motion: reduce) {
  .rh-form .ff-el-form-control,
  .rh-form .rh-form__souhait .ff-el-form-check-label,
  .rh-form .ff-btn-submit {
    transition: none;
  }

  .rh-form .ff-btn-submit:active {
    transform: none;
  }
}

/* ---------------------------------------------------------------------------
 * Contrastes forcés (Windows, « High Contrast »)
 *
 * L'`input[type=radio]` réel est réduit à 1px et transparent : l'état coché n'est porté que par
 * la couleur de fond du label. Or en contrastes forcés le système écrase `background-color` —
 * coché et non coché redevenaient donc IDENTIQUES, et l'indicateur natif est invisible.
 * On repasse ici sur les couleurs système, seules autorisées dans ce mode.
 * ------------------------------------------------------------------------ */

@media (forced-colors: active) {
  .rh-form .rh-form__souhait .ff-el-form-check-label:has(.ff-el-form-check-input:checked),
  .rh-form .rh-form__souhait .ff_item_selected .ff-el-form-check-label {
    /* En contrastes forcés, le rouge de charte est écrasé comme toute autre couleur. */
    forced-color-adjust: none;
    background: Highlight;
    color: HighlightText;
    border-color: Highlight;
  }

  /* L'anneau de focus doit rester visible : `box-shadow` est ignoré en contrastes forcés. */
  .rh-form .ff-el-form-control:focus,
  .rh-form .ff-btn-submit:focus,
  .rh-form .rh-form__souhait .ff-el-form-check-label:focus-within {
    outline: 3px solid CanvasText;
    outline-offset: 2px;
  }
}

/* ---------------------------------------------------------------------------
 * Sélecteur de date (flatpickr, embarqué par Fluent Forms)
 *
 * ⚠️ Ces règles ne sont PAS scopées à `.rh-form` : flatpickr injecte son calendrier en fin de
 * <body>, hors du formulaire. Aucune règle scopée ne peut l'atteindre.
 *
 * Deux défauts du CSS de flatpickr, relevés en revue :
 *   - `.flatpickr-day:focus { outline: 0; background: #e6e6e6 }` → 1,25:1 contre le fond blanc du
 *     calendrier, et identique au `:hover`. Un utilisateur clavier ne voit pas quel jour a le
 *     focus (échec SC 2.4.7) — c'est le seul widget JS du formulaire.
 *   - `.flatpickr-day.selected { background: #569ff7 }` → un bleu hors charte, exactement le
 *     même problème que celui qui a fait retirer `ff_list_buttons`.
 * ------------------------------------------------------------------------ */

.flatpickr-calendar .flatpickr-day:focus,
.flatpickr-calendar .flatpickr-day:focus-visible {
  outline: 2px solid var(--theme-palette-color-4, #011412);
  outline-offset: -2px;
  background: var(--theme-palette-color-6, #FFF4EF);
}

.flatpickr-calendar .flatpickr-day.selected,
.flatpickr-calendar .flatpickr-day.selected:hover,
.flatpickr-calendar .flatpickr-day.startRange,
.flatpickr-calendar .flatpickr-day.endRange {
  background: var(--theme-palette-color-3, #283836);
  border-color: var(--theme-palette-color-3, #283836);
  color: var(--theme-palette-color-8, #ffffff);
}
