/* =========================================================================
   VIGIPRO — socle de style (Lot 1.3)
   Thème clair / sombre bâti sur la charte graphique officielle.

   Charte (source : « LOGO et codes couleurs/Codes Couleurs Logo Vigipro.xlsx ») :
     Bleu Profond   #1D4275  fond du bouclier
     Orange Feu     #E88320  branche droite du V et flamme
     Argent / Acier #A6ADAF  branche gauche du V et bordures
     Bleu Goutte    #3FA9F5  goutte d'eau centrale
     Bleu éclairci  #6393D3  fond d'encadrés (documents)

   ⚠️ Contraste : l'Orange Feu sur fond clair n'atteint pas le seuil de
   lisibilité pour du petit texte. Il est donc réservé aux accents, bordures et
   pastilles — jamais à du texte courant sur fond blanc.

   Règle du projet : tout écran doit être correct dans LES DEUX thèmes.
   ========================================================================= */

/* ---------- Thème clair (défaut) ---------- */
:root {
    --bleu-profond: #1D4275;
    --orange-feu: #E88320;
    --argent: #A6ADAF;
    --bleu-goutte: #3FA9F5;
    --bleu-eclairci: #6393D3;

    --fond: #f4f6f8;
    --surface: #ffffff;
    --surface-alt: #eef2f6;
    --texte: #1a2332;
    --texte-doux: #5a6472;
    --bordure: #dde3ea;

    --primaire: var(--bleu-profond);
    --primaire-texte: #ffffff;
    --lien: #1D4275;
    --entete-fond: var(--bleu-profond);
    --entete-texte: #ffffff;

    --succes: #1e7f4f;
    --alerte: #8a5200;
    --alerte-texte: #ffffff;
    --erreur: #b3261e;

    --ombre: 0 1px 3px rgba(16, 32, 56, .12), 0 1px 2px rgba(16, 32, 56, .08);
    --rayon: 8px;
}

/* ---------- Thème sombre : suit la préférence système… ---------- */
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="clair"]) {
        --fond: #0f1720;
        --surface: #182430;
        --surface-alt: #1f2d3b;
        --texte: #e8edf3;
        --texte-doux: #9aa8b8;
        --bordure: #2a3a4a;

        --primaire: var(--bleu-eclairci);
        --primaire-texte: #0f1720;
        --lien: #7fb0e5;
        --entete-fond: #131c26;

        --succes: #4cc38a;
        --alerte: #e0a33a;
        --alerte-texte: #0f1720;
            --erreur: #f2726a;

        --ombre: 0 1px 3px rgba(0, 0, 0, .45);
    }
}

/* ---------- …et bascule manuelle, qui prime toujours ---------- */
:root[data-theme="sombre"] {
    --fond: #0f1720;
    --surface: #182430;
    --surface-alt: #1f2d3b;
    --texte: #e8edf3;
    --texte-doux: #9aa8b8;
    --bordure: #2a3a4a;

    --primaire: var(--bleu-eclairci);
    --primaire-texte: #0f1720;
    --lien: #7fb0e5;
    --entete-fond: #131c26;

    --succes: #4cc38a;
    --alerte: #e0a33a;
    --alerte-texte: #0f1720;
    --erreur: #f2726a;

    --ombre: 0 1px 3px rgba(0, 0, 0, .45);
}

/* ---------- Base ---------- */
* { box-sizing: border-box; }

body {
    margin: 0;
    font-family: system-ui, -apple-system, "Segoe UI", Arial, sans-serif;
    font-size: 16px;
    line-height: 1.5;
    background: var(--fond);
    color: var(--texte);
    -webkit-text-size-adjust: 100%;
}

a { color: var(--lien); }

h1, h2, h3 { line-height: 1.25; margin: 0 0 .5em; }
h1 { font-size: 1.6rem; }
h2 { font-size: 1.25rem; }

/* ---------- En-tête ---------- */
.entete {
    background: var(--entete-fond);
    color: var(--entete-texte);
    padding: .6rem 1.25rem;
    display: flex;
    align-items: center;
    gap: 1.25rem;
    flex-wrap: wrap;
}

