/* ==========================================================================
   abiu — console client. La feuille de style est TOUTE l'identité visuelle.

   Contrainte qui décide de tout : la console sert
     default-src 'none'; style-src 'self'; img-src 'self'; script-src 'self'; ...
   Donc aucun style en ligne, aucun attribut style=, aucune police distante,
   aucune image distante. Ce fichier et les SVG voisins sont servis par la
   console elle-même, sous /static/<nom>?v=<empreinte>.
   Voir https://gitlab.com/abiu/apps/erp/-/blob/main/docs/architecture/console-client.md (§4, §5, §14)

   Le parti pris (refonte du 2026-08-02) : la console est un BACK-OFFICE WEB
   moderne — barre latérale sombre à gauche (marque, navigation, déconnexion),
   zone de contenu claire, cartes blanches, tableaux denses. Le langage
   « fenêtre de terminal » est désormais réservé au client lourd poste ; ici la
   marque vit dans la barre latérale d'encre et dans l'accent doré, jamais en
   dominante.

   Les quatre couleurs de marque restent les seuls jetons bruts
   (brand/colors/colors.json). Tout le reste est une transparence posée sur
   elles ou une dérivée précalculée et commentée, pour qu'une évolution de la
   marque n'ait qu'un endroit à changer.
   ========================================================================== */

/* Figtree, police variable auto-hébergée (SIL Open Font License 1.1, voir
   api/internal/console/licences/OFL-Figtree.txt). La politique de sécurité ouvre font-src à la
   seule origine de la console pour elle. */
@font-face {
  font-family: "Figtree";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("Figtree-Variable.woff2") format("woff2");
}

:root {
  /* --- brand/colors/colors.json, les quatre seuls jetons bruts ----------- */
  /* Identité « Soleil » (2026-09-25), dépôt brand colors/colors.json. */
  --encre: #1e231f;
  --surface: #323b35;
  --or: #f2b200;
  --papier: #fffbf3;
  /* Doré foncé : contour du bouton doré, anneau de focus et traits sur fond
     clair, où le doré nu ne fait que 1,8:1. */
  --or-fonce: #7a5200;

  /* Le doré survolé, unique dérivée nommée : c'est exactement la valeur du
     thème de connexion Keycloak, pour que le bouton se comporte pareil des
     deux côtés. */
  --or-clair: #f7c21a;

  /* --- Échelle d'espacement (passe 2, 2026-08-02) ------------------------- *
     Six pas, du serrage d'un jeton à la respiration d'une page. Les règles
     nouvelles s'y réfèrent ; les règles historiques migrent au fil de l'eau
     plutôt que d'un bloc, pour que chaque diff reste lisible. */
  --e-1: 0.25rem;
  --e-2: 0.5rem;
  --e-3: 0.75rem;
  --e-4: 1rem;
  --e-5: 1.5rem;
  --e-6: 2.25rem;

  /* --- Mouvement ---------------------------------------------------------- *
     Une seule durée pour toute l'interface : 140 ms, easing standard. Une
     transition qui varie d'un composant à l'autre se remarque ; une transition
     uniforme s'oublie, et c'est le but. `prefers-reduced-motion` la coupe. */
  --transition: 140ms ease;

  /* --- Pile de polices --------------------------------------------------- *
     Une seule police embarquée depuis l'identité Soleil (2026-09-25) :
     Figtree, servie par la console elle-même (font-src 'self'), en tête de la
     pile SANS. Aucune police distante ; la pile MONOSPACE reste celle de la
     machine.

     Deux piles, et c'est une décision, pas une facilité :
     - la SANS porte l'interface : titres, navigation, boutons, texte courant.
       C'est le langage d'un back-office professionnel, et le lecteur cible est
       un épicier de 55 ans dans un dépôt mal éclairé, pas un développeur ;
     - la MONOSPACE porte les VALEURS : montants, quantités, identifiants,
       tickets. Des chiffres tabulaires alignés sont plus sûrs à comparer, et
       c'est la signature qui relie la console au poste et à la marque. */
  --mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas,
    "Liberation Mono", monospace;
  --sans: "Figtree", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial,
    sans-serif;

  /* --- Thème CLAIR, celui par défaut ------------------------------------- *
     Fond papier, cartes blanches, texte d'encre, accent doré réservé
     aux éléments actifs et aux appels à l'action.

     Contrastes re-mesurés pour l'identité Soleil (WCAG 2.1, luminance relative) :
       encre sur blanc ................ 15,96:1  (AAA)
       encre sur fond de page ......... 15,47:1  (AAA)
       atténué (encre 72 %) sur blanc .  6,29:1  (AA texte courant, AAA grand texte)
       encre sur doré ................. 8,47:1   (AAA, le texte des boutons)
       papier sur encre (barre) ....... 15,47:1  (AAA)
       doré sur encre (barre) ......... 8,47:1   (AAA)
       doré foncé sur fond de page .... 6,70:1   (contour du bouton, focus : 3:1 requis)
     RÈGLE DE MARQUE : le doré ne porte JAMAIS de texte sur fond clair
     (1,83:1). En thème clair il ne sert qu'à remplir des surfaces à texte
     sombre, à souligner et à marquer — jamais à écrire. */
  --fond: #fffbf3;
  --carte: #ffffff;
  --texte: var(--encre);
  --attenue: rgb(30 35 31 / 72%);
  --bordure: rgb(30 35 31 / 10%);
  --bordure-forte: rgb(30 35 31 / 26%);
  --saisie: #ffffff;
  /* Le doré ne contraste pas assez avec un fond clair pour servir d'anneau de
     focus (1,83:1) : c'est le doré foncé qui le porte, à 6,7:1. La barre latérale,
     toujours sombre, redéclare le sien en doré plus bas. */
  --focus: var(--or-fonce);

  /* --- Échelle d'élévation (passe 2) -------------------------------------- *
     Trois niveaux, et une seule idée : une carte est POSÉE, une carte survolée
     se SOULÈVE, un panneau flottant (popover) est AU-DESSUS de tout. L'ancien
     jeton --ombre reste un alias du niveau posé : les règles historiques n'ont
     pas à changer pour continuer d'être vraies. */
  --ombre-1: 0 1px 2px rgb(30 35 31 / 5%), 0 8px 24px rgb(30 35 31 / 6%);
  --ombre-2: 0 2px 4px rgb(30 35 31 / 7%), 0 12px 32px rgb(30 35 31 / 10%);
  --ombre-3: 0 4px 10px rgb(30 35 31 / 12%), 0 20px 48px rgb(30 35 31 / 18%);
  --ombre: var(--ombre-1);

  /* Le creux : une zone EN RETRAIT dans une carte (piste de jauge, fond de
     code). Un cran sous la carte, un cran au-dessus de rien. */
  --creux: rgb(30 35 31 / 6%);

  /* --- Palette sémantique (passe 2) --------------------------------------- *
     Des TONS TEINTÉS, jamais la couleur seule : chaque emploi porte un MOT, la
     teinte ne fait qu'accompagner (WCAG 1.4.1, règle maison). Le doré reste la
     marque et l'action ; le vert dit « en règle », le rouge « en retard », le
     bleu « information ». Contrastes mesurés (luminance relative WCAG 2.1) :
       succès  #1a5530 sur son fond #e7f2ea ...  7,66:1  (AAA)
       succès  #1a5530 sur carte blanche ......  8,80:1  (AAA)
       danger  #8a2a2a sur son fond #fdecec ...  7,52:1  (AAA)
       danger  #8a2a2a sur carte blanche ......  8,59:1  (AAA)
       info    #1f4e79 sur son fond #e8effa ...  7,49:1  (AAA)
       info    #1f4e79 sur carte blanche ......  8,66:1  (AAA) */
  --succes-texte: #1a5530;
  --succes-fond: #e7f2ea;
  --succes-bord: rgb(46 125 79 / 40%);
  --danger-texte: #8a2a2a;
  --danger-fond: #fdecec;
  --danger-bord: rgb(138 42 42 / 40%);
  --info-texte: #1f4e79;
  --info-fond: #e8effa;
  --info-bord: rgb(31 78 121 / 40%);

  /* La piste d'une jauge : décorative (le chiffre exact est toujours écrit à
     côté), elle peut rester sous 3:1 — 1,26:1 mesuré, c'est un guide d'œil. */
  --piste: rgb(30 35 31 / 12%);

  /* La barre latérale est d'encre DANS LES DEUX THÈMES : c'est elle qui porte
     la marque, comme la barre de fenêtre du poste. */
  --lateral-fond: var(--encre);
  --lateral-texte: var(--papier);
  --lateral-attenue: rgb(255 251 243 / 68%);
  --lateral-filet: rgb(255 251 243 / 14%);

  color-scheme: light;
}

