/* ═══════════════════════════════════════════════════════════════════════════
   CHARTE GRAPHIQUE DGO EXPERTISES FORMATIONS
   Identité : OR (#C8A95A) + BLEU NUIT (#1C2340).
   Interdits : orange vif, noir pur comme couleurs d'identité.
   ═══════════════════════════════════════════════════════════════════════════ */

:root{
  --or:        #C8A95A; /* accent principal — or premium */
  --or-fonce:  #A8863E; /* survols / bordures accent */
  --bleu-nuit: #1C2340; /* structural : en-têtes, barres, tableaux */
  --bleu-2:    #2A3358; /* variation claire du bleu nuit */
  --gris-clair:#F3F3F3; /* fonds, respiration, lignes alternées */
  --gris-bord: #DDDDDD; /* bordures fines */
  --texte:     #111111; /* texte courant */
  --texte-doux:#555555; /* légendes, mentions */
  --blanc:     #FFFFFF;
  --ok:        #2E7D32;
  --alerte:    #C62828;
  --attente:   #8A6508; /* assombri : le blanc n atteignait que 3,25:1 dessus */

  /* Tokens dérivés : mêmes valeurs que les anciens littéraux — ils rendent les
     surfaces thémables (déclinaison sombre par simple surcharge de :root). */
  --surface-survol: #ECE7DA; /* survol des lignes de tableau (or très pâle) */
  --danger:         #7E1B1B; /* rouge assombri (boutons danger, badge cloche) */
  --danger-fonce:   #641414; /* survol du rouge assombri */
  --fond-ok:        #E6F1E7; /* fond des messages de succès */
  --fond-erreur:    #F9E7E7; /* fond des messages d'erreur */
  --we-fond:        #ECECEC; /* cases week-end du calendrier mural */
  --we-texte:       #A0A0A0;
  --we-ouvre:       #1F5E3C; /* lettre S/D du week-end (vert foncé lisible) */
  --cellule-edition:#FFF7E0; /* cellule en cours de saisie (calendrier) */
  --voile-a:        #E9E9E9; /* hachures des demi-journées hors centre */
  --voile-b:        #F5F5F5;
  --bulle-moi:      #F3E7C8; /* bulle de message de l'auteur (or très clair) */
  --bulle-moi-bord: #E4D3A6;

  --police-titres: 'Montserrat', 'Segoe UI', system-ui, sans-serif;
  --police-texte: 'Calibri', 'Segoe UI', system-ui, sans-serif;
  --rayon: 8px;
  --ombre: 0 2px 10px rgba(28, 35, 64, 0.10);

  /* ═══ SOCLE VISUEL ═══════════════════════════════════════════════════════
     L'identité reste OR + BLEU NUIT. Ce qui change, c'est la RIGUEUR de son
     application : l'interface comptait 27 tailles de police, 66 valeurs
     d'espacement et 14 rayons différents. Cette dispersion, plus que les
     couleurs, est ce qui donnait une impression d'à-peu-près. Les échelles
     ci-dessous sont volontairement courtes : on choisit dedans, on n'invente
     plus de valeur.

     Public : élèves, entreprises clientes et partenaires, formateurs. Chacun
     juge l'établissement sur cet écran — il doit inspirer le sérieux d'une
     institution, pas d'un outil interne. ══════════════════════════════════ */

  /* Or LISIBLE. L'or d'identité (#C8A95A) sur fond clair plafonne à 2,2:1 de
     contraste : illisible au sens WCAG. Il reste réservé aux aplats et aux
     filets ; le texte doré utilise ces deux teintes plus profondes. */
  --attente-texte: #6E5106; /* ambre sur fond CLAIR (textes, jamais aplat) */
  --or-texte:      #7A5F22; /* or sur fond clair — 6,2:1, lisible partout */
  --or-texte-doux: #8F7233; /* or sur fond clair, texte large ≥ 1,25 rem */

  /* Surfaces : un blanc cassé très légèrement chaud plutôt qu'un gris neutre,
     pour poser l'or sans le faire jurer. */
  --fond:          #F6F5F2;
  --surface:       #FFFFFF;
  --surface-basse: #FAF9F6;
  --bord:          #E4E1D9; /* séparation douce, remplace le trait dur #DDD */
  --bord-fort:     #CFCABC;

  /* Échelle typographique — sept crans, pas un de plus. */
  --t-xs:   0.75rem;   /* mentions légales, unités */
  --t-sm:   0.8125rem; /* légendes, aide */
  --t-base: 0.9375rem; /* texte courant */
  --t-md:   1.0625rem; /* sous-titres */
  --t-lg:   1.25rem;   /* titres de section */
  --t-xl:   1.5rem;    /* titre de page */
  --t-2xl:  1.875rem;  /* chiffres de pilotage */

  /* Espacements — multiples de 4, un rythme vertical unique. */
  --e-1: 4px;  --e-2: 8px;  --e-3: 12px; --e-4: 16px;
  --e-5: 20px; --e-6: 24px; --e-7: 32px; --e-8: 48px;

  /* Rayons et élévations. Les ombres sont teintées de bleu nuit : une ombre
     grise sur fond chaud donne l'aspect « boîte posée » des interfaces datées. */
  --r-sm: 6px; --r-md: 10px; --r-lg: 14px; --r-pill: 999px;
  --niv-1: 0 1px 2px rgba(28, 35, 64, 0.06);
  --niv-2: 0 2px 8px rgba(28, 35, 64, 0.08);
  --niv-3: 0 8px 24px rgba(28, 35, 64, 0.12);

  --niv-4: 0 16px 48px rgba(28, 35, 64, 0.18); /* surfaces flottantes : connexion, pop-up */
  --transition: 140ms ease;
}

/* ── Base ─────────────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  font-family: var(--police-texte);
  font-size: 16px;
  line-height: 1.55;
  color: var(--texte);
  background: var(--fond);
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4 {
  font-family: var(--police-titres);
  font-weight: 700;
  margin: 0 0 var(--e-3);
  line-height: 1.25;
  text-wrap: balance;
}

/* H1 en or majuscules, comme l'impose la charte — mais dans l'or PROFOND :
   l'or d'identité sur fond clair ne dépasse pas 2,2:1 et n'est pas lisible. */
h1 {
  color: var(--or-texte);
  text-transform: uppercase;
  font-size: var(--t-xl);
  letter-spacing: 0.045em;
}

/* H2 en bleu nuit avec filet or dessous (charte). Le filet est un accent, pas
   une bordure de tableau : il ne court plus sur toute la largeur. */
h2 {
  color: var(--bleu-nuit);
  font-size: var(--t-lg);
  padding-bottom: var(--e-2);
  border-bottom: none;
  position: relative;
}
h2::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: 0;
  width: 44px;
  height: 3px;
  background: var(--or);
  border-radius: var(--r-pill);
}
/* Titre sans filet : à l'intérieur d'une carte déjà délimitée. */
h2.sans-filet::after { display: none; }

h3 { color: var(--bleu-nuit); font-size: var(--t-md); }
h4 { color: var(--bleu-nuit); font-size: var(--t-base); }

p { margin: 0 0 var(--e-3); }

a { color: var(--or-texte); text-decoration: none; }
a:hover { text-decoration: underline; }

/* Anneau de focus unique. L'or seul ne tient pas : 2,26:1 sur une carte
   blanche, quand WCAG 1.4.11 exige 3:1 pour un indicateur d'interface. Le trait
   est donc en bleu nuit (14,5:1) et l'or vient en halo — l'identité reste
   visible, la lisibilité ne dépend plus d'elle. */
:focus-visible {
  outline: 2px solid var(--bleu-nuit);
  outline-offset: 2px;
  box-shadow: 0 0 0 5px rgba(200, 169, 90, 0.45);
  border-radius: var(--r-sm);
}

/* Aller au contenu : premier élément focusable de la page. Sur téléphone, le
   menu précède le contenu dans le document — sans ce lien, il faut traverser
   une cinquantaine d'entrées avant d'atteindre le champ à remplir. */
.lien-evitement {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: var(--bleu-nuit);
  color: var(--blanc);
  padding: var(--e-3) var(--e-5);
  border-radius: 0 0 var(--r-md) 0;
  font-family: var(--police-titres);
  font-weight: 600;
}
.lien-evitement:focus {
  left: 0;
  text-decoration: none;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; animation: none !important; }
}

p { line-height: 1.5; }

/* ── Structure applicative : barre haute + navigation latérale ────────────── */
.barre-haute {
  display: flex;
  align-items: center;
  gap: 14px;
  background: var(--bleu-nuit);
  color: var(--blanc);
  padding: 10px 18px;
  border-bottom: 3px solid var(--or);
  position: sticky;
  top: 0;
  z-index: 50;
}

