/* ============================================================================
   SAMKO ACADEMY : systeme de design
   ----------------------------------------------------------------------------
   Deux sources, et une seule d'entre elles est negociable.

   LA PALETTE vient de la charte graphique SAMKO Group V1.0 (avril 2026,
   validee par Massaoule SAMAKE). Elle n'est pas negociable : SK-Bleu-Nuit
   #1A3A5C, SK-Bleu-Ciel #3AABDB, SK-Bleu-Intersection #2B7FA8, Gris-Acier
   #5A6B7A, Or #D4A017, et les quatre couleurs fonctionnelles.
   L'entite ACADEMY a pour couleur d'accroche le DEGRADE bleu ciel vers bleu
   nuit : c'est ce qui la distingue d'Audit & Conseil (nuit dominant) et de
   Consulting (ciel dominant).

   LA STRUCTURE vient de recrutement.samko.group, la plateforme publique SAMKO
   deja en ligne. Reprendre son squelette n'est pas de la paresse : c'est ce
   qui fait que les deux sites se ressemblent, et ses trois partis pris ont ete
   ecrits en reponse a des reproches deja formules.

   TROIS REGLES QUI NE SE DISCUTENT PAS.

   1. LE SOL EST CLAIR. La charte l'ecrit noir sur blanc : « pas de fond de
      page colore, les couleurs uniquement sur les elements ». Le bleu nuit est
      un ACCENT, employe sur le hero, une bande de rappel et le pied. Un site
      de formation entierement sombre fatigue sur une session de deux heures et
      ne ressemble a aucun document SAMKO.

   2. UN ELEMENT QUI PORTE UN FOND NE PORTE JAMAIS DE LARGEUR MAXIMALE. C'est
      la regle qui supprime l'impression d'ilot centre sur un grand ecran. Le
      fond va d'un bord a l'autre de la vitre ; seul son CONTENU est bride par
      .laize. Une laize de 1080 sur une vitre de 1920 laisse 420 px de vide de
      chaque cote, et le site a l'air d'avoir ete centre par accident.

   3. LE TEXTE GRANDIT AVEC L'ECRAN. Elargir la boite sans grossir le corps ne
      fait qu'etaler du petit texte. La racine passe de 16 px a 18 px entre
      1280 et 1920, et tout le reste etant en rem, la page entiere grandit de
      12,5 pour cent.

   ⛔ Ne jamais poser overflow-x: hidden sur body. Un overflow autre que
   visible sur un ancetre fait de l'element un conteneur de defilement et tue
   SILENCIEUSEMENT tous les position: sticky de la page. Le debordement se
   traite a la source ; le hero porte overflow: clip en local (clip, pas
   hidden : clip ne cree pas de conteneur de defilement).
   ========================================================================= */

:root {
  /* ---- palette officielle SAMKO ---- */
  --nuit:          #1A3A5C;   /* SK-Bleu-Nuit    : H1, bandes, pied */
  --nuit-profond:  #12293F;   /* assombrissement du nuit, pour les degrades */
  --nuit-surface:  #234B75;   /* survol sur fond nuit */
  --ciel:          #3AABDB;   /* SK-Bleu-Ciel    : H2, accents, liens actifs */
  --inter:         #2B7FA8;   /* SK-Bleu-Inters. : bordures, separateurs */
  /* La MEME couleur, assombrie juste ce qu'il faut pour passer le seuil de
     contraste quand elle porte du TEXTE. La charte destine --inter aux
     bordures et aux separateurs, ou le seuil est de 3 ; le site l'employait
     aussi pour les surtitres, les etiquettes et les intertitres, ou il est de
     4,5. #2B7FA8 y rendait 4,46 sur blanc, 4,26 sur le papier et 4,00 sur le
     bleu voile : sous le seuil sur LES TROIS fonds clairs du site, d'un
     cheveu, donc invisible a l'oeil et systematique. #26739A rend 5,25, 5,01
     et 4,70, pour un ecart de teinte que l'on ne distingue pas. */
  --inter-texte:   #26739A;
  --wordmark:      #2D6FA8;   /* SK-Bleu-Wordmark: H3, liens */
  --or:            #D4A017;   /* Or accent       : mise en valeur, filets */
  --or-doux:       #E3B94A;
  /* Les deux emplois transparents de l'or. Ils etaient ecrits en rgba() en dur
     dans le bloc de style de l'accueil, seules couleurs du projet a vivre hors
     de cette palette : le jour ou l'or change, elles ne suivaient pas. */
  --or-filet:      rgba(212, 160, 23, .55);   /* le filet de tete du heros */
  --or-voile:      rgba(212, 160, 23, .08);   /* le fond d'une cellule saisie */

  /* ---- fonds ---- */
  --blanc:         #FFFFFF;
  --papier:        #F8FAFB;   /* blanc casse de la charte */
  --bleu-voile:    #EBF5FB;   /* bleu ciel tres leger, alternance et callouts */

  /* ---- encres ---- */
  --encre:         #2C2C2C;   /* quasi-noir, corps de texte */
  --encre-douce:   #44515E;
  --acier:         #5A6B7A;   /* SK-Gris-Acier : legendes, mentions */
  --filet:         #DDE5EA;
  --filet-fort:    #C3D0D9;
  --sur-nuit:      rgba(255, 255, 255, .80);
  --sur-nuit-fort: #F2F8FC;

  /* ---- couleurs fonctionnelles ---- */
  --succes:        #1E7C3A;  --succes-voile: #E2EFDA;
  --attention:     #C8580A;  --attention-voile: #FFF8E7;
  --critique:      #C00000;  --critique-voile: #FCE4D6;

  /* ---- mesures ---- */
  /* LA LAIZE EST FLUIDE, PAS PLAFONNEE SEC.
     Un plafond fixe a 1440 laisse 280 px de vide de chaque cote sur une vitre
     de 2000 : 72 pour cent de largeur utile, et le contenu redevient une ile
     posee au milieu, exactement le reproche a corriger. Mesure faite a l'ecran.
     Avec cette formule : 1168 utiles a 1280 de vitre, 1440 a 1600, 1800 a 2000
     (90 pour cent), 2040 a 2560 (80 pour cent).
     Le confort de LECTURE n'est pas menace par cette largeur : la prose est
     bridee separement par --laize-texte, et les sections larges sont celles qui
     portent des grilles, pas des paragraphes. */
  --laize:         clamp(1440px, 90vw, 2040px);
  --laize-texte:   64ch;
  --marge:         clamp(20px, 4vw, 56px);
  --rayon:         10px;
  --rayon-bouton:  6px;
  --ancre-haut:    64px;

  /* ---- mouvement ---- */
  --courbe:        cubic-bezier(.22, .61, .36, 1);
  --courbe-longue: cubic-bezier(.16, 1, .3, 1);
}

