/* ==========================================================================
   Economat - feuille de style unique
   --------------------------------------------------------------------------
   Direction artistique : calme, aere, beaucoup de blanc.
   Un seul accent (vert profond), aucune ombre portee, aucun degrade,
   aucune bordure verticale dans les tableaux, casse de phrase partout.
   Deux graisses seulement : 400 et 500.

   Toutes les couleurs sont declarees en variables sur :root.
   Aucune couleur n'est ecrite en dur ailleurs dans ce fichier.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Variables
   -------------------------------------------------------------------------- */

:root {
  /* Les controles natifs (liste deroulante, calendrier, selecteur de couleur,
     ascenseurs) suivent le theme du systeme. Sans cette ligne, un champ de date
     reste blanc sur fond sombre et devient illisible. */
  color-scheme: light dark;

  /* surfaces et filets */
  --fond: #FAFAF9;
  --carte: #FFFFFF;
  --bord: #E7E5E4;
  --bord-fort: #D6D3D1;

  /* texte */
  --texte: #1C1917;
  --texte-doux: #78716C;
  --texte-faible: #A8A29E;

  /* accent unique */
  --accent: #15803D;
  --accent-fond: #F0FDF4;
  --accent-texte: #FFFFFF;

  /* etats */
  --danger: #B91C1C;
  --danger-fond: #FEF2F2;
  --alerte: #C2410C;
  --alerte-fond: #FFF7ED;
  --attention: #A16207;
  --attention-fond: #FEFCE8;

  /* surfaces derivees */
  --barre: #F5F5F4;          /* fond de la barre laterale */
  --survol: #F5F5F4;         /* survol de ligne et de lien */
  --anneau: rgba(21, 128, 61, 0.24);  /* unique ombre autorisee : le focus */
  --voile: rgba(28, 25, 23, 0.28);    /* fond du menu ouvert sur mobile */

  /* typographie */
  --police: system-ui, "Segoe UI Variable Text", "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

  /* geometrie */
  --rayon-carte: 10px;
  --rayon-controle: 8px;
  --largeur-barre: 232px;
}

@media (prefers-color-scheme: dark) {
  :root {
    --fond: #151312;
    --carte: #1C1917;
    --bord: #2E2A28;
    --bord-fort: #44403C;

    --texte: #F5F5F4;
    --texte-doux: #A8A29E;
    --texte-faible: #78716C;

    --accent: #4ADE80;
    --accent-fond: #14261A;
    --accent-texte: #0B1F12;

    --danger: #F87171;
    --danger-fond: #2A1616;
    --alerte: #FB923C;
    --alerte-fond: #2A1A10;
    --attention: #FACC15;
    --attention-fond: #26200D;

    --barre: #1A1716;
    --survol: #232020;
    --anneau: rgba(74, 222, 128, 0.26);
    --voile: rgba(0, 0, 0, 0.55);
  }
}

/* --------------------------------------------------------------------------
   2. Reinitialisation minimale
   -------------------------------------------------------------------------- */

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

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--fond);
  color: var(--texte);
  font-family: var(--police);
  font-size: 15px;
  font-weight: 400;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 { font-weight: 500; margin: 0; }
h1 { font-size: 20px; }
h2 { font-size: 16px; }
h3 { font-size: 15px; }

p { margin: 0 0 12px; }
p:last-child { margin-bottom: 0; }

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

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

hr {
  border: 0;
  border-top: 1px solid var(--bord);
  margin: 24px 0;
}

:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--anneau);
  border-radius: var(--rayon-controle);
}

/* --------------------------------------------------------------------------
   3. Mise en page
   -------------------------------------------------------------------------- */

.appli {
  display: grid;
  grid-template-columns: var(--largeur-barre) 1fr;
  min-height: 100vh;
}

.contenu {
  padding: 24px 32px 64px;
  max-width: 1280px;
  width: 100%;
}

/* En-tete de page : titre a gauche, boutons d'action a droite */
.entete-page {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 24px;
}

.entete-page h1 { font-size: 20px; font-weight: 500; }

.entete-page .sous-titre {
  display: block;
  font-size: 13px;
  font-weight: 400;
  color: var(--texte-doux);
  margin-top: 2px;
}

.entete-page .actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

/* Grille de cartes ou de statistiques */
.grille {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 16px;
  margin-bottom: 24px;
}

.grille-2 { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }

/* Espacement standard entre deux blocs */
.bloc { margin-bottom: 24px; }

/* --------------------------------------------------------------------------
   4. Barre laterale
   -------------------------------------------------------------------------- */

.barre-laterale {
  background: var(--barre);
  border-right: 1px solid var(--bord);
  padding: 20px 12px 32px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
}

.marque {
  display: block;
  padding: 0 12px 20px;
  color: var(--texte);
  font-size: 15px;
  font-weight: 500;
}
.marque:hover { text-decoration: none; }