/* Le logo (texte noir + livre bleu, fond transparent) est posé sur une plaque
   blanche pour rester lisible sur la barre bleu nuit. */
.barre-haute .logo-plaque {
  display: flex;
  align-items: center;
  background: var(--blanc);
  border-radius: var(--rayon);
  padding: 5px 12px;
  flex-shrink: 0;
}

.barre-haute .logo-plaque .logo {
  height: 30px;
  width: auto;
  display: block;
}

.barre-haute .espace { flex: 1; }

.barre-haute .identite {
  text-align: right;
  font-size: 0.85rem;
  line-height: 1.25;
}

.barre-haute .identite .role {
  color: var(--or);
  text-transform: capitalize;
  font-size: 0.75rem;
}

.disposition {
  display: flex;
  min-height: calc(100vh - 61px);
}

.navigation {
  width: 244px;
  flex-shrink: 0;
  background: var(--bleu-nuit);
  padding: var(--e-4) 0 var(--e-7);
  overflow-y: auto;
}

/* Les entrées respirent : c'est la densité, plus que la couleur, qui donnait
   l'impression d'un menu d'outil interne. */
.navigation a {
  display: block;
  color: rgba(255, 255, 255, 0.82);
  padding: var(--e-2) var(--e-5);
  font-size: var(--t-base);
  border-left: 3px solid transparent;
  transition: background var(--transition), color var(--transition);
}

.navigation a:hover {
  background: rgba(255, 255, 255, 0.06);
  color: var(--blanc);
  text-decoration: none;
}

.navigation a.actif {
  border-left-color: var(--or);
  background: rgba(200, 169, 90, 0.14);
  color: var(--or);
  font-weight: 600;
}

/* Chapitres du menu (sous-catégories repliables). */
/* Filtre du menu : une cinquantaine d écrans, deux lettres suffisent. */
.nav-recherche { padding: 0 10px 10px; }
.nav-recherche input[type="search"] {
  width: 100%; margin: 0; padding: 7px 10px;
  border: 1px solid var(--gris-bord); border-radius: 6px;
  font-size: 0.85rem; background: var(--blanc); color: var(--texte);
}
.nav-recherche input[type="search"]:focus-visible { outline: 2px solid var(--or); outline-offset: 1px; }
.nav-filtre-vide { margin: 8px 2px 0; font-size: 0.8rem; color: var(--gris-bord); }
.visuellement-cache {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

.nav-chapitre > summary {
  list-style: none;
  cursor: pointer;
  padding: var(--e-5) var(--e-5) var(--e-2);
  font-family: var(--police-titres);
  font-size: var(--t-xs);
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--or);
  font-weight: 700;
  user-select: none;
  opacity: 0.9;
}
.nav-chapitre > summary::-webkit-details-marker { display: none; }
.nav-chapitre > summary::after { content: '▾'; float: right; opacity: 0.55; }
.nav-chapitre[open] > summary::after { content: '▴'; }
.nav-chapitre > a { padding-left: var(--e-7); font-size: var(--t-base); }

/* Le contenu était collé à gauche : sur un écran large, l application
   paraissait posée dans un coin. Il est désormais centré dans la place
   disponible, avec une largeur de lecture bornée. */
.contenu {
  flex: 1;
  min-width: 0;
  padding: var(--e-7) var(--e-7) var(--e-8);
  max-width: 1320px;
  margin: 0 auto;
  width: 100%;
}

/* Page de secours d'émargement hors-ligne (hors-ligne-emargement.html). */
.page-secours { max-width: 720px; margin: 0 auto; }

/* ── Bandeau « voir en tant que » ─────────────────────────────────────────── */
.bandeau-impersonation {
  background: var(--attente);
  color: var(--blanc);
  padding: 8px 18px;
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 0.9rem;
}

.bandeau-impersonation form { margin-left: auto; }

/* ── Pop-up d'anniversaire (jour J, CDC §6.6) ─────────────────────────────── */
.voile-anniversaire {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: rgba(28, 35, 64, 0.72); /* bleu nuit translucide */
}
.carte-anniversaire {
  background: var(--blanc);
  border-top: 4px solid var(--or);
  border-radius: 10px;
  max-width: 420px;
  width: 100%;
  padding: 28px 26px;
  text-align: center;
  box-shadow: var(--niv-4);
}
.carte-anniversaire h2 { color: var(--bleu-nuit); margin: 6px 0 10px; }
.carte-anniversaire p { color: var(--texte-doux); margin: 0 0 20px; }
.anniversaire-emoji { font-size: 3rem; line-height: 1; }

/* ── Éditeur de maquette : saisie en ligne type tableur ───────────────────── */
.saisie-cellule {
  width: 100%;
  box-sizing: border-box;
  border: 1px solid transparent;
  background: transparent;
  padding: 6px 8px;
  border-radius: 4px;
  font: inherit;
  color: inherit;
}
.saisie-cellule:hover { border-color: var(--gris-bord); }
/* La saisie en ligne (matières, volumes) supprimait elle aussi l'anneau : sur
   une grille de cellules identiques, il est le seul repère de position. */
.saisie-cellule:focus { border-color: var(--or-fonce); background: var(--blanc); }
.saisie-cellule.enregistre { background: rgba(46, 125, 50, 0.15); border-color: var(--ok); } /* flash de confirmation */
.saisie-cellule.erreur { background: rgba(198, 40, 40, 0.12); border-color: var(--alerte); }
.col-volume { width: 190px; }
.col-coef { width: 120px; }
.col-couleur { width: 250px; }
.col-actions { width: 90px; }

/* ── Cartes et encadrés ───────────────────────────────────────────────────── */
.carte {
  background: var(--surface);
  border: 1px solid var(--bord);
  border-radius: var(--r-md);
  box-shadow: var(--niv-1);
  padding: var(--e-6);
  margin-bottom: var(--e-5);
}

.encadre {
  background: var(--gris-clair);
  border-left: 4px solid var(--or);
  padding: 12px 16px;
  margin: 14px 0;
  border-radius: 0 var(--rayon) var(--rayon) 0;
}

/* ── La barre latérale OR de 4 px : UN seul sens ───────────────────────────
   La charte la réserve aux encadrés importants. Elle avait fini par marquer
   sept choses sans rapport — un encadré, un panneau de formulaire, une ligne
   de tableau, une notification non lue, un élément de liste, un panneau de
   création — c'est-à-dire plus rien du tout.
   Elle ne signifie désormais qu'une chose : CECI DEMANDE VOTRE ATTENTION
   (.encadre, .encadre-accent, .notif-non-lue). Tout ce qui n'est que
   structure se contente d'une bordure neutre. */
.encadre-accent { border-left: 4px solid var(--or); }

/* Jour hors centre dans l'éditeur de semaine (entreprise/vacances) : atténué. */
.carte-hors-centre { opacity: 0.72; }

/* Résumé repliable (ex. « Répartition par matière »). */
details.carte > summary { cursor: pointer; font-family: var(--police-titres); color: var(--bleu-nuit); }

/* Mode d'emploi clavier du calendrier : replié par défaut, jamais masqué. */
.aide-clavier { font-size: var(--t-sm); }
.aide-clavier > summary {
  cursor: pointer;
  font-family: var(--police-titres);
  font-weight: 600;
  color: var(--bleu-nuit);
}
.aide-clavier ul { margin: var(--e-2) 0 0; padding: 0; }
.sans-puces { list-style: none; padding-left: 0; }
.sans-puces > li { margin-bottom: var(--e-1); }

/* Valeur à recopier telle quelle : adresse de connexion, mot de passe
   provisoire. La chasse fixe évite de confondre un « l » et un « 1 ». */
code {
  font-family: Consolas, 'Courier New', monospace;
  font-size: 0.94em;
  padding: 1px 5px;
  border-radius: var(--r-sm);
  background: var(--surface-basse);
  border: 1px solid var(--bord);
  color: var(--texte);
  word-break: break-all;
}

kbd {
  display: inline-block;
  padding: 1px 6px;
  border: 1px solid var(--bord-fort);
  border-bottom-width: 2px;
  border-radius: var(--r-sm);
  background: var(--surface-basse);
  font-family: var(--police-texte);
  font-size: 0.85em;
  color: var(--texte);
  white-space: nowrap;
}

/* Blocs de séquence du déroulé pédagogique. La légende est fille directe du
   fieldset — c'est ce qui nomme le groupe — donc le bouton « Retirer » se cale
   en haut à droite plutôt que de partager une ligne avec elle. */
.seq-bloc { border: 1px solid var(--gris-bord); position: relative; }
.seq-bloc legend { font-family: var(--police-titres); font-weight: 600; color: var(--bleu-nuit); padding: 0 4px; }
.seq-retirer { position: absolute; top: var(--e-3); right: var(--e-4); }

