/* ─────────────────────────────────────────────────────────────────────────
   Page Contact (template-contact.php)
   Chargée uniquement sur ce gabarit (ml_page_contact_enqueue() dans
   functions.php, handle « ml-page-contact »), dépendante de main.css : tous
   les tokens (--ml-*) sont lus depuis le :root de main.css, jamais
   redéclarés ici. Mobile first, palier principal à 900px comme le reste du
   thème. Toute animation respecte prefers-reduced-motion.

   Refonte (juillet 2026, demande de Marino, page jugée trop neutre) : le
   même haut de page violet plein que les gabarits Langue et Formule, pour
   que le contact ne soit plus la seule page à l'ancien habillage générique
   de main.css (encore lu tel quel par .ml-contact-grid, .ml-field-honeypot
   et .ml-info-list : ce fichier ne fait qu'affiner ce que main.css pose déjà,
   jamais le redéfinir ailleurs). Le formulaire garde exactement sa mécanique
   (action, nonce, piège à robots, validations, libellés) : rien ici ne
   touche à autre chose qu'à l'apparence.
───────────────────────────────────────────────────────────────────────── */

/* La barre de menu flotte par dessus le haut de page violet : même marge
   négative que sur les pages Langue et Formule. */
.page-template-template-contact-php .ml-header {
  margin-block-end: calc(-1 * (var(--ml-header-h) + var(--ml-space-sm)));
}

/* ── HAUT DE PAGE : bloc violet plein, grand arrondi en bas à droite ──────
   Même langage visuel que les pages Langue et Formule. Le groupe éditable
   ml-blk-contact-intro ne porte toujours ni image ni chiffre : la deuxième
   colonne du haut de page (à partir de 900px) est posée en chrome par le
   gabarit, c'est la mascotte du site (voir plus bas, "Linguine, dans la
   zone de droite du haut de page"), jamais un contenu éditable. */
.ml-contact-hero {
  position: relative;
  isolation: isolate;
  background: var(--ml-accent);
  color: #fff;
  padding-block: calc(var(--ml-header-h) + var(--ml-space-lg)) var(--ml-space-xl);
  padding-inline: var(--ml-space-sm);
  border-end-end-radius: 140px;
}

.ml-contact-hero-inner {
  position: relative;
  z-index: 1;
  display: grid;
  gap: var(--ml-space-lg);
}
@media (min-width: 900px) {
  .ml-contact-hero-inner {
    grid-template-columns: 1.4fr 1fr;
    align-items: center;
    gap: var(--ml-space-xl);
  }
}

/* Le bloc de texte du groupe ml-blk-contact-intro est rendu tel quel
   (ml_section(), jamais décomposé bloc par bloc) : les sélecteurs ci dessous
   visent donc les classes génériques que Gutenberg pose lui même
   (wp-block-heading, ml-eyebrow), à l'intérieur de ce conteneur précis. Un
   futur contenu qui ajouterait un lien dans le paragraphe reste lisible
   (voir la règle sur les liens, plus bas) : le contrat Gutenberg du projet
   laisse la cliente libre du texte, jamais du style. */
.ml-contact-hero-texte {
  max-inline-size: 56ch;
}
.ml-contact-hero-texte .ml-eyebrow {
  color: rgba(255, 255, 255, 0.85);
}
.ml-contact-hero-texte .ml-eyebrow::before {
  background: rgba(255, 255, 255, 0.55);
}
.ml-contact-hero-texte .wp-block-heading {
  color: #fff;
  max-inline-size: 22ch;
  margin-block: var(--ml-space-xs) var(--ml-space-sm);
  text-shadow: 0 2px 18px rgba(20, 8, 28, 0.25);
}
.ml-contact-hero-texte p:not(.ml-eyebrow) {
  color: rgba(255, 255, 255, 0.92);
  font-size: var(--ml-fs-lg);
  max-inline-size: 52ch;
}
/* Repli de lisibilité si un lien est un jour ajouté dans le paragraphe
   éditable : le violet de marque tombe sous 4,5:1 sur ce fond, le blanc
   souligné reste la seule option qui tienne. */
