/* ============================================================
   DESIGN SYSTEM : jetons uniques, remplis depuis DESIGN.md.
   Regle : AUCUNE couleur/taille en dur dans le reste du CSS.
   Concept : « la table de tri ». Deux matieres, encre et papier,
   et une couleur rationnee qui ne sert qu'a porter un signal.
   ============================================================ */

/* ---------- Polices self-hosted (assets, pas dependances) ----------
   Sous-ensemble latin, fichiers variables. Licences dans fonts/LICENCES.md. */
@font-face {
  font-family: "Geist";
  src: url("../fonts/geist-variable.woff2") format("woff2");
  font-weight: 300 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Geist Mono";
  src: url("../fonts/geist-mono-variable.woff2") format("woff2");
  font-weight: 400 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Literata";
  src: url("../fonts/literata-variable.woff2") format("woff2");
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Literata";
  src: url("../fonts/literata-variable-italic.woff2") format("woff2");
  font-weight: 400 600;
  font-style: italic;
  font-display: swap;
}

:root {
  /* ---------- Surface papier (mode par defaut) ----------
     Contrastes calcules le 22/08/2026, tous AA ou AAA. */
  --couleur-papier: #f4f6f3;             /* fond de la zone de travail */
  --couleur-surface: #ffffff;            /* les « feuilles » posees dessus */
  --couleur-encre: #12181a;              /* texte principal, 16.5 sur papier */
  --couleur-encre-douce: #55605c;        /* texte secondaire, 6.0 sur papier */
  --couleur-bordure: #dde2dc;            /* filet 1px, separateur par defaut */

  /* ---------- Couleur rationnee : elle porte un sens, jamais un decor ---------- */
  --couleur-signal: #1d4d3b;             /* vert foret, 9.7 sur blanc */
  --couleur-signal-contraste: #ffffff;
  --couleur-signal-clair: #4e9e7c;       /* la seule qui se voit sur l'encre, 5.6 */
  --couleur-alerte: #9e3b2c;             /* UNIQUEMENT le danger, 6.7 sur blanc */
  --couleur-attention: #8a6212;          /* avertissement, 5.5 sur blanc */

  /* La teinte que prennent le marqueur « vous etes ici » et l'anneau de focus sur
     la surface courante. Le rail et la barre d'encre la redefinissent chez eux :
     le vert foret ne se voit pas sur l'encre (DESIGN.md §4 et §6). */
  --couleur-signal-local: var(--couleur-signal);

  /* ---------- Matiere encre (rail de navigation, ecran de connexion) ---------- */
  --couleur-encre-fond: #12181a;
  --couleur-encre-surface: #1b2325;      /* survol, groupe ouvert */
  --couleur-encre-filet: #333e41;        /* separateur, purement decoratif */
  --couleur-sur-encre: #f4f6f3;          /* 16.5 sur l'encre */
  --couleur-sur-encre-douce: #9aa7a2;    /* 7.2 sur l'encre */

  /* ---------- Typographie : voix editoriale, voix d'interface, chiffres ---------- */
  --police-editoriale: "Literata", Georgia, "Times New Roman", serif;
  --police-interface: "Geist", system-ui, -apple-system, "Segoe UI", sans-serif;
  --police-donnees: "Geist Mono", ui-monospace, "Cascadia Mono", Consolas, monospace;

  --taille-base: 1rem;
  --txt-display: 2rem;
  --txt-h1: 1.5rem;
  --txt-h2: 1.25rem;
  --txt-h3: 1rem;
  --txt-lecture: 1.0625rem;
  --txt-corps: 0.9375rem;
  --txt-dense: 0.875rem;
  --txt-libelle: 0.8125rem;
  --txt-donnee: 0.8125rem;

  /* ---------- Espacements ---------- */
  --espace-xs: 0.25rem;
  --espace-s: 0.5rem;
  --espace-m: 1rem;
  --espace-l: 2rem;
  --espace-xl: 4rem;

  /* ---------- Divers ---------- */
  --rayon: 0.375rem;                     /* une seule echelle d'arrondi */
  --largeur-max: 72rem;
  --largeur-lecture: 68ch;               /* contenus de formation uniquement */
  --largeur-rail: 15rem;
  --hauteur-barre: 3.5rem;               /* barre d'encre mobile */
  --hauteur-ligne-dense: 2.25rem;
  --hauteur-commande: 2.75rem;           /* 44px : plancher d'une zone cliquable */

  /* ---------- Motion : liste fermee, voir DESIGN.md §7 ---------- */
  --duree-survol: 120ms;
  --duree-appui: 80ms;
  --duree-ouverture: 180ms;
  --duree-fermeture: 120ms;
  --courbe-sortie: ease-out;
  --courbe-entree: cubic-bezier(0.16, 1, 0.3, 1);
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

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

/* L'attribut `hidden` pilote les états d'une application (écran affiché, bouton
   disponible…). Sans cette règle, la moindre classe qui fixe `display` l'emporte sur
   la feuille du navigateur et l'élément « caché » reste visible, voir PIEGES.md E1.
   C'est la seule justification acceptable d'un `!important` dans nos feuilles. */
[hidden] {
  display: none !important;
}

body {
  margin: 0;
  font-family: var(--police-interface);
  font-size: var(--txt-corps);
  color: var(--couleur-encre);
  background: var(--couleur-papier);
  line-height: 1.55;
}

h1, h2, h3 {
  font-family: var(--police-editoriale);
  line-height: 1.2;
}

img {
  max-width: 100%;
  height: auto;
}

/* ============================================================
   PRIMITIVES PARTAGÉES (DESIGN.md §6)
   Elles naissent avec le shell parce que c'est le premier endroit
   qui les emploie. Tout écran suivant les réutilise sans les redéfinir.
   ============================================================ */

/* ---------- Anneau de focus ----------
   Le focus a DEUX expressions et il ne faut pas les confondre : ce qui se
   COMMANDE porte l'anneau, ce dans quoi on TAPE n'en porte aucun. La règle des
   champs est écrite juste après, donc plus loin dans la cascade. */
:focus-visible {
  outline: 2px solid var(--couleur-signal-local);
  outline-offset: 2px;
}

/* ---------- Marqueur « vous êtes ici » ----------
   UN SEUL pour toute l'application : rail, listes, onglets, cartes. Un contour
   qui fait le tour, en `box-shadow` inset pour qu'apparaître ne décale aucun
   voisin. Jamais un filet sur le côté gauche (DESIGN.md §8). */
.est-ici {
  box-shadow: inset 0 0 0 1.5px var(--couleur-signal-local);
}

/* ---------- Filet ----------
   Le séparateur par défaut de l'application, à la place des cartes et des ombres. */
.filet {
  border: 0;
  border-top: 1px solid var(--couleur-bordure);
  margin: 0;
}

/* ---------- Icônes ----------
   Dessinées sur mesure, boîte de 20px, trait 1.6, `currentColor`. */
.icone {
  width: 20px;
  height: 20px;
  flex: none;
}

/* ---------- Boutons ---------- */
.bouton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--espace-s);
  min-height: var(--hauteur-commande);
  min-width: 0;
  padding: 0 var(--espace-m);
  border: 1px solid transparent;
  border-radius: var(--rayon);
  background: none;
  color: inherit;
  font-family: var(--police-interface);
  font-size: var(--txt-dense);
  font-weight: 500;
  line-height: 1;
  cursor: pointer;
  transition:
    background-color var(--duree-survol) var(--courbe-sortie),
    border-color var(--duree-survol) var(--courbe-sortie),
    opacity var(--duree-survol) var(--courbe-sortie),
    transform var(--duree-appui) var(--courbe-sortie);
}