.marque {
    display: flex;
    align-items: center;
    gap: .6rem;
    text-decoration: none;
    color: var(--entete-texte);
    font-weight: 700;
    letter-spacing: .04em;
    font-size: 1.15rem;
}

.marque img { height: 38px; width: auto; display: block; }

.navigation {
    display: flex;
    gap: .25rem;
    flex-wrap: wrap;
    flex: 1;
}

.navigation a {
    color: var(--entete-texte);
    text-decoration: none;
    padding: .45rem .8rem;
    border-radius: var(--rayon);
    font-size: .95rem;
    opacity: .88;
}

.navigation a:hover { background: rgba(255, 255, 255, .12); opacity: 1; }

/* L'onglet courant est signalé par l'Orange Feu de la charte. */
.navigation a.actif {
    background: rgba(255, 255, 255, .14);
    opacity: 1;
    box-shadow: inset 0 -3px 0 var(--orange-feu);
}

.entete-droite { display: flex; align-items: center; gap: .5rem; }
.entete-utilisateur { font-size: .9rem; opacity: .9; }

/* Libellé du mode en cours dans la barre du haut (« Mode signature » du
   kiosque, « Signature de présence » du parcours par QR).

   ⚠️ Il DOIT porter `--entete-texte`, jamais `.doux`. Ces deux libellés
   employaient `class="petit doux"`, c'est-à-dire `--texte-doux`, une couleur
   prévue pour le fond du contenu : posée sur `--entete-fond`, qui est sombre
   dans les deux thèmes, elle tombait à **1,68** de contraste en thème clair.
   Mesuré, pas supposé — et invisible en thème sombre, où la même couleur
   s'éclaircit et remonte au-dessus du seuil. C'est le piège de l'Orange Feu
   sur `--primaire` (2026-08-01), sous une autre forme.

   Contrastes après correction : 8,44 en clair, 14,15 en sombre (seuil AA 4,5). */
.entete-mode {
    font-size: .875rem;
    color: var(--entete-texte);
    opacity: .9;
}

.bouton-theme {
    background: rgba(255, 255, 255, .12);
    border: 1px solid rgba(255, 255, 255, .22);
    color: var(--entete-texte);
    border-radius: var(--rayon);
    padding: .35rem .6rem;
    cursor: pointer;
    font-size: 1rem;
    line-height: 1;
}

.bouton-theme:hover { background: rgba(255, 255, 255, .22); }

/* ---------- Contenu ---------- */
.contenu { padding: 1.5rem; max-width: 1180px; margin: 0 auto; }

.carte {
    background: var(--surface);
    border: 1px solid var(--bordure);
    border-radius: var(--rayon);
    padding: 1.25rem;
    box-shadow: var(--ombre);
    margin-bottom: 1.25rem;
}

.carte-titre {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    margin-bottom: 1rem;
}

.doux { color: var(--texte-doux); }
.petit { font-size: .875rem; }

/* ---------- Tableaux (défilement horizontal sur mobile) ---------- */
.tableau-conteneur { overflow-x: auto; }

table.tableau {
    width: 100%;
    border-collapse: collapse;
    font-size: .95rem;
}

table.tableau th,
table.tableau td {
    text-align: left;
    padding: .6rem .7rem;
    border-bottom: 1px solid var(--bordure);
    white-space: nowrap;
}

table.tableau th {
    font-size: .8rem;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--texte-doux);
    background: var(--surface-alt);
}

table.tableau tbody tr:hover { background: var(--surface-alt); }
table.tableau td.libre { white-space: normal; }

/* ---------- Pastilles de statut ---------- */
.pastille {
    display: inline-block;
    padding: .15rem .55rem;
    border-radius: 999px;
    font-size: .78rem;
    font-weight: 600;
    border: 1px solid transparent;
    white-space: nowrap;
}

.pastille-prevue { background: var(--surface-alt); color: var(--texte-doux); border-color: var(--bordure); }
.pastille-confirmee { background: color-mix(in srgb, var(--bleu-goutte) 18%, transparent); color: var(--lien); border-color: var(--bleu-goutte); }
.pastille-realisee { background: color-mix(in srgb, var(--succes) 16%, transparent); color: var(--succes); border-color: var(--succes); }
.pastille-annulee { background: color-mix(in srgb, var(--erreur) 14%, transparent); color: var(--erreur); border-color: var(--erreur); }

