/*
 * ═══════════════════════════════════════════════════════════════════════════
 * regard pro — LE SYSTÈME DE DESIGN, APPLIQUÉ
 *
 * Anatomie des composants de DESIGN.md § 7 et § 8, écrite avec les jetons de
 * « jetons.css ». Aucune valeur en dur : tout passe par une variable.
 *
 * ───────────────────────────────────────────────────────────────────────────
 * TOUT EST SOUS PORTÉE « .systeme »
 *
 * Un écran adopte le système en passant `systeme: true` à son gabarit. Les
 * autres gardent l'habillage actuel, au pixel près.
 *
 * C'est ce qui permet de juger un écran pilote sur pièce sans faire bouger les
 * huit autres, et de revenir en arrière en retirant un drapeau — le projet n'a
 * pas de gestion de versions, une bascule générale serait irréversible.
 *
 * Le jour où tous les écrans auront basculé : retirer « .systeme » de ces
 * sélecteurs, supprimer le :root de style.css, et fondre ce fichier dedans.
 * ═══════════════════════════════════════════════════════════════════════════
 */

/* ───────────────────────────────────────────────────────────────────────────
 * Le conteneur
 * ─────────────────────────────────────────────────────────────────────────── */
.systeme {
  max-width: var(--largeur-contenu);
  margin: 0 auto;
  padding: var(--e-6) var(--e-5);
  font-size: var(--t-corps);
  font-weight: var(--g-normal);
  line-height: var(--i-corps);
}

.systeme h1 {
  font-size: var(--t-titre);
  line-height: var(--i-titre);
  font-weight: var(--g-gras);
  letter-spacing: -0.02em;
}

.systeme h2 {
  font-size: var(--t-section);
  line-height: var(--i-section);
  font-weight: var(--g-demi);
  letter-spacing: -0.01em;
}

/* Le texte d'introduction d'un écran : une seule phrase, largeur de lecture. */
.systeme .chapeau {
  margin-top: var(--e-2);
  max-width: var(--largeur-lecture);
  color: var(--gris);
}

.systeme .titre-ligne {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--e-3);
  flex-wrap: wrap;
}

.systeme .secondaire {
  font-size: var(--t-secondaire);
  line-height: var(--i-secondaire);
  color: var(--gris);
  font-weight: var(--g-normal);
}

/* ⚠️ « --gris-clair » est SOUS le seuil AA : réservé à ce qui ne porte
   aucune information — un tiret d'absence de valeur, un espace réservé. */
.systeme .absent,
.systeme .manquant { color: var(--gris-clair); }

.systeme .etiquette-jeton {
  font-family: var(--mono);
  font-size: var(--t-micro);
  line-height: var(--i-micro);
  text-transform: uppercase;
  letter-spacing: var(--approche-micro);
  color: var(--gris);
}

/* ───────────────────────────────────────────────────────────────────────────
 * Compteurs — § 4.2, grille auto-ajustable
 *
 * Compter les cartes dans le gabarit pour choisir une classe se trompe dès
 * qu'une carte devient conditionnelle. C'est arrivé, deux fois.
 * ─────────────────────────────────────────────────────────────────────────── */
.systeme .compteurs {
  display: grid;
  /* « min(100%, 190px) » : sous 190 px de large, la grille passe a UNE colonne
     au lieu d'ecraser les cartes. Mesure a 375 px : les compteurs tombaient a
     157 px et « 4 960,00 € » se coupait sur trois lignes. */
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 190px), 1fr));
  gap: 14px;
  margin-top: var(--e-5);
}
.systeme .compteurs > * { min-width: 0; }

/*
 * ⚠️⚠️ LA TEINTE D'ACCENT EST RETIRÉE DU COMPTEUR — 10/09/2026.
 *
 * Cette règle mélangeait 6 % d'accent au fond et 18 % à la bordure, et son
 * commentaire disait l'avoir « relevé dans le DOM de Regard AI ». C'était une
 * lecture trop large : dans Regard AI, la teinte `from-primary/5` est posée
 * sur UN SEUL bloc — le briefing du matin, en tête de cockpit. Toutes les
 * autres cartes, y compris les blocs de chiffres, sont le composant `Card` :
 * `rounded-2xl border-border/60 bg-card p-4 shadow-card`. BLANC.
 *
 * Le défaut ne se voyait pas tant que l'accent était un ardoise : 6 % de gris
 * bleu sur du blanc ne se remarque pas. Passé au rouge REGARD, chaque compteur
 * du produit est devenu rose. **Une teinte dérivée d'une couleur variable
 * cache son propre défaut tant que la couleur est discrète.**
 */
.systeme .compteur {
  padding: var(--e-4);                        /* ← Card : p-4                */
  border: var(--trait) solid var(--ligne);    /* ← border-border/60          */
  background: var(--blanc);                   /* ← bg-card                   */
  border-radius: var(--rayon-grand);          /* ← rounded-2xl               */
}

/* ⚠️ LIBELLÉ ET VALEUR SUR LA MÊME LIGNE DE BASE, AUX DEUX BORDS.
   C'est LE trait du motif de Regard AI, et le seul que je n'avais nulle part :
   nos compteurs empilaient la valeur PUIS l'étiquette, l'une sous l'autre.
   Le libellé porte l'accent du club ; la valeur reste en encre. */
.systeme .compteur-tete {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--e-3);
}

.systeme .compteur .nombre {
  /* ⚠️ OUTFIT, PAS DM MONO — mesuré dans le DOM de Regard AI.
     Le produit écrivait le MÊME chiffre de deux façons : `<strong>` en DM Mono
     18 px sur six écrans, `.nombre` en Outfit 30 px sur trois autres, parce que
     seul « style.css » stylait `.nombre`. Un seul nom, une seule règle. */
  font-family: var(--sans);
  font-size: var(--t-chiffre);
  font-weight: var(--g-noir);
  line-height: 1.2;
  letter-spacing: -0.02em;
  color: var(--encre);
  font-variant-numeric: tabular-nums;
  /* Un montant ne se coupe jamais entre le nombre et sa devise. */
  white-space: nowrap;
  text-align: right;
}

.systeme .compteur .etiquette {
  /* `min-width: 0` : sans lui, un libellé long (« quatre mille sept cent… »)
     pousse la valeur hors de la carte au lieu de passer à la ligne. */
  min-width: 0;
  font-family: var(--sans);
  font-size: var(--t-petit);
  font-weight: var(--g-gras);
  line-height: var(--i-petit);
  text-transform: uppercase;
  letter-spacing: var(--approche-micro);
  /* ⚠️ Le libellé portait l'accent du club. Dans Regard AI, un libellé de carte
     est `text-muted-foreground` — jamais le primaire : le rouge y désigne une
     ACTION, pas une étiquette. Un écran où dix libellés sont rouges n'a plus
     de rouge disponible pour dire « clique ici ». */
  color: var(--gris);
}

/* La ligne de précision — facultative. Elle dit ce que le chiffre ne dit pas
   tout seul : un reste, un dénominateur, une échéance. */
.systeme .compteur .precision {
  display: block;
  margin-top: 3px;
  font-size: var(--t-micro);
  line-height: var(--i-micro);
  color: var(--gris);
  text-transform: none;
  letter-spacing: normal;
  font-weight: var(--g-normal);
}

/* Un seul cas colore une valeur : de l'argent en retard, ou un reste à livrer. */
.systeme .compteur-erreur { border-color: var(--etat-retard-bord); }
.systeme .compteur-erreur .nombre { color: var(--etat-retard-texte); }

/* Imbriqué dans une carte, le compteur se resserre — Regard AI passe de `p-4`
   à `p-3` dès qu'une carte en contient d'autres. */
.systeme .carte-cockpit .compteurs { margin-top: var(--e-4); gap: var(--e-2); }
.systeme .carte-cockpit .compteur { padding: var(--e-3); }

/* ───────────────────────────────────────────────────────────────────────────
 * Boutons — § 7.1
 * ─────────────────────────────────────────────────────────────────────────── */
/*
 * LE BOUTON — porté de `components/ui/Button.tsx` (Regard AI), 10/09/2026.
 *
 * ⚠️ Regard AI a SIX variantes et TROIS tailles ; regard pro en avait deux et
 * une. Le portage n'ajoute pas ce qui ne sert pas : on porte l'ANATOMIE — les
 * hauteurs, les rayons, les textes, les états — et les variantes qui ont un
 * emploi réel ici. `success` (« Approuver / Terminer ») n'en a pas encore.
 */
.systeme .bouton,
.systeme .bouton-discret,
.systeme .bouton-danger {
  display: inline-flex;              /* ← inline-flex                          */
  align-items: center;
  justify-content: center;
  gap: var(--e-2);                   /* ← gap-2                                */
  min-height: var(--h-bouton-m);     /* ← h-9 (36 px)                          */
  padding: 0 14px;                   /* ← px-3.5                               */
  font-family: inherit;
  font-size: var(--t-corps);         /* ← text-[12.5px]                        */
  font-weight: var(--g-demi);        /* ← font-semibold                        */
  text-decoration: none;
  border: none;
  border-radius: var(--rayon);       /* ← rounded-xl                           */
  cursor: pointer;                   /* ← cursor-pointer                       */
  user-select: none;                 /* ← select-none                          */
  transition: background-color var(--duree) var(--courbe),
              opacity var(--duree) var(--courbe);
}

/* ─── Les tailles de Regard AI ─────────────────────────────────────────────
   ⚠️ `petit` descend à 28 px. DESIGN.md § 7.1 porte la règle de compensation :
   elle est réservée aux actions SECONDAIRES d'une ligne dense sur écran large.
   Jamais un geste qu'on peut avoir à faire depuis un téléphone. */
.systeme .bouton.petit,
.systeme .bouton-discret.petit {
  min-height: var(--h-bouton-s);     /* ← h-7 (28 px)                          */
  padding: 0 10px;                   /* ← px-2.5                               */
  gap: 6px;                          /* ← gap-1.5                              */
  font-size: var(--t-petit);         /* ← text-[11.5px]                        */
  border-radius: var(--rayon-petit); /* ← rounded-lg                           */
}
.systeme .bouton.grand,
.systeme .bouton-discret.grand {
  min-height: var(--h-bouton-l);     /* ← h-11 (44 px)                         */
  padding: 0 20px;                   /* ← px-5                                 */
  font-size: var(--t-section);       /* ← text-[14px] → notre palier 13        */
}

/* ─── Les variantes ───────────────────────────────────────────────────────
   `primary` = l'accent. `secondary` de Regard AI est `bg-foreground` : l'encre,
   pas une seconde couleur — c'est ce que porte `.bouton-discret.sombre`. */