/* --- Thème SOMBRE : RETIRÉ (direction propriétaire, 2026-08-03) ----------- *
   La console est CLAIRE, quel que soit le réglage du poste : barre latérale
   d'encre, scène blanche — l'identité back-office voulue. Suivre le réglage
   sombre du système rendait l'écran « terne et triste » (mots du propriétaire)
   et surprenait : la même console changeait de visage d'un poste à l'autre.
   Le bloc @media (prefers-color-scheme: dark) qui vivait ici portait une
   palette mesurée AAA ; le retirer est une décision d'identité, pas d'
   accessibilité — les contrastes du thème clair restent mesurés en tête de
   fichier. color-scheme: light (ci-dessus et dans la balise meta) aligne les
   contrôles natifs. */

/* ==========================================================================
   Socle
   ========================================================================== */

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

html {
  /* 17 px de base plutôt que 16 : un point de plus change tout pour un lecteur
     presbyte, et rien pour les autres. */
  font-size: 106.25%;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  min-height: 100vh;
  background: var(--fond);
  color: var(--texte);
  font-family: var(--sans);
  font-size: 1rem;
  /* 1,55 et non 1,6 (densité passe 2) : le texte courant reste aéré pour un
     lecteur presbyte — la base 17 px ne bouge pas — mais l'écran gagne une
     ligne par carte, et un back-office se juge aussi à ce qu'il montre sans
     défiler. */
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

/* Le dessin d'icône hérite de la couleur du texte qui le porte : une icône
   n'est jamais une information seule, elle accompagne un mot (WCAG 1.4.1).
   `aria-hidden` est posé par le sous-gabarit `icone` de partials.html. */
.icone {
  flex: none;
  width: 1em;
  height: 1em;
  vertical-align: -0.125em;
}

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

/* Un anneau unique pour tout ce qui prend le focus. Visible, épais, décalé :
   c'est la seule affordance dont dispose quelqu'un qui navigue au clavier, et
   la supprimer est la faute d'accessibilité la plus fréquente du web. */
:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 2px;
  border-radius: 4px;
}

/* Lien d'évitement : premier élément focalisable de chaque page, invisible tant
   qu'il n'a pas le focus. */
.saut {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 10;
  padding: 0.6rem 1rem;
  border-radius: 0 0 8px 0;
  background: var(--or);
  color: var(--encre);
  font-weight: 700;
}

.saut:focus {
  left: 0;
}

/* ==========================================================================
   Coquille d'application — barre latérale + scène
   ========================================================================== */

.app {
  display: flex;
  min-height: 100vh;
}