/* ---------- Jauge de remplissage ---------- */
.jauge {
    display: block;
    width: 110px;
    height: 8px;
    background: var(--surface-alt);
    border: 1px solid var(--bordure);
    border-radius: 999px;
    overflow: hidden;
}

.jauge span { display: block; height: 100%; background: var(--primaire); }
.jauge.complete span { background: var(--orange-feu); }

/* ---------- Boutons ---------- */
.bouton {
    display: inline-block;
    background: var(--primaire);
    color: var(--primaire-texte);
    border: 1px solid transparent;
    border-radius: var(--rayon);
    padding: .5rem .9rem;
    font-size: .95rem;
    font-weight: 600;
    text-decoration: none;
    cursor: pointer;
}

.bouton:hover { filter: brightness(1.08); }

.bouton-secondaire {
    background: transparent;
    color: var(--lien);
    border-color: var(--bordure);
}

.bouton-secondaire:hover { background: var(--surface-alt); filter: none; }

/* ---------- Formulaires ---------- */
label { display: block; font-weight: 600; font-size: .9rem; margin-bottom: .3rem; }

/* ⚠️ Cette liste est **énumérative** : un type de champ absent retombe sur le
   style du navigateur (fond blanc, police système), ce qui ne se voit qu'en
   thème sombre. C'est exactement le défaut du `textarea` décrit plus bas.
   `number` et `file` ont été ajoutés au Lot 5.4, où ils apparaissent pour la
   première fois ; `search` et `tel` au Lot 9.5. **Ajouter tout nouveau type ici
   avant de l'employer.**
   ⚠️ Le piège s'est reproduit à l'identique : le champ de filtre des tableaux
   est un `input[type="search"]`, absent de cette liste — donc blanc sur fond
   sombre, et invisible en thème clair où le défaut ressemble au thème. */
input[type="text"],
input[type="password"],
input[type="email"],
input[type="date"],
input[type="number"],
input[type="file"],
input[type="search"],
input[type="tel"],
input[type="time"],
select,
textarea {
    width: 100%;
    padding: .55rem .7rem;
    font-size: 1rem;
    color: var(--texte);
    background: var(--surface);
    border: 1px solid var(--bordure);
    border-radius: var(--rayon);
}

/* Le bouton « Parcourir » d'un champ fichier est dessiné par le navigateur et
   n'hérite de rien : sans cette règle il reste gris clair sur fond sombre. */
input[type="file"] { font-size: .9rem; padding: .4rem .5rem; }

input[type="file"]::file-selector-button {
    font: inherit;
    margin-right: .6rem;
    padding: .3rem .7rem;
    color: var(--texte);
    background: var(--surface-alt);
    border: 1px solid var(--bordure);
    border-radius: var(--rayon);
    cursor: pointer;
}

/* ⚠️ `textarea` a été ajouté au Lot 5.1, et il manquait depuis le Lot 1.
   Personne ne l'avait vu parce qu'aucun écran n'en utilisait avant les
   formulaires en ligne : sans règle, le navigateur applique son fond blanc et
   sa police à chasse fixe — texte noir sur blanc au milieu d'une page sombre,
   illisible. Trouvé en ouvrant l'écran, aucun test ne pouvait le signaler. */
textarea {
    font-family: inherit;   /* sinon : police à chasse fixe du navigateur */
    resize: vertical;       /* l'élargir casserait la mise en page */
    min-height: 5rem;
}

input:focus, select:focus, textarea:focus,
.bouton:focus-visible, .bouton-theme:focus-visible {
    outline: 2px solid var(--bleu-goutte);
    outline-offset: 1px;
}

.champ { margin-bottom: 1rem; }

.message-erreur {
    background: color-mix(in srgb, var(--erreur) 12%, transparent);
    border: 1px solid var(--erreur);
    color: var(--erreur);
    padding: .6rem .8rem;
    border-radius: var(--rayon);
    margin-bottom: 1rem;
}

