/* Page Contact — issue de la fusion de /contact/ et /faqs/ (direction
   explicite).

   Reprend le squelette partagé .page-split (page-split.css) plutôt que la
   grille sur mesure de l'ancien contact-hero.css, et les mêmes tokens
   --li-* que les autres familles de cartes du site, redéclarés ici comme
   le fait chaque fichier de ce dossier.

   Les accordéons réutilisent tels quels le recette de faq.css : rien n'y
   est dupliqué, la page charge simplement les deux fichiers. */

.contact-section,
.faq-section {
  --li-card-bg: rgba(38, 32, 56, 0.55);
  --li-card-blur: blur(24px);
  --li-border: rgba(255, 255, 255, 0.08);
  --li-shadow: 0 4px 24px rgba(0, 0, 0, 0.35);
  --li-text: rgba(255, 255, 255, 0.92);
  --li-text-secondary: rgba(255, 255, 255, 0.6);
  --field-focus: #7d8ff5;
}

.contact-section .section__inner,
.faq-section .section__inner {
  max-width: 1320px;
}

/* Espace sous la navbar construit sur sa hauteur RÉELLE et mesurée, comme
   partout ailleurs sur le site : 16px de padding haut + 64px de barre =
   80px en mobile, 43px + 64px = 107px à partir de 1024px (header.css). */
.contact-section {
  padding-top: 128px;
  /* 0 : l'écart avec la section FAQ est porté par le padding-top de
     celle-ci (voir plus bas). */
  padding-bottom: 0;
}

/* Cible de l'ancre #faq. Deux choses en une :

   — l'écart entre les deux sections est porté ICI, et non par le
     padding-bottom de la section Contact (mis à 0) : le haut de cette
     boîte coïncide donc avec la fin du formulaire, et l'arrivée sur
     l'ancre ne laisse rien dépasser de la section précédente ;
   — ce même padding-top dégage l'en-tête FIXE. Mesuré avant correction :
     le surtitre « FAQ » arrivait à 69px du haut, sous un en-tête qui
     descend à 107px — donc illisible. Les valeurs sont construites sur sa
     hauteur réelle : 16 + 64 = 80px en mobile, 43 + 64 = 107px à partir
     de 1024px (header.css), plus une marge de respiration.

   scroll-margin-top reste donc à sa valeur par défaut, 0. */
.faq-section {
  padding-top: 110px;
  padding-bottom: 104px;
}