.lateral {
  position: sticky;
  top: 0;
  flex: none;
  display: flex;
  flex-direction: column;
  gap: 1.4rem;
  width: 15.5rem;
  height: 100vh;
  padding: 1.2rem 0.9rem;
  overflow-y: auto;
  background: var(--lateral-fond);
  color: var(--lateral-texte);
  /* La barre est toujours sombre : son anneau de focus est toujours doré,
     quel que soit le thème de la page. */
  --focus: var(--or);
}

.lateral-marque {
  display: flex;
  align-items: baseline;
  gap: 0.55rem;
  padding: 0.2rem 0.55rem;
}

/* Le logo complet Soleil (fruit + mot tracé) : version sombre dans la barre
   d'encre, version claire au-dessus des cartes du portail. 1,75 rem de haut
   donnent plus de 96 px de large, le minimum de la marque. */
.marque-logo {
  /* Pas de display: block : l'image garde sa ligne de base (son bord bas, qui
     est celui des lettres), sur laquelle « console » s'aligne. */
  height: 1.75rem;
  width: auto;
}

.marque-suite {
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--lateral-attenue);
}

.lateral-nav {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
}

.lateral-nav a {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  padding: 0.55rem 0.75rem;
  border-radius: 8px;
  color: var(--lateral-attenue);
  font-size: 0.95rem;
  text-decoration: none;
  transition: background-color var(--transition), color var(--transition);
}

.lateral-nav a:hover {
  background: rgb(255 251 243 / 7%);
  color: var(--papier);
}

/* L'entrée active : filet doré à gauche, voile doré, texte plein. La couleur
   n'informe jamais seule — aria-current="page" porte l'état (WCAG 1.4.1). */
.lateral-nav a[aria-current="page"] {
  background: rgb(242 178 0 / 13%);
  box-shadow: inset 3px 0 0 var(--or);
  color: var(--papier);
  font-weight: 600;
}

.lateral-nav svg {
  flex: none;
  width: 18px;
  height: 18px;
  opacity: 0.85;
}

/* Le groupe dépliable « Tableau de bord » (2026-08-03) : un details/summary
   sans script, dans le langage exact des entrées de la barre. Le chevron —
   dernier svg du summary — pivote à l'ouverture ; les sous-entrées sont
   indentées sous l'icône du groupe, en corps réduit. */
.lateral-groupe > summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 0.65rem;
  padding: 0.55rem 0.75rem;
  border-radius: 8px;
  color: var(--lateral-attenue);
  font-size: 0.95rem;
  transition: background-color var(--transition), color var(--transition);
}

.lateral-groupe > summary::-webkit-details-marker {
  display: none;
}

.lateral-groupe > summary:hover {
  background: rgb(255 251 243 / 7%);
  color: var(--papier);
}

/* Quand une page du groupe est active, le summary reste marqué même replié :
   la classe est posée par le serveur, jamais par la couleur seule (le lien
   actif du sous-menu porte aria-current). */
.lateral-groupe--actif {
  color: var(--papier);
  font-weight: 600;
}

.lateral-groupe > summary span {
  flex: 1;
}

.lateral-groupe > summary svg:last-child {
  width: 14px;
  height: 14px;
  transition: transform var(--transition);
}

.lateral-groupe[open] > summary svg:last-child {
  transform: rotate(180deg);
}

.lateral-sous {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  margin: 0.1rem 0 0.25rem;
  padding-left: 1.55rem;
}

.lateral-sous a {
  display: block;
  padding: 0.42rem 0.75rem;
  border-radius: 8px;
  color: var(--lateral-attenue);
  font-size: 0.9rem;
  text-decoration: none;
  transition: background-color var(--transition), color var(--transition);
}

.lateral-sous a:hover {
  background: rgb(255 251 243 / 7%);
  color: var(--papier);
}

.lateral-sous a[aria-current="page"] {
  background: rgb(242 178 0 / 13%);
  box-shadow: inset 3px 0 0 var(--or);
  color: var(--papier);
  font-weight: 600;
}

/* Le groupe bas de la navigation (« Réglages ») : calé au fond de la barre,
   juste au-dessus du profil — la convention back-office. C'est LUI qui pousse
   désormais vers le bas ; le profil et la sortie suivent sans marge propre. */
.lateral-nav--pied {
  margin-top: auto;
  padding-top: 0.6rem;
  border-top: 1px solid var(--lateral-filet);
}

.lateral-nav--pied ~ .lateral-profil,
.lateral-nav--pied ~ .lateral-sortie {
  margin-top: 0;
}

/* Le profil : les initiales du compte, au-dessus de la déconnexion. La pastille
   reprend le langage de la marque — encre sur doré, 10,43:1 (AAA) — et le nom
   complet reste écrit à côté : la pastille décore, le mot informe. */
.lateral-profil {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  margin-top: auto;
  padding: 0.45rem 0.55rem;
  border-top: 1px solid var(--lateral-filet);
  padding-top: 0.9rem;
}

.lateral-initiales {
  flex: none;
  display: grid;
  place-items: center;
  width: 2.1rem;
  height: 2.1rem;
  border-radius: 50%;
  background: var(--or);
  color: var(--encre);
  font-family: var(--mono);
  font-size: 0.85rem;
  font-weight: 700;
  letter-spacing: 0.02em;
}

