/* ============================================================
   Refonte v2 — les motifs partagés (lot 2)

   Six motifs réutilisés par tous les écrans, plus les états vides.
   Construits une fois ici, jamais réécrits dans un écran.

   Tout est sous `[data-v2]` : les écrans encore à l'ancienne ne
   voient rien de ce fichier.
   ============================================================ */

/* ══════════════════════════════════════════════════════════════
   1. TABLEAU DE LISTE
   Colonnes en grid : px fixes pour les chiffres et les statuts,
   minmax() pour le texte, qui doit pouvoir se réduire.
   ══════════════════════════════════════════════════════════════ */
[data-v2] .m-liste {
  background: var(--panel);
  backdrop-filter: blur(20px);
  border: 1px solid var(--stroke);
  border-radius: var(--r-md);
  overflow: hidden;
  font-family: var(--font);
}

[data-v2] .m-liste-tete,
[data-v2] .m-liste-l {
  display: grid;
  grid-template-columns: var(--m-cols, minmax(160px, 2fr) minmax(120px, 1fr) 110px 96px 40px);
  align-items: center;
  gap: 14px;
  padding: 0 16px;
}

[data-v2] .m-liste-tete {
  background: var(--panel-2);
  border-bottom: 1px solid var(--stroke-2);
  min-height: 38px;
}
[data-v2] .m-liste-tete span {
  font-size: 11px;
  font-weight: 640;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--v2-text-3);
}

[data-v2] .m-liste-l {
  position: relative;
  min-height: 52px;
  border-bottom: 1px solid var(--stroke-2);
  color: var(--v2-text);
  font-size: 13.5px;
  font-weight: 550;
  letter-spacing: -.01em;
  cursor: pointer;
  transition: background .14s ease;
}
[data-v2] .m-liste-l:last-child { border-bottom: 0; }
[data-v2] .m-liste-l:hover { background: var(--inset); }
[data-v2] .m-liste-l:focus-visible { outline: 2px solid var(--v2-accent); outline-offset: -2px; }

/* Colonne secondaire sous le libellé principal. */
[data-v2] .m-liste-sec { display: block; font-size: 11.5px; font-weight: 550; color: var(--v2-text-3); margin-top: 1px; }

/* Toute colonne de chiffres, sinon les colonnes tremblent au
   défilement (piège n° 9). */
[data-v2] .m-num { font-variant-numeric: tabular-nums; text-align: right; }

[data-v2] .m-chevron { color: var(--v2-text-3); display: grid; place-items: center; }
[data-v2] .m-chevron svg { width: 15px; height: 15px; }

/* ══════════════════════════════════════════════════════════════
   2. RAIL DE STATUT
   Filet de 4 px à gauche de la ligne : la répartition d'une liste
   se lit sans lire le texte.
   ══════════════════════════════════════════════════════════════ */
[data-v2] .m-liste-l[data-statut]::before {
  content: '';
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 4px;
  background: var(--m-rail, transparent);
}
/* QUATRE COULEURS, PAS SIX (Claude Design, 07/08/2026).
   À 4 px de large, le bleu « en attente », le violet « cas particulier » et
   le sarcelle « catégorie » se confondaient : on ne les séparait qu'en lisant
   le libellé, c'est-à-dire en faisant précisément ce que le filet existe pour
   éviter. Et « catégorie » n'est pas un statut mais une taxonomie — le filet
   répond à « où en est-on », pas à « de quel type ». Un écran qui doit
   distinguer des catégories le fera autrement.
   L'ambre est parti aussi : il remplit les boutons d'action, et un filet
   ambre au milieu d'une liste faisait croire à une commande. */
[data-v2] .m-liste-l[data-statut="pos"]    { --m-rail: var(--pos-fg); }
[data-v2] .m-liste-l[data-statut="neg"]    { --m-rail: var(--neg-fg); }
[data-v2] .m-liste-l[data-statut="info"]   { --m-rail: var(--info-fg); }
[data-v2] .m-liste-l[data-statut="neutre"] { --m-rail: var(--v2-text-3); }