.bouton:active {
  transform: scale(0.98);
}

.bouton--principal {
  background: var(--couleur-signal);
  color: var(--couleur-signal-contraste);
}

.bouton--principal:hover {
  opacity: 0.9;
}

.bouton--discret {
  background: var(--couleur-surface);
  border-color: var(--couleur-bordure);
  color: var(--couleur-encre);
}

.bouton--discret:hover {
  background: var(--couleur-papier);
}

/* Carré, sans libellé visible : il porte son intitulé en `aria-label`. Employé
   sur l'encre uniquement, d'où le survol en surface d'encre. */
.bouton--icone {
  width: var(--hauteur-commande);
  padding: 0;
}

.bouton--icone:hover {
  background: var(--couleur-encre-surface);
}

.bouton--icone .icone--fermer {
  display: none;
}

.bouton--icone[aria-expanded="true"] .icone--menu {
  display: none;
}

.bouton--icone[aria-expanded="true"] .icone--fermer {
  display: block;
}

/* ---------- Champs ----------
   `grid-template-columns` explicite : une grille sans template fabrique une
   colonne implicite large comme son contenu, et le groupe déborde de son hôte
   étroit (PIEGES.md E2, troisième cran). */
.champ-groupe {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--espace-xs);
}

.champ-libelle {
  font-size: var(--txt-libelle);
  font-weight: 500;
  letter-spacing: 0.01em;
  color: var(--couleur-encre-douce);
}