@media (min-width: 1024px) { :root { --ancre-haut: 76px; } }

* { box-sizing: border-box; }

html {
  /* Voir la regle 3 de l'en-tete. */
  font-size: clamp(16px, 12px + 0.3125vw, 18px);
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--papier);
  color: var(--encre-douce);
  font-family: Carlito, Calibri, Inter, system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: 1rem;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img, svg { display: block; max-width: 100%; }

/* ⚠ L'ATTRIBUT `hidden` DOIT GAGNER, ET SANS CETTE LIGNE IL PERDAIT.
   La regle ci-dessus pose `display: block` sur toute image et toute icone.
   Elle vient de la feuille du site, donc elle l'emporte sur le `[hidden] {
   display: none }` de la feuille du navigateur, qui est de priorite plus
   faible : une icone marquee `hidden` restait VISIBLE. Constate a l'ecran, le
   bouton qui montre le mot de passe affichant ses DEUX icones cote a cote,
   l'oeil ouvert et l'oeil barre, en meme temps.
   La regle vaut pour tout le projet, pas seulement pour ce bouton : c'est le
   `display` de l'auteur qui est en cause, pas l'element. */
[hidden] { display: none !important; }
:where(a) { color: inherit; }

/* Un seul anneau de focus pour tout le site, et il est BLEU : l'or ne passe
   pas le contraste sur un fond clair. */
:focus-visible { outline: 2px solid var(--inter); outline-offset: 3px; border-radius: 2px; }

[id] { scroll-margin-top: var(--ancre-haut); }

.lecture-seule {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}

/* LE LIEN D'EVITEMENT DOIT REAPPARAITRE AU CLAVIER. Il portait `.lecture-seule`
   sans aucune exception au focus : il restait donc a un pixel meme une fois
   atteint, et la toute premiere tabulation de chaque page semblait ne rien
   faire. La regle ne vise que les LIENS : les titres masques pour lecteur
   d'ecran ne sont pas focalisables et ne bougent pas. */
a.lecture-seule:focus-visible {
  position: fixed; top: 10px; left: 10px; z-index: 200;
  width: auto; height: auto; margin: 0; overflow: visible; clip: auto;
  padding: .7rem 1.1rem; border-radius: var(--rayon-bouton);
  background: var(--nuit); color: var(--blanc);
  font-size: .9375rem; font-weight: 600; text-decoration: none;
  box-shadow: 0 10px 30px -12px rgba(26,58,92,.5);
}

/* ---------------------------------------------------------------------------
   LA LAIZE : une seule formule, ecrite une fois
   ---------------------------------------------------------------------------
   Deux laizes differentes produiraient un decrochement de bord sur l'axe le
   plus visible de la composition. L'en-tete, le hero, toutes les sections et
   le pied partagent celle-ci : sur 2000 px, le logotype de l'en-tete, la
   premiere lettre du titre et le logotype du pied sont sur la meme verticale.
   ------------------------------------------------------------------------- */
.laize { width: min(100% - 2 * var(--marge), var(--laize)); margin-inline: auto; }
.laize-etroite { width: min(100% - 2 * var(--marge), 720px); margin-inline: auto; }

/* La marge grandit aussi, mais LENTEMENT : sans cela, un contenu colle aux
   bords sur une tres grande vitre est aussi desagreable qu'une ile au milieu. */
@media (min-width: 1800px) { :root { --marge: 64px; } }

/* ---------------------------------------------------------------------------
   TYPOGRAPHIE
   ---------------------------------------------------------------------------
   Carlito est le clone libre metriquement compatible de Calibri, la police de
   la charte : le rendu du web et celui des documents Word coincident. Playfair
   Display porte les titres, comme sur recrutement.samko.group.
   ------------------------------------------------------------------------- */
h1, h2, h3, h4 { margin: 0; color: var(--nuit); text-wrap: balance; }

h1 {
  font-family: "Playfair Display", Georgia, "Times New Roman", serif;
  font-weight: 700;
  font-size: clamp(1.9rem, 1.1rem + 2.6vw, 3.4rem);
  line-height: 1.06;
  letter-spacing: -.02em;
}
h1 .or { color: var(--or); font-style: italic; }
h1 .ligne { display: inline; }
@media (min-width: 768px) { h1 .ligne { display: block; } }

h2 {
  font-family: "Playfair Display", Georgia, "Times New Roman", serif;
  font-weight: 700;
  font-size: clamp(1.6rem, 1.05rem + 1.5vw, 2.25rem);
  line-height: 1.18;
  letter-spacing: -.015em;
}