.systeme .bouton {
  background: var(--accent);         /* ← bg-primary                           */
  color: var(--texte-sur-accent);
  box-shadow: 0 1px 2px rgba(10, 10, 10, 0.05);   /* ← shadow-sm               */
}
.systeme .bouton:hover {
  /* ⚠️ Regard AI éclaircit le FOND (`hover:bg-primary/90`), il ne baisse pas
     l'opacité de tout le bouton : le texte blanc resterait à 90 % sur un fond
     à 90 %, et le contraste baisserait des deux côtés à la fois. */
  background: color-mix(in srgb, var(--accent) 90%, var(--blanc));
}
.systeme .bouton-discret {
  background: var(--blanc);          /* ← outline : bg-white                   */
  color: var(--encre);
  border: var(--trait) solid var(--ligne);
}
.systeme .bouton-discret:hover { background: var(--sourdine); }  /* ← hover:bg-muted */
.systeme .bouton-discret.sombre {
  background: var(--encre);          /* ← secondary : bg-foreground            */
  color: var(--blanc);
  border-color: var(--encre);
}
.systeme .bouton-discret.sombre:hover {
  background: color-mix(in srgb, var(--encre) 90%, var(--blanc));
}
/* ⚠️ LE DANGER N'EST PAS L'ACCENT, et Regard AI fait la même séparation : son
   `danger` est `rose-600`, jamais son primaire. Un « Supprimer » du même rouge
   que « Enregistrer » se clique par erreur. */
.systeme .bouton-danger {
  background: var(--etat-retard-texte);
  color: var(--blanc);
}
.systeme .bouton-danger:hover {
  background: color-mix(in srgb, var(--etat-retard-texte) 88%, #000);
}

/* ⚠️ L'ANNEAU DE FOCUS PASSE À L'ACCENT — ← focus-visible:ring-ring/50.
   Il était en encre parce que l'accent appartenait au club et pouvait être
   illisible ; il ne peut plus l'être. */
.systeme .bouton:focus-visible,
.systeme .bouton-discret:focus-visible,
.systeme .bouton-danger:focus-visible,
.systeme .lien-bouton:focus-visible,
.systeme .pastille:focus-visible {
  outline: var(--trait-fort) solid var(--accent);
  outline-offset: 1px;               /* ← ring-offset-1                        */
}

/* ← disabled:opacity-50 disabled:pointer-events-none */
.systeme .bouton[disabled],
.systeme .bouton-discret[disabled],
.systeme .bouton-danger[disabled] {
  opacity: 0.5;
  pointer-events: none;
}

/* Une action tertiaire, en apparence de lien — mais à 40 px de haut. */
.systeme .lien-bouton {
  display: inline-flex;
  align-items: center;
  min-height: var(--h-cible);
  padding: 0 var(--e-2);
  background: none;
  border: none;
  font-family: inherit;
  font-size: var(--t-secondaire);
  color: var(--gris);
  text-decoration: underline;
  cursor: pointer;
  border-radius: var(--rayon);
}
.systeme .lien-bouton:hover { color: var(--encre); background: var(--papier); }

.systeme .petit-lien {
  display: inline-flex;
  align-items: center;
  min-height: var(--h-cible);
  font-size: var(--t-secondaire);
  color: var(--gris);
}
.systeme .petit-lien:hover { color: var(--encre); }

/* ───────────────────────────────────────────────────────────────────────────
 * Pastilles de filtre
 *
 * L'actif est en ENCRE, jamais en accent : un filtre actif en accent devient
 * illisible avec un accent pâle et hurle avec un accent saturé.
 * ─────────────────────────────────────────────────────────────────────────── */
.systeme .pastilles {
  display: flex;
  flex-wrap: wrap;
  gap: var(--e-2);
  margin-top: var(--e-5);
}
/* ⚠️ 28 PX, LA TAILLE `sm` DE REGARD AI. Une pastille de filtre est une action
   SECONDAIRE dans une rangée dense — le cas que DESIGN.md § 7.1 autorise
   expressément pour `sm`. Elles étaient à 40. */
.systeme .pastille {
  display: inline-flex;
  align-items: center;
  gap: 6px;                          /* ← gap-1.5                              */
  min-height: var(--h-bouton-s);     /* ← h-7                                  */
  padding: 0 12px;
  font-size: var(--t-petit);         /* ← text-[11.5px]                        */
  font-weight: var(--g-demi);
  text-decoration: none;
  color: var(--gris);
  background: var(--blanc);
  border: var(--trait) solid var(--ligne);
  border-radius: var(--rayon-plein);
  transition: background var(--duree) var(--courbe), color var(--duree) var(--courbe);
}
.systeme .pastille:hover { color: var(--encre); background: var(--sourdine); }
/*
 * ⚠️ L'ÉTAT ACTIF RESTE EN ENCRE, PAS EN ACCENT — et le motif a changé.
 *
 * Il disait : « sur le fond encre, un accent sombre tombe à 1,41:1 — un
 * ornement que la moitié des clubs ne verrait pas ». Ce motif est mort avec la
 * personnalisation. Le nouveau : un écran d'inventaire porte QUINZE pastilles
 * de filtre. Les allumer en rouge mettrait quinze appels à l'action sur un
 * écran qui n'en a qu'un — le bouton principal. Regard AI réserve son primaire
 * de la même façon : son entrée de navigation active est `bg-muted`, pas
 * `bg-primary`, et seul un rail de 2 px porte le rouge.
 */
.systeme .pastille.active {
  background: var(--encre);
  color: var(--blanc);
  border-color: var(--encre);
}
.systeme .pastille .compte {
  font-family: var(--mono);
  font-size: var(--t-petit);
  font-variant-numeric: tabular-nums;
  opacity: 0.7;
}
.systeme .pastille-alerte { border-color: var(--etat-retard-bord); color: var(--etat-retard-texte); }
.systeme .pastille-alerte.active {
  background: var(--etat-retard-texte);
  border-color: var(--etat-retard-texte);
  color: var(--blanc);
}

/* ───────────────────────────────────────────────────────────────────────────
 * Étiquettes d'état — § 7.2, palette FIXE
 *
 * Toujours accompagnées de leur libellé écrit : daltonisme, écran mal réglé,
 * impression en noir et blanc — la même information doit passer.
 * ─────────────────────────────────────────────────────────────────────────── */
/*
 * ⚠️ PORTÉ DE `components/ui/Badge.tsx` — `rounded-full px-2 py-0.5
 * text-[10px] font-bold`, un aplat pastel SANS bordure.
 *
 * ⚠️ DEUX ÉCARTS, TOUS DEUX MOTIVÉS :
 *
 *   · la TAILLE. Regard AI écrit ses badges à 10 px ; le plancher du produit
 *     est 11 (DESIGN.md § 3.2), et son propre `MASTER.md` documente « micro
 *     10–10,5 ». Un état — « impayée », « en retard » — est une information
 *     qu'on doit lire, pas une décoration : c'est exactement ce que le
 *     plancher protège.
 *
 *   · la BORDURE, gardée. Regard AI s'en passe parce que ses badges vivent sur
 *     du blanc. Les nôtres se posent aussi sur `--papier` et dans des cellules
 *     survolées en `--sourdine`, où un aplat très pâle perd son contour. La
 *     bordure est ce qui fait qu'un état reste un objet distinct, et non une
 *     nuance de fond.
 */
.systeme .etat {
  display: inline-flex;
  align-items: center;
  gap: 4px;                          /* ← gap-1                                */
  padding: 2px 8px;                  /* ← px-2 py-0.5                          */
  font-size: var(--t-micro);         /* ← text-[10px] → plancher 11            */
  line-height: var(--i-micro);
  font-weight: var(--g-gras);        /* ← font-bold                            */
  border-radius: var(--rayon-plein); /* ← rounded-full                         */
  border: var(--trait) solid;
  white-space: nowrap;
}

.systeme .etat-fa-brouillon,
.systeme .etat-fa-annulee {
  color: var(--etat-neutre-texte);
  background: var(--etat-neutre-fond);
  border-color: var(--etat-neutre-bord);
}
.systeme .etat-fa-emise {
  color: var(--etat-alerte-texte);
  background: var(--etat-alerte-fond);
  border-color: var(--etat-alerte-bord);
}
.systeme .etat-fa-partiellement_payee {
  color: var(--etat-info-texte);
  background: var(--etat-info-fond);
  border-color: var(--etat-info-bord);
}
.systeme .etat-fa-payee {
  color: var(--etat-succes-texte);
  background: var(--etat-succes-fond);
  border-color: var(--etat-succes-bord);
}

/* Le retard : le SEUL signal de cet écran. */
.systeme .en-retard { color: var(--etat-retard-texte); font-weight: var(--g-demi); }
.systeme .complet { color: var(--etat-succes-texte); font-weight: var(--g-demi); }

/* ───────────────────────────────────────────────────────────────────────────
 * Tableau — § 7.4, lignes de 40 px
 * ─────────────────────────────────────────────────────────────────────────── */
.systeme .liste {
  width: 100%;
  border-collapse: collapse;
  margin-top: var(--e-5);
  background: var(--blanc);
  border: var(--trait) solid var(--ligne);
  border-radius: var(--rayon-grand);
  overflow: hidden;
}
/* ⚠️ L'EN-TÊTE DE REGARD AI : `px-3 py-2 text-left font-semibold`, en police
   de texte et non en monospace. Le produit l'écrivait en DM Mono, capitales
   espacées — un trait qui n'existe nulle part chez lui, et qu'on remarque
   immédiatement en ouvrant les deux logiciels l'un après l'autre. La monospace
   reste où elle sert : les CHIFFRES alignés. */
.systeme .liste th {
  text-align: left;
  padding: 8px 12px;                 /* ← px-3 py-2                            */
  font-family: var(--sans);
  font-size: var(--t-petit);         /* ← text-[11.5px]                        */
  font-weight: var(--g-demi);        /* ← font-semibold                        */
  text-transform: none;
  letter-spacing: normal;
  color: var(--gris);                /* ← text-muted-foreground                */
  border-bottom: var(--trait) solid var(--ligne);
}
.systeme .liste td {
  padding: 10px 12px;                /* ← px-3 py-2.5                          */
  font-size: var(--t-corps);
  border-bottom: var(--trait) solid var(--ligne);
  vertical-align: middle;
}
.systeme .liste tbody tr:last-child td { border-bottom: 0; }
.systeme .liste tbody tr { transition: background var(--duree) var(--courbe); }
.systeme .liste tbody tr:hover { background: var(--sourdine); }  /* ← hover:bg-muted */

.systeme .liste .principal { font-weight: var(--g-demi); }
.systeme .liste .principal a { color: var(--encre); text-decoration: none; }
.systeme .liste .principal a:hover { text-decoration: underline; }

/* ─── LA LIGNE ENTIÈRE EST LA CIBLE ────────────────────────────────────────
 *
 * Mesuré : le lien de référence faisait 18 px de haut, celui du partenaire
 * 19 px — très loin du plancher de 40 px. Un lien en ligne dans une cellule
 * n'est pas cliquable au pouce, et c'est le geste le plus fréquent de cet
 * écran.
 *
 * Le lien principal s'étire sur toute la ligne : la cible devient la ligne
 * elle-même. Motif standard, accessible — le lien reste un vrai lien pour le
 * clavier et le lecteur d'écran, seule sa surface de clic change.
 * ───────────────────────────────────────────────────────────────────────── */
.systeme .liste tbody tr { position: relative; }
.systeme .liste td.principal > a::after {
  content: '';
  position: absolute;
  inset: 0;
}

/* ⚠️ TOUT CE QUI EST CLIQUABLE DANS UNE LIGNE DOIT REPRENDRE LA MAIN
   ------------------------------------------------------------------------
   La surface étirée ci-dessus recouvre la ligne ENTIÈRE, boutons compris. Un
   bouton posé dans une cellule sans reprendre la main est parfaitement visible,
   parfaitement stylé — et parfaitement inerte : le clic part sur la fiche.

   Le défaut est apparu sur « Aujourd'hui » : « Marquer comme faite », le bouton
   le plus cliqué de l'écran d'accueil, ne faisait rien. Aucun test ne pouvait le
   voir, et à l'écran tout paraissait normal. Vérifié par
   `document.elementFromPoint` au centre du bouton.

   La règle vise donc la CELLULE d'action, pas une classe de lien : une nouvelle
   commande y sera couverte sans qu'on ait à y penser. */
.systeme .liste td.actions,
.systeme .liste td.actions form {
  position: relative;
  z-index: 1;
}

/* Le bouton d'une ligne est une cible comme une autre : 40 px, jamais moins.
   Mesuré à 20 px avant correction — la moitié du plancher. */
.systeme .liste td.actions button,
.systeme .liste td.actions .lien-bouton {
  min-height: var(--h-cible);
  padding: 0 12px;
  font-size: var(--t-secondaire);
  font-weight: var(--g-demi);
  color: var(--encre);
  background: var(--blanc);
  border: var(--trait) solid var(--ligne);
  border-radius: var(--rayon);
  cursor: pointer;
}

.systeme .liste td.actions button:hover { border-color: var(--gris); }

.systeme .liste td.actions button:focus-visible {
  outline: var(--trait-fort) solid var(--encre);
  outline-offset: 2px;
}

/* Les liens SECONDAIRES d'une ligne doivent rester atteignables par-dessus la
   surface étirée, et atteindre eux aussi les 40 px. */
.systeme .liste td .lien-discret {
  position: relative;
  z-index: 1;
  display: inline-block;
  padding: 11px 0;
  margin: -11px 0;
}
.systeme .liste .secondaire { display: block; }

/* ⚠️ « display: block » vise le rappel placé SOUS un nom. Sur un <td>, il sort
   la cellule de la mise en table : sa bordure basse flotte au milieu de la
   ligne. Défaut déjà rencontré sur la liste des packs — il revient dès qu'on
   réécrit la règle ailleurs. */
.systeme .liste td.secondaire { display: table-cell; }
.systeme .liste .a-droite { text-align: right; }
.systeme .liste .montant {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
/* ⚠️ « border: 0 » : la feuille historique donne une bordure basse a ce lien
   pour le souligner. Combinee a la marge negative qui lui donne ses 40 px,
   elle dessinait un trait parasite au milieu de la carte en petit ecran. */
.systeme .lien-discret { color: var(--gris); text-decoration: none; border: 0; }
.systeme .lien-discret:hover { color: var(--encre); text-decoration: underline; }

.systeme .denombrement {
  margin-top: var(--e-3);
  font-family: var(--mono);
  font-size: var(--t-micro);
  text-transform: uppercase;
  letter-spacing: var(--approche-micro);
  color: var(--gris);
}

/* Sous 760 px : l'en-tête disparaît, chaque cellule porte son intitulé.
   Sans lui, un « 1 » isolé ne veut plus rien dire — défaut constaté. */
@media (max-width: 760px) {
  .systeme .liste thead { display: none; }
  .systeme .liste tr { display: block; border-bottom: var(--trait) solid var(--ligne); }
  .systeme .liste tr:last-child { border-bottom: 0; }
  .systeme .liste td { display: block; border: 0; padding: var(--e-1) var(--e-4); }
  .systeme .liste td:first-child { padding-top: var(--e-3); }
  .systeme .liste td:last-child { padding-bottom: var(--e-3); text-align: left; }
  .systeme .liste td[data-intitule]::before {
    content: attr(data-intitule);
    display: block;
    margin-bottom: 1px;
    font-family: var(--mono);
    /* ⚠️ Écrit à 10 px, SOUS le plancher de 11 — et sur téléphone, là où on lit
       le plus mal. C'est le rappel d'intitulé de colonne : le retirer rendrait
       la cellule incompréhensible, le rendre illisible revient au même. */
    font-size: var(--t-micro);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--gris);
  }
}

/* ───────────────────────────────────────────────────────────────────────────
 * Filtre par partenaire
 * ─────────────────────────────────────────────────────────────────────────── */
.systeme .filtre-ligne {
  display: flex;
  align-items: center;
  gap: var(--e-3);
  flex-wrap: wrap;
  margin-top: var(--e-4);
}
.systeme .filtre-ligne .etiquette-champ {
  font-family: var(--mono);
  font-size: var(--t-micro);
  text-transform: uppercase;
  letter-spacing: var(--approche-micro);
  color: var(--gris);
}
.systeme .filtre-ligne select {
  min-height: var(--h-champ);
  padding: 0 14px;
  font-family: inherit;
  font-size: var(--t-corps);
  color: var(--encre);
  background: var(--champ);
  border: var(--trait) solid var(--ligne);
  border-radius: var(--rayon);
}
.systeme .filtre-ligne select:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 25%, transparent);
}