.marque .marque-lieu {
  display: block;
  font-size: 12px;
  font-weight: 400;
  color: var(--texte-faible);
  margin-top: 2px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.nav-lien {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 40px;
  padding: 8px 12px;
  border-radius: var(--rayon-controle);
  color: var(--texte);
  font-size: 15px;
  font-weight: 400;
}
.nav-lien:hover { background: var(--survol); text-decoration: none; }

.nav-lien.actif {
  background: var(--accent-fond);
  color: var(--accent);
  font-weight: 500;
}

.nav-lien svg { flex: 0 0 auto; }

.nav-groupe {
  margin: 20px 0 4px;
  padding: 0 12px;
  font-size: 12px;
  font-weight: 400;
  color: var(--texte-faible);
}

.nav-bas { margin-top: auto; padding-top: 20px; }

/* Bouton hamburger : masque sur grand ecran */
.bouton-menu { display: none; }
.voile-menu { display: none; }

/* --------------------------------------------------------------------------
   5. Cartes et statistiques
   -------------------------------------------------------------------------- */

.carte {
  background: var(--carte);
  border: 1px solid var(--bord);
  border-radius: var(--rayon-carte);
  padding: 16px 20px;
}

.carte + .carte { margin-top: 16px; }

.carte-titre {
  font-size: 13px;
  font-weight: 500;
  color: var(--texte-doux);
  margin-bottom: 12px;
}

.carte-lien { display: block; color: inherit; }
.carte-lien:hover { border-color: var(--bord-fort); text-decoration: none; }

/* Grand chiffre du tableau de bord */
.stat {
  background: var(--carte);
  border: 1px solid var(--bord);
  border-radius: var(--rayon-carte);
  padding: 16px 20px;
  display: block;
  color: inherit;
}
.stat:hover { text-decoration: none; }
a.stat:hover { border-color: var(--bord-fort); }

.stat-valeur {
  display: block;
  font-size: 28px;
  font-weight: 500;
  line-height: 1.2;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
}

.stat-libelle {
  display: block;
  font-size: 13px;
  font-weight: 400;
  color: var(--texte-doux);
  margin-top: 4px;
}

.stat-detail {
  display: block;
  font-size: 12px;
  color: var(--texte-faible);
  margin-top: 4px;
}

.stat-accent  .stat-valeur { color: var(--accent); }
.stat-danger  .stat-valeur { color: var(--danger); }
.stat-alerte  .stat-valeur { color: var(--alerte); }

/* --------------------------------------------------------------------------
   6. Tableaux
   Aucune bordure verticale. Filets horizontaux uniquement.
   -------------------------------------------------------------------------- */

.table-defilante {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

/* Un conteneur qui defile horizontalement devient, selon la specification, un
   conteneur de defilement sur les DEUX axes : "overflow-x: auto" force
   "overflow-y" a passer de "visible" a "auto". L'en-tete collant s'accrochait
   donc a ce conteneur au lieu de suivre la fenetre ; comme le conteneur fait
   exactement la hauteur du tableau, il n'avait jamais de quoi coller et
   l'effet etait nul sur tous les ecrans.

   Sur grand ecran on retire donc le conteneur, et thead se cale enfin sur le
   haut de la fenetre. Les trois tableaux les plus larges en sont exclus : eux
   debordent reellement et ont besoin de leur ascenseur horizontal. La regle
   est ecrite en :not(:has(...)) pour que, sur un navigateur qui ignorerait
   :has(), le selecteur soit invalide et le comportement actuel conserve :
   l'echec se fait du cote sur. */
@media (min-width: 901px) {
  .table-defilante:not(:has(.tableau-prix)):not(:has(.cmd-tableau)):not(:has(.tableau-lignes)) {
    overflow: visible;
  }
}

.tableau {
  width: 100%;
  border-collapse: collapse;
  font-size: 15px;
}

.tableau th,
.tableau td {
  text-align: left;
  padding: 12px 12px;
  border: 0;
  border-bottom: 1px solid var(--bord);
  vertical-align: middle;
}

.tableau th:first-child,
.tableau td:first-child { padding-left: 0; }

.tableau th:last-child,
.tableau td:last-child { padding-right: 0; }

.tableau thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  /* fond identique a la carte qui contient le tableau : visuellement neutre,
     mais opaque pour que les lignes ne transparaissent pas au defilement */
  background: var(--carte);
  font-size: 12px;
  font-weight: 500;
  color: var(--texte-doux);
  border-bottom: 1px solid var(--bord-fort);
  white-space: nowrap;
}

.tableau thead th a { color: inherit; }

.tableau tbody tr:hover { background: var(--survol); }

.tableau tbody tr:last-child td { border-bottom: 0; }

.tableau tfoot td {
  font-weight: 500;
  border-top: 1px solid var(--bord-fort);
  border-bottom: 0;
}

/* Nombres : toujours a droite, chasse fixe */
.num,
.tableau th.num,
.tableau td.num {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Colonne d'actions : discrete, revelee au survol sur grand ecran */
.actions-ligne {
  text-align: right;
  white-space: nowrap;
}

.actions-ligne a,
.actions-ligne button {
  display: inline-flex;
  align-items: center;
  min-height: 32px;
  font-size: 13px;
  color: var(--texte-doux);
  background: none;
  border: 0;
  padding: 4px 8px;
  cursor: pointer;
  font-family: inherit;
}
.actions-ligne a:hover { color: var(--accent); }
.actions-ligne button:hover { color: var(--danger); }

@media (hover: hover) and (min-width: 901px) {
  .actions-ligne { opacity: 0; transition: opacity 0.12s ease-out; }
  tr:hover .actions-ligne,
  .actions-ligne:focus-within { opacity: 1; }
}

/* Doigt plutot que souris : toutes les cibles passent a 40px.
   L'econome est souvent en cuisine, sur une tablette, les mains prises. */
@media (pointer: coarse) {
  .actions-ligne a,
  .actions-ligne button,
  .bouton-discret,
  .tableau .sortie-note { min-height: 40px; }
}

/* Ligne de sous-total ou de regroupement */
.ligne-groupe td {
  font-size: 12px;
  font-weight: 500;
  color: var(--texte-doux);
  background: var(--fond);
}

/* --------------------------------------------------------------------------
   7. Pastilles, badges, etats
   -------------------------------------------------------------------------- */

/* Pastille ronde de 6px : prend la couleur du texte courant */
.pastille {
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
  vertical-align: 0.12em;
  margin-right: 6px;
  flex: 0 0 auto;
}

.badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  border: 1px solid var(--bord);
  border-radius: 999px;
  padding: 2px 10px;
  font-size: 12px;
  font-weight: 400;
  color: var(--texte-doux);
  white-space: nowrap;
  /* Un badge porte souvent une quantite : "385 paquets en stock". */
  font-variant-numeric: tabular-nums;
}

.badge-accent    { color: var(--accent);    border-color: var(--accent); }
.badge-danger    { color: var(--danger);    border-color: var(--danger); }
.badge-alerte    { color: var(--alerte);    border-color: var(--alerte); }
.badge-attention { color: var(--attention); border-color: var(--attention); }

/* Etats DLC : ils colorent le TEXTE et la pastille, jamais la ligne entiere */
.dlc-perime { color: var(--danger); }
.dlc-urgent { color: var(--alerte); }
.dlc-proche { color: var(--attention); }
.dlc-ok     { color: var(--texte); }

/* --------------------------------------------------------------------------
   8. Boutons
   Un seul bouton plein par ecran : .bouton-primaire.
   -------------------------------------------------------------------------- */

.bouton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 40px;
  padding: 8px 16px;
  border: 1px solid var(--bord-fort);
  border-radius: var(--rayon-controle);
  background: var(--carte);
  color: var(--texte);
  font-family: inherit;
  font-size: 15px;
  font-weight: 400;
  line-height: 1.3;
  cursor: pointer;
  white-space: nowrap;
  text-decoration: none;
}
.bouton:hover { background: var(--survol); text-decoration: none; }
.bouton:disabled,
.bouton[aria-disabled="true"] { color: var(--texte-faible); cursor: default; }

.bouton-primaire {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-texte);
  font-weight: 500;
}
.bouton-primaire:hover { background: var(--accent); opacity: 0.92; }

.bouton-danger {
  border-color: var(--bord-fort);
  color: var(--danger);
  background: var(--carte);
}
.bouton-danger:hover { background: var(--danger-fond); }

.bouton-discret {
  min-height: 36px;
  padding: 4px 8px;
  border: 0;
  background: none;
  color: var(--texte-doux);
  font-size: 13px;
}
.bouton-discret:hover { background: none; color: var(--accent); text-decoration: underline; }

.bouton-large { width: 100%; }

/* --------------------------------------------------------------------------
   9. Formulaires
   -------------------------------------------------------------------------- */

.ligne-formulaire { margin-bottom: 16px; }

.ligne-formulaire > label,
.libelle {
  display: block;
  font-size: 12px;
  font-weight: 400;
  color: var(--texte-faible);
  margin-bottom: 4px;
}

.champ {
  display: block;
  width: 100%;
  min-height: 40px;
  padding: 8px 12px;
  border: 1px solid var(--bord-fort);
  border-radius: var(--rayon-controle);
  background: var(--carte);
  color: var(--texte);
  font-family: inherit;
  font-size: 15px;
  font-weight: 400;
  line-height: 1.4;
}
.champ:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--anneau);
}
.champ::placeholder { color: var(--texte-faible); }
.champ:disabled { color: var(--texte-doux); background: var(--fond); }

textarea.champ { min-height: 88px; resize: vertical; line-height: 1.55; }

/* La fleche de la liste deroulante est celle du systeme : aucune image, aucune
   couleur en dur, et elle suit le mode sombre grace a color-scheme. */
select.champ { padding-right: 8px; }

