/* =============================================================================
   connect · socle graphique
   Source de vérité : _project/02-charte + _project/01-logo
   Toute couleur de la charte est déclarée ici et nulle part ailleurs.
   ============================================================================= */

:root {
    /* Les six nuances officielles */
    --nuit: #0B1E3D;
    --encre: #12294D;
    --azur: #2E6EB5;
    --elec: #4D9DE0;
    --givre: #A8CFF0;
    --brume: #EAF3FC;

    /* Dérivés de texte.
       Le gris est d'un cran plus foncé que la charte de référence, qui le pose à #5D7290 :
       cette valeur ne donne que 4,38:1 sur Brume, sous le seuil AA de 4,5, et le module écrit
       constamment du texte secondaire sur ce fond. #586C88 tient 4,78:1 sur Brume, 5,06 sur
       Brume claire et 5,36 sur blanc : conforme partout où il est employé. */
    --texte: #22344C;
    --gris: #586C88;
    --blanc: #fff;

    /* Teintes de service.
       Un seul gris de bord, celui de la charte. Le filet est plus clair et sert les séparateurs
       internes, pas le contour d'un bloc : ce sont deux rôles, pas deux nuances du même. */
    --brume-claire: #F4F9FE;
    --voile: #FBFDFF;
    --bord: #D9E6F3;
    --filet: #EDF4FB;

    /* Fond d'une capsule survolée ou pressée quand elle repose déjà sur Brume. Distinct du
       #DCEDFC de --degrade-clair, dont il n'est pas une reprise. */
    --brume-appui: #DCEBFA;

    /* Ocre. Départ des dégradés de jauge tiède, là où l'ambre seul serait trop sourd.
       Il n'a pas d'emploi en aplat ni en texte : son contraste n'est pas garanti. */
    --ocre: #D9A64D;

    /* Dégradés.
       Le dégradé signature : 135°, Électrique vers Azur à 55 %, puis Encre.

       Le dégradé d'action ne reprend pas Électrique. La charte le dessinait de #4D9DE0 à
       #2E6EB5, où le blanc plafonne à 2,91:1 sur l'extrémité claire. Aucune couleur de texte ne
       tient sur une amplitude pareille : l'encre y donne 4,98:1 en haut mais 2,77:1 en bas, le
       blanc fait l'inverse. Les deux extrémités sont donc resserrées vers le foncé, le blanc y
       tenant alors 4,57:1 puis 7,52:1. Électrique reste la couleur des surfaces qui ne portent
       aucun texte, où il garde tout son éclat : voir les familles d'outils ci-dessous. */
    --action-clair: #2F79BD;
    --action-fonce: #21568F;

    --degrade: linear-gradient(135deg, var(--elec), var(--azur) 55%, var(--encre));
    --degrade-action: linear-gradient(135deg, var(--action-clair), var(--action-fonce));
    --degrade-clair: linear-gradient(135deg, #8FC2F0, #DCEDFC);
    --degrade-sombre: linear-gradient(175deg, var(--encre), var(--nuit));

    /* Familles d'outils, du plus clair au plus profond : plus l'outil engage la responsabilité
       du formateur, plus son bleu est profond. Trois segments consécutifs du dégradé signature,
       posés sur des tuiles qui ne portent qu'un picto. */
    --fam-creation: linear-gradient(135deg, var(--elec), var(--azur));
    --fam-pilotage: linear-gradient(135deg, var(--azur), var(--encre));
    --fam-controle: linear-gradient(135deg, var(--encre), var(--nuit));

    /* Typographie */
    --police-titre: 'Quicksand', 'Trebuchet MS', sans-serif;
    --police-courante: 'Figtree', Verdana, sans-serif;

    /* Rayons : la capsule est la signature de la marque.
       Le rayon de bloc, à 80px, appartient au site vitrine et à ses grandes sections
       décoratives. Il n'a rien à voir avec le rayon de section de l'application. */
    --rayon-capsule: 999px;
    --rayon-champ: 18px;
    --rayon-carte: 28px;
    --rayon-carte-large: 36px;
    --rayon-section: 48px;
    --rayon-bloc: 80px;

    /* Ombres : toujours teintées bleu sur la base Azur, de 8 à 16 % d'opacité.
       Jamais de gris neutre, jamais d'ombre dure. */
    --ombre-s: 0 6px 16px rgba(46, 110, 181, .08);
    --ombre-m: 0 12px 30px rgba(46, 110, 181, .10);
    --ombre-l: 0 18px 44px rgba(46, 110, 181, .14);
    --ombre-action: 0 10px 24px rgba(46, 110, 181, .16);

    /* États, hors palette bleue, réservés à l'alerte et à l'attention. */
    --alerte: #B03A3A;
    --alerte-fond: #FDECEC;

    /* L'alerte, éclaircie pour tenir sur un aplat Nuit : le rouge du socle y disparaît. Employée
       par le bilan projeté et par le chrono dépassé de l'écran candidat. */
    --alerte-claire: #F0A8A8;
    --attention: #B26A00;
    --attention-fond: #FFF3E0;

    /* Le vert n'existait pas dans la charte : rien n'avait jamais eu à dire « ça marche ».
       L'indicateur de direct le demande. Assombri par rapport au vert d'écran habituel pour
       tenir le contraste de 4,5:1 sur fond blanc, comme le reste du texte. */
    --vert: #1E7A4B;
    --vert-fond: #E8F5EE;

    /* Rythme */
    --gouttiere: 24px;
    --largeur-max: 1140px;
    --contenu: 1280px;
}

/* ---------- Réinitialisation ---------- */

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

html {
    scroll-behavior: smooth;
}

body {
    font-family: var(--police-courante);
    color: var(--texte);
    background: #fff;
    line-height: 1.65;
    overflow-x: hidden;
}

h1, h2, h3, h4, h5 {
    font-family: var(--police-titre);
    color: var(--encre);
    line-height: 1.18;
    font-weight: 700;
}

a {
    text-decoration: none;
    color: var(--azur);
}

/* ---------- Focus ----------

   Neuf règles du produit écrivaient « outline: none » sur « :focus » pour retirer le liseré que
   le navigateur pose au clic, et signalaient le focus par un seul changement de bordure d'un
   pixel. C'est assez à la souris, où l'on sait où l'on vient de cliquer ; ce n'est pas assez au
   clavier, où le liseré est le seul moyen de savoir où l'on se trouve.

   Le liseré est donc retiré pour la souris seulement, et posé pour le clavier. Les deux règles
   vivent ici et non dans chaque feuille : « :focus » l'emportant sur « :focus-visible » dès
   qu'il est plus spécifique, une rustine par endroit se serait périmée au premier oubli. */
:focus-visible {
    outline: 2px solid var(--azur);
    outline-offset: 2px;
}

:focus:not(:focus-visible) {
    outline: none;
}

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

/* ---------- Mise en page ---------- */

.wrap {
    max-width: var(--largeur-max);
    margin: 0 auto;
    padding: 0 var(--gouttiere);
}

section {
    padding: 110px 0;
}

.sec-head {
    max-width: 660px;
    margin-bottom: 60px;
}

.sec-head h2 {
    font-size: clamp(1.8rem, 3.2vw, 2.6rem);
    margin-bottom: 16px;
}

.sec-head p {
    color: var(--gris);
    font-size: 1.06rem;
}

/* ---------- Composants ---------- */

.pill-eyebrow {
    display: inline-block;
    background: var(--brume);
    color: var(--azur);
    font-weight: 600;
    font-size: .78rem;
    letter-spacing: .14em;
    text-transform: uppercase;
    padding: 8px 20px;
    border-radius: var(--rayon-capsule);
    margin-bottom: 20px;
}

/* Un seul barème de bouton pour tout le produit.
   Le site vitrine en portait un, le module de jury un deuxième, les maquettes un troisième : un
   bouton n'avait donc pas la même taille selon l'écran. Celui-ci est le barème des maquettes. */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 9px;
    min-height: 44px;
    padding: 12px 24px;
    border-radius: var(--rayon-capsule);
    font-weight: 700;
    font-size: 14px;
    font-family: var(--police-titre);
    white-space: nowrap;
    transition: transform .15s ease, box-shadow .15s ease;

    /* Le bouton natif est neutralisé ici. Cinq feuilles du module le refaisaient chacune de son
       côté, faute de le trouver dans le socle : un « .btn » posé sur un <button> gardait sinon
       la bordure et le fond du navigateur. Les variantes qui suivent reposent leur fond. */
    border: none;
    background: none;
    cursor: pointer;
}