.ml-contact-hero-texte a {
  color: #fff;
  text-decoration: underline;
  text-underline-offset: 0.2em;
}
.ml-contact-hero-texte a:focus-visible {
  outline-color: #fff;
}

/* Repère « humain » (ml_cta_humain()) et bouton de rendez-vous, côte à côte
   sous le texte. Ni l'un ni l'autre n'existe si le réglage ou la photo
   manquent (voir template-contact.php) : jamais de ligne vide. */
.ml-contact-hero-cta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--ml-space-md);
  margin-block-start: var(--ml-space-lg);
}
/* Le gap du flex gère déjà l'écart entre le composant et le bouton : on
   retire la marge de flux propre à ml_cta_humain() pour ne pas la doubler
   (même correctif que sur les CTA des pages Langue, Pays et Formule). */
.ml-contact-hero-cta .ml-cta-humain {
  margin-block-end: 0;
}
/* Bouton blanc sur le violet plein, jamais l'inverse : .ml-btn-primary
   (violet sur blanc) serait invisible ici. Même recette que le bouton de
   l'appel final de la page Formule. */
.ml-contact-hero-bouton {
  background: #fff;
  color: var(--ml-accent);
}
.ml-contact-hero-bouton:hover {
  background: var(--ml-accent-soft);
}
.ml-contact-hero-bouton:focus-visible {
  outline-color: #fff;
}

/* ── Linguine, dans la zone de droite du haut de page ──────────────────────
   La mascotte du site (globe et bras, assets/img/mascotte.svg), en blanc :
   c'est le seul fond du gabarit assez soutenu (le violet plein du bandeau)
   pour qu'un tracé blanc se détache vraiment, la même règle que le globe de
   l'accueil sur son fond sombre (voir assets/css/assistant-modale.css,
   .ml-am-mascotte-hero .ml-am-mascotte-image). Décorative, donc aria-hidden
   côté gabarit : rien de ce qu'elle montre n'est une information, le texte
   du haut de page se suffit à lui même.

   Sur mobile elle suit le texte dans l'ordre du document (une seule colonne
   de la grille) ; à partir de 900px elle prend sa propre colonne, à droite,
   comme la bulle à la craie du gabarit Langue (assets/css/page-langue.css,
   .ml-langue-hero-bulle-img) dont elle reprend le même flottement doux. */
.ml-contact-hero-mascotte {
  display: flex;
  justify-content: center;
  align-items: center;
  color: #fff;
}
/* TROIS FOIS PLUS GRANDE (demande de Marino). Elle était posée à la taille
   d'un ornement de coin ; c'est le sujet de la moitié droite du bandeau, elle
   doit en occuper la place. L'ombre portée grandit avec elle, sans quoi un
   grand tracé blanc se met à flotter sans poids sur le violet.

   La borne haute est celle de la colonne qui l'accueille, pas trois fois la
   valeur d'avant : la grille donne 1fr sur 2,4 au bandeau, soit environ 500px
   sur la largeur maximale du conteneur. Au delà, elle déborderait de sa colonne
   et repousserait le texte. */
.ml-contact-hero-mascotte svg {
  display: block;
  inline-size: clamp(200px, 62vw, 380px);
  block-size: auto;
  filter: drop-shadow(0 26px 44px rgba(30, 10, 42, 0.5));
  animation: ml-contact-mascotte-flotte 6s ease-in-out infinite;
}
@media (min-width: 900px) {
  .ml-contact-hero-mascotte svg {
    inline-size: clamp(320px, 34vw, 500px);
  }
}
@keyframes ml-contact-mascotte-flotte {
  0%,
  100% {
    transform: translateY(0);
  }
  50% {
    /* En pourcentage plutôt qu'en pixels : le mouvement garde la même ampleur
       relative quelle que soit la taille rendue, du téléphone au grand écran. */
    transform: translateY(-3.5%);
  }
}
@media (prefers-reduced-motion: reduce) {
  .ml-contact-hero-mascotte svg {
    animation: none;
  }
}

