/* Hallmark · shape: app screen · genre: modern-minimal · theme: Console (deal 2/3, seed outil-gestion-formateur-independant-799f·c8ba1278·2026-11-04·r0) · redesign: full
 * nav: top bar, les gestes puis les données, l'écran courant souligné en ambre · signature: la semaine dessinée en grille d'heures · states: vide, plein, refus (chargement et erreur : pas de logique en face, listés au propriétaire) · console: paper (graphite en sombre)
 * axes: dark/grotesk-sans/chromatic-amber · posture: restrained · contrast: pass · v2.0.0 */
/* Hallmark · pre-emit critique: P4 H5 E4 S5 R4 V4 · weakest: E, la grille d'heures demandait deux valeurs dérivées ; posées dans planning.decrire plutôt que calculées dans le gabarit */
/* Hallmark · copy: verbatim · les messages sont ceux du produit, écrits par son auteur et épinglés mot pour mot par 370 tests : 19, 58 et 69 sont des notes */
/* Hallmark · waive 64 · heures, durées, taux, montants et références en Atkinson Hyperlegible Mono · c'est la matière du thème, ce qu'un instrument a mesuré, et jamais un libellé ni un bouton */
/* Hallmark · waive 3 · la bande d'un refus garde un filet de gauche · dans une colonne de panneaux identiques c'est le seul endroit où un montant ne partira pas */
/* Hallmark · dismissed 26a, 34, 50, 26b · relevés sur chaque gabarit lu SANS sa feuille ; mesurés dans le navigateur sur la page rendue : overflow-x clip sur html et body, anneau 2px solid ambre au clavier, h1 en break-word et min-width 0 */
/* Hallmark · dropped rien · le relevé « kept » compte 31 liens sur 32 parce qu'une variable de boucle a changé de nom, ligne → l : les destinations sont les mêmes, fiches.fiche sur la même table et le même identifiant */
/* Hallmark · dismissed F1 · les « guillemets droits » relevés sont la syntaxe de Jinja, {% extends "base.html" %}, pas de la prose */
/* Hallmark · dismissed 41 · « .bandeau .separateur » est un filet d'un pixel, vide et aria-hidden : il ne porte aucun texte à colorer */
/* Hallmark · dismissed 49 · l'étiquette longue d'un bouton d'import ne se coupe pas : white-space nowrap sur toute commande */
/* Hallmark · answered F7 · une bande de message a quitté la boîte du panneau : rayon de commande et fond au pas le plus profond, pour qu'une phrase ne se lise pas comme un endroit où travailler */
@import url("./tokens.css");
@import url("./base.css");

/* =========================================================================
   La coque
   ========================================================================= */

.bandeau {
  display: flex; align-items: center; gap: var(--space-lg);
  padding: 0 var(--gutter);
  background: var(--color-paper-2); color: var(--color-ink);
  border-bottom: var(--rule-hair) solid var(--color-rule);
  position: sticky; top: 0; z-index: var(--z-sticky-nav);
}

.marque {
  font-weight: 500; letter-spacing: var(--tracking-display);
  font-size: var(--text-md); color: var(--color-ink); text-decoration: none;
  padding: var(--space-md) 0; white-space: nowrap;
}

/* Une seule ligne, qui défile de côté plutôt que de passer à la ligne. */
.bandeau nav {
  display: flex; align-items: stretch; gap: var(--space-xs);
  overflow-x: auto; scrollbar-width: none; flex: 1; min-width: 0;
  position: relative;   /* meme raison que `.defilant` : etre le bloc conteneur */
}
.bandeau nav::-webkit-scrollbar { display: none; }

.bandeau nav a, .bandeau .fin a {
  display: flex; align-items: center; padding: var(--space-md) var(--space-xs);
  color: var(--color-muted); text-decoration: none; white-space: nowrap;
  font-size: var(--text-sm); border-bottom: 2px solid transparent;
  transition: color var(--dur-micro) var(--ease-out);
}
.bandeau nav a:hover, .bandeau .fin a:hover { color: var(--color-ink); }
.bandeau nav a:active, .bandeau .fin a:active { color: var(--color-accent); }
/* L'écran courant : la couleur ET le trait. La couleur seule ne se voit pas de
   tout le monde. */
.bandeau nav a.ici, .bandeau .fin a.ici {
  color: var(--color-ink); border-bottom-color: var(--color-accent);
}