/* ───────────────────────────────────────────────────────────────────────────
 * Messages et état vide — § 7.7 et § 7.8
 * ─────────────────────────────────────────────────────────────────────────── */
.systeme .confirmation {
  margin-bottom: var(--e-5);
  padding: 14px 18px;
  border-radius: var(--rayon);
  border-left: 3px solid var(--etat-succes-texte);
  background: var(--etat-succes-fond);
  color: var(--etat-succes-texte);
}

/*
 * L'ÉTAT VIDE — porté de `components/ui/EmptyState.tsx` (Regard AI).
 *
 * Sa forme : colonne centrée, icône en gris très pâle, titre 13 px, explication
 * 11,5 px sur une largeur courte, action en dessous. `gap-2 px-6 py-10`.
 *
 * ⚠️ L'ICÔNE EST FACULTATIVE ET DÉCORATIVE. Elle porte `aria-hidden` : ce qui
 * dit quoi faire, c'est la PHRASE. Une icône qui remplacerait le texte
 * laisserait un écran vide entièrement muet — exactement le moment où l'on a
 * le plus besoin qu'on nous parle. DESIGN.md § 7.8 l'exige déjà : « les états
 * vides disent QUOI FAIRE ».
 */
.systeme .vide {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--e-2);                   /* ← gap-2                                */
  margin-top: var(--e-5);
  padding: 40px 24px;                /* ← px-6 py-10                           */
  text-align: center;
  background: var(--blanc);
  border: var(--trait) solid var(--ligne);
  border-radius: var(--rayon-grand); /* ← rounded-2xl                          */
  font-size: var(--t-petit);         /* ← text-[11.5px]                        */
  line-height: 1.6;                  /* ← leading-relaxed                      */
  color: var(--gris);
}
/* ⚠️ Une explication qui traverse tout l'écran ne se lit pas : Regard AI la
   borne à `max-w-xs`. La nôtre suit la mesure de lecture du produit. */
.systeme .vide > * { max-width: 34ch; }
.systeme .vide .vide-icone {
  color: var(--ligne);               /* ← text-muted-foreground/30             */
  margin-bottom: var(--e-1);
}
.systeme .vide .vide-titre {
  font-size: var(--t-section);       /* ← text-[13px]                          */
  font-weight: var(--g-demi);        /* ← font-semibold                        */
  color: var(--encre);
  margin: 0;
}
.systeme .vide a { color: var(--encre); }

/* ───────────────────────────────────────────────────────────────────────────
 * Écran « Aujourd'hui »
 *
 * Les alertes sont des CARTES, pas des bandeaux empilés : un bandeau pleine
 * largeur se lit comme un message système qu'on chasse, une carte se lit comme
 * un dossier à traiter. Chacune porte son libellé écrit — jamais la couleur
 * seule (daltonisme, écran mal réglé, impression en noir et blanc).
 * ─────────────────────────────────────────────────────────────────────────── */

.systeme .alertes {
  display: grid;
  /* Même garde que les compteurs : sous 375 px, une grille en fractions pures
     écrasait les cartes au lieu de les empiler. */
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
  gap: var(--e-4);
  margin-top: var(--e-5);
}

/*
 * ⚠️⚠️ REPRISES EN DISCRÉTION LE 10/09/2026 — DEMANDE DE CHARLES.
 *
 * Elles avaient été GROSSIES le 09/09, à sa demande aussi : titre 24 px,
 * bouton 44 px, couleur de gravité sur le texte. Cinq cartes de ce poids sur
 * un écran qui n'a qu'UNE action principale : chacune réclamait le regard, et
 * plus rien ne ressortait. C'est le défaut classique d'une page où tout est
 * important.
 *
 * Ce qui porte la gravité maintenant : le FILET de gauche et le MOTIF. Le
 * titre revient à l'encre et à l'échelle du produit. Un signal se lit d'autant
 * mieux qu'il est seul de son espèce.
 */
.systeme .alerte-carte {
  display: flex;
  flex-direction: column;
  gap: var(--e-3);
  padding: var(--e-4);
  background: var(--blanc);
  border: var(--trait) solid var(--ligne);
  /* Le filet de gauche porte la gravité. 3 px : il se voit sans peser, la
     couleur du motif le redit juste à côté. */
  border-left: 3px solid var(--ligne);
  border-radius: var(--rayon-grand);
  box-shadow: var(--ombre-carte);
}

/* Le motif et le titre sur une seule ligne de base. */
.systeme .alerte-tete {
  display: flex;
  align-items: flex-start;
  gap: var(--e-3);
  margin: 0;
}

/* ⚠️ LE MOTIF DANS UNE PASTILLE TEINTÉE, pas nu : posé seul sur du blanc, un
   trait de 15 px se perd. La pastille lui donne la surface minimale pour se
   lire, et c'est elle qui porte la couleur de gravité. */
.systeme .alerte-motif {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  flex-shrink: 0;
  border-radius: var(--rayon-petit);
  background: var(--sourdine);
  color: var(--gris);
}

.systeme .alerte-bloquant    { border-left-color: var(--etat-retard-texte); }
.systeme .alerte-attention   { border-left-color: var(--etat-alerte-texte); }
.systeme .alerte-information { border-left-color: var(--etat-info-texte); }

/* La pastille du motif reprend le triplet de l'état — fond pâle, texte foncé.
   Ce sont les mêmes couleurs que partout ailleurs dans le produit (§ 2.3) :
   un retard se lit du même rouge sur une vignette et sur une étiquette. */
.systeme .alerte-bloquant  .alerte-motif {
  background: var(--etat-retard-fond); color: var(--etat-retard-texte);
}
.systeme .alerte-attention .alerte-motif {
  background: var(--etat-alerte-fond); color: var(--etat-alerte-texte);
}
.systeme .alerte-information .alerte-motif {
  background: var(--etat-info-fond); color: var(--etat-info-texte);
}

/* ⚠️ LE TITRE REVIENT DANS L'ÉCHELLE — `--t-alerte` (24 px) est retiré.
   C'était la seule exception typographique du produit, née le 09/09 pour
   grossir ces vignettes ; elle disparaît avec la raison qui l'avait créée.
   Une exception qu'on garde après son motif devient une dette. */
.systeme .alerte-titre {
  font-size: var(--t-chiffre);
  font-weight: var(--g-demi);
  line-height: 1.3;
  letter-spacing: -0.01em;
  color: var(--encre);
}

.systeme .alerte-detail {
  font-size: var(--t-secondaire);
  line-height: var(--i-secondaire);
  color: var(--gris);
  /* Pousse le lien en bas : sans cela, des cartes de hauteurs différentes
     alignent leurs liens n'importe où et l'œil ne trouve plus l'action. */
  flex: 1;
}