.btn:hover {
    transform: translateY(-1px);
}

.btn:active {
    transform: translateY(1px);
}

.btn:focus-visible {
    outline: 3px solid var(--azur);
    outline-offset: 3px;
}

.btn .picto {
    width: 14px;
    height: 14px;
    stroke-width: 11;
}

/* L'action principale. Les deux noms désignent le même bouton : « grad » est celui du site
   vitrine, « p » celui des maquettes, et rien ne justifie de renommer des dizaines de gabarits
   pour la seule symétrie. */
/* La couleur pleine est posée sous le dégradé, jamais remplacée par lui. Un dégradé est une
   image de fond : déclaré seul, il ne laisse aucune couleur dessous, et le bouton principal
   devient un texte blanc sur le fond de la page — invisible en tant que bouton. Le cas s'est
   produit en production, sur l'écran où un apprenant confirme son identité. */
.btn-grad,
.btn-p {
    background-color: var(--action-fonce);
    background-image: var(--degrade-action);
    color: var(--blanc);
    box-shadow: var(--ombre-action);
}

.btn-grad:hover,
.btn-p:hover {
    box-shadow: var(--ombre-l);
}

/* L'action secondaire. Une bordure, et pas seulement une ombre.

   Ces boutons ne portaient qu'une ombre douce pour tout relief, ce qui suffit sur une carte
   blanche posée sur un fond Brume. Cela ne suffit plus dès qu'ils tombent sur un fond clair :
   dans la barre fixe des écrans apprenants, en pleine largeur et sur un aplat à 92 % de blanc,
   un bouton blanc sans bordure ne se distingue plus de la barre. Il reste cliquable et devient
   invisible, ce qui est la pire des deux erreurs — l'apprenant croit qu'il n'y a rien à faire.

   La bordure ne coûte rien là où l'ombre suffisait déjà, et elle rattrape tous les fonds. */