h3 { font-size: 1.125rem; font-weight: 700; line-height: 1.3; color: var(--nuit); }
h4 { font-size: 1rem; font-weight: 700; color: var(--wordmark); }

.surtitre {
  margin: 0 0 .7rem;
  font-size: .72rem; font-weight: 700; letter-spacing: .2em;
  text-transform: uppercase; color: var(--inter-texte);
}

/* Le filet de signature : 56 par 2 px au-dessus de chaque surtitre. C'est le
   seul repere qui dit « une section commence » sans un titre plus gros. */
.filet-signature {
  display: block; width: 56px; height: 2px; margin-bottom: 1rem;
  background: var(--or); transform-origin: left center;
}
.sur-nuit .filet-signature { background: var(--or); }
.sur-nuit .surtitre { color: var(--or-doux); }

/* LE CHAPO AUSSI. `.chapo` porte `color: var(--encre-douce)` en dur, donc il
   n'herite PAS de la bande qui le contient : pose sur un fond nuit, il y rend
   2,5 pour un. Chaque page a fond sombre redeclarait sa couleur a la main, ce
   qui marchait tant qu'on y pensait ; le premier ecran ecrit sans y penser, le
   fil de contestation, l'a rendu illisible. La regle est desormais ici, avec
   celles du surtitre et du filet : c'est ce que `sur-nuit` veut dire. */
.sur-nuit .chapo, .bande-nuit .chapo, .hero .chapo { color: rgba(255, 255, 255, .8); }

.chapo {
  margin: .9rem 0 0; font-size: 1.0625rem; line-height: 1.68;
  max-width: var(--laize-texte); color: var(--encre-douce);
}
.discret { color: var(--acier); }
.mono {
  font-family: "IBM Plex Mono", "Courier New", monospace;
  font-variant-numeric: tabular-nums;
}

/* ---------------------------------------------------------------------------
   LES BANDES : voir la regle 2
   ------------------------------------------------------------------------- */
.bande { padding-block: 48px; }
@media (min-width: 768px)  { .bande { padding-block: 68px; } }
@media (min-width: 1280px) { .bande { padding-block: 92px; } }

.bande-papier  { background: var(--papier); }
.bande-blanche { background: var(--blanc); border-block: 1px solid var(--filet); }
.bande-voile   { background: var(--bleu-voile); }
.bande-nuit    { background: var(--nuit); color: var(--sur-nuit); }
.bande-nuit h1, .bande-nuit h2, .bande-nuit h3, .bande-nuit h4 { color: var(--blanc); }

/* ---------------------------------------------------------------------------
   L'EN-TETE
   ------------------------------------------------------------------------- */
/* LA HAUTEUR DE L'ENTETE EST UNE VARIABLE, parce qu'une page a hero doit
   pouvoir la reprendre en marge negative. Voir juste en dessous. */
.entete {
  --h-entete: 60px;
  position: sticky; top: 0; z-index: 50;
  background: rgba(255, 255, 255, .94);
  backdrop-filter: saturate(150%) blur(8px);
  border-bottom: 1px solid var(--filet);
}

/* L'ENTETE EST TOUJOURS OPAQUE, et ce n'est pas un renoncement esthetique.
   Une premiere version la rendait transparente au-dessus de la bande sombre,
   puis la reposait au defilement, par script. Ce dispositif a echoue trois fois
   de suite a l'ecran, et son mode de defaillance est le pire possible : une
   entete restee transparente au-dessus d'un contenu clair affiche un logotype
   blanc sur blanc et une navigation invisible. Un effet decoratif qui, quand il
   rate, rend la navigation illisible ne vaut pas son risque.
   Sur les pages qui s'ouvrent sur une bande sombre, l'entete PREND la couleur
   de cette bande : elle en devient le prolongement, sans script, sans bascule,
   et sans defaillance possible. */
body.page-hero .entete {
  background: var(--nuit);
  border-bottom-color: transparent;
  backdrop-filter: none;
}
body.page-hero .marque .sur-sombre { opacity: 1; position: static; }
body.page-hero .marque .sur-clair  { opacity: 0; position: absolute; }
body.page-hero .entete nav a { color: rgba(255, 255, 255, .84); }
body.page-hero .entete .bouton-nu { color: rgba(255, 255, 255, .86); }
body.page-hero .entete .bouton-nu:hover { color: var(--blanc); }
body.page-hero .menu-mobile > summary {
  background: rgba(255, 255, 255, .10); border-color: rgba(255, 255, 255, .24); color: var(--blanc);
}

.entete .laize {
  display: flex; align-items: center; gap: 1rem;
  height: var(--h-entete);
}
@media (min-width: 1024px) { .entete { --h-entete: 72px; } }

/* LE DEFAUT QUE CETTE REGLE CORRIGE, et il ne se voit qu'a l'ecran.
   position: sticky garde l'element DANS LE FLUX : il occupe donc ses soixante
   pixels, et une entete transparente y laisse voir le fond du body, presque
   blanc, au lieu de la bande sombre qui la suit. Le logotype clair devient
   alors blanc sur blanc, et la page semble porter un bandeau vide.
   La marge negative fait remonter la premiere bande SOUS l'entete, ce qui est
   precisement ce qu'on veut d'une entete flottante. Elle est portee par le
   BODY et non par .sur-hero : sur la classe basculee, la page sauterait de
   soixante pixels des le premier defilement. */
body.page-hero .entete { margin-bottom: calc(-1 * var(--h-entete)); }

/* La sentinelle doit avoir une SURFACE. Un element de hauteur nulle
   n'intersecte jamais rien : l'IntersectionObserver ne se declenche pas, et
   l'entete reste transparente pour toujours, donc illisible des qu'on quitte
   la bande sombre. Un pixel suffit, repris par une marge negative pour qu'il
   ne decale rien. */