/* ⚠️ L'ACTION D'UNE ALERTE EST UN BOUTON, PLUS UN LIEN SOULIGNÉ.
   Demande de Charles, 09/09/2026 : « agrandis les boutons ». C'est la variante
   « contour » de DESIGN.md § 7.1 — fond blanc, trait de 1 px, encre — celle
   des « actions courantes ». Pas « principal » : il n'y en a qu'un par écran,
   et une alerte peut en porter cinq.
   Hauteur 44 px et marges 0 20px : la taille MOYENNE du § 7.1, pas une
   quatrième inventée pour l'occasion. */
/* ⚠️ 44 → 36 PX. C'est la taille MOYENNE de Regard AI (`h-9`), pas une
   quatrième inventée : voir DESIGN.md § 7.1. Elle avait été portée à 44 le
   09/09 avec les titres, pour la même demande, et redescend avec eux.
   ⚠️ PAS 28 : une alerte du matin se traite aussi depuis un téléphone, et
   `sm` est réservée aux actions secondaires d'une ligne dense sur grand
   écran. C'est la règle de compensation du § 7.1, appliquée. */
.systeme .alerte-lien {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  min-height: var(--h-bouton-m);
  padding: 0 14px;
  background: var(--blanc);
  border: var(--trait) solid var(--ligne);
  border-radius: var(--rayon);
  font-size: var(--t-corps);
  font-weight: var(--g-demi);
  color: var(--encre);
  text-decoration: none;
  transition: background var(--duree) var(--courbe);
}

.systeme .alerte-lien:hover { background: var(--sourdine); }

.systeme .rien-a-signaler {
  margin-top: var(--e-5);
  padding: var(--e-4) var(--e-5);
  background: var(--etat-succes-fond);
  border: var(--trait) solid var(--etat-succes-bord);
  border-radius: var(--rayon-grand);
  font-size: var(--t-corps);
  color: var(--etat-succes-texte);
  max-width: var(--largeur-lecture);
}

/* Une échéance qui tombe le jour même n'est pas un retard : elle ne prend pas
   la couleur du retard, sinon tout paraît en retard tout le temps. */
.systeme .echeance-du-jour {
  font-weight: var(--g-demi);
  color: var(--encre);
}

.systeme .note-basse {
  margin-top: var(--e-3);
  font-size: var(--t-secondaire);
  color: var(--gris);
  max-width: var(--largeur-lecture);
}

/* ─── Jauge d'objectif ───────────────────────────────────────────────────────
 * L'un des quatre endroits où l'accent du club a le droit d'être un aplat.
 * `--accent-lisible` et non `--accent` : sur le fond clair de la piste, un
 * accent pâle disparaîtrait — mesure faite sur la barre de navigation.
 * ─────────────────────────────────────────────────────────────────────────── */

.systeme .jauge {
  margin-top: var(--e-4);
  height: 10px;
  background: var(--champ);
  border: var(--trait) solid var(--ligne);
  border-radius: var(--rayon-plein);
  overflow: hidden;
}

.systeme .jauge-remplie {
  height: 100%;
  background: var(--accent-lisible);
  border-radius: var(--rayon-plein);
}

/* ─── Voyant de conformité, en résumé ─────────────────────────────────────── */

.systeme .conformite-resume {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--e-3);
  margin-top: var(--e-4);
  padding: var(--e-3) var(--e-4);
  background: var(--blanc);
  border: var(--trait) solid var(--ligne);
  border-radius: var(--rayon-grand);
  font-size: var(--t-corps);
}

.systeme .conformite-resume .conformite-pastille {
  width: 10px;
  height: 10px;
  border-radius: var(--rayon-plein);
  flex: none;
}

.systeme .conformite-ok .conformite-pastille        { background: var(--etat-succes-texte); }
.systeme .conformite-attention .conformite-pastille { background: var(--etat-alerte-texte); }

.systeme .conformite-resume a {
  /* Repoussé à droite, et à 40 px de haut comme toute cible. */
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  min-height: var(--h-cible);
  font-weight: var(--g-demi);
  color: var(--encre);
  text-underline-offset: 3px;
}

.systeme .deconnexion {
  margin-top: var(--e-6);
  padding-top: var(--e-4);
  border-top: var(--trait) solid var(--ligne);
}

/* Se déconnecter n'est pas une action de l'écran d'accueil : le bouton reste
   atteignable à 40 px, mais il ne pèse pas plus que le reste. Sans cette
   règle il s'affichait large et centré, et attirait l'œil avant les alertes. */
.systeme .deconnexion button {
  min-height: var(--h-cible);
  padding: 0 14px;
  font-size: var(--t-secondaire);
  color: var(--gris);
  background: transparent;
  border: var(--trait) solid var(--ligne);
  border-radius: var(--rayon);
  cursor: pointer;
}

.systeme .deconnexion button:hover { color: var(--encre); border-color: var(--gris); }

.systeme .deconnexion button:focus-visible {
  outline: var(--trait-fort) solid var(--encre);
  outline-offset: 2px;
}

/* ───────────────────────────────────────────────────────────────────────────
 * Les CINQ autres familles d'états — même palette fixe que les factures
 *
 * Chaque famille dit la même chose avec ses propres mots : un contrat « signé »
 * et une contrepartie « livrée » et une facture « payée » sont trois succès. Ils
 * doivent donc porter la même couleur, sinon on réapprend l'outil à chaque
 * écran.
 *
 * ⚠️ Les couleurs d'avant étaient écrites en dur, hors palette. Mesure sur la
 * liste des partenaires : « Actif » tombait à 4,58:1 — le minimum strict pour du
 * texte de 11 px. La palette fixe le porte à 6,52:1.
 *
 * Le NEUTRE sert à ce qui n'est pas commencé ou plus actif ; l'INFO à ce qui est
 * en cours ; le SUCCÈS à ce qui est tenu ; l'ALERTE à ce qui attend une suite ;
 * le RETARD à ce qui a échoué ou été annulé.
 * ─────────────────────────────────────────────────────────────────────────── */

.systeme .etat-prospect,
.systeme .etat-inactif,
.systeme .etat-cp-a_faire,
.systeme .etat-cp-annulee,
.systeme .etat-contrat-brouillon,
.systeme .etat-ec-a_venir {
  color: var(--etat-neutre-texte);
  background: var(--etat-neutre-fond);
  border-color: var(--etat-neutre-bord);
}

.systeme .etat-en_negociation,
.systeme .etat-cp-planifiee,
.systeme .etat-contrat-envoye,
.systeme .etat-contrat-actif {
  color: var(--etat-info-texte);
  background: var(--etat-info-fond);
  border-color: var(--etat-info-bord);
}

.systeme .etat-actif,
.systeme .etat-cp-livree,
.systeme .etat-cp-prouvee,
.systeme .etat-preuve,
.systeme .etat-contrat-signe,
.systeme .etat-contrat-termine,
.systeme .etat-ec-payee {
  color: var(--etat-succes-texte);
  background: var(--etat-succes-fond);
  border-color: var(--etat-succes-bord);
}

.systeme .etat-contacte {
  color: var(--etat-alerte-texte);
  background: var(--etat-alerte-fond);
  border-color: var(--etat-alerte-bord);
}

.systeme .etat-perdu,
.systeme .etat-contrat-annule,
.systeme .etat-ec-en_retard {
  color: var(--etat-retard-texte);
  background: var(--etat-retard-fond);
  border-color: var(--etat-retard-bord);
}

/* ⚠️ « Inactif » n'avait AUCUN fond : seule étiquette sur six à flotter sans
   pastille. Le sélecteur générique ci-dessus ne suffit pas — il faut que la
   règle de forme s'applique aussi, sinon la couleur arrive sur rien. */
.systeme [class*='etat-'] {
  display: inline-flex;
  align-items: center;
  padding: 3px 10px;
  font-size: var(--t-petit);
  font-weight: var(--g-demi);
  line-height: var(--i-petit);
  border-radius: var(--rayon-plein);
  border: var(--trait) solid;
  white-space: nowrap;
}

/* ─── Tri des colonnes ───────────────────────────────────────────────────────
 * ⚠️ Mesuré à 15 px de haut : un en-tête de colonne cliquable est une cible
 * comme une autre. Le remplissage est repris en marge négative pour ne pas
 * gonfler l'en-tête.
 * ─────────────────────────────────────────────────────────────────────────── */

.systeme .liste th a {
  display: inline-flex;
  align-items: center;
  min-height: var(--h-cible);
  margin: -12px 0;
  color: inherit;
  text-decoration: none;
}

.systeme .liste th a:hover { color: var(--encre); }

/* L'ACTIF EN ENCRE, jamais en accent — la règle vaut aussi pour le tri. */
.systeme .liste th a.tri-actif {
  color: var(--encre);
  font-weight: var(--g-gras);
}

.systeme .liste th a:focus-visible {
  outline: var(--trait-fort) solid var(--encre);
  outline-offset: 2px;
}

/* ───────────────────────────────────────────────────────────────────────────
 * Fiches — blocs, fil d'Ariane, commandes en ligne
 *
 * ⚠️ MESURE SUR LA FICHE PARTENAIRE : le fil d'Ariane faisait 17 px, le bouton
 * « Marquer comme faite » 37 px, et l'adresse e-mail d'un contact 22 px. Trois
 * cibles sous le plancher, sur l'écran qu'un bénévole ouvre le plus souvent.
 * ─────────────────────────────────────────────────────────────────────────── */

.systeme .fil {
  font-size: var(--t-secondaire);
  margin-bottom: var(--e-3);
}

.systeme .fil a {
  display: inline-flex;
  align-items: center;
  min-height: var(--h-cible);
  /* Le remplissage est repris en marge : le fil ne pousse pas le titre. */
  margin: -11px 0;
  color: var(--gris);
  text-decoration: none;
}

.systeme .fil a:hover { color: var(--encre); text-decoration: underline; }

.systeme .fil a:focus-visible {
  outline: var(--trait-fort) solid var(--encre);
  outline-offset: 2px;
}

.systeme .petit-bouton {
  min-height: var(--h-cible);
  padding: 0 14px;
  font-size: var(--t-secondaire);
  font-weight: var(--g-demi);
  border-radius: var(--rayon);
  cursor: pointer;
}

/* Une adresse e-mail ou un téléphone dans une fiche est un lien : on l'appelle,
   on lui écrit. C'est donc une cible, pas du texte. */
.systeme .fiche-contact a,
.systeme .bloc a[href^='mailto:'],
.systeme .bloc a[href^='tel:'] {
  display: inline-flex;
  align-items: center;
  min-height: var(--h-cible);
  margin: -11px 0;
  color: var(--encre);
  text-underline-offset: 3px;
}

/* ⚠️ « principal » qualifie un contact — ce n'est ni une action ni l'identité
   du club. Il portait un aplat d'accent, soit le quatrième de l'écran. Une
   qualification se dit avec la palette d'états, comme partout ailleurs. */
.systeme .jeton-principal {
  color: var(--etat-info-texte);
  background: var(--etat-info-fond);
  border: var(--trait) solid var(--etat-info-bord);
}

/* Le filet du bloc « prochaine action » n'est pas un des quatre emplois
   autorisés de l'accent. En encre, il dit « c'est ici » sans emprunter la
   couleur du club — et il reste lisible chez un club à l'accent pâle. */