.btn-blanc,
.btn-g {
    border: 1px solid var(--bord);
    background: var(--blanc);
    color: var(--encre);
    box-shadow: var(--ombre-s);
}

.btn-blanc:hover,
.btn-g:hover {
    border-color: var(--azur);
    color: var(--azur);
}

/* L'action secondaire, en bleu de la charte plutôt qu'en blanc.

   Le blanc convient sur une carte, où il se détache. Sur une barre d'actions il ne dit plus
   qu'une chose : « ceci n'est pas le vrai bouton ». Quand les deux actions sont légitimes —
   « c'est bien moi » et « ce n'est pas moi » —, les deux doivent se lire comme des boutons. Le
   contour porte alors la hiérarchie : plein pour l'action attendue, contour pour l'autre. */
.btn-ligne {
    border: 1.5px solid var(--azur);
    background: var(--blanc);
    color: var(--azur);
    box-shadow: var(--ombre-s);
}

.btn-ligne:hover {
    background: var(--brume);
    border-color: var(--action-fonce);
    color: var(--action-fonce);
}

.btn-t {
    background: transparent;
    color: var(--azur);
    padding: 12px 16px;
}

.btn-t:hover {
    background: var(--brume);
}

.btn-danger,
.btn-alerte {
    border: 1px solid var(--alerte);
    background: var(--blanc);
    color: var(--alerte);
    box-shadow: var(--ombre-s);
}

.btn-danger:hover,
.btn-alerte:hover {
    background: var(--alerte-fond);
}

/* Sur fond Encre ou Nuit. */
.btn-clair {
    background: rgba(255, 255, 255, .14);
    color: var(--blanc);
}

.btn-contour {
    border: 2px solid var(--givre);
    color: var(--encre);
    background: rgba(255, 255, 255, .6);
}

.btn-mini {
    min-height: 38px;
    font-size: 14px;
    padding: 9px 18px;
}

.btn-grand {
    font-size: 16px;
    padding: 16px 30px;
}

.btn-large {
    width: 100%;
}

.btn[disabled],
.btn.bloque {
    opacity: .45;
    pointer-events: none;
    box-shadow: none;
}

.tag {
    font-size: .72rem;
    font-weight: 600;
    padding: 4px 12px;
    border-radius: var(--rayon-capsule);
}

.tag.ok {
    background: #E7F3FE;
    color: var(--azur);
}

.tag.moy {
    background: var(--attention-fond);
    color: var(--attention);
}

/* Séparateur ondulé entre deux sections. */
.vague {
    display: block;
    width: 100%;
    height: 90px;
    margin-bottom: -1px;
}

.vague.retour {
    transform: rotate(180deg);
    margin-top: -1px;
    margin-bottom: 0;
}