/* ── FORMULAIRE + COORDONNÉES ──────────────────────────────────────────────
   main.css pose déjà .ml-contact-grid (une colonne, deux à partir de 900px)
   et le contour commun des deux cartes : ce fichier ne fait qu'affiner ce
   qui rend la page terne aujourd'hui (deux cartes identiques, champs sans
   air, coordonnées sans repère visuel). */
.ml-contact-grid {
  align-items: start;
}

.ml-contact-form-card {
  box-shadow: var(--ml-shadow-md);
}
.ml-contact-form-card h2 {
  margin-block-start: 0;
}

/* La carte de coordonnées se détache par la matière plutôt que par une
   bordure neutre : même paire fond clair + bordure lilas que l'encart de
   rendez-vous du pied de page (--ml-accent-soft, --ml-accent-bordure). */
.ml-contact-info {
  background: var(--ml-accent-soft);
  border-color: var(--ml-accent-bordure);
}
.ml-contact-info h2 {
  margin-block-start: 0;
}

/* ── Champs du formulaire : deux colonnes à partir de 560px ────────────────
   Le nom et l'e-mail vont naturellement côte à côte ; le téléphone
   (optionnel) et le message reprennent toute la largeur. Purement une
   affaire de mise en page : les attributs id, name, for, required et type de
   chaque champ ne bougent pas d'une ligne dans le gabarit. */
.ml-contact-form {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--ml-space-md);
}
@media (min-width: 560px) {
  .ml-contact-form {
    grid-template-columns: 1fr 1fr;
  }
  .ml-champ--pleine {
    grid-column: 1 / -1;
  }
}
.ml-champ {
  margin: 0;
}
.ml-champ label {
  display: block;
  margin-block-end: 0.35em;
  font-weight: 600;
  color: var(--ml-text);
}
/* --ml-text-mid, jamais --ml-text-dim : ce dernier tombe à 3,7:1 sur blanc
   (mesure déjà consignée dans footer.css), sous le seuil de 4,5:1 exigé pour
   du texte de cette taille. */
.ml-champ label span {
  font-weight: 400;
  color: var(--ml-text-mid);
}
.ml-champ input,
.ml-champ textarea {
  width: 100%;
  padding: 0.75em 1em;
  border: 1px solid var(--ml-border-strong);
  border-radius: var(--ml-radius);
  background: var(--ml-bg);
  font: inherit;
  color: var(--ml-text);
  transition: border-color 200ms var(--ml-ease), box-shadow 200ms var(--ml-ease);
}
.ml-champ input:focus-visible,
.ml-champ textarea:focus-visible {
  border-color: var(--ml-accent);
  box-shadow: var(--ml-focus-ring);
  /* Le contour générique (main.css) se superposerait à cet anneau : celui ci
     porte déjà le même violet, on ne garde qu'un seul repère de focus. */
  outline: none;
}
.ml-champ textarea {
  resize: vertical;
  min-block-size: 8em;
}
@media (prefers-reduced-motion: reduce) {
  .ml-champ input,
  .ml-champ textarea {
    transition: none;
  }
}

.ml-contact-form-bouton {
  justify-self: start;
  margin-block-start: var(--ml-space-xs);
}
@media (min-width: 560px) {
  .ml-contact-form-bouton {
    grid-column: 1 / -1;
  }
}

/* ── Liste des coordonnées : une pastille icône par ligne ──────────────────
   .ml-info-list n'est utilisée que sur cette page (voir CLAUDE.md) : les
   règles ci dessous peuvent donc redéfinir sa mise en page sans risque pour
   un autre gabarit. */