.lateral-profil-nom {
  min-width: 0;
  overflow: hidden;
  color: var(--lateral-texte);
  font-size: 0.85rem;
  font-weight: 600;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* La sortie vit en bas : une action de service, discrète mais jamais cachée.
   Quand le profil est présent, c'est lui qui pousse le bloc vers le bas. */
.lateral-sortie {
  margin-top: auto;
}

.lateral-profil + .lateral-sortie {
  margin-top: 0;
}

.lateral-sortie button {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  width: 100%;
  padding: 0.55rem 0.75rem;
  border: 1px solid var(--lateral-filet);
  border-radius: 8px;
  background: transparent;
  color: var(--lateral-attenue);
  font: inherit;
  font-size: 0.9rem;
  cursor: pointer;
  transition: border-color var(--transition), color var(--transition);
}

.lateral-sortie button:hover {
  border-color: var(--lateral-attenue);
  color: var(--papier);
}

/* La scène : zone de contenu claire, largeur de lecture bornée. */
.scene {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  padding: clamp(1.2rem, 0.8rem + 2vw, 2.6rem);
}

.page {
  width: min(64rem, 100%);
  margin-inline: auto;
}

/* Sous 60rem, la barre latérale devient un bandeau : marque et déconnexion sur
   la première ligne, navigation défilante en dessous. Rien n'est masqué, aucun
   toggle, aucun script — la mise en page cède, pas le contenu. */
@media (max-width: 60rem) {
  .app {
    flex-direction: column;
  }

  .lateral {
    position: static;
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem 1rem;
    width: 100%;
    height: auto;
    padding: 0.7rem 1rem;
    overflow: visible;
  }

  .lateral-nav {
    order: 3;
    flex-direction: row;
    flex-basis: 100%;
    overflow-x: auto;
    padding-bottom: 0.2rem;
  }

  /* En bandeau, le groupe bas rejoint la ligne de navigation : plus de fond
     à pousser. */
  .lateral-nav--pied {
    order: 4;
    flex-basis: auto;
    margin-top: 0;
    padding-top: 0;
    border-top: 0;
  }

  .lateral-nav a {
    flex: none;
    padding: 0.4rem 0.65rem;
    font-size: 0.88rem;
  }

  .lateral-nav a[aria-current="page"] {
    box-shadow: inset 0 -3px 0 var(--or);
  }

  .lateral-profil {
    margin-top: 0;
    margin-left: auto;
    padding: 0.2rem;
    border-top: 0;
  }

  .lateral-profil-nom {
    /* Le nom reste dans l'arbre d'accessibilité ; l'entête de page l'affiche
       déjà, le bandeau n'a pas la place de le répéter. */
    position: absolute;
    left: -9999px;
  }

  .lateral-sortie {
    margin-top: 0;
    /* Sans profil (pages qui ne portent pas le nom légal), c'est la sortie qui
       se cale à droite du bandeau. */
    margin-left: auto;
  }

  .lateral-profil + .lateral-sortie {
    margin-left: 0;
  }

  .lateral-sortie button {
    width: auto;
  }

  .lateral-sortie button span {
    /* Le mot reste dans l'accessible name ; seul l'affichage se resserre. */
    position: absolute;
    left: -9999px;
  }
}

/* ==========================================================================
   Portail — les pages hors session (essai, acceptation, refus)
   ========================================================================== */

.portail {
  width: min(34rem, 100% - 2rem);
  margin-inline: auto;
  padding-block: clamp(1.5rem, 1rem + 4vw, 4rem);
}

.portail .marque {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  margin-bottom: 1.2rem;
  padding-left: 0.2rem;
}

.portail .marque .marque-suite {
  color: var(--attenue);
}

.carte-portail {
  padding: clamp(1.4rem, 1rem + 2vw, 2.2rem);
  border: 1px solid var(--bordure);
  /* Le filet doré en haut de carte est la citation du
     `--keycloak-card-top-color` de l'écran de connexion : le client vient de
     le traverser, la carte doit dire « même endroit ». AUCUN état ne change
     cette couleur — ce sont les MOTS qui informent (WCAG 1.4.1). */
  border-top: 3px solid var(--or);
  border-radius: 14px;
  background: var(--carte);
  box-shadow: var(--ombre);
}

/* ==========================================================================
   En-tête de page et cartes de contenu
   ========================================================================== */

/* L'entête de page est une TOPBAR (passe 2) : identité et jeton à gauche,
   filtres et actions à droite, sur une seule ligne tant que la place le permet.
   Les enfants directs se répartissent ; `.entete-droite` porte ce qui se cale
   à droite (périodes, actions). En dessous de 52rem tout retombe en pile. */
.entete-page {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0.6rem 1.2rem;
  margin-bottom: 1.2rem;
}

.entete-identite {
  flex: 1 1 22rem;
  min-width: 0;
}

/* Tout ce qui n'est pas un des deux côtés de la topbar (chapeau, avis, et les
   entêtes historiques non restructurées) occupe sa propre ligne : la topbar ne
   change rien aux pages qui ne l'adoptent pas. */
.entete-page > :not(.entete-identite) {
  flex-basis: 100%;
}

/* Le nom de l'entreprise, au-dessus du titre : la première chose qui dit au
   client que cet espace est le sien. */
.entite {
  margin: 0 0 0.4rem;
  font-family: var(--mono);
  font-size: 0.78rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--attenue);
}

h1 {
  margin: 0 0 0.35rem;
  /* Un cran plus bas qu'avant (1,9rem max → 1,7rem) : densité passe 2. Le
     titre reste le plus gros mot de l'écran, il n'a pas besoin d'être énorme. */
  font-size: clamp(1.35rem, 1.1rem + 1.2vw, 1.7rem);
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -0.015em;
  text-wrap: balance;
}

h2 {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0 0 0.7rem;
  font-size: 1.05rem;
  font-weight: 700;
  letter-spacing: -0.005em;
}

/* L'icône d'un titre de section : un repère d'œil, atténué pour ne pas peser —
   le contraste non textuel demandé est 3:1, l'atténué tient à 5,9:1. */
