/*
  Feuille de style unique, écrite à la main.

  L'ancien site chargeait Bootstrap 4, jQuery et dix greffons — 2,19 Mo pour
  deux sections. Ce fichier fait quelques kilo-octets et ne dépend de rien.
  Aucune dépendance à mettre à jour, aucune CVE à suivre, aucun élagage à faire.

  Le vert de marque #18d26e est conservé, mais jamais sous du texte blanc : le
  contraste n'y est que de 2:1, sous le seuil AA de 4,5. Deux déclinaisons le
  remplacent selon l'usage — voir --accent-texte.
*/

:root {
  /* CE QUE LE NAVIGATEUR DESSINE LUI-MÊME suit cette déclaration, et rien
     d'autre : la liste déroulante OUVERTE d'un « select », la case à cocher, le
     bouton « Parcourir » d'un champ de fichier, les barres de défilement, le
     curseur de saisie. Aucune règle CSS ne les atteint, parce qu'ils sont
     rendus par le système et non par la page.
     Sans elle, un formulaire sombre ouvrait un menu BLANC en plein milieu.
     Relevé par le dirigeant le 2026-09-05 sur la page d'inscription.
     Le site n'a pas de bascule de thème : « dark » seul, pas « dark light ». */
  color-scheme: dark;

  /* Signature graphique de la marque : SOMBRE, comme le site historique.
     Une première version passait au clair — c'était changer l'identité, pas
     la moderniser. Le fond sombre et le vert #18d26e restent ; seuls les
     contrastes fautifs de l'ancien site sont corrigés. */
  --encre: #e9edf2;           /* texte principal, sur fond sombre */
  --encre-douce: #9fb0c0;
  --papier: #0d1117;          /* fond de page */
  --papier-doux: #141b23;     /* surfaces posées SUR la page : sections, pied */
  --papier-releve: #1a222c;   /* surfaces posées sur une surface : cartes.
                                 En interface sombre, ce qui avance s'éclaircit
                                 — les cartes étaient en --papier, plus sombres
                                 que la section qui les porte : le relief était
                                 inversé. */
  --trait: #26303c;

  /* LES CHAMPS ONT LEUR PROPRE TRAIT, plus clair, et c'est structurel : un
     champ de saisie porte le fond de la PAGE, donc rien ne l'en distingue par
     l'aplat : sa BORDURE est la seule chose qui dise où il commence.
     La WCAG 1.4.11 exige 3:1 pour ce qui identifie un composant ; « --trait »
     est à 1,4:1, ce qui convient parfaitement à un filet de séparation et pas
     du tout à un champ.

     Pourquoi #64748b et pas plus sombre : le site a TROIS fonds, et la bordure
     doit tenir sur les trois. Le candidat #5c6b7b passait sur la page (3,46) et
     sur les sections (3,17) mais tombait à 2,94 sur « --papier-releve », le
     fond des cartes. Relevé par le dirigeant, qui a demandé pourquoi ne pas prendre la
     valeur avec de la marge.
       page #0d1117 → 3,98:1 · section #141b23 → 3,64:1 · carte #1a222c → 3,37:1 */
  --trait-champ: #64748b;

  /* Le texte d'erreur : #ff8a80, 8,29:1 sur la page, 7,03:1 sur une carte.
     L'ancien #b3261e ne donnait que 2,90:1 sur la page. */
  --erreur: #ff8a80;

  --accent: #18d26e;          /* aplats : fond vert, texte ENCRE SOMBRE (9:1) —
                                 jamais blanc sur vert, qui donnait 2:1 */
  --accent-texte: #3ee88a;    /* le vert EN TEXTE sur fond sombre : 9,8:1 */
  --accent-sombre: #13a456;

  --mesure: 68ch;
  --rayon: 6px;
  --pas: clamp(1rem, 2vw, 1.5rem);

  --police: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto,
            "Helvetica Neue", Arial, sans-serif;
  --police-titre: var(--police);
}

*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  font-family: var(--police);
  font-size: 1.0625rem;
  line-height: 1.65;
  color: var(--encre);
  background: var(--papier);
  -webkit-text-size-adjust: 100%;
}

h1, h2, h3 {
  font-family: var(--police-titre);
  line-height: 1.2;
  letter-spacing: -0.02em;
  text-wrap: balance;
  margin: 0 0 0.5em;
}