.champ {
  min-height: var(--hauteur-commande);
  width: 100%;
  padding: 0 var(--espace-s);
  border: 1px solid var(--couleur-bordure);
  border-radius: var(--rayon);
  background: var(--couleur-surface);
  color: var(--couleur-encre);
  font-family: var(--police-interface);
  font-size: var(--txt-corps);
  transition: border-color var(--duree-survol) var(--courbe-sortie);
}

.champ::placeholder {
  color: var(--couleur-encre-douce);
}

/* Aucun anneau sur ce dans quoi on tape : le curseur de saisie dit déjà où l'on
   est, et la bordure change de teinte (DESIGN.md §6). */
.champ:focus,
.champ:focus-visible {
  outline: none;
  border-color: var(--couleur-signal);
}

.champ-aide {
  margin: 0;
  font-size: var(--txt-libelle);
  color: var(--couleur-encre-douce);
}

/* ---------- Pastille de signal ----------
   Un point de 6px, puis un texte en encre. Jamais un fond pastel avec un texte de
   la même teinte. Le point ne porte jamais l'information seul. */
.pastille {
  display: inline-flex;
  align-items: center;
  gap: var(--espace-s);
  font-size: var(--txt-dense);
  color: var(--couleur-encre);
}

.pastille::before {
  content: "";
  flex: none;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--couleur-encre-douce);   /* en attente : l'état par défaut */
}

.pastille--signal::before {
  background: var(--couleur-signal);
}

.pastille--attention::before {
  background: var(--couleur-attention);
}

.pastille--alerte::before {
  background: var(--couleur-alerte);
}

/* ---------- Marque ----------
   Le mot-symbole, partagé par le rail et les écrans de message. */
.marque {
  font-family: var(--police-editoriale);
  font-weight: 700;
  letter-spacing: -0.01em;
  text-decoration: none;
}

.marque__point {
  display: inline-block;
  width: 0.4em;
  height: 0.4em;
  border-radius: 50%;
  background: var(--couleur-signal-clair);
  margin-left: 0.15em;
}

/* ---------- Lien d'évitement ----------
   Hors de vue par `transform`, donc sans position absolue qui ferait grandir la
   page depuis un cadre défilant (PIEGES.md E12). */
.lien-evitement {
  position: absolute;
  z-index: 40;
  top: var(--espace-s);
  left: var(--espace-s);
  padding: var(--espace-s) var(--espace-m);
  border-radius: var(--rayon);
  background: var(--couleur-surface);
  color: var(--couleur-encre);
  font-size: var(--txt-dense);
  transform: translateY(-300%);
}

.lien-evitement:focus-visible {
  transform: none;
}

/* ============================================================
   ÉCRAN DE MESSAGE PLEIN CADRE
   Matiere encre, un seul bloc centre verticalement. Meme famille que l'ecran de
   connexion (DESIGN.md §5). Sert la page hors ligne, et resservira pour « page
   introuvable » et « acces refuse » (feature 9).
   ============================================================ */
.ecran-message {
  min-height: 100dvh;
  margin: 0;
  display: grid;
  place-items: center;
  padding: var(--espace-l);
  background: var(--couleur-encre-fond);
  color: var(--couleur-sur-encre);
  text-align: center;
}

.ecran-message__bloc {
  max-width: 32rem;
}

.ecran-message__marque {
  font-size: var(--txt-h2);
  color: var(--couleur-sur-encre-douce);
  margin: 0 0 var(--espace-l);
}

.ecran-message h1 {
  font-family: var(--police-editoriale);
  font-size: var(--txt-display);
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.15;
  margin: 0 0 var(--espace-m);
}

.ecran-message p {
  font-size: var(--txt-corps);
  color: var(--couleur-sur-encre-douce);
  margin: 0;
}