.systeme .bloc-action { border-left-color: var(--encre); }

/* ═══════════════════════════════════════════════════════════════════════════
 * FORMULAIRES
 *
 * C'est là que la densité compte le plus : saisir une fiche partenaire sur un
 * téléphone, dans les tribunes, est le geste le plus ingrat du produit.
 * ═══════════════════════════════════════════════════════════════════════════ */

.systeme .bloc {
  margin-top: var(--e-5);
  padding: var(--e-5);
  background: var(--blanc);
  border: var(--trait) solid var(--ligne);
  border-radius: var(--rayon-grand);
  box-shadow: var(--ombre-carte);
}

.systeme .bloc-entete {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--e-3);
  margin-bottom: var(--e-4);
}

/* ⚠️ Mesurée à 9,5 px. Le plancher est 11, et il ne se négocie pas : nos
   utilisateurs ne sont pas des experts qui viennent tous les jours. */
.systeme .etiquette {
  font-family: var(--mono);
  font-size: var(--t-micro);
  line-height: var(--i-micro);
  font-weight: var(--g-normal);
  text-transform: uppercase;
  letter-spacing: var(--approche-micro);
  color: var(--gris);
  margin: 0;
}

.systeme .champ { margin-top: var(--e-4); }
.systeme .champ:first-of-type { margin-top: var(--e-2); }

.systeme .champ > label {
  display: block;
  font-size: var(--t-secondaire);
  font-weight: var(--g-demi);
  line-height: var(--i-secondaire);
  color: var(--encre);
  margin-bottom: var(--e-2);
}

.systeme .champ input:not([type='file']):not([type='checkbox']):not([type='radio']),
.systeme .champ select,
.systeme .champ textarea {
  font: inherit;
  font-size: var(--t-corps);
  width: 100%;
  min-height: var(--h-champ);
  padding: 0 var(--e-3);
  color: var(--encre);
  background: var(--champ);
  border: var(--trait) solid var(--ligne);
  border-radius: var(--rayon);
}

.systeme .champ textarea { padding: var(--e-3); line-height: var(--i-corps); }

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

.systeme .aide {
  font-size: var(--t-petit);
  line-height: var(--i-petit);
  color: var(--gris);
  margin-top: var(--e-1);
  max-width: var(--largeur-lecture);
}

/* ⚠️ DEUX CHAMPS CÔTE À CÔTE ÉTAIENT DÉCALÉS DE 10 PX
   -------------------------------------------------------------------------
   `.champ:first-of-type` porte 4 px de marge haute, les suivants 14. Dans une
   grille à deux colonnes, le premier est « first-of-type » et le second ne
   l'est pas : les deux champs ne commencent donc jamais à la même hauteur.
   Mesuré sur QUATRE paires du seul formulaire partenaire, et présent sur tous
   les autres. À l'œil, on voit juste « quelque chose de bâclé » sans savoir
   quoi. L'espacement passe sur la grille, où il est le même pour les deux. */
.systeme .deux {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 var(--e-4);
  align-items: start;
  margin-top: var(--e-4);
}

.systeme .deux > .champ,
.systeme .deux > .champ:first-of-type { margin-top: 0; }

/* ───────────────────────────────────────────────────────────────────────────
 * Quatre classes employées par les gabarits et stylées NULLE PART
 *
 * ⚠️ Trouvées par le test « toute classe posée dans un gabarit est stylée
 * quelque part », écrit après avoir constaté que ma propre classe `.etroit`
 * ne faisait rien. Trois d'entre elles étaient là AVANT aujourd'hui : le
 * balisage les portait, la feuille les ignorait, et personne ne l'avait vu —
 * un paragraphe sans style reste un paragraphe lisible.
 * ─────────────────────────────────────────────────────────────────────── */

/* Une valeur qu'on montre sans pouvoir la modifier ici. Elle doit se lire
   comme une valeur, pas comme un champ désactivé — il n'y a rien à activer. */
.systeme .valeur-figee {
  margin-top: 2px;
  font-size: var(--t-corps);
  line-height: var(--i-corps);
  font-weight: var(--g-demi);
  color: var(--encre);
}

/* Un lien ou une précision qui suit un bloc, et qui lui appartient encore. */
.systeme .apres-bloc {
  margin-top: var(--e-3);
  font-size: var(--t-petit);
  line-height: var(--i-petit);
  color: var(--gris);
}

/* ⚠️ « archivé » n'est pas une erreur : c'est un ÉTAT NEUTRE. En rouge, il
   ferait croire à un problème alors que rien n'est perdu — et le texte dit
   précisément le contraire. */
.systeme .bandeau-archive {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--e-2);
  margin-top: var(--e-4);
  padding: var(--e-3) var(--e-4);
  border: var(--trait) solid var(--etat-neutre-bord);
  border-radius: var(--rayon);
  background: var(--etat-neutre-fond);
  color: var(--etat-neutre-texte);
  font-size: var(--t-secondaire);
  line-height: var(--i-secondaire);
}

/* Un champ qui prend toute la largeur, y compris dans une grille à deux
   colonnes — un motif d'annulation ne se saisit pas dans une demi-ligne. */
.systeme .champ.champ-large { grid-column: 1 / -1; }

/* ───────────────────────────────────────────────────────────────────────────
 * Une ligne de tableau qui se corrige sur place
 *
 * Le détail d'une facture en brouillon se modifie dans le tableau lui-même.
 * Deux règles suffisent, et elles manquaient toutes les deux :
 *
 * ⚠️ Le champ doit REMPLIR sa cellule. Sans cela il gardait la largeur par
 * défaut d'un champ de formulaire — mesuré : 143 px dans une cellule de
 * 199 px — et « Panneau bord de terrain 3 m » s'affichait « Panneau bord de
 * terrai ». On corrige un libellé qu'on ne peut pas lire en entier.
 *
 * ⚠️ Une colonne de nombres n'a pas besoin de la même place qu'un libellé.
 * Le tableau distribuait tout également : « Qté » recevait 198 px pour deux
 * caractères, pendant que le libellé étouffait dans la même largeur.
 * ─────────────────────────────────────────────────────────────────────── */

.systeme .liste td input[type='text'],
.systeme .liste td input[type='date'] {
  width: 100%;
  min-width: 0;
}

/* Un champ qui ne porte que des chiffres. La classe était posée dans le
   gabarit et n'existait NULLE PART dans la feuille : elle ne faisait rien. */
/* ⚠️ Un MINIMUM autant qu'un maximum. Sans plancher, la colonne des libellés
   — qui prend tout l'espace restant — écrasait celle des montants : « 1200,00 »
   s'affichait « 1200 ». Un champ qui coupe la valeur qu'il contient invite à la
   ressaisir de travers. */
.systeme .liste td input.etroit { min-width: 5.5rem; max-width: 7rem; }

/* La colonne des libellés prend ce que les autres ne réclament pas. */
.systeme .liste td.principal,
.systeme .liste th:first-child { width: 100%; }
.systeme .liste td.actions { white-space: nowrap; }
/* Une période « du … au … » coupée en quatre lignes se déchiffre au lieu de se
   lire. Elle tient sur une ligne, la colonne des libellés absorbe le reste. */
.systeme .liste td.periode { white-space: nowrap; }

/* Plusieurs liens discrets au bout d'un titre de section. */
.systeme .liens-section { display: flex; align-items: baseline; gap: var(--e-4);
                          flex-wrap: wrap; }

/* Une mention neutre sur une ligne — « vous », un rappel sans jugement.
   Palette d'état FIXE, jamais l'accent du club : ce n'est pas une couleur de
   marque, c'est une information. */
.systeme .etat-neutre {
  color: var(--etat-neutre-texte);
  background: var(--etat-neutre-fond);
  border-color: var(--etat-neutre-bord);
}

/* ═══════════════════════════════════════════════════════════════════════════
 * ⚠️ LE PREMIER ENFANT D'UN <fieldset> S'EFFONDRE S'IL EST EN GRILLE
 *
 * Mesuré dans le navigateur, sur l'écran d'identité fiscale : un `.deux` placé
 * juste après le `<legend>` faisait 0 px de large, ses deux colonnes 22 px,
 * et les champs se tassaient contre le bord droit. Le MÊME `.deux` placé plus
 * bas dans le même fieldset faisait 638 px.
 *
 * Ce n'est ni le contenu ni une règle de la feuille : c'est la POSITION.
 * Vérifié en insérant trois éléments neufs en tête du fieldset :
 *
 *     <div> ordinaire        → 638 px
 *     <div display:grid>     →   0 px
 *     <div display:flex>     →   0 px
 *
 * Un bloc ordinaire va bien ; un contexte de grille ou de boîte flexible
 * s'effondre. `min-inline-size: 0`, `display: flow-root` et une cale devant
 * n'y changent rien — seule une largeur explicite corrige.
 *
 * ⚠️ CE DÉFAUT ÉTAIT DÉJÀ EN PRODUCTION, sur `actif-formulaire` (deux fois) et
 * `partenaire-formulaire`. Personne ne l'avait signalé : un formulaire dont
 * deux champs sont écrasés à droite se lit comme un formulaire mal dessiné,
 * pas comme un défaut.
 * ═══════════════════════════════════════════════════════════════════════════ */
.systeme fieldset > legend + * { width: 100%; }

/* Sous 760 px, deux colonnes de saisie font des champs trop étroits pour un
   pouce : elles s'empilent. */
@media (max-width: 760px) {
  .systeme .deux { grid-template-columns: 1fr; gap: var(--e-4); }
}

/* ⚠️ LA CASE À COCHER MESURAIT 13 PX
   -------------------------------------------------------------------------
   Intouchable au pouce. On agrandit la case ET on fait du LIBELLÉ ENTIER une
   cible de 40 px : viser une case de 20 px reste difficile, viser une ligne de
   texte ne l'est pas. */
.systeme .champ-case > label,
.systeme .case-role {
  display: flex;
  align-items: center;
  gap: var(--e-3);
  min-height: var(--h-cible);
  font-size: var(--t-corps);
  font-weight: var(--g-normal);
  line-height: var(--i-corps);
  cursor: pointer;
}

.systeme .champ-case input[type='checkbox'],
.systeme .case-role input[type='checkbox'],
.systeme .champ input[type='radio'] {
  width: 20px;
  height: 20px;
  flex: none;
  accent-color: var(--encre);
  cursor: pointer;
}

.systeme .cases { display: flex; flex-wrap: wrap; gap: var(--e-1) var(--e-4); }

.systeme .pied-formulaire,
.systeme .actions-formulaire {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--e-4);
  margin-top: var(--e-5);
}

.systeme .message-erreur,
.systeme .erreur-bandeau {
  margin-top: var(--e-3);
  padding: var(--e-3) var(--e-4);
  font-size: var(--t-secondaire);
  color: var(--etat-retard-texte);
  background: var(--etat-retard-fond);
  border: var(--trait) solid var(--etat-retard-bord);
  border-radius: var(--rayon);
  max-width: var(--largeur-lecture);
}

.systeme .champ.en-erreur input,
.systeme .champ.en-erreur select,
.systeme .champ.en-erreur textarea { border-color: var(--etat-retard-texte); }

.systeme .champ .requis { color: var(--etat-retard-texte); }