h2 .icone {
  width: 18px;
  height: 18px;
  color: var(--attenue);
}

h3 {
  margin: 1.2rem 0 0.5rem;
  font-size: 0.95rem;
  font-weight: 700;
}

/* Les sous-titres à icône (rubriques des réglages) : même langage que h2,
   un cran plus discret. Flex pour la même raison que h2 — le socle pose
   `svg { display: block }`, une icône en ligne passerait à la ligne. */
h3 {
  display: flex;
  align-items: center;
  gap: 0.45rem;
}

h3 .icone {
  width: 16px;
  height: 16px;
  color: var(--attenue);
}

p {
  margin: 0 0 1rem;
  max-width: 68ch;
}

/* Le paragraphe de tête, un cran au-dessus du texte courant : il porte la
   phrase que le client lira s'il ne lit qu'une phrase. */
.chapeau {
  font-size: 1.05rem;
  line-height: 1.55;
  color: var(--attenue);
}

.note {
  margin-top: 1.2rem;
  font-size: 0.9rem;
  color: var(--attenue);
}

/* Les liens gardent la couleur du texte et prennent le doré en soulignement :
   du doré en TEXTE serait illisible en thème clair (1,88:1 sur blanc), alors
   qu'un soulignement doré est décoratif et reste conforme. */
a {
  color: inherit;
  text-decoration: underline;
  text-decoration-color: var(--or);
  text-decoration-thickness: 2px;
  text-underline-offset: 0.22em;
}

a:hover {
  text-decoration-thickness: 3px;
}

strong {
  font-weight: 700;
}

/* Chaque section de page est une carte blanche : c'est l'unité visuelle du
   back-office. Le dernier paragraphe d'une carte ne traîne pas sa marge.
   Le survol SOULÈVE la carte d'un niveau d'élévation : une affordance pure,
   qui ne porte aucune information — la carte ne devient pas cliquable. */
.page > section {
  margin: 0 0 1.1rem;
  padding: clamp(1rem, 0.85rem + 0.8vw, 1.4rem);
  border: 1px solid var(--bordure);
  border-radius: 12px;
  background: var(--carte);
  box-shadow: var(--ombre-1);
  transition: box-shadow var(--transition), border-color var(--transition);
}

.page > section:hover {
  border-color: var(--bordure-forte);
  box-shadow: var(--ombre-2);
}

.page > section > :last-child {
  margin-bottom: 0;
}

/* La carte d'état de l'accueil : la carte principale de l'écran, marquée du
   filet doré comme la carte de connexion. */
.carte-etat {
  border-top: 3px solid var(--or);
}

/* ==========================================================================
   Le jeton d'état — badge de statut
   ========================================================================== */

/* Un mot, pas une couleur. Le doré signale « il y a quelque chose à savoir
   ici », et le texte dit quoi. Encre sur doré : 10,43:1 dans les deux thèmes. */
.jeton {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  margin: 0 0 0.6rem;
  padding: 0.18rem 0.65rem;
  border: 1px solid transparent;
  border-radius: 999px;
  background: var(--or);
  color: var(--encre);
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.jeton .icone {
  width: 12px;
  height: 12px;
}

/* Variante sobre pour les états où il n'y a rien à faire : tout va bien, la
   page n'a pas à le crier. */
.jeton--calme {
  background: transparent;
  border-color: var(--bordure-forte);
  color: var(--attenue);
}

/* Variantes sémantiques (passe 2) : ton teinté + mot, jamais la couleur seule.
   Contrastes mesurés en tête de feuille — tous AAA en clair, AA fort en sombre. */
.jeton--succes {
  background: var(--succes-fond);
  border-color: var(--succes-bord);
  color: var(--succes-texte);
}

/* Bannière d'accès anticipé, au-dessus de la carte des pages hors session. */
.bandeau-alpha {
  margin: 0 0 1rem;
  padding: 0.6rem 1rem;
  border-radius: 8px;
  background: var(--encre);
  color: #fff;
  font-size: 0.9rem;
  text-align: center;
  max-width: none;
}

.bandeau-alpha strong {
  margin-right: 0.5rem;
  padding: 0.1rem 0.45rem;
  border-radius: 4px;
  background: var(--or);
  color: var(--encre);
  font-size: 0.75rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

/* ==========================================================================
   Encadré d'avis
   ========================================================================== */

.avis {
  margin: 0 0 1.1rem;
  padding: 0.85rem 1rem;
  border: 1px solid rgb(242 178 0 / 45%);
  border-left: 4px solid var(--or);
  border-radius: 0 8px 8px 0;
  background: rgb(242 178 0 / 12%);
  max-width: none;
}

.avis > :last-child {
  margin-bottom: 0;
}

/* ==========================================================================
   Actions
   ========================================================================== */

.actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.7rem;
  align-items: center;
  margin: 1.3rem 0 0;
  max-width: none;
}

.bouton {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.6rem 1.15rem;
  border: 1px solid var(--or-fonce);
  border-radius: 8px;
  background: var(--or);
  color: var(--encre);
  font-family: var(--sans);
  font-size: 0.95rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--transition), border-color var(--transition),
    box-shadow var(--transition), transform var(--transition);
}

.bouton .icone {
  width: 16px;
  height: 16px;
}

.bouton:hover {
  box-shadow: var(--ombre-1);
}

.bouton:hover {
  background: var(--or-clair);
  text-decoration: none;
}

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

/* Action secondaire : même géométrie, aucun poids. Elle ne doit jamais
   ressembler à l'action principale de l'écran. */
.bouton--discret {
  background: transparent;
  border-color: var(--bordure-forte);
  color: var(--texte);
}