/* ---------- Apparition au défilement ----------
   La classe « reveal » est posée par le contrôleur Stimulus du même nom :
   sans JavaScript, le contenu reste visible. */

.reveal {
    opacity: 0;
    transform: translateY(22px);
    transition: opacity .7s ease, transform .7s ease;
}

.reveal.vu {
    opacity: 1;
    transform: none;
}

/* ---------- Identité : logo ---------- */

.logo {
    display: flex;
    align-items: center;
    gap: 12px;
}

.logo svg {
    height: 38px;
    width: auto;
}

.logo .lt b {
    font-family: var(--police-titre);
    font-weight: 700;
    font-size: 1.3rem;
    color: var(--encre);
    display: block;
    line-height: 1;
    letter-spacing: .01em;
}

.logo .lt span {
    font-size: .55rem;
    letter-spacing: .17em;
    color: var(--azur);
    font-weight: 600;
}

/* ---------- Navigation ---------- */

.nav {
    position: sticky;
    top: 14px;
    z-index: 60;
    pointer-events: none;
}

.nav-capsule {
    pointer-events: auto;
    max-width: 1100px;
    margin: 0 auto;
    background: rgba(255, 255, 255, .82);
    backdrop-filter: blur(14px);
    border: 1px solid rgba(168, 207, 240, .5);
    border-radius: var(--rayon-capsule);
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 10px 12px 10px 26px;
    box-shadow: 0 12px 34px rgba(18, 41, 77, .09);
}

.nav-liens {
    display: flex;
    gap: 26px;
    align-items: center;
}

/* Les boutons sont exclus : « .nav-liens a » combine une classe et un élément, sa spécificité
   l'emportait donc sur celle de « .btn-grad » et repeignait en gris le texte prévu en blanc. */
.nav-liens a:not(.btn) {
    color: var(--texte);
    font-weight: 600;
    font-size: .9rem;
}

.nav-liens a:not(.btn):hover {
    color: var(--azur);
}

/* Détaché des liens de rubrique par un filet, pour qu'il se lise comme une action et non
   comme une sixième section du site. */
.nav-connexion {
    padding-left: 26px;
    border-left: 1px solid var(--bord);
    white-space: nowrap;
}

.nav-liens .btn {
    padding: 11px 24px;
}

/* Salutation affichée au formateur connecté, avant le lien vers son espace. */
.nav-salut {
    font-family: var(--police-titre);
    font-weight: 700;
    font-size: .9rem;
    color: var(--encre);
    white-space: nowrap;
}

@media (max-width: 940px) {
    .nav-liens a:not(.btn),
    .nav-salut {
        display: none;
    }

    .nav {
        top: 8px;
    }
}

/* ---------- Pied de page ---------- */

.pied {
    background: var(--degrade-sombre);
    color: var(--givre);
    padding: 80px 0 36px;
    margin-top: 120px;
    border-radius: var(--rayon-bloc) var(--rayon-bloc) 0 0;
}

.pied-grille {
    display: grid;
    grid-template-columns: 2fr 1fr 1fr 1fr;
    gap: 44px;
    padding-bottom: 44px;
    border-bottom: 1px solid rgba(168, 207, 240, .18);
}

.pied h5 {
    font-family: var(--police-titre);
    color: #fff;
    font-size: .92rem;
    margin-bottom: 16px;
}

.pied a {
    display: block;
    color: var(--givre);
    font-size: .88rem;
    padding: 5px 0;
}

.pied a:hover {
    color: #fff;
}

.pied .logo .lt b {
    color: #fff;
}

.pied .logo .lt span {
    color: var(--givre);
}

.pied-signature {
    font-size: .87rem;
    color: #9db4d2;
    max-width: 20rem;
}

.pied-bas {
    display: flex;
    justify-content: space-between;
    padding-top: 26px;
    font-size: .8rem;
    color: #7f97b5;
    flex-wrap: wrap;
    gap: 10px;
}

.pied-bas a {
    display: inline;
    color: #7f97b5;
}

@media (max-width: 820px) {
    .pied-grille {
        grid-template-columns: 1fr 1fr;
    }

    .pied {
        border-radius: 48px 48px 0 0;
    }
}

/* ---------- Accessibilité ---------- */

@media (prefers-reduced-motion: reduce) {
    html {
        scroll-behavior: auto;
    }

    .reveal {
        opacity: 1;
        transform: none;
        transition: none;
    }

    .btn {
        transition: none;
    }
}