.champ-nombre {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.champ-court { max-width: 140px; }
.champ-moyen { max-width: 260px; }

/* Cases a cocher : cible tactile confortable */
.case {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 40px;
  font-size: 15px;
  cursor: pointer;
}
.case input { width: 18px; height: 18px; accent-color: var(--accent); }

.aide {
  display: block;
  font-size: 12px;
  color: var(--texte-faible);
  margin-top: 4px;
}

/* Deux ou trois champs cote a cote */
.champs {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 16px;
}

.actions-formulaire {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 24px;
  padding-top: 20px;
  border-top: 1px solid var(--bord);
}

/* --------------------------------------------------------------------------
   10. L'equivalence
   La classe la plus utilisee du projet : le texte discret place sous un champ
   pour dire "2 colis = 400 paquets". Elle est le langage de la conversion.
   -------------------------------------------------------------------------- */

.equivalence {
  display: block;
  margin-top: 4px;
  font-size: 12px;
  font-weight: 400;
  line-height: 1.4;
  color: var(--texte-doux);
  font-variant-numeric: tabular-nums;
  min-height: 17px;   /* reserve la place : le champ ne saute pas a la frappe */
}

.equivalence:empty { min-height: 17px; }

/* Variante appliquee brievement quand la valeur vient de changer */
.equivalence-forte {
  color: var(--accent);
  animation: equivalence-apparait 0.9s ease-out;
}

@keyframes equivalence-apparait {
  from { background: var(--accent-fond); }
  to   { background: transparent; }
}

@media (prefers-reduced-motion: reduce) {
  .equivalence-forte { animation: none; }
}

/* Equivalence placee dans une cellule de tableau, alignee a droite */
.tableau .equivalence { text-align: right; }

/* --------------------------------------------------------------------------
   11. Alertes et encadres de synthese
   Les fonds teintes sont reserves a ces encadres, jamais aux lignes.
   -------------------------------------------------------------------------- */

.alerte {
  border: 1px solid var(--bord);
  border-radius: var(--rayon-carte);
  padding: 12px 16px;
  font-size: 15px;
  margin-bottom: 16px;
  color: var(--texte);
}

.alerte-succes { background: var(--accent-fond);    border-color: var(--accent);    color: var(--accent); }
.alerte-erreur { background: var(--danger-fond);    border-color: var(--danger);    color: var(--danger); }
.alerte-info   { background: var(--fond);           border-color: var(--bord-fort); color: var(--texte-doux); }
.alerte-attention { background: var(--attention-fond); border-color: var(--attention); color: var(--attention); }

/* Encadre du verdict prix : le fournisseur le moins cher, la tendance */
.verdict {
  background: var(--accent-fond);
  border: 1px solid var(--accent);
  border-radius: var(--rayon-carte);
  padding: 16px 20px;
  margin-bottom: 24px;
}
.verdict .verdict-reponse {
  font-size: 20px;
  font-weight: 500;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}
.verdict .verdict-detail {
  font-size: 13px;
  color: var(--texte-doux);
  margin-top: 4px;
}

/* --------------------------------------------------------------------------
   12. Barre d'outils, recherche, pagination, etat vide
   -------------------------------------------------------------------------- */

.barre-outils {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 16px;
}

.barre-outils .espaceur { flex: 1 1 auto; }

.recherche {
  position: relative;
  flex: 1 1 240px;
  max-width: 340px;
}

.recherche input {
  width: 100%;
  min-height: 40px;
  padding: 8px 12px 8px 36px;
  border: 1px solid var(--bord-fort);
  border-radius: var(--rayon-controle);
  background: var(--carte);
  color: var(--texte);
  font-family: inherit;
  font-size: 15px;
}
.recherche input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--anneau);
}

.recherche svg {
  position: absolute;
  left: 10px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--texte-faible);
  pointer-events: none;
}

.compteur-resultats {
  font-size: 13px;
  color: var(--texte-doux);
  font-variant-numeric: tabular-nums;
}

.pagination {
  display: flex;
  align-items: center;
  gap: 4px;
  flex-wrap: wrap;
  margin-top: 20px;
}

.pagination a,
.pagination span {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 40px;
  min-height: 40px;
  padding: 0 10px;
  border-radius: var(--rayon-controle);
  font-size: 15px;
  color: var(--texte-doux);
  font-variant-numeric: tabular-nums;
}
.pagination a:hover { background: var(--survol); color: var(--texte); text-decoration: none; }
.pagination .actif { background: var(--accent-fond); color: var(--accent); font-weight: 500; }
.pagination .inactif { color: var(--texte-faible); }

/* Etat vide : une phrase courte qui invite */
.vide {
  padding: 48px 24px;
  text-align: center;
  color: var(--texte-doux);
  font-size: 15px;
}
.vide p { margin-bottom: 16px; }

/* --------------------------------------------------------------------------
   13. Textes secondaires et divers
   -------------------------------------------------------------------------- */

.doux   { color: var(--texte-doux); font-size: 13px; }
.faible { color: var(--texte-faible); font-size: 12px; }
.accent { color: var(--accent); }
.rouge  { color: var(--danger); }

.mono { font-variant-numeric: tabular-nums; }

.nowrap { white-space: nowrap; }

.separateur {
  border-top: 1px solid var(--bord);
  margin: 24px 0;
}

/* Liste de definitions : fiche fournisseur, fiche produit */
.fiche {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 16px 24px;
  margin: 0;
}
.fiche dt {
  font-size: 12px;
  color: var(--texte-faible);
  margin-bottom: 2px;
}
/* Une fiche empile des quantites, des prix et des dates sur deux colonnes :
   la chasse fixe les aligne verticalement, comme dans un tableau. */
.fiche dd { margin: 0; font-size: 15px; font-variant-numeric: tabular-nums; }

/* Liste a puces sobre */
.liste {
  margin: 0;
  padding-left: 20px;
  color: var(--texte-doux);
  font-size: 13px;
}
.liste li { margin-bottom: 4px; }

/* Bloc de code ou de configuration a recopier */
.bloc-code {
  margin: 0;
  overflow-x: auto;
  font-family: ui-monospace, "Cascadia Mono", Consolas, "Courier New", monospace;
  font-size: 13px;
  line-height: 1.5;
  color: var(--texte-doux);
  white-space: pre;
}

/* Page autonome centree : installation, message isole */
.page-simple {
  max-width: 760px;
  margin: 0 auto;
  padding: 40px 24px 64px;
}
@media (max-width: 900px) {
  .page-simple { padding: 24px 16px 64px; }
}

/* Ecran de connexion */
.connexion {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}
.connexion-carte {
  width: 100%;
  max-width: 360px;
  background: var(--carte);
  border: 1px solid var(--bord);
  border-radius: var(--rayon-carte);
  padding: 32px;
}
.connexion-carte h1 { margin-bottom: 4px; }
.connexion-carte .doux { margin-bottom: 24px; display: block; }

/* --------------------------------------------------------------------------
   14. Petit ecran : jusqu'a 380px de large
   -------------------------------------------------------------------------- */