.bouton--discret:hover {
  background: rgb(30 35 31 / 6%);
  border-color: var(--texte);
}

/* ==========================================================================
   Formulaires
   ========================================================================== */

.champ {
  display: block;
  margin: 0 0 1.2rem;
  max-width: 34rem;
}

.champ label {
  display: block;
  margin-bottom: 0.3rem;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--attenue);
}

.champ input,
.champ textarea {
  width: 100%;
  padding: 0.6rem 0.75rem;
  border: 1px solid var(--bordure-forte);
  border-radius: 8px;
  background: var(--saisie);
  color: var(--texte);
  font: inherit;
  transition: border-color var(--transition);
}

.champ input:hover,
.champ textarea:hover {
  border-color: var(--texte);
}

/* La case de consentement occupe une ligne entière et cliquable : la cocher
   forme un contrat, elle ne doit pas être une cible de 13 px au milieu d'un
   paragraphe.
   Voir https://gitlab.com/abiu/apps/erp/-/blob/main/docs/architecture/abonnement-et-paiement.md (§6) */
.consentement {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.8rem;
  align-items: start;
  margin: 0 0 1.2rem;
  padding: 1rem;
  border: 1px solid var(--bordure-forte);
  border-radius: 10px;
  background: rgb(242 178 0 / 7%);
  cursor: pointer;
}

.consentement input[type="checkbox"],
.consentement input[type="radio"] {
  width: 1.2rem;
  height: 1.2rem;
  margin: 0.18rem 0 0;
  /* Le seul endroit du produit où le navigateur dessine lui-même : on lui
     donne la couleur de marque plutôt que de reconstruire une case. */
  accent-color: var(--or);
  cursor: pointer;
}

.consentement span {
  line-height: 1.55;
}

/* Le groupe borné (mentions, droits) : un `fieldset` plutôt que des champs
   libres, la légende dit la borne une seule fois et une synthèse vocale
   l'annonce avant de lire les champs. */
fieldset {
  margin: 1.2rem 0;
  padding: 0.9rem 1rem 0.4rem;
  border: 1px solid var(--bordure);
  border-radius: 8px;
}

legend {
  padding: 0 0.4rem;
  color: var(--attenue);
  font-size: 0.85rem;
  font-weight: 600;
}

/* Une valeur qu'on recopie, pas une phrase qu'on lit. */
code {
  padding: 0.1rem 0.3rem;
  border-radius: 4px;
  background: var(--fond);
  font-family: var(--mono);
  font-size: 0.9em;
}

/* Le sélecteur de fichier est natif : `color-scheme` sur la page suffit à ce
   qu'il suive le thème, et le styler davantage demanderait un faux bouton —
   donc du JavaScript, que cette console n'a pas. */
.champ input[type="file"] {
  width: 100%;
  padding: 0.5rem 0;
  border: 0;
  background: transparent;
  color: var(--texte);
  font-family: var(--sans);
  font-size: 0.95rem;
}

.poste {
  position: relative;
  padding: 0.85rem 1rem;
  border: 1px solid var(--bordure);
  border-radius: 10px;
  background: var(--carte);
  transition: box-shadow var(--transition), border-color var(--transition);
}

.poste:hover {
  border-color: var(--bordure-forte);
  box-shadow: var(--ombre-1);
}

.poste-entete {
  display: flex;
  flex-wrap: wrap;
  gap: 0.7rem;
  align-items: baseline;
  justify-content: space-between;
}

.poste-nom {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  font-weight: 600;
}

.poste-nom .icone {
  width: 16px;
  height: 16px;
  color: var(--attenue);
}

.poste-entete .jeton {
  margin-bottom: 0;
}

/* ==========================================================================
   Étapes
   ========================================================================== */

/* Un fil d'Ariane d'inscription. Il n'affiche QUE des étapes déjà vraies : rien
   n'y annonce un délai, parce que le serveur n'en garantit aucun. */
.etapes {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.4rem;
  margin: 0 0 1.4rem;
  padding: 0;
  list-style: none;
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--attenue);
}

.etape {
  display: flex;
  align-items: center;
  gap: 0.45rem;
}

/* Un carré, pas un rond : la marque est un pixel art, ses puces sont des
   pixels. */
.etape::before {
  content: "";
  width: 0.5rem;
  height: 0.5rem;
  background: var(--bordure-forte);
}

.etape--faite::before {
  background: var(--attenue);
}

.etape--ici {
  color: var(--texte);
  font-weight: 700;
}

.etape--ici::before {
  background: var(--or);
  box-shadow: 0 0 0 3px rgb(242 178 0 / 30%);
}

/* ==========================================================================
   Pied de page
   ========================================================================== */

.pied {
  display: flex;
  flex-wrap: wrap;
  gap: 0.8rem 1.5rem;
  align-items: center;
  justify-content: space-between;
  margin-top: 1.6rem;
  padding: 0 0.2rem;
  font-size: 0.88rem;
  color: var(--attenue);
}

.pied p {
  margin: 0;
}

/* ==========================================================================
   Jauges — SVG rendus par le SERVEUR
   ========================================================================== */

.anneau-piste {
  stroke: var(--piste);
}

/* Le nombre au centre de l'anneau : un TEXTE SVG, même encre que la page. */
.anneau-valeur {
  fill: var(--texte);
  font-family: var(--mono);
  font-size: 9px;
  font-weight: 700;
}

.anneau-libelle {
  fill: var(--attenue);
  font-family: var(--sans);
  font-size: 3.4px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* La jauge de l'essai sur l'accueil : anneau simple, le doré trace sur la
   PASTILLE D'ENCRE que le SVG embarque (10,43:1, non textuel largement au-delà
   de 3:1) — jamais sur la carte claire. */