/* ============================================================
   SHELL APPLICATIF (DESIGN.md §5)
   Écrit en mobile d'abord : le rail est un tiroir, et la colonne
   permanente arrive dans la requête de media de fin de fichier.
   ============================================================ */
.app {
  min-height: 100dvh;
  padding-top: var(--hauteur-barre);
}

.rail-ouvert {
  overflow: hidden;
}

/* ---------- Barre d'encre, mobile ---------- */
.barre-mobile {
  --couleur-signal-local: var(--couleur-signal-clair);
  position: fixed;
  z-index: 30;
  inset: 0 0 auto 0;
  height: var(--hauteur-barre);
  display: flex;
  align-items: center;
  gap: var(--espace-xs);
  padding-inline: var(--espace-s);
  background: var(--couleur-encre-fond);
  color: var(--couleur-sur-encre);
}

.barre-mobile__titre {
  min-width: 0;
  margin: 0;
  font-size: var(--txt-h2);
  font-weight: 600;
  letter-spacing: -0.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ---------- Voile du tiroir ----------
   `visibility` plutôt que `hidden` : un élément en `display: none` ne peut pas
   être animé, et l'ouverture doit se faire en opacité seule (DESIGN.md §7). */
.voile {
  position: fixed;
  z-index: 20;
  inset: 0;
  background: var(--couleur-encre-fond);
  opacity: 0;
  visibility: hidden;
  transition:
    opacity var(--duree-fermeture) var(--courbe-sortie),
    visibility 0s linear var(--duree-fermeture);
}

.rail-ouvert .voile {
  opacity: 0.55;
  visibility: visible;
  transition:
    opacity var(--duree-ouverture) var(--courbe-entree),
    visibility 0s;
}

/* ---------- Rail d'encre ---------- */
.rail {
  --couleur-signal-local: var(--couleur-signal-clair);
  position: fixed;
  z-index: 25;
  inset: 0 auto 0 0;
  width: var(--largeur-rail);
  max-width: 85vw;
  display: flex;
  flex-direction: column;
  background: var(--couleur-encre-fond);
  color: var(--couleur-sur-encre);
  transform: translateX(-100%);
  visibility: hidden;
  transition:
    transform var(--duree-fermeture) var(--courbe-sortie),
    visibility 0s linear var(--duree-fermeture);
}

.rail-ouvert .rail {
  transform: none;
  visibility: visible;
  transition:
    transform var(--duree-ouverture) var(--courbe-entree),
    visibility 0s;
}

.rail__marque {
  flex: none;
  display: flex;
  align-items: center;
  height: var(--hauteur-barre);
  padding-inline: var(--espace-m);
  font-size: var(--txt-h3);
  color: var(--couleur-sur-encre);
}

/* `position: relative` sur le cadre défilant : sans lui, un descendant en
   position absolue s'échappe du cadre et fait grandir la page (PIEGES.md E12). */
.rail__defilement {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  position: relative;
  padding: var(--espace-s) var(--espace-s) var(--espace-m);
  /* La barre de defilement par defaut est un bandeau clair sur l'encre. */
  scrollbar-width: thin;
  scrollbar-color: var(--couleur-encre-filet) transparent;
}

.rail__groupe + .rail__groupe {
  margin-top: var(--espace-m);
}

.rail__titre {
  margin: 0 0 var(--espace-xs);
  padding-inline: var(--espace-s);
  font-size: var(--txt-libelle);
  font-weight: 500;
  letter-spacing: 0.01em;
  color: var(--couleur-sur-encre-douce);
}

.rail__liste {
  list-style: none;
  margin: 0;
  padding: 0;
}

.rail__lien {
  display: flex;
  align-items: center;
  min-height: var(--hauteur-commande);
  padding: 0 var(--espace-s);
  border-radius: var(--rayon);
  color: var(--couleur-sur-encre-douce);
  text-decoration: none;
  font-size: var(--txt-dense);
  transition:
    background-color var(--duree-survol) var(--courbe-sortie),
    color var(--duree-survol) var(--courbe-sortie);
}

.rail__lien:hover,
.rail__lien.est-ici {
  background: var(--couleur-encre-surface);
  color: var(--couleur-sur-encre);
}

.rail__pied {
  flex: none;
  border-top: 1px solid var(--couleur-encre-filet);
  padding: var(--espace-s);
}

/* ---------- Surface papier ----------
   `min-width: 0` : une piste de grille refuse par défaut de devenir plus étroite
   que son contenu, et le débordement remonte alors au document (PIEGES.md E2). */
.surface {
  min-width: 0;
}

/* La colonne de contenu est CENTRÉE, jamais collée à la gauche de la fenêtre
   (DESIGN.md §5, règle d'agence). */
.colonne {
  max-width: var(--largeur-max);
  margin-inline: auto;
  padding: var(--espace-m);
}

/* Le titre d'écran vit dans la barre d'encre en mobile, ici au bureau. */
.ecran-tete {
  display: none;
  margin-bottom: var(--espace-l);
  padding-bottom: var(--espace-m);
  border-bottom: 1px solid var(--couleur-bordure);
}

.ecran-tete__titre {
  margin: 0;
  font-size: var(--txt-h1);
  font-weight: 600;
  letter-spacing: -0.015em;
}

.ecran-attente {
  margin: 0;
  max-width: 44rem;
  color: var(--couleur-encre-douce);
}

/* ---------- Socle des primitives ----------
   Contenu provisoire de l'accueil : il montre le vocabulaire visuel tant qu'aucun
   écran métier n'existe, et s'en va avec le premier d'entre eux. */
.socle {
  max-width: 44rem;
}

.socle__intro {
  margin: 0 0 var(--espace-l);
  color: var(--couleur-encre-douce);
}

.socle__bloc {
  padding-block: var(--espace-l);
}

.socle__titre {
  margin: 0 0 var(--espace-m);
  font-size: var(--txt-libelle);
  font-weight: 500;
  letter-spacing: 0.01em;
  color: var(--couleur-encre-douce);
}

.socle__rangee {
  display: flex;
  flex-wrap: wrap;
  gap: var(--espace-s);
  margin-bottom: var(--espace-m);
}

/* `min-width: 0` sur les enfants flexibles : sans lui, un bouton impose sa
   largeur à sa barre au lieu de se partager la sienne (PIEGES.md E2). */
.socle__rangee > .bouton {
  min-width: 0;
}

.socle__liste {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: var(--espace-s) var(--espace-l);
  margin: 0 0 var(--espace-m);
  padding: 0;
}

.socle__liste--empilee {
  flex-direction: column;
  gap: var(--espace-xs);
  max-width: 20rem;
}

.socle__choix {
  padding: var(--espace-s) var(--espace-m);
  border-radius: var(--rayon);
  background: var(--couleur-surface);
  font-size: var(--txt-dense);
}

.socle__note {
  margin: 0;
  font-size: var(--txt-dense);
  color: var(--couleur-encre-douce);
}

/* ============================================================
   BUREAU : à partir de 48rem, le tiroir devient une colonne.
   Les requêtes de media sont groupées ici, en fin de feuille : toute retouche
   d'un composant doit donc être écrite APRÈS ce bloc, jamais à côté de sa
   définition, sinon elle est battue en silence (PIEGES.md E27).
   ============================================================ */
@media (min-width: 48rem) {
  :root {
    --txt-display: 2.75rem;
    --txt-h1: 1.875rem;
    --txt-h2: 1.375rem;
    --txt-h3: 1.0625rem;
    --txt-lecture: 1.125rem;
  }

  .app {
    display: grid;
    grid-template-columns: var(--largeur-rail) minmax(0, 1fr);
    padding-top: 0;
  }

  .rail-ouvert {
    overflow: visible;
  }

  .barre-mobile,
  .voile {
    display: none;
  }

  /* Colonne permanente, pleine hauteur, qui ne défile pas avec le contenu.
     Valeurs réécrites en toutes lettres : `revert` rendrait au défaut du
     navigateur, pas à ce que la feuille a déclaré plus haut (PIEGES.md E14). */
  .rail {
    position: sticky;
    inset: auto;
    top: 0;
    align-self: start;
    height: 100dvh;
    width: auto;
    max-width: none;
    transform: none;
    visibility: visible;
    transition: none;
  }

  .rail__lien {
    min-height: var(--hauteur-ligne-dense);
  }

  .ecran-tete {
    display: block;
  }

  .colonne {
    padding: var(--espace-l);
  }
}