@media (min-width: 1024px) {
  /* Même respiration que .services-rate sur /services/ (services-rate.css) :
     min-height: 100vh + centrage flex, le contenu flotte au milieu d'une
     boîte pleine hauteur. Sûr ici : rien dans le formulaire ne change de
     hauteur après le premier rendu (contrairement à .faq-section
     juste en dessous), donc rien ne peut faire bouger ce centrage une
     fois posé. */
  .contact-section {
    --header-height: 107px;
    /* Nudge, pas une renégociation du centrage : réglage manuel demandé
       après coup ("remonte légèrement"), en attendant confirmation. Un
       translateY sur .section__inner (pas un padding-bottom) -- ça
       déplace le contenu SANS toucher à la boîte min-height:100vh qui
       fait le centrage lui-même. */
    --contact-nudge-y: -60px;
    min-height: 100vh;
    display: flex;
    align-items: center;
    padding-top: calc(var(--header-height) + clamp(56px, 6vh, 76px));
    padding-bottom: 0;
  }

  .contact-section > .section__inner {
    width: 100%;
    transform: translateY(var(--contact-nudge-y));
  }

  /* PAS le même mécanisme que .contact-section/.services-rate : un
     min-height: 100vh + centrage flex ici recalcule sa boîte à CHAQUE
     ouverture/fermeture d'accordéon (.faq-feed change de hauteur), ce qui
     déplace le bloc entier — colonne de gauche comprise — de tout l'écart
     que l'accordéon vient de gagner ou perdre (mesuré : jusqu'à 55px, un
     vrai bug remonté après coup, pas une supposition). Un padding-top
     STATIQUE ne dépend que de la hauteur du VIEWPORT (via vh), jamais du
     contenu qui vient de s'ouvrir en dessous, donc rien ne bouge plus.
     clamp(...,29vh,...) reproduit la même respiration mesurée avec l'ancien
     centrage à un viewport de 900px (900 * 0.29 ≈ 261px) sans jamais la
     recalculer depuis le DOM.

     La colonne de gauche N'utilise PAS .page-split__intro--sticky
     (page-split.css), essayé puis retiré : .faq-intro est seule dans sa
     propre rangée de grille (grid-template-rows: auto 1fr), une rangée
     "auto" dimensionnée sur son seul contenu -- donc quasiment aucune
     marge de manœuvre pour un vrai effet sticky, et en fin de section
     (près du footer) l'élément relâchait son ancrage et retombait au
     niveau de l'illustration, qui elle ne bougeait pas -- lu comme
     "l'image remonte au niveau du titre". Demande explicite ensuite :
     "tout doit être fixe" -- donc intro ET illustration sont maintenant
     de simples blocs statiques, sans sticky du tout : zéro mouvement
     est plus sûr ici qu'un sticky mal dimensionné. */
  .faq-section {
    /* Deuxième réglage manuel demandé après coup : encore plus haut, et
       plus d'écart avant le footer -- donc padding-top réduit ENCORE et
       padding-bottom augmenté, dans le même mouvement (pas juste un
       translateY, qui aurait remonté le haut sans toucher le bas). */
    padding-top: clamp(30px, 12vh, 120px);
    padding-bottom: 170px;
  }

  /* Première section : 42 % / 58 % demandés. 0.85fr / 1.17fr = 42,1 % /
     57,9 % à toute largeur de bureau. */
  .page-split--contact {
    max-width: 1320px;
    --page-split-intro: 0.85fr;
    --page-split-content: 1.17fr;
    --page-split-gap: 72px;
    /* Les deux colonnes sont alignées en HAUT, pas centrées : le
       formulaire est plus haut que la colonne de gauche, et le centrer
       creuserait un vide au-dessus du titre — exactement le « grand vide
       dans la colonne gauche » à corriger. */
    align-items: start;
  }

  /* FAQ : 34 % / 66 %, dans la fourchette 32-36 / 64-68 demandée.
     Deux lignes : le texte puis l'illustration à gauche, la liste
     d'accordéons à droite sur toute la hauteur. C'est ce placement
     explicite qui permet à l'illustration d'être le dernier enfant du DOM
     — donc dernière sur mobile, comme demandé — tout en restant sous le
     texte sur bureau. */
  .page-split--faq {
    max-width: 1320px;
    --page-split-intro: 0.85fr;
    --page-split-content: 1.65fr;
    --page-split-gap: 64px;
    align-items: start;
    grid-template-rows: auto 1fr;
  }

  .page-split--faq > .faq-intro {
    grid-column: 1;
    grid-row: 1;
  }

  .page-split--faq > .faq-feed {
    grid-column: 2;
    grid-row: 1 / span 2;
  }

  .page-split--faq > .faq-illustration-wrap {
    grid-column: 1;
    grid-row: 2;
  }
}

/* ---- Section 1 : colonne gauche ------------------------------------ */

.contact-title {
  /* Le titre est long : une largeur de lecture explicite évite qu'il
     s'étale sur toute la colonne en lignes trop longues. */
  max-width: 20ch;
}

/* Le « ? » vit DANS le span en dégradé, et y annule le dégradé pour
   rester blanc.

   Pourquoi : .page-title-highlight est un `display: inline-block`
   (page-heading.css — la technique background-clip: text en a besoin),
   donc une boîte ATOMIQUE. Du texte placé après elle ne peut pas se
   glisser sur sa dernière ligne : mesuré, le « ? » se retrouvait seul sur
   une quatrième ligne, en blanc, détaché du titre. L'espace fine
   insécable qui le précède n'y changeait rien — la coupure venait de la
   frontière de la boîte, pas d'une opportunité de césure dans le texte.

   -webkit-text-fill-color est ce qui reprend la main : le parent peint son
   texte en `color: transparent` pour laisser voir le dégradé découpé, et
   seule cette propriété permet à un enfant de redevenir opaque sans
   toucher au clip du parent. */
.contact-title__suffix {
  color: #fff;
  -webkit-text-fill-color: #fff;
}

.contact-subtitle {
  max-width: 44ch;
  margin-top: clamp(16px, 1.8vw, 22px);
}