.jauge-essai {
  margin: 0.4rem 0 1rem;
}

.jauge-essai .anneau {
  width: 7.5rem;
  height: 7.5rem;
}

.anneau-fond {
  fill: var(--encre);
}

.anneau--pastille .anneau-piste {
  stroke: rgb(255 251 243 / 22%);
}

.anneau--pastille .seg-or {
  stroke: var(--or);
}

.anneau--pastille .anneau-valeur {
  fill: var(--papier);
}

.anneau--pastille .anneau-libelle {
  fill: rgb(255 251 243 / 78%);
}

/* ==========================================================================
   Préférences système
   ========================================================================== */

/* Une transition de 140 ms n'a jamais aidé personne à comprendre un écran.
   Quelqu'un qui a demandé moins d'animation la reçoit. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
  }
}

/* Réglage « contraste élevé » : on retire les transparences des filets, qui
   sont précisément ce que ce réglage demande de supprimer. Les tons teintés de
   la palette sémantique perdent leur voile de fond — le texte teinté, déjà
   AAA sur carte nue, reste ; et les pistes décoratives des jauges montent au
   niveau des filets. */
@media (prefers-contrast: more) {
  :root {
    --bordure: var(--texte);
    --bordure-forte: var(--texte);
    --attenue: var(--texte);
    --lateral-attenue: var(--lateral-texte);
    --lateral-filet: var(--lateral-texte);
    --succes-fond: transparent;
    --danger-fond: transparent;
    --info-fond: transparent;
    --succes-bord: var(--succes-texte);
    --danger-bord: var(--danger-texte);
    --info-bord: var(--info-texte);
    --piste: var(--texte);
  }
}

/* ==========================================================================
   Attente animée — l'écran de préparation d'un environnement
   ==========================================================================

   Décision du 2026-08-06 (proprietaire) : cet écran a le droit de bouger. La
   règle qui tenait avant — aucune animation d'attente — venait d'un temps où
   RIEN ne consommait les demandes ; un anneau aurait alors tourné dans le vide.
   Le réconciliateur existe désormais et provisionne en continu, donc un
   indicateur INDÉTERMINÉ redevient honnête : il dit « ça travaille », jamais
   « ça finit dans X ». Toujours pas de pourcentage, pas de compte à rebours.
   Sans JS, la page se recharge seule (noscript meta-refresh) ; avec JS, un
   petit sondage remplace le rechargement et joue la coche quand c'est prêt. */

.attente {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.9rem;
  margin: 1.4rem 0 1.2rem;
}

/* Le fruit Soleil qui saute, tourne et se coupe (GIF du dépôt brand,
   animations/chargement, fond blanc = celui de la carte). Un GIF ne s'arrête
   pas avec `animation-duration` : sous `prefers-reduced-motion`, la <picture>
   sert le fruit fixe à la place. */
.attente-fruit,
.attente-fruit img {
  display: block;
  width: 120px;
  height: 120px;
}

.scene {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.25rem;
  padding: 1rem 0 0.5rem;
  text-align: center;
}

.attente--grand {
  margin: 0 0 -1.5rem;
}

.attente--grand .attente-fruit,
.attente--grand .attente-fruit img {
  width: 240px;
  height: 240px;
}

.attente--grand .attente-coche {
  width: 120px;
  height: 120px;
  margin: 60px 0;
}

.scene-titre {
  margin: 0;
  font-size: clamp(1.6rem, 1.2rem + 1.4vw, 2.4rem);
  font-weight: 800;
  letter-spacing: -0.02em;
}

/* Les trois points clignotent l'un après l'autre. */
.points span {
  animation: points-clignent 1.2s ease-in-out infinite;
}

.points span:nth-child(2) {
  animation-delay: 0.2s;
}

.points span:nth-child(3) {
  animation-delay: 0.4s;
}

@keyframes points-clignent {
  0%,
  100% {
    opacity: 0.2;
  }
  50% {
    opacity: 1;
  }
}

.astuces {
  width: min(100%, 38rem);
  margin-top: 0.75rem;
  padding: 1.5rem 1.75rem;
  border: 1px solid var(--bordure);
  border-radius: 16px;
  background: var(--carte);
  text-align: left;
}

.astuces-titre {
  margin: 0 0 0.6rem;
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--or-fonce);
}

.astuce {
  min-height: 5.2rem;
  animation: astuce-monte 450ms ease-out both;
}

.astuce[hidden] {
  display: none;
}

.astuce-nom {
  margin: 0 0 0.3rem;
  font-size: 1.25rem;
  font-weight: 700;
}

.astuce-texte {
  margin: 0;
  font-size: 1.05rem;
  line-height: 1.5;
  color: var(--attenue);
}