h1 { font-size: clamp(2rem, 5vw, 3.25rem); font-weight: 800; }
h2 { font-size: clamp(1.5rem, 3vw, 2.125rem); font-weight: 700; }
h3 { font-size: 1.1875rem; font-weight: 650; }

p { margin: 0 0 1em; max-width: var(--mesure); text-wrap: pretty; }

a { color: var(--accent-texte); text-underline-offset: 0.2em; }
a:hover { color: var(--accent-sombre); }

/* Un anneau de focus visible partout : c'est ce qui rend le site utilisable
   au clavier. Le supprimer pour l'esthétique est la faute d'accessibilité la
   plus répandue. */
:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 2px;
  border-radius: 2px;
}

.contenant {
  width: min(100% - 2.5rem, 1120px);
  margin-inline: auto;
}

.lien-evitement {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  padding: 0.75rem 1.25rem;
  background: var(--accent);
  color: #0d1117;
  font-weight: 650;
  text-decoration: none;
}
.lien-evitement:focus { left: 0; }

/* --- En-tête ------------------------------------------------------------- */

/* Défilement animé vers les ancres de la page unique ; coupé pour qui
   préfère réduire le mouvement. L'en-tête est collant : chaque cible de
   défilement s'en décale pour ne pas arriver masquée dessous. */
html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}
[id] { scroll-margin-top: 5.5rem; }

.entete {
  border-bottom: 1px solid var(--trait);
  background: var(--papier);
  position: sticky;
  top: 0;
  z-index: 10;
}

.entete__interieur {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  min-height: 4.5rem;
  flex-wrap: wrap;
}

.marque { text-decoration: none; color: var(--encre); }
.marque__nom {
  font-weight: 800;
  font-size: 1.25rem;
  letter-spacing: -0.03em;
  border-left: 4px solid var(--accent);
  padding-left: 0.6rem;
}

.nav {
  display: flex;
  align-items: center;
  gap: clamp(0.75rem, 2vw, 1.5rem);
  flex-wrap: wrap;
}
.nav a {
  color: var(--encre-douce);
  text-decoration: none;
  font-size: 0.9375rem;
  font-weight: 550;
  padding: 0.35rem 0;
}
.nav a:hover { color: var(--encre); }
.nav a[aria-current="page"] {
  color: var(--encre);
  box-shadow: inset 0 -2px 0 var(--accent);
}

.nav__action {
  background: var(--accent);
  color: #0d1117 !important;
  padding: 0.5rem 1rem !important;
  border-radius: var(--rayon);
  font-weight: 650;
}
.nav__action:hover { background: var(--accent-sombre); }

.nav__langue {
  border: 1px solid var(--trait);
  border-radius: var(--rayon);
  padding: 0.35rem 0.6rem !important;
  font-weight: 650;
}

/* --- Sections ------------------------------------------------------------ */

.section { padding-block: clamp(3rem, 7vw, 5.5rem); }
.section--doux { background: var(--papier-doux); }
.section__intro { max-width: var(--mesure); }

/* Les photos du carrousel historique, en fondu enchaîné sans JavaScript.
   Voile ≥ 0,80 : en dessous, les zones claires des photos font passer le
   texte sous le seuil AA de 4,5:1. Le bas est plus opaque pour fondre dans
   --papier, la section suivante commence sans couture. */