/* ══════════════════════════════════════════════════════════════
   3. PASTILLE DE STATUT
   Toujours la paire encre + fond, jamais une couleur brute ni un
   #fff en dur sur fond teinté (piège n° 3).
   ══════════════════════════════════════════════════════════════ */
[data-v2] .m-pastille {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  height: 23px;
  padding: 0 9px;
  border-radius: 99px;
  font-size: 12.5px;
  font-weight: 550;
  white-space: nowrap;
  color: var(--m-fg, var(--v2-text-2));
  background: var(--m-bg, var(--inset));
}
[data-v2] .m-pastille svg { width: 12px; height: 12px; flex: 0 0 12px; }
[data-v2] .m-pastille[data-statut="pos"]    { --m-fg: var(--pos-fg);    --m-bg: var(--pos); }
[data-v2] .m-pastille[data-statut="neg"]    { --m-fg: var(--neg-fg);    --m-bg: var(--neg-soft); }
[data-v2] .m-pastille[data-statut="info"]   { --m-fg: var(--info-fg);   --m-bg: var(--info-soft); }
[data-v2] .m-pastille[data-statut="alt"]    { --m-fg: var(--alt-fg);    --m-bg: var(--alt-soft); }
[data-v2] .m-pastille[data-statut="teal"]   { --m-fg: var(--teal-fg);   --m-bg: var(--teal-soft); }
/* Pas de pastille ambre. L'ambre remplit les boutons : sur un écran qui
   porte les deux, plus rien ne dit ce qui est cliquable. « En négociation »
   et « À décider » sont des statuts d'attente — ils n'ont aucune raison
   d'être plus visibles qu'un statut en cours, donc gris neutre, qui est
   déjà le défaut de `.m-pastille`. */
[data-v2] .m-pastille[data-statut="neutre"] { --m-fg: var(--v2-text-2); --m-bg: var(--inset); }

/* ══════════════════════════════════════════════════════════════
   4. SEGMENTS DE FILTRE
   Les compteurs se dérivent de la liste comptée, jamais écrits en
   dur (piège n° 7) — c'est au JS de les fournir.
   ══════════════════════════════════════════════════════════════ */
[data-v2] .m-segments {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 3px;
  border-radius: 99px;
  background: var(--inset);
  border: 1px solid var(--stroke-2);
}
[data-v2] .m-segment {
  all: unset;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 28px;
  padding: 0 12px;
  border-radius: 99px;
  font-family: var(--font);
  font-size: 12.5px;
  font-weight: 550;
  color: var(--v2-text-2);
  transition: background .14s ease, color .14s ease;
}
[data-v2] .m-segment:hover { color: var(--v2-text); }
[data-v2] .m-segment:focus-visible { outline: 2px solid var(--v2-accent); outline-offset: 1px; }
[data-v2] .m-segment[aria-pressed="true"] {
  background: var(--accent-soft);
  color: var(--v2-text);
  box-shadow: var(--shadow-sm);
}
[data-v2] .m-segment b {
  font-size: 11px;
  font-weight: 640;
  color: var(--v2-text-3);
  font-variant-numeric: tabular-nums;
}
[data-v2] .m-segment[aria-pressed="true"] b { color: var(--v2-accent); }

/* ══════════════════════════════════════════════════════════════
   5. CARTE KPI
   ══════════════════════════════════════════════════════════════ */