@keyframes astuce-monte {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

.astuces-points {
  display: flex;
  gap: 6px;
  margin-top: 0.9rem;
}

.astuces-points span {
  width: 6px;
  height: 6px;
  border-radius: 3px;
  background: var(--bordure-forte);
  transition: width var(--transition), background var(--transition);
}

.astuces-points span.actif {
  width: 24px;
  background: var(--or);
}

/* Moins d'animation demandée : la règle globale réduit les durées, mais une
   animation infinie de 0,01 ms clignoterait ; on les coupe net. */
@media (prefers-reduced-motion: reduce) {
  .points span,
  .astuce {
    animation: none;
    opacity: 1;
  }
}

/* La coche : absente pendant l'attente, révélée et tracée quand c'est prêt. */
.attente-coche {
  width: 72px;
  height: 72px;
  display: none;
}

.attente-coche .cercle {
  fill: none;
  stroke: var(--or);
  stroke-width: 5;
  opacity: 0.35;
}

.attente-coche .trait {
  fill: none;
  stroke: var(--or);
  stroke-width: 6;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 42;
  stroke-dashoffset: 42;
}

/* Bascule « prêt », posée par attente.js : l'anneau s'efface, la coche surgit
   et se trace. */
.attente--pret .attente-fruit {
  display: none;
}

.attente--pret .attente-coche {
  display: block;
  animation: attente-pop 420ms ease-out both;
}

.attente--pret .attente-coche .trait {
  animation: attente-trace 520ms 140ms ease-out forwards;
}

@keyframes attente-trace {
  to {
    stroke-dashoffset: 0;
  }
}

@keyframes attente-pop {
  0% {
    transform: scale(0.55);
    opacity: 0;
  }
  60% {
    transform: scale(1.1);
    opacity: 1;
  }
  100% {
    transform: scale(1);
    opacity: 1;
  }
}

/* Entrée douce de la carte « prêt » (chemin sans JS, après rechargement). */
.pret-arrivee {
  animation: pret-monte 460ms ease-out both;
}

@keyframes pret-monte {
  from {
    transform: translateY(8px);
    opacity: 0;
  }
  to {
    transform: translateY(0);
    opacity: 1;
  }
}

/* ==========================================================================
   Parcours d'ouverture d'une démo (maquette B « Vitrine », brand
   maquettes/inscription, validée le 2026-10-06) : la marque et ses promesses
   sur fond d'encre à gauche, l'écran du moment sur papier à droite. Sur un
   écran étroit, les deux blocs s'empilent.
   ========================================================================== */
.vitrine {
  min-height: 100vh;
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
  background: var(--papier);
}

.vitrine-marque {
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 2.2rem;
  padding: 3rem clamp(1.5rem, 5vw, 3.5rem);
  background: var(--encre);
  color: #f4f0e7;
}

/* Le halo doré du coin : décoratif, sous le texte. */
.vitrine-marque::after {
  content: "";
  position: absolute;
  right: -180px;
  bottom: -200px;
  width: 520px;
  height: 520px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(242, 178, 0, 0.35), transparent 65%);
  pointer-events: none;
}

.vitrine-titre {
  margin: 0;
  max-width: 14ch;
  font-size: clamp(1.9rem, 3.4vw, 2.4rem);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.03em;
}

.vitrine-titre em {
  font-style: normal;
  color: var(--or);
}

.vitrine-promesses {
  position: relative;
  z-index: 1;
  display: grid;
  gap: 0.7rem;
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: 1.1rem;
  color: rgba(244, 240, 231, 0.85);
}

.vitrine-promesses li {
  display: flex;
  align-items: center;
  gap: 0.7rem;
}

.vitrine-promesses .icone {
  flex: none;
  width: 1.5rem;
  height: 1.5rem;
  padding: 0.3rem;
  border-radius: 50%;
  background: rgba(124, 196, 149, 0.18);
  color: #7cc495;
}

.vitrine-sortie {
  position: relative;
  z-index: 1;
  margin: 0;
}

.vitrine-sortie button {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  font-size: 0.9rem;
  color: rgba(244, 240, 231, 0.6);
  cursor: pointer;
}

.vitrine-sortie button:hover {
  color: #f4f0e7;
}

.vitrine-ecran {
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 3rem clamp(1.5rem, 5vw, 4.5rem);
}

.vitrine-ecran h1 {
  margin: 0 0 0.5rem;
  font-size: 2rem;
  letter-spacing: -0.02em;
}

.vitrine-chapeau {
  margin: 0 0 2rem;
  line-height: 1.5;
  color: rgba(30, 35, 31, 0.62);
}

.vitrine-formulaire {
  display: grid;
  gap: 1.1rem;
  max-width: 26rem;
}

.vitrine-formulaire .champ,
.vitrine-formulaire .note {
  margin: 0;
}

.vitrine-formulaire .bouton {
  justify-content: center;
  width: 100%;
  padding: 0.9rem 1.4rem;
  font-size: 1.05rem;
}

.vitrine-bas {
  margin: 1.4rem 0 0;
  font-size: 0.9rem;
  color: rgba(30, 35, 31, 0.62);
}

.vitrine-bas + .vitrine-bas {
  margin-top: 0.4rem;
}

.vitrine-bas a {
  color: inherit;
}

/* L'attente : le fruit, le titre, une barre INDÉTERMINÉE (jamais un
   pourcentage), puis les astuces. */
.vitrine-ecran--attente {
  align-items: center;
  text-align: center;
}

.vitrine-ecran--attente .astuces {
  max-width: 26rem;
  text-align: left;
}

.vitrine-barre {
  width: 16rem;
  height: 6px;
  margin: 0 auto 2rem;
  overflow: hidden;
  border-radius: 99px;
  background: rgba(30, 35, 31, 0.12);
}

.vitrine-barre span {
  display: block;
  width: 35%;
  height: 100%;
  border-radius: 99px;
  background: var(--or);
  animation: vitrine-glisse 1.4s ease-in-out infinite;
}

@keyframes vitrine-glisse {
  from {
    transform: translateX(-100%);
  }
  to {
    transform: translateX(300%);
  }
}

@media (prefers-reduced-motion: reduce) {
  .vitrine-barre span {
    animation: none;
    width: 100%;
    opacity: 0.4;
  }
}

@media (max-width: 820px) {
  .vitrine {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto 1fr;
  }

  .vitrine-marque {
    gap: 1.2rem;
    padding: 1.5rem 1rem;
  }

  .vitrine-marque::after {
    display: none;
  }

  .vitrine-ecran {
    padding: 2rem 1rem;
  }
}