/* ---------- Page de connexion ---------- */
.page-connexion {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1.5rem;
}

.bloc-connexion { width: 100%; max-width: 400px; }

.bloc-connexion .marque-connexion {
    text-align: center;
    margin-bottom: 1.5rem;
}

.bloc-connexion .marque-connexion img { width: 96px; height: auto; }

.bloc-connexion .marque-connexion .nom {
    font-size: 1.75rem;
    font-weight: 700;
    letter-spacing: .06em;
    color: var(--primaire);
    margin-top: .5rem;
}

/* ---------- Signature tactile (Lot 5.2) ---------- */
.zone-signature {
    border: 2px dashed var(--bordure);
    border-radius: 8px;
    background: #ffffff;          /* toujours clair : la signature s'imprime */
    position: relative;
    overflow: hidden;
}

.zone-signature canvas {
    display: block;
    width: 100%;
    height: 180px;
    /* ⚠️ Sans ceci, le doigt fait défiler la page au lieu de tracer. */
    touch-action: none;
    cursor: crosshair;
}

/* Consigne affichée dans le cadre, effacée dès le premier trait. */
.zone-signature .consigne {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    pointer-events: none;
    color: #9aa4b0;
    font-size: .9rem;
}

.zone-signature.signature-tracee .consigne { display: none; }

/* Note : l'image de signature n'est affichée nulle part dans l'application.
   Elle est stockée en privé (StockagePrive, dont url() échoue volontairement)
   et ne ressortira que sur le PDF de la feuille d'émargement. Les écrans se
   contentent d'indiquer « signé le … » — il n'y a aucune raison d'exposer la
   signature manuscrite d'une personne à qui que ce soit d'autre. */

/* ---------- Divers ---------- */
/* Utilisée depuis le Lot 1 dans les gabarits, mais jamais définie : le texte
   « gras » ne l'était pas. Repéré au Lot 4 en relisant la feuille de style. */
.gras { font-weight: 600; }

.vide {
    text-align: center;
    padding: 2.5rem 1rem;
    color: var(--texte-doux);
}

.liste-nue { list-style: none; padding: 0; margin: 0; }
.liste-nue li { padding: .4rem 0; border-bottom: 1px solid var(--bordure); }
.liste-nue li:last-child { border-bottom: 0; }

.grille-2 {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: 1.25rem;
}

/* Champs courts alignés côte à côte (saisie des résultats, Lot 5.4). Le
   `minmax` retombe seul sur une colonne unique en dessous de ~330 px : pas de
   media query, donc rien à maintenir en double, et aucun débordement en 375 px. */
.grille-champs {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: .6rem .75rem;
}

/* ---------- Vignettes chiffrées du tableau de bord (Lot 9.2) ---------- */
/* Même principe que `.grille-champs` : `auto-fit` + `minmax` retombent seuls
   sur une colonne en dessous de ~360 px. Aucune media query à maintenir, et
   aucun débordement en 375 px. */
.vignettes {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
    gap: .75rem;
}

.vignette {
    background: var(--surface-alt);
    border: 1px solid var(--bordure);
    border-radius: var(--rayon);
    padding: .85rem 1rem;
    display: block;
    color: inherit;
    text-decoration: none;
}

a.vignette:hover { border-color: var(--primaire); }

.vignette .chiffre {
    font-size: 1.75rem;
    font-weight: 600;
    line-height: 1.1;
    display: block;
}

.vignette .libelle { font-size: .875rem; color: var(--texte-doux); }

/* ⚠️ La couleur porte l'attention, jamais l'information seule : le libellé dit
   toujours de quoi il s'agit. Un daltonien lit le même écran que les autres. */
.vignette-alerte { border-color: var(--alerte); }
.vignette-alerte .chiffre { color: var(--alerte); }
.vignette-calme .chiffre { color: var(--succes); }

/* ---------- Encart d'information ou d'avertissement ---------- */
.encart {
    border-left: 4px solid var(--primaire);
    background: var(--surface-alt);
    border-radius: var(--rayon);
    padding: .75rem 1rem;
    margin-bottom: 1rem;
}