@media (max-width: 900px) {
  .appli { grid-template-columns: 1fr; }

  .barre-laterale {
    position: fixed;
    inset: 0 auto 0 0;
    width: 260px;
    z-index: 40;
    transform: translateX(-100%);
    transition: transform 0.16s ease-out;
    border-right: 1px solid var(--bord-fort);
  }
  .barre-laterale.ouverte { transform: translateX(0); }

  .voile-menu {
    display: none;
    position: fixed;
    inset: 0;
    background: var(--voile);
    z-index: 30;
  }
  .voile-menu.visible { display: block; }

  .bouton-menu {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    min-height: 40px;
    padding: 8px 12px;
    margin: 0 0 16px;
    border: 1px solid var(--bord-fort);
    border-radius: var(--rayon-controle);
    background: var(--carte);
    color: var(--texte);
    font-family: inherit;
    font-size: 15px;
    cursor: pointer;
  }

  .contenu { padding: 16px 16px 64px; }

  .grille,
  .grille-2,
  .champs,
  .fiche { grid-template-columns: 1fr; }

  .entete-page { align-items: flex-start; flex-direction: column; gap: 12px; }
  .entete-page .actions { width: 100%; }

  .recherche { max-width: none; flex-basis: 100%; }

  /* Les tableaux defilent horizontalement dans leur conteneur */
  .table-defilante { margin: 0 -16px; padding: 0 16px; }
  .tableau { min-width: 560px; }

  /* Sur tablette et telephone, les actions restent toujours visibles */
  .actions-ligne { opacity: 1; }
}

@media (max-width: 420px) {
  .carte { padding: 16px; }
  .connexion-carte { padding: 24px; }
  .stat-valeur { font-size: 24px; }
  .bouton { padding: 8px 12px; }
}

/* --------------------------------------------------------------------------
   15. Impression
   Les ecrans Tracabilite et Prix servent de justificatif : ils doivent
   s'imprimer proprement, en noir sur blanc, sans navigation.
   -------------------------------------------------------------------------- */

@media print {
  /* TOUTES les variables sont redefinies, y compris celles des etats.
     Sans cela, un poste regle en mode sombre imprimerait un rouge pale et un
     jaune vif sur du papier blanc : illisible. */
  :root {
    color-scheme: light;

    --fond: #FFFFFF;
    --carte: #FFFFFF;
    --bord: #CCCCCC;
    --bord-fort: #999999;
    --texte: #000000;
    --texte-doux: #333333;
    --texte-faible: #555555;

    --accent: #000000;
    --accent-fond: #FFFFFF;
    --accent-texte: #FFFFFF;

    --danger: #000000;
    --danger-fond: #FFFFFF;
    --alerte: #333333;
    --alerte-fond: #FFFFFF;
    --attention: #333333;
    --attention-fond: #FFFFFF;

    --survol: #FFFFFF;
    --barre: #FFFFFF;
    --anneau: transparent;
    --voile: transparent;
  }

  /* Rien de cliquable ne doit atteindre le papier : ni bouton, ni raccourci,
     ni depliant de saisie. Un bon imprime ne porte que de l'information. */
  .barre-laterale,
  .bouton-menu,
  .voile-menu,
  .barre-outils,
  .pagination,
  .actions-formulaire,
  .entete-page .actions,
  .bouton,
  .bouton-discret,
  .recherche,
  .sans-impression,
  .actions-ligne,
  .filtres-actions,
  .param-boutons,
  .sortie-raccourcis,
  .sortie-ajout,
  .sortie-reprise,
  .cmd-recherche,
  .cmd-pied,
  .assistant,
  .tri-fleche { display: none !important; }

  .appli { display: block; }
  .contenu { padding: 0; max-width: none; }

  body { background: var(--fond); color: var(--texte); font-size: 11pt; }

  .carte,
  .stat,
  .alerte,
  .verdict {
    border: 1px solid var(--bord);
    background: var(--carte);
    break-inside: avoid;
    page-break-inside: avoid;
  }

  .tableau { font-size: 10pt; }
  .tableau thead th { position: static; background: var(--carte); }
  .tableau tr {
    break-inside: avoid;
    page-break-inside: avoid;
  }
  .tableau thead { display: table-header-group; }

  a { color: var(--texte); text-decoration: none; }

  .table-defilante { overflow: visible; }
  .tableau { min-width: 0; }
}

/* --------------------------------------------------------------------------
   16. Module tableau de bord, paramètres et compte
   Ajouts de l'agent "tableau de bord". Aucune couleur en dur : uniquement
   les variables déclarées sur :root.
   -------------------------------------------------------------------------- */

/* En-tête d'un bloc : un titre à gauche, une précision ou une action à droite */
.bloc-entete {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 12px;
}

.bloc-entete h2 { font-size: 16px; font-weight: 500; }
.bloc-entete .doux { font-size: 13px; color: var(--texte-doux); }
.bloc-entete .bouton { align-self: center; }

/* Deux cartes qui se suivent gardent le rythme de 24px, sans s'additionner */
.carte.bloc + .carte.bloc { margin-top: 0; }
.grille > .carte + .carte { margin-top: 0; }

/* Seconde ligne discrète dans une cellule : numéro de bon, échéance, rappel.
   --texte-faible est réservé aux libellés et aux mentions ; ici on porte des
   chiffres que l'économe doit vraiment lire, parfois sur une tablette en
   cuisine. On prend donc --texte-doux, nettement plus contrasté. */
.tb-second {
  display: block;
  font-size: 12px;
  font-weight: 400;
  line-height: 1.4;
  color: var(--texte-doux);
  font-variant-numeric: tabular-nums;
}
.tableau .num .tb-second { text-align: right; }

/* Note posée sous un tableau */
.tb-note {
  margin: 12px 0 0;
  font-size: 13px;
  color: var(--texte-doux);
}

/* Réapprovisionnement : un groupe par fournisseur */
.tb-groupe {
  margin-top: 20px;
  padding-top: 20px;
  border-top: 1px solid var(--bord);
}
/* Le premier groupe suit directement l'en-tête du bloc : pas de filet inutile */
.bloc-entete + .tb-groupe { margin-top: 0; padding-top: 0; border-top: 0; }

.tb-groupe-entete {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 8px;
}
.tb-groupe-entete h3 { font-size: 15px; font-weight: 500; }

/* Paramètres : aperçu du logo et boutons posés côte à côte */
.param-logo {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  padding: 16px;
  margin-bottom: 16px;
  border: 1px solid var(--bord);
  border-radius: var(--rayon-carte);
  background: var(--fond);
}
.param-logo img { max-height: 96px; width: auto; }

.param-en-ligne { display: inline-flex; margin: 0; }

/* Rangée de boutons sans séparateur : hors formulaire, pas de filet au-dessus */
.param-boutons {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 16px;
}

/* Case à cocher isolée, hors grille de champs */
.param-case { margin-bottom: 16px; }

/* --------------------------------------------------------------------------
   Module Sorties - ecrans sorties.php et sortie_edit.php
   --------------------------------------------------------------------------
   Rappel : sur ces ecrans, TOUTES les quantites sont en unite de suivi.
   L'unite d'achat n'apparait qu'en rappel gris sur le stock disponible.
   -------------------------------------------------------------------------- */

/* Filtre de periode, aligne sur la ligne de la barre d'outils */
.sortie-filtre {
  display: flex;
  align-items: flex-end;
  gap: 12px;
  flex-wrap: wrap;
}
.sortie-filtre .ligne-formulaire { margin-bottom: 0; }

/* Raccourcis de periode : de simples liens, aucun bouton de plus */
.sortie-raccourcis {
  display: flex;
  gap: 16px;
  flex-wrap: wrap;
  margin: -4px 0 16px;
  font-size: 13px;
}
.sortie-raccourcis a { color: var(--texte-doux); }
.sortie-raccourcis a:hover { color: var(--accent); }