/* Le contour de focus est en ENCRE, jamais en accent : un club à l'accent pâle
   n'aurait aucun repère au clavier. 19,80:1 quelle que soit la couleur. */
.systeme .champ input:focus-visible,
.systeme .champ select:focus-visible,
.systeme .champ textarea:focus-visible,
.systeme .champ-case input:focus-visible,
.systeme .case-role input:focus-visible {
  outline: var(--trait-fort) solid var(--encre);
  outline-offset: 2px;
  border-color: var(--encre);
}

/* ─── Les sections d'un formulaire sont des <fieldset> ───────────────────────
 * Et non des « .bloc » : les règles écrites pour les fiches ne les touchent
 * pas. La légende native se pose SUR la bordure et la coupe — un titre à
 * cheval sur un trait, illisible à 9,5 px. On la sort du cadre : elle devient
 * un micro-libellé posé au-dessus de la carte, comme les en-têtes de colonne.
 * ─────────────────────────────────────────────────────────────────────────── */

.systeme .formulaire-large fieldset {
  padding: var(--e-5);
  margin-bottom: var(--e-4);
  background: var(--blanc);
  border: var(--trait) solid var(--ligne);
  border-radius: var(--rayon-grand);
  box-shadow: var(--ombre-carte);
}

.systeme .formulaire-large legend {
  /* « float: left » sort la légende du flux réservé par le navigateur, donc
     elle cesse d'entailler la bordure ; le padding du fieldset la remet dans
     le cadre. `width: 100%` force le champ suivant à passer à la ligne. */
  float: left;
  width: 100%;
  padding: 0;
  margin-bottom: var(--e-2);
  font-family: var(--mono);
  font-size: var(--t-micro);
  line-height: var(--i-micro);
  text-transform: uppercase;
  letter-spacing: var(--approche-micro);
  color: var(--gris);
}

/* Le rappel du catalogue : ses deux liens sont le SEUL chemin vers les actifs
   et les packs depuis que la barre est passée à cinq entrées. Mesurés à 17 px
   — c'est-à-dire la hauteur de leur texte, et rien de plus. */
.systeme .rappel-catalogue {
  margin-top: var(--e-2);
  font-size: var(--t-secondaire);
  color: var(--gris);
  max-width: var(--largeur-lecture);
}

.systeme .rappel-catalogue a {
  display: inline-flex;
  align-items: center;
  min-height: var(--h-cible);
  margin: -11px 0;
  color: var(--encre);
  text-underline-offset: 3px;
}

.systeme .rappel-catalogue a:focus-visible {
  outline: var(--trait-fort) solid var(--encre);
  outline-offset: 2px;
}

/* Le dépôt de fichier de l'import : le sélecteur des champs exclut
   explicitement « type=file », donc il gardait la boîte native de 22 px. */
.systeme .champ input[type='file'],
.systeme input[type='file'] {
  font: inherit;
  font-size: var(--t-secondaire);
  width: 100%;
  min-height: var(--h-champ);
  padding: var(--e-2) var(--e-3);
  background: var(--champ);
  border: var(--trait) dashed var(--ligne);
  border-radius: var(--rayon);
  cursor: pointer;
}

.systeme input[type='file']:hover { border-color: var(--gris); }

.systeme input[type='file']:focus-visible {
  outline: var(--trait-fort) solid var(--encre);
  outline-offset: 2px;
}

/* Le sous-titre d'une fiche porte des liens — le partenaire, le contrat
   d'origine. Mesurés à 22 px : la hauteur de leur texte. Ce sont les chemins
   de navigation les plus empruntés du produit, ils méritent une vraie cible. */
.systeme .sous-titre {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--e-3);
  font-size: var(--t-secondaire);
  color: var(--gris);
}

.systeme .sous-titre a {
  display: inline-flex;
  align-items: center;
  min-height: var(--h-cible);
  margin: -11px 0;
  color: var(--encre);
  text-underline-offset: 3px;
}

.systeme .sous-titre a:focus-visible {
  outline: var(--trait-fort) solid var(--encre);
  outline-offset: 2px;
}

/* ═══════════════════════════════════════════════════════════════════════════
 * LARGEUR : les écrans de DONNÉES respirent, les écrans de LECTURE se tiennent
 *
 * Mesuré à 1440 px : le contenu occupait 992 px et laissait 224 px de vide de
 * chaque côté, pendant que le tableau des partenaires serrait six colonnes.
 * Une largeur de lecture appliquée à un tableau n'est pas de la sobriété,
 * c'est une mesure prise pour autre chose.
 *
 * La classe vient du gabarit, pas d'une devinette sur le contenu : un écran
 * sait s'il montre des données ou du texte.
 * ═══════════════════════════════════════════════════════════════════════════ */

.systeme.large { max-width: var(--largeur-large); }

/* En dessous, la largeur large ne change plus rien : le contenu prend déjà
   toute la place. La règle n'a donc pas besoin de media query. */

/* ═══════════════════════════════════════════════════════════════════════════
 * AFFÛTAGE — sept défauts mesurés sur un écran de 1440 px
 *
 * Aucun arbitrage de DESIGN.md n'est rouvert : densité de bénévole, actif en
 * encre, six paliers typographiques, palette d'états fixe. Ce qui change, c'est
 * la PRÉSENCE — le produit avait la qualité sans l'assurance.
 * ═══════════════════════════════════════════════════════════════════════════ */

/* ─── 1. L'en-tête de page : une zone, pas trois éléments qui flottent ─────
 * Le titre, le chapeau et les actions partagent une ligne de base et une
 * séparation nette avec le contenu. Avant, « Importer un fichier » et le bouton
 * principal flottaient à des hauteurs différentes du titre.
 * ───────────────────────────────────────────────────────────────────────── */

.systeme .titre-ligne {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--e-5);
  flex-wrap: wrap;
}

.systeme .titre-ligne > :first-child { flex: 1 1 24rem; }

/* Les actions d'en-tête s'alignent sur la HAUTEUR DU TITRE, pas sur son haut :
   un bouton de 44 px calé sur la première ligne d'un titre de 26 px paraît
   toujours trop haut. */
.systeme .titre-ligne .bouton,
.systeme .titre-ligne .bouton-discret,
.systeme .boutons-titre {
  align-self: center;
  flex: none;
}

.systeme .boutons-titre {
  display: flex;
  align-items: center;
  gap: var(--e-4);
  flex-wrap: wrap;
}

/* Le chapeau appartient à l'en-tête : il ne doit pas s'en détacher. */
.systeme .chapeau {
  margin-top: var(--e-2);
  font-size: var(--t-secondaire);
  line-height: var(--i-secondaire);
  color: var(--gris);
  max-width: var(--largeur-lecture);
}

/* ─── 2. Le tableau : un en-tête qui se voit, un survol qui répond ────────
 * L'en-tête de colonne était à 11 px gris pâle sur blanc, indiscernable de la
 * première ligne. Un tableau de données a besoin qu'on distingue l'étiquette
 * de la donnée sans y penser.
 * ───────────────────────────────────────────────────────────────────────── */

.systeme .liste thead th {
  background: var(--champ);
  border-bottom: var(--trait) solid var(--ligne);
  color: var(--gris);
  /* Le repos vertical vient du remplissage, pas d'une hauteur imposée : une
     colonne triable porte un lien de 40 px qui doit tenir dedans. */
  padding-top: var(--e-2);
  padding-bottom: var(--e-2);
}

.systeme .liste thead th:first-child { border-top-left-radius: var(--rayon-grand); }
.systeme .liste thead th:last-child  { border-top-right-radius: var(--rayon-grand); }

/* Le survol dit « cette ligne entière est cliquable ». Sans lui, la surface
   étirée sous la ligne est une promesse invisible. */
.systeme .liste tbody tr:hover { background: var(--champ); }

/* ─── 3. La recherche : un groupe, pas un champ et un bouton posés côte à côte */

.systeme .barre-recherche {
  display: flex;
  gap: var(--e-2);
  margin-top: var(--e-5);
  max-width: 34rem;
}

.systeme .barre-recherche input {
  flex: 1;
  min-height: var(--h-champ);
  padding: 0 var(--e-4);
  font-size: var(--t-corps);
  color: var(--encre);
  background: var(--blanc);
  border: var(--trait) solid var(--ligne);
  border-radius: var(--rayon);
}

.systeme .barre-recherche input:focus-visible {
  outline: var(--trait-fort) solid var(--encre);
  outline-offset: 2px;
  border-color: var(--encre);
}

.systeme .barre-recherche button {
  flex: none;
  min-height: var(--h-champ);
  padding: 0 var(--e-5);
  font-size: var(--t-corps);
  font-weight: var(--g-demi);
  color: var(--encre);
  background: var(--blanc);
  border: var(--trait) solid var(--ligne);
  border-radius: var(--rayon);
  cursor: pointer;
}

.systeme .barre-recherche button:hover { border-color: var(--gris); }

/* ─── 4. La profondeur : les ombres existaient, on ne les voyait pas ──────
 * 2 px de décalage et 7 % d'opacité sur un fond crème ne produisent aucune
 * séparation. Une carte doit se détacher de son fond, sinon elle n'est qu'un
 * rectangle blanc.
 * ───────────────────────────────────────────────────────────────────────── */

/* ⚠️ L'ombre de Regard AI, telle quelle : `shadow-card`. Le produit en avait
   fabriqué une à deux couches, plus douce ; deux surfaces voisines venues de
   deux logiciels ne doivent pas se poser différemment. */
.systeme .bloc,
.systeme .liste,
.systeme .alerte-carte,
.systeme .compteur,
.systeme .formulaire-large fieldset {
  box-shadow: var(--ombre-carte);
}

/* ─── 5. La grille d'alertes : jamais une carte orpheline ─────────────────
 * Quatre alertes donnaient 3 + 1, avec un trou béant à droite et une quatrième
 * carte plus courte que ses voisines. Deux colonnes se remplissent toujours
 * proprement, et laissent plus de place au texte de chaque alerte.
 * ───────────────────────────────────────────────────────────────────────── */

/*
 * ⚠️ LE NOMBRE DE COLONNES EST DÉCIDÉ, PAS DEVINÉ
 *
 * `auto-fit` remplit ce qu'il peut : à 1344 px et 380 px minimum, il tient
 * trois colonnes — donc quatre alertes donnent 3 + 1, avec une carte orpheline
 * et un trou béant à droite. Élargir le minimum ne fait que déplacer le
 * problème vers un autre compte.
 *
 * On compte donc les cartes. Quatre alertes se rangent en 2 × 2, trois en une
 * ligne, cinq en 3 + 2. Aucune configuration ne laisse une carte seule sur sa
 * ligne, et l'écran ne change pas de forme d'un jour à l'autre pour une alerte
 * de plus ou de moins.
 */
.systeme .alertes { grid-template-columns: repeat(3, 1fr); }

.systeme .alertes:has(> :nth-child(1):last-child) { grid-template-columns: 1fr; }
.systeme .alertes:has(> :nth-child(2):last-child) { grid-template-columns: repeat(2, 1fr); }
.systeme .alertes:has(> :nth-child(4):last-child) { grid-template-columns: repeat(2, 1fr); }

/* Une alerte seule ne s'étale pas sur toute la largeur : au-delà, son texte
   dépasse la mesure de lecture et devient pénible à parcourir. */