.encart-alerte { border-left-color: var(--alerte); }

/* ---------- Agenda (Lot 9.1) ---------- */
.agenda-vues {
    display: flex;
    gap: .4rem;
    align-items: center;
    flex-wrap: wrap;
    margin-bottom: 1rem;
}

/* La grille de mois ne peut pas tenir en 375 px sans devenir illisible : elle
   défile dans son `.tableau-conteneur`, comme les tableaux larges du projet.
   Le corps de page, lui, ne défile jamais latéralement. */
.agenda-mois {
    display: grid;
    grid-template-columns: repeat(7, minmax(104px, 1fr));
    gap: 1px;
    background: var(--bordure);
    border: 1px solid var(--bordure);
    border-radius: var(--rayon);
    overflow: hidden;
    min-width: 728px;
}

.agenda-entete {
    background: var(--surface-alt);
    padding: .4rem .5rem;
    font-size: .8rem;
    font-weight: 600;
    color: var(--texte-doux);
    text-align: center;
}

.agenda-case {
    background: var(--surface);
    min-height: 92px;
    padding: .3rem;
}

/* Estompé, jamais masqué : sans cela on croit lire le mois affiché alors qu'on
   regarde le voisin. */
.agenda-case.hors-periode { background: var(--surface-alt); }
.agenda-case.hors-periode .agenda-numero { opacity: .45; }

/* ⚠️ Le jour courant est marqué par une bordure ET par le fond, pas par la
   seule couleur : la bordure reste perceptible en niveaux de gris. */
.agenda-case.aujourdhui {
    box-shadow: inset 0 0 0 2px var(--primaire);
}

.agenda-numero {
    font-size: .8rem;
    font-weight: 600;
    color: var(--texte-doux);
    margin-bottom: .2rem;
}

.agenda-creneau {
    display: block;
    background: color-mix(in srgb, var(--bleu-goutte) 18%, transparent);
    border-left: 3px solid var(--primaire);
    border-radius: 4px;
    padding: .2rem .35rem;
    margin-bottom: .2rem;
    font-size: .78rem;
    line-height: 1.25;
    color: var(--texte);
    text-decoration: none;
    overflow: hidden;
    text-overflow: ellipsis;
}

.agenda-creneau:hover { filter: brightness(1.08); }
.agenda-creneau .heure { font-weight: 600; margin-right: .25rem; }

.agenda-jour {
    border-top: 1px solid var(--bordure);
    padding-top: .75rem;
    margin-top: .75rem;
}

.agenda-jour:first-of-type { border-top: 0; margin-top: 0; padding-top: 0; }

/* ⚠️ PAS `text-transform: capitalize` : il met une majuscule à CHAQUE mot et
   produit « Lundi 3 Août 2026 ». En français, les noms de mois et de jours
   sont des noms communs — seule l'initiale de la phrase se capitalise. */
.agenda-jour h3 { font-size: 1rem; }
.agenda-jour h3::first-letter { text-transform: uppercase; }
.agenda-jour.aujourdhui h3 { color: var(--primaire); }

/* ---------- Onglets (Lot 9.3) ---------- */
/* ⚠️ La barre est créée par `onglets.js`. Sans lui, aucune de ces règles ne
   s'applique et les sections restent empilées : c'est voulu. */
.onglets {
    display: flex;
    gap: .25rem;
    flex-wrap: wrap;
    border-bottom: 2px solid var(--bordure);
    margin-bottom: 1.25rem;
}

.onglet {
    background: transparent;
    border: 0;
    border-bottom: 3px solid transparent;
    margin-bottom: -2px;
    padding: .6rem .9rem;
    font-size: .95rem;
    font-family: inherit;
    font-weight: 600;
    color: var(--texte-doux);
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: .4rem;
}

.onglet:hover { color: var(--texte); }

/* L'onglet actif est marqué par la couleur ET par le trait : le trait reste
   perceptible en niveaux de gris. */
.onglet.actif {
    color: var(--primaire);
    border-bottom-color: var(--primaire);
}