.heros {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  padding-block: clamp(3.5rem, 9vw, 7rem);
}
.heros::before,
.heros::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background-position: center;
  background-size: cover;
}
.heros::before {
  background-image:
    linear-gradient(rgba(13, 17, 23, 0.8), rgba(13, 17, 23, 0.96)),
    url("../img/heros.056acce6fded.webp");
}
.heros::after {
  background-image:
    linear-gradient(rgba(13, 17, 23, 0.8), rgba(13, 17, 23, 0.96)),
    url("../img/heros-2.b977118b812f.webp");
  opacity: 0;
  animation: heros-fondu 18s ease-in-out infinite;
}
@keyframes heros-fondu {
  0%, 42% { opacity: 0; }
  50%, 92% { opacity: 1; }
  100% { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .heros::after { animation: none; }
}

/* Bandeaux d'entrée de page : les autres photos de l'ancien site, sous le
   même voile que le héros. La carte du monde est presque blanche : elle
   exige le voile le plus opaque. */
.bandeau {
  padding-block: clamp(2.5rem, 6vw, 4.5rem);
  background-position: center;
  background-size: cover;
}
.bandeau--monde {
  background-image:
    linear-gradient(rgba(13, 17, 23, 0.88), rgba(13, 17, 23, 0.97)),
    url("../img/monde.0e177f9dd180.webp");
}
/* Sans porteur depuis le retrait du bandeau de chiffres. Conservée : les cinq
   photos couvrent les entrées de page, et la prochaine section qui en demande
   une trouvera celle-ci prête. */
.bandeau--ville {
  background-image:
    linear-gradient(rgba(13, 17, 23, 0.84), rgba(13, 17, 23, 0.96)),
    url("../img/ville.a029c81f5150.webp");
}
/* 0,82 et non 0,72 : la règle est écrite trois commentaires plus haut — voile
   ≥ 0,80 — et ce bandeau seul y dérogeait. Sur une zone claire de la photo,
   .heros__sous et .mandat__meta (--encre-douce) tombaient à 3,42:1, sous le
   seuil AA de 4,5 pour du texte normal. Ce bandeau porte le sous-titre de
   Postuler, de Nous joindre, de Merci et de Candidature reçue : quatre pages
   où l'on demande quelque chose au visiteur. À 0,82, le rapport passe à
   4,98:1 dans le pire cas, photo blanche. */
.bandeau--action {
  background-image:
    linear-gradient(rgba(13, 17, 23, 0.82), rgba(13, 17, 23, 0.95)),
    url("../img/action.bbf67eafe7ec.webp");
}
.bandeau--plans {
  background-image:
    linear-gradient(rgba(13, 17, 23, 0.86), rgba(13, 17, 23, 0.96)),
    url("../img/heros.056acce6fded.webp");
}
.bandeau--croquis {
  background-image:
    linear-gradient(rgba(13, 17, 23, 0.82), rgba(13, 17, 23, 0.96)),
    url("../img/heros-2.b977118b812f.webp");
}
.heros h1 { max-width: 20ch; }
.heros__sous {
  font-size: clamp(1.0625rem, 2vw, 1.3125rem);
  color: var(--encre-douce);
  max-width: 58ch;
}

.actions { display: flex; gap: 0.875rem; flex-wrap: wrap; margin-top: 2rem; }

.bouton {
  display: inline-block;
  padding: 0.75rem 1.5rem;
  border-radius: var(--rayon);
  font-weight: 650;
  text-decoration: none;
  border: 1px solid transparent;
  cursor: pointer;
  font-size: 1rem;
  font-family: inherit;
}
/* Encre sur vert : 9,4:1. Blanc sur vert n'aurait donné que 2:1. */
/* Texte SOMBRE sur le vert : #0d1117 sur #18d26e = 9:1. */
.bouton--principal { background: var(--accent); color: #0d1117; }
.bouton--principal:hover { background: var(--accent-sombre); color: #0d1117; }
.bouton--discret { border-color: var(--trait); color: var(--encre); }
.bouton--discret:hover { border-color: var(--encre-douce); color: var(--encre); }
/* Cette marge vivait dans un attribut style= sur les deux boutons d'envoi. La
   CSP ne porte pas 'unsafe-inline' sur style-src — et un nonce ne couvre pas
   les attributs style, seulement les balises <style> — donc le navigateur la
   rejetait : le bouton restait collé au widget Turnstile. La règle appartient
   ici. Ne jamais résoudre ça par 'unsafe-hashes' ni 'unsafe-inline'. */
.bouton--soumettre { margin-top: 1.25rem; }

.grille {
  display: grid;
  gap: clamp(1.25rem, 3vw, 2rem);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
  margin-top: 2.5rem;
}

.carte {
  padding: 1.5rem;
  border: 1px solid var(--trait);
  border-radius: var(--rayon);
  background: var(--papier-releve);
}
.carte h3 { margin-bottom: 0.4rem; }
.carte p { margin-bottom: 0; color: var(--encre-douce); font-size: 0.9688rem; }

.etiquettes { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 1rem; padding: 0; list-style: none; }
.etiquettes li {
  font-size: 0.8125rem;
  padding: 0.2rem 0.6rem;
  border-radius: 999px;
  background: var(--papier-doux);
  border: 1px solid var(--trait);
  color: var(--encre-douce);
}

.conviction { border-top: 1px solid var(--trait); padding-top: 1.75rem; margin-top: 1.75rem; }
.conviction:first-of-type { border-top: 0; }

.mandat { border: 1px solid var(--trait); border-radius: var(--rayon); padding: 1.5rem; }
.mandat__meta { color: var(--encre-douce); font-size: 0.9375rem; margin-bottom: 0.75rem; }
.mandat--clos { background: var(--papier-doux); }
/* Le mandat clos le dit avant ses conditions : sans marque, la phrase se lit
   comme une ligne de plus et le lecteur clique « candidature spontanée » sans
   savoir pourquoi le bouton a changé. */
.mandat__clos { border-left: 3px solid var(--encre-douce); padding-left: 0.75rem; margin-bottom: 1rem; }

/* Le panneau de faits d'un mandat : les paires terme-valeur qui font décider,
   avant la prose. L'échéance vient en premier — c'est sur elle qu'un
   consultant arbitre. */
.mandat__faits {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 2.5rem;
  margin: 1.25rem 0 0.5rem;
}
.mandat__faits dt {
  color: var(--encre-douce);
  font-size: 0.8125rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.mandat__faits dd { margin: 0.15rem 0 0; font-weight: 600; }

/* --- Formulaire ---------------------------------------------------------- */

.champ { margin-bottom: 1.25rem; max-width: 34rem; }
.porte-code { display: grid; gap: 2rem; max-width: 34rem; }
.porte-code .champ { margin-bottom: 1rem; }
.porte-code > p { margin: 0; }
.champ label { display: block; font-weight: 600; margin-bottom: 0.3rem; font-size: 0.9375rem; }
/* La pleine largeur ne vaut que pour ce qui se remplit au clavier. Sans
   l'exclusion, « .champ input » attrapait aussi les boutons radio et la case
   à cocher : le point s'étirait sur toute la largeur du formulaire, et son
   libellé tombait dessous. Cliquable, mais sur une annonce publique ça a
   l'air d'un formulaire cassé. */
.champ input:not([type="radio"]):not([type="checkbox"]), .champ textarea, .champ select {
  width: 100%;
  padding: 0.65rem 0.75rem;
  border: 1px solid var(--trait-champ);
  border-radius: var(--rayon);
  font: inherit;
  color: inherit;
  background: var(--papier);
}
.champ input:focus, .champ textarea:focus, .champ select:focus { border-color: var(--accent-texte); }

/* Point de radio et case à cocher : taille propre, libellé à leur DROITE.
   Le libellé qui ENTOURE un champ (ce que produit RadioSelect) n'est pas le
   libellé du bloc : il ne doit être ni gras ni en bloc, sinon le texte passe
   sous le point. */
.champ input[type="radio"], .champ input[type="checkbox"] {
  width: auto;
  margin: 0;
  flex: none;
}
.champ label:has(input) {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-weight: 400;
  margin-bottom: 0.35rem;
}

/* Un critère, ou une question à réponses fermées : un groupe que le lecteur
   d'écran annonce par sa légende. Le cadre par défaut du navigateur suffit ;
   on n'ajoute que l'espace et le poids de la légende. */
.groupe { border: 1px solid var(--trait-champ); border-radius: var(--rayon); padding: 1rem 1.25rem; margin: 0 0 1.5rem; max-width: 36rem; }
.groupe legend { font-weight: 700; padding: 0 0.4rem; }
.groupe--choix { border: 0; padding: 0; }
.groupe--choix legend { padding: 0; margin-bottom: 0.3rem; font-size: 0.9375rem; }
.groupe__enonce { margin: 0 0 1rem; }

.erreurs { color: var(--erreur); font-size: 0.9063rem; margin: 0.3rem 0 0; }
.erreurs ul { margin: 0; padding-left: 1.1rem; }

/* Le récapitulatif en tête d'un formulaire en erreur. */
.recapitulatif { border: 2px solid var(--erreur); border-radius: var(--rayon); padding: 0.75rem 1.25rem; margin: 0 0 1.5rem; max-width: 36rem; }
.recapitulatif:focus { outline: 3px solid var(--erreur); outline-offset: 3px; }
.recapitulatif h2 { margin: 0 0 0.5rem; font-size: 1.125rem; color: var(--erreur); }
.recapitulatif ul { margin: 0; padding-left: 1.1rem; }

/* Leurre anti-robot : hors écran plutôt que display:none, que les robots
   sérieux savent lire pour sauter le piège. Hors tabulation via le HTML. */
/* Le leurre, étiquette comprise : hors écran plutôt que display:none, que les
   robots sérieux lisent pour sauter le piège. Il reste dans l'arbre
   d'accessibilité — c'est voulu depuis qu'il porte une étiquette qui dit de le
   laisser vide. */
.leurre {
  position: absolute !important;
  left: -5000px !important;
  width: 1px !important;
  height: 1px !important;
  overflow: hidden !important;
  opacity: 0 !important;
}

/* --- Pied ---------------------------------------------------------------- */

.pied {
  border-top: 1px solid var(--trait);
  background: var(--papier-doux);
  padding-block: 2.5rem;
  margin-top: 4rem;
  font-size: 0.9375rem;
}
.pied__interieur {
  display: flex;
  gap: 2rem;
  justify-content: space-between;
  flex-wrap: wrap;
}
.pied__marque { font-weight: 800; margin: 0; }
.pied__note { color: var(--encre-douce); margin: 0.2rem 0 0; }
.pied nav { display: flex; flex-direction: column; gap: 0.35rem; }
.pied a { color: var(--encre-douce); }
.pied a:hover { color: var(--accent-texte); }

/* --- Préférences du visiteur --------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}

/* Pas de bascule claire/sombre : le sombre EST la signature de la marque,
   comme sur le site historique. */


/* --- Impression -----------------------------------------------------------
   Les gens de l'approvisionnement impriment : un mandat part en PDF dans un
   dossier de soumission, une politique de confidentialité s'annexe. Sans cette
   feuille, le fond #0d1117 s'imprime en aplat noir — quand le navigateur ne
   supprime pas les fonds, auquel cas c'est le texte clair qui disparaît sur du
   blanc. Le sombre est la signature à l'écran, pas sur papier.
   -------------------------------------------------------------------------- */

@media print {
  :root {
    --encre: #000;
    --encre-douce: #333;
    --papier: #fff;
    --papier-doux: #fff;
    --papier-releve: #fff;
    --trait: #999;
    --accent-texte: #000;
  }

  body { background: #fff; color: #000; font-size: 11pt; }

  /* Navigation, pied, boutons et widgets n'existent pas sur papier : ils
     prennent la place du contenu qu'on imprime. */
  .entete, .pied, .lien-evitement, .actions, .cf-turnstile {
    display: none !important;
  }

  /* Les photos de fond passent par ::before/::after sur le héros et par
     background-image sur les bandeaux : les deux chemins doivent tomber. */
  .heros::before, .heros::after { display: none !important; }
  .bandeau, .heros { background-image: none !important; padding-block: 0.5rem; }
  .section { padding-block: 0.5rem; }
  .contenant { max-width: none; padding: 0; }

  a { color: #000; text-decoration: underline; }
  /* L'adresse derrière un lien se perd à l'impression. On l'écrit. */
  main a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 9pt; }

  h1, h2, h3 { page-break-after: avoid; }
  .mandat, .carte, .etiquettes { page-break-inside: avoid; }
}

.facultatif { font-weight: 400; color: var(--encre-douce); }
.cf-turnstile { margin-top: 1rem; }

/* --- Produits, dans le pied ----------------------------------------------
   Nos propres logiciels : une mention en pied, pas une section. Leur acheteur
   n'arrive pas par ce site — ils figurent ici parce qu'ils se vérifient en un
   clic, ce qu'aucune conviction ne fait. */
.pied__produits img {
  display: block;
  height: 2.25rem;
  width: auto;
  margin: 0.5rem 0 0.45rem;
}

/* --- Candidature spontanée -----------------------------------------------
   Toujours présente sur la liste des mandats, y compris quand des mandats
   sont ouverts : un consultant qui n'écrit qu'en voyant l'annonce qui lui va
   arrive après la clôture. Séparée par un filet plutôt que par une carte —
   c'est une porte de sortie, pas une offre de plus. */
.sourcing {
  margin-top: 2.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--trait);
}

/* Aperçu administrateur du formulaire de documents : rien ne s'envoie. */
.apercu {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.25rem;
  align-items: baseline;
  padding: 0.75rem var(--pas);
  background: var(--encre);
  color: var(--papier);
  font-weight: 600;
}
.apercu a { color: var(--papier); }
.apercu a[aria-current="true"] { text-decoration: none; }
.apercu button:disabled, .bouton--soumettre:disabled { opacity: 0.5; cursor: not-allowed; }

/* « Non » à la question des autres contrats : le bloc des contrats sort de la page, et de
   l'arbre d'accessibilité. Sans JavaScript ; « Oui » ou pas de réponse le laissent visible. */
form:has(input[name$="-reponse"][value="non"]:checked) .autres-contrats__contrats { display: none; }