.systeme .alertes .alerte-carte:only-child { max-width: 46rem; }

/* Sous 760 px, tout s'empile — trois colonnes de 380 px n'y tiennent pas, et
   `:has()` ne doit pas ressusciter une grille impossible. */
@media (max-width: 760px) {
  .systeme .alertes,
  .systeme .alertes:has(> :nth-child(2):last-child),
  .systeme .alertes:has(> :nth-child(4):last-child) { grid-template-columns: 1fr; }
}

/* ─── 6. Ce qui pesait plus lourd que son importance ───────────────────────
 * « Me déconnecter » s'affichait large et centré, en bas de l'écran d'accueil :
 * il attirait l'œil avant les alertes. Se déconnecter n'est pas une action de
 * l'écran d'entrée — le bouton reste atteignable à 40 px, mais rentre dans le
 * rang.
 * ───────────────────────────────────────────────────────────────────────── */

.systeme .deconnexion { display: flex; }
.systeme .deconnexion button { flex: none; }

/* ─── 7. La respiration en haut de page ───────────────────────────────────
 * Le titre démarrait à 20 px du filet de la barre. Un écran qui commence
 * immédiatement sous sa navigation paraît serré, quelle que soit la qualité de
 * ce qu'il contient.
 * ───────────────────────────────────────────────────────────────────────── */

.systeme { padding-top: var(--e-6); }

/* ─── 8. La ligne de conformité : deux blocs, pas deux bords ──────────────
 * Le texte à gauche et le lien à droite laissaient 1 200 px de vide entre eux
 * sur un écran large. Le lien suit maintenant son texte.
 * ───────────────────────────────────────────────────────────────────────── */

.systeme .conformite-resume { max-width: 48rem; }
.systeme .conformite-resume a { margin-left: var(--e-4); }

/* ─── 9. La jauge dit où elle en est ──────────────────────────────────────
 * Un trait rempli à 19 % sans chiffre oblige à estimer à l'œil. Le pourcentage
 * est déjà connu du serveur : il s'écrit.
 * ───────────────────────────────────────────────────────────────────────── */

.systeme .jauge-ligne {
  display: flex;
  align-items: center;
  gap: var(--e-4);
  margin-top: var(--e-4);
}

.systeme .jauge-ligne .jauge { flex: 1; margin-top: 0; max-width: 42rem; }

.systeme .jauge-part {
  font-family: var(--mono);
  font-size: var(--t-corps);
  font-weight: var(--g-demi);
  font-variant-numeric: tabular-nums;
  color: var(--encre);
  white-space: nowrap;
}

/* ═══════════════════════════════════════════════════════════════════════════
 * ALIGNEMENT SUR REGARD AI — petites tailles, graisses fortes
 *
 * Ce qui suit annule la transposition « pour bénévoles » de l'échelle et des
 * graisses. Le crème, les rayons, Outfit, DM Mono et les ombres étaient déjà
 * identiques au pixel près : ce qui manquait était le CONTRASTE DE GRAISSE.
 *
 * Regard AI met du semibold et du bold partout, à des tailles que nous avions
 * doublées. C'est ce qui lui donne son assurance — et c'est exactement ce qui
 * nous manquait.
 * ═══════════════════════════════════════════════════════════════════════════ */

/* ─── Titres ──────────────────────────────────────────────────────────────
 * Regard AI : titre de page 18px, titre de carte 13px en `font-bold`.
 * ───────────────────────────────────────────────────────────────────────── */

.systeme h1 {
  font-size: var(--t-titre);
  line-height: var(--i-titre);
  font-weight: var(--g-gras);
  letter-spacing: -0.02em;
}

.systeme h2,
.systeme .titre-section {
  font-size: var(--t-section);
  line-height: var(--i-section);
  font-weight: var(--g-gras);
  letter-spacing: -0.01em;
  margin-top: var(--e-6);
}

.systeme .chapeau,
.systeme .note-haute {
  font-size: var(--t-secondaire);
  font-weight: var(--g-normal);
  color: var(--gris);
}

/* ─── Étiquettes d'état : 10 px en GRAS, comme les badges de Regard AI ────
 * Une étiquette de 12 px en 600 occupe la place d'un mot ; à 10 px en 700 elle
 * devient un repère, et la ligne du tableau respire.
 * ───────────────────────────────────────────────────────────────────────── */

.systeme [class*='etat-'] {
  padding: 1px 8px;
  font-size: var(--t-micro);
  font-weight: var(--g-gras);
  line-height: var(--i-micro);
  letter-spacing: 0.01em;
}

/* ─── Le tableau se resserre ──────────────────────────────────────────────
 * Les cellules gardent 40 px de hauteur — la cible ne bouge pas — mais le
 * texte descend à 12,5 px et les intitulés à 10 px en gras.
 * ───────────────────────────────────────────────────────────────────────── */

.systeme .liste { font-size: var(--t-corps); }

.systeme .liste thead th {
  font-size: var(--t-micro);
  font-weight: var(--g-gras);
  letter-spacing: var(--approche-micro);
}

.systeme .liste td { padding-top: var(--e-2); padding-bottom: var(--e-2); }
.systeme .liste .principal a { font-weight: var(--g-demi); }
.systeme .liste .secondaire { font-size: var(--t-petit); }

/* ─── Boutons : le texte rétrécit, la cible reste ────────────────────────── */

.systeme .bouton,
.systeme .bouton-discret,
.systeme .lien-bouton,
.systeme .petit-bouton,
.systeme .liste td.actions button {
  font-size: var(--t-corps);
  font-weight: var(--g-demi);
}

/* ─── Compteurs et cartes ─────────────────────────────────────────────────
 * Regard AI tient ses cartes en 16 px de padding. Une carte trop matelassée
 * fait paraître son contenu maigre.
 * ───────────────────────────────────────────────────────────────────────── */

.systeme .bloc,
.systeme .alerte-carte,
.systeme .formulaire-large fieldset { padding: var(--e-5); }

/* Les tailles du compteur sont définies une seule fois, avec le composant.
   Elles l'étaient ici AUSSI, et les deux endroits divergeaient. */

/* ⚠️ DOUBLON RETIRÉ LE 09/09/2026. Ces trois règles répétaient, à l'identique
   et sans contexte différent, celles posées avec le composant plus haut. Le
   commentaire juste au-dessus dénonce exactement ce piège pour les compteurs —
   « les deux endroits divergeaient » — et l'alerte le portait encore. Un
   composant, un endroit. */

/* ─── Formulaires ────────────────────────────────────────────────────────── */

.systeme .champ > label { font-size: var(--t-petit); font-weight: var(--g-demi); }
.systeme .champ input:not([type='file']),
.systeme .champ select,
.systeme .champ textarea { font-size: var(--t-corps); }
.systeme .aide { font-size: var(--t-petit); }

/* ─── Navigation : 56 px de barre, texte serré ───────────────────────────── */

.systeme ~ * .navigation a,
.navigation a { font-size: var(--t-corps); }

/* ═══════════════════════════════════════════════════════════════════════════
 * L'ENTRÉE — connexion, lien envoyé, confirmation
 *
 * ⚠️ Ces écrans étaient restés hors du système par une distinction qui ne
 * tenait pas : « écrans sans structure ». Or la structure est parfaitement
 * connue ici — c'est le sous-domaine qui la donne. Seuls le domaine racine et
 * la page « structure inconnue » n'en ont réellement pas.
 *
 * C'est le premier écran qu'un bénévole voit, et longtemps le seul dont il se
 * souviendra. Il portait encore l'ancienne échelle.
 * ═══════════════════════════════════════════════════════════════════════════ */

.systeme.centre {
  display: flex;
  align-items: center;
  justify-content: center;
  /* La barre fait 56 px : on retire sa hauteur pour centrer sur ce qui reste,
     sinon la carte descend d'une demi-barre. */
  min-height: calc(100vh - var(--h-barre) - var(--e-6) * 2);
  padding-top: var(--e-6);
  padding-bottom: var(--e-6);
}

.carte-accueil {
  width: 100%;
  max-width: 25rem;
  padding: var(--e-6) var(--e-5) var(--e-5);
  background: var(--blanc);
  border: var(--trait) solid var(--ligne);
  border-radius: var(--rayon-grand);
  box-shadow:
    0 1px 2px rgba(10, 10, 10, 0.04),
    0 8px 32px rgba(10, 10, 10, 0.08);
}

.carte-accueil-tete {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--e-1);
  margin-bottom: var(--e-5);
}

/* La couleur du club, en petit et une seule fois : elle dit « vous êtes bien
   chez vous » avant même que le nom soit lu. */
.carte-accueil-pastille {
  width: 34px;
  height: 34px;
  border-radius: var(--rayon);
  background: var(--accent);
  margin-bottom: var(--e-3);
}

.carte-accueil h1 { font-size: var(--t-titre); font-weight: var(--g-gras); }
.carte-accueil .chapeau { margin: 0; font-size: var(--t-secondaire); }

.carte-accueil .formulaire { display: flex; flex-direction: column; gap: var(--e-4); }
.carte-accueil .champ { margin-top: 0; }
.carte-accueil .bouton { width: 100%; justify-content: center; }

.carte-accueil-pied {
  margin-top: var(--e-5);
  padding-top: var(--e-4);
  border-top: var(--trait) solid var(--ligne);
  font-size: var(--t-petit);
  line-height: var(--i-petit);
  color: var(--gris);
  text-align: center;
}

/* Les deux écrans qui suivent — lien envoyé, confirmation — partagent la même
   forme sans avoir la carte : ils tiennent en une phrase. */
.systeme.centre > h1,
.systeme.centre > .chapeau,
.systeme.centre > .fiche,
.systeme.centre > .formulaire,
.systeme.centre > p { max-width: 30rem; }

.systeme.centre > * { margin-left: auto; margin-right: auto; }
.systeme.centre { flex-direction: column; text-align: center; }
.systeme.centre .carte-accueil { text-align: left; }
.systeme.centre .fiche { text-align: left; }





/* ═══════════════════════════════════════════════════════════════════════════
 * LA CARTE DE COCKPIT — le motif de Regard AI
 *
 * Relevé dans « components/cockpit/CeoCockpit.tsx », bloc « Business Score » :
 *
 *   Card (rounded-2xl · border-border/60 · p-4 · shadow-card)
 *     ├ en-tête : icône 16 px en accent + titre 12 px gras
 *     ├ corps   : chiffre 40 px font-black à GAUCHE, badge + résumé à DROITE
 *     └ détails : lignes de 10,5 px
 *
 * ⚠️ UN SEUL chiffre est énorme. Les autres restent petits — c'est ce qui le
 * fait ressortir. J'avais agrandi les quatre à la fois, ce qui revenait à n'en
 * grandir aucun.
 *
 * ⚠️ Et une carte de Regard AI commence TOUJOURS par une icône. Le produit
 * n'en avait aucune, nulle part : rien n'aidait à repérer un bloc du regard.
 * ═══════════════════════════════════════════════════════════════════════════ */

.systeme .carte-cockpit {
  margin-top: var(--e-4);
  padding: var(--e-5);
  background: var(--blanc);
  border: var(--trait) solid var(--ligne);
  border-radius: var(--rayon-grand);
  box-shadow:
    0 1px 2px rgba(10, 10, 10, 0.04),
    0 4px 16px rgba(10, 10, 10, 0.06);
}

