/* ProgLabAi — formulaire de demande de programmation (page publique).
   Complète shell.css : seules les pièces propres à ce formulaire sont ici. */

body.contact-body{
  background:
    radial-gradient(85% 55% at 8% -10%, #17293a 0%, transparent 58%),
    radial-gradient(65% 50% at 98% 4%, #221a3d 0%, transparent 60%),
    var(--bg);
  background-repeat:no-repeat;
  background-attachment:fixed;
}
.shell.contact-shell{ max-width:720px; }

/* ---------------- en-tête ----------------
   La barre propre au formulaire a disparu : la marque, la langue, la connexion
   et le menu sont dans la bannière commune du site, qui suit le défilement.
   Une barre à elle demandait un jeu de règles à elle, et elle se resserrait de
   son côté quand la barre commune se resserrait du sien. */
.ct-head{ margin-bottom:22px; }
.ct-head h1{
  font-size:28px; line-height:1.14; letter-spacing:-0.8px; margin:0 0 11px; font-weight:800;
}
.ct-head h1 .hl{
  background:linear-gradient(120deg, var(--accent), var(--accent-2));
  -webkit-background-clip:text; background-clip:text; color:transparent;
}
/* Le texte de présentation prend TOUTE la largeur du formulaire, écran large
   comme téléphone. Coupé à 56 caractères, il s'arrêtait au milieu de la page
   et laissait à sa droite un vide que rien ne justifiait, juste au-dessus d'un
   formulaire qui, lui, va d'un bord à l'autre. */
.ct-head .lede{ font-size:14px; line-height:1.62; color:var(--dim); margin:0; max-width:none; }
.ct-head .meta{ font-size:11.5px; color:var(--dim); margin:10px 0 0; opacity:.8; }
@media (min-width:640px){
  .ct-head h1{ font-size:34px; letter-spacing:-1px; }
  .ct-head .lede{ font-size:15px; }
}

/* ---------------- progression ---------------- */
/* Masquée tant que le pas-à-pas n'est pas actif : sans JavaScript toutes les
   questions s'affichent d'un bloc et une progression n'aurait aucun sens. */
.ct-progress{ display:none; }
.ct-form.js .ct-progress{ display:block; margin-bottom:18px; }
.ct-bar{
  height:4px; border-radius:4px; background:var(--surface-2);
  border:1px solid var(--line); overflow:hidden;
}
.ct-bar i{
  display:block; height:100%; width:20%;
  background:linear-gradient(90deg, var(--accent), var(--accent-2));
  transition:width .32s cubic-bezier(.4,0,.2,1);
}
.ct-marks{ display:flex; gap:6px; margin-top:9px; }
/* Les étapes à venir étaient à 45 % d'opacité, soit 2,65 de contraste : sous
   le seuil de 4,5, et sur un formulaire de vente — celui qui hésite entre deux
   étapes doit pouvoir LIRE laquelle vient après. À 70 % elles tiennent 4,80 et
   restent nettement en retrait de l'étape en cours, qui est en couleur et en
   gras. La hiérarchie ne vient pas de l'illisibilité. */
.ct-marks span{
  flex:1 1 0; font-size:10.5px; letter-spacing:.4px; text-transform:uppercase;
  color:var(--dim); opacity:.7; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.ct-marks span.done{ opacity:.85; }
.ct-marks span.now{ opacity:1; color:var(--accent); font-weight:700; }
@media (max-width:520px){
  /* Cinq libellés ne tiennent pas : seul celui de l'étape en cours reste. */
  .ct-marks span{ display:none; }
  .ct-marks span.now{ display:block; flex:1 1 auto; }
}

/* ---------------- étapes ---------------- */
.ct-step{ margin-bottom:14px; }
.ct-form.js .ct-step{ display:none; }
.ct-form.js .ct-step.on{ display:block; animation:ct-in .26s ease both; }
@keyframes ct-in{ from{ opacity:0; transform:translateY(8px); } to{ opacity:1; transform:none; } }

.ct-step .card > h2{
  display:flex; align-items:center; gap:10px;
  font-size:16px; color:var(--text); margin:0 0 5px;
}
.ct-step .ico{
  width:32px; height:32px; border-radius:9px; flex:none;
  display:flex; align-items:center; justify-content:center;
  background:var(--surface-2); border:1px solid var(--line); color:var(--accent);
}
.ct-step .ico svg{ width:17px; height:17px; }
.ct-step .card > .sub{ margin-bottom:20px; }

/* LA MENTION « OBLIGATOIRE » PASSE SOUS LE LIBELLÉ, ET LE LIBELLÉ NE SE COUPE
   PLUS. Posée à la suite, elle allongeait la ligne juste assez pour que « Ton
   adresse e-mail » se casse au trait d'union, et « obligatoire » se retrouvait
   seul à la ligne suivante, sous un mot orphelin. En dessous, elle tient dans
   toutes les colonnes et les trois champs s'alignent. */
.req{
  display:block;
  font-size:9.5px; letter-spacing:.5px; text-transform:uppercase; font-weight:700;
  color:var(--accent); margin-top:2px; opacity:.85;
}
/* « OPTIONNEL » PORTE LA MÊME PASTILLE, en gris. Deux raisons : le champ dit
   ce qu'il attend au même endroit que ses voisins, et surtout les libellés
   d'une rangée ont alors tous deux lignes. Sans elle, « Téléphone » n'en avait
   qu'une et son champ remontait de quatorze pixels au-dessus des deux autres.

   « facultatif » ET NON « opt » : cette classe-là est déjà celle des pastilles
   de choix, quinze lignes plus bas, et son « display:inline-flex » écrasait le
   « display:block » hérité de .req — même spécificité, donc c'est l'ordre
   d'écriture qui tranchait, et la mention repassait sur la ligne du libellé. */
.req.facultatif{ color:var(--dim); font-weight:600; }

/* Piège à robots : hors de l'écran plutôt que display:none, que les robots
   savent détecter. Un lecteur d'écran ne le rencontre pas non plus, le bloc
   étant marqué aria-hidden. */
.ct-hp{
  position:absolute; left:-9999px; top:auto; width:1px; height:1px;
  overflow:hidden; margin:0;
}

/* ---------------- pastilles de choix ---------------- */
.opts{ display:flex; flex-wrap:wrap; gap:8px; }
.opt{ display:inline-flex; position:relative; }
/* La case reste dans le flux du formulaire — elle est simplement invisible :
   la navigation au clavier et le remplissage automatique continuent d'agir. */
.opt input{ position:absolute; opacity:0; width:1px; height:1px; margin:0; pointer-events:none; }
.opt-box{
  display:inline-flex; align-items:center; gap:8px; cursor:pointer;
  background:var(--surface-2); border:1px solid var(--line); border-radius:11px;
  padding:9px 13px 9px 11px; font-size:13.5px; color:var(--text); line-height:1.25;
  /* 44 px : la cible tactile minimale, celle d'un pouce d'adulte. Le rembourrage
     seul donnait 37 px — assez pour la souris, pas pour un doigt sur un
     téléphone, et ce formulaire se remplit surtout sur un téléphone.
     min-height plutôt qu'une hauteur fixe : une pastille dont le texte passe à
     la ligne — « poids du corps uniquement » sur un écran étroit — doit pouvoir
     grandir au lieu de déborder. */
  min-height:44px;
  transition:border-color .15s, background .15s, transform .1s;
  /* .field label impose des capitales aux etiquettes de champ, et une pastille
     est un <label> : sans cela « poids du corps uniquement » s'affiche en
     capitales ici et en minuscules dans le recapitulatif. */
  text-transform:none; letter-spacing:0;
}
/* Le survol ECLAIRE la bordure d'un cran au-dessus de --line (la base) —
   melange sur palette, plus un hex de la peau sombre en repli sans color-mix. */
.opt-box:hover{
  border-color:#3a4557;
  border-color:color-mix(in srgb, var(--line) 55%, var(--text));
}
.opt-box:active{ transform:scale(.98); }
.opt-tick{
  width:16px; height:16px; border-radius:5px; flex:none;
  border:1.5px solid var(--line); background:var(--bg);
  display:inline-flex; align-items:center; justify-content:center;
}
.opt-tick::after{
  content:""; width:8px; height:4px; margin-top:-2px;
  border-left:2px solid var(--sur-acc, #000814); border-bottom:2px solid var(--sur-acc, #000814);
  transform:rotate(-45deg) scale(.4); opacity:0; transition:transform .16s, opacity .12s;
}
.opt input:checked + .opt-box{
  border-color:var(--accent); background:rgba(34,211,238,.09); color:var(--text);
}
.opt input:checked + .opt-box .opt-tick{ background:var(--accent); border-color:var(--accent); }
.opt input:checked + .opt-box .opt-tick::after{ transform:rotate(-45deg) scale(1); opacity:1; }
.opt input:focus-visible + .opt-box{ outline:2px solid var(--accent); outline-offset:2px; }
/* Choix exclusif : la pastille ronde annonce qu'un seul est possible. */
.opt.one .opt-tick{ border-radius:50%; }
.opt.one .opt-tick::after{
  content:""; width:7px; height:7px; margin:0; border:none; border-radius:50%;
  background:var(--sur-acc, #000814); transform:scale(.3);
}
.opt.one input:checked + .opt-box .opt-tick::after{ transform:scale(1); }

/* Groupes de matériel */
.opt-group + .opt-group{ margin-top:16px; }
.opt-group > h3{
  font-size:10.5px; text-transform:uppercase; letter-spacing:.7px; color:var(--dim);
  font-weight:700; margin:0 0 9px;
}

/* ---------------- segments ---------------- */
.seg{
  display:flex; flex-wrap:wrap; gap:6px;
  background:var(--surface-2); border:1px solid var(--line);
  border-radius:12px; padding:5px;
}
.seg .opt{ flex:1 1 auto; }
.seg .opt-box{
  width:100%; justify-content:center; background:transparent; border-color:transparent;
  padding:9px 10px; font-size:13.5px; font-weight:600; color:var(--dim);
  border-radius:8px; text-align:center;
}
.seg .opt-box:hover{ border-color:transparent; color:var(--text); }
.seg .opt-tick{ display:none; }
.seg .opt input:checked + .opt-box{
  background:linear-gradient(135deg, var(--accent), var(--accent-2));
  color:var(--sur-acc, #000814); border-color:transparent;
}

/* ---------------- jours ---------------- */
.days{ display:flex; gap:7px; flex-wrap:wrap; }
.days .opt{ flex:1 1 40px; }
.days .opt-box{
  width:100%; justify-content:center; padding:0; height:46px; border-radius:12px;
  font-size:13px; font-weight:700; letter-spacing:.3px; color:var(--dim);
}
.days .opt-tick{ display:none; }
.days .opt input:checked + .opt-box{
  color:var(--sur-acc, #000814); border-color:transparent;
  background:linear-gradient(135deg, var(--accent), var(--accent-2));
}

/* ---------------- récapitulatif ---------------- */
.ct-recap{
  border:1px solid var(--line); border-radius:12px; background:var(--surface-2);
  padding:4px 14px; margin:0 0 18px;
}
.ct-recap dl{ margin:0; }
.ct-recap div{
  display:flex; gap:12px; padding:9px 0; border-bottom:1px solid var(--line);
  font-size:12.5px; line-height:1.5;
}
.ct-recap div:last-child{ border-bottom:none; }
.ct-recap dt{ color:var(--dim); flex:0 0 34%; }
.ct-recap dd{ margin:0; color:var(--text); flex:1 1 auto; }

/* ---------------- consentement et envoi ---------------- */
.ct-consent{
  display:flex; gap:11px; align-items:flex-start;
  border:1px solid var(--line); border-radius:12px; background:var(--surface-2);
  padding:14px; margin:6px 0 16px;
}
/* La case reste à 18 px, et c'est volontaire : ce n'est pas elle qu'on vise.
   Le <label for="ct-consent"> à côté mesure 73 px de haut sur toute la largeur
   de la carte, et cocher la case revient à toucher le texte — une cible bien
   plus généreuse que les 44 px recommandés.
   Une tentative d'agrandir la case elle-même par un ::after a été retirée : les
   pseudo-éléments ne sont pas garantis d'être peints sur un <input>, qui est un
   élément remplacé. Un agrandissement qui dépend du navigateur ne vaut rien. */
.ct-consent input{ width:18px; height:18px; flex:none; margin-top:1px; accent-color:var(--accent); }
.ct-consent span{ font-size:12.5px; line-height:1.55; color:var(--dim); }
.ct-consent label{ cursor:pointer; }
.ct-consent a{ color:var(--accent); }
.ct-consent.on{ border-color:var(--accent); }

.ct-nav{ display:none; gap:9px; margin-top:14px; }
.ct-form.js .ct-nav{ display:flex; }
/* .btn est declare width:100% : sans width:auto, « Retour » occuperait toute la
   ligne et pèserait autant que le bouton d'action. */
.ct-nav .btn{ flex:1 1 auto; width:auto; }
.ct-nav .btn.secondary{ flex:0 0 auto; padding-left:22px; padding-right:22px; }
/* .btn se déclare display:inline-block, ce qui l'emporterait sur le display:none
   que le navigateur associe à l'attribut hidden : sans ceci, masquer un bouton
   de navigation resterait sans effet. */
.ct-nav .btn[hidden]{ display:none; }

/* Un envoi qui n'a pas l'air d'être parti se fait envoyer deux fois. */
.btn[aria-busy="true"]{ opacity:.65; pointer-events:none; }

.ct-err{
  font-size:12px; color:var(--danger); margin:8px 0 0; min-height:0;
}
.ct-err:empty{ display:none; }
.field input.bad, .field textarea.bad{ border-color:var(--danger); }

/* ---------------- confirmation ---------------- */
.ct-done{ text-align:center; padding:14px 4px 6px; }
.ct-done .seal{
  width:66px; height:66px; margin:0 auto 18px; border-radius:50%;
  display:flex; align-items:center; justify-content:center;
  background:rgba(73,183,131,.12); border:1px solid #265741; color:var(--success);
  animation:ct-pop .4s cubic-bezier(.2,1.4,.5,1) both;
}
.ct-done .seal svg{ width:30px; height:30px; }
@keyframes ct-pop{ from{ transform:scale(.6); opacity:0; } to{ transform:scale(1); opacity:1; } }
.ct-done h1{ font-size:21px; margin:0 0 9px; font-weight:800; }
.ct-done p{ font-size:13.5px; line-height:1.65; color:var(--dim); margin:0 auto 8px; max-width:46ch; }
/* Le conseil sur les indésirables : détaché du reste, sans être une alarme.
   Le liseré d'accent le distingue des deux phrases qui le précèdent — c'est le
   seul endroit du site où l'on demande quelque chose au visiteur. Les couleurs
   passent par color-mix pour suivre le mode clair comme le mode sombre. */
.ct-done .ct-spam{
  margin-top:14px; padding:11px 14px; text-align:left;
  font-size:12.5px; line-height:1.6;
  background:color-mix(in srgb, var(--acc) 7%, transparent);
  border:1px solid color-mix(in srgb, var(--acc) 24%, transparent);
  border-radius:10px;
}
.ct-done .btn{ margin-top:16px; width:auto; }

/* ---------------- l'option de suivi ---------------- */
/* La case, le nom et le prix sur une seule ligne, cliquable en entier : sur un
   téléphone, viser une case de 16 px est une punition. Le libellé porte la
   cible, qui fait toute la hauteur de la ligne. */
.ct-option{ margin:0 0 14px; }
.ct-option-tete{
  display:flex; align-items:center; gap:10px; cursor:pointer;
  min-height:44px; margin:0;
}
.ct-option-tete input{ width:19px; height:19px; accent-color:var(--acc); flex:none; }
.ct-option-nom{ font-size:14.5px; font-weight:700; flex:1; }
.ct-option-prix{ font-size:15px; font-weight:800; color:var(--acc); white-space:nowrap; }
/* « / 4 semaines », en retrait du montant. Sans cette mention le supplement se
   lit comme le prix du cycle entier, et le total du recapitulatif juste en
   dessous parait alors sorti de nulle part. */
.ct-option-par{ font-size:12px; font-weight:600; color:var(--dim); }
.ct-option-texte{ margin:8px 0 0; font-size:13px; line-height:1.6; color:var(--dim); }

/* ---------------- le prix, avant le bouton ---------------- */
/* Le montant est ce que le visiteur cherche des yeux à cette étape : il est
   donc le seul élément gras et le seul en couleur d'accent. Le nom du palier,
   l'explication et les deux notes descendent en taille dans cet ordre — la
   hiérarchie visuelle raconte la même chose que le texte. */
.ct-prix{ margin:0 0 18px; }
.ct-prix-tete{
  display:flex; align-items:baseline; justify-content:space-between;
  gap:12px; flex-wrap:wrap; margin-bottom:8px;
}
.ct-prix-nom{
  font-size:12px; font-weight:700; letter-spacing:.08em; text-transform:uppercase;
  color:var(--dim);
}
.ct-prix-montant{ font-size:27px; font-weight:800; color:var(--acc); line-height:1.1; }
/* Le détail « palier + option » : présent uniquement quand il y a deux lignes à
   additionner, et volontairement discret — c'est une vérification, pas
   l'information principale. */
.ct-prix-detail{ margin:0 0 8px; font-size:12.5px; color:var(--dim); }
.ct-prix-motif{ margin:0 0 10px; font-size:13.5px; line-height:1.6; color:var(--text); }
.ct-prix-note{ margin:0 0 6px; font-size:12.5px; line-height:1.6; color:var(--dim); }
.ct-prix-note:last-child{ margin-bottom:0; }

/* ---------------- retour sans avoir payé ---------------- */
/* Ni une erreur ni une alerte : rien de fâcheux n'est arrivé. Le liseré
   d'accent le distingue du formulaire qui suit, sans couleur d'alarme. */
.ct-reprise{
  margin:0 0 18px;
  border-color:color-mix(in srgb, var(--acc) 30%, var(--line));
}
.ct-reprise h2{ font-size:17px; margin:0 0 8px; font-weight:800; }
.ct-reprise p{ font-size:13.5px; line-height:1.65; color:var(--dim); margin:0 0 14px; max-width:52ch; }

@media (prefers-reduced-motion:reduce){
  .ct-form.js .ct-step.on, .ct-done .seal{ animation:none; }
  .ct-bar i{ transition:none; }
  .opt-box, .opt-tick::after{ transition:none; }
}