[data-v2] .m-kpi {
  background: var(--panel);
  backdrop-filter: blur(20px);
  border: 1px solid var(--stroke);
  border-radius: var(--r-md);
  padding: 14px 16px 15px;
  box-shadow: var(--shadow);
  display: flex;
  flex-direction: column;
  gap: 3px;
  font-family: var(--font);
}
[data-v2] .m-kpi-titre {
  font-size: 11px;
  font-weight: 640;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--v2-text-3);
}
/* LE SÉPARATEUR DE MILLIERS DOIT SURVIVRE AU CRÉNAGE.
   Les chiffres d'affichage portent `letter-spacing: -.04em`, qui resserre
   TOUS les caractères — y compris l'espace insécable qui sépare les
   milliers. À 25 px, « 108 075 » se lisait « 108075 ». Le caractère n'y
   est pour rien : U+202F, U+00A0 et U+2009 rendent la même chose une fois
   crénés. `word-spacing` ne touche que les espaces, donc uniquement ce
   séparateur, et lui rend sa lisibilité sans desserrer les chiffres. */
[data-v2] .m-kpi-val {
  word-spacing: .12em;
  font-family: var(--font-display);
  font-size: 25px;
  font-weight: 640;
  letter-spacing: -.04em;
  line-height: 1.1;
  color: var(--m-fg, var(--v2-text));
  font-variant-numeric: tabular-nums;
}
[data-v2] .m-kpi-val small {
  font-family: var(--font);
  font-size: 12.5px;
  font-weight: 550;
  letter-spacing: 0;
  color: var(--v2-text-3);
  margin-left: 4px;
}
[data-v2] .m-kpi-sous { font-size: 11.5px; font-weight: 550; color: var(--v2-text-3); }
/* Le chiffre prend la couleur du statut quand c'est une alerte. */
[data-v2] .m-kpi[data-statut="pos"]    { --m-fg: var(--pos-fg); }
[data-v2] .m-kpi[data-statut="neg"]    { --m-fg: var(--neg-fg); }
[data-v2] .m-kpi[data-statut="info"]   { --m-fg: var(--info-fg); }
/* Pas de chiffre KPI ambre non plus : même raison. Un chiffre qui alerte est
   rouge, un chiffre qui rassure est vert, tout le reste est neutre. */

/* ══════════════════════════════════════════════════════════════
   6. BARRE DE PROGRESSION
   ══════════════════════════════════════════════════════════════ */
/* La barre a son PROPRE slot, `--m-fill`, et ne touche pas à `--m-fg`.
   Les deux ne veulent pas dire la même chose : `--m-fg` est une encre
   (pastille, carte KPI, chiffre), `--m-fill` est un aplat. Les faire
   partager un nom rejouait exactement le piège de `--accent` un cran
   plus bas : une barre sans statut posée dans une carte
   `.m-kpi[data-statut="accent"]` héritait de son `--m-fg`, et son
   remplissage se peignait en olive #7d640d — une encre de texte — au
   lieu de l'ambre. Aucune erreur console, juste une barre sale. */
[data-v2] .m-barre {
  /* L'AMBRE, ET POURQUOI C'EST ACCEPTABLE ICI.
     Mesuré le 10/08/2026 : ambre #f5d547 sur la piste claire donne 1,26:1,
     sous les 3:1 exigés d'un élément graphique porteur d'information. C'est
     ce qui avait fait choisir l'olive --v2-accent (4,94:1) — un choix juste
     dans l'absolu, mais qui rendait des barres brunes là où la maquette
     montre de l'ambre franc.
     Le critère ne s'applique qu'aux éléments dont la compréhension dépend de
     leur perception. Ici, JAMAIS : chaque barre de ce CRM est doublée de son
     pourcentage écrit à côté d'elle, en texte à plus de 4,5:1. La barre
     donne l'ordre de grandeur d'un coup d'œil, le chiffre donne la valeur.
     Retirer la barre ne ferait perdre aucune information.
     Si une barre sans pourcentage écrit apparaît un jour, elle devra porter
     l'olive — et ce commentaire est là pour qu'on s'en souvienne. */
  --m-fill: var(--accent-bright);
  position: relative;
  height: 6px;
  border-radius: 99px;
  background: var(--track);
  /* `hidden` comme la maquette : la piste doit couper le remplissage. */
  overflow: hidden;
}
[data-v2] .m-barre-fine { height: 5px; }
[data-v2] .m-barre i {
  display: block;
  height: 100%;
  border-radius: 99px;
  background: var(--m-fill);
  transition: width .18s ease;
}
[data-v2] .m-barre[data-statut="pos"]  { --m-fill: var(--pos-fg); }
[data-v2] .m-barre[data-statut="neg"]  { --m-fill: var(--neg-fg); }
[data-v2] .m-barre[data-statut="info"] { --m-fill: var(--info-fg); }
[data-v2] .m-barre[data-statut="teal"] { --m-fill: var(--teal-fg); }
/* Neutre : une jauge qui ne porte aucun jugement. Une complétude à 26 %
   n'attend rien — elle manque. Le bleu, qui veut dire « en attente »
   partout ailleurs, y était un contresens. */