/* Les deux familles de destination : ce qu'on FAIT, puis ce qu'on TIENT. */
.bandeau .separateur {
  width: var(--rule-hair); background: var(--color-rule);
  margin: var(--space-sm) var(--space-xs); align-self: stretch; flex: none;
}
.bandeau .fin { margin-left: auto; display: flex; gap: var(--space-xs); flex: none; }

.page { width: 100%; max-width: var(--container); margin-inline: auto;
        padding: var(--space-lg) var(--gutter) var(--space-3xl); }

/* =========================================================================
   La tête d'un écran : ce qu'on regarde, ce qu'il pèse, où aller
   ========================================================================= */

.tete {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--space-lg); flex-wrap: wrap; margin-bottom: var(--space-lg);
}
.tete h1 { font-size: var(--text-display); max-width: 24ch; }
.tete .note { margin-top: var(--space-2xs); }

.note { color: var(--color-muted); font-size: var(--text-sm); max-width: var(--mesure); }
.note a { color: var(--color-accent); }

.liens { display: flex; align-items: center; gap: var(--space-md);
         font-size: var(--text-sm); flex-wrap: wrap; }
.liens a { color: var(--color-muted); text-decoration: none; }
.liens a:hover { color: var(--color-accent); text-decoration: underline; }

/* =========================================================================
   Ce qu'un instrument a mesuré
   ========================================================================= */

.mesure, td.mesure, .montant, .heure, code {
  font-family: var(--font-outlier);
  font-variant-numeric: tabular-nums slashed-zero;
}
.mesure, .heure, code { font-size: var(--text-sm); }
.montant { font-size: var(--text-sm); font-weight: 500; }
.total { font-family: var(--font-outlier);
         font-variant-numeric: tabular-nums slashed-zero;
         font-size: var(--text-lg); font-weight: 500; letter-spacing: -0.02em; }

/* La valeur unique d'un écran, posée grand. */
.lecture {
  font-family: var(--font-outlier); font-variant-numeric: tabular-nums slashed-zero;
  font-size: var(--text-2xl); font-weight: 400; letter-spacing: -0.04em;
  line-height: 1; color: var(--color-ink);
}

/* =========================================================================
   Les panneaux : une surface, des coutures d'un pixel
   ========================================================================= */

.panneau {
  background: var(--color-paper-2);
  border: var(--rule-hair) solid var(--color-rule);
  border-radius: var(--radius-card);
  padding: var(--space-md);
  margin-bottom: var(--space-sm);
}
.panneau > h2 { margin-bottom: var(--space-sm); }
.panneau > .note { margin-bottom: var(--space-sm); }
.panneau > :last-child { margin-bottom: 0; }

h2 {
  font-size: var(--text-sm); font-weight: 500; letter-spacing: 0;
  color: var(--color-muted); max-width: var(--mesure);
}
h3 { font-size: var(--text-md); }