/* Ligne d'ajout rapide (éditeur de semaine) : champs alignés, repli sur mobile. */
.ligne-ajout {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  padding-top: 12px;
  border-top: 1px dashed var(--gris-bord);
}
.ligne-ajout select,
.ligne-ajout input[type="time"] { margin: 0; width: auto; }

/* ── Tableaux premium ─────────────────────────────────────────────────────── */
.conteneur-tableau { overflow-x: auto; }

/* Tableaux : en-tête bleu nuit et texte or, comme l'impose la charte. Ce qui
   change, c'est la respiration — les lignes zébrées et les filets sur chaque
   cellule créaient un quadrillage lourd. Une séparation horizontale discrète
   suffit à suivre une ligne, et les chiffres s'alignent enfin. */
.tableau-premium {
  width: 100%;
  border-collapse: collapse;
  background: var(--surface);
  font-size: var(--t-base);
}

.tableau-premium th {
  background: var(--bleu-nuit);
  color: var(--or);
  font-family: var(--police-titres);
  font-weight: 600;
  font-size: var(--t-xs);
  text-transform: uppercase;
  letter-spacing: 0.07em;
  text-align: left;
  padding: var(--e-3) var(--e-4);
  white-space: nowrap;
}
.tableau-premium thead tr:first-child th:first-child { border-top-left-radius: var(--r-sm); }
.tableau-premium thead tr:first-child th:last-child { border-top-right-radius: var(--r-sm); }

.tableau-premium td {
  padding: var(--e-3) var(--e-4);
  border-bottom: 1px solid var(--bord);
  vertical-align: middle;
}
/* Les colonnes de chiffres s'alignent au chiffre près. */
.tableau-premium td.texte-droite, .tableau-premium td.num { font-variant-numeric: tabular-nums; }

.tableau-premium tbody tr:nth-child(even) { background: var(--surface-basse); }
.tableau-premium tbody tr:hover { background: var(--surface-survol); }
.tableau-premium tbody tr:last-child td { border-bottom: none; }

/* Tri au clic sur l'en-tête (tableaux « data-triable », voir js/tri-tableau.js). */
.tableau-premium th[data-tri] { cursor: pointer; user-select: none; }
.tableau-premium th[data-tri]:hover { background: var(--bleu-2); }
.tableau-premium th[data-tri]:focus-visible { outline: 2px solid var(--or); outline-offset: -2px; }
.tri-fleche { color: var(--or); font-size: 0.85em; }

/* ── Boutons ──────────────────────────────────────────────────────────────── */
.bouton, .bouton-secondaire, .bouton-danger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--e-2);
  min-height: 38px;
  font-family: var(--police-titres);
  font-weight: 600;
  font-size: var(--t-base);
  padding: 0 var(--e-5);
  border-radius: var(--r-sm);
  border: 1px solid transparent;
  cursor: pointer;
  text-decoration: none;
  transition: background var(--transition), border-color var(--transition), box-shadow var(--transition);
}

.bouton { background: var(--or); color: var(--bleu-nuit); box-shadow: var(--niv-1); }
.bouton:hover { background: var(--or-fonce); color: var(--blanc); text-decoration: none; }

.bouton-secondaire { background: var(--surface); color: var(--bleu-nuit); border-color: var(--bord-fort); }
.bouton-secondaire:hover { border-color: var(--or); background: var(--surface-basse); text-decoration: none; }

/* Rouge assombri (retour direction : l'ancien rouge vif fatiguait l'œil). */
.bouton-danger { background: var(--danger); color: var(--blanc); }
.bouton-danger:hover { background: var(--danger-fonce); }

/* Commande secondaire — mais commande quand même : « Retard », « Exclure »,
   « Faire signer », « Effacer » de la console d’émargement en dépendent. L’or
   d’identité y plafonnait à 2,26:1 sur fond clair : un formateur en salle, sous
   un néon, ne distinguait pas ces boutons du fond. Or profond : 6,2:1. */
.bouton-discret {
  background: none;
  border: none;
  color: var(--or-texte);
  cursor: pointer;
  font-size: var(--t-sm);
  font-weight: 600;
  text-decoration: underline;
  padding: 0;
}

/* ── Formulaires ──────────────────────────────────────────────────────────── */
.champ { margin-bottom: var(--e-4); }

.champ label {
  display: block;
  font-weight: 600;
  font-size: var(--t-sm);
  color: var(--bleu-nuit);
  margin-bottom: var(--e-1);
}

/* Étiquette enveloppante : là où les blocs se répètent ou sont clonés par
   script, le champ vit DANS son étiquette (association implicite) plutôt que
   de dépendre d'identifiants uniques fragiles. L'intitulé porte alors la mise
   en forme, l'étiquette n'est plus qu'un conteneur. */
.champ label:has(> input, > select, > textarea) { margin-bottom: 0; }

.intitule-champ {
  display: block;
  font-weight: 600;
  font-size: var(--t-sm);
  color: var(--bleu-nuit);
  margin-bottom: var(--e-1);
}

.champ input, .champ select, .champ textarea {
  width: 100%;
  min-height: 38px;
  padding: var(--e-2) var(--e-3);
  border: 1px solid var(--bord-fort);
  border-radius: var(--r-sm);
  font-family: var(--police-texte);
  font-size: var(--t-base);
  background: var(--surface);
  color: var(--texte);
  transition: border-color var(--transition), box-shadow var(--transition);
}

/* On ne supprime plus l anneau : il porte seul l information « je suis ici »
   pour qui navigue au clavier. La bordure et le halo restent en renfort. */
.champ input:focus-visible, .champ select:focus-visible, .champ textarea:focus-visible {
  border-color: var(--or-fonce);
}
.champ input:focus, .champ select:focus, .champ textarea:focus {
  border-color: var(--or-fonce);
}

/* Cases à cocher / boutons radio : ne pas étirer à 100 % comme les autres champs. */
.champ input[type="checkbox"], .champ input[type="radio"] { width: auto; margin-right: 6px; }

.champ .aide { font-size: 0.8rem; color: var(--texte-doux); margin-top: 4px; }

.grille-champs {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 0 18px;
}

/* Couples « intitulé / valeur » en lecture seule (bulletin, fiche profil).
   Un <label> n'y a pas sa place : il annonce un champ de saisie, et il n'y en
   a aucun — le lecteur d'écran cherche alors une zone qui n'existe pas.
   La liste de définitions dit la vraie relation : ce terme vaut cette valeur.
   L'habillage reste identique à celui d'un formulaire. */
.fiche-donnees { margin: 0; }
.fiche-terme {
  font-weight: 600;
  font-size: var(--t-sm);
  color: var(--bleu-nuit);
  margin-bottom: var(--e-1);
}
.fiche-valeur { margin: 0 0 var(--e-4); }

fieldset {
  border: 1px solid var(--bord);
  border-radius: var(--r-md);
  margin: 0 0 var(--e-5);
  padding: var(--e-4) var(--e-5);
}

legend {
  font-family: var(--police-titres);
  font-weight: 600;
  font-size: 0.85rem;
  color: var(--bleu-nuit);
  text-transform: uppercase;
  padding: 0 8px;
}

/* ── Badges et statuts ────────────────────────────────────────────────────── */
.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--e-1);
  font-family: var(--police-titres);
  font-size: var(--t-xs);
  font-weight: 600;
  padding: 2px var(--e-3);
  border-radius: var(--r-pill);
  white-space: nowrap;
  color: var(--blanc);
}

.badge-ok { background: var(--ok); }
.badge-alerte { background: var(--alerte); }
.badge-attente { background: var(--attente); }
.badge-neutre { background: var(--bleu-2); }
.badge-role { background: var(--bleu-nuit); color: var(--or); text-transform: capitalize; }

/* ── Messages éphémères ───────────────────────────────────────────────────── */
.flash {
  padding: 12px 16px;
  border-radius: var(--rayon);
  margin-bottom: 18px;
  font-size: 0.92rem;
  border-left: 4px solid;
}

.flash-succes { background: var(--fond-ok); border-color: var(--ok); color: var(--ok); }
.flash-erreur { background: var(--fond-erreur); border-color: var(--alerte); color: var(--alerte); }
.flash-info { background: var(--gris-clair); border-color: var(--or); color: var(--texte); }

/* ── Pages publiques (connexion, réinitialisation…) ───────────────────────── */
.page-publique {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--e-5);
  background: linear-gradient(160deg, var(--bleu-nuit) 0%, var(--bleu-2) 100%);
  padding: 20px;
}

.carte-publique {
  background: var(--blanc);
  border-radius: var(--rayon);
  box-shadow: var(--niv-4);
  border-top: 4px solid var(--or);
  width: 100%;
  max-width: 420px;
  padding: 32px;
}