[data-fin-hero] { display: block; height: 1px; margin-top: -1px; }

.marque { display: flex; align-items: center; flex: none; }
.marque img { height: 34px; width: auto; }
@media (min-width: 1024px) { .marque img { height: 38px; } }
.marque .sur-sombre, .marque .sur-clair { transition: opacity 240ms ease-out; }
.marque .sur-sombre { opacity: 0; position: absolute; }

/* LA PLACE DU LOGOTYPE SUR TELEPHONE, mesuree et non estimee.
   Le logotype complet fait 170 px de large a 34 px de haut. Avec le bouton
   d'action (126 px), le menu (40 px), les ecarts et les marges, le contenu
   minimal de l'entete pesait 381 px : elle debordait donc de tout appareil
   plus etroit, iPhone SE et iPhone 13 mini compris. Deux paliers y repondent,
   sans jamais faire disparaitre le chemin vers l'accueil. */
@media (max-width: 419px) { .marque img { height: 28px; } }
.marque-sceau { display: none; }
@media (max-width: 379px) {
  .marque .sur-clair, .marque .sur-sombre { display: none; }
  .marque-sceau { display: block; height: 30px; width: auto; }
}

.entete .nav-large { display: none; margin-left: auto; }
@media (min-width: 900px) { .entete .nav-large { display: flex; align-items: center; gap: 26px; } }
.entete nav a {
  position: relative; font-size: .9375rem; font-weight: 500;
  color: var(--encre-douce); text-decoration: none; transition: color 200ms ease-out;
}
.entete.sur-hero nav a { color: rgba(255, 255, 255, .84); }
.entete nav a::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -6px; height: 2px;
  background: var(--or); transform: scaleX(0); transform-origin: left center;
  transition: transform 180ms var(--courbe);
}
.entete nav a:hover::after, .entete nav a:focus-visible::after,
.entete nav a[aria-current="page"]::after { transform: scaleX(1); }

.entete-actions { display: flex; align-items: center; gap: .6rem; margin-left: auto; }
@media (min-width: 900px) { .entete-actions { margin-left: 26px; gap: .8rem; } }

/* Le bouton nu : du texte cliquable a hauteur de bouton, sans fond ni bordure.
   Il herite de la couleur de l'entete, donc il passe du sombre au clair avec
   elle sans qu'on ait a le declarer deux fois. */
.bouton-nu { background: transparent; color: inherit; border-color: transparent; padding-inline: .5rem; }
.bouton-nu:hover { color: var(--inter-texte); }

/* Sur telephone, l'entete ne doit JAMAIS passer sur deux lignes : elle
   deviendrait plus haute que le titre qu'elle surplombe. Les libelles ne se
   coupent pas, et les actions secondaires cedent la place au menu. */
.entete .bouton { white-space: nowrap; }
.menu-mobile { position: relative; }
.menu-mobile > summary {
  list-style: none; cursor: pointer; display: grid; place-items: center;
  width: 40px; height: 40px; border-radius: var(--rayon-bouton);
  border: 1px solid var(--filet-fort); color: var(--nuit); background: var(--blanc);
}
.menu-mobile > summary::-webkit-details-marker { display: none; }
.menu-tiroir {
  position: absolute; right: 0; top: calc(100% + 10px); z-index: 60; min-width: 220px;
  background: var(--blanc); border: 1px solid var(--filet); border-radius: var(--rayon);
  box-shadow: 0 14px 40px rgba(26,58,92,.16); padding: .5rem; display: grid; gap: .1rem;
  animation: monter 180ms var(--courbe) both;
}
.menu-tiroir a, .menu-tiroir button {
  display: block; width: 100%; text-align: left; padding: .6rem .7rem;
  border: 0; background: transparent; border-radius: 6px;
  font-family: inherit; font-size: .9375rem; font-weight: 500; color: var(--encre-douce);
  text-decoration: none; cursor: pointer;
}
.menu-tiroir a:hover, .menu-tiroir button:hover { background: var(--bleu-voile); color: var(--nuit); }

@media (min-width: 900px) {
  .menu-mobile { display: none; }
}
@media (max-width: 560px) {
  /* En dessous de 560, on ne garde qu'UNE action a cote du menu : la plus
     utile selon qu'on est connecte ou non. Le reste vit dans le tiroir.

     ATTENTION A LA SPECIFICITE, c'est le defaut qui a ete corrige ici. Ecrite
     `.entrer-large { display: none }`, cette regle pese 0,1,0 : exactement le
     meme poids que `.bouton { display: inline-flex }`, declaree QUINZE LIGNES
     PLUS BAS. A egalite, la derniere gagne, donc le lien restait affiche et
     l'entete debordait de la fenetre sur TOUT telephone de moins de 495 px.
     Une media query ne change pas la specificite : seul le prefixe `.entete`
     la fait passer a 0,2,0 et rend la regle insensible a l'ordre. */
  .entete .sortir-large, .entete .entrer-large { display: none; }
}

/* ---------------------------------------------------------------------------
   LES BOUTONS
   ------------------------------------------------------------------------- */
.bouton {
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  min-height: 44px; padding-block: .55rem; padding-inline: clamp(.9rem, 3vw, 1.4rem);
  border: 1px solid transparent; border-radius: var(--rayon-bouton);
  font-family: inherit; font-size: .9375rem; font-weight: 600;
  text-decoration: none; cursor: pointer; text-align: center; max-width: 100%;
  transition: background-color 200ms var(--courbe), border-color 200ms var(--courbe),
              color 200ms var(--courbe), transform 200ms var(--courbe);
}
.bouton:active { transform: translateY(1px); }
.bouton svg { flex: none; }