[data-v2] .m-barre[data-statut="neutre"] { --m-fill: var(--v2-text-3); }
/* Pas de repère d'objectif : aucun objectif n'existe dans ce CRM, le trait
   afficherait donc un nombre inventé. Le jour où les objectifs sont
   définis — décision produit, pas détail de composant — il faudra aussi
   repasser la piste en `overflow: visible` pour laisser dépasser le trait. */

/* ══════════════════════════════════════════════════════════════
   7. ÉTATS VIDES
   Absents du handoff, proposés au lot 2 : chaque tableau en aura
   un, et sans motif commun ils seraient improvisés quinze fois.
   ══════════════════════════════════════════════════════════════ */
[data-v2] .m-vide {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 4px;
  padding: 44px 24px;
  font-family: var(--font);
}
[data-v2] .m-vide-ico {
  width: 44px; height: 44px;
  display: grid; place-items: center;
  border-radius: 99px;
  background: var(--inset);
  color: var(--v2-text-3);
  margin-bottom: 6px;
}
[data-v2] .m-vide-ico svg { width: 19px; height: 19px; }
[data-v2] .m-vide-titre { font-size: 15px; font-weight: 640; letter-spacing: -.02em; color: var(--v2-text); }
[data-v2] .m-vide-txt { font-size: 12.5px; font-weight: 550; color: var(--v2-text-3); max-width: 42ch; }
[data-v2] .m-vide .m-action { margin-top: 12px; }

/* Variante « filtré » : ce n'est pas vide, c'est le filtre qui ne
   renvoie rien. Le remède n'est pas le même, le ton non plus. */
[data-v2] .m-vide[data-genre="filtre"] .m-vide-ico { background: var(--accent-soft); color: var(--v2-accent); }
/* Variante « erreur » : on n'a pas pu charger, ce n'est pas un vide. */
[data-v2] .m-vide[data-genre="erreur"] .m-vide-ico { background: var(--neg-soft); color: var(--neg-fg); }

/* Un seul bouton ambre plein par écran : dans un état vide, c'est
   lui l'action principale. */
[data-v2] .m-action {
  all: unset;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: 36px;
  padding: 0 15px;
  border-radius: var(--r-sm);
  background: var(--accent-bright);
  color: var(--sur-accent, #1b1a12);
  font-family: var(--font);
  font-size: 13.5px;
  font-weight: 640;
  letter-spacing: -.01em;
  box-shadow: var(--shadow-sm);
  transition: filter .14s ease, transform .14s ease;
}
[data-v2] .m-action:hover { filter: brightness(1.06); }
[data-v2] .m-action:active { transform: scale(.98); }
[data-v2] .m-action:focus-visible { outline: 2px solid var(--v2-accent); outline-offset: 2px; }
[data-v2] .m-action.m-action-neutre {
  background: var(--panel);
  border: 1px solid var(--stroke);
  color: var(--v2-text-2);
  box-shadow: none;
}

@media (prefers-reduced-motion: reduce) {
  [data-v2] .m-liste-l, [data-v2] .m-segment, [data-v2] .m-barre i, [data-v2] .m-action { transition: none; }
}