.onglet:focus-visible {
    outline: 2px solid var(--primaire);
    outline-offset: -2px;
    border-radius: var(--rayon) var(--rayon) 0 0;
}

/* Compteur repris sur l'onglet : replier une section ne doit pas masquer ce
   qui appelle une action.

   ⚠️ `--alerte-texte` et surtout PAS `#ffffff` en dur. `--alerte` change de
   luminosité entre les thèmes (sombre en clair, clair en sombre) : un blanc
   figé donnait 6,39 en thème clair et **2,22** en thème sombre — illisible.
   Même appariement que `--primaire` / `--primaire-texte`. */
.onglet-compteur {
    background: var(--alerte);
    color: var(--alerte-texte);
    border-radius: 999px;
    padding: 0 .4rem;
    font-size: .75rem;
    line-height: 1.5;
    min-width: 1.3em;
    text-align: center;
}

/* ---------- Barre de progression des heures (Lot 9.3) ---------- */
/* Distincte de `.jauge` (remplissage d'une session, en places) : celle-ci
   porte des heures et affiche son libellé à côté. */
.progression {
    display: flex;
    align-items: center;
    gap: .6rem;
}

.progression-piste {
    flex: 1;
    min-width: 80px;
    height: 10px;
    background: var(--surface-alt);
    border: 1px solid var(--bordure);
    border-radius: 999px;
    overflow: hidden;
}

.progression-piste span {
    display: block;
    height: 100%;
    background: var(--succes);
}

/* ⚠️ Provisoire ≠ mauvais. Tant que des feuilles restent ouvertes, le total
   sous-estime (Lot 5.6) : la barre se distingue alors visuellement, et le
   libellé le dit en toutes lettres — la couleur seule ne porte jamais
   l'information. */
.progression-piste.provisoire span { background: var(--texte-doux); }

.progression-valeur { font-size: .85rem; white-space: nowrap; }

/* ---------- Tableaux exploitables (Lot 9.5) ---------- */
/* ⚠️ Créés par `tableau.js`. Sans lui, le tableau reste un tableau ordinaire :
   aucune de ces règles ne s'applique et rien ne manque à la lecture. */
.tableau-outils {
    display: flex;
    gap: .6rem;
    align-items: center;
    flex-wrap: wrap;
    margin-bottom: .75rem;
}

.tableau-recherche {
    flex: 1;
    min-width: 180px;
    max-width: 340px;
}

/* Le compteur passe en alerte quand le filtre ne ramène rien : sans quoi un
   tableau vide se lit « cassé » aussi bien que « aucun résultat ». */
.tableau-outils .aucun-resultat { color: var(--alerte); font-weight: 600; }

th.triable { cursor: pointer; user-select: none; }
th.triable:hover { color: var(--texte); }

/* ⚠️ La flèche est un caractère, pas une image de fond : elle reste lisible
   en fort contraste et se lit par une synthèse vocale avec `aria-sort`. */
th.tri-croissant::after { content: " ▲"; font-size: .7em; }
th.tri-decroissant::after { content: " ▼"; font-size: .7em; }

th.triable:focus-visible {
    outline: 2px solid var(--primaire);
    outline-offset: -2px;
}

/* ---------- Impression ---------- */
/* Le formateur imprime sa liste de participants pour la salle. Ce qui ne sert
   qu'à l'écran n'a rien à faire sur le papier — et l'encre coûte. */
@media print {
    .entete,
    .tableau-outils,
    .onglets,
    .bouton,
    .agenda-vues { display: none !important; }

    /* Les volets repliés par `onglets.js` se rouvrent à l'impression : on
       imprime le dossier, pas l'onglet qu'on avait sous les yeux. */
    [data-onglet][hidden] { display: block !important; }

    .carte {
        box-shadow: none;
        border-color: #999;
        break-inside: avoid;
    }

    /* Le papier est blanc : on force le thème clair, quel que soit celui de
       l'écran — même règle que les PDF générés, toujours en clair. */
    body { background: #fff; color: #000; }
}

@media (max-width: 600px) {
    .contenu { padding: 1rem; }
    .entete { gap: .75rem; }
    .marque img { height: 32px; }
}