.bouton-or     { background: var(--or); color: var(--nuit); }
.bouton-or:hover { background: var(--or-doux); }
.bouton-nuit   { background: var(--nuit); color: var(--sur-nuit-fort); }
.bouton-nuit:hover { background: var(--nuit-surface); }
.bouton-clair  { background: var(--blanc); color: var(--nuit); border-color: var(--filet-fort); }
.bouton-clair:hover { background: var(--bleu-voile); border-color: var(--inter); }
.bouton-fantome { background: transparent; color: var(--sur-nuit-fort); border-color: rgba(255,255,255,.28); }
.bouton-fantome:hover { border-color: rgba(255,255,255,.55); }
.bouton-petit  { min-height: 36px; font-size: .875rem; padding-inline: .85rem; }
.bouton[disabled], .bouton[aria-disabled="true"] { opacity: .5; pointer-events: none; }

/* ---------------------------------------------------------------------------
   LES CARTES
   ------------------------------------------------------------------------- */
.carte {
  background: var(--blanc); border: 1px solid var(--filet);
  border-radius: var(--rayon); padding: 22px 24px;
  transition: border-color 200ms var(--courbe), box-shadow 200ms var(--courbe),
              transform 200ms var(--courbe);
}
a.carte { text-decoration: none; display: block; }
a.carte:hover {
  border-color: var(--inter);
  box-shadow: 0 6px 22px rgba(26, 58, 92, .09);
  transform: translateY(-2px);
}

/* Le liseré d'entite : le degrade Academy, sur le bord gauche des cartes de
   parcours. C'est la couleur d'accroche que la charte donne a SAMKO Academy. */
.carte-parcours { border-left: 4px solid transparent;
  border-image: linear-gradient(180deg, var(--ciel), var(--nuit)) 1;
  border-radius: 0 var(--rayon) var(--rayon) 0; }

/* ---------------------------------------------------------------------------
   LES ETIQUETTES ET LES CALLOUTS
   ------------------------------------------------------------------------- */