.carte-publique .entete-connexion { text-align: center; margin-bottom: 24px; }

/* Logo large affiché en bandeau sur la carte blanche de connexion. */
.carte-publique .entete-connexion .logo {
  width: 100%;
  max-width: 300px;
  height: auto;
  display: block;
  margin: 0 auto;
}

.qr-2fa { display: block; margin: 14px auto; border: 1px solid var(--gris-bord); border-radius: var(--rayon); }

/* ── Utilitaires ──────────────────────────────────────────────────────────── */
/* Formulaire aligné dans une cellule de tableau (actions en ligne). */
.form-inline { display: inline; }

/* ── Calendrier annuel (rythme d'alternance) ───────────────────────────────── */
.cal-table { width: 100%; border-collapse: collapse; font-size: 0.8rem; }
.cal-table th, .cal-table td {
  border: 1px solid var(--gris-bord);
  padding: 3px 4px;
  text-align: center;
  vertical-align: middle;
}
.cal-table thead th { background: var(--bleu-nuit); color: var(--or); font-weight: 700; }
.cal-table td.cal-obs { text-align: left; font-size: var(--t-xs); color: var(--texte-doux); min-width: 120px; }
.cal-table td.cal-iso { color: var(--texte-doux); font-weight: 700; }

/* Une case-jour : n° du jour + deux barres (matin / après-midi). */
.cal-jour { display: flex; flex-direction: column; align-items: stretch; gap: 2px; min-width: 26px; }
.cal-jour .num { font-size: var(--t-xs); font-weight: 700; line-height: 1; color: var(--texte-doux); }
/* La barre porte un NOMBRE D'HEURES : c'est une donnée, pas un ornement. Elle
   ne descend donc pas sous 12 px, et la barre s'élargit pour l'accueillir. */
.cal-demi {
  height: 16px;
  border-radius: 2px;
  border: 1px solid rgba(0, 0, 0, 0.08);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--t-xs);
  font-weight: 700;
  line-height: 1;
  color: #fff; /* les heures ne s'affichent que sur « centre » (bleu nuit) */
}
.cal-table td.cal-total { font-weight: 700; color: var(--bleu-nuit); background: var(--gris-clair); }