/* ─── En-tête : icône + titre ─────────────────────────────────────────── */

.systeme .carte-cockpit-tete {
  display: flex;
  align-items: center;
  gap: var(--e-2);
  margin-bottom: var(--e-3);
}

.systeme .carte-cockpit-tete svg {
  width: 16px;
  height: 16px;
  flex: none;
  /* L'icône porte la couleur du club — `--accent-lisible` et non `--accent` :
     un accent pâle disparaîtrait sur le blanc de la carte. */
  color: var(--accent-lisible);
}

.systeme .carte-cockpit-tete h3 {
  font-size: var(--t-secondaire);
  font-weight: var(--g-gras);
  line-height: var(--i-secondaire);
  margin: 0;
}

/* ─── Corps : le chiffre, puis son résumé ─────────────────────────────── */

.systeme .carte-cockpit-corps {
  display: flex;
  align-items: center;
  gap: var(--e-5);
}

/* ⚠️ ALIGNÉ À GAUCHE, PAS CENTRÉ.
   Regard AI centre parce que sa légende — « / 100 » — est plus ÉTROITE que son
   chiffre. La nôtre — « % de l'objectif » — est trois fois plus large : centrée,
   elle débordait des deux côtés et le chiffre ne tenait plus le bord gauche du
   bloc. Reprendre le centrage aurait été copier la forme sans la raison. */
.systeme .score { text-align: left; flex: none; }

.systeme .score-valeur {
  display: block;
  /* ⚠️ OUTFIT, PAS DM MONO.
     Mesuré dans le DOM de Regard AI : son « 39 » est en Outfit 900, jamais en
     mono. Le chiffre géant de regard pro était le SEUL élément du produit à
     s'écrire dans une autre police que le reste de la page — c'était l'écart
     visuel principal avec Regard AI, et je l'avais mis là de moi-même.
     Notre Outfit est une variable plafonnée à 800 : mesuré, 82,05 px de large
     là où Regard AI en fait 83,32. L'écart de graisse est de 1,5 %. */
  font-family: var(--sans);
  font-size: var(--t-score);
  font-weight: var(--g-noir);
  line-height: 1;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
}

/* ⚠️ LE GRAND CHIFFRE PORTE LE VERDICT — mesuré : `rgb(225, 29, 72)` sur le
   score « fragile » de Regard AI. Ce n'est pas une entorse à la règle « actif
   en noir » : celle-là vise l'ÉTAT DE NAVIGATION, pas un jugement. Ici la
   couleur EST l'information, et elle vient de la palette FIXE à ≥ 6,45:1 —
   jamais de l'accent du club, qui varie et ne veut rien dire. */
.systeme .score-valeur.est-faible { color: var(--etat-retard-texte); }
.systeme .score-valeur.est-moyen  { color: var(--etat-alerte-texte); }
.systeme .score-valeur.est-bon    { color: var(--etat-succes-texte); }

.systeme .score-sur {
  display: block;
  margin-top: 2px;
  font-size: var(--t-micro);
  line-height: var(--i-micro);
  color: var(--gris);
}

.systeme .score-resume { min-width: 0; flex: 1; }

/* Le libellé du cycle prend la forme d'une étiquette d'état — Regard AI met un
   Badge à cet endroit. */
.systeme .etat-cycle {
  display: inline-flex;
  align-items: center;
  padding: 1px 8px;
  border-radius: var(--rayon-plein);
  border: var(--trait) solid var(--etat-info-bord);
  background: var(--etat-info-fond);
  color: var(--etat-info-texte);
  font-size: var(--t-micro);
  font-weight: var(--g-gras);
  line-height: var(--i-micro);
}

.systeme .score-resume p {
  margin-top: var(--e-1);
  font-size: var(--t-petit);
  line-height: var(--i-petit);
  color: var(--gris);
}

.systeme .score-resume strong {
  font-weight: var(--g-gras);
  color: var(--encre);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Les trois autres repères de la saison utilisent le composant `.compteur`.
   Ils avaient d'abord leur propre jeu de règles `.releve-*` — c'est-à-dire le
   MÊME composant sous un second nom, donc deux endroits où il pouvait dériver. */


@media (max-width: 760px) {
  .systeme .carte-cockpit-corps { flex-direction: column; align-items: flex-start; gap: var(--e-3); }
}

/* ─── Inventaire ─────────────────────────────────────────────────────────── */

/* ⚠️⚠️ LA JAUGE EN TROIS SEGMENTS — engagé, réservé, disponible.
   Trois segments et pas un de plus : ils répondent aux trois seuls états
   qu'un stock peut avoir. Aucune animation — DESIGN.md l'interdit, et une
   barre qui bouge attire l'œil sur la ligne qui bouge, pas sur celle qui
   compte.

   ⚠️ LA COULEUR NE PORTE JAMAIS SEULE L'INFORMATION. La jauge est doublée
   d'un « aria-label » et d'un « title » qui disent les mêmes chiffres en
   toutes lettres, et la colonne voisine les répète en texte. Une barre de
   couleur seule ne se lit ni par un lecteur d'écran, ni par qui distingue
   mal le rouge du vert. */
.systeme .jauge {
  display: flex;
  width: 100%;
  min-width: 7rem;
  height: 10px;
  border-radius: var(--rayon-petit, 3px);
  overflow: hidden;
  background: var(--ligne);
}

/* L'accent du club pour l'ENGAGÉ : c'est ce qui est vendu, donc ce dont le
   club est fier. Son voile pour le RÉSERVÉ : même famille, moins d'affirmation
   — une promesse n'est pas une signature. */
.systeme .jauge-engage  { background: var(--couleur-principale); }
.systeme .jauge-reserve { background: var(--voile-accent, var(--champ)); }
.systeme .jauge-libre   { background: transparent; }

/* ⚠️ TROIS CLICS POUR AJUSTER UN STOCK : le champ vit DANS la ligne. Cible de
   40 px comme partout — un pavé numérique se manque sur un téléphone. */
.systeme .stock-en-ligne {
  display: flex;
  align-items: center;
  gap: var(--e-2);
  justify-content: flex-end;
}
.systeme .stock-en-ligne input {
  width: 5rem;
  min-height: var(--h-cible);
  padding: 0 var(--e-2);
  text-align: right;
  font-variant-numeric: tabular-nums;
  border: var(--trait) solid var(--ligne);
  border-radius: var(--rayon);
  background: var(--blanc);
  color: var(--encre);
}
.systeme .stock-en-ligne button { min-height: var(--h-cible); }

/* ⚠️ Un libellé lu par les lecteurs d'écran et invisible à l'œil. Chaque champ
   de stock en porte un : « Stock de Panneau bord de terrain ». Sans lui, une
   colonne de champs numériques identiques est indéchiffrable à l'oreille. */
.systeme .visuellement-cache {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ─── Inventaire · les vignettes ─────────────────────────────────────────── */

/* ⚠️ UNE GRILLE QUI SE REMPLIT, JAMAIS UN NOMBRE DE COLONNES FIGÉ.
   « auto-fill » avec une largeur minimale : trois vignettes sur un écran
   large, une sur un téléphone, sans point de rupture à maintenir. Le contenu
   décide, pas une liste de tailles d'écran. */
.systeme .inventaire-grille {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr));
  gap: var(--e-4);
  margin-bottom: var(--e-6);
}

.systeme .carte-actif {
  display: flex;
  flex-direction: column;
  gap: var(--e-2);
  padding: var(--e-4);
  background: var(--blanc);
  border: var(--trait) solid var(--ligne);
  border-radius: var(--rayon-grand);
}

/* ⚠️ Un actif COMPLET se signale par un trait, pas par un fond rouge : il n'y
   a rien d'anormal à avoir tout vendu — c'est même le but. Le trait dit
   « celui-ci n'a plus rien », il n'alarme pas. */
.systeme .carte-actif.est-complet { border-color: var(--encre); }

.systeme .carte-actif-nom {
  font-size: var(--t-section);
  font-weight: var(--g-demi);
  line-height: 1.25;
  margin: 0;
}
.systeme .carte-actif-nom a { color: var(--encre); text-decoration: none; }
.systeme .carte-actif-nom a:hover { text-decoration: underline; }

.systeme .carte-actif-meta {
  margin: 0;
  font-size: var(--t-micro);
  font-family: var(--police-mono, monospace);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--gris-clair);
}

/* LE CHIFFRE — ce que l'écran répond. Le reste de la vignette l'explique. */
.systeme .carte-actif-chiffre {
  display: flex;
  align-items: baseline;
  gap: var(--e-2);
  margin: var(--e-2) 0 0;
}
.systeme .carte-actif-chiffre .valeur {
  font-size: var(--t-compteur);
  font-weight: var(--g-gras);
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.systeme .carte-actif-chiffre .unite { font-size: var(--t-secondaire); color: var(--gris); }

/* ⚠️ Un actif complet garde son chiffre à ZÉRO en encre, pas en rouge. Le
   rouge du produit dit « quelque chose ne va pas » ; ici tout va bien. */
.systeme .carte-actif-detail {
  margin: 0;
  font-size: var(--t-secondaire);
  color: var(--gris);
}

.systeme .carte-actif-argent {
  display: flex;
  justify-content: space-between;
  gap: var(--e-2);
  margin: 0;
  font-size: var(--t-secondaire);
  color: var(--gris);
}
.systeme .carte-actif-argent strong { color: var(--encre); font-variant-numeric: tabular-nums; }

/* Le champ de stock ferme la vignette, aligné à gauche comme le reste. */
.systeme .carte-actif .stock-en-ligne {
  justify-content: flex-start;
  margin-top: var(--e-2);
  padding-top: var(--e-3);
  border-top: var(--trait) solid var(--ligne);
}

/* ─── Inventaire · la fiche et la reprise ────────────────────────────────── */

/* Sur la FICHE, l'ajustement de stock porte un libellé visible : on est venu
   pour comprendre, pas pour corriger — le champ doit se nommer. Sur la liste
   il est nu, entouré du nom de l'actif ; ici il est seul. */
.systeme .stock-fiche {
  justify-content: flex-start;
  margin: var(--e-4) 0 var(--e-6);
  padding-top: var(--e-3);
  border-top: var(--trait) solid var(--ligne);
}
.systeme .stock-fiche label {
  font-size: var(--t-secondaire);
  color: var(--gris);
}

/* ⚠️ LES CHAMPS DE LA REPRISE VIVENT DANS UN TABLEAU, et gardent la cible de
   40 px. Un tableau serré tente de rétrécir ses champs ; un pavé numérique de
   28 px se manque sur un téléphone, et c'est un prix qu'on saisit. */
.systeme .liste input[type="number"] {
  width: 6.5rem;
  min-height: var(--h-cible);
  padding: 0 var(--e-2);
  text-align: right;
  font-variant-numeric: tabular-nums;
  border: var(--trait) solid var(--ligne);
  border-radius: var(--rayon);
  background: var(--blanc);
  color: var(--encre);
}
.systeme .liste input[type="checkbox"] {
  width: 20px;
  height: 20px;
  /* La case elle-même ne peut pas faire 40 px sans devenir une tache : c'est
     sa CELLULE qui porte la cible, et le libellé caché la rend cliquable. */
  margin: var(--e-2);
}
.systeme .champ-centimes + .secondaire {
  display: block;
  margin-top: 2px;
}