.etiq {
  display: inline-flex; align-items: center; gap: .35rem;
  font-size: .6875rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  padding: .25rem .55rem; border-radius: 4px;
  background: var(--bleu-voile); color: var(--inter-texte);
}
.etiq-or       { background: #FFF3D1; color: #8A6608; }
/* Les etiquettes reprennent les couleurs de TEXTE des encarts .mot-*, et non
   les couleurs de charte brutes. Sur leur propre fond voile, --succes rendait
   4,40 et --attention 4,08, tous deux sous le seuil ; les deux teintes
   assombries, deja employees six lignes plus bas, rendent 6,42 et 6,48. La
   critique passait deja (5,31) et ne bouge pas. */
.etiq-succes   { background: var(--succes-voile); color: #15602C; }
.etiq-attention{ background: var(--attention-voile); color: #8A4A06; }
.etiq-critique { background: var(--critique-voile); color: var(--critique); }

/* Les callouts de la charte : fond leger, filet gauche de 4 px. */
.mot {
  border-radius: 0 6px 6px 0; padding: .85rem 1.1rem; margin: 0 0 1.25rem;
  font-size: .9375rem; line-height: 1.55; border-left: 4px solid;
}
.mot-info      { background: var(--bleu-voile);     border-color: var(--ciel);      color: #14506B; }
.mot-succes    { background: var(--succes-voile);   border-color: var(--succes);    color: #15602C; }
.mot-attention { background: var(--attention-voile);border-color: var(--or);        color: #8A4A06; }
.mot-critique  { background: var(--critique-voile); border-color: var(--critique);  color: #8E0000; }

/* ---------------------------------------------------------------------------
   LES FORMULAIRES
   ------------------------------------------------------------------------- */
.champ { margin-top: 1.1rem; }
.champ label {
  display: block; font-size: .875rem; font-weight: 600;
  color: var(--nuit); margin-bottom: .4rem;
}
/* LA LISTE DES TYPES EST UN PIEGE. Un champ dont le type n'y figure pas garde
   sa largeur native du navigateur, environ 170 px, et se retrouve minuscule au
   milieu d'une ligne de filtres. Aucune erreur, aucun style manquant a l'oeil :
   juste un champ qui ne grandit pas. C'est arrive a `type=search` sur l'ecran
   des comptes. On enumere donc TOUS les types de saisie textuelle, y compris
   ceux qu'on n'emploie pas encore. */
.champ input[type=text], .champ input[type=email], .champ input[type=password],
.champ input[type=search], .champ input[type=tel], .champ input[type=url],
.champ input[type=number], .champ input[type=date], .champ input:not([type]),
.champ textarea, .champ select {
  width: 100%; font-family: inherit; font-size: 1rem; color: var(--encre);
  background: var(--blanc); border: 1px solid var(--filet-fort);
  border-radius: var(--rayon-bouton); padding: .7rem .85rem;
  /* Un contour TRANSPARENT plutot que `outline: none` : le focus est bien
     rendu ici par la bordure et le halo, mais un `none` sec efface aussi
     l'anneau que les modes a contraste force dessinent a la place du halo,
     et le champ focalise n'y est alors plus signale du tout. */
  outline: 2px solid transparent; outline-offset: 2px;
  transition: border-color 160ms var(--courbe), box-shadow 160ms var(--courbe);
}
.champ input:focus, .champ textarea:focus, .champ select:focus {
  border-color: var(--inter); box-shadow: 0 0 0 3px rgba(58, 171, 219, .18);
}
.champ input[aria-invalid=true] { border-color: var(--critique); }
.champ .aide  { font-size: .8125rem; color: var(--acier); margin-top: .35rem; }

/* L'INVITE DE SAISIE. Aucune regle ::placeholder n'existait dans le projet :
   les sept champs a invite retombaient sur le gris du moteur, entre 2,4 et 3,3
   pour un. Deux de ces invites sont le SEUL texte visible de leur champ, les
   barres de recherche du catalogue et de l'administration ayant leur etiquette
   masquee. --acier donne 5,50 sur blanc.
   `opacity: 1` n'est pas une precaution decorative : Firefox applique .54 par
   defaut a ce pseudo-element, ce qui ramenerait --acier a 2,2, donc PIRE que
   le defaut qu'on corrige. */
input::placeholder,
textarea::placeholder { color: var(--acier); opacity: 1; }
.champ .faute { font-size: .8125rem; color: var(--critique); margin-top: .35rem; font-weight: 600; }

/* ─────────────────────────────────────────────────────────────────────
   LE MOT DE PASSE : l'oeil, la jauge, et le resume des fautes.

   ⚠ CES TROIS BLOCS SONT NES D'UN DEFAUT REPRODUIT, pas d'une envie de
   decoration. Un mot de passe de DOUZE caracteres, donc valide, soumis sur
   l'inscription avec une adresse deja prise : les deux cases sont videes par
   le navigateur, la vraie faute vit deux champs plus haut, et la seule phrase
   qui reste sous le champ est « Douze caracteres au minimum ». On retape douze
   caracteres, on echoue encore, on relit la meme phrase. Le champ ne disait
   jamais combien on avait tape, et rien ne permettait de le voir.
   ───────────────────────────────────────────────────────────────────── */

.champ-mdp { position: relative; display: block; }

/* La place du bouton est reservee DANS le champ, sinon le dernier caractere
   saisi passe dessous et devient illisible au moment ou l'on veut justement
   le relire. */
.champ-mdp input { padding-right: 3rem !important; }

.mdp-oeil {
  position: absolute; top: 50%; right: .25rem; transform: translateY(-50%);
  /* 44 px : la cible tactile minimale. Le bouton est visuellement plus petit,
     c'est la ZONE qui fait 44. */
  width: 44px; height: 44px; display: flex; align-items: center; justify-content: center;
  background: none; border: 0; border-radius: var(--rayon-bouton);
  color: var(--acier); cursor: pointer;
  transition: color 160ms var(--courbe), background-color 160ms var(--courbe);
}
.mdp-oeil:hover { color: var(--inter-texte); background: var(--bleu-voile); }
.mdp-oeil:focus-visible { outline: 2px solid var(--inter); outline-offset: -2px; }

/* La jauge. Elle part de l'aide ordinaire et ne change que de couleur : c'est
   la MEME ligne qui parle, donc l'oeil ne la cherche pas ailleurs. */
.jauge-mdp { transition: color 160ms var(--courbe); }
.jauge-mdp.jauge-court { color: var(--encre-douce); }
.jauge-mdp.jauge-bon   { color: var(--succes); font-weight: 600; }
.jauge-mdp.jauge-bon::before {
  content: ''; display: inline-block; width: .8em; height: .45em;
  margin-right: .45em; vertical-align: .12em;
  border-left: 2px solid currentColor; border-bottom: 2px solid currentColor;
  transform: rotate(-45deg);
}

/* Le resume : ce que le formulaire reproche, la ou le navigateur repose le
   regard apres un renvoi, c'est-a-dire tout en haut. */
.resume-fautes {
  margin-bottom: 1.4rem; padding: .9rem 1rem;
  background: var(--critique-voile); border-left: 3px solid var(--critique);
  border-radius: 0 var(--rayon-bouton) var(--rayon-bouton) 0;
}
.resume-fautes-titre {
  margin: 0; display: flex; align-items: center; gap: .5rem;
  font-weight: 700; color: var(--critique); font-size: .9375rem;
}
.resume-fautes ul { margin: .5rem 0 0; padding-left: 2.05rem; }
.resume-fautes li { font-size: .875rem; color: var(--encre); margin: .2rem 0; }
.case { display: flex; gap: .6rem; align-items: flex-start; margin-top: 1.1rem;
        font-size: .9375rem; color: var(--encre-douce); }
.case input { margin-top: .3rem; flex: 0 0 auto; width: 17px; height: 17px; accent-color: var(--inter); }
.bouton-pleine { width: 100%; }

/* La feuille : le gabarit des ecrans d'entree. Une carte blanche posee sur le
   papier, jamais un formulaire nu au milieu du vide. */
.feuille {
  background: var(--blanc); border: 1px solid var(--filet); border-radius: var(--rayon);
  padding: clamp(24px, 5vw, 40px);
  box-shadow: 0 1px 3px rgba(26, 58, 92, .05);
}
.sous { margin-top: 1.4rem; font-size: .9375rem; text-align: center; color: var(--encre-douce); }
.sous a { color: var(--wordmark); font-weight: 600; text-decoration: underline; text-underline-offset: 2px; }

/* ---------------------------------------------------------------------------
   LES GRILLES
   ------------------------------------------------------------------------- */
.trio { display: grid; gap: 20px; grid-template-columns: 1fr; }
@media (min-width: 700px)  { .trio { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .trio { grid-template-columns: repeat(3, 1fr); } }

.duo { display: grid; gap: 24px; grid-template-columns: 1fr; }
@media (min-width: 900px) { .duo { grid-template-columns: 1fr 1fr; } }

.pile { display: grid; gap: 14px; }

/* ---------------------------------------------------------------------------
   LE PIED
   ------------------------------------------------------------------------- */
.pied {
  position: relative; background: var(--nuit-profond);
  color: rgba(255, 255, 255, .64); padding-block: 44px; font-size: .875rem;
}
.pied::before {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 2px;
  background: linear-gradient(90deg, transparent, var(--or), transparent);
}
.pied .laize { display: grid; gap: 1.75rem; }
@media (min-width: 800px) { .pied .laize { grid-template-columns: 2fr 1fr 1fr; column-gap: 40px; } }
.pied h4 {
  font-size: .72rem; font-weight: 700; letter-spacing: .2em; text-transform: uppercase;
  color: var(--or-doux); margin-bottom: .8rem;
}
.pied a { color: rgba(255,255,255,.82); text-decoration: none; }
.pied a:hover { color: var(--blanc); text-decoration: underline; }
.pied ul { list-style: none; margin: 0; padding: 0; display: grid; gap: .45rem; }
.pied img { height: 36px; width: auto; margin-bottom: .9rem; }
.pied p { margin: 0 0 .35rem; }
.pied .mention {
  margin-top: 1.75rem; padding-top: 1.25rem; border-top: 1px solid rgba(255,255,255,.12);
  font-size: .8125rem; color: rgba(255,255,255,.5);
}

/* ---------------------------------------------------------------------------
   LE MOUVEMENT : il sert a comprendre, jamais a decorer
   ---------------------------------------------------------------------------
   Aucune bibliotheque : chaque requete compte sur une 4G malienne. Aucune
   boucle infinie. Et tout s'eteint si la personne a demande moins d'animation.
   ------------------------------------------------------------------------- */
.reveler { opacity: 0; transform: translateY(16px); transition: opacity 520ms var(--courbe-longue), transform 520ms var(--courbe-longue); }
.reveler.vu { opacity: 1; transform: none; }
/* ⚠ LE GARDE-FOU SANS SCRIPT. `.reveler` pose `opacity: 0` et n'est relevee
   QUE par l'observateur ecrit dans socle.blade.php. Sans JavaScript, les blocs
   qui la portent restaient donc INVISIBLES, sur quatre vues : la page se
   chargeait, ne montrait rien, et n'avait aucune erreur a signaler. Trois
   lignes, valables pour tout le site. */
@media (scripting: none) {
  .reveler { opacity: 1; transform: none; }
}

@keyframes monter { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
@keyframes onde   { from { transform: scale(1); opacity: .5; } to { transform: scale(2.4); opacity: 0; } }

.pastille-vive { position: relative; display: inline-block; width: 8px; height: 8px;
                 border-radius: 50%; background: var(--succes); flex: none; }
.pastille-vive::after {
  content: ""; position: absolute; inset: 0; border-radius: 50%; background: var(--succes);
  animation: onde 2.4s var(--courbe-longue) infinite;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .001ms !important; animation-iteration-count: 1 !important;
                           transition-duration: .001ms !important; }
  .reveler { opacity: 1; transform: none; }
}

/* ---------------------------------------------------------------------------
   LES VIGNETTES DE MODULE
   ---------------------------------------------------------------------------
   Des cartes a image, disposees en grille, comme sur les plateformes que tout
   le monde connait. L'image n'est pas une photo : le cabinet n'a pas de
   photothèque, et une photo de banque d'images sonnerait faux sur un site de
   formation au chiffre. Elle est DESSINEE, avec le degrade du metier et une
   trame qui evoque le support de l'exercice. Zero requete reseau, ce qui
   compte sur une 4G qui lache.

   L'ombre est portee au repos et se creuse au survol : c'est elle qui donne a
   la grille son relief, et c'est ce qui a ete demande.
   ------------------------------------------------------------------------- */
.vignettes {
  display: grid; gap: 24px; margin-top: 1.75rem;
  grid-template-columns: repeat(auto-fill, minmax(268px, 1fr));
}

.vignette {
  /* height: 100% : sans cela, deux cartes d'une meme rangee prennent la
     hauteur de leur propre texte et la grille devient dentelee. Mesure : 325,
     306 et 330 px sur la meme rangee. */
  display: flex; flex-direction: column; height: 100%; text-decoration: none;
  background: var(--blanc); border: 1px solid var(--filet);
  border-radius: 12px; overflow: hidden;
  box-shadow: 0 1px 2px rgba(26, 58, 92, .06), 0 6px 18px -8px rgba(26, 58, 92, .18);
  transition: transform 220ms var(--courbe), box-shadow 220ms var(--courbe),
              border-color 220ms var(--courbe);
}
.vignette:hover, .vignette:focus-visible {
  transform: translateY(-4px);
  border-color: var(--filet-fort);
  box-shadow: 0 4px 10px rgba(26, 58, 92, .10), 0 22px 44px -14px rgba(26, 58, 92, .34);
}

/* L'image. Rapport 16 sur 10 : assez haut pour porter un motif, assez bas pour
   que six vignettes tiennent dans un ecran sans defiler. */
.vignette-image {
  position: relative; display: block; aspect-ratio: 16 / 10; overflow: hidden;
  background: linear-gradient(145deg, var(--v-a) 0%, var(--v-b) 100%);
}
/* La trame, propre au metier. Toutes en pochoir clair sur le degrade, pour
   qu'aucune ne devienne un aplat qui masque la couleur. */
.vignette-image::before {
  /* La trame doit SE VOIR. A 30 pour cent sous un masque qui s'eteint a 74
     pour cent, elle disparaissait sur les degrades sombres et la vignette
     rendait un aplat. */
  content: ""; position: absolute; inset: 0; opacity: .42;
  mask-image: linear-gradient(200deg, #000 12%, rgba(0,0,0,.35) 68%, transparent 96%);
}
/* Une echancrure de lumiere en haut a droite : elle donne du volume au
   degrade et empeche les grandes plages unies. */
.vignette-image::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(78% 90% at 88% 4%, rgba(255,255,255,.20) 0%, transparent 58%);
}
.trame-quadrillage::before {
  background-image:
    linear-gradient(rgba(255,255,255,.55) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,.55) 1px, transparent 1px);
  background-size: 34px 22px;
}
.trame-lignes::before {
  background-image: repeating-linear-gradient(180deg,
    rgba(255,255,255,.5) 0 1px, transparent 1px 15px);
}
.trame-colonnes::before {
  background-image: repeating-linear-gradient(90deg,
    rgba(255,255,255,.42) 0 6px, transparent 6px 26px);
}
.trame-code::before {
  background-image: repeating-linear-gradient(115deg,
    rgba(255,255,255,.38) 0 2px, transparent 2px 13px);
}
.trame-diagonale::before {
  background-image: repeating-linear-gradient(135deg,
    rgba(255,255,255,.34) 0 1px, transparent 1px 16px);
}
/* ⚠ LA SIXIEME TRAME, ET ELLE MANQUAIT.
   Cinq trames existaient pour SIX metiers. Le metier sans trame etait RHS, les
   ressources humaines, sous lequel cinquante-neuf modules sont entres : leurs
   vignettes retombaient toutes sur le repli, c'est-a-dire sur l'apparence
   reservee a un code ERRONE. Le commanditaire l'a dit autrement : « Il y a
   d'autres modules RH, il n'y a pas ca qui est mentionne. »
   Une reglure de registre avec sa colonne de gauche : le support d'un bulletin. */
/* ⚠ L'EMBLEME D'UN METIER, VENU DE partiels/fiche-style.blade.php.
   Ce n'est plus un style de fiche : la fiche module, la fiche parcours ET la
   page d'accueil l'emploient. Le laisser dans le bloc de style d'une seule des
   trois obligeait les deux autres a tirer trois cent quarante-six lignes de
   regles qui ne les concernent pas. */
.embleme {
  display: grid; place-items: center; flex: none;
  width: var(--e-taille, 76px); height: var(--e-taille, 76px);
  /* Le rayon suit la taille : le meme embleme sert a 84 px en tete de page et a
     44 px dans une carte, et un rayon fixe ferait un galet a la petite taille. */
  border-radius: calc(var(--e-taille, 76px) / 4.2); color: rgba(255,255,255,.94);
  background: linear-gradient(145deg, var(--e-a, var(--inter)) 0%, var(--e-b, var(--nuit)) 100%);
  box-shadow: 0 18px 40px -16px rgba(0,0,0,.6);
  border: 1px solid rgba(255,255,255,.18);
}

.trame-registre::before {
  background-image:
    repeating-linear-gradient(180deg, rgba(255,255,255,.46) 0 1px, transparent 1px 13px),
    linear-gradient(90deg, rgba(255,255,255,.30) 0 22%, transparent 22%);
}

.vignette-code {
  position: absolute; left: 16px; top: 14px; z-index: 2;
  font-size: .8125rem; font-weight: 600; letter-spacing: .06em;
  color: rgba(255, 255, 255, .92);
}
.vignette-marque {
  position: absolute; right: 14px; bottom: 13px; z-index: 2;
  color: rgba(255, 255, 255, .8);
}
.vignette-duree {
  position: absolute; left: 16px; bottom: 13px; z-index: 2;
  font-size: .6875rem; font-weight: 600; padding: .18rem .45rem; border-radius: 4px;
  background: rgba(18, 41, 63, .55); color: rgba(255, 255, 255, .94);
}

.vignette-corps { display: flex; flex-direction: column; gap: .3rem; padding: 15px 17px 17px; }
.vignette-service {
  font-size: .6875rem; font-weight: 700; letter-spacing: .13em;
  text-transform: uppercase; color: var(--inter-texte);
}
.vignette-titre {
  font-family: "Playfair Display", Georgia, serif; font-size: 1.125rem; font-weight: 700;
  line-height: 1.25; color: var(--nuit);
  /* Deux lignes reservees : la ligne de meta se pose alors a la meme hauteur
     sur toute la rangee, qu'un titre tienne sur une ligne ou sur deux. */
  min-height: calc(2 * 1.25em);
}
.vignette-meta {
  display: flex; align-items: center; gap: .35rem; margin-top: auto; padding-top: .5rem;
  font-size: .8125rem; color: var(--acier);
}

@media (prefers-reduced-motion: reduce) { .vignette:hover { transform: none; } }

/* ---------------------------------------------------------------------------
   LE RUBAN DE CHANTIER
   ---------------------------------------------------------------------------
   La bande rayee qui coiffe les etats vides : « ce n'est pas casse, c'est en
   cours ». Elle etait ecrite TROIS fois sous trois noms (.ruban, .ruban-fab,
   .liseret), avec le meme degrade et une hauteur qui differait d'un pixel.
   Un objet, un nom, une definition.
   ------------------------------------------------------------------------- */
.ruban-chantier {
  height: 6px;
  background: repeating-linear-gradient(45deg,
    var(--or) 0 12px, var(--bleu-voile) 12px 24px);
}

/* La note en etoiles. Une seule definition, employee par le catalogue et par
   les fiches ; le ton s'adapte au fond par une variable, jamais par une
   seconde regle. */
.etoiles { display: inline-flex; align-items: center; gap: .3rem; color: var(--ton-etoile, var(--or)); }
.etoiles .dessin { display: inline-flex; gap: 1px; }
.etoiles b { font-size: .8125rem; font-weight: 700; }
.etoiles small { font-size: .75rem; color: var(--acier); }
.sur-nuit .etoiles small, .bande-nuit .etoiles small { color: rgba(255, 255, 255, .62); }