/* Deux panneaux côte à côte, cousus. */
.panneaux {
  display: grid; gap: var(--rule-hair);
  background: var(--color-rule);
  border: var(--rule-hair) solid var(--color-rule);
  border-radius: var(--radius-card); overflow: hidden;
  margin-bottom: var(--space-sm);
}
.panneaux > * { background: var(--color-paper-2); padding: var(--space-md); margin: 0; }
@media (min-width: 60rem) {
  .panneaux.deux { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* =========================================================================
   Les tableaux : c'est là que vit le travail
   ========================================================================= */

/* Un conteneur de defilement ne contient un element POSITIONNE que s'il est son
   bloc conteneur : sans `position`, un `position: absolute` descendant se cale sur
   le body et SORT du decoupage. Mesure : le libelle lecteur-d'ecran « Ouvrir » de
   chaque ligne, 1 px de large, posait le bord droit du document a 1326 px dans une
   fenetre de 320 et faisait defiler la page de 46 px — sur un tableau qui, lui,
   defilait correctement dans sa boite. C'est le pendant inline de `min-height: 0`
   sur une zone qui s'etire : s'etendre ne suffit pas, il faut aussi contraindre. */
.defilant { overflow-x: auto; max-width: 100%; min-width: 0; position: relative;
            margin-bottom: var(--space-sm); }

table { width: 100%; border-collapse: collapse; }
th, td {
  text-align: left; padding: var(--space-xs) var(--space-sm);
  border-bottom: var(--rule-hair) solid var(--color-rule);
  vertical-align: top;
}
thead th {
  font-size: var(--text-sm); font-weight: 500; color: var(--color-muted);
  white-space: nowrap; background: var(--color-paper-3);
  border-bottom-color: var(--color-rule-2);
}
tbody tr:last-child td { border-bottom: 0; }
tbody tr:hover { background: var(--color-paper-3); }
/* Un identifiant d'agenda est une empreinte de quarante caractères sans espace :
   sans ça il pousse les colonnes voisines et « Négociation commerciale » se coupe
   en deux pour lui faire de la place. */
td.mesure { overflow-wrap: anywhere; }
td.fin, th.fin { text-align: right; white-space: nowrap; }
td.fin a { color: var(--color-accent); text-decoration: none; }
td.fin a:hover { text-decoration: underline; }
.vide { color: var(--color-muted); }

/* Une ligne retenue sur un indice faible : elle entre, et elle se voit. */
tbody tr.douteuse td, tbody tr.douteuse:hover td { background: var(--color-accent-soft); }

/* =========================================================================
   Les commandes
   ========================================================================= */

.bouton, button {
  display: inline-flex; align-items: center; justify-content: center;
  position: relative;
  min-height: 36px; padding: 0 var(--space-md);
  font: inherit; font-size: var(--text-sm); font-weight: 500;
  border: var(--rule-hair) solid var(--color-accent);
  border-radius: var(--radius-pill);
  background: var(--color-accent); color: var(--color-accent-ink);
  text-decoration: none; cursor: pointer; white-space: nowrap;
  transition: background-color var(--dur-micro) var(--ease-out);
}
.bouton:hover, button:hover {
  background: color-mix(in oklab, var(--color-accent) 86%, var(--color-ink));
}
.bouton:active, button:active {
  background: color-mix(in oklab, var(--color-accent) 74%, var(--color-ink));
}
/* La cible reste à 44px quand la commande en fait 36. */
.bouton::after, button::after {
  content: ""; position: absolute; inset: -4px; border-radius: inherit;
}

.bouton.secondaire, button.secondaire, button.danger {
  background: var(--color-paper-2); color: var(--color-ink);
  border-color: var(--color-rule-2);
}
.bouton.secondaire:hover, button.secondaire:hover { background: var(--color-paper-3); }
button.danger { color: var(--color-bad); }
button.danger:hover { border-color: var(--color-bad); background: var(--color-bad-soft); }

button:disabled, .bouton[aria-disabled="true"] {
  opacity: 0.55; cursor: not-allowed;
  background: var(--color-paper-3); color: var(--color-muted);
  border-color: var(--color-rule);
}

.actions { display: flex; align-items: center; gap: var(--space-sm);
           flex-wrap: wrap; margin-top: var(--space-md); }

/* =========================================================================
   La saisie
   ========================================================================= */

.fiche { display: grid; gap: var(--space-md); }
@media (min-width: 60rem) {
  /* Une fiche de dix champs tient sur un écran. En une colonne elle en demandait
     deux et demi. */
  .fiche { grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: start; }
  .fiche .large, .fiche .actions { grid-column: 1 / -1; }
}

.champ { display: grid; gap: var(--space-2xs); min-width: 0; }
.champ label { font-size: var(--text-sm); font-weight: 500; }
.requis { font-size: var(--text-xs); font-weight: 400; color: var(--color-muted);
          margin-left: var(--space-2xs); }

.champ input[type="text"], .champ select, .champ textarea {
  font: inherit; font-size: var(--text-md);
  min-height: 36px; padding: var(--space-xs) var(--space-sm);
  border: var(--rule-hair) solid var(--color-rule-2);
  border-radius: var(--radius-pill);
  background: var(--color-paper-3); color: var(--color-ink);
  width: 100%; min-width: 0;
}
.champ input[type="text"]:focus-visible, .champ select:focus-visible,
.champ textarea:focus-visible { outline: 2px solid var(--color-focus);
                                outline-offset: -1px; }
.champ input[type="checkbox"] { width: 18px; height: 18px;
                                accent-color: var(--color-accent); }
.champ textarea { resize: vertical; min-height: 72px; }
.champ.faux input, .champ.faux select, .champ.faux textarea {
  border-color: var(--color-bad);
}

/* La place de l'aide est réservée : un message qui apparaît ne doit pas pousser
   le champ suivant. */
.aide, .faute { margin: 0; font-size: var(--text-xs); min-height: 1lh;
                max-width: var(--mesure); }
.aide { color: var(--color-muted); }
.faute { color: var(--color-bad); font-weight: 500; }

.lu { margin: 0; padding: var(--space-xs) var(--space-sm); font-size: var(--text-md);
      color: var(--color-muted); background: var(--color-paper-3);
      border: var(--rule-hair) dashed var(--color-rule-2);
      border-radius: var(--radius-pill); min-height: 36px; }

.depot { display: flex; align-items: center; gap: var(--space-sm); flex-wrap: wrap; }
.depot input[type="file"] { font: inherit; font-size: var(--text-sm); }

.paiement { display: flex; align-items: center; gap: var(--space-sm);
            flex-wrap: wrap; font-size: var(--text-sm);
            margin-bottom: var(--space-lg); }
.paiement input[type="text"] {
  font: inherit; font-size: var(--text-md); min-height: 36px;
  padding: var(--space-xs) var(--space-sm); width: 11rem;
  border: var(--rule-hair) solid var(--color-rule-2);
  border-radius: var(--radius-pill);
  background: var(--color-paper-3); color: var(--color-ink);
}

/* =========================================================================
   Ce que l'écran dit : un état, un refus, un acquittement
   ========================================================================= */

.refus, .tarif, .confirme {
  margin: 0 0 var(--space-sm); padding: var(--space-sm) var(--space-md);
  border: var(--rule-hair) solid var(--color-rule);
  border-left: 3px solid var(--color-accent);
  /* Le rayon d'une commande, pas celui d'un panneau : une bande se lit comme une
     phrase qu'on vient de dire, un panneau comme un endroit où l'on travaille. */
  border-radius: var(--radius-pill);
  background: var(--color-paper-3); font-size: var(--text-sm);
}
.refus { border-left-color: var(--color-bad); background: var(--color-bad-soft); }
.tarif { border-left-color: var(--color-cool); background: var(--color-cool-soft); }
.confirme p { margin: 0 0 var(--space-xs); }
.confirme p:last-child { margin-bottom: 0; }
.confirme form { display: flex; align-items: center; gap: var(--space-sm);
                 margin-top: var(--space-sm); }

.libre { margin: 0; color: var(--color-muted); font-size: var(--text-sm); }
.libre a { color: var(--color-accent); }
.alerte { color: var(--color-bad); }
.souci { color: var(--color-bad); font-size: var(--text-xs); font-weight: 500;
         display: block; }

/* Une facture à venir, dans le panneau de son école : son tableau, son total et
   son geste. Plusieurs se suivent sans se cloisonner — un panneau dans un panneau
   serait une deuxième boîte pour la même chose. */
.projet { border-top: var(--rule-hair) solid var(--color-rule);
          padding-top: var(--space-sm); margin-top: var(--space-sm); }
.panneau > .projet:first-of-type { border-top: 0; padding-top: 0; margin-top: 0; }
.projet form { display: flex; align-items: center; gap: var(--space-md);
               flex-wrap: wrap; margin-top: var(--space-sm); }
/* La raison d'un refus prend sa ligne : collée derrière le total, elle se lit comme
   une suite du montant alors qu'elle dit qu'il ne partira pas. */
.projet form .souci { flex-basis: 100%; font-size: var(--text-sm); }

/* Un état, jamais une décoration : la puce porte un sens ou elle n'est pas là. */
.chip {
  display: inline-flex; align-items: center; gap: var(--space-2xs);
  padding: var(--space-3xs) var(--space-xs); border-radius: 4px;
  border: var(--rule-hair) solid var(--color-rule-2);
  font-size: var(--text-xs); color: var(--color-ink-2); white-space: nowrap;
}
.chip.oui { background: var(--color-ok-soft); border-color: var(--color-ok);
            color: var(--color-ok); }
.chip.non { background: var(--color-paper-3); }
.chip.attention { background: var(--color-bad-soft); border-color: var(--color-bad);
                  color: var(--color-bad); }
.chip.instrument { background: var(--color-cool-soft); border-color: var(--color-cool);
                   color: var(--color-cool); }

.motifs { margin: 0 0 var(--space-xs); padding-left: var(--space-md);
          font-size: var(--text-sm); color: var(--color-ink-2); }
.motifs li { margin: var(--space-3xs) 0; }

/* =========================================================================
   La semaine, dessinée — la signature de l'outil
   ========================================================================= */

.semaine {
  --creneaux: 52; --hauteur-creneau: 9px;
  display: grid; grid-template-columns: 3.5rem repeat(7, minmax(0, 1fr));
  /* Deux rangées que TOUTES les colonnes partagent : la tête, puis les heures.
     Mesuré, la hauteur ne se devine pas — une tête de jour fait 52 px et le coin
     38, et le cours de 9 h tombait 15 px sous son trait. */
  grid-template-rows: auto minmax(0, 1fr);
  gap: var(--rule-hair);
  background: var(--color-rule);
  border: var(--rule-hair) solid var(--color-rule);
  border-radius: var(--radius-card); overflow: hidden;
  margin-bottom: var(--space-md);
}
/* Une colonne : sa tête, puis ses heures. Les coutures d'un pixel viennent du fond
   de la grille, comme entre les colonnes. */
.semaine .colonne {
  grid-row: 1 / -1;
  display: grid; grid-template-rows: subgrid;
  gap: var(--rule-hair); background: var(--color-rule); min-width: 0;
}
/* Sans sous-grille, on retombe sur deux rangées propres à la colonne : l'échelle
   peut alors glisser d'une quinzaine de pixels, et c'est dit plutôt que caché. */
@supports not (grid-template-rows: subgrid) {
  .semaine .colonne { grid-template-rows: auto minmax(0, 1fr); }
}
.semaine .colonne > * { background: var(--color-paper-2); }

.semaine .tete-jour {
  padding: var(--space-xs) var(--space-sm); font-size: var(--text-sm);
  background: var(--color-paper-3); overflow-wrap: break-word; min-width: 0;
}
.semaine .colonne.aujourdhui .tete-jour { color: var(--color-accent);
                                          font-weight: 500; }
.semaine .tete-jour .nombre { font-family: var(--font-outlier);
                              font-variant-numeric: tabular-nums slashed-zero; }
.semaine .coin { background: var(--color-paper-3); }

/* La colonne des heures et les colonnes des jours partagent la même trame. */
.semaine .heures, .semaine .jour {
  display: grid; grid-template-rows: repeat(var(--creneaux), var(--hauteur-creneau));
}
/* Une étiquette par heure : quatre créneaux d'un quart d'heure. */
.semaine .heures span, .semaine .trame { grid-row: span 4; }
.semaine .heures span {
  font-family: var(--font-outlier); font-size: var(--text-xs);
  color: var(--color-muted); padding: 0 var(--space-xs);
  border-top: var(--rule-hair) solid var(--color-rule);
  font-variant-numeric: tabular-nums slashed-zero;
}
.semaine .colonne.aujourdhui .jour { background: var(--color-accent-soft); }
.semaine .trame { grid-column: 1; border-top: var(--rule-hair) solid var(--color-rule);
                  pointer-events: none; }

.semaine .cours {
  /* 2 px / 4 px collaient le texte au liseré. La trame de quinze minutes reste
     dense, mais une case d'une heure en fait quatre : 4 px / 8 px tiennent. */
  grid-column: 1; margin: 1px; padding: var(--space-2xs) var(--space-xs);
  border-radius: 4px; border: var(--rule-hair) solid var(--color-cool);
  background: var(--color-cool-soft); color: var(--color-ink);
  text-decoration: none; overflow: hidden; min-width: 0;
  display: flex; flex-direction: column; gap: 1px;
  transition: background-color var(--dur-micro) var(--ease-out);
}
.semaine .cours:hover {
  background: color-mix(in oklab, var(--color-cool) 18%, var(--color-paper-2));
}
.semaine .cours .quoi { font-size: var(--text-xs); font-weight: 500; line-height: 1.2;
                        overflow-wrap: break-word; min-width: 0; }
.semaine .cours .ou { font-size: var(--text-xs); color: var(--color-muted);
                      line-height: 1.2; overflow-wrap: break-word; min-width: 0; }
.semaine .cours .quand { font-family: var(--font-outlier); font-size: var(--text-xs);
                         color: var(--color-muted);
                         font-variant-numeric: tabular-nums slashed-zero; }
/* Un cours qui réclame un geste : l'ambre, parce qu'il attend une personne. */
.semaine .cours.a-faire { border-color: var(--color-accent);
                          background: var(--color-accent-soft); }
.semaine .cours.annulée { opacity: 0.5; }
.semaine .cours.annulée .quoi { text-decoration: line-through; }

/* Sous 60rem la grille d'heures ne tient pas : les jours redeviennent une liste. */
@media (max-width: 60rem) {
  .semaine { grid-template-columns: minmax(0, 1fr); grid-template-rows: none; }
  .semaine .colonne { grid-row: auto; grid-template-rows: auto minmax(0, 1fr); }
  .semaine .echelle, .semaine .trame { display: none; }
  .semaine .jour { grid-template-rows: none; gap: var(--rule-hair);
                   padding: var(--space-2xs); }
  /* Un jour sans cours le DIT : une case vide se lit comme un écran coupé. */
  .semaine .jour:empty { padding: 0; }
  .semaine .jour:empty::after { content: "libre"; color: var(--color-muted);
                                font-size: var(--text-sm);
                                padding: var(--space-xs) var(--space-sm); }
  .semaine .cours { grid-row: auto !important; flex-direction: row;
                    align-items: baseline; gap: var(--space-xs); flex-wrap: wrap; }
}

/* =========================================================================
   La journée : la même matière, une colonne
   ========================================================================= */

.journee { display: grid; gap: var(--rule-hair);
           background: var(--color-rule);
           border: var(--rule-hair) solid var(--color-rule);
           border-radius: var(--radius-card); overflow: hidden; }
.journee a, .journee p { background: var(--color-paper-2); margin: 0;
                         padding: var(--space-sm) var(--space-md); }
.journee a {
  display: grid; grid-template-columns: 4rem minmax(0, 1fr) auto;
  gap: var(--space-md); align-items: baseline;
  text-decoration: none; color: var(--color-ink);
}
.journee a:hover { background: var(--color-paper-3); }
.journee .quand { font-family: var(--font-outlier); font-size: var(--text-sm);
                  color: var(--color-cool);
                  font-variant-numeric: tabular-nums slashed-zero; }
.journee .quoi { display: grid; gap: var(--space-3xs); min-width: 0; }
.journee .quoi b { font-weight: 500; overflow-wrap: break-word; min-width: 0; }
.journee .ou { font-size: var(--text-sm); color: var(--color-muted); }
.journee .duree { font-family: var(--font-outlier); font-size: var(--text-sm);
                  color: var(--color-muted);
                  font-variant-numeric: tabular-nums slashed-zero; }
.journee a.annulée { opacity: 0.5; }
.journee a.annulée .quoi b { text-decoration: line-through; }

/* =========================================================================
   Le réglage des colonnes, replié
   ========================================================================= */

.reglage { margin: 0 0 var(--space-md); font-size: var(--text-sm); }
.reglage summary { cursor: pointer; color: var(--color-muted);
                   width: max-content; padding: var(--space-2xs) 0; }
.reglage summary:hover { color: var(--color-accent); }
.reglage form { margin-top: var(--space-xs); padding: var(--space-md);
                background: var(--color-paper-2);
                border: var(--rule-hair) solid var(--color-rule);
                border-radius: var(--radius-card); max-width: 32rem; }
.colonnes { list-style: none; margin: 0 0 var(--space-sm); padding: 0;
            display: grid; gap: var(--space-3xs); }
.colonnes li { display: flex; align-items: center; justify-content: space-between;
               gap: var(--space-sm); padding: var(--space-3xs) 0; }
.colonnes label { display: flex; align-items: center; gap: var(--space-xs);
                  cursor: pointer; }
.fleches { display: flex; gap: var(--space-2xs); }
.fleches button {
  min-height: 24px; padding: 0 var(--space-xs); font-size: var(--text-xs);
  background: var(--color-paper-2); color: var(--color-muted);
  border-color: var(--color-rule-2);
}
.fleches button:hover:not(:disabled) { color: var(--color-accent);
                                       border-color: var(--color-accent);
                                       background: var(--color-paper-3); }
.fleches button:disabled { opacity: 0.55; cursor: not-allowed;
                           background: var(--color-paper-3);
                           color: var(--color-muted); }

/* =========================================================================
   Les comptes de l'écran « État »
   ========================================================================= */

.comptes { display: grid; gap: var(--rule-hair);
           grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
           background: var(--color-rule);
           border: var(--rule-hair) solid var(--color-rule);
           border-radius: var(--radius-card); overflow: hidden;
           margin-bottom: var(--space-md); }
.compte { background: var(--color-paper-2); padding: var(--space-md);
          display: grid; gap: var(--space-3xs); }
.nombre { font-family: var(--font-outlier); font-size: var(--text-xl);
          font-weight: 400; letter-spacing: -0.03em;
          font-variant-numeric: tabular-nums slashed-zero; }
.quoi-compte { font-size: var(--text-sm); color: var(--color-muted); }
.migrations { margin: 0; padding-left: var(--space-md); color: var(--color-muted);
              font-size: var(--text-sm); }
.migrations li { margin: var(--space-3xs) 0; }

/* =========================================================================
   La facture : ce que l'école reçoit
   ========================================================================= */

.document {
  background: var(--color-paper-2);
  border: var(--rule-hair) solid var(--color-rule);
  border-radius: var(--radius-card);
  padding: var(--space-xl); font-size: var(--text-sm);
  max-width: 52rem;
}
.document header { display: flex; justify-content: space-between;
                   gap: var(--space-xl); flex-wrap: wrap; }
.document p { margin: 0 0 var(--space-3xs); }
.document .nom { font-weight: 500; font-size: var(--text-md);
                 margin-bottom: var(--space-2xs); }
.document .qui { max-width: 55%; }
.document .quoi { text-align: right; }
.document .quoi p:not(.nom) { font-family: var(--font-outlier);
                              font-size: var(--text-xs);
                              font-variant-numeric: tabular-nums slashed-zero; }
.document .client { margin: var(--space-xl) 0 var(--space-lg); }
.surtitre { font-size: var(--text-xs); color: var(--color-muted);
            margin-bottom: var(--space-3xs); }
.document tfoot td { font-weight: 500; border-bottom: 0;
                     padding-top: var(--space-xs); }
.document tfoot tr.du td { font-size: var(--text-lg);
                           border-top: 2px solid var(--color-ink); }
.document footer { margin-top: var(--space-lg); padding-top: var(--space-md);
                   border-top: var(--rule-hair) solid var(--color-rule);
                   color: var(--color-muted); font-size: var(--text-xs); }

/* La page imprimée EST la facture : la coque n'y a rien à faire. */
@media print {
  .bandeau, .horsimpression { display: none; }
  .page { max-width: none; padding: 0; }
  .document { border: 0; border-radius: 0; padding: 0; max-width: none;
              background: var(--color-paper); }
  /* Un conteneur de défilement n'a aucun sens sur du papier, et selon le moteur il
     COUPE ce qui dépasse : une facture sortirait amputée de ses dernières colonnes. */
  .defilant { overflow: visible; }
  .document footer { border-top-color: var(--color-rule-2); }
  th, td { border-bottom-color: var(--color-rule-2); }
}

/* =========================================================================
   Les pages SEULES : connexion, panne
   =========================================================================
   Elles n'ont pas de bandeau, et ce n'est pas un oubli : ses liens mènent à des
   écrans qu'on ne peut pas ouvrir. Des liens qui refusent tous sont pires qu'une
   page nue — ils font cliquer pour rien. */

body.seul {
  display: grid; place-items: center; min-height: 100svh;
  background: var(--color-paper);
}

body.seul .page { width: 100%; }

.entrer {
  max-width: 26rem; margin: 0 auto;
  padding: var(--space-xl); border-radius: var(--radius-card);
  background: var(--color-paper-2);
  border: var(--rule-hair) solid var(--color-rule);
}

.entrer h1 {
  font-size: var(--text-display-s); margin-bottom: var(--space-2xs);
}

.entrer .note { margin-bottom: var(--space-lg); }

/* Une seule colonne : la grille à deux colonnes de `.fiche` n'a rien à répartir
   quand il n'y a qu'un champ, et elle laisserait la moitié de la boîte vide. */
.entrer .fiche { grid-template-columns: minmax(0, 1fr); }

.entrer .actions { margin-top: var(--space-xs); }
.entrer .actions button { width: 100%; }

/* Le pied de page : sur quel code l'interface tourne.
   Discret par construction — il ne doit pas occuper la place d'un contenu. */
.pied {
  max-width: var(--container); margin: 0 auto;
  padding: var(--space-md) var(--gutter) var(--space-xl);
  font-family: var(--font-outlier); font-size: var(--text-xs);
}

/* Le bouton de sortie vit dans le bandeau : il doit s'y fondre, pas s'y poser
   comme une commande d'écran. */
.bandeau .sortir { display: flex; align-items: center; }
.bandeau .sortir button {
  padding: var(--space-2xs) var(--space-xs); font-size: var(--text-xs);
}