/* États (charte : centre = bleu nuit, entreprise = or). */
.etat-centre { background: var(--bleu-nuit); }
.etat-entreprise { background: var(--blanc); } /* NEUTRE : « hors formation », non coloré (comme l'Excel) */
.etat-autre { background: #7E5BA6; } /* mauve : ex. journée portes ouvertes (précisée en observation) */
.etat-ferie { background: var(--alerte); }
.etat-examen { background: var(--attente); }


/* Légende. */
.legende { display: flex; flex-wrap: wrap; gap: 12px; margin: 6px 0 12px; }
.legende .item { display: flex; align-items: center; gap: 6px; font-size: 0.85rem; }
.legende .pastille { width: 16px; height: 16px; border-radius: 3px; border: 1px solid var(--gris-bord); }

/* Pinceau : demi-journées cliquables + barre d'outils. */
.cal-demi[data-demi] { cursor: pointer; }
.cal-demi[data-demi]:hover { outline: 2px solid var(--or); outline-offset: -1px; }
.pinceau { display: flex; flex-wrap: wrap; gap: 20px; align-items: flex-end; margin-bottom: 8px; }
.pinceau-etats { display: flex; flex-wrap: wrap; gap: 10px; }
.pinceau-etats label { align-items: center; gap: 5px; }
.pinceau-etats .pastille { width: 14px; height: 14px; border-radius: 3px; border: 1px solid var(--gris-bord); display: inline-block; }

/* ── Calendrier mural (façon Excel DGO) : mois empilés, jours en colonnes ─── */
/* Ancres de mois : une année de mural fait défiler longtemps, et on cherche
   presque toujours le mois courant. Liens HTML purs — la politique de
   sécurité interdit le script en ligne, et les quatre rôles y ont droit. */
.cal-ancres {
  display: flex; flex-wrap: wrap; gap: 4px 6px;
  margin: 10px 0 4px;
}
.cal-ancres a {
  font-size: var(--t-xs); text-transform: uppercase; letter-spacing: 0.03em;
  padding: 2px 8px; border: 1px solid var(--gris-bord); border-radius: 3px;
  color: var(--bleu-nuit); text-decoration: none; background: var(--blanc);
}
.cal-ancres a:hover, .cal-ancres a:focus-visible {
  border-color: var(--or-fonce); color: var(--or-fonce);
}

.cal-mois-titre {
  font-family: var(--police-titres);
  font-weight: 700;
  color: var(--bleu-nuit);
  margin: 16px 0 4px;
  padding-bottom: 3px;
  border-bottom: 2px solid var(--or);
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}
.cal-obs-mois {
  flex: 0 1 320px;
  font-family: var(--police-texte);
  font-weight: 400;
  font-size: 0.82rem;
  padding: 3px 8px;
  border: 1px solid var(--gris-bord);
  border-radius: var(--rayon);
}
.cal-mural { border-collapse: collapse; font-size: var(--t-xs); white-space: nowrap; }
.cal-mural td, .cal-mural th { border: 1px solid var(--gris-bord); text-align: center; padding: 0; }
.cal-etiq {
  background: var(--bleu-nuit); color: var(--or);
  font-size: var(--t-xs); font-weight: 600;
  padding: 2px 8px; text-align: right; white-space: nowrap;
  position: sticky; left: 0; z-index: 1;
}
.cal-sem-num { background: var(--gris-clair); font-weight: 700; font-size: var(--t-xs); color: var(--texte-doux); }
.cal-jl, .cal-jn { font-size: var(--t-xs); color: var(--texte-doux); min-width: 30px; }
.cal-jn { font-weight: 700; color: var(--texte); }
.cal-we { background: var(--we-fond); color: var(--we-texte); }
/* Week-end : lettre S / D en vert foncé (lettre toujours lisible). */
.cal-we-jour { background: var(--we-ouvre); color: var(--blanc); font-weight: 700; }
/* Jour férié : c'est la DATE qui est rouge (numéro visible en blanc). */
.cal-jn.cal-ferie-date { background: var(--alerte); color: var(--blanc); }
.cal-cell {
  width: 16px; min-width: 16px; height: 22px;
  cursor: pointer; font-weight: 700; color: var(--bleu-nuit);
  background: var(--blanc);
}
/* Contraste : fond FONCÉ → chiffre blanc ; fond CLAIR → chiffre foncé. */
.cal-cell.etat-vide, .cal-cell.etat-entreprise { background: var(--blanc); color: var(--bleu-nuit); } /* neutre : hors formation */
.cal-cell.etat-centre { background: var(--bleu-nuit); color: var(--blanc); }
.cal-cell.etat-ferie { background: var(--alerte); color: var(--blanc); }
.cal-cell.etat-examen { background: var(--attente); color: var(--blanc); }
.cal-cell.etat-autre { background: #7E5BA6; color: var(--blanc); } /* mauve */

/* Férié, examen et « autre » sont trois fonds sombres que la couleur seule
   sépare — et une vision daltonienne les confond. « Centre » et « examen »
   portent au moins un nombre d'heures ; les deux autres n'avaient rien.
   Une trame les distingue sans dépendre de la teinte, dans les cases comme
   dans la légende, où le même repère est donc lisible.
   (Déclarée APRÈS le fond : la propriété raccourcie « background » remet
   l'image à zéro.) */
.cal-cell.etat-ferie, .pastille.etat-ferie, .cal-demi.etat-ferie {
  background-image: repeating-linear-gradient(45deg,
    transparent 0 3px, rgba(255, 255, 255, 0.5) 3px 5px);
}
.cal-cell.etat-autre, .pastille.etat-autre, .cal-demi.etat-autre {
  background-image: repeating-linear-gradient(-45deg,
    transparent 0 3px, rgba(255, 255, 255, 0.5) 3px 5px);
}
.cal-cell:hover { outline: 2px solid var(--or-fonce); outline-offset: -2px; }
.cal-cell.selection { outline: 2px solid var(--bleu-nuit); outline-offset: -2px; }

/* Focus clavier : le contour général est bleu nuit, donc invisible sur une
   case « au centre » qui est elle-même bleu nuit. Ici c'est l'or qui marque la
   case active, doublé d'un liseré blanc pour tenir sur les fonds sombres
   comme sur les fonds clairs. */
.cal-cell[data-demi]:focus-visible {
  outline: 3px solid var(--or);
  outline-offset: -3px;
  box-shadow: inset 0 0 0 5px rgba(255, 255, 255, 0.85);
}
.cal-edit { width: 100%; height: 100%; border: 0; text-align: center; font-weight: 700; font-size: var(--t-xs); padding: 0; background: var(--cellule-edition); color: var(--bleu-nuit); }
.cal-edit:focus { outline: 2px solid var(--or); outline-offset: -2px; }

/* ── Palette d'édition directe du calendrier ─────────────────────────────── */
.palette { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.palette-etat {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 9px; border: 1px solid var(--gris-bord);
  border-radius: var(--rayon); background: var(--blanc); cursor: pointer;
  font-size: 0.82rem; color: var(--texte);
}
.palette-etat .pastille { width: 14px; height: 14px; border-radius: 3px; border: 1px solid var(--gris-bord); display: inline-block; }
.palette-etat:hover { border-color: var(--or-fonce); }
.palette-etat.actif { border-color: var(--bleu-nuit); box-shadow: inset 0 0 0 2px var(--bleu-nuit); font-weight: 600; }
.palette-heures { display: inline-flex; align-items: center; gap: 6px; margin-left: auto; font-size: 0.85rem; flex-wrap: wrap; }
.palette-heures-libelle { font-weight: 600; color: var(--bleu-nuit); }
.palette-heures input { width: 58px; }
.champ-taux { width: 90px; }
.champ-mini { width: 64px; }
.champ-court { width: 130px; }

/* Panneaux « Retard / Exclure » de la console d'émargement. */
.evt-details { display: inline-block; position: relative; margin-right: 4px; }
.evt-details > summary { list-style: none; cursor: pointer; display: inline-block; }
.evt-details > summary::-webkit-details-marker { display: none; }
.evt-panneau {
  position: absolute; z-index: 20; right: 0; top: calc(100% + 4px);
  /* Jamais plus large que l'écran : sur téléphone, un panneau de 280 px
     ancré à droite dépassait la fenêtre et devenait inatteignable. */
  min-width: min(280px, calc(100vw - 2rem));
  max-width: calc(100vw - 2rem);
  background: var(--blanc);
  border: 1px solid var(--bord-fort);
  border-radius: var(--rayon);
  box-shadow: var(--ombre);
  padding: 12px;
  text-align: left;
}

/* ── Tableau → fiches empilées sur écran étroit ───────────────────────────── */
/* L'émargement se fait au téléphone, en salle, debout. Cinq colonnes y
   imposaient 450 px de défilement horizontal : on lisait le nom d'un élève
   sans voir son statut. Chaque ligne devient une fiche, chaque cellule porte
   son intitulé — l'en-tête du tableau n'étant plus affiché. */
@media (max-width: 760px) {
  .tableau-cartes,
  .tableau-cartes tbody,
  .tableau-cartes tr,
  .tableau-cartes td { display: block; width: auto; }

  .tableau-cartes thead {
    position: absolute;
    width: 1px; height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .tableau-cartes tr {
    border: 1px solid var(--bord-fort);
    border-radius: var(--r-md);
    background: var(--surface);
    padding: var(--e-3) var(--e-4);
    margin-bottom: var(--e-3);
  }

  .tableau-cartes td {
    border: 0;
    padding: var(--e-2) 0;
    display: grid;
    grid-template-columns: 8.5rem minmax(0, 1fr);
    gap: var(--e-3);
    align-items: start;
  }
  .tableau-cartes td + td { border-top: 1px solid var(--bord); }

  .tableau-cartes td::before {
    content: attr(data-libelle);
    font-size: var(--t-sm);
    font-weight: 600;
    color: var(--bleu-nuit);
  }
  /* Une cellule sans intitulé ne creuse pas une colonne vide. */
  .tableau-cartes td:not([data-libelle]) { display: block; }

  /* Cellule d'actions : les formulaires qu'elle ouvre ont besoin de toute la
     largeur de la fiche, pas des 185 px qui restent à droite d'un intitulé. */
  .tableau-cartes td.cellule-large { display: block; }
  .tableau-cartes td.cellule-large::before { display: block; margin-bottom: var(--e-2); }

  /* En fiche, le panneau s'ouvre DANS le flux : la fiche s'allonge. Un panneau
     flottant ancré à un bouton déjà à 170 px du bord sortait de l'écran, et
     aucun calcul de position ne tient sur toutes les largeurs de téléphone. */
  .tableau-cartes .evt-details { display: block; }
  .tableau-cartes .evt-panneau {
    position: static;
    min-width: 0;
    max-width: none;
    margin-top: var(--e-2);
  }
}

/* Un panneau en position absolue est ROGNÉ par le conteneur qui défile : sur
   les dernières colonnes, la moitié du formulaire « Retard » ou « Départ
   anticipé » disparaissait sous le bord du tableau. Tant qu'un panneau est
   ouvert, le conteneur cesse de rogner ; il retrouve son défilement dès la
   fermeture. */
.conteneur-tableau:has(.evt-details[open]) { overflow: visible; }

.evt-panneau label { display: block; font-size: var(--t-sm); font-weight: 600; margin-bottom: 8px; }
.evt-panneau input, .evt-panneau textarea { width: 100%; margin-top: 3px; font-weight: 400; }
.evt-ligne { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; margin-top: 4px; }
.lien-discret { color: var(--or-fonce); font-size: 0.8rem; text-decoration: underline; }

/* Bascule « afficher / masquer les sessions terminées », sous un sélecteur de classe. */
.lien-bascule {
  display: inline-block;
  margin-top: 4px;
  color: var(--texte-doux);
  font-size: 0.78rem;
  text-decoration: underline dotted;
}
.lien-bascule:hover, .lien-bascule:focus-visible { color: var(--or-fonce); text-decoration: underline; }

/* Icônes dessinées : elles prennent la couleur du texte qui les entoure et
   gardent le même dessin sur tous les systèmes, contrairement aux emoji. */
.icone {
  width: 1.35em;
  height: 1.35em;
  display: block;
  flex-shrink: 0;
}

/* Cloche de notifications (en-tête). */
.cloche {
  position: relative;
  display: inline-flex;
  align-items: center;
  color: var(--or);
  text-decoration: none;
  margin-right: 14px;
}
.cloche:hover, .cloche:focus-visible { color: var(--blanc); }
.cloche-badge {
  position: absolute;
  top: -6px; right: -10px;
  background: var(--danger); color: var(--blanc);
  border-radius: 10px;
  font-size: var(--t-xs); font-weight: 700;
  padding: 1px 5px;
}
.notif-non-lue { border-left: 4px solid var(--or); }

/* Actions de la fiche utilisateur : grille DEUX COLONNES, boutons pleine largeur
   (retour direction : fini les boutons entassés les uns sur les autres). */
.actions-grille {
  display: grid;
  grid-template-columns: repeat(2, minmax(220px, 1fr));
  gap: 10px;
}
.actions-grille > a,
.actions-grille form { width: 100%; }
.actions-grille .bouton,
.actions-grille .bouton-secondaire,
.actions-grille .bouton-danger {
  width: 100%;
  text-align: center;
  box-sizing: border-box;
}
@media (max-width: 700px) {
  .actions-grille { grid-template-columns: 1fr; }
}

/* Zone d'archivage d'un compte : champ de motif confortable. */
.zone-archivage {
  border-top: 1px solid var(--gris-bord);
  padding-top: 14px;
}
.zone-archivage .champ input { max-width: 560px; }

/* Liste des fichiers accumulés avant dépôt (multi-fichiers.js). */
.liste-fichiers { list-style: none; padding: 0; margin: 8px 0 0; }
.liste-fichiers li { font-size: 0.85rem; padding: 2px 0; border-bottom: 1px dashed var(--gris-bord); }

/* ── Grille « Planifier les cours » (type Excel ⑤) ────────────────────────── */
/* Hauteur d'un créneau de 30 min : 22 px (constante reprise par grille-cours.js). */
.grille-cours { display: flex; gap: 4px; user-select: none; overflow-x: auto; }
.gc-heures { width: 46px; flex: none; }
.gc-entete-vide, .gc-entete { height: 46px; }
.gc-h {
  height: 22px;
  font-size: var(--t-xs);
  color: var(--texte-doux);
  text-align: right;
  padding-right: 6px;
  border-top: 1px solid transparent;
}
/* Panneau « Mettre les formateurs en face » : replié = libellé + compte,
   déplié (flèche à droite) = un formateur par cours, avec date et horaires. */
.bloc-affecter { border-bottom: 1px solid var(--gris-bord); }
.bloc-affecter:last-child { border-bottom: none; }
.bloc-affecter > summary {
  cursor: pointer;
  list-style: none;
  padding: 10px 4px;
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: var(--police-titres);
  color: var(--bleu-nuit);
}
.bloc-affecter > summary::-webkit-details-marker { display: none; }
.bloc-affecter > summary::after { content: '▾'; margin-left: auto; opacity: 0.55; }
.bloc-affecter[open] > summary::after { content: '▴'; }
.bloc-affecter > summary:hover { background: var(--surface-survol); }
.bloc-affecter-corps { padding: 4px 4px 16px; }
.bloc-affecter-corps .tableau-premium select { margin: 0; width: 100%; }
.bloc-affecter-corps > form + form { margin-top: 14px; }
.bloc-affecter-commun { margin: 12px 0; border: 1px dashed var(--gris-bord); border-radius: 8px; padding: 10px 14px; }
.bloc-affecter-commun > summary { cursor: pointer; font-size: 0.9rem; color: var(--or-fonce); }
.bloc-affecter-commun input[type="text"] { width: 100%; margin-top: 8px; }
.bloc-affecter-masse { border-top: 1px dashed var(--gris-bord); padding-top: 14px; }

.gc-jour { flex: 1; min-width: 128px; }
/* Témoin d'écart du jour (pied de colonne) : cours posés vs calendrier annuel.
   Discret et informatif : ambre = reste à planifier, rouge = dépassement. */
.gc-pied {
  min-height: 22px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--police-titres);
  font-weight: 600;
  font-size: var(--t-xs);
  border-top: 1px solid var(--gris-bord);
}
.gc-ecart-ok { color: var(--ok); }
.gc-ecart-plus { color: var(--alerte); }
.gc-ecart-moins { color: var(--attente); }
.gc-entete { text-align: center; }
.gc-jour-nom { font-family: var(--police-titres); font-weight: 600; font-size: 0.78rem; color: var(--bleu-nuit); }
.gc-attendu .badge { font-size: var(--t-xs); padding: 1px 6px; }
.gc-corps {
  position: relative;
  border: 1px solid var(--gris-bord);
  background:
    repeating-linear-gradient(to bottom,
      var(--blanc) 0, var(--blanc) 21px,
      var(--gris-bord) 21px, var(--gris-bord) 22px);
  cursor: crosshair;
}
.gc-voile {
  position: absolute; left: 0; right: 0;
  background: repeating-linear-gradient(135deg, var(--voile-a) 0, var(--voile-a) 6px, var(--voile-b) 6px, var(--voile-b) 12px);
  pointer-events: none;
}
/* Demi-journée d'ÉPREUVE : planifiable, donc PAS de voile hachuré (qui
   signifie « interdit » dans cet écran), mais jamais l'aspect d'un cours
   ordinaire — on ne doit pas les confondre. Aplat ocre très clair + filet
   latéral ocre, la même couleur que l'état « examen » du calendrier mural.
   L'étiquette porte l'information sans dépendre de la seule couleur. */
.gc-examen {
  position: absolute; left: 0; right: 0;
  background: rgba(138, 101, 8, 0.08);
  border-left: 3px solid var(--attente);
  pointer-events: none; /* le glisser passe au travers : la création reste possible */
}
.gc-examen-etiquette {
  position: absolute; top: 2px; left: 8px;
  font-size: var(--t-xs); font-weight: 700; letter-spacing: 0.04em;
  color: var(--attente-texte);
}
.gc-selection {
  position: absolute; left: 2px; right: 2px;
  background: rgba(200, 169, 90, 0.35);
  border: 1.5px dashed var(--or-fonce);
  border-radius: 4px;
  pointer-events: none;
}
.bloc-cours {
  position: absolute; left: 2px; right: 2px;
  background: var(--bleu-nuit); color: var(--blanc);
  border-radius: 4px;
  font-size: var(--t-xs); line-height: 1.25;
  padding: 2px 4px; overflow: hidden;
  cursor: grab; /* le milieu du bloc se DÉPLACE (jour et heure) */
}
.bloc-cours.bloc-deplace {
  cursor: grabbing;
  opacity: 0.85;
  outline: 2px dashed var(--or);
  z-index: 10;
}
/* « À affecter » : fond ambre par défaut + liseré ambre comme repère. Si une couleur
   de matière est choisie, celle-ci prime sur le fond (palette ci-dessous, déclarée
   après) et le liseré ambre reste visible pour signaler « formateur à mettre ». */
.bloc-cours.a-affecter { background: var(--attente); box-shadow: inset 0 0 0 2px var(--attente); }
/* ── Coûts consolidés : ce qui est facialement dû, ce qui est réellement payé ── */
/* Ligne de total d une synthese, et chiffre en gain (heures ou euros
   economises par la mutualisation). */
tfoot tr.ligne-total td { background: var(--bleu-2); color: var(--blanc); font-weight: 700; }
.valeur-gain { color: var(--ok); font-weight: 600; }

/* Affectation rapide : le geste le plus courant, sur la barre de semaine.
   Une semaine, un intervenant — un menu, un bouton. */
.affect-rapide {
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px;
  margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--gris-bord);
}
.affect-rapide select { margin: 0; width: auto; min-width: 190px; }
.affect-rapide-commun { display: flex; align-items: center; gap: 6px; font-size: 0.85rem; }

/* ── Cours communs et doublons de formateur ──────────────────────────────── */

.mut-dossier > summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  font-family: var(--police-titres);
  color: var(--bleu-nuit);
}
.mut-dossier > summary::-webkit-details-marker { display: none; }
.mut-dossier > summary::after { content: '▾'; margin-left: auto; opacity: 0.55; }
.mut-dossier[open] > summary::after { content: '▴'; }
.mut-quand { text-transform: capitalize; font-variant-numeric: tabular-nums; }
.mut-corps { margin-top: 14px; border-top: 1px solid var(--gris-bord); padding-top: 14px; }
.mut-corps h3 { font-family: var(--police-titres); font-size: 0.95rem; color: var(--bleu-nuit); margin-bottom: 8px; }

/* Le détail heure par heure : c'est lui qui lève l'ambiguïté quand les
   chevauchements sont partiels (15h-17h face à 15h-16h puis 16h-17h). */
.mut-tranches { list-style: none; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.mut-tranches li {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  background: var(--gris-clair);
  border: 1px solid var(--bord);
  border-radius: 6px;
  padding: 8px 12px;
}
.mut-plage { font-family: var(--police-titres); font-weight: 600; font-variant-numeric: tabular-nums; }
.mut-classes { font-weight: 600; color: var(--bleu-nuit); }

.mut-decision { margin-top: 18px; border-top: 1px dashed var(--gris-bord); padding-top: 14px; }
.mut-choix { list-style: none; padding: 0; display: flex; flex-direction: column; gap: 4px; margin-bottom: 10px; }
.mut-choix label { display: flex; align-items: center; gap: 8px; font-size: 0.92rem; }

/* Précision attachée au cours : pastille discrète en haut à droite du bloc,
   texte complet au survol. Signale une intention que le planning ne dit pas
   (cours commun avec une autre classe, jeu de rôle, intervenant extérieur). */
.bc-precision {
  position: absolute;
  top: 2px;
  right: 4px;
  font-size: var(--t-xs);
  line-height: 1;
  color: var(--or);
  cursor: help;
}

/* Palette de matières (lisibilité du planning hebdomadaire). 0 = défaut = le bleu
   nuit du .bloc-cours ; 1..9 = teintes sobres de la charte, toujours foncées (texte
   blanc lisible) et jamais « flash ». Après .a-affecter pour primer sur le fond ambre. */
/* Palette « joaillerie » : des tons profonds et saturés (saphir, émeraude,
   grenat…) plutôt que des teintes terreuses, pour un rendu premium cohérent avec
   l'or et le bleu nuit de la charte. Une seule teinte par famille (distinction
   immédiate) et un contraste ≥ 4,5:1 avec le texte BLANC des blocs (WCAG AA). */
.bloc-cours.bc-c1 { background: #2A5DA8; } /* saphir */
.bloc-cours.bc-c2 { background: #106B73; } /* bleu paon */
.bloc-cours.bc-c3 { background: #126B4F; } /* émeraude */
.bloc-cours.bc-c4 { background: #836515; } /* bronze doré (rappel de la charte) */
.bloc-cours.bc-c5 { background: #A05720; } /* cuivre */
.bloc-cours.bc-c6 { background: #8E2434; } /* grenat */
.bloc-cours.bc-c7 { background: #6E2A5B; } /* aubergine */
.bloc-cours.bc-c8 { background: #4A3A8C; } /* améthyste */
.bloc-cours.bc-c9 { background: #4A5560; } /* graphite (neutre) */

/* Touche premium : un voile très léger (clair en haut, sombre en bas) donne du
   relief aux blocs sans dégradé voyant ni ombre — le fond de couleur reste net. */
.bloc-cours { background-image: linear-gradient(rgba(255, 255, 255, 0.07), rgba(0, 0, 0, 0.07)); }

/* Sélecteur de couleur par matière (Structure › Matières & volumes par année). */
.cellule-couleurs { display: flex; flex-wrap: wrap; gap: 6px; }
.pastille {
  width: 22px; height: 22px; border-radius: 50%;
  border: 0; padding: 0; cursor: pointer;
  /* Fin liseré sombre + reflet interne : la pastille a du relief, comme une perle. */
  background-image: linear-gradient(rgba(255, 255, 255, 0.18), rgba(0, 0, 0, 0.12));
  box-shadow: inset 0 0 0 1px rgba(28, 35, 64, 0.28);
  transition: transform 0.12s ease, box-shadow 0.12s ease;
}
.pastille:hover { transform: scale(1.15); box-shadow: inset 0 0 0 1px rgba(28, 35, 64, 0.28), 0 0 0 2px var(--gris-bord); }
/* Sélection : anneau OR de la charte, détaché par un liseré blanc. */
.pastille-active,
.pastille-active:hover { box-shadow: inset 0 0 0 1px rgba(28, 35, 64, 0.28), 0 0 0 2px var(--blanc), 0 0 0 4px var(--or); }
.pastille-c0 { background: var(--bleu-nuit); }
.pastille-c1 { background: #2A5DA8; } /* saphir */
.pastille-c2 { background: #106B73; } /* bleu paon */
.pastille-c3 { background: #126B4F; } /* émeraude */
.pastille-c4 { background: #836515; } /* bronze doré */
.pastille-c5 { background: #A05720; } /* cuivre */
.pastille-c6 { background: #8E2434; } /* grenat */
.pastille-c7 { background: #6E2A5B; } /* aubergine */
.pastille-c8 { background: #4A3A8C; } /* améthyste */
.pastille-c9 { background: #4A5560; } /* graphite */
.bc-titre { font-weight: 700; padding-right: 30px; }
.bc-sous { opacity: 0.9; }
.bc-actions { position: absolute; top: 1px; right: 1px; display: flex; gap: 1px; }
.bc-btn {
  border: 0; background: rgba(255, 255, 255, 0.22); color: var(--blanc);
  border-radius: 3px; font-size: var(--t-xs); line-height: 1;
  padding: 2px 4px; cursor: pointer;
}
.bc-btn:hover { background: rgba(255, 255, 255, 0.45); }
.bc-poignee {
  position: absolute; bottom: 0; left: 0; right: 0; height: 6px;
  cursor: ns-resize;
  background: rgba(255, 255, 255, 0.35);
  border-radius: 0 0 4px 4px;
}
.bc-poignee-haut { top: 0; bottom: auto; border-radius: 4px 4px 0 0; }
.panneau-creation { border: 1px solid var(--bord-fort); }
/* Quand il apparaît (après un glisser-sélection), le panneau « Nouveau cours »
   FLOTTE au-dessus de la grille au lieu de s'insérer dans le flux : sinon il
   pousse la grille vers le bas et le contenu « saute » sous le curseur. Caché,
   il reste [hidden] (aucun espace occupé). */
.panneau-creation:not([hidden]) {
  position: fixed;
  left: 50%;
  bottom: 18px;
  transform: translateX(-50%);
  width: min(960px, calc(100% - 32px));
  z-index: 60;
  box-shadow: 0 8px 28px rgba(28, 35, 64, 0.32);
  background: var(--blanc);
}
body.mode-collage .gc-corps { cursor: copy; }
[data-calendrier] .cal-mural { user-select: none; }
/* Édition au doigt (tablette) : le glisser est suivi en Pointer Events —
   touch-action:none sur les seules zones de peinture/glisser pour que le doigt
   peigne/déplace au lieu de faire défiler la page (CDC §11). */
.gc-corps { touch-action: none; }
[data-calendrier] .cal-cell[data-demi] { touch-action: none; }

/* Pad de signature (émargement) : cadre net, fond blanc, tactile. */
.pad-signature {
  display: block;
  width: 100%;
  max-width: 600px;
  height: 180px;
  border: 1px solid var(--gris-bord);
  border-radius: var(--rayon);
  background: var(--blanc);
  touch-action: none;
}

/* En-tête de fiche : photo/pastille + identité côte à côte. */
.bloc-fiche { display: flex; gap: 24px; align-items: flex-start; flex-wrap: wrap; }

/* Pastille d'initiales affichée en l'absence de photo de profil. */
.photo-profil.initiales {
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--police-titres);
  font-weight: 700;
  font-size: 1.6rem;
  color: var(--bleu-nuit);
}

.texte-doux { color: var(--texte-doux); font-size: 0.87rem; }
.texte-centre { text-align: center; }
.texte-droite { text-align: right; }
.pleine-largeur { width: 100%; }
.marge-haut { margin-top: 18px; }
.sans-marge { margin: 0; }
.actions { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin-top: 16px; }
.entete-page { display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap; margin-bottom: 18px; }
.entete-page h1 { margin: 0; }

.photo-profil {
  width: 84px;
  height: 84px;
  border-radius: 50%;
  object-fit: cover;
  border: 2px solid var(--or);
  background: var(--gris-clair);
}

/* Indicateurs de pilotage. Six boîtes identiques au contenu centré ne
   hiérarchisent rien : le regard ne sait pas où se poser, et la dernière
   restait seule sur sa ligne. Alignement à gauche (on lit un chiffre comme
   un mot), filet or discret, et une grille qui se remplit sans orpheline. */
.grille-cartes {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(168px, 1fr));
  gap: var(--e-3);
  align-items: stretch;
}

.carte-indicateur {
  position: relative;
  overflow: hidden;
  padding: var(--e-5);
  display: flex;
  flex-direction: column;
  gap: var(--e-1);
  transition: box-shadow var(--transition), transform var(--transition);
}
/* Le filet dit « chiffre de tête ». Coloré, il dit en plus dans quel état se
   trouve ce chiffre — la couleur n'est jamais le seul porteur : la valeur
   change de teinte avec lui, et le libellé nomme toujours la mesure. */
.carte-indicateur::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: 3px;
  background: var(--or);
}
.carte-indicateur.est-ok::before { background: var(--ok); }
.carte-indicateur.est-alerte::before { background: var(--alerte); }
.carte-indicateur.est-attente::before { background: var(--attente); }
.carte-indicateur.est-ok .valeur { color: var(--ok); }
.carte-indicateur.est-alerte .valeur { color: var(--alerte); }
.carte-indicateur.est-attente .valeur { color: var(--attente-texte); }
/* Chiffre de contexte, volontairement en retrait (ex. coût facial). */
.carte-indicateur.est-doux .valeur { color: var(--texte-doux); font-weight: 600; }
.carte-indicateur:hover { box-shadow: var(--niv-2); }
.carte-indicateur .valeur {
  font-family: var(--police-titres);
  font-size: var(--t-2xl);
  font-weight: 800;
  line-height: 1.05;
  color: var(--bleu-nuit);
  font-variant-numeric: tabular-nums;
}
.carte-indicateur .libelle {
  color: var(--texte-doux);
  font-family: var(--police-titres);
  font-size: var(--t-xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

/* ── Messagerie : bulles de discussion (type WhatsApp, charte DGO) ─────────── */
.carte-chat { padding: 0; overflow: hidden; }
.chat {
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-height: 58vh;
  overflow-y: auto;
  padding: 16px;
  background: var(--gris-clair);
}
.bulle {
  max-width: 74%;
  padding: 8px 12px;
  border-radius: 12px;
  box-shadow: var(--niv-1);
  overflow-wrap: anywhere;
}
.bulle-autre {
  align-self: flex-start;
  background: var(--blanc);
  border: 1px solid var(--gris-bord);
  border-bottom-left-radius: 3px;
}
.bulle-moi {
  align-self: flex-end;
  background: var(--bulle-moi); /* or très clair (charte) */
  border: 1px solid var(--bulle-moi-bord);
  border-bottom-right-radius: 3px;
}
/* Nom de l'auteur sur les bulles des autres — petit et doré, comme WhatsApp. */
.bulle-auteur { font-size: var(--t-xs); font-weight: 700; color: var(--or-fonce); margin-bottom: 2px; }
.bulle-texte { white-space: pre-wrap; color: var(--texte); }
.bulle-piece { margin-top: 4px; font-size: 0.9rem; }
.bulle-meta { font-size: var(--t-xs); color: var(--texte-doux); margin-top: 4px; text-align: right; }
/* Panneau « Vu par… » (menu contextuel de la bulle). */
.bulle-lecteurs {
  margin-top: 4px;
  padding-top: 4px;
  border-top: 1px dashed rgba(0, 0, 0, 0.15);
  font-size: var(--t-xs);
  color: var(--texte-doux);
}

/* Modification en place d'un message. */
.bulle-edition { width: 100%; min-height: 56px; margin: 0; font-size: 0.9rem; }
.bulle-edition-actions { margin-top: 4px; justify-content: flex-end; }

/* Menu contextuel des bulles (clic droit / appui long). */
.menu-contextuel {
  position: fixed;
  z-index: 50;
  min-width: 170px;
  background: var(--blanc);
  border: 1px solid var(--gris-bord);
  border-radius: var(--rayon);
  box-shadow: var(--ombre);
  padding: 4px;
  display: flex;
  flex-direction: column;
}
.menu-item {
  border: 0;
  background: none;
  text-align: left;
  padding: 8px 10px;
  border-radius: 6px;
  cursor: pointer;
  font-size: 0.9rem;
  color: var(--texte);
}
.menu-item:hover { background: var(--gris-clair); }

/* Composeur compact façon WhatsApp : 📎 + champ + Envoyer sur une ligne. */
.compose {
  display: flex;
  gap: 8px;
  align-items: flex-end;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--gris-bord);
}
.compose-piece {
  cursor: pointer;
  font-size: 1.3rem;
  line-height: 1;
  padding: 9px 10px;
  border: 1px solid var(--gris-bord);
  border-radius: 50%;
  background: var(--gris-clair);
}
.compose-piece:hover { border-color: var(--or-fonce); }
/* display:none retire l element du parcours clavier : impossible de joindre
   un fichier sans souris. Masquage VISUEL seulement — il reste focusable. */
.compose-fichier {
  position: absolute; width: 1px; height: 1px;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}
.compose-piece:focus-within { outline: 2px solid var(--bleu-nuit); outline-offset: 2px; border-radius: var(--r-sm); }
.compose-champ {
  flex: 1;
  margin: 0;
  resize: none;
  border-radius: 18px;
  padding: 10px 14px;
}
.compose-envoyer { border-radius: 18px; }

/* ── Responsive ────────────────────────────────────────────────────────────── */
/* Bascule du menu : inutile sur grand écran, indispensable sur téléphone. */
.nav-bascule { display: none; }

@media (max-width: 860px) {
  .disposition { flex-direction: column; }

  /* L'émargement est pensé mobile-first (CDC §11), et c'est l'écran où l'élève
     est le plus pressé : il scanne, le formateur dicte le code, il doit signer.
     Le menu déplié occupait 52 % de l'écran AVANT le titre de la page. Il est
     donc replié par défaut, et le contenu remonte en premier. */
  .navigation {
    width: 100%;
    max-height: 60vh;
    overflow-y: auto;
    display: none;
    order: 2;
  }
  .navigation.nav-ouverte { display: block; }
  .contenu { padding: var(--e-4); order: 1; }

  .nav-bascule {
    display: inline-flex;
    align-items: center;
    gap: var(--e-2);
    min-height: 40px;
    padding: 0 var(--e-4);
    background: rgba(255, 255, 255, 0.10);
    color: var(--blanc);
    border: 1px solid rgba(255, 255, 255, 0.28);
    border-radius: var(--r-sm);
    font-family: var(--police-titres);
    font-size: var(--t-sm);
    font-weight: 600;
    cursor: pointer;
  }
  .nav-bascule[aria-expanded="true"] { background: var(--or); color: var(--bleu-nuit); border-color: var(--or); }

  .barre-haute .titre-app { display: none; }
  /* Logo, menu, identité et déconnexion ne tiennent pas sur 375 px : sans
     retour à la ligne, la page entière défilait latéralement. */
  .barre-haute {
    flex-wrap: wrap;
    gap: var(--e-2);
    padding: var(--e-2) var(--e-3);
  }
  .barre-haute .espace { flex-basis: 100%; height: 0; }
  .barre-haute .identite { font-size: var(--t-xs); }
  /* Zones tactiles : 44 px est le minimum confortable au doigt. */
  .navigation a { padding: var(--e-3) var(--e-5); min-height: 44px; }
}

/* Un tableau dans une carte, c est deux cadres pour une seule information.
   La carte cède ses marges au tableau, qui porte déjà sa structure. */
.carte > .conteneur-tableau:only-child,
.carte > .conteneur-tableau:last-child { margin: 0 calc(var(--e-6) * -1) calc(var(--e-6) * -1); }
.carte > .conteneur-tableau:last-child .tableau-premium { border-radius: 0 0 var(--r-md) var(--r-md); }
.carte > .conteneur-tableau:last-child .tableau-premium thead th:first-child,
.carte > .conteneur-tableau:last-child .tableau-premium thead th:last-child { border-radius: 0; }
.conteneur-tableau { overflow-x: auto; -webkit-overflow-scrolling: touch; }

/* ── Pied légal ────────────────────────────────────────────────────────────
   L écran s arrêtait net après la dernière carte. Ces mentions figuraient au
   pied des PDF (CDC §13) mais nulle part à l écran, alors que l application
   est vue par des entreprises clientes et des prospects. */
.pied-legal {
  margin-top: var(--e-8);
  padding-top: var(--e-5);
  border-top: 1px solid var(--bord);
  color: var(--texte-doux);
  font-size: var(--t-xs);
  line-height: 1.7;
}
.pied-legal p { margin: 0; }
.pied-raison {
  font-family: var(--police-titres);
  font-weight: 700;
  color: var(--bleu-nuit);
  letter-spacing: 0.04em;
  margin-bottom: var(--e-1) !important;
}
/* Sur fond bleu nuit, le pied doit être CLAIR : il était sombre sur sombre. */
.page-publique .pied-legal {
  text-align: center;
  border-top: none;
  margin-top: 0;
  padding-top: 0;
  max-width: 560px;
  color: rgba(255, 255, 255, 0.72);
}
.page-publique .pied-raison { color: var(--or); }

/* Accroche sous le logo : la première page vue par un prospect ne disait pas
   qui nous sommes. */
.accroche-publique {
  margin: var(--e-3) 0 0;
  font-size: var(--t-xs);
  line-height: 1.5;
  color: var(--texte-doux);
  text-align: center;
}

/* Barre de filtres : les formulaires de filtre n avaient aucun traitement
   commun ; quatre d entre eux utilisaient display:inline sur une carte, ce qui
   faisait ignorer les marges verticales et chevaucher le contenu suivant. */
.barre-filtres {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--e-3);
}
.barre-filtres .champ { margin-bottom: 0; }
.barre-filtres select, .barre-filtres input { width: auto; min-width: 180px; }

/* ── Notifications ─────────────────────────────────────────────────────────
   Le bouton d action passait sous le texte dès que le message était long :
   la ligne réutilisait le composant d en-tête de page, qui se replie. Ici la
   colonne d actions ne se rétrécit jamais et le texte prend ce qui reste —
   « Ouvrir » est TOUJOURS à droite, quelle que soit la longueur du message. */
.notif-ligne {
  display: flex;
  align-items: flex-start;
  gap: var(--e-5);
}
.notif-corps { flex: 1 1 auto; min-width: 0; }
.notif-actions {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--e-2);
  text-align: center;
}
.notif-actions form { margin: 0; }
.notif-actions .bouton { white-space: nowrap; }

/* Onglets : deux listes distinctes, pas un filtre caché dans un menu. */
.onglets {
  display: flex;
  gap: var(--e-1);
  margin-bottom: var(--e-5);
  border-bottom: 1px solid var(--bord);
}
.onglet {
  display: inline-flex;
  align-items: center;
  gap: var(--e-2);
  padding: var(--e-3) var(--e-5);
  font-family: var(--police-titres);
  font-weight: 600;
  font-size: var(--t-base);
  color: var(--texte-doux);
  border-bottom: 3px solid transparent;
  margin-bottom: -1px;
  transition: color var(--transition), border-color var(--transition);
}
.onglet:hover { color: var(--bleu-nuit); text-decoration: none; }
.onglet-actif { color: var(--bleu-nuit); border-bottom-color: var(--or); }
.onglet-compte {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 22px;
  height: 22px;
  padding: 0 6px;
  border-radius: var(--r-pill);
  background: var(--or);
  color: var(--bleu-nuit);
  font-size: var(--t-xs);
  font-variant-numeric: tabular-nums;
}
.onglet:not(.onglet-actif) .onglet-compte { background: var(--bord); color: var(--texte-doux); }

/* Code de séance : dicté en salle, il doit se lire de loin sans être un
   titre de page — il y avait deux <h1> sur la console d emargement. */
.code-seance {
  font-family: var(--police-titres);
  font-size: var(--t-2xl);
  font-weight: 700;
  letter-spacing: 0.18em;
  font-variant-numeric: tabular-nums;
  color: var(--bleu-nuit);
  margin: 0;
}