.ml-contact-info .ml-info-list {
  display: grid;
  gap: 0;
  margin: 0;
  padding: 0;
  list-style: none;
}
/* Deux classes, pour primer sur .ml-info-list li de main.css (une classe, un
   élément) : sans quoi son padding et sa bordure basse, pensés pour l'ancien
   habillage en simple liste, se mêleraient aux miens (double filet, padding
   incohérent). Le rembourrage et la bordure de main.css sont donc neutralisés
   ici avant d'être reposés à ma façon. */
.ml-contact-info .ml-info-item {
  display: flex;
  align-items: flex-start;
  gap: var(--ml-space-sm);
  padding: var(--ml-space-sm) 0;
  border-bottom: 0;
  border-block-start: 1px solid var(--ml-accent-bordure);
}
.ml-contact-info .ml-info-item:first-child {
  border-block-start: 0;
  padding-block-start: 0;
}
.ml-contact-info .ml-info-item:last-child {
  padding-block-end: 0;
}
.ml-info-contenu {
  min-inline-size: 0;
}
/* L'intitulé (« E-mail », « Téléphone »...) : même famille que les étiquettes
   de coordonnées du pied de page (footer.css, .ml-footer-coordonnees dt),
   mais en --ml-text-mid et non --ml-text-dim. Ce dernier tombe à 3,7:1 sur
   blanc (mesure déjà consignée dans footer.css) : encore moins lisible sur le
   fond lilas --ml-accent-soft de cette carte, il n'a donc pas sa place ici.
   --ml-text-mid, lui, reste largement au dessus de 4,5:1 sur ce fond presque
   blanc. La règle prime sur .ml-info-list span (main.css, une classe et un
   élément) grâce à ses deux classes : aucun besoin de !important. */
.ml-contact-info .ml-info-label {
  display: block;
  margin-block-end: 0.2em;
  font-size: 0.78rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ml-text-mid);
}
.ml-info-contenu a {
  font-weight: 600;
  color: var(--ml-text);
  text-decoration: none;
}
.ml-info-contenu a:hover,
.ml-info-contenu a:focus-visible {
  color: var(--ml-accent-dark);
  text-decoration: underline;
  text-underline-offset: 0.2em;
}
.ml-info-contenu address,
.ml-info-valeur {
  font-style: normal;
  font-weight: 600;
  color: var(--ml-text);
}
/* La note secondaire des horaires (« Sur rendez-vous en dehors de ces
   horaires ») : même --ml-text-mid que l'intitulé, pour la même raison de
   contraste, et deux classes pour la même raison de spécificité que
   .ml-info-label plus haut. Elle reste plus légère que la valeur grâce au
   poids de police seul, jamais à une couleur qui échouerait le contraste. */
.ml-contact-info .ml-info-note {
  display: block;
  font-weight: 400;
  color: var(--ml-text-mid);
}

/* La pastille : un cercle lilas plus soutenu que le fond de la carte, un
   glyphe en masque CSS teinté de l'accent (même technique que la coche des
   points forts de la page Formule, assets/css/fiche-formule.css). Purement
   décoratif (aria-hidden dans le gabarit) : l'intitulé écrit juste à côté
   porte le sens. Deux classes, encore pour la même raison de spécificité :
   sans elles, le display: block de .ml-info-list span (main.css) gagnerait
   sur le display: grid qui centre le glyphe. */