.contact-formats {
  margin: clamp(14px, 1.6vw, 18px) 0 0;
  font-family: var(--font-satoshi);
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--li-text-secondary);
}

@media (min-width: 1024px) {
  .contact-title,
  .contact-subtitle,
  .contact-formats {
    text-align: left;
  }
}

/* ---- Illustrations ------------------------------------------------- */

.contact-illustration-wrap,
.faq-illustration-wrap {
  display: flex;
  justify-content: center;
  margin-top: clamp(28px, 3.5vw, 44px);
}

@media (min-width: 1024px) {
  .contact-illustration-wrap,
  .faq-illustration-wrap {
    justify-content: flex-start;
  }
}

/* height: auto pour que le ratio soit tenu par la largeur, tout en gardant
   les attributs width/height du HTML : c'est eux qui réservent la place
   avant le chargement, donc aucun décalage de mise en page. */
.contact-illustration {
  width: 100%;
  max-width: 268px;
  height: auto;
  /* Mouvement vertical de quelques pixels, lent : aucune rotation, aucune
     boucle agressive. transform seul, donc composité — jamais de recalcul
     de mise en page. */
  animation: contact-float 7s ease-in-out infinite;
}

.faq-illustration {
  width: 100%;
  max-width: 196px;
  height: auto;
}

@keyframes contact-float {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-7px); }
}

@media (prefers-reduced-motion: reduce) {
  .contact-illustration {
    animation: none;
  }
}

/* ---- Section 1 : la carte du formulaire ---------------------------- */

.contact-form-wrap {
  width: 100%;
  padding: clamp(22px, 2.2vw, 30px);
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.05), transparent 42%),
    var(--li-card-bg);
  border: 1px solid var(--li-border);
  border-radius: 20px;
  box-shadow: var(--li-shadow), inset 0 1px 0 rgba(255, 255, 255, 0.07);
  backdrop-filter: var(--li-card-blur);
  -webkit-backdrop-filter: var(--li-card-blur);
}