/* Reprise d'une sortie precedente : un depliant sobre, sans onglet */
.sortie-reprise { padding: 0; }
.sortie-reprise > summary {
  display: flex;
  align-items: center;
  min-height: 40px;
  padding: 10px 20px;
  list-style: none;
  cursor: pointer;
  font-size: 15px;
  color: var(--texte);
}
.sortie-reprise > summary::-webkit-details-marker { display: none; }
.sortie-reprise > summary::after {
  content: '+';
  margin-left: auto;
  padding-left: 16px;
  color: var(--texte-faible);
}
.sortie-reprise[open] > summary::after { content: '–'; }
.sortie-reprise[open] > summary { border-bottom: 1px solid var(--bord); }
.sortie-reprise-corps { padding: 12px 20px 16px; }

/* Recherche de produit et liste de resultats */
.sortie-ajout { margin-bottom: 0; position: relative; }

.sortie-resultats {
  margin-top: 8px;
  border: 1px solid var(--bord);
  border-radius: var(--rayon-controle);
  background: var(--carte);
  max-height: 320px;
  overflow-y: auto;
}

.sortie-resultat {
  display: block;
  width: 100%;
  min-height: 40px;
  padding: 8px 12px;
  border: 0;
  border-bottom: 1px solid var(--bord);
  background: none;
  color: var(--texte);
  font-family: inherit;
  font-size: 15px;
  font-weight: 400;
  line-height: 1.4;
  text-align: left;
  cursor: pointer;
}
.sortie-resultat:last-child { border-bottom: 0; }
.sortie-resultat:hover { background: var(--survol); }

.sortie-resultat-nom { display: block; }
.sortie-resultat-detail {
  display: block;
  font-size: 12px;
  color: var(--texte-doux);
  font-variant-numeric: tabular-nums;
}

.sortie-resultat-vide {
  margin: 0;
  padding: 16px 12px;
  font-size: 13px;
  color: var(--texte-doux);
}

/* Tableau de saisie des lignes */
.sortie-nom { display: block; }

.tableau .sortie-note {
  display: block;
  width: 100%;
  max-width: 220px;
  margin-top: 4px;
  min-height: 32px;
  padding: 4px 8px;
  border: 1px solid var(--bord);
  border-radius: var(--rayon-controle);
  background: var(--carte);
  color: var(--texte-doux);
  font-family: inherit;
  font-size: 13px;
}
.tableau .sortie-note:focus {
  outline: none;
  color: var(--texte);
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--anneau);
}

.tableau .sortie-lot { min-width: 240px; }

/* Etat de la DLC : couleur de texte et pastille, jamais la ligne entiere */
.sortie-info {
  display: block;
  margin-top: 4px;
  font-size: 12px;
  line-height: 1.4;
  color: var(--texte-doux);
  font-variant-numeric: tabular-nums;
}

.sortie-dispo {
  color: var(--texte-doux);
  font-size: 13px;
}

.tableau .sortie-qte {
  display: inline-block;
  width: 100px;
}

.sortie-unite {
  display: block;
  margin-top: 4px;
  font-size: 12px;
  color: var(--texte-faible);
}

.sortie-alerte {
  display: block;
  margin-top: 4px;
  font-size: 12px;
  line-height: 1.4;
  color: var(--danger);
  white-space: normal;
}

.sortie-champ-erreur { border-color: var(--danger); }
.sortie-champ-erreur:focus {
  border-color: var(--danger);
  box-shadow: 0 0 0 3px var(--danger-fond);
}

.sortie-actions {
  text-align: right;
  white-space: normal;
}
.sortie-actions button {
  display: block;
  margin-left: auto;
  text-align: right;
}

/* Le total est pousse a droite de la barre d'enregistrement */
.actions-formulaire .espaceur { flex: 1 1 auto; }

@media (max-width: 900px) {
  /* Le tableau de saisie porte un select et deux champs : il lui faut de la place */
  .tableau-lignes { min-width: 760px; }
}

/* --------------------------------------------------------------------------
   16. Module Stock, tracabilite et inventaire
   Ajout cible : rien de ce qui precede n'est modifie.
   Aucune couleur en dur, uniquement les variables declarees sur :root.
   -------------------------------------------------------------------------- */

/* Barre de filtres : des controles alignes par le bas, qui passent a la ligne */
.filtres {
  display: flex;
  align-items: flex-end;
  flex-wrap: wrap;
  gap: 12px 16px;
  margin-bottom: 16px;
}

.filtres .filtre {
  display: flex;
  flex-direction: column;
  min-width: 150px;
}

.filtres .filtre .libelle { margin-bottom: 4px; }

.filtre-large { flex: 1 1 240px; }
.filtre-large .recherche { flex: none; max-width: none; width: 100%; }

.filtres .champ-filtre { min-width: 150px; }

.filtres .filtre-case { align-self: center; font-size: 13px; color: var(--texte-doux); }

/* Bascule entre deux vues : deux liens contigus, un seul en evidence */
.segments {
  display: inline-flex;
  border: 1px solid var(--bord-fort);
  border-radius: var(--rayon-controle);
  overflow: hidden;
}

.segments a {
  display: inline-flex;
  align-items: center;
  min-height: 40px;
  padding: 8px 16px;
  background: var(--carte);
  color: var(--texte-doux);
  font-size: 15px;
  font-weight: 400;
}
.segments a + a { border-left: 1px solid var(--bord); }
.segments a:hover { background: var(--survol); color: var(--texte); text-decoration: none; }
.segments a.actif { background: var(--accent-fond); color: var(--accent); font-weight: 500; }

/* En-tete de colonne triable */
.tri-lien { color: inherit; }
.tri-actif { color: var(--texte); font-weight: 500; }
.tri-lien:hover, .tri-actif:hover { text-decoration: underline; }

/* Colonne secondaire : presente, mais qui ne tire pas l'oeil */
.colonne-discrete { color: var(--texte-doux); font-size: 13px; }

/* Formulaire pose dans une cellule d'actions */
.actions-ligne .en-ligne { display: inline; }

/* Rappel de l'equivalent en unite d'achat, sous une valeur ou un champ.
   C'est le coeur du logiciel : "385 paquets (soit 1,9 colis)". Il se lit,
   il ne se devine pas. Donc --texte-doux, jamais --texte-faible. */
.equivalent-achat {
  display: block;
  margin-top: 2px;
  font-size: 12px;
  line-height: 1.4;
  color: var(--texte-doux);
  font-variant-numeric: tabular-nums;
  min-height: 17px;
}

/* Champ de comptage : compact et cale a droite dans sa colonne */
.champ-comptage { max-width: 130px; margin-left: auto; }

/* Ecarts d'inventaire : une couleur de texte, jamais une ligne coloree */
.ecart-plus  { color: var(--accent); }
.ecart-moins { color: var(--danger); }
.ecart-nul   { color: var(--texte-faible); }