.ml-contact-info .ml-info-icone {
  flex: none;
  display: grid;
  place-items: center;
  inline-size: 2.25rem;
  block-size: 2.25rem;
  border-radius: var(--ml-radius-pill);
  background: #fff;
}
.ml-contact-info .ml-info-icone::before {
  content: '';
  inline-size: 1.1rem;
  block-size: 1.1rem;
  background-color: var(--ml-accent);
  -webkit-mask: var(--ml-info-icone-forme) no-repeat center / contain;
          mask: var(--ml-info-icone-forme) no-repeat center / contain;
}
.ml-info-item--email .ml-info-icone {
  --ml-info-icone-forme: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='5' width='18' height='14' rx='2'/%3E%3Cpath d='M3 7l9 6 9-6'/%3E%3C/svg%3E");
}
.ml-info-item--telephone .ml-info-icone {
  --ml-info-icone-forme: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M22 16.9v3a2 2 0 0 1-2.2 2 19.7 19.7 0 0 1-8.6-3.1 19.4 19.4 0 0 1-6-6 19.7 19.7 0 0 1-3.1-8.6A2 2 0 0 1 4.1 2h3a2 2 0 0 1 2 1.7c.1 1 .4 1.9.7 2.8a2 2 0 0 1-.4 2.1L8.1 9.9a16 16 0 0 0 6 6l1.3-1.3a2 2 0 0 1 2.1-.4c.9.3 1.8.6 2.8.7a2 2 0 0 1 1.7 2z'/%3E%3C/svg%3E");
}
.ml-info-item--adresse .ml-info-icone {
  --ml-info-icone-forme: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z'/%3E%3Ccircle cx='12' cy='10' r='3'/%3E%3C/svg%3E");
}
.ml-info-item--horaires .ml-info-icone {
  --ml-info-icone-forme: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpolyline points='12 7 12 12 15.5 14'/%3E%3C/svg%3E");
}

/* ── CARTE ──────────────────────────────────────────────────────────────── */
.ml-contact-carte-iframe {
  display: block;
  width: 100%;
  height: 420px;
  margin-block-start: var(--ml-space-md);
  border: 1px solid var(--ml-accent-bordure);
  border-radius: var(--ml-radius-lg);
  box-shadow: var(--ml-shadow-md);
}
.ml-contact-carte-lien {
  margin-block-start: var(--ml-space-sm);
  margin-block-end: 0;
}
.ml-contact-carte-lien a {
  font-weight: 600;
  color: var(--ml-accent);
  text-decoration: underline;
  text-underline-offset: 0.2em;
}
.ml-contact-carte-lien a:hover,
.ml-contact-carte-lien a:focus-visible {
  color: var(--ml-accent-dark);
}

/* ─────────────────────────────────────────
   LES BULLES DE SALUTATION EN FOND DE HAUT DE PAGE
   Elles remplacent le filigrane du globe. Quatre bulles de marque, une par
   langue enseignée, dessinées à la craie, semées en nombre pour faire une
   TEXTURE et non quelques taches (demande de Marino : quatre fois plus, et
   moins opaques).

   Chaque bulle porte sa position, sa taille et son inclinaison en variables,
   posées par le gabarit : le CSS ne connaît qu'une seule règle, et le semis se
   corrige dans le PHP, à la bulle près.
───────────────────────────────────────── */

/* La règle de base du haut de page est plus haut dans ce fichier (fond, rayon,
   isolation). On n'ajoute ici que le rognage : sans lui, une bulle déborderait
   du grand arrondi du coin. */
.ml-contact-hero {
  overflow: hidden;
}

.ml-contact-hero-bulles {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.ml-contact-hero-bulle {
  position: absolute;
  inset-block-start: var(--ml-bulle-haut, 50%);
  inset-inline-start: var(--ml-bulle-gauche, 50%);
  inline-size: var(--ml-bulle-taille, 6rem);
  block-size: auto;
  transform: rotate(var(--ml-bulle-angle, 0deg));
  /* Basse, et c'est le point : à ce niveau elles font un grain, pas un motif.
     Le texte du haut de page passe par dessus sans jamais avoir à lutter. */
  opacity: 0.09;
}

/* Sur un écran étroit, la même densité donnerait une bouillie derrière un texte
   qui occupe déjà toute la largeur : les bulles rétrécissent et s'effacent
   encore un peu. */
@media (max-width: 700px) {
  .ml-contact-hero-bulle {
    inline-size: calc(var(--ml-bulle-taille, 6rem) * 0.7);
    opacity: 0.07;
  }
}