.contact-form {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* Nom et e-mail sur une ligne dès qu'il y a la place, empilés en dessous.
   Le seuil est en largeur de CONTENEUR et non de viewport : c'est la
   largeur réelle de la carte qui décide, quelle que soit la colonne dans
   laquelle elle se trouve. */
.contact-form__row {
  display: grid;
  grid-template-columns: 1fr;
  gap: 16px;
}

@container contact-card (min-width: 420px) {
  .contact-form__row {
    grid-template-columns: 1fr 1fr;
  }
}

.contact-form-wrap {
  container-type: inline-size;
  container-name: contact-card;
}

.contact-form__field {
  display: flex;
  flex-direction: column;
  gap: 7px;
  min-width: 0;
}

/* De VRAIS labels visibles, jamais remplacés par les placeholders. */
.contact-form label {
  font-family: var(--font-satoshi);
  font-weight: 600;
  font-size: 13.5px;
  color: var(--li-text);
  transition: color 0.18s ease;
}

.contact-form__field:focus-within label {
  color: #cdd7ff;
}

.contact-form input[type="text"],
.contact-form input[type="email"],
.contact-form textarea {
  width: 100%;
  font-family: var(--font-satoshi);
  font-size: 14.5px;
  color: #fff;
  background: rgba(255, 255, 255, 0.04);
  /* Bordure 1px présente dans TOUS les états, y compris au focus : une
     bordure qui s'épaissit au focus décale le contenu du champ. */
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 12px;
  padding: 12px 14px;
  transition: border-color 0.18s ease, box-shadow 0.18s ease, background-color 0.18s ease;
}

.contact-form textarea {
  min-height: 132px;
  resize: vertical;
}

.contact-form input::placeholder,
.contact-form textarea::placeholder {
  color: rgba(255, 255, 255, 0.38);
}

/* Halo LOCALISÉ : un anneau de 3px, pas un grand flou. box-shadow non
   animée en dimension, seule sa valeur change d'un état à l'autre. */
.contact-form input:focus,
.contact-form textarea:focus {
  outline: none;
  border-color: var(--field-focus);
  background: rgba(255, 255, 255, 0.06);
  box-shadow: 0 0 0 3px rgba(125, 143, 245, 0.22);
}

.contact-form input:focus-visible,
.contact-form textarea:focus-visible {
  outline: none;
}

.contact-form input.is-invalid,
.contact-form textarea.is-invalid {
  border-color: rgba(248, 113, 113, 0.7);
}

.contact-form input.is-invalid:focus,
.contact-form textarea.is-invalid:focus {
  box-shadow: 0 0 0 3px rgba(248, 113, 113, 0.2);
}

/* Vide, l'emplacement d'erreur ne prend aucune place : il n'y a donc pas
   de saut de mise en page quand un message apparaît, seulement une ligne
   qui s'ajoute sous le champ concerné. */
.contact-form__error {
  margin: 0;
  font-family: var(--font-satoshi);
  font-size: 12.5px;
  line-height: 1.4;
  color: #fca5a5;
}

.contact-form__error:empty {
  display: none;
}

.contact-form__disclaimer {
  margin: 2px 0 0;
  font-family: var(--font-satoshi);
  font-size: 12px;
  line-height: 1.55;
  color: var(--li-text-secondary);
}

.contact-form__disclaimer a {
  color: #9fb8ff;
  text-decoration: underline;
  text-underline-offset: 2px;
}

.contact-form__disclaimer a:hover,
.contact-form__disclaimer a:focus-visible {
  color: #fff;
}

.contact-form__status {
  margin: 0;
  font-family: var(--font-satoshi);
  font-size: 13.5px;
  line-height: 1.5;
  display: none;
}

.contact-form__status.is-visible {
  display: block;
}

.contact-form__status.is-success {
  color: #86efac;
}

.contact-form__status.is-error {
  color: #fca5a5;
}

/* ---- Le bouton ----------------------------------------------------- */

.contact-form__submit {
  /* Largeur naturelle sur bureau : .btn impose 234px, remplacé ici par
     la largeur du texte plus un rembourrage. Le bouton ne prend jamais
     toute la largeur de la carte. */
  width: auto;
  align-self: flex-start;
  padding-inline: 28px;
  gap: 10px;
}

@media (max-width: 480px) {
  .contact-form__submit {
    width: 100%;
    align-self: stretch;
  }
}

/* Largeur stable pendant l'envoi : le fantôme contient le plus long des
   deux libellés et occupe la place, le libellé réel se superpose. Sans
   ça, le bouton rétrécit ou s'élargit au passage en « envoi en cours ». */
.contact-form__submit-label {
  position: relative;
  display: inline-grid;
}

.contact-form__submit-label > span {
  grid-area: 1 / 1;
}

.contact-form__submit-ghost {
  visibility: hidden;
  pointer-events: none;
}

.contact-form__submit-icon {
  transition: transform 0.18s ease;
}

.contact-form__submit:hover .contact-form__submit-icon {
  transform: translateX(3px);
}

.contact-form.is-sending .contact-form__submit {
  cursor: progress;
}

/* Indicateur léger : l'icône d'envoi pulse doucement pendant la requête.
   Aucun élément ajouté, aucune dimension modifiée. */
.contact-form.is-sending .contact-form__submit-icon {
  animation: contact-sending 0.9s ease-in-out infinite;
}

@keyframes contact-sending {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.35; }
}

@media (prefers-reduced-motion: reduce) {
  /* Les sélecteurs des champs sont répétés à l'IDENTIQUE de la règle de
     base : `.contact-form input` seul ne suffisait pas, la règle de base
     porte des sélecteurs d'attribut (input[type="text"]) donc une
     spécificité plus forte, et la transition survivait. Constaté à la
     mesure. */
  .contact-form__submit-icon,
  .contact-form input[type="text"],
  .contact-form input[type="email"],
  .contact-form textarea,
  .contact-form label {
    transition: none;
  }

  .contact-form__submit:hover .contact-form__submit-icon {
    transform: none;
  }

  .contact-form.is-sending .contact-form__submit-icon {
    animation: none;
    opacity: 0.6;
  }
}

/* ---- Section 2 : colonne gauche de la FAQ -------------------------- */

.faq-label {
  margin: 0 0 12px;
  font-family: var(--font-satoshi);
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: #9fb8ff;
}

.faq-title {
  margin-top: 0;
}

.faq-subtitle {
  max-width: 36ch;
  margin-top: clamp(14px, 1.6vw, 18px);
}

@media (min-width: 1024px) {
  .faq-label,
  .faq-title,
  .faq-subtitle {
    text-align: left;
  }
}