/* Champ de recherche suivi de son bouton */
.ligne-recherche {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.recherche-large { flex: 1 1 320px; max-width: 480px; }

/* Fiche d'un lot en tracabilite */
.fiche-lot-entete {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 20px;
}
.fiche-lot-entete .doux { display: block; margin-top: 2px; }
.fiche-lot-etat { display: flex; gap: 8px; flex-wrap: wrap; }

/* Frise verticale : d'ou il vient, ce qu'il en reste, ou il est parti */
.frise {
  list-style: none;
  margin: 0;
  padding: 0 0 0 24px;
  border-left: 1px solid var(--bord);
}

.frise-etape { position: relative; padding-bottom: 24px; }
.frise-etape:last-child { padding-bottom: 0; }

.frise-etape::before {
  content: "";
  position: absolute;
  left: -30px;
  top: 5px;
  width: 9px;
  height: 9px;
  border: 1px solid var(--bord-fort);
  border-radius: 50%;
  background: var(--carte);
}
.frise-etape.etape-accent::before { border-color: var(--accent); background: var(--accent); }

.frise-titre {
  margin: 0 0 8px;
  font-size: 12px;
  font-weight: 400;
  color: var(--texte-faible);
}

.frise .fiche { margin-bottom: 8px; }
.frise .fiche > div { min-width: 0; }
.frise .fiche dd .faible { display: block; }

/* Tableau imbrique dans une frise : un peu plus serre */
.tableau-compact th,
.tableau-compact td { padding: 8px 12px; }

/* Libelle reserve aux lecteurs d'ecran */
.sr-libelle {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

@media (max-width: 900px) {
  .filtres .filtre { min-width: 0; flex: 1 1 160px; }
  .filtre-large { flex: 1 1 100%; }
  .segments { width: 100%; }
  .segments a { flex: 1 1 50%; justify-content: center; }
  .champ-comptage { max-width: none; }
  .frise { padding-left: 20px; }
  .frise-etape::before { left: -26px; }
}

@media print {
  .filtres,
  .segments,
  .compteur-resultats { display: none !important; }

  /* La feuille d'inventaire s'emporte en réserve : le champ de comptage
     devient une case vide qu'on remplit au crayon. */
  .champ-comptage {
    border: 1px solid var(--bord-fort);
    background: var(--carte);
    min-height: 28px;
    max-width: 90px;
  }

  .frise-etape { break-inside: avoid; page-break-inside: avoid; }
  .fiche-lot { break-inside: avoid; page-break-inside: avoid; }
}

/* --------------------------------------------------------------------------
   16. Module Prix
   Ecrans pages/prix.php et pages/prix_produit.php.
   Ajout en fin de feuille : rien de ce qui precede n'est redefini.
   Seules exceptions a la regle du mono-accent : les couleurs de courbe, une
   par fournisseur, sans lesquelles un graphique multi-series est illisible.
   Elles ne servent QUE dans le graphique de prix et sa legende.
   -------------------------------------------------------------------------- */

:root {
  --serie-1: #15803D;
  --serie-2: #1D4ED8;
  --serie-3: #B45309;
  --serie-4: #7E22CE;
  --serie-5: #0F766E;
  --serie-6: #BE123C;
}

@media (prefers-color-scheme: dark) {
  :root {
    --serie-1: #4ADE80;
    --serie-2: #60A5FA;
    --serie-3: #FBBF24;
    --serie-4: #C084FC;
    --serie-5: #2DD4BF;
    --serie-6: #FB7185;
  }
}

.serie-1 { color: var(--serie-1); }
.serie-2 { color: var(--serie-2); }
.serie-3 { color: var(--serie-3); }
.serie-4 { color: var(--serie-4); }
.serie-5 { color: var(--serie-5); }
.serie-6 { color: var(--serie-6); }

/* Barre d'outils : les listes deroulantes de filtre ne s'etirent pas */
.filtre-champ {
  width: auto;
  min-width: 168px;
  flex: 0 1 auto;
}

/* Titre de section a l'interieur d'une carte */
.bloc-titre {
  font-size: 16px;
  font-weight: 500;
  margin: 0 0 12px;
}

/* En-tete de carte : titre a gauche, selecteur a droite */
.carte-entete {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 16px;
}
.carte-entete h2 { font-size: 16px; font-weight: 500; }

/* Seconde ligne discrete dans une cellule de tableau : le prix par unite
   d'achat sous le prix par unite de suivi, le fournisseur sous le montant. */
/* Le prix par unite d'achat sous le prix par unite de suivi, le fournisseur
   sous le montant : c'est la reponse a la directrice. On la lit sans effort. */
.cellule-detail {
  display: block;
  margin-top: 2px;
  font-size: 12px;
  font-weight: 400;
  line-height: 1.35;
  color: var(--texte-doux);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.cellule-detail.accent { color: var(--accent); }
.cellule-detail.rouge  { color: var(--alerte); }

/* Variation d'un achat a l'autre : hausse en rouge, baisse en vert */
.variation-hausse { color: var(--danger); white-space: nowrap; }
.variation-baisse { color: var(--accent); white-space: nowrap; }
.variation-stable { color: var(--texte-faible); white-space: nowrap; }

/* Le prix actuel, en tres gros : la reponse a la question posee */
.prix-vedette { padding: 20px 24px; }

.prix-vedette-valeur {
  font-size: 36px;
  font-weight: 500;
  line-height: 1.15;
  letter-spacing: -0.015em;
  font-variant-numeric: tabular-nums;
}

.prix-vedette-unite {
  font-size: 15px;
  font-weight: 400;
  color: var(--texte-doux);
  letter-spacing: 0;
  margin-left: 4px;
}

.prix-vedette-detail {
  margin-top: 8px;
  font-size: 15px;
  color: var(--texte-doux);
}

.prix-vedette-achat {
  margin-top: 2px;
  font-size: 13px;
  color: var(--texte-doux);
  font-variant-numeric: tabular-nums;
}

.prix-vedette-fiche {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--bord);
  font-size: 12px;
  color: var(--texte-faible);
}

/* Selecteur de periode du graphique */
.periodes {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  flex-wrap: wrap;
}

.periodes .periode {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 40px;
  padding: 0 14px;
  border-radius: var(--rayon-controle);
  color: var(--texte-doux);
  font-size: 15px;
}
.periodes .periode:hover { background: var(--survol); color: var(--texte); text-decoration: none; }
.periodes .periode.actif { background: var(--accent-fond); color: var(--accent); font-weight: 500; }

/* Graphique d'evolution : SVG genere par PHP, aucune bibliotheque */
.graphique {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  margin-bottom: 12px;
}

.graphique-svg {
  display: block;
  width: 100%;
  min-width: 680px;
  height: auto;
}

.graphique-svg .grille-svg { stroke: var(--bord); stroke-width: 1; }
.graphique-svg .axe-ligne-svg { stroke: var(--bord-fort); stroke-width: 1; }

/* Graduations du graphique : ce sont des montants, pas de la decoration.
   L'ecran est montre a la directrice, il se lit a un metre. */
.graphique-svg .axe-svg {
  fill: var(--texte-doux);
  font-family: var(--police);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}

.graphique-svg .ligne-svg {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.75;
  stroke-linejoin: round;
  stroke-linecap: round;
}

.graphique-svg .point-svg {
  fill: var(--carte);
  stroke: currentColor;
  stroke-width: 1.75;
}
.graphique-svg .point-svg:hover { fill: currentColor; }

/* Legende : une pastille coloree, un nom de fournisseur en texte normal */
.serie-legende {
  display: flex;
  align-items: center;
  gap: 8px 20px;
  flex-wrap: wrap;
  margin-bottom: 12px;
}

.serie-item {
  display: inline-flex;
  align-items: center;
  font-size: 13px;
  color: var(--texte-doux);
}

/* Les tableaux de l'ecran Prix comptent jusqu'a onze colonnes, et certains
   rappels y sont longs ("achat par colis de 200 paquets"). On les laisse
   revenir a la ligne : moins de defilement horizontal a l'ecran, et surtout un
   tableau qui tient dans la feuille a l'impression, ou la largeur est imposee.
   Les nombres, eux, restent insecables : c'est .num qui les protege. */
.tableau-prix thead th { white-space: normal; }
.tableau-prix .cellule-detail { white-space: normal; }

/* Les tableaux de l'ecran Prix comptent beaucoup de colonnes */
@media (max-width: 900px) {
  .tableau-prix { min-width: 880px; }
  .filtre-champ { width: 100%; min-width: 0; flex: 1 1 100%; }
  .carte-entete { align-items: flex-start; }
  .prix-vedette-valeur { font-size: 28px; }
}

@media print {
  /* Les filtres ne s'impriment pas : la periode figure dans les titres. */
  .periodes,
  .filtre-champ { display: none !important; }

  .graphique { overflow: visible; }
  .graphique-svg { min-width: 0; }

  /* En noir et blanc, les courbes se distinguent par leur trace. */
  :root {
    --serie-1: #000000;
    --serie-2: #333333;
    --serie-3: #555555;
    --serie-4: #000000;
    --serie-5: #333333;
    --serie-6: #555555;
  }
  .graphique-svg .serie-2 .ligne-svg { stroke-dasharray: 6 3; }
  .graphique-svg .serie-3 .ligne-svg { stroke-dasharray: 2 3; }
  .graphique-svg .serie-4 .ligne-svg { stroke-dasharray: 8 3 2 3; }
  .graphique-svg .serie-5 .ligne-svg { stroke-dasharray: 4 2; }
  .graphique-svg .serie-6 .ligne-svg { stroke-dasharray: 1 3; }

  .variation-hausse,
  .variation-baisse,
  .variation-stable { color: var(--texte); }

  .prix-vedette-valeur { font-size: 24pt; }
}

/* --------------------------------------------------------------------------
   16. Module Referentiel
   Produits, fournisseurs, zones de stockage, categories.
   Ajoute par le module referentiel : ne rien reecrire au-dessus.
   -------------------------------------------------------------------------- */

/* L'attribut hidden l'emporte sur toute regle de disposition (grille, table). */
[hidden] { display: none !important; }

/* Bouton d'envoi implicite : invisible, mais premier de son formulaire, pour que
   la touche Entree enregistre au lieu de declencher une suppression de ligne. */
.submit-implicite {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  border: 0;
  overflow: hidden;
  clip-path: inset(50%);
}

/* Barre d'outils : les selecteurs gardent une largeur naturelle */
.barre-outils .champ { width: auto; min-width: 168px; }
.barre-outils .case { white-space: nowrap; }

/* Fleche de tri dans un en-tete de colonne cliquable */
.tri-fleche {
  font-size: 12px;
  color: var(--texte-doux);
  margin-left: 2px;
}

/* Deuxieme ligne discrete dans une cellule de tableau */
.sous-ligne {
  display: block;
  font-size: 12px;
  font-weight: 400;
  color: var(--texte-faible);
}

/* Couleurs de texte pour un signalement d'etat, jamais une ligne entiere */
.txt-attention { color: var(--attention); }
.txt-alerte    { color: var(--alerte); }

/* Pastille prenant la couleur d'une categorie.
   La couleur arrive en variable inline : c'est une donnee, pas une decision
   de style, et elle est validee en PHP avant d'etre ecrite. */
.pastille-couleur { background: var(--pastille-couleur, var(--texte-faible)); }

/* Carte mise en avant : le bloc Unites de la fiche produit */
.carte-appuyee { border-color: var(--bord-fort); }

/* Bloc Unites : libelle a gauche, champ au milieu, precision a droite */
.unites-ligne {
  display: grid;
  grid-template-columns: minmax(180px, 24em) minmax(120px, 220px) 1fr;
  gap: 12px;
  align-items: center;
  margin-bottom: 12px;
}

.unites-ligne > label {
  margin: 0;
  font-size: 15px;
  font-weight: 400;
  color: var(--texte);
}

.unites-suffixe {
  font-size: 13px;
  color: var(--texte-doux);
}

/* Variante d'attention de l'encadre de verdict : conversion incomplete */
.verdict-attention {
  background: var(--attention-fond);
  border-color: var(--attention);
}
.verdict-attention .verdict-reponse { color: var(--attention); }

/* Tableau de saisie en ligne : zones de stockage, categories */
.tableau-saisie td {
  padding-top: 8px;
  padding-bottom: 8px;
}
.tableau-saisie .champ { min-width: 0; }
.tableau-saisie .case { min-height: 40px; }

.champ-mini { max-width: 96px; }

.champ-couleur {
  width: 48px;
  min-width: 48px;
  padding: 2px;
  cursor: pointer;
}

/* Barre de titre d'une carte, avec un lien ou un rappel a droite */
.carte-barre {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 12px;
}
.carte-barre .carte-titre { margin-bottom: 0; }

@media (max-width: 720px) {
  .unites-ligne {
    grid-template-columns: 1fr;
    gap: 4px;
    margin-bottom: 16px;
  }
  .unites-ligne > label {
    font-size: 12px;
    color: var(--texte-faible);
  }
  .barre-outils .champ { width: 100%; }
}

/* --------------------------------------------------------------------------
   Module Entrées - écrans entrees.php et entree_edit.php
   --------------------------------------------------------------------------
   Une réception se saisit en cartes, pas en tableau : l'économe est souvent
   debout devant la palette, sur une tablette, et chaque ligne porte huit
   informations (quantité, unité de saisie, prix, lot, DLC, origine, agrément,
   zone). Un tableau les rendrait illisibles.
   Rappel d'unités : la quantité saisie peut être en unité d'ACHAT ou en unité
   de SUIVI ; le stock enregistré est toujours en unité de suivi.
   -------------------------------------------------------------------------- */

/* Une carte = une ligne de bon = un lot */
.ligne-entree {
  background: var(--carte);
  border: 1px solid var(--bord);
  border-radius: var(--rayon-carte);
  padding: 16px 20px;
}
.ligne-entree + .ligne-entree { margin-top: 12px; }

/* Un bloc masqué le reste, même quand sa classe impose un display */
.ligne-entree [hidden] { display: none; }

.ligne-entree-tete {
  display: flex;
  align-items: flex-start;
  gap: 16px;
  margin-bottom: 16px;
}
.ligne-entree-produit { flex: 1 1 auto; min-width: 0; }
.ligne-entree-tete .bouton-discret { margin-top: 20px; }

.ligne-entree-chiffres { align-items: start; }

/* Champ suivi de son unité : "2 [colis]" ou "60,00 [€ le colis]" */
.saisie-unite {
  display: flex;
  align-items: center;
  gap: 8px;
}
.saisie-unite .champ { flex: 1 1 auto; min-width: 0; }

.champ-unite {
  flex: 0 0 auto;
  width: auto;
  min-width: 104px;
}

.suffixe-unite {
  flex: 0 0 auto;
  font-size: 13px;
  color: var(--texte-doux);
  white-space: nowrap;
}

.total-ligne {
  display: block;
  min-height: 40px;
  padding-top: 8px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}

/* Repère de variation : la comparaison porte TOUJOURS sur le prix par unité
   de suivi, jamais sur le prix du colis. */
.repere-prix {
  display: block;
  margin-top: 2px;
  font-size: 12px;
  line-height: 1.4;
  color: var(--texte-doux);
  font-variant-numeric: tabular-nums;
}
.repere-prix.hausse { color: var(--danger); }
.repere-prix.baisse { color: var(--accent); }

/* Conditionnement : visible seulement quand le produit a une unité d'achat */
.entree-conditionnement {
  display: flex;
  align-items: flex-end;
  gap: 16px;
  flex-wrap: wrap;
  margin-top: 16px;
}
.entree-conditionnement .case { margin-bottom: 2px; font-size: 13px; }
.entree-conditionnement.different .champ { border-color: var(--attention); }
.entree-conditionnement.different .libelle { color: var(--attention); }

/* Assistant de prix : replié par défaut, il ne gêne personne */
.assistant { margin-top: 12px; }
.assistant > summary {
  display: flex;
  align-items: center;
  min-height: 40px;
  font-size: 13px;
  color: var(--texte-doux);
  cursor: pointer;
}
.assistant > summary:hover { color: var(--accent); }
.assistant-corps {
  display: flex;
  align-items: flex-end;
  gap: 12px;
  flex-wrap: wrap;
  padding: 4px 0 8px;
}
.assistant-corps .champ-court { max-width: 120px; }
.assistant-corps .equivalence { flex: 1 1 200px; margin-top: 0; }

.entree-lot { margin-top: 16px; }

/* Pied du bon : ajout d'une ligne à gauche, total général à droite */
.entree-pied {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin-top: 16px;
}
.entree-total-general {
  font-size: 20px;
  font-weight: 500;
  color: var(--texte);
  font-variant-numeric: tabular-nums;
}

/* Le verrou d'une entrée déjà sortie en cuisine désactive les lignes d'un bloc */
.entree-fieldset {
  border: 0;
  margin: 0;
  padding: 0;
  min-width: 0;
}

.actions-formulaire .espaceur { flex: 1 1 auto; }

/* Liste des entrées : rappel discret sous la valeur principale d'une cellule */
.entree-sous-ligne {
  display: block;
  font-size: 12px;
  line-height: 1.4;
  color: var(--texte-faible);
}

/* Le formulaire de suppression tient dans la cellule d'actions */
.actions-ligne form { display: inline; }

/* Boutons et raccourcis sous les champs de filtre */
.filtres-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 16px;
}

@media (max-width: 900px) {
  .ligne-entree { padding: 16px; }
  .ligne-entree-tete { flex-wrap: wrap; }
  .total-ligne { min-height: 0; padding-top: 0; }
}

/* --------------------------------------------------------------------------
   16. Module commandes
   Liste des commandes et saisie d'une commande au telephone.
   Aucune couleur en dur : uniquement les variables declarees sur :root.
   -------------------------------------------------------------------------- */


/* Seconde ligne discrete d'une cellule ou d'une ligne de saisie :
   code produit, conditionnement, stock, provenance du prix */
.cmd-meta {
  display: block;
  margin-top: 2px;
  font-size: 12px;
  line-height: 1.4;
  color: var(--texte-faible);
}

/* Formulaire de suppression pose dans une colonne d'actions */
.cmd-form-inline { display: inline; }

/* --- Saisie d'une commande ----------------------------------------------- */

.cmd-nom {
  display: block;
  font-size: 15px;
  line-height: 1.4;
}

/* Recherche produit et ses suggestions */
.cmd-recherche { margin-bottom: 20px; }

.cmd-suggest {
  position: relative;
  max-width: 520px;
}

.cmd-liste {
  position: absolute;
  z-index: 20;
  top: 100%;
  left: 0;
  right: 0;
  margin: 4px 0 0;
  padding: 4px;
  max-height: 320px;
  overflow-y: auto;
  list-style: none;
  background: var(--carte);
  border: 1px solid var(--bord-fort);
  border-radius: var(--rayon-controle);
}
.cmd-liste[hidden] { display: none; }

.cmd-option {
  padding: 8px 12px;
  min-height: 40px;
  border-radius: var(--rayon-controle);
  cursor: pointer;
}
.cmd-option:hover { background: var(--survol); }
.cmd-option.actif { background: var(--accent-fond); }

.cmd-option-nom { display: block; font-size: 15px; }

/* Stock et conditionnement dans la liste de suggestions : on commande au
   telephone, il faut lire ces chiffres du premier coup d'oeil. */
.cmd-option-meta {
  display: block;
  font-size: 12px;
  color: var(--texte-doux);
  font-variant-numeric: tabular-nums;
}

.cmd-option-alerte {
  display: block;
  font-size: 12px;
  color: var(--alerte);
}

/* Un champ et son unite, cote a cote */
.cmd-saisie {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.cmd-unite {
  font-size: 12px;
  color: var(--texte-faible);
  white-space: nowrap;
}

/* Conditionnement : replie par defaut, deplie a la demande */
.cmd-cond { display: block; margin-top: 6px; }

.cmd-coef {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 4px;
}
.cmd-coef[hidden] { display: none; }
.cmd-coef .libelle { margin: 0; }
.cmd-coef .champ { width: 84px; }

/* Colonnes du tableau de saisie */
.cmd-tableau .cmd-col-produit { width: 42%; }
.cmd-tableau .cmd-col-qte     { width: 168px; }
.cmd-tableau .cmd-col-prix    { width: 210px; }
.cmd-tableau .cmd-col-total   { width: 110px; }
.cmd-tableau .cmd-col-retirer { width: 80px; text-align: right; }

.cmd-tableau .cmd-col-qte .champ  { width: 88px; }
.cmd-tableau .cmd-col-prix .champ { width: 104px; }

.cmd-tableau td { vertical-align: top; padding-top: 14px; }

/* Etat vide du tableau de saisie */
.cmd-aucune {
  padding: 32px 0;
  text-align: center;
  color: var(--texte-doux);
}

/* Actions de bas de page : envoyer, supprimer */
.cmd-pied {
  display: flex;
  align-items: center;
  gap: 20px;
  flex-wrap: wrap;
  margin-top: 24px;
  padding-top: 16px;
  border-top: 1px solid var(--bord);
}
.cmd-supprimer:hover { color: var(--danger); }

/* Une ligne de saisie de commande. L'en-tete du tableau est collant : sans
   cette marge, la ligne qu'on vient d'ajouter se glisse dessous au moment ou
   le script amene le curseur sur sa quantite. */
.cmd-ligne { scroll-margin-top: 56px; }

/* Le commentaire ferme le bloc : pas de marge en trop sous la carte. */
.cmd-commentaire { margin-bottom: 0; }

@media (max-width: 900px) {
  /* Le tableau de saisie defile horizontalement plutot que de se tasser */
  .cmd-tableau { min-width: 700px; }
  .cmd-suggest { max-width: none; }
}

/* Un en-tete de colonne ne se cache jamais : seules les actions des lignes
   apparaissent au survol. */
.tableau thead th.actions-ligne { opacity: 1; }

/* --------------------------------------------------------------------------
   Grille « ce que chaque point reçoit »
   --------------------------------------------------------------------------
   Un bloc par point, les catégories à la suite qui reviennent à la ligne.
   La version en tableau débordait de l'écran dès la dizaine de catégories et
   cassait les noms de points sur trois lignes. Ici la largeur ne dépend plus
   du nombre de catégories : elles s'empilent.
   -------------------------------------------------------------------------- */

.point-categories {
  border: 1px solid var(--bord);
  border-radius: 8px;
  padding: 4px 16px 10px;
  margin: 0 0 14px;
}

.point-categories legend {
  padding: 0 6px;
  font-size: 15px;
  font-weight: 500;
}

.point-categories legend .faible { font-weight: 400; }

.cases-groupe {
  display: flex;
  flex-wrap: wrap;
  gap: 0 22px;
  margin-bottom: 4px;
}

.cases-groupe .case { min-height: 34px; }
